summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--bin/empty.txt2
-rw-r--r--compiler/ast.nim15
-rw-r--r--compiler/c2nim/c2nim.nim92
-rw-r--r--compiler/c2nim/clex.nim787
-rw-r--r--compiler/c2nim/cparse.nim2272
-rw-r--r--compiler/c2nim/cpp.nim347
-rw-r--r--compiler/c2nim/nimrod.cfg4
-rw-r--r--compiler/c2nim/tests/enum.h40
-rw-r--r--compiler/c2nim/tests/matrix.h240
-rw-r--r--compiler/c2nim/tests/struct_anonym.h27
-rw-r--r--compiler/c2nim/tests/systest.c622
-rw-r--r--compiler/c2nim/tests/systest2.c17
-rw-r--r--compiler/c2nim/tests/vincent.c33
-rw-r--r--compiler/c2nim/tests/vincent.h3
-rw-r--r--compiler/ccgexprs.nim56
-rw-r--r--compiler/ccgtypes.nim17
-rw-r--r--compiler/ccgutils.nim6
-rw-r--r--compiler/cgen.nim2
-rw-r--r--compiler/commands.nim8
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--compiler/jsgen.nim6
-rw-r--r--compiler/lambdalifting.nim834
-rw-r--r--compiler/lexer.nim4
-rw-r--r--compiler/lists.nim8
-rw-r--r--compiler/lowerings.nim111
-rw-r--r--compiler/magicsys.nim2
-rw-r--r--compiler/nimrod.nim2
-rw-r--r--compiler/pas2nim/nimrod.cfg4
-rw-r--r--compiler/pas2nim/pas2nim.nim64
-rw-r--r--compiler/pas2nim/paslex.nim570
-rw-r--r--compiler/pas2nim/pasparse.nim1513
-rw-r--r--compiler/pragmas.nim14
-rw-r--r--compiler/renderer.nim2
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/semdestruct.nim3
-rw-r--r--compiler/semexprs.nim11
-rw-r--r--compiler/semparallel.nim14
-rw-r--r--compiler/semstmts.nim30
-rw-r--r--compiler/semtypinst.nim2
-rw-r--r--compiler/service.nim2
-rw-r--r--compiler/tccgen.nim8
-rw-r--r--compiler/vm.nim14
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim18
-rw-r--r--compiler/wordrecg.nim8
-rw-r--r--doc/advopt.txt1
-rw-r--r--doc/c2nim.txt295
-rw-r--r--doc/exception_hierarchy_fragment.txt31
-rw-r--r--doc/keywords.txt2
-rw-r--r--doc/lib.txt11
-rw-r--r--doc/manual.txt227
-rw-r--r--doc/nimrodc.txt52
-rw-r--r--doc/sets_fragment.txt40
-rw-r--r--doc/spawn.txt4
-rw-r--r--doc/tut1.txt240
-rw-r--r--doc/tut2.txt57
-rw-r--r--koch.nim3
-rw-r--r--lib/core/typeinfo.nim53
-rw-r--r--lib/nimbase.h3
-rw-r--r--lib/packages/docutils/highlite.nim2
-rw-r--r--lib/packages/docutils/rstgen.nim2
-rw-r--r--lib/posix/posix.nim2
-rw-r--r--lib/pure/algorithm.nim14
-rw-r--r--lib/pure/base64.nim2
-rw-r--r--lib/pure/collections/critbits.nim2
-rw-r--r--lib/pure/collections/sequtils.nim3
-rw-r--r--lib/pure/collections/sets.nim709
-rw-r--r--lib/pure/collections/tables.nim7
-rw-r--r--lib/pure/complex.nim39
-rw-r--r--lib/pure/concurrency/threadpool.nim18
-rw-r--r--lib/pure/encodings.nim1
-rw-r--r--lib/pure/json.nim8
-rw-r--r--lib/pure/os.nim146
-rw-r--r--lib/pure/osproc.nim4
-rw-r--r--lib/pure/parsecfg.nim3
-rw-r--r--lib/pure/parseurl.nim4
-rw-r--r--lib/pure/parseutils.nim158
-rw-r--r--lib/pure/strutils.nim284
-rw-r--r--lib/pure/typetraits.nim23
-rw-r--r--lib/pure/uri.nim350
-rw-r--r--lib/pure/xmldom.nim435
-rw-r--r--lib/system.nim297
-rw-r--r--lib/system/ansi_c.nim2
-rw-r--r--lib/system/atomics.nim2
-rw-r--r--lib/system/deepcopy.nim141
-rw-r--r--lib/system/excpt.nim29
-rw-r--r--lib/system/hti.nim1
-rw-r--r--lib/system/jssys.nim84
-rw-r--r--lib/system/repr.nim4
-rw-r--r--lib/system/sysstr.nim113
-rw-r--r--lib/system/widestrs.nim4
-rw-r--r--tests/closure/tclosure.nim8
-rw-r--r--tests/closure/tforum.nim44
-rw-r--r--tests/closure/tjester.nim32
-rw-r--r--tests/closure/tnestedclosure.nim51
-rw-r--r--tests/destructor/tdestructor.nim6
-rw-r--r--tests/destructor/tdestructor2.nim2
-rw-r--r--tests/float/tfloat4.nim42
-rw-r--r--tests/manyloc/keineschweine/lib/gl.nim1536
-rw-r--r--tests/manyloc/keineschweine/lib/glext.nim4673
-rw-r--r--tests/manyloc/keineschweine/lib/glu.nim335
-rw-r--r--tests/manyloc/keineschweine/lib/glut.nim438
-rw-r--r--tests/manyloc/keineschweine/lib/glx.nim153
-rw-r--r--tests/manyloc/keineschweine/lib/wingl.nim368
-rw-r--r--tests/manyloc/packages/package1/p1.babel0
-rw-r--r--tests/manyloc/packages/package2/p2.babel0
-rw-r--r--tests/matrix/tmatrix2.nim2
-rw-r--r--tests/parallel/tdeepcopy.nim18
-rw-r--r--tests/sets/tsets3.nim21
-rw-r--r--tests/showoff/tdrdobbs_examples.nim2
-rw-r--r--tests/stdlib/testequivalence.nim1
-rw-r--r--tests/system/tfloatToString.nim22
-rw-r--r--tests/table/ptables.nim9
-rw-r--r--tests/testament/categories.nim5
-rw-r--r--todo.txt22
-rw-r--r--tools/nimrepl.nim2
-rw-r--r--tools/trimcc.nim2
-rw-r--r--web/babelpkglist.nim11
-rw-r--r--web/index.txt2
-rw-r--r--web/news.txt19
-rw-r--r--web/nimrod.ini6
121 files changed, 11283 insertions, 8300 deletions
diff --git a/bin/empty.txt b/bin/empty.txt
index 666142073..20f9a91e3 100644
--- a/bin/empty.txt
+++ b/bin/empty.txt
@@ -1 +1 @@
-This file keeps several tools from deleting this subdirectory.
+This file keeps several tools from deleting this subdirectory.

diff --git a/compiler/ast.nim b/compiler/ast.nim
index 516954b88..51319127c 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -263,7 +263,7 @@ type
     sfNamedParamCall, # symbol needs named parameter call syntax in target
                       # language; for interfacing with Objective C
     sfDiscardable,    # returned value may be discarded implicitly
-    sfDestructor,     # proc is destructor
+    sfOverriden,      # proc is overriden
     sfGenSym          # symbol is 'gensym'ed; do not add to symbol table
 
   TSymFlags* = set[TSymFlag]
@@ -417,6 +417,7 @@ type
                 # efficiency
     nfTransf,   # node has been transformed
     nfSem       # node has been checked for semantics
+    nfLL        # node has gone through lambda lifting
     nfDotField  # the call can use a dot operator
     nfDotSetter # the call can use a setter dot operarator
     nfExplicitCall # x.y() was used instead of x.y
@@ -552,7 +553,7 @@ type
     mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq,
     mIsPartOf, mAstToStr, mParallel,
     mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
-    mNewString, mNewStringOfCap,
+    mNewString, mNewStringOfCap, mParseBiggestFloat,
     mReset,
     mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
     mOrdinal,
@@ -784,12 +785,13 @@ type
                               # the body of the user-defined type class
                               # formal param list
                               # else: unused
-    destructor*: PSym         # destructor. warning: nil here may not necessary
-                              # mean that there is no destructor.
-                              # see instantiateDestructor in types.nim
     owner*: PSym              # the 'owner' of the type
     sym*: PSym                # types have the sym associated with them
                               # it is used for converting types to strings
+    destructor*: PSym         # destructor. warning: nil here may not necessary
+                              # mean that there is no destructor.
+                              # see instantiateDestructor in semdestruct.nim
+    deepCopy*: PSym           # overriden 'deepCopy' operation
     size*: BiggestInt         # the size of the type in bytes
                               # -1 means that the size is unkwown
     align*: int               # the type's alignment requirements
@@ -1189,6 +1191,7 @@ proc assignType(dest, src: PType) =
   dest.size = src.size
   dest.align = src.align
   dest.destructor = src.destructor
+  dest.deepCopy = src.deepCopy
   # this fixes 'type TLock = TSysLock':
   if src.sym != nil:
     if dest.sym != nil:
@@ -1505,7 +1508,7 @@ proc isGenericRoutine*(s: PSym): bool =
 proc skipGenericOwner*(s: PSym): PSym =
   internalAssert s.kind in skProcKinds
   ## Generic instantiations are owned by their originating generic
-  ## symbol. This proc skips such owners and goes straigh to the owner
+  ## symbol. This proc skips such owners and goes straight to the owner
   ## of the generic itself (the module or the enclosing proc).
   result = if sfFromGeneric in s.flags: s.owner.owner
            else: s.owner
diff --git a/compiler/c2nim/c2nim.nim b/compiler/c2nim/c2nim.nim
deleted file mode 100644
index 9b12b9e47..000000000
--- a/compiler/c2nim/c2nim.nim
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-#
-#      c2nim - C to Nimrod source converter
-#        (c) Copyright 2013 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-import
-  strutils, os, times, parseopt, llstream, ast, renderer, options, msgs,
-  clex, cparse
-
-const
-  Version = NimrodVersion
-  Usage = """
-c2nim - C to Nimrod source converter
-  (c) 2013 Andreas Rumpf
-Usage: c2nim [options] inputfile [options]
-Options:
-  -o, --out:FILE         set output filename
-  --cpp                  process C++ input file
-  --dynlib:SYMBOL        import from dynlib: SYMBOL will be used for the import
-  --header:HEADER_FILE   import from a HEADER_FILE (discouraged!)
-  --cdecl                annotate procs with ``{.cdecl.}``
-  --stdcall              annotate procs with ``{.stdcall.}``
-  --ref                  convert typ* to ref typ (default: ptr typ)
-  --prefix:PREFIX        strip prefix for the generated Nimrod identifiers
-                         (multiple --prefix options are supported)
-  --suffix:SUFFIX        strip suffix for the generated Nimrod identifiers
-                         (multiple --suffix options are supported)
-  --skipinclude          do not convert ``#include`` to ``import``
-  --typeprefixes         generate ``T`` and ``P`` type prefixes
-  --skipcomments         do not copy comments
-  --ignoreRValueRefs     translate C++'s ``T&&`` to ``T`` instead ``of var T``
-  --keepBodies           keep C++'s method bodies
-  --spliceHeader         parse and emit header before source file
-  -v, --version          write c2nim's version
-  -h, --help             show this help
-"""
-
-proc parse(infile: string, options: PParserOptions): PNode =
-  var stream = llStreamOpen(infile, fmRead)
-  if stream == nil: rawMessage(errCannotOpenFile, infile)
-  var p: TParser
-  openParser(p, infile, stream, options)
-  result = parseUnit(p)
-  closeParser(p)
-
-proc main(infile, outfile: string, options: PParserOptions, spliceHeader: bool) =
-  var start = getTime()
-  if spliceHeader and infile.splitFile.ext == ".c" and existsFile(infile.changeFileExt(".h")):
-    var header_module = parse(infile.changeFileExt(".h"), options)
-    var source_module = parse(infile, options)
-    for n in source_module:
-      addson(header_module, n)
-    renderModule(header_module, outfile)
-  else:
-    renderModule(parse(infile, options), outfile)
-  rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start), 
-                            formatSize(getTotalMem())])
-
-var
-  infile = ""
-  outfile = ""
-  spliceHeader = false
-  parserOptions = newParserOptions()
-for kind, key, val in getopt():
-  case kind
-  of cmdArgument: infile = key
-  of cmdLongOption, cmdShortOption:
-    case key.toLower
-    of "help", "h":
-      stdout.write(Usage)
-      quit(0)
-    of "version", "v":
-      stdout.write(Version & "\n")
-      quit(0)
-    of "o", "out": outfile = val
-    of "spliceheader": spliceHeader = true
-    else:
-      if not parserOptions.setOption(key, val):
-        stdout.writeln("[Error] unknown option: " & key)
-  of cmdEnd: assert(false)
-if infile.len == 0:
-  # no filename has been given, so we show the help:
-  stdout.write(Usage)
-else:
-  if outfile.len == 0:
-    outfile = changeFileExt(infile, "nim")
-  infile = addFileExt(infile, "h")
-  main(infile, outfile, parserOptions, spliceHeader)
diff --git a/compiler/c2nim/clex.nim b/compiler/c2nim/clex.nim
deleted file mode 100644
index 3934eea63..000000000
--- a/compiler/c2nim/clex.nim
+++ /dev/null
@@ -1,787 +0,0 @@
-#
-#
-#      c2nim - C to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# This module implements an Ansi C scanner. This is an adaption from
-# the scanner module. Keywords are not handled here, but in the parser to make
-# it more flexible.
-
-
-import 
-  options, msgs, strutils, platform, nimlexbase, llstream
-
-const 
-  MaxLineLength* = 80         # lines longer than this lead to a warning
-  numChars*: TCharSet = {'0'..'9', 'a'..'z', 'A'..'Z'} 
-  SymChars*: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF'}
-  SymStartChars*: TCharSet = {'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF'}
-
-type
-  TTokKind* = enum 
-    pxInvalid, pxEof,         
-    pxMacroParam,             # fake token: macro parameter (with its index)
-    pxStarComment,            # /* */ comment
-    pxLineComment,            # // comment
-    pxDirective,              # #define, etc.
-    pxDirectiveParLe,         # #define m( with parle (yes, C is that ugly!)
-    pxDirConc,                # ##
-    pxNewLine,                # newline: end of directive
-    pxAmp,                    # &
-    pxAmpAmp,                 # && 
-    pxAmpAsgn,                # &=
-    pxAmpAmpAsgn,             # &&=
-    pxBar,                    # |
-    pxBarBar,                 # ||
-    pxBarAsgn,                # |=
-    pxBarBarAsgn,             # ||=
-    pxNot,                    # !
-    pxPlusPlus,               # ++
-    pxMinusMinus,             # --
-    pxPlus,                   # +
-    pxPlusAsgn,               # +=
-    pxMinus,                  # -
-    pxMinusAsgn,              # -=
-    pxMod,                    # %
-    pxModAsgn,                # %=
-    pxSlash,                  # /
-    pxSlashAsgn,              # /=
-    pxStar,                   # *
-    pxStarAsgn,               # *=
-    pxHat,                    # ^
-    pxHatAsgn,                # ^=
-    pxAsgn,                   # =
-    pxEquals,                 # ==
-    pxDot,                    # .
-    pxDotDotDot,              # ...
-    pxLe,                     # <=
-    pxLt,                     # <
-    pxGe,                     # >=
-    pxGt,                     # >
-    pxNeq,                    # != 
-    pxConditional,            # ?
-    pxShl,                    # <<
-    pxShlAsgn,                # <<=
-    pxShr,                    # >>
-    pxShrAsgn,                # >>=
-    pxTilde,                  # ~
-    pxTildeAsgn,              # ~=
-    pxArrow,                  # ->
-    pxScope,                  # ::
-
-    pxStrLit, 
-    pxCharLit,
-    pxSymbol,                 # a symbol
-    pxIntLit, 
-    pxInt64Lit, # long constant like 0x70fffffff or out of int range
-    pxFloatLit, 
-    pxParLe, pxBracketLe, pxCurlyLe, # this order is important 
-    pxParRi, pxBracketRi, pxCurlyRi, # for macro argument parsing!
-    pxComma, pxSemiColon, pxColon,
-    pxAngleRi                 # '>' but determined to be the end of a
-                              # template's angle bracket
-  TTokKinds* = set[TTokKind]
-
-type
-  TNumericalBase* = enum base10, base2, base8, base16
-  TToken* = object
-    xkind*: TTokKind          # the type of the token
-    s*: string                # parsed symbol, char or string literal
-    iNumber*: BiggestInt      # the parsed integer literal;
-                              # if xkind == pxMacroParam: parameter's position
-    fNumber*: BiggestFloat    # the parsed floating point literal
-    base*: TNumericalBase     # the numerical base; only valid for int
-                              # or float literals
-    next*: ref TToken         # for C we need arbitrary look-ahead :-(
-  
-  TLexer* = object of TBaseLexer
-    fileIdx*: int32
-    inDirective: bool
-  
-proc getTok*(L: var TLexer, tok: var TToken)
-proc printTok*(tok: TToken)
-proc `$`*(tok: TToken): string
-# implementation
-
-var
-  gLinesCompiled*: int
-
-proc fillToken(L: var TToken) = 
-  L.xkind = pxInvalid
-  L.iNumber = 0
-  L.s = ""
-  L.fNumber = 0.0
-  L.base = base10
-  
-proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) = 
-  openBaseLexer(lex, inputstream)
-  lex.fileIdx = filename.fileInfoIdx
-
-proc closeLexer*(lex: var TLexer) = 
-  inc(gLinesCompiled, lex.LineNumber)
-  closeBaseLexer(lex)
-
-proc getColumn*(L: TLexer): int = 
-  result = getColNumber(L, L.bufPos)
-
-proc getLineInfo*(L: TLexer): TLineInfo = 
-  result = newLineInfo(L.fileIdx, L.linenumber, getColNumber(L, L.bufpos))
-
-proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = 
-  msgs.GlobalError(getLineInfo(L), msg, arg)
-
-proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = 
-  var info = newLineInfo(L.fileIdx, L.linenumber, pos - L.lineStart)
-  msgs.GlobalError(info, msg, arg)
-
-proc tokKindToStr*(k: TTokKind): string =
-  case k
-  of pxEof: result = "[EOF]"
-  of pxInvalid: result = "[invalid]"
-  of pxMacroParam: result = "[macro param]"
-  of pxStarComment, pxLineComment: result = "[comment]" 
-  of pxStrLit: result = "[string literal]"
-  of pxCharLit: result = "[char literal]"
-
-  of pxDirective, pxDirectiveParLe: result = "#"             # #define, etc.
-  of pxDirConc: result = "##"
-  of pxNewLine: result = "[NewLine]"
-  of pxAmp: result = "&"                   # &
-  of pxAmpAmp: result = "&&"                # && 
-  of pxAmpAsgn: result = "&="                # &=
-  of pxAmpAmpAsgn: result = "&&="            # &&=
-  of pxBar: result = "|"                   # |
-  of pxBarBar: result = "||"                # ||
-  of pxBarAsgn: result = "|="               # |=
-  of pxBarBarAsgn: result = "||="            # ||=
-  of pxNot: result = "!"                   # !
-  of pxPlusPlus: result = "++"             # ++
-  of pxMinusMinus: result = "--"            # --
-  of pxPlus: result = "+"                  # +
-  of pxPlusAsgn: result = "+="              # +=
-  of pxMinus: result = "-"                 # -
-  of pxMinusAsgn: result = "-="             # -=
-  of pxMod: result = "%"                   # %
-  of pxModAsgn: result = "%="               # %=
-  of pxSlash: result = "/"                 # /
-  of pxSlashAsgn: result = "/="             # /=
-  of pxStar: result = "*"                  # *
-  of pxStarAsgn: result = "*="              # *=
-  of pxHat: result = "^"                   # ^
-  of pxHatAsgn: result = "^="               # ^=
-  of pxAsgn: result = "="                  # =
-  of pxEquals: result = "=="                # ==
-  of pxDot: result = "."                   # .
-  of pxDotDotDot: result = "..."             # ...
-  of pxLe: result = "<="                    # <=
-  of pxLt: result = "<"                    # <
-  of pxGe: result = ">="                    # >=
-  of pxGt: result = ">"                    # >
-  of pxNeq: result = "!="                   # != 
-  of pxConditional: result = "?"
-  of pxShl: result = "<<"
-  of pxShlAsgn: result = "<<="
-  of pxShr: result = ">>"
-  of pxShrAsgn: result = ">>="
-  of pxTilde: result = "~"
-  of pxTildeAsgn: result = "~="
-  of pxArrow: result = "->"
-  of pxScope: result = "::"
-
-  of pxSymbol: result = "[identifier]"
-  of pxIntLit, pxInt64Lit: result = "[integer literal]"
-  of pxFloatLit: result = "[floating point literal]"
-  of pxParLe: result = "("
-  of pxParRi: result = ")"
-  of pxBracketLe: result = "["
-  of pxBracketRi: result = "]"
-  of pxComma: result = ","
-  of pxSemiColon: result = ";"
-  of pxColon: result = ":"
-  of pxCurlyLe: result = "{"
-  of pxCurlyRi: result = "}"
-  of pxAngleRi: result = "> [end of template]"
-
-proc `$`(tok: TToken): string = 
-  case tok.xkind
-  of pxSymbol, pxInvalid, pxStarComment, pxLineComment, pxStrLit: result = tok.s
-  of pxIntLit, pxInt64Lit: result = $tok.iNumber
-  of pxFloatLit: result = $tok.fNumber
-  else: result = tokKindToStr(tok.xkind)
-  
-proc printTok(tok: TToken) = 
-  writeln(stdout, $tok)
-  
-proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = 
-  # matches ([chars]_)*
-  var pos = L.bufpos              # use registers for pos, buf
-  var buf = L.buf
-  while true: 
-    if buf[pos] in chars: 
-      add(tok.s, buf[pos])
-      inc(pos)
-    else: 
-      break 
-    if buf[pos] == '_': 
-      add(tok.s, '_')
-      inc(pos)
-  L.bufPos = pos
-
-proc isFloatLiteral(s: string): bool = 
-  for i in countup(0, len(s)-1): 
-    if s[i] in {'.', 'e', 'E'}: 
-      return true
-
-proc getNumber2(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos + 2 # skip 0b
-  tok.base = base2
-  var xi: BiggestInt = 0
-  var bits = 0
-  while true: 
-    case L.buf[pos]
-    of 'A'..'Z', 'a'..'z':
-      # ignore type suffix:
-      inc(pos)
-    of '2'..'9', '.': 
-      lexMessage(L, errInvalidNumber)
-      inc(pos)
-    of '_': 
-      inc(pos)
-    of '0', '1': 
-      xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0'))
-      inc(pos)
-      inc(bits)
-    else: break 
-  tok.iNumber = xi
-  if (bits > 32): tok.xkind = pxInt64Lit
-  else: tok.xkind = pxIntLit
-  L.bufpos = pos
-
-proc getNumber8(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos + 1 # skip 0
-  tok.base = base8
-  var xi: BiggestInt = 0
-  var bits = 0
-  while true: 
-    case L.buf[pos]
-    of 'A'..'Z', 'a'..'z':
-      # ignore type suffix:
-      inc(pos)
-    of '8'..'9', '.': 
-      lexMessage(L, errInvalidNumber)
-      inc(pos)
-    of '_': 
-      inc(pos)
-    of '0'..'7': 
-      xi = `shl`(xi, 3) or (ord(L.buf[pos]) - ord('0'))
-      inc(pos)
-      inc(bits)
-    else: break 
-  tok.iNumber = xi
-  if (bits > 12): tok.xkind = pxInt64Lit
-  else: tok.xkind = pxIntLit
-  L.bufpos = pos
-
-proc getNumber16(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos + 2          # skip 0x
-  tok.base = base16
-  var xi: BiggestInt = 0
-  var bits = 0
-  while true: 
-    case L.buf[pos]
-    of 'G'..'Z', 'g'..'z': 
-      # ignore type suffix:
-      inc(pos)
-    of '_': inc(pos)
-    of '0'..'9': 
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('0'))
-      inc(pos)
-      inc(bits, 4)
-    of 'a'..'f': 
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('a') + 10)
-      inc(pos)
-      inc(bits, 4)
-    of 'A'..'F': 
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('A') + 10)
-      inc(pos)
-      inc(bits, 4)
-    else: break 
-  tok.iNumber = xi
-  if bits > 32: tok.xkind = pxInt64Lit
-  else: tok.xkind = pxIntLit
-  L.bufpos = pos
-
-proc getFloating(L: var TLexer, tok: var TToken) =
-  matchUnderscoreChars(L, tok, {'0'..'9'})
-  if L.buf[L.bufpos] in {'e', 'E'}:
-    add(tok.s, L.buf[L.bufpos])
-    inc(L.bufpos)
-    if L.buf[L.bufpos] in {'+', '-'}:
-      add(tok.s, L.buf[L.bufpos])
-      inc(L.bufpos)
-    matchUnderscoreChars(L, tok, {'0'..'9'})
-
-proc getNumber(L: var TLexer, tok: var TToken) = 
-  tok.base = base10
-  if L.buf[L.bufpos] == '.':
-    add(tok.s, "0.")
-    inc(L.bufpos)
-    getFloating(L, tok)
-  else:
-    matchUnderscoreChars(L, tok, {'0'..'9'})
-    if L.buf[L.bufpos] == '.':
-      add(tok.s, '.')
-      inc(L.bufpos)
-      getFloating(L, tok)
-  try: 
-    if isFloatLiteral(tok.s): 
-      tok.fnumber = parseFloat(tok.s)
-      tok.xkind = pxFloatLit
-    else: 
-      tok.iNumber = parseInt(tok.s)
-      if (tok.iNumber < low(int32)) or (tok.iNumber > high(int32)): 
-        tok.xkind = pxInt64Lit
-      else: 
-        tok.xkind = pxIntLit
-  except EInvalidValue: 
-    lexMessage(L, errInvalidNumber, tok.s)
-  except EOverflow: 
-    lexMessage(L, errNumberOutOfRange, tok.s)
-  # ignore type suffix:
-  while L.buf[L.bufpos] in {'A'..'Z', 'a'..'z'}: inc(L.bufpos)
-  
-proc handleCRLF(L: var TLexer, pos: int): int = 
-  case L.buf[pos]
-  of CR: result = nimlexbase.handleCR(L, pos)
-  of LF: result = nimlexbase.handleLF(L, pos)
-  else: result = pos
-  
-proc escape(L: var TLexer, tok: var TToken, allowEmpty=false) = 
-  inc(L.bufpos) # skip \ 
-  case L.buf[L.bufpos]
-  of 'b', 'B':
-    add(tok.s, '\b')
-    inc(L.bufpos)
-  of 't', 'T':
-    add(tok.s, '\t')
-    inc(L.bufpos)
-  of 'n', 'N':
-    add(tok.s, '\L')
-    inc(L.bufpos)
-  of 'f', 'F':
-    add(tok.s, '\f')
-    inc(L.bufpos)
-  of 'r', 'R':
-    add(tok.s, '\r')
-    inc(L.bufpos)
-  of '\'':
-    add(tok.s, '\'')
-    inc(L.bufpos)
-  of '"':
-    add(tok.s, '"')
-    inc(L.bufpos)
-  of '\\':
-    add(tok.s, '\b')
-    inc(L.bufpos)  
-  of '0'..'7':
-    var xi = ord(L.buf[L.bufpos]) - ord('0')
-    inc(L.bufpos)
-    if L.buf[L.bufpos] in {'0'..'7'}:
-      xi = (xi shl 3) or (ord(L.buf[L.bufpos]) - ord('0'))
-      inc(L.bufpos)
-      if L.buf[L.bufpos] in {'0'..'7'}:
-        xi = (xi shl 3) or (ord(L.buf[L.bufpos]) - ord('0'))
-        inc(L.bufpos)
-    add(tok.s, chr(xi))
-  of 'x':
-    var xi = 0
-    inc(L.bufpos)
-    while true: 
-      case L.buf[L.bufpos]
-      of '0'..'9': 
-        xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('0'))
-        inc(L.bufpos)
-      of 'a'..'f': 
-        xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('a') + 10)
-        inc(L.bufpos)
-      of 'A'..'F': 
-        xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('A') + 10)
-        inc(L.bufpos)
-      else:
-        break 
-    add(tok.s, chr(xi))
-  elif not allowEmpty:
-    lexMessage(L, errInvalidCharacterConstant)
-  
-proc getCharLit(L: var TLexer, tok: var TToken) = 
-  inc(L.bufpos) # skip '
-  if L.buf[L.bufpos] == '\\':
-    escape(L, tok)
-  else:
-    add(tok.s, L.buf[L.bufpos])
-    inc(L.bufpos)
-  if L.buf[L.bufpos] == '\'':
-    inc(L.bufpos)
-  else:
-    lexMessage(L, errMissingFinalQuote)
-  tok.xkind = pxCharLit
-
-proc getString(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufPos + 1          # skip "
-  var buf = L.buf                 # put `buf` in a register
-  var line = L.linenumber         # save linenumber for better error message
-  while true: 
-    case buf[pos]
-    of '\"': 
-      inc(pos)
-      break
-    of CR: 
-      pos = nimlexbase.HandleCR(L, pos)
-      buf = L.buf
-    of LF: 
-      pos = nimlexbase.HandleLF(L, pos)
-      buf = L.buf
-    of nimlexbase.EndOfFile: 
-      var line2 = L.linenumber
-      L.LineNumber = line
-      lexMessagePos(L, errClosingQuoteExpected, L.lineStart)
-      L.LineNumber = line2
-      break 
-    of '\\': 
-      # we allow an empty \ for line concatenation, but we don't require it
-      # for line concatenation
-      L.bufpos = pos
-      escape(L, tok, allowEmpty=true)
-      pos = L.bufpos
-    else: 
-      add(tok.s, buf[pos])
-      inc(pos)
-  L.bufpos = pos
-  tok.xkind = pxStrLit
-
-proc getSymbol(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos
-  var buf = L.buf
-  while true: 
-    var c = buf[pos]
-    if c notin SymChars: break
-    add(tok.s, c)
-    inc(pos)
-  L.bufpos = pos
-  tok.xkind = pxSymbol
-
-proc scanLineComment(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos
-  var buf = L.buf 
-  # a comment ends if the next line does not start with the // on the same
-  # column after only whitespace
-  tok.xkind = pxLineComment
-  var col = getColNumber(L, pos)
-  while true: 
-    inc(pos, 2)               # skip //
-    add(tok.s, '#')
-    while not (buf[pos] in {CR, LF, nimlexbase.EndOfFile}): 
-      add(tok.s, buf[pos])
-      inc(pos)
-    pos = handleCRLF(L, pos)
-    buf = L.buf
-    var indent = 0
-    while buf[pos] == ' ': 
-      inc(pos)
-      inc(indent)
-    if (col == indent) and (buf[pos] == '/') and (buf[pos + 1] == '/'): 
-      add(tok.s, "\n")
-    else: 
-      break 
-  L.bufpos = pos
-
-proc scanStarComment(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos
-  var buf = L.buf
-  tok.s = "#"
-  tok.xkind = pxStarComment
-  while true: 
-    case buf[pos]
-    of CR, LF: 
-      pos = handleCRLF(L, pos)
-      buf = L.buf
-      add(tok.s, "\n#")
-      # skip annoying stars as line prefix: (eg.
-      # /*
-      #  * ugly comment <-- this star
-      #  */
-      while buf[pos] in {' ', '\t'}:
-        add(tok.s, ' ')
-        inc(pos)
-      if buf[pos] == '*' and buf[pos+1] != '/': inc(pos)
-    of '*': 
-      inc(pos)
-      if buf[pos] == '/': 
-        inc(pos)
-        break 
-      else: 
-        add(tok.s, '*')
-    of nimlexbase.EndOfFile: 
-      lexMessage(L, errTokenExpected, "*/")
-    else: 
-      add(tok.s, buf[pos])
-      inc(pos)
-  L.bufpos = pos
-
-proc skip(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos
-  var buf = L.buf
-  while true: 
-    case buf[pos]
-    of '\\': 
-      # Ignore \ line continuation characters when not inDirective
-      inc(pos)
-      if L.inDirective:
-        while buf[pos] in {' ', '\t'}: inc(pos)
-        if buf[pos] in {CR, LF}:
-          pos = handleCRLF(L, pos)
-          buf = L.buf
-    of ' ', Tabulator: 
-      inc(pos)                # newline is special:
-    of CR, LF: 
-      pos = handleCRLF(L, pos)
-      buf = L.buf
-      if L.inDirective:
-        tok.xkind = pxNewLine
-        L.inDirective = false
-    else: 
-      break                   # EndOfFile also leaves the loop
-  L.bufpos = pos
-
-proc getDirective(L: var TLexer, tok: var TToken) = 
-  var pos = L.bufpos + 1
-  var buf = L.buf
-  while buf[pos] in {' ', '\t'}: inc(pos)
-  while buf[pos] in SymChars: 
-    add(tok.s, buf[pos])
-    inc(pos)
-  # a HACK: we need to distinguish 
-  # #define x (...)
-  # from:
-  # #define x(...)
-  # 
-  L.bufpos = pos
-  # look ahead:
-  while buf[pos] in {' ', '\t'}: inc(pos)
-  while buf[pos] in SymChars: inc(pos)
-  if buf[pos] == '(': tok.xkind = pxDirectiveParLe
-  else: tok.xkind = pxDirective
-  L.inDirective = true
-
-proc getTok(L: var TLexer, tok: var TToken) = 
-  tok.xkind = pxInvalid
-  fillToken(tok)
-  skip(L, tok)
-  if tok.xkind == pxNewLine: return
-  var c = L.buf[L.bufpos]
-  if c in SymStartChars: 
-    getSymbol(L, tok)
-  elif c == '0':
-    case L.buf[L.bufpos+1]
-    of 'x', 'X': getNumber16(L, tok)
-    of 'b', 'B': getNumber2(L, tok)
-    of '1'..'7': getNumber8(L, tok)
-    else: getNumber(L, tok)
-  elif c in {'1'..'9'} or (c == '.' and L.buf[L.bufpos+1] in {'0'..'9'}): 
-    getNumber(L, tok)
-  else: 
-    case c
-    of ';': 
-      tok.xkind = pxSemicolon
-      inc(L.bufpos)
-    of '/': 
-      if L.buf[L.bufpos + 1] == '/': 
-        scanLineComment(L, tok)
-      elif L.buf[L.bufpos+1] == '*':
-        inc(L.bufpos, 2)
-        scanStarComment(L, tok)
-      elif L.buf[L.bufpos+1] == '=':
-        inc(L.bufpos, 2)
-        tok.xkind = pxSlashAsgn
-      else: 
-        tok.xkind = pxSlash
-        inc(L.bufpos)
-    of ',': 
-      tok.xkind = pxComma
-      inc(L.bufpos)
-    of '(': 
-      inc(L.bufpos)
-      tok.xkind = pxParLe
-    of '*': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        inc(L.bufpos)
-        tok.xkind = pxStarAsgn
-      else:
-        tok.xkind = pxStar
-    of ')': 
-      inc(L.bufpos)
-      tok.xkind = pxParRi
-    of '[': 
-      inc(L.bufpos)
-      tok.xkind = pxBracketLe
-    of ']': 
-      inc(L.bufpos)
-      tok.xkind = pxBracketRi
-    of '.': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '.' and L.buf[L.bufpos+1] == '.': 
-        tok.xkind = pxDotDotDot
-        inc(L.bufpos, 2)
-      else: 
-        tok.xkind = pxDot
-    of '{': 
-      inc(L.bufpos)
-      tok.xkind = pxCurlyLe
-    of '}': 
-      inc(L.bufpos)
-      tok.xkind = pxCurlyRi
-    of '+': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxPlusAsgn
-        inc(L.bufpos)
-      elif L.buf[L.bufpos] == '+': 
-        tok.xkind = pxPlusPlus
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxPlus
-    of '-': 
-      inc(L.bufpos)
-      case L.buf[L.bufpos] 
-      of '>':
-        tok.xkind = pxArrow
-        inc(L.bufpos)
-      of '=':
-        tok.xkind = pxMinusAsgn
-        inc(L.bufpos)
-      of '-': 
-        tok.xkind = pxMinusMinus
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxMinus
-    of '?':
-      inc(L.bufpos)
-      tok.xkind = pxConditional
-    of ':': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == ':':
-        tok.xkind = pxScope
-        inc(L.bufpos)
-      else:
-        tok.xkind = pxColon
-    of '!':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxNeq
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxNot
-    of '<': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=': 
-        inc(L.bufpos)
-        tok.xkind = pxLe
-      elif L.buf[L.bufpos] == '<':
-        inc(L.bufpos)
-        if L.buf[L.bufpos] == '=': 
-          inc(L.bufpos)
-          tok.xkind = pxShlAsgn
-        else:
-          tok.xkind = pxShl
-      else: 
-        tok.xkind = pxLt
-    of '>': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=': 
-        inc(L.bufpos)
-        tok.xkind = pxGe
-      elif L.buf[L.bufpos] == '>':
-        inc(L.bufpos)
-        if L.buf[L.bufpos] == '=': 
-          inc(L.bufpos)
-          tok.xkind = pxShrAsgn
-        else:
-          tok.xkind = pxShr
-      else: 
-        tok.xkind = pxGt
-    of '=': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxEquals
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxAsgn
-    of '&': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxAmpAsgn
-        inc(L.bufpos)
-      elif L.buf[L.bufpos] == '&':
-        inc(L.bufpos)
-        if L.buf[L.bufpos] == '=':
-          inc(L.bufpos)
-          tok.xkind = pxAmpAmpAsgn
-        else:
-          tok.xkind = pxAmpAmp
-      else: 
-        tok.xkind = pxAmp
-    of '|': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxBarAsgn
-        inc(L.bufpos)
-      elif L.buf[L.bufpos] == '|':
-        inc(L.bufpos)
-        if L.buf[L.bufpos] == '=':
-          inc(L.bufpos)
-          tok.xkind = pxBarBarAsgn
-        else:
-          tok.xkind = pxBarBar
-      else: 
-        tok.xkind = pxBar
-    of '^': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxHatAsgn
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxHat
-    of '%': 
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxModAsgn
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxMod
-    of '~':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        tok.xkind = pxTildeAsgn
-        inc(L.bufpos)
-      else: 
-        tok.xkind = pxTilde
-    of '#': 
-      if L.buf[L.bufpos+1] == '#':
-        inc(L.bufpos, 2)
-        tok.xkind = pxDirConc
-      else:
-        getDirective(L, tok)
-    of '"': getString(L, tok)
-    of '\'': getCharLit(L, tok)
-    of nimlexbase.EndOfFile: 
-      tok.xkind = pxEof
-    else: 
-      tok.s = $c
-      tok.xkind = pxInvalid
-      lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')')
-      inc(L.bufpos)
diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim
deleted file mode 100644
index 2e31af528..000000000
--- a/compiler/c2nim/cparse.nim
+++ /dev/null
@@ -1,2272 +0,0 @@
-#
-#
-#      c2nim - C to Nimrod source converter
-#        (c) Copyright 2013 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## This module implements an Ansi C parser.
-## It translates a C source file into a Nimrod AST. Then the renderer can be
-## used to convert the AST to its text representation.
-
-# TODO
-# - document 'cpp' mode
-# - implement handling of '::': function declarations
-# - C++'s "operator" still needs some love
-# - support '#if' in classes
-
-import 
-  os, llstream, renderer, clex, idents, strutils, pegs, ast, astalgo, msgs,
-  options, strtabs, hashes, algorithm
-
-type 
-  TParserFlag = enum
-    pfRefs,             ## use "ref" instead of "ptr" for C's typ*
-    pfCDecl,            ## annotate procs with cdecl
-    pfStdCall,          ## annotate procs with stdcall
-    pfSkipInclude,      ## skip all ``#include``
-    pfTypePrefixes,     ## all generated types start with 'T' or 'P'
-    pfSkipComments,     ## do not generate comments
-    pfCpp,              ## process C++
-    pfIgnoreRValueRefs, ## transform C++'s 'T&&' to 'T'
-    pfKeepBodies        ## do not skip C++ method bodies
-  
-  TMacro = object
-    name: string
-    params: int           # number of parameters
-    body: seq[ref TToken] # can contain pxMacroParam tokens
-  
-  TParserOptions = object
-    flags: set[TParserFlag]
-    prefixes, suffixes: seq[string]
-    mangleRules: seq[tuple[pattern: TPeg, frmt: string]]
-    privateRules: seq[TPeg]
-    dynlibSym, header: string
-    macros: seq[TMacro]
-    toMangle: PStringTable
-    classes: PStringTable
-  PParserOptions* = ref TParserOptions
-  
-  TParser* = object
-    lex: TLexer
-    tok: ref TToken       # current token
-    options: PParserOptions
-    backtrack: seq[ref TToken]
-    inTypeDef: int
-    scopeCounter: int
-    hasDeadCodeElimPragma: bool
-    currentClass: PNode   # type that needs to be added as 'this' parameter
-  
-  TReplaceTuple* = array[0..1, string]
-
-  ERetryParsing = object of ESynch
-
-
-
-proc addTypeDef(section, name, t: PNode)
-proc parseStruct(p: var TParser, stmtList: PNode, isUnion: bool): PNode
-proc parseStructBody(p: var TParser, stmtList: PNode, isUnion: bool,
-                     kind: TNodeKind = nkRecList): PNode
-
-
-
-proc newParserOptions*(): PParserOptions = 
-  new(result)
-  result.prefixes = @[]
-  result.suffixes = @[]
-  result.macros = @[]
-  result.mangleRules = @[]
-  result.privateRules = @[]
-  result.flags = {}
-  result.dynlibSym = ""
-  result.header = ""
-  result.toMangle = newStringTable(modeCaseSensitive)
-  result.classes = newStringTable(modeCaseSensitive)
-
-proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool = 
-  result = true
-  case key.normalize
-  of "ref": incl(parserOptions.flags, pfRefs)
-  of "dynlib": parserOptions.dynlibSym = val
-  of "header": parserOptions.header = val
-  of "cdecl": incl(parserOptions.flags, pfCdecl)
-  of "stdcall": incl(parserOptions.flags, pfStdCall)
-  of "prefix": parserOptions.prefixes.add(val)
-  of "suffix": parserOptions.suffixes.add(val)
-  of "skipinclude": incl(parserOptions.flags, pfSkipInclude)
-  of "typeprefixes": incl(parserOptions.flags, pfTypePrefixes)
-  of "skipcomments": incl(parserOptions.flags, pfSkipComments)
-  of "cpp": incl(parserOptions.flags, pfCpp)
-  of "keepbodies": incl(parserOptions.flags, pfKeepBodies)
-  of "ignorervaluerefs": incl(parserOptions.flags, pfIgnoreRValueRefs)
-  of "class": parserOptions.classes[val] = "true"
-  else: result = false
-
-proc parseUnit*(p: var TParser): PNode
-proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
-                 options = newParserOptions())
-proc closeParser*(p: var TParser)
-
-# implementation
-
-proc openParser(p: var TParser, filename: string, 
-                inputStream: PLLStream, options = newParserOptions()) = 
-  openLexer(p.lex, filename, inputStream)
-  p.options = options
-  p.backtrack = @[]
-  new(p.tok)
-
-proc parMessage(p: TParser, msg: TMsgKind, arg = "") = 
-  #assert false
-  lexMessage(p.lex, msg, arg)
-
-proc closeParser(p: var TParser) = closeLexer(p.lex)
-proc saveContext(p: var TParser) = p.backtrack.add(p.tok)
-proc closeContext(p: var TParser) = discard p.backtrack.pop()
-proc backtrackContext(p: var TParser) = p.tok = p.backtrack.pop()
-
-proc rawGetTok(p: var TParser) = 
-  if p.tok.next != nil:
-    p.tok = p.tok.next
-  elif p.backtrack.len == 0: 
-    p.tok.next = nil
-    getTok(p.lex, p.tok[])
-  else: 
-    # We need the next token and must be able to backtrack. So we need to 
-    # allocate a new token.
-    var t: ref TToken
-    new(t)
-    getTok(p.lex, t[])
-    p.tok.next = t
-    p.tok = t
-
-proc insertAngleRi(currentToken: ref TToken) = 
-  var t: ref TToken
-  new(t)
-  t.xkind = pxAngleRi
-  t.next = currentToken.next
-  currentToken.next = t
-
-proc findMacro(p: TParser): int =
-  for i in 0..high(p.options.macros):
-    if p.tok.s == p.options.macros[i].name: return i
-  return -1
-
-proc rawEat(p: var TParser, xkind: TTokKind) = 
-  if p.tok.xkind == xkind: rawGetTok(p)
-  else: parMessage(p, errTokenExpected, tokKindToStr(xkind))
-
-proc parseMacroArguments(p: var TParser): seq[seq[ref TToken]] = 
-  result = @[]
-  result.add(@[])
-  var i: array[pxParLe..pxCurlyLe, int]
-  var L = 0
-  saveContext(p)
-  while true:
-    var kind = p.tok.xkind
-    case kind
-    of pxEof: rawEat(p, pxParRi)
-    of pxParLe, pxBracketLe, pxCurlyLe: 
-      inc(i[kind])
-      result[L].add(p.tok)
-    of pxParRi:
-      # end of arguments?
-      if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0: break
-      if i[pxParLe] > 0: dec(i[pxParLe])
-      result[L].add(p.tok)
-    of pxBracketRi, pxCurlyRi:
-      kind = pred(kind, 3)
-      if i[kind] > 0: dec(i[kind])
-      result[L].add(p.tok)
-    of pxComma: 
-      if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0:
-        # next argument: comma is not part of the argument
-        result.add(@[])
-        inc(L)
-      else: 
-        # comma does not separate different arguments:
-        result[L].add(p.tok)
-    else:
-      result[L].add(p.tok)
-    rawGetTok(p)
-  closeContext(p)
-
-proc expandMacro(p: var TParser, m: TMacro) = 
-  rawGetTok(p) # skip macro name
-  var arguments: seq[seq[ref TToken]]
-  if m.params > 0:
-    rawEat(p, pxParLe)
-    arguments = parseMacroArguments(p)
-    if arguments.len != m.params: parMessage(p, errWrongNumberOfArguments)
-    rawEat(p, pxParRi)
-  # insert into the token list:
-  if m.body.len > 0:
-    var newList: ref TToken
-    new(newList)
-    var lastTok = newList
-    for tok in items(m.body): 
-      if tok.xkind == pxMacroParam: 
-        for t in items(arguments[int(tok.iNumber)]):
-          #echo "t: ", t^
-          lastTok.next = t
-          lastTok = t
-      else:
-        #echo "tok: ", tok^
-        lastTok.next = tok
-        lastTok = tok
-    lastTok.next = p.tok
-    p.tok = newList.next
-
-proc getTok(p: var TParser) = 
-  rawGetTok(p)
-  if p.tok.xkind == pxSymbol:
-    var idx = findMacro(p)
-    if idx >= 0: 
-      expandMacro(p, p.options.macros[idx])
-
-proc parLineInfo(p: TParser): TLineInfo = 
-  result = getLineInfo(p.lex)
-
-proc skipComAux(p: var TParser, n: PNode) =
-  if n != nil and n.kind != nkEmpty: 
-    if pfSkipComments notin p.options.flags:
-      if n.comment == nil: n.comment = p.tok.s
-      else: add(n.comment, "\n" & p.tok.s)
-  else: 
-    parMessage(p, warnCommentXIgnored, p.tok.s)
-  getTok(p)
-
-proc skipCom(p: var TParser, n: PNode) = 
-  while p.tok.xkind in {pxLineComment, pxStarComment}: skipComAux(p, n)
-
-proc skipStarCom(p: var TParser, n: PNode) = 
-  while p.tok.xkind == pxStarComment: skipComAux(p, n)
-
-proc getTok(p: var TParser, n: PNode) =
-  getTok(p)
-  skipCom(p, n)
-
-proc expectIdent(p: TParser) = 
-  if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok[]))
-  
-proc eat(p: var TParser, xkind: TTokKind, n: PNode) = 
-  if p.tok.xkind == xkind: getTok(p, n)
-  else: parMessage(p, errTokenExpected, tokKindToStr(xkind))
-  
-proc eat(p: var TParser, xkind: TTokKind) = 
-  if p.tok.xkind == xkind: getTok(p)
-  else: parMessage(p, errTokenExpected, tokKindToStr(xkind))
-  
-proc eat(p: var TParser, tok: string, n: PNode) = 
-  if p.tok.s == tok: getTok(p, n)
-  else: parMessage(p, errTokenExpected, tok)
-  
-proc opt(p: var TParser, xkind: TTokKind, n: PNode) = 
-  if p.tok.xkind == xkind: getTok(p, n)
-  
-proc addSon(father, a, b: PNode) = 
-  addSon(father, a)
-  addSon(father, b)
-
-proc addSon(father, a, b, c: PNode) = 
-  addSon(father, a)
-  addSon(father, b)
-  addSon(father, c)
-  
-proc newNodeP(kind: TNodeKind, p: TParser): PNode = 
-  result = newNodeI(kind, getLineInfo(p.lex))
-
-proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.intVal = intVal
-
-proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, 
-                   p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.floatVal = floatVal
-
-proc newStrNodeP(kind: TNodeKind, strVal: string, p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.strVal = strVal
-
-proc newIdentNodeP(ident: PIdent, p: TParser): PNode = 
-  result = newNodeP(nkIdent, p)
-  result.ident = ident
-
-proc newIdentNodeP(ident: string, p: TParser): PNode =
-  result = newIdentNodeP(getIdent(ident), p)
-
-proc mangleRules(s: string, p: TParser): string = 
-  block mangle:
-    for pattern, frmt in items(p.options.mangleRules):
-      if s.match(pattern):
-        result = s.replacef(pattern, frmt)
-        break mangle
-    block prefixes:
-      for prefix in items(p.options.prefixes): 
-        if s.startsWith(prefix): 
-          result = s.substr(prefix.len)
-          break prefixes
-      result = s
-    block suffixes:
-      for suffix in items(p.options.suffixes):
-        if result.endsWith(suffix):
-          setLen(result, result.len - suffix.len)
-          break suffixes
-
-proc mangleName(s: string, p: TParser): string = 
-  if p.options.toMangle.hasKey(s): result = p.options.toMangle[s]
-  else: result = mangleRules(s, p)
-
-proc isPrivate(s: string, p: TParser): bool = 
-  for pattern in items(p.options.privateRules): 
-    if s.match(pattern): return true
-
-proc mangledIdent(ident: string, p: TParser): PNode = 
-  result = newNodeP(nkIdent, p)
-  result.ident = getIdent(mangleName(ident, p))
-
-proc newIdentPair(a, b: string, p: TParser): PNode = 
-  result = newNodeP(nkExprColonExpr, p)
-  addSon(result, newIdentNodeP(a, p))
-  addSon(result, newIdentNodeP(b, p))
-
-proc newIdentStrLitPair(a, b: string, p: TParser): PNode =
-  result = newNodeP(nkExprColonExpr, p)
-  addSon(result, newIdentNodeP(a, p))
-  addSon(result, newStrNodeP(nkStrLit, b, p))
-
-proc addImportToPragma(pragmas: PNode, ident: string, p: TParser) =
-  addSon(pragmas, newIdentStrLitPair("importc", ident, p))
-  if p.options.dynlibSym.len > 0:
-    addSon(pragmas, newIdentPair("dynlib", p.options.dynlibSym, p))
-  else:
-    addSon(pragmas, newIdentStrLitPair("header", p.options.header, p))
-
-proc exportSym(p: TParser, i: PNode, origName: string): PNode = 
-  assert i.kind == nkIdent
-  if p.scopeCounter == 0 and not isPrivate(origName, p):
-    result = newNodeI(nkPostfix, i.info)
-    addSon(result, newIdentNode(getIdent("*"), i.info), i)
-  else:
-    result = i
-
-proc varIdent(ident: string, p: TParser): PNode = 
-  result = exportSym(p, mangledIdent(ident, p), ident)
-  if p.scopeCounter > 0: return
-  if p.options.dynlibSym.len > 0 or p.options.header.len > 0: 
-    var a = result
-    result = newNodeP(nkPragmaExpr, p)
-    var pragmas = newNodeP(nkPragma, p)
-    addSon(result, a)
-    addSon(result, pragmas)
-    addImportToPragma(pragmas, ident, p)
-
-proc fieldIdent(ident: string, p: TParser): PNode = 
-  result = exportSym(p, mangledIdent(ident, p), ident)
-  if p.scopeCounter > 0: return
-  if p.options.header.len > 0: 
-    var a = result
-    result = newNodeP(nkPragmaExpr, p)
-    var pragmas = newNodeP(nkPragma, p)
-    addSon(result, a)
-    addSon(result, pragmas)
-    addSon(pragmas, newIdentStrLitPair("importc", ident, p))
-
-proc doImport(ident: string, pragmas: PNode, p: TParser) = 
-  if p.options.dynlibSym.len > 0 or p.options.header.len > 0: 
-    addImportToPragma(pragmas, ident, p)
-
-proc doImportCpp(ident: string, pragmas: PNode, p: TParser) = 
-  if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
-    addSon(pragmas, newIdentStrLitPair("importcpp", ident, p))
-    if p.options.dynlibSym.len > 0:
-      addSon(pragmas, newIdentPair("dynlib", p.options.dynlibSym, p))
-    else:
-      addSon(pragmas, newIdentStrLitPair("header", p.options.header, p))
-
-proc newBinary(opr: string, a, b: PNode, p: TParser): PNode =
-  result = newNodeP(nkInfix, p)
-  addSon(result, newIdentNodeP(getIdent(opr), p))
-  addSon(result, a)
-  addSon(result, b)
-
-proc skipIdent(p: var TParser): PNode = 
-  expectIdent(p)
-  result = mangledIdent(p.tok.s, p)
-  getTok(p, result)
-
-proc skipIdentExport(p: var TParser): PNode = 
-  expectIdent(p)
-  result = exportSym(p, mangledIdent(p.tok.s, p), p.tok.s)
-  getTok(p, result)
-
-proc skipTypeIdentExport(p: var TParser, prefix='T'): PNode = 
-  expectIdent(p)
-  var n = prefix & mangleName(p.tok.s, p)
-  p.options.toMangle[p.tok.s] = n
-  var i = newNodeP(nkIdent, p)
-  i.ident = getIdent(n)
-  result = exportSym(p, i, p.tok.s)
-  getTok(p, result)
-
-proc markTypeIdent(p: var TParser, typ: PNode) = 
-  if pfTypePrefixes in p.options.flags:
-    var prefix = ""
-    if typ == nil or typ.kind == nkEmpty: 
-      prefix = "T"
-    else: 
-      var t = typ
-      while t != nil and t.kind in {nkVarTy, nkPtrTy, nkRefTy}: 
-        prefix.add('P')
-        t = t.sons[0]
-      if prefix.len == 0: prefix.add('T')
-    expectIdent(p)
-    p.options.toMangle[p.tok.s] = prefix & mangleRules(p.tok.s, p)
-  
-# --------------- parser -----------------------------------------------------
-# We use this parsing rule: If it looks like a declaration, it is one. This
-# avoids to build a symbol table, which can't be done reliably anyway for our
-# purposes.
-
-proc expression(p: var TParser, rbp: int = 0): PNode
-proc constantExpression(p: var TParser): PNode = expression(p, 40)
-proc assignmentExpression(p: var TParser): PNode = expression(p, 30)
-proc compoundStatement(p: var TParser): PNode
-proc statement(p: var TParser): PNode
-
-proc declKeyword(p: TParser, s: string): bool = 
-  # returns true if it is a keyword that introduces a declaration
-  case s
-  of  "extern", "static", "auto", "register", "const", "volatile", "restrict",
-      "inline", "__inline", "__cdecl", "__stdcall", "__syscall", "__fastcall",
-      "__safecall", "void", "struct", "union", "enum", "typedef",
-      "short", "int", "long", "float", "double", "signed", "unsigned", "char": 
-    result = true
-  of "class":
-    result = p.options.flags.contains(pfCpp)
-
-proc stmtKeyword(s: string): bool =
-  case s
-  of  "if", "for", "while", "do", "switch", "break", "continue", "return",
-      "goto":
-    result = true
-
-# ------------------- type desc -----------------------------------------------
-
-proc isIntType(s: string): bool =
-  case s
-  of "short", "int", "long", "float", "double", "signed", "unsigned":
-    result = true
-
-proc skipConst(p: var TParser) = 
-  while p.tok.xkind == pxSymbol and
-      (p.tok.s == "const" or p.tok.s == "volatile" or p.tok.s == "restrict"): 
-    getTok(p, nil)
-
-proc isTemplateAngleBracket(p: var TParser): bool =
-  if pfCpp notin p.options.flags: return false
-  saveContext(p)
-  getTok(p, nil) # skip "<"
-  var i: array[pxParLe..pxCurlyLe, int]
-  var angles = 0
-  while true:
-    let kind = p.tok.xkind
-    case kind
-    of pxEof: break
-    of pxParLe, pxBracketLe, pxCurlyLe: inc(i[kind])
-    of pxGt, pxAngleRi:
-      # end of arguments?
-      if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0 and
-          angles == 0:
-        # mark as end token:
-        p.tok.xkind = pxAngleRi
-        result = true; 
-        break
-      if angles > 0: dec(angles)
-    of pxShr:
-      # >> can end a template too:
-      if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0 and
-          angles == 1:
-        p.tok.xkind = pxAngleRi
-        insertAngleRi(p.tok)
-        result = true
-        break
-      if angles > 1: dec(angles, 2)
-    of pxLt: inc(angles)
-    of pxParRi, pxBracketRi, pxCurlyRi:
-      let kind = pred(kind, 3)
-      if i[kind] > 0: dec(i[kind])
-      else: break
-    of pxSemicolon: break
-    else: discard
-    getTok(p, nil)
-  backtrackContext(p)
-
-proc optAngle(p: var TParser, n: PNode): PNode =
-  if p.tok.xkind == pxLt and isTemplateAngleBracket(p):
-    getTok(p)
-    result = newNodeP(nkBracketExpr, p)
-    result.add(n)
-    while true:
-      let a = assignmentExpression(p)
-      if not a.isNil: result.add(a)
-      if p.tok.xkind != pxComma: break
-      getTok(p)
-    eat(p, pxAngleRi)
-  else:
-    result = n
-
-proc optScope(p: var TParser, n: PNode): PNode =
-  result = n
-  if pfCpp in p.options.flags:
-    while p.tok.xkind == pxScope:
-      let a = result
-      result = newNodeP(nkDotExpr, p)
-      result.add(a)
-      getTok(p, result)
-      expectIdent(p)
-      result.add(mangledIdent(p.tok.s, p))
-      getTok(p, result)
-
-proc typeAtom(p: var TParser): PNode = 
-  skipConst(p)
-  expectIdent(p)
-  case p.tok.s
-  of "void": 
-    result = newNodeP(nkNilLit, p) # little hack
-    getTok(p, nil)
-  of "struct", "union", "enum": 
-    getTok(p, nil)
-    result = skipIdent(p)
-  elif isIntType(p.tok.s):
-    var x = ""
-    #getTok(p, nil)
-    var isUnsigned = false
-    while p.tok.xkind == pxSymbol and (isIntType(p.tok.s) or p.tok.s == "char"):
-      if p.tok.s == "unsigned":
-        isUnsigned = true
-      elif p.tok.s == "signed" or p.tok.s == "int":
-        discard
-      else:
-        add(x, p.tok.s)
-      getTok(p, nil)
-    if x.len == 0: x = "int"
-    let xx = if isUnsigned: "cu" & x else: "c" & x
-    result = mangledIdent(xx, p)
-  else:
-    result = mangledIdent(p.tok.s, p)
-    getTok(p, result)
-    result = optScope(p, result)
-    result = optAngle(p, result)
-    
-proc newPointerTy(p: TParser, typ: PNode): PNode =
-  if pfRefs in p.options.flags: 
-    result = newNodeP(nkRefTy, p)
-  else:
-    result = newNodeP(nkPtrTy, p)
-  result.addSon(typ)
-
-proc pointer(p: var TParser, a: PNode): PNode = 
-  result = a
-  var i = 0
-  skipConst(p)
-  while true:
-    if p.tok.xkind == pxStar:
-      inc(i)
-      getTok(p, result)
-      skipConst(p)
-      result = newPointerTy(p, result)
-    elif p.tok.xkind == pxAmp and pfCpp in p.options.flags:
-      getTok(p, result)
-      skipConst(p)
-      let b = result
-      result = newNodeP(nkVarTy, p)
-      result.add(b)
-    elif p.tok.xkind == pxAmpAmp and pfCpp in p.options.flags:
-      getTok(p, result)
-      skipConst(p)
-      if pfIgnoreRvalueRefs notin p.options.flags:
-        let b = result
-        result = newNodeP(nkVarTy, p)
-        result.add(b)
-    else: break
-  if a.kind == nkIdent and a.ident.s == "char": 
-    if i >= 2: 
-      result = newIdentNodeP("cstringArray", p)
-      for j in 1..i-2: result = newPointerTy(p, result)
-    elif i == 1: result = newIdentNodeP("cstring", p)
-  elif a.kind == nkNilLit and i > 0:
-    result = newIdentNodeP("pointer", p)
-    for j in 1..i-1: result = newPointerTy(p, result)
-
-proc newProcPragmas(p: TParser): PNode =
-  result = newNodeP(nkPragma, p)
-  if pfCDecl in p.options.flags: 
-    addSon(result, newIdentNodeP("cdecl", p))
-  elif pfStdCall in p.options.flags:
-    addSon(result, newIdentNodeP("stdcall", p))
-
-proc addPragmas(father, pragmas: PNode) =
-  if sonsLen(pragmas) > 0: addSon(father, pragmas)
-  else: addSon(father, ast.emptyNode)
-
-proc addReturnType(params, rettyp: PNode) =
-  if rettyp == nil: addSon(params, ast.emptyNode)
-  elif rettyp.kind != nkNilLit: addSon(params, rettyp)
-  else: addSon(params, ast.emptyNode)
-
-proc parseFormalParams(p: var TParser, params, pragmas: PNode)
-
-proc parseTypeSuffix(p: var TParser, typ: PNode): PNode = 
-  result = typ
-  while true:
-    case p.tok.xkind 
-    of pxBracketLe:
-      getTok(p, result)
-      skipConst(p) # POSIX contains: ``int [restrict]``
-      if p.tok.xkind != pxBracketRi:
-        var tmp = result
-        var index = expression(p)
-        # array type:
-        result = newNodeP(nkBracketExpr, p)
-        addSon(result, newIdentNodeP("array", p))
-        #var r = newNodeP(nkRange, p)
-        #addSon(r, newIntNodeP(nkIntLit, 0, p))
-        #addSon(r, newBinary("-", index, newIntNodeP(nkIntLit, 1, p), p))
-        #addSon(result, r)
-        addSon(result, index)
-        addSon(result, tmp)
-      else:
-        # pointer type:
-        var tmp = result
-        if pfRefs in p.options.flags: 
-          result = newNodeP(nkRefTy, p)
-        else:
-          result = newNodeP(nkPtrTy, p)
-        result.addSon(tmp)
-      eat(p, pxBracketRi, result)
-    of pxParLe:
-      # function pointer:
-      var procType = newNodeP(nkProcTy, p)
-      var pragmas = newProcPragmas(p)
-      var params = newNodeP(nkFormalParams, p)
-      addReturnType(params, result)
-      parseFormalParams(p, params, pragmas)
-      addSon(procType, params)
-      addPragmas(procType, pragmas)
-      result = procType
-    else: break
-
-proc typeDesc(p: var TParser): PNode = 
-  result = pointer(p, typeAtom(p))
-
-proc abstractDeclarator(p: var TParser, a: PNode): PNode
-
-proc directAbstractDeclarator(p: var TParser, a: PNode): PNode =
-  if p.tok.xkind == pxParLe:
-    getTok(p, a)
-    if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp}:
-      result = abstractDeclarator(p, a)
-      eat(p, pxParRi, result)
-  return parseTypeSuffix(p, a)
-
-proc abstractDeclarator(p: var TParser, a: PNode): PNode =
-  return directAbstractDeclarator(p, pointer(p, a))
-
-proc typeName(p: var TParser): PNode =
-  return abstractDeclarator(p, typeAtom(p))
-
-proc parseField(p: var TParser, kind: TNodeKind): PNode =
-  if p.tok.xkind == pxParLe: 
-    getTok(p, nil)
-    while p.tok.xkind == pxStar: getTok(p, nil)
-    result = parseField(p, kind)
-    eat(p, pxParRi, result)
-  else: 
-    expectIdent(p)
-    if kind == nkRecList: result = fieldIdent(p.tok.s, p) 
-    else: result = mangledIdent(p.tok.s, p)
-    getTok(p, result)
-
-proc structPragmas(p: TParser, name: PNode, origName: string): PNode = 
-  assert name.kind == nkIdent
-  result = newNodeP(nkPragmaExpr, p)
-  addSon(result, exportSym(p, name, origName))
-  var pragmas = newNodeP(nkPragma, p)
-  #addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p))
-  if p.options.header.len > 0:
-    addSon(pragmas, newIdentStrLitPair("importc", origName, p),
-                    newIdentStrLitPair("header", p.options.header, p))
-  if pragmas.len > 0: addSon(result, pragmas)
-  else: addSon(result, ast.emptyNode)
-
-proc hashPosition(p: TParser): string =
-  let lineInfo = parLineInfo(p)
-  let fileInfo = fileInfos[lineInfo.fileIndex]
-  result = $hash(fileInfo.shortName & "_" & $lineInfo.line & "_" & $lineInfo.col).uint
-
-proc parseInnerStruct(p: var TParser, stmtList: PNode, isUnion: bool): PNode =
-  getTok(p, nil)
-  if p.tok.xkind != pxCurlyLe:
-    parMessage(p, errUser, "Expected '{' but found '" & $(p.tok[]) & "'")
-  
-  let structName =  if isUnion: "INNER_C_UNION_" & p.hashPosition
-                    else: "INNER_C_STRUCT_" & p.hashPosition
-  let typeSection = newNodeP(nkTypeSection, p)
-  let newStruct = newNodeP(nkObjectTy, p)
-  var pragmas = ast.emptyNode
-  if isUnion:
-    pragmas = newNodeP(nkPragma, p)
-    addSon(pragmas, newIdentNodeP("union", p))
-  addSon(newStruct, pragmas, ast.emptyNode) # no inheritance 
-  result = newNodeP(nkIdent, p)
-  result.ident = getIdent(structName)
-  let struct = parseStructBody(p, stmtList, isUnion)
-  let defName = newNodeP(nkIdent, p)
-  defName.ident = getIdent(structName)
-  addSon(newStruct, struct)
-  addTypeDef(typeSection, structPragmas(p, defName, "no_name"), newStruct)
-  addSon(stmtList, typeSection)
-
-proc parseStructBody(p: var TParser, stmtList: PNode, isUnion: bool,
-                     kind: TNodeKind = nkRecList): PNode =
-  result = newNodeP(kind, p)
-  eat(p, pxCurlyLe, result)
-  while p.tok.xkind notin {pxEof, pxCurlyRi}:
-    skipConst(p)
-    var baseTyp: PNode
-    if p.tok.xkind == pxSymbol and (p.tok.s == "struct" or p.tok.s == "union"):
-      let gotUnion = if p.tok.s == "union": true   else: false
-      saveContext(p)
-      getTok(p, nil)
-      if p.tok.xkind == pxSymbol:
-        backtrackContext(p)
-        baseTyp = typeAtom(p)
-      else:
-        backtrackContext(p)
-        baseTyp = parseInnerStruct(p, stmtList, gotUnion)
-        if p.tok.xkind == pxSemiColon:
-          let def = newNodeP(nkIdentDefs, p)
-          var t = pointer(p, baseTyp)
-          let i = fieldIdent("ano_" & p.hashPosition, p)
-          t = parseTypeSuffix(p, t)
-          addSon(def, i, t, ast.emptyNode)
-          addSon(result, def)
-          getTok(p, nil)
-          continue
-    else:
-      baseTyp = typeAtom(p)
-    
-    while true:
-      var def = newNodeP(nkIdentDefs, p)
-      var t = pointer(p, baseTyp)
-      var i = parseField(p, kind)
-      t = parseTypeSuffix(p, t)
-      addSon(def, i, t, ast.emptyNode)
-      addSon(result, def)
-      if p.tok.xkind != pxComma: break
-      getTok(p, def)
-    eat(p, pxSemicolon, lastSon(result))
-  eat(p, pxCurlyRi, result)
-
-proc enumPragmas(p: TParser, name: PNode): PNode =
-  result = newNodeP(nkPragmaExpr, p)
-  addSon(result, name)
-  var pragmas = newNodeP(nkPragma, p)
-  var e = newNodeP(nkExprColonExpr, p)
-  # HACK: sizeof(cint) should be constructed as AST
-  addSon(e, newIdentNodeP("size", p), newIdentNodeP("sizeof(cint)", p))
-  addSon(pragmas, e)
-  addSon(result, pragmas)
-
-proc parseStruct(p: var TParser, stmtList: PNode, isUnion: bool): PNode =
-  result = newNodeP(nkObjectTy, p)
-  var pragmas = ast.emptyNode
-  if isUnion:
-    pragmas = newNodeP(nkPragma, p)
-    addSon(pragmas, newIdentNodeP("union", p))
-  addSon(result, pragmas, ast.emptyNode) # no inheritance 
-  if p.tok.xkind == pxCurlyLe:
-    addSon(result, parseStructBody(p, stmtList, isUnion))
-  else: 
-    addSon(result, newNodeP(nkRecList, p))
-
-proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode
-
-proc directDeclarator(p: var TParser, a: PNode, ident: ptr PNode): PNode =
-  case p.tok.xkind
-  of pxSymbol:
-    ident[] = skipIdent(p)
-  of pxParLe:
-    getTok(p, a)
-    if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp, pxSymbol}:
-      result = declarator(p, a, ident)
-      eat(p, pxParRi, result)
-  else:
-    discard
-  return parseTypeSuffix(p, a)
-
-proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode =
-  return directDeclarator(p, pointer(p, a), ident)
-
-# parameter-declaration
-#   declaration-specifiers declarator
-#   declaration-specifiers asbtract-declarator(opt)
-proc parseParam(p: var TParser, params: PNode) = 
-  var typ = typeDesc(p)
-  # support for ``(void)`` parameter list: 
-  if typ.kind == nkNilLit and p.tok.xkind == pxParRi: return
-  var name: PNode
-  typ = declarator(p, typ, addr name)
-  if name == nil:
-    var idx = sonsLen(params)+1
-    name = newIdentNodeP("a" & $idx, p)
-  var x = newNodeP(nkIdentDefs, p)
-  addSon(x, name, typ)
-  if p.tok.xkind == pxAsgn: 
-    # we support default parameters for C++:
-    getTok(p, x)
-    addSon(x, assignmentExpression(p))
-  else:
-    addSon(x, ast.emptyNode)
-  addSon(params, x)
-
-proc parseFormalParams(p: var TParser, params, pragmas: PNode) = 
-  eat(p, pxParLe, params)
-  while p.tok.xkind notin {pxEof, pxParRi}:
-    if p.tok.xkind == pxDotDotDot:  
-      addSon(pragmas, newIdentNodeP("varargs", p))
-      getTok(p, pragmas)
-      break
-    parseParam(p, params)
-    if p.tok.xkind != pxComma: break
-    getTok(p, params)
-  eat(p, pxParRi, params)
-
-proc parseCallConv(p: var TParser, pragmas: PNode) = 
-  while p.tok.xkind == pxSymbol:
-    case p.tok.s
-    of "inline", "__inline": addSon(pragmas, newIdentNodeP("inline", p))
-    of "__cdecl": addSon(pragmas, newIdentNodeP("cdecl", p))
-    of "__stdcall": addSon(pragmas, newIdentNodeP("stdcall", p))
-    of "__syscall": addSon(pragmas, newIdentNodeP("syscall", p))
-    of "__fastcall": addSon(pragmas, newIdentNodeP("fastcall", p))
-    of "__safecall": addSon(pragmas, newIdentNodeP("safecall", p))
-    else: break
-    getTok(p, nil)
-
-proc parseFunctionPointerDecl(p: var TParser, rettyp: PNode): PNode = 
-  var procType = newNodeP(nkProcTy, p)
-  var pragmas = newProcPragmas(p)
-  var params = newNodeP(nkFormalParams, p)
-  eat(p, pxParLe, params)
-  addReturnType(params, rettyp)
-  parseCallConv(p, pragmas)
-  if p.tok.xkind == pxStar: getTok(p, params)
-  else: parMessage(p, errTokenExpected, "*")
-  if p.inTypeDef > 0: markTypeIdent(p, nil)
-  var name = skipIdentExport(p)
-  eat(p, pxParRi, name)
-  parseFormalParams(p, params, pragmas)
-  addSon(procType, params)
-  addPragmas(procType, pragmas)
-  
-  if p.inTypeDef == 0:
-    result = newNodeP(nkVarSection, p)
-    var def = newNodeP(nkIdentDefs, p)
-    addSon(def, name, procType, ast.emptyNode)
-    addSon(result, def)    
-  else:
-    result = newNodeP(nkTypeDef, p)
-    addSon(result, name, ast.emptyNode, procType)
-  assert result != nil
-  
-proc addTypeDef(section, name, t: PNode) = 
-  var def = newNodeI(nkTypeDef, name.info)
-  addSon(def, name, ast.emptyNode, t)
-  addSon(section, def)
-  
-proc otherTypeDef(p: var TParser, section, typ: PNode) = 
-  var name: PNode
-  var t = typ
-  if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp}:
-    t = pointer(p, t)
-  if p.tok.xkind == pxParLe: 
-    # function pointer: typedef typ (*name)();
-    var x = parseFunctionPointerDecl(p, t)
-    name = x[0]
-    t = x[2]
-  else: 
-    # typedef typ name;
-    markTypeIdent(p, t)
-    name = skipIdentExport(p)
-  t = parseTypeSuffix(p, t)
-  addTypeDef(section, name, t)
-
-proc parseTrailingDefinedTypes(p: var TParser, section, typ: PNode) = 
-  while p.tok.xkind == pxComma:
-    getTok(p, nil)
-    var newTyp = pointer(p, typ)
-    markTypeIdent(p, newTyp)
-    var newName = skipIdentExport(p)
-    newTyp = parseTypeSuffix(p, newTyp)
-    addTypeDef(section, newName, newTyp)
-
-proc createConst(name, typ, val: PNode, p: TParser): PNode =
-  result = newNodeP(nkConstDef, p)
-  addSon(result, name, typ, val)
-
-proc exprToNumber(n: PNode not nil): tuple[succ: bool, val: BiggestInt] =
-  result = (false, 0.BiggestInt)
-  case n.kind:
-  of nkPrefix:
-    # Check for negative/positive numbers  -3  or  +6
-    if n.sons.len == 2 and n.sons[0].kind == nkIdent and n.sons[1].kind == nkIntLit:
-      let pre = n.sons[0]
-      let num = n.sons[1]
-      if pre.ident.s == "-": result = (true, - num.intVal)
-      elif pre.ident.s == "+": result = (true, num.intVal)
-  else: discard
-
-proc enumFields(p: var TParser, constList: PNode): PNode = 
-  result = newNodeP(nkEnumTy, p)
-  addSon(result, ast.emptyNode) # enum does not inherit from anything
-  var i: BiggestInt = 0
-  var field: tuple[id: BiggestInt, isNumber: bool, node: PNode]
-  var fields = newSeq[type(field)]()
-  while true:
-    var e = skipIdent(p)
-    if p.tok.xkind == pxAsgn: 
-      getTok(p, e)
-      var c = constantExpression(p)
-      var a = e
-      e = newNodeP(nkEnumFieldDef, p)
-      addSon(e, a, c)
-      skipCom(p, e)
-      if c.kind == nkIntLit:
-        i = c.intVal
-        field.isNumber = true
-      else:
-        var (success, number) = exprToNumber(c)
-        if success:
-          i = number
-          field.isNumber = true
-        else:
-          field.isNumber = false
-    else:
-      inc(i)
-      field.isNumber = true
-    field.id = i
-    field.node = e
-    fields.add(field)
-    if p.tok.xkind != pxComma: break
-    getTok(p, e)
-    # allow trailing comma:
-    if p.tok.xkind == pxCurlyRi: break
-  fields.sort do (x, y: type(field)) -> int:
-    cmp(x.id, y.id)
-  var lastId: BiggestInt
-  var lastIdent: PNode
-  for count, f in fields:
-    if not f.isNumber:
-      addSon(result, f.node)
-    elif f.id == lastId and count > 0:
-      var currentIdent: PNode
-      case f.node.kind:
-      of nkEnumFieldDef:
-        if f.node.sons.len > 0 and f.node.sons[0].kind == nkIdent:
-          currentIdent = f.node.sons[0]
-        else: parMessage(p, errGenerated, "Warning: When sorting enum fields an expected nkIdent was not found. Check the fields!")
-      of nkIdent: currentIdent = f.node
-      else: parMessage(p, errGenerated, "Warning: When sorting enum fields an expected nkIdent was not found. Check the fields!")
-      var constant = createConst( currentIdent, ast.emptyNode, lastIdent, p)
-      constList.addSon(constant)
-    else:
-      addSon(result, f.node)
-      lastId = f.id
-      case f.node.kind:
-      of nkEnumFieldDef:
-        if f.node.sons.len > 0 and f.node.sons[0].kind == nkIdent:
-          lastIdent = f.node.sons[0]
-        else: parMessage(p, errGenerated, "Warning: When sorting enum fields an expected nkIdent was not found. Check the fields!")
-      of nkIdent: lastIdent = f.node
-      else: parMessage(p, errGenerated, "Warning: When sorting enum fields an expected nkIdent was not found. Check the fields!")
-
-proc parseTypedefStruct(p: var TParser, result: PNode, stmtList: PNode, isUnion: bool) = 
-  getTok(p, result)
-  if p.tok.xkind == pxCurlyLe:
-    var t = parseStruct(p, stmtList, isUnion)
-    var origName = p.tok.s
-    markTypeIdent(p, nil)
-    var name = skipIdent(p)
-    addTypeDef(result, structPragmas(p, name, origName), t)
-    parseTrailingDefinedTypes(p, result, name)
-  elif p.tok.xkind == pxSymbol: 
-    # name to be defined or type "struct a", we don't know yet:
-    markTypeIdent(p, nil)
-    var origName = p.tok.s
-    var nameOrType = skipIdent(p)
-    case p.tok.xkind 
-    of pxCurlyLe:
-      var t = parseStruct(p, stmtList, isUnion)
-      if p.tok.xkind == pxSymbol: 
-        # typedef struct tagABC {} abc, *pabc;
-        # --> abc is a better type name than tagABC!
-        markTypeIdent(p, nil)
-        var origName = p.tok.s
-        var name = skipIdent(p)
-        addTypeDef(result, structPragmas(p, name, origName), t)
-        parseTrailingDefinedTypes(p, result, name)
-      else:
-        addTypeDef(result, structPragmas(p, nameOrType, origName), t)
-    of pxSymbol: 
-      # typedef struct a a?
-      if mangleName(p.tok.s, p) == nameOrType.ident.s:
-        # ignore the declaration:
-        getTok(p, nil)
-      else:
-        # typedef struct a b; or typedef struct a b[45];
-        otherTypeDef(p, result, nameOrType)
-    else: 
-      otherTypeDef(p, result, nameOrType)
-  else:
-    expectIdent(p)
-
-proc parseTypedefEnum(p: var TParser, result, constSection: PNode) = 
-  getTok(p, result)
-  if p.tok.xkind == pxCurlyLe:
-    getTok(p, result)
-    var t = enumFields(p, constSection)
-    eat(p, pxCurlyRi, t)
-    var origName = p.tok.s
-    markTypeIdent(p, nil)
-    var name = skipIdent(p)
-    addTypeDef(result, enumPragmas(p, exportSym(p, name, origName)), t)
-    parseTrailingDefinedTypes(p, result, name)
-  elif p.tok.xkind == pxSymbol: 
-    # name to be defined or type "enum a", we don't know yet:
-    markTypeIdent(p, nil)
-    var origName = p.tok.s
-    var nameOrType = skipIdent(p)
-    case p.tok.xkind 
-    of pxCurlyLe:
-      getTok(p, result)
-      var t = enumFields(p, constSection)
-      eat(p, pxCurlyRi, t)
-      if p.tok.xkind == pxSymbol: 
-        # typedef enum tagABC {} abc, *pabc;
-        # --> abc is a better type name than tagABC!
-        markTypeIdent(p, nil)
-        var origName = p.tok.s
-        var name = skipIdent(p)
-        addTypeDef(result, enumPragmas(p, exportSym(p, name, origName)), t)
-        parseTrailingDefinedTypes(p, result, name)
-      else:
-        addTypeDef(result, 
-                   enumPragmas(p, exportSym(p, nameOrType, origName)), t)
-    of pxSymbol: 
-      # typedef enum a a?
-      if mangleName(p.tok.s, p) == nameOrType.ident.s:
-        # ignore the declaration:
-        getTok(p, nil)
-      else:
-        # typedef enum a b; or typedef enum a b[45];
-        otherTypeDef(p, result, nameOrType)
-    else: 
-      otherTypeDef(p, result, nameOrType)
-  else:
-    expectIdent(p)
-
-proc parseTypeDef(p: var TParser): PNode =  
-  result = newNodeP(nkStmtList, p)
-  var typeSection = newNodeP(nkTypeSection, p)
-  var afterStatements = newNodeP(nkStmtList, p)
-  while p.tok.xkind == pxSymbol and p.tok.s == "typedef":
-    getTok(p, typeSection)
-    inc(p.inTypeDef)
-    expectIdent(p)
-    case p.tok.s
-    of "struct": parseTypedefStruct(p, typeSection, result, isUnion=false)
-    of "union": parseTypedefStruct(p, typeSection, result, isUnion=true)
-    of "enum":
-      var constSection = newNodeP(nkConstSection, p)
-      parseTypedefEnum(p, typeSection, constSection)
-      addSon(afterStatements, constSection)
-    of "class":
-      if pfCpp in p.options.flags:
-        parseTypedefStruct(p, typeSection, result, isUnion=false)
-      else:
-        var t = typeAtom(p)
-        otherTypeDef(p, typeSection, t)
-    else: 
-      var t = typeAtom(p)
-      otherTypeDef(p, typeSection, t)
-    eat(p, pxSemicolon)
-    dec(p.inTypeDef)
-  
-  addSon(result, typeSection)
-  for s in afterStatements:
-    addSon(result, s)
-  
-proc skipDeclarationSpecifiers(p: var TParser) =
-  while p.tok.xkind == pxSymbol:
-    case p.tok.s
-    of "extern", "static", "auto", "register", "const", "volatile": 
-      getTok(p, nil)
-    else: break
-
-proc parseInitializer(p: var TParser): PNode = 
-  if p.tok.xkind == pxCurlyLe: 
-    result = newNodeP(nkBracket, p)
-    getTok(p, result)
-    while p.tok.xkind notin {pxEof, pxCurlyRi}: 
-      addSon(result, parseInitializer(p))
-      opt(p, pxComma, nil)
-    eat(p, pxCurlyRi, result)
-  else:
-    result = assignmentExpression(p)
-
-proc addInitializer(p: var TParser, def: PNode) = 
-  if p.tok.xkind == pxAsgn:
-    getTok(p, def)
-    addSon(def, parseInitializer(p))
-  else:
-    addSon(def, ast.emptyNode)  
-
-proc parseVarDecl(p: var TParser, baseTyp, typ: PNode, 
-                  origName: string): PNode =  
-  result = newNodeP(nkVarSection, p)
-  var def = newNodeP(nkIdentDefs, p)
-  addSon(def, varIdent(origName, p))
-  addSon(def, parseTypeSuffix(p, typ))
-  addInitializer(p, def)
-  addSon(result, def)
-    
-  while p.tok.xkind == pxComma: 
-    getTok(p, def)
-    var t = pointer(p, baseTyp)
-    expectIdent(p)
-    def = newNodeP(nkIdentDefs, p)
-    addSon(def, varIdent(p.tok.s, p))
-    getTok(p, def)
-    addSon(def, parseTypeSuffix(p, t))
-    addInitializer(p, def)
-    addSon(result, def)
-  eat(p, pxSemicolon)
-
-proc declarationName(p: var TParser): string =
-  expectIdent(p)
-  result = p.tok.s
-  getTok(p) # skip identifier
-  while p.tok.xkind == pxScope and pfCpp in p.options.flags:
-    getTok(p) # skip "::"
-    expectIdent(p)
-    result.add("::")
-    result.add(p.tok.s)
-    getTok(p)
-
-proc declaration(p: var TParser): PNode = 
-  result = newNodeP(nkProcDef, p)
-  var pragmas = newNodeP(nkPragma, p)
-  
-  skipDeclarationSpecifiers(p)
-  parseCallConv(p, pragmas)
-  skipDeclarationSpecifiers(p)
-  expectIdent(p)
-  var baseTyp = typeAtom(p)
-  var rettyp = pointer(p, baseTyp)
-  skipDeclarationSpecifiers(p)
-  parseCallConv(p, pragmas)
-  skipDeclarationSpecifiers(p)
-  
-  if p.tok.xkind == pxParLe: 
-    # Function pointer declaration: This is of course only a heuristic, but the
-    # best we can do here.
-    result = parseFunctionPointerDecl(p, rettyp)
-    eat(p, pxSemicolon)
-    return
-  var origName = declarationName(p)
-  case p.tok.xkind
-  of pxParLe:
-    # really a function!
-    var name = mangledIdent(origName, p)
-    var params = newNodeP(nkFormalParams, p)
-    addReturnType(params, rettyp)
-    parseFormalParams(p, params, pragmas)
-    if pfCpp in p.options.flags and p.tok.xkind == pxSymbol and
-        p.tok.s == "const":
-      addSon(pragmas, newIdentNodeP("noSideEffect", p))
-      getTok(p)
-    if pfCDecl in p.options.flags:
-      addSon(pragmas, newIdentNodeP("cdecl", p))
-    elif pfStdcall in p.options.flags:
-      addSon(pragmas, newIdentNodeP("stdcall", p))
-    # no pattern, no exceptions:
-    addSon(result, exportSym(p, name, origName), ast.emptyNode, ast.emptyNode)
-    addSon(result, params, pragmas, ast.emptyNode) # no exceptions
-    case p.tok.xkind 
-    of pxSemicolon: 
-      getTok(p)
-      addSon(result, ast.emptyNode) # nobody
-      if p.scopeCounter == 0: doImport(origName, pragmas, p)
-    of pxCurlyLe:
-      addSon(result, compoundStatement(p))
-    else:
-      parMessage(p, errTokenExpected, ";")
-    if sonsLen(result.sons[pragmasPos]) == 0: 
-      result.sons[pragmasPos] = ast.emptyNode
-  else:
-    result = parseVarDecl(p, baseTyp, rettyp, origName)
-  assert result != nil
-
-proc enumSpecifier(p: var TParser): PNode =  
-  saveContext(p)
-  getTok(p, nil) # skip "enum"
-  case p.tok.xkind
-  of pxCurlyLe: 
-    closeContext(p)
-    # make a const section out of it:
-    result = newNodeP(nkConstSection, p)
-    getTok(p, result)
-    var i = 0
-    var hasUnknown = false
-    while true:
-      var name = skipIdentExport(p)
-      var val: PNode
-      if p.tok.xkind == pxAsgn: 
-        getTok(p, name)
-        val = constantExpression(p)
-        if val.kind == nkIntLit:  
-          i = int(val.intVal)+1
-          hasUnknown = false
-        else:
-          hasUnknown = true
-      else:
-        if hasUnknown:
-          parMessage(p, warnUser, "computed const value may be wrong: " &
-            name.renderTree)
-        val = newIntNodeP(nkIntLit, i, p)
-        inc(i)
-      var c = createConst(name, ast.emptyNode, val, p)
-      addSon(result, c)
-      if p.tok.xkind != pxComma: break
-      getTok(p, c)
-      # allow trailing comma:
-      if p.tok.xkind == pxCurlyRi: break
-    eat(p, pxCurlyRi, result)
-    eat(p, pxSemicolon)
-  of pxSymbol: 
-    var origName = p.tok.s
-    markTypeIdent(p, nil)
-    result = skipIdent(p)
-    case p.tok.xkind 
-    of pxCurlyLe: 
-      closeContext(p)
-      var name = result
-      # create a type section containing the enum
-      result = newNodeP(nkStmtList, p)
-      var tSection = newNodeP(nkTypeSection, p)
-      var t = newNodeP(nkTypeDef, p)
-      getTok(p, t)
-      var constSection = newNodeP(nkConstSection, p)
-      var e = enumFields(p, constSection)
-      addSon(t, exportSym(p, name, origName), ast.emptyNode, e)
-      addSon(tSection, t)
-      addSon(result, tSection)
-      addSon(result, constSection)
-      eat(p, pxCurlyRi, result)
-      eat(p, pxSemicolon)
-    of pxSemicolon:
-      # just ignore ``enum X;`` for now.
-      closeContext(p)
-      getTok(p, nil)
-    else: 
-      backtrackContext(p)
-      result = declaration(p)
-  else:
-    closeContext(p)
-    parMessage(p, errTokenExpected, "{")
-    result = ast.emptyNode
-    
-# Expressions
-
-proc setBaseFlags(n: PNode, base: TNumericalBase) = 
-  case base
-  of base10: discard
-  of base2: incl(n.flags, nfBase2)
-  of base8: incl(n.flags, nfBase8)
-  of base16: incl(n.flags, nfBase16)
-
-proc startExpression(p : var TParser, tok : TToken) : PNode =
-  #echo "nud ", $tok
-  case tok.xkind:
-  of pxSymbol:
-    if tok.s == "NULL":
-      result = newNodeP(nkNilLit, p)
-    elif tok.s == "sizeof":
-      result = newNodeP(nkCall, p)
-      addSon(result, newIdentNodeP("sizeof", p))
-      saveContext(p)
-      try:
-        addSon(result, expression(p, 139))
-        closeContext(p)
-      except ERetryParsing:
-        backtrackContext(p)
-        eat(p, pxParLe)
-        addSon(result, typeName(p))
-        eat(p, pxParRi)
-    elif (tok.s == "new" or tok.s == "delete") and pfCpp in p.options.flags:
-      var opr = tok.s
-      result = newNodeP(nkCall, p)
-      if p.tok.xkind == pxBracketLe:
-        getTok(p)
-        eat(p, pxBracketRi)
-        opr.add("Array")
-      addSon(result, newIdentNodeP(opr, p))
-      if p.tok.xkind == pxParLe:
-        getTok(p, result)
-        addSon(result, typeDesc(p))
-        eat(p, pxParRi, result)
-      else:
-        addSon(result, expression(p, 139))
-    else:
-      result = mangledIdent(tok.s, p)
-      result = optScope(p, result)
-      result = optAngle(p, result)
-  of pxIntLit: 
-    result = newIntNodeP(nkIntLit, tok.iNumber, p)
-    setBaseFlags(result, tok.base)
-  of pxInt64Lit: 
-    result = newIntNodeP(nkInt64Lit, tok.iNumber, p)
-    setBaseFlags(result, tok.base)
-  of pxFloatLit: 
-    result = newFloatNodeP(nkFloatLit, tok.fNumber, p)
-    setBaseFlags(result, tok.base)
-  of pxStrLit: 
-    result = newStrNodeP(nkStrLit, tok.s, p)
-    while p.tok.xkind == pxStrLit:
-      add(result.strVal, p.tok.s)
-      getTok(p, result)
-  of pxCharLit:
-    result = newIntNodeP(nkCharLit, ord(tok.s[0]), p)
-  of pxParLe:
-    try:
-      saveContext(p)
-      result = newNodeP(nkPar, p)
-      addSon(result, expression(p, 0))
-      if p.tok.xkind != pxParRi:
-        raise newException(ERetryParsing, "expected a ')'")
-      getTok(p, result)
-      if p.tok.xkind in {pxSymbol, pxIntLit, pxFloatLit, pxStrLit, pxCharLit}:
-        raise newException(ERetryParsing, "expected a non literal token")
-      closeContext(p)
-    except ERetryParsing:
-      backtrackContext(p)
-      result = newNodeP(nkCast, p)
-      addSon(result, typeName(p))
-      eat(p, pxParRi, result)
-      addSon(result, expression(p, 139))
-  of pxPlusPlus:
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP("inc", p))
-    addSon(result, expression(p, 139))
-  of pxMinusMinus:
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP("dec", p))
-    addSon(result, expression(p, 139))
-  of pxAmp:
-    result = newNodeP(nkAddr, p)
-    addSon(result, expression(p, 139))
-  of pxStar:
-    result = newNodeP(nkBracketExpr, p)
-    addSon(result, expression(p, 139))
-  of pxPlus:
-    result = newNodeP(nkPrefix, p)
-    addSon(result, newIdentNodeP("+", p))
-    addSon(result, expression(p, 139))
-  of pxMinus:
-    result = newNodeP(nkPrefix, p)
-    addSon(result, newIdentNodeP("-", p))
-    addSon(result, expression(p, 139))
-  of pxTilde:
-    result = newNodeP(nkPrefix, p)
-    addSon(result, newIdentNodeP("not", p))
-    addSon(result, expression(p, 139))
-  of pxNot:
-    result = newNodeP(nkPrefix, p)
-    addSon(result, newIdentNodeP("not", p))
-    addSon(result, expression(p, 139))
-  else:
-    # probably from a failed sub expression attempt, try a type cast
-    raise newException(ERetryParsing, "did not expect " & $tok)
-
-proc leftBindingPower(p : var TParser, tok : ref TToken) : int =
-  #echo "lbp ", $tok[]
-  case tok.xkind:
-  of pxComma:
-    return 10
-    # throw == 20
-  of pxAsgn, pxPlusAsgn, pxMinusAsgn, pxStarAsgn, pxSlashAsgn, pxModAsgn, 
-     pxShlAsgn, pxShrAsgn, pxAmpAsgn, pxHatAsgn, pxBarAsgn:
-    return 30
-  of pxConditional:
-    return 40
-  of pxBarBar:
-    return 50
-  of pxAmpAmp:
-    return 60
-  of pxBar:
-    return 70
-  of pxHat:
-    return 80
-  of pxAmp:
-    return 90
-  of pxEquals, pxNeq:
-    return 100
-  of pxLt, pxLe, pxGt, pxGe:
-    return 110
-  of pxShl, pxShr:
-    return 120
-  of pxPlus, pxMinus:
-    return 130
-  of pxStar, pxSlash, pxMod:
-    return 140
-    # .* ->* == 150
-  of pxPlusPlus, pxMinusMinus, pxParLe, pxDot, pxArrow, pxBracketLe:
-    return 160
-    # :: == 170
-  else:
-    return 0
-
-proc buildStmtList(a: PNode): PNode
-
-proc leftExpression(p : var TParser, tok : TToken, left : PNode) : PNode =
-  #echo "led ", $tok
-  case tok.xkind:
-  of pxComma: # 10
-    # not supported as an expression, turns into a statement list
-    result = buildStmtList(left)
-    addSon(result, expression(p, 0))
-    # throw == 20
-  of pxAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    addSon(result, left, expression(p, 29))
-  of pxPlusAsgn: # 30
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP(getIdent("inc"), p), left, expression(p, 29))
-  of pxMinusAsgn: # 30
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP(getIdent("dec"), p), left, expression(p, 29))
-  of pxStarAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("*", copyTree(left), right, p))
-  of pxSlashAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("/", copyTree(left), right, p))
-  of pxModAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("mod", copyTree(left), right, p))
-  of pxShlAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("shl", copyTree(left), right, p))
-  of pxShrAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("shr", copyTree(left), right, p))
-  of pxAmpAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("and", copyTree(left), right, p))
-  of pxHatAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("xor", copyTree(left), right, p))
-  of pxBarAsgn: # 30
-    result = newNodeP(nkAsgn, p)
-    var right = expression(p, 29)
-    addSon(result, left, newBinary("or", copyTree(left), right, p))
-  of pxConditional: # 40
-    var a = expression(p, 0)
-    eat(p, pxColon, a)
-    var b = expression(p, 39)
-    result = newNodeP(nkIfExpr, p)
-    var branch = newNodeP(nkElifExpr, p)
-    addSon(branch, left, a)
-    addSon(result, branch)
-    branch = newNodeP(nkElseExpr, p)
-    addSon(branch, b)
-    addSon(result, branch)
-  of pxBarBar: # 50
-    result = newBinary("or", left, expression(p, 50), p)
-  of pxAmpAmp: # 60
-    result = newBinary("and", left, expression(p, 60), p)
-  of pxBar: # 70
-    result = newBinary("or", left, expression(p, 70), p)
-  of pxHat: # 80
-    result = newBinary("^", left, expression(p, 80), p)
-  of pxAmp: # 90
-    result = newBinary("and", left, expression(p, 90), p)
-  of pxEquals: # 100
-    result = newBinary("==", left, expression(p, 100), p)
-  of pxNeq: # 100
-    result = newBinary("!=", left, expression(p, 100), p)
-  of pxLt: # 110
-    result = newBinary("<", left, expression(p, 110), p)
-  of pxLe: # 110
-    result = newBinary("<=", left, expression(p, 110), p)
-  of pxGt: # 110
-    result = newBinary(">", left, expression(p, 110), p)
-  of pxGe: # 110
-    result = newBinary(">=", left, expression(p, 110), p)
-  of pxShl: # 120
-    result = newBinary("shl", left, expression(p, 120), p)
-  of pxShr: # 120
-    result = newBinary("shr", left, expression(p, 120), p)
-  of pxPlus: # 130
-    result = newNodeP(nkInfix, p)
-    addSon(result, newIdentNodeP("+", p), left)
-    addSon(result, expression(p, 130))
-  of pxMinus: # 130
-    result = newNodeP(nkInfix, p)
-    addSon(result, newIdentNodeP("+", p), left)
-    addSon(result, expression(p, 130))
-  of pxStar: # 140
-    result = newNodeP(nkInfix, p)
-    addSon(result, newIdentNodeP("*", p), left)
-    addSon(result, expression(p, 140))
-  of pxSlash: # 140
-    result = newNodeP(nkInfix, p)
-    addSon(result, newIdentNodeP("div", p), left)
-    addSon(result, expression(p, 140))
-  of pxMod: # 140
-    result = newNodeP(nkInfix, p)
-    addSon(result, newIdentNodeP("mod", p), left)
-    addSon(result, expression(p, 140))
-    # .* ->* == 150
-  of pxPlusPlus: # 160
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP("inc", p), left)
-  of pxMinusMinus: # 160
-    result = newNodeP(nkCall, p)
-    addSon(result, newIdentNodeP("dec", p), left)
-  of pxParLe: # 160
-    result = newNodeP(nkCall, p)
-    addSon(result, left)
-    while p.tok.xkind != pxParRi:
-      var a = expression(p, 29)
-      addSon(result, a)
-      while p.tok.xkind == pxComma:
-        getTok(p, a)
-        a = expression(p, 29)
-        addSon(result, a)
-    eat(p, pxParRi, result)
-  of pxDot: # 160
-    result = newNodeP(nkDotExpr, p)
-    addSon(result, left)
-    addSon(result, skipIdent(p))
-  of pxArrow: # 160
-    result = newNodeP(nkDotExpr, p)
-    addSon(result, left)
-    addSon(result, skipIdent(p))
-  of pxBracketLe: # 160
-    result = newNodeP(nkBracketExpr, p)
-    addSon(result, left, expression(p))
-    eat(p, pxBracketRi, result)
-    # :: == 170
-  else:
-    result = left
-
-proc expression*(p : var TParser, rbp : int = 0) : PNode =
-  var tok : TToken
-
-  tok = p.tok[]
-  getTok(p, result)
-
-  result = startExpression(p, tok)
-
-  while rbp < leftBindingPower(p, p.tok):
-    tok = p.tok[]
-    getTok(p, result)
-    result = leftExpression(p, tok, result)
-    
-# Statements
-
-proc buildStmtList(a: PNode): PNode = 
-  if a.kind == nkStmtList: result = a
-  else:
-    result = newNodeI(nkStmtList, a.info)
-    addSon(result, a)
-
-proc nestedStatement(p: var TParser): PNode =
-  # careful: We need to translate:
-  # if (x) if (y) stmt;
-  # into:
-  # if x:
-  #   if x:
-  #     stmt
-  # 
-  # Nimrod requires complex statements to be nested in whitespace!
-  const
-    complexStmt = {nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef,
-      nkTemplateDef, nkIteratorDef, nkIfStmt,
-      nkWhenStmt, nkForStmt, nkWhileStmt, nkCaseStmt, nkVarSection, 
-      nkConstSection, nkTypeSection, nkTryStmt, nkBlockStmt, nkStmtList,
-      nkCommentStmt, nkStmtListExpr, nkBlockExpr, nkStmtListType, nkBlockType}
-  result = statement(p)
-  if result.kind in complexStmt:
-    result = buildStmtList(result)
-
-proc expressionStatement(p: var TParser): PNode = 
-  # do not skip the comment after a semicolon to make a new nkCommentStmt
-  if p.tok.xkind == pxSemicolon: 
-    getTok(p)
-    result = ast.emptyNode
-  else:
-    result = expression(p)
-    if p.tok.xkind == pxSemicolon: getTok(p)
-    else: parMessage(p, errTokenExpected, ";")
-  assert result != nil
-
-proc parseIf(p: var TParser): PNode = 
-  # we parse additional "else if"s too here for better Nimrod code
-  result = newNodeP(nkIfStmt, p)
-  while true: 
-    getTok(p) # skip ``if``
-    var branch = newNodeP(nkElifBranch, p)
-    eat(p, pxParLe, branch)
-    addSon(branch, expression(p))
-    eat(p, pxParRi, branch)
-    addSon(branch, nestedStatement(p))
-    addSon(result, branch)
-    skipCom(p, branch)
-    if p.tok.s == "else": 
-      getTok(p, result)
-      if p.tok.s != "if": 
-        # ordinary else part:
-        branch = newNodeP(nkElse, p)
-        addSon(branch, nestedStatement(p))
-        addSon(result, branch)
-        break 
-    else: 
-      break 
-  
-proc parseWhile(p: var TParser): PNode = 
-  result = newNodeP(nkWhileStmt, p)
-  getTok(p, result)
-  eat(p, pxParLe, result)
-  addSon(result, expression(p))
-  eat(p, pxParRi, result)
-  addSon(result, nestedStatement(p))
-
-proc embedStmts(sl, a: PNode)
-
-proc parseDoWhile(p: var TParser): PNode =  
-  # parsing
-  result = newNodeP(nkWhileStmt, p)
-  getTok(p, result)
-  var stm = nestedStatement(p)
-  eat(p, "while", result)
-  eat(p, pxParLe, result)
-  var exp = expression(p)
-  eat(p, pxParRi, result)
-  if p.tok.xkind == pxSemicolon: getTok(p)
-
-  # while true:
-  #   stmt
-  #   if not expr:
-  #     break
-  addSon(result, newIdentNodeP("true", p))
-
-  stm = buildStmtList(stm)
-
-  # get the last exp if it is a stmtlist
-  var cleanedExp = exp
-  if exp.kind == nkStmtList:
-    cleanedExp = exp.sons[exp.len-1]
-    exp.sons = exp.sons[0..exp.len-2]
-    embedStmts(stm, exp)
-
-  var notExp = newNodeP(nkPrefix, p)
-  addSon(notExp, newIdentNodeP("not", p))
-  addSon(notExp, cleanedExp)
-
-  var brkStm = newNodeP(nkBreakStmt, p)
-  addSon(brkStm, ast.emptyNode)
-
-  var ifStm = newNodeP(nkIfStmt, p)
-  var ifBranch = newNodeP(nkElifBranch, p)
-  addSon(ifBranch, notExp)
-  addSon(ifBranch, brkStm)
-  addSon(ifStm, ifBranch)
-
-  embedStmts(stm, ifStm)
-
-  addSon(result, stm)
-
-proc declarationOrStatement(p: var TParser): PNode = 
-  if p.tok.xkind != pxSymbol:
-    result = expressionStatement(p)
-  elif declKeyword(p, p.tok.s): 
-    result = declaration(p)
-  else:
-    # ordinary identifier:
-    saveContext(p)
-    getTok(p) # skip identifier to look ahead
-    case p.tok.xkind
-    of pxSymbol, pxStar, pxLt, pxAmp, pxAmpAmp:
-      # we parse 
-      # a b
-      # a * b
-      # always as declarations! This is of course not correct, but good
-      # enough for most real world C code out there.
-      backtrackContext(p)
-      result = declaration(p)
-    of pxColon: 
-      # it is only a label:
-      closeContext(p)
-      getTok(p)
-      result = statement(p)
-    else: 
-      backtrackContext(p)
-      result = expressionStatement(p)
-  assert result != nil
-
-proc parseTuple(p: var TParser, statements: PNode, isUnion: bool): PNode = 
-  parseStructBody(p, statements, isUnion, nkTupleTy)
-
-proc parseTrailingDefinedIdents(p: var TParser, result, baseTyp: PNode) =
-  var varSection = newNodeP(nkVarSection, p)
-  while p.tok.xkind notin {pxEof, pxSemicolon}:
-    var t = pointer(p, baseTyp)
-    expectIdent(p)
-    var def = newNodeP(nkIdentDefs, p)
-    addSon(def, varIdent(p.tok.s, p))
-    getTok(p, def)
-    addSon(def, parseTypeSuffix(p, t))
-    addInitializer(p, def)
-    addSon(varSection, def)
-    if p.tok.xkind != pxComma: break
-    getTok(p, def)
-  eat(p, pxSemicolon)
-  if sonsLen(varSection) > 0:
-    addSon(result, varSection)
-
-proc parseStandaloneStruct(p: var TParser, isUnion: bool): PNode =
-  result = newNodeP(nkStmtList, p)
-  saveContext(p)
-  getTok(p, result) # skip "struct" or "union"
-  var origName = ""
-  if p.tok.xkind == pxSymbol: 
-    markTypeIdent(p, nil)
-    origName = p.tok.s
-    getTok(p, result)
-  if p.tok.xkind in {pxCurlyLe, pxSemiColon}:
-    if origName.len > 0: 
-      var name = mangledIdent(origName, p)
-      var t = parseStruct(p, result, isUnion)
-      var typeSection = newNodeP(nkTypeSection, p)
-      addTypeDef(typeSection, structPragmas(p, name, origName), t)
-      addSon(result, typeSection)
-      parseTrailingDefinedIdents(p, result, name)
-    else:
-      var t = parseTuple(p, result, isUnion)
-      parseTrailingDefinedIdents(p, result, t)
-  else:
-    backtrackContext(p)
-    result = declaration(p)
-
-proc parseFor(p: var TParser, result: PNode) = 
-  # 'for' '(' expression_statement expression_statement expression? ')'
-  #   statement
-  getTok(p, result)
-  eat(p, pxParLe, result)
-  var initStmt = declarationOrStatement(p)
-  if initStmt.kind != nkEmpty:
-    embedStmts(result, initStmt)
-  var w = newNodeP(nkWhileStmt, p)
-  var condition = expressionStatement(p)
-  if condition.kind == nkEmpty: condition = newIdentNodeP("true", p)
-  addSon(w, condition)
-  var step = if p.tok.xkind != pxParRi: expression(p) else: ast.emptyNode
-  eat(p, pxParRi, step)
-  var loopBody = nestedStatement(p)
-  if step.kind != nkEmpty:
-    loopBody = buildStmtList(loopBody)
-    embedStmts(loopBody, step)
-  addSon(w, loopBody)
-  addSon(result, w)
-  
-proc switchStatement(p: var TParser): PNode = 
-  result = newNodeP(nkStmtList, p)
-  while true:
-    if p.tok.xkind in {pxEof, pxCurlyRi}: break
-    case p.tok.s 
-    of "break":
-      getTok(p, result)
-      eat(p, pxSemicolon, result)
-      break
-    of "return", "continue", "goto": 
-      addSon(result, statement(p))
-      break
-    of "case", "default":
-      break
-    else: discard
-    addSon(result, statement(p))
-  if sonsLen(result) == 0:
-    # translate empty statement list to Nimrod's ``nil`` statement
-    result = newNodeP(nkNilLit, p)
-
-proc rangeExpression(p: var TParser): PNode =
-  # We support GCC's extension: ``case expr...expr:`` 
-  result = constantExpression(p)
-  if p.tok.xkind == pxDotDotDot:
-    getTok(p, result)
-    var a = result
-    var b = constantExpression(p)
-    result = newNodeP(nkRange, p)
-    addSon(result, a)
-    addSon(result, b)
-
-proc parseSwitch(p: var TParser): PNode = 
-  # We cannot support Duff's device or C's crazy switch syntax. We just support
-  # sane usages of switch. ;-)
-  result = newNodeP(nkCaseStmt, p)
-  getTok(p, result)
-  eat(p, pxParLe, result)
-  addSon(result, expression(p))
-  eat(p, pxParRi, result)
-  eat(p, pxCurlyLe, result)
-  var b: PNode
-  while (p.tok.xkind != pxCurlyRi) and (p.tok.xkind != pxEof): 
-    case p.tok.s 
-    of "default": 
-      b = newNodeP(nkElse, p)
-      getTok(p, b)
-      eat(p, pxColon, b)
-    of "case": 
-      b = newNodeP(nkOfBranch, p)
-      while p.tok.xkind == pxSymbol and p.tok.s == "case":
-        getTok(p, b)
-        addSon(b, rangeExpression(p))
-        eat(p, pxColon, b)
-    else:
-      parMessage(p, errXExpected, "case")
-    addSon(b, switchStatement(p))
-    addSon(result, b)
-    if b.kind == nkElse: break 
-  eat(p, pxCurlyRi)
-
-proc addStmt(sl, a: PNode) = 
-  # merge type sections if possible:
-  if a.kind != nkTypeSection or sonsLen(sl) == 0 or
-      lastSon(sl).kind != nkTypeSection:
-    addSon(sl, a)
-  else:
-    var ts = lastSon(sl)
-    for i in 0..sonsLen(a)-1: addSon(ts, a.sons[i])
-
-proc embedStmts(sl, a: PNode) = 
-  if a.kind != nkStmtList:
-    addStmt(sl, a)
-  else:
-    for i in 0..sonsLen(a)-1: 
-      if a[i].kind != nkEmpty: addStmt(sl, a[i])
-
-proc compoundStatement(p: var TParser): PNode = 
-  result = newNodeP(nkStmtList, p)
-  eat(p, pxCurlyLe)
-  inc(p.scopeCounter)
-  while p.tok.xkind notin {pxEof, pxCurlyRi}: 
-    var a = statement(p)
-    if a.kind == nkEmpty: break
-    embedStmts(result, a)
-  if sonsLen(result) == 0:
-    # translate ``{}`` to Nimrod's ``discard`` statement
-    result = newNodeP(nkDiscardStmt, p)
-    result.add(ast.emptyNode)
-  dec(p.scopeCounter)
-  eat(p, pxCurlyRi)
-
-proc skipInheritKeyw(p: var TParser) =
-  if p.tok.xkind == pxSymbol and (p.tok.s == "private" or 
-                                  p.tok.s == "protected" or
-                                  p.tok.s == "public"):
-    getTok(p)
-
-proc parseConstructor(p: var TParser, pragmas: PNode, 
-                      isDestructor=false): PNode =
-  var origName = p.tok.s
-  getTok(p)
-  
-  result = newNodeP(nkProcDef, p)
-  var rettyp = if isDestructor: newNodeP(nkNilLit, p)
-               else: mangledIdent(origName, p)
-  
-  let oname = if isDestructor: "destroy" & origName
-              else: "construct" & origName
-  var name = mangledIdent(oname, p)
-  var params = newNodeP(nkFormalParams, p)
-  addReturnType(params, rettyp)
-  if p.tok.xkind == pxParLe:
-    parseFormalParams(p, params, pragmas)
-  if p.tok.xkind == pxSymbol and p.tok.s == "const":
-    addSon(pragmas, newIdentNodeP("noSideEffect", p))
-  if pfCDecl in p.options.flags:
-    addSon(pragmas, newIdentNodeP("cdecl", p))
-  elif pfStdcall in p.options.flags:
-    addSon(pragmas, newIdentNodeP("stdcall", p))
-  if p.tok.xkind == pxColon:
-    # skip initializer list:
-    while true:
-      getTok(p)
-      discard expression(p)
-      if p.tok.xkind != pxComma: break
-  # no pattern, no exceptions:
-  addSon(result, exportSym(p, name, origName), ast.emptyNode, ast.emptyNode)
-  addSon(result, params, pragmas, ast.emptyNode) # no exceptions
-  addSon(result, ast.emptyNode) # no body
-  case p.tok.xkind 
-  of pxSemicolon: getTok(p)
-  of pxCurlyLe:
-    let body = compoundStatement(p)
-    if pfKeepBodies in p.options.flags:
-      result.sons[bodyPos] = body
-  else:
-    parMessage(p, errTokenExpected, ";")
-  if result.sons[bodyPos].kind == nkEmpty:
-    doImport((if isDestructor: "~" else: "") & origName, pragmas, p)
-  elif isDestructor:
-    addSon(pragmas, newIdentNodeP("destructor", p))
-  if sonsLen(result.sons[pragmasPos]) == 0:
-    result.sons[pragmasPos] = ast.emptyNode
-
-proc parseMethod(p: var TParser, origName: string, rettyp, pragmas: PNode,
-                 isStatic: bool): PNode =
-  result = newNodeP(nkProcDef, p)
-  var params = newNodeP(nkFormalParams, p)
-  addReturnType(params, rettyp)
-  var thisDef = newNodeP(nkIdentDefs, p)
-  if not isStatic:
-    # declare 'this':
-    var t = newNodeP(nkVarTy, p)
-    t.add(p.currentClass)
-    addSon(thisDef, newIdentNodeP("this", p), t, ast.emptyNode)
-    params.add(thisDef)
-  parseFormalParams(p, params, pragmas)
-  if p.tok.xkind == pxSymbol and p.tok.s == "const":
-    addSon(pragmas, newIdentNodeP("noSideEffect", p))
-    getTok(p, result)
-    if not isStatic:
-      # fix the type of the 'this' parameter:
-      thisDef.sons[1] = thisDef.sons[1].sons[0]
-  if pfCDecl in p.options.flags:
-    addSon(pragmas, newIdentNodeP("cdecl", p))
-  elif pfStdcall in p.options.flags:
-    addSon(pragmas, newIdentNodeP("stdcall", p))
-  # no pattern, no exceptions:
-  let methodName = newIdentNodeP(origName, p)
-  addSon(result, exportSym(p, methodName, origName),
-         ast.emptyNode, ast.emptyNode)
-  addSon(result, params, pragmas, ast.emptyNode) # no exceptions
-  addSon(result, ast.emptyNode) # no body
-  case p.tok.xkind
-  of pxSemicolon: getTok(p)
-  of pxCurlyLe:
-    let body = compoundStatement(p)
-    if pfKeepBodies in p.options.flags:
-      result.sons[bodyPos] = body
-  else:
-    parMessage(p, errTokenExpected, ";")
-  if result.sons[bodyPos].kind == nkEmpty:
-    if isStatic: doImport(origName, pragmas, p)
-    else: doImportCpp(origName, pragmas, p)
-  if sonsLen(result.sons[pragmasPos]) == 0:
-    result.sons[pragmasPos] = ast.emptyNode
-
-proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode
-
-proc followedByParLe(p: var TParser): bool =
-  saveContext(p)
-  getTok(p) # skip Identifier
-  result = p.tok.xkind == pxParLe
-  backtrackContext(p)
-
-proc parseOperator(p: var TParser, origName: var string): bool =
-  getTok(p) # skip 'operator' keyword
-  case p.tok.xkind
-  of pxAmp..pxArrow:
-    # ordinary operator symbol:
-    origName.add(tokKindToStr(p.tok.xkind))
-    getTok(p)
-  of pxSymbol:
-    if p.tok.s == "new" or p.tok.s == "delete":
-      origName.add(p.tok.s)
-      getTok(p)
-      if p.tok.xkind == pxBracketLe:
-        getTok(p)
-        eat(p, pxBracketRi)
-        origName.add("[]")
-    else:
-      # type converter
-      let x = typeAtom(p)
-      if x.kind == nkIdent:
-        origName.add(x.ident.s)
-      else:
-        parMessage(p, errGenerated, "operator symbol expected")
-      result = true
-  of pxParLe:
-    getTok(p)
-    eat(p, pxParRi)
-    origName.add("()")
-  of pxBracketLe:
-    getTok(p)
-    eat(p, pxBracketRi)
-    origName.add("[]")
-  else:
-    parMessage(p, errGenerated, "operator symbol expected")
-
-proc parseClass(p: var TParser; isStruct: bool; stmtList: PNode): PNode =
-  result = newNodeP(nkObjectTy, p)
-  addSon(result, ast.emptyNode, ast.emptyNode) # no pragmas, no inheritance 
-  
-  var recList = newNodeP(nkRecList, p)
-  addSon(result, recList)
-  if p.tok.xkind == pxColon:
-    getTok(p, result)
-    skipInheritKeyw(p)
-    var baseTyp = typeAtom(p)
-    var inh = newNodeP(nkOfInherit, p)
-    inh.add(baseTyp)
-    if p.tok.xkind == pxComma:
-      parMessage(p, errGenerated, "multiple inheritance is not supported")
-      while p.tok.xkind == pxComma:
-        getTok(p)
-        skipInheritKeyw(p)
-        discard typeAtom(p)
-    result.sons[0] = inh
-    
-  eat(p, pxCurlyLe, result)
-  var private = not isStruct
-  var pragmas = newNodeP(nkPragma, p)
-  while p.tok.xkind notin {pxEof, pxCurlyRi}:
-    skipCom(p, stmtList)
-    if p.tok.xkind == pxSymbol and (p.tok.s == "private" or 
-                                    p.tok.s == "protected"):
-      getTok(p, result)
-      eat(p, pxColon, result)
-      private = true
-    elif p.tok.xkind == pxSymbol and p.tok.s == "public":
-      getTok(p, result)
-      eat(p, pxColon, result)
-      private = false
-    if p.tok.xkind == pxSymbol and (p.tok.s == "friend" or p.tok.s == "using"):
-      # we skip friend declarations:
-      while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
-      eat(p, pxSemicolon)
-    elif p.tok.xkind == pxSymbol and p.tok.s == "enum":
-      let x = enumSpecifier(p)
-      if not private or pfKeepBodies in p.options.flags: stmtList.add(x)
-    elif p.tok.xkind == pxSymbol and p.tok.s == "typedef":
-      let x = parseTypeDef(p)
-      if not private or pfKeepBodies in p.options.flags: stmtList.add(x)
-    elif p.tok.xkind == pxSymbol and(p.tok.s == "struct" or p.tok.s == "class"):
-      let x = parseStandaloneClass(p, isStruct=p.tok.s == "struct")
-      if not private or pfKeepBodies in p.options.flags: stmtList.add(x)
-    elif p.tok.xkind == pxSymbol and p.tok.s == "union":
-      let x = parseStandaloneStruct(p, isUnion=true)
-      if not private or pfKeepBodies in p.options.flags: stmtList.add(x)
-    else:
-      if pragmas.len != 0: pragmas = newNodeP(nkPragma, p)
-      parseCallConv(p, pragmas)
-      var isStatic = false
-      if p.tok.xkind == pxSymbol and p.tok.s == "virtual":
-        getTok(p, stmtList)
-      if p.tok.xkind == pxSymbol and p.tok.s == "explicit":
-        getTok(p, stmtList)
-      if p.tok.xkind == pxSymbol and p.tok.s == "static":
-        getTok(p, stmtList)
-        isStatic = true
-      parseCallConv(p, pragmas)
-      if p.tok.xkind == pxSymbol and p.tok.s == p.currentClass.ident.s and 
-          followedByParLe(p):
-        # constructor
-        let cons = parseConstructor(p, pragmas)
-        if not private or pfKeepBodies in p.options.flags: stmtList.add(cons)
-      elif p.tok.xkind == pxTilde:
-        # destructor
-        getTok(p, stmtList)
-        if p.tok.xkind == pxSymbol and p.tok.s == p.currentClass.ident.s:
-          let des = parseConstructor(p, pragmas, isDestructor=true)
-          if not private or pfKeepBodies in p.options.flags: stmtList.add(des)
-        else:
-          parMessage(p, errGenerated, "invalid destructor")
-      else:
-        # field declaration or method:
-        var baseTyp = typeAtom(p)
-        while true:
-          var def = newNodeP(nkIdentDefs, p)
-          var t = pointer(p, baseTyp)
-          let canBeMethod = p.tok.xkind != pxParLe
-          var origName: string
-          if p.tok.xkind == pxSymbol:
-            origName = p.tok.s
-            if p.tok.s == "operator":
-              var isConverter = parseOperator(p, origName)
-              let meth = parseMethod(p, origName, t, pragmas, isStatic)
-              if not private or pfKeepBodies in p.options.flags:
-                if isConverter: meth.kind = nkConverterDef
-                stmtList.add(meth)
-              break
-          var i = parseField(p, nkRecList)
-          if canBeMethod and p.tok.xkind == pxParLe:
-            let meth = parseMethod(p, origName, t, pragmas, isStatic)
-            if not private or pfKeepBodies in p.options.flags:
-              stmtList.add(meth)
-          else:
-            t = parseTypeSuffix(p, t)
-            addSon(def, i, t, ast.emptyNode)
-            if not isStatic: addSon(recList, def)
-          if p.tok.xkind != pxComma: break
-          getTok(p, def)
-        if p.tok.xkind == pxSemicolon:
-          getTok(p, lastSon(recList))
-  eat(p, pxCurlyRi, result)
-
-proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode =
-  result = newNodeP(nkStmtList, p)
-  saveContext(p)
-  getTok(p, result) # skip "class" or "struct"
-  var origName = ""
-  let oldClass = p.currentClass
-  if p.tok.xkind == pxSymbol: 
-    markTypeIdent(p, nil)
-    origName = p.tok.s
-    getTok(p, result)
-    p.currentClass = mangledIdent(origName, p)
-  else:
-    p.currentClass = nil
-  if p.tok.xkind in {pxCurlyLe, pxSemiColon, pxColon}:
-    if origName.len > 0:
-      p.options.classes[origName] = "true"
-
-      var typeSection = newNodeP(nkTypeSection, p)
-      addSon(result, typeSection)
-      
-      var name = mangledIdent(origName, p)
-      var t = parseClass(p, isStruct, result)
-      addTypeDef(typeSection, structPragmas(p, name, origName), t)
-      parseTrailingDefinedIdents(p, result, name)
-    else:
-      var t = parseTuple(p, result, isUnion=false)
-      parseTrailingDefinedIdents(p, result, t)
-  else:
-    backtrackContext(p)
-    result = declaration(p)
-  p.currentClass = oldClass
-
-proc unwrap(a: PNode): PNode =
-  if a.kind == nkPar:
-    return a.sons[0]
-  return a
-
-include cpp
-
-proc statement(p: var TParser): PNode = 
-  case p.tok.xkind 
-  of pxSymbol: 
-    case p.tok.s
-    of "if": result = parseIf(p)
-    of "switch": result = parseSwitch(p)
-    of "while": result = parseWhile(p)
-    of "do": result = parseDoWhile(p)
-    of "for": 
-      result = newNodeP(nkStmtList, p)
-      parseFor(p, result)
-    of "goto": 
-      # we cannot support "goto"; in hand-written C, "goto" is most often used
-      # to break a block, so we convert it to a break statement with label.
-      result = newNodeP(nkBreakStmt, p)
-      getTok(p)
-      addSon(result, skipIdent(p))
-      eat(p, pxSemicolon)
-    of "continue":
-      result = newNodeP(nkContinueStmt, p)
-      getTok(p)
-      eat(p, pxSemicolon)
-      addSon(result, ast.emptyNode)
-    of "break":
-      result = newNodeP(nkBreakStmt, p)
-      getTok(p)
-      eat(p, pxSemicolon)
-      addSon(result, ast.emptyNode)
-    of "return":
-      result = newNodeP(nkReturnStmt, p)
-      getTok(p)
-      if p.tok.xkind == pxSemicolon:
-        addSon(result, ast.emptyNode)
-      else:
-        addSon(result, unwrap(expression(p)))
-      eat(p, pxSemicolon)
-    of "enum": result = enumSpecifier(p)
-    of "typedef": result = parseTypeDef(p)
-    of "union": result = parseStandaloneStruct(p, isUnion=true)
-    of "struct":
-      if pfCpp in p.options.flags:
-        result = parseStandaloneClass(p, isStruct=true)
-      else:
-        result = parseStandaloneStruct(p, isUnion=false)
-    of "class":
-      if pfCpp in p.options.flags:
-        result = parseStandaloneClass(p, isStruct=false)
-      else:
-        result = declarationOrStatement(p)
-    of "namespace":
-      if pfCpp in p.options.flags:
-        while p.tok.xkind notin {pxEof, pxCurlyLe}: getTok(p)
-        result = compoundStatement(p)
-      else:
-        result = declarationOrStatement(p)
-    of "using":
-      if pfCpp in p.options.flags:
-        while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
-        eat(p, pxSemicolon)
-        result = newNodeP(nkNilLit, p)
-      else:
-        result = declarationOrStatement(p)
-    else: result = declarationOrStatement(p)
-  of pxCurlyLe:
-    result = compoundStatement(p)
-  of pxDirective, pxDirectiveParLe:
-    result = parseDir(p)
-  of pxLineComment, pxStarComment:
-    result = newNodeP(nkCommentStmt, p)
-    skipCom(p, result)
-  of pxSemicolon:
-    # empty statement:
-    getTok(p)
-    if p.tok.xkind in {pxLineComment, pxStarComment}:
-      result = newNodeP(nkCommentStmt, p)
-      skipCom(p, result)
-    else:
-      result = newNodeP(nkNilLit, p)
-  else:
-    result = expressionStatement(p)
-  assert result != nil
-
-proc parseUnit(p: var TParser): PNode =
-  try:
-    result = newNodeP(nkStmtList, p)
-    getTok(p) # read first token
-    while p.tok.xkind != pxEof:
-      var s = statement(p)
-      if s.kind != nkEmpty: embedStmts(result, s)
-  except ERetryParsing:
-    parMessage(p, errGenerated, "Uncaught parsing exception raised")
-
diff --git a/compiler/c2nim/cpp.nim b/compiler/c2nim/cpp.nim
deleted file mode 100644
index 84b4c4dfb..000000000
--- a/compiler/c2nim/cpp.nim
+++ /dev/null
@@ -1,347 +0,0 @@
-#
-#
-#      c2nim - C to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# Preprocessor support
-
-const
-  c2nimSymbol = "C2NIM"
-
-proc eatNewLine(p: var TParser, n: PNode) = 
-  if p.tok.xkind == pxLineComment:
-    skipCom(p, n)
-    if p.tok.xkind == pxNewLine: getTok(p)
-  elif p.tok.xkind == pxNewLine: 
-    eat(p, pxNewLine)
-  
-proc skipLine(p: var TParser) = 
-  while p.tok.xkind notin {pxEof, pxNewLine, pxLineComment}: getTok(p)
-  eatNewLine(p, nil)
-
-proc parseDefineBody(p: var TParser, tmplDef: PNode): string = 
-  if p.tok.xkind == pxCurlyLe or 
-    (p.tok.xkind == pxSymbol and (
-        declKeyword(p, p.tok.s) or stmtKeyword(p.tok.s))):
-    addSon(tmplDef, statement(p))
-    result = "stmt"
-  elif p.tok.xkind in {pxLineComment, pxNewLine}:
-    addSon(tmplDef, buildStmtList(newNodeP(nkNilLit, p)))
-    result = "stmt"
-  else:
-    addSon(tmplDef, buildStmtList(expression(p)))
-    result = "expr"
-
-proc parseDefine(p: var TParser): PNode = 
-  if p.tok.xkind == pxDirectiveParLe: 
-    # a macro with parameters:
-    result = newNodeP(nkTemplateDef, p)
-    getTok(p)
-    addSon(result, skipIdentExport(p))
-    addSon(result, ast.emptyNode)
-    eat(p, pxParLe)
-    var params = newNodeP(nkFormalParams, p)
-    # return type; not known yet:
-    addSon(params, ast.emptyNode)
-    if p.tok.xkind != pxParRi:
-      var identDefs = newNodeP(nkIdentDefs, p)
-      while p.tok.xkind != pxParRi: 
-        addSon(identDefs, skipIdent(p))
-        skipStarCom(p, nil)
-        if p.tok.xkind != pxComma: break
-        getTok(p)
-      addSon(identDefs, newIdentNodeP("expr", p))
-      addSon(identDefs, ast.emptyNode)
-      addSon(params, identDefs)
-    eat(p, pxParRi)
-    
-    addSon(result, ast.emptyNode) # no generic parameters
-    addSon(result, params)
-    addSon(result, ast.emptyNode) # no pragmas
-    addSon(result, ast.emptyNode)
-    var kind = parseDefineBody(p, result)
-    params.sons[0] = newIdentNodeP(kind, p)
-    eatNewLine(p, result)
-  else:
-    # a macro without parameters:
-    result = newNodeP(nkConstSection, p)
-    while p.tok.xkind == pxDirective and p.tok.s == "define":
-      getTok(p) # skip #define
-      var c = newNodeP(nkConstDef, p)
-      addSon(c, skipIdentExport(p))
-      addSon(c, ast.emptyNode)
-      skipStarCom(p, c)
-      if p.tok.xkind in {pxLineComment, pxNewLine, pxEof}:
-        addSon(c, newIdentNodeP("true", p))
-      else:
-        addSon(c, expression(p))
-      addSon(result, c)
-      eatNewLine(p, c)
-  assert result != nil
-  
-proc parseDefBody(p: var TParser, m: var TMacro, params: seq[string]) =
-  m.body = @[]
-  # A little hack: We safe the context, so that every following token will be 
-  # put into a newly allocated TToken object. Thus we can just save a
-  # reference to the token in the macro's body.
-  saveContext(p)
-  while p.tok.xkind notin {pxEof, pxNewLine, pxLineComment}: 
-    case p.tok.xkind 
-    of pxSymbol:
-      # is it a parameter reference?
-      var tok = p.tok
-      for i in 0..high(params):
-        if params[i] == p.tok.s: 
-          new(tok)
-          tok.xkind = pxMacroParam
-          tok.iNumber = i
-          break
-      m.body.add(tok)
-    of pxDirConc: 
-      # just ignore this token: this implements token merging correctly
-      discard
-    else:
-      m.body.add(p.tok)
-    # we do not want macro expansion here:
-    rawGetTok(p)
-  eatNewLine(p, nil)
-  closeContext(p) 
-  # newline token might be overwritten, but this is not
-  # part of the macro body, so it is safe.
-  
-proc parseDef(p: var TParser, m: var TMacro) = 
-  var hasParams = p.tok.xkind == pxDirectiveParLe
-  getTok(p)
-  expectIdent(p)
-  m.name = p.tok.s
-  getTok(p)
-  var params: seq[string] = @[]
-  # parse parameters:
-  if hasParams:
-    eat(p, pxParLe)
-    while p.tok.xkind != pxParRi: 
-      expectIdent(p)
-      params.add(p.tok.s)
-      getTok(p)
-      skipStarCom(p, nil)
-      if p.tok.xkind != pxComma: break
-      getTok(p)
-    eat(p, pxParRi)
-  m.params = params.len
-  parseDefBody(p, m, params)
-  
-proc isDir(p: TParser, dir: string): bool = 
-  result = p.tok.xkind in {pxDirectiveParLe, pxDirective} and p.tok.s == dir
-
-proc parseInclude(p: var TParser): PNode = 
-  result = newNodeP(nkImportStmt, p)
-  while isDir(p, "include"):
-    getTok(p) # skip "include"
-    if p.tok.xkind == pxStrLit and pfSkipInclude notin p.options.flags:
-      var file = newStrNodeP(nkStrLit, changeFileExt(p.tok.s, ""), p)
-      addSon(result, file)
-      getTok(p)
-      skipStarCom(p, file)
-      eatNewLine(p, nil)
-    else:
-      skipLine(p)
-  if sonsLen(result) == 0: 
-    # we only parsed includes that we chose to ignore:
-    result = ast.emptyNode
-
-proc definedExprAux(p: var TParser): PNode = 
-  result = newNodeP(nkCall, p)
-  addSon(result, newIdentNodeP("defined", p))
-  addSon(result, skipIdent(p))
-
-proc parseStmtList(p: var TParser): PNode = 
-  result = newNodeP(nkStmtList, p)
-  while true: 
-    case p.tok.xkind
-    of pxEof: break 
-    of pxDirectiveParLe, pxDirective: 
-      case p.tok.s
-      of "else", "endif", "elif": break
-    else: discard
-    addSon(result, statement(p))
-  
-proc eatEndif(p: var TParser) =
-  if isDir(p, "endif"): 
-    skipLine(p)
-  else: 
-    parMessage(p, errXExpected, "#endif")
-  
-proc parseIfDirAux(p: var TParser, result: PNode) = 
-  addSon(result.sons[0], parseStmtList(p))
-  while isDir(p, "elif"): 
-    var b = newNodeP(nkElifBranch, p)
-    getTok(p)
-    addSon(b, expression(p))
-    eatNewLine(p, nil)
-    addSon(b, parseStmtList(p))
-    addSon(result, b)
-  if isDir(p, "else"): 
-    var s = newNodeP(nkElse, p)
-    skipLine(p)
-    addSon(s, parseStmtList(p))
-    addSon(result, s)
-  eatEndif(p)
-    
-proc skipUntilEndif(p: var TParser) =
-  var nested = 1
-  while p.tok.xkind != pxEof:
-    if isDir(p, "ifdef") or isDir(p, "ifndef") or isDir(p, "if"): 
-      inc(nested)
-    elif isDir(p, "endif"): 
-      dec(nested)
-      if nested <= 0:
-        skipLine(p)
-        return
-    getTok(p)
-  parMessage(p, errXExpected, "#endif")
-  
-type
-  TEndifMarker = enum
-    emElif, emElse, emEndif
-  
-proc skipUntilElifElseEndif(p: var TParser): TEndifMarker =
-  var nested = 1
-  while p.tok.xkind != pxEof:
-    if isDir(p, "ifdef") or isDir(p, "ifndef") or isDir(p, "if"): 
-      inc(nested)
-    elif isDir(p, "elif") and nested <= 1:
-      return emElif
-    elif isDir(p, "else") and nested <= 1:
-      return emElse
-    elif isDir(p, "endif"): 
-      dec(nested)
-      if nested <= 0:
-        return emEndif
-    getTok(p)
-  parMessage(p, errXExpected, "#endif")
-  
-proc parseIfdef(p: var TParser): PNode = 
-  getTok(p) # skip #ifdef
-  expectIdent(p)
-  case p.tok.s
-  of "__cplusplus":
-    skipUntilEndif(p)
-    result = ast.emptyNode
-  of c2nimSymbol:
-    skipLine(p)
-    result = parseStmtList(p)
-    skipUntilEndif(p)
-  else:
-    result = newNodeP(nkWhenStmt, p)
-    addSon(result, newNodeP(nkElifBranch, p))
-    addSon(result.sons[0], definedExprAux(p))
-    eatNewLine(p, nil)
-    parseIfDirAux(p, result)
-  
-proc parseIfndef(p: var TParser): PNode = 
-  result = ast.emptyNode
-  getTok(p) # skip #ifndef
-  expectIdent(p)
-  if p.tok.s == c2nimSymbol: 
-    skipLine(p)
-    case skipUntilElifElseEndif(p)
-    of emElif:
-      result = newNodeP(nkWhenStmt, p)
-      addSon(result, newNodeP(nkElifBranch, p))
-      getTok(p)
-      addSon(result.sons[0], expression(p))
-      eatNewLine(p, nil)
-      parseIfDirAux(p, result)
-    of emElse:
-      skipLine(p)
-      result = parseStmtList(p)
-      eatEndif(p)
-    of emEndif: skipLine(p)
-  else:
-    result = newNodeP(nkWhenStmt, p)
-    addSon(result, newNodeP(nkElifBranch, p))
-    var e = newNodeP(nkCall, p)
-    addSon(e, newIdentNodeP("not", p))
-    addSon(e, definedExprAux(p))
-    eatNewLine(p, nil)
-    addSon(result.sons[0], e)
-    parseIfDirAux(p, result)
-  
-proc parseIfDir(p: var TParser): PNode = 
-  result = newNodeP(nkWhenStmt, p)
-  addSon(result, newNodeP(nkElifBranch, p))
-  getTok(p)
-  addSon(result.sons[0], expression(p))
-  eatNewLine(p, nil)
-  parseIfDirAux(p, result)
-
-proc parsePegLit(p: var TParser): TPeg =
-  var col = getColumn(p.lex) + 2
-  getTok(p)
-  if p.tok.xkind != pxStrLit: expectIdent(p)
-  try:
-    result = parsePeg(
-      pattern = if p.tok.xkind == pxStrLit: p.tok.s else: escapePeg(p.tok.s), 
-      filename = p.lex.fileIdx.toFilename, 
-      line = p.lex.linenumber, 
-      col = col)
-    getTok(p)
-  except EInvalidPeg:
-    parMessage(p, errUser, getCurrentExceptionMsg())
-
-proc parseMangleDir(p: var TParser) = 
-  var pattern = parsePegLit(p)
-  if p.tok.xkind != pxStrLit: expectIdent(p)
-  p.options.mangleRules.add((pattern, p.tok.s))
-  getTok(p)
-  eatNewLine(p, nil)
-
-proc modulePragmas(p: var TParser): PNode = 
-  if p.options.dynlibSym.len > 0 and not p.hasDeadCodeElimPragma:
-    p.hasDeadCodeElimPragma = true
-    result = newNodeP(nkPragma, p)
-    var e = newNodeP(nkExprColonExpr, p)
-    addSon(e, newIdentNodeP("deadCodeElim", p), newIdentNodeP("on", p))
-    addSon(result, e)
-  else:
-    result = ast.emptyNode
-
-proc parseDir(p: var TParser): PNode = 
-  result = ast.emptyNode
-  assert(p.tok.xkind in {pxDirective, pxDirectiveParLe})
-  case p.tok.s
-  of "define": result = parseDefine(p)
-  of "include": result = parseInclude(p)
-  of "ifdef": result = parseIfdef(p)
-  of "ifndef": result = parseIfndef(p)
-  of "if": result = parseIfDir(p)
-  of "cdecl", "stdcall", "ref", "skipinclude", "typeprefixes", "skipcomments": 
-    discard setOption(p.options, p.tok.s)
-    getTok(p)
-    eatNewLine(p, nil)
-  of "dynlib", "header", "prefix", "suffix", "class": 
-    var key = p.tok.s
-    getTok(p)
-    if p.tok.xkind != pxStrLit: expectIdent(p)
-    discard setOption(p.options, key, p.tok.s)
-    getTok(p)
-    eatNewLine(p, nil)
-    result = modulePragmas(p)
-  of "mangle":
-    parseMangleDir(p)
-  of "def":
-    var L = p.options.macros.len
-    setLen(p.options.macros, L+1)
-    parseDef(p, p.options.macros[L])
-  of "private":
-    var pattern = parsePegLit(p)
-    p.options.privateRules.add(pattern)
-    eatNewLine(p, nil)
-  else: 
-    # ignore unimportant/unknown directive ("undef", "pragma", "error")
-    skipLine(p)
-
diff --git a/compiler/c2nim/nimrod.cfg b/compiler/c2nim/nimrod.cfg
deleted file mode 100644
index cfeda63ed..000000000
--- a/compiler/c2nim/nimrod.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# Use the modules of the compiler
-
-path: "$nimrod/compiler"
-
diff --git a/compiler/c2nim/tests/enum.h b/compiler/c2nim/tests/enum.h
deleted file mode 100644
index 16bc59058..000000000
--- a/compiler/c2nim/tests/enum.h
+++ /dev/null
@@ -1,40 +0,0 @@
-
-enum vehicles
-{
-	car = 0x10,
-	truck,
-	boat = 0x01,
-	ship = 1,
-	speedboat = 1,
-	bicycle = 4,
-	bobycar
-};
-
-enum
-{
-	red = 4,
-	green = 2,
-	blue
-};
-
-typedef enum food
-{
-	bread = 4,
-	toast = 4,
-	bun = 0x04,
-	cucumber = 2,
-	chocolate = 6
-};
-
-typedef enum numbers
-{
-	one = 1,
-	two,
-	nten = - 10,
-	nnine,
-	four = 4,
-	three = + 3,
-	positivenine = + 9,
-	nfour = - 4,
-	negativeten = -10
-};
\ No newline at end of file
diff --git a/compiler/c2nim/tests/matrix.h b/compiler/c2nim/tests/matrix.h
deleted file mode 100644
index 715e9e43b..000000000
--- a/compiler/c2nim/tests/matrix.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////

-// Name:         wx/matrix.h

-// Purpose:      wxTransformMatrix class. NOT YET USED

-// Author:       Chris Breeze, Julian Smart

-// Modified by:  Klaas Holwerda

-// Created:      01/02/97

-// RCS-ID:       $Id$

-// Copyright:    (c) Julian Smart, Chris Breeze

-// Licence:      wxWindows licence

-/////////////////////////////////////////////////////////////////////////////

-

-#ifndef _WX_MATRIXH__

-#define _WX_MATRIXH__

-

-//! headerfiles="matrix.h wx/object.h"

-#include "wx/object.h"

-#include "wx/math.h"

-

-//! codefiles="matrix.cpp"

-

-// A simple 3x3 matrix. This may be replaced by a more general matrix

-// class some day.

-//

-// Note: this is intended to be used in wxDC at some point to replace

-// the current system of scaling/translation. It is not yet used.

-
-#def WXDLLIMPEXP_CORE
-#header "wxmatrix.h"
-

-//:definition

-//  A 3x3 matrix to do 2D transformations.

-//  It can be used to map data to window coordinates,

-//  and also for manipulating your own data.

-//  For example drawing a picture (composed of several primitives)

-//  at a certain coordinate and angle within another parent picture.

-//  At all times m_isIdentity is set if the matrix itself is an Identity matrix.

-//  It is used where possible to optimize calculations.

-class WXDLLIMPEXP_CORE wxTransformMatrix: public wxObject<string, string<ubyte>>

-{

-public:

-    wxTransformMatrix(void);

-    wxTransformMatrix(const wxTransformMatrix& mat);
-    
-    ~wxTransformMatrix(void);

-

-    //get the value in the matrix at col,row

-    //rows are horizontal (second index of m_matrix member)

-    //columns are vertical (first index of m_matrix member)

-    double GetValue(int col, int row) const;

-

-    //set the value in the matrix at col,row

-    //rows are horizontal (second index of m_matrix member)

-    //columns are vertical (first index of m_matrix member)

-    void SetValue(int col, int row, double value);

-

-    void operator = (const wxTransformMatrix& mat);

-    bool operator == (const wxTransformMatrix& mat) const;

-    bool operator != (const module::gah::wxTransformMatrix& mat) const;

-

-    //multiply every element by t

-    wxTransformMatrix&          operator*=(const double& t);

-    //divide every element by t

-    wxTransformMatrix&          operator/=(const double& t);

-    //add matrix m to this t

-    wxTransformMatrix&          operator+=(const wxTransformMatrix& m);

-    //subtract matrix m from this

-    wxTransformMatrix&          operator-=(const wxTransformMatrix& m);

-    //multiply matrix m with this

-    wxTransformMatrix&          operator*=(const wxTransformMatrix& m);

-

-    // constant operators

-

-    //multiply every element by t  and return result

-    wxTransformMatrix           operator*(const double& t) const;

-    //divide this matrix by t and return result

-    wxTransformMatrix           operator/(const double& t) const;

-    //add matrix m to this and return result

-    wxTransformMatrix           operator+(const wxTransformMatrix& m) const;

-    //subtract matrix m from this and return result

-    wxTransformMatrix           operator-(const wxTransformMatrix& m) const;

-    //multiply this by matrix m and return result

-    wxTransformMatrix           operator*(const wxTransformMatrix& m) const;

-    wxTransformMatrix           operator-() const;

-

-    //rows are horizontal (second index of m_matrix member)

-    //columns are vertical (first index of m_matrix member)

-    double& operator()(int col, int row);

-

-    //rows are horizontal (second index of m_matrix member)

-    //columns are vertical (first index of m_matrix member)

-    double operator()(int col, int row) const;

-

-    // Invert matrix

-    bool Invert(void);

-

-    // Make into identity matrix

-    bool Identity(void);

-

-    // Is the matrix the identity matrix?

-    // Only returns a flag, which is set whenever an operation

-    // is done.

-    inline bool IsIdentity(void) const { return m_isIdentity; }

-

-    // This does an actual check.

-    inline bool IsIdentity1(void) const ;

-

-    //Scale by scale (isotropic scaling i.e. the same in x and y):

-    //!ex:

-    //!code:           | scale  0      0      |

-    //!code: matrix' = |  0     scale  0      | x matrix

-    //!code:           |  0     0      scale  |

-    bool Scale(double scale);

-

-    //Scale with center point and x/y scale

-    //

-    //!ex:

-    //!code:           |  xs    0      xc(1-xs) |

-    //!code: matrix' = |  0    ys      yc(1-ys) | x matrix

-    //!code:           |  0     0      1        |

-    wxTransformMatrix&  Scale(const double &xs, const double &ys,const double &xc, const double &yc);

-

-    // mirror a matrix in x, y

-    //!ex:

-    //!code:           | -1     0      0 |

-    //!code: matrix' = |  0    -1      0 | x matrix

-    //!code:           |  0     0      1 |

-    wxTransformMatrix<float>&  Mirror(bool x=true, bool y=false);

-    // Translate by dx, dy:

-    //!ex:

-    //!code:           | 1  0 dx |

-    //!code: matrix' = | 0  1 dy | x matrix

-    //!code:           | 0  0  1 |

-    bool Translate(double x, double y);

-

-    // Rotate clockwise by the given number of degrees:

-    //!ex:

-    //!code:           |  cos sin 0 |

-    //!code: matrix' = | -sin cos 0 | x matrix

-    //!code:           |   0   0  1 |

-    bool Rotate(double angle);

-

-    //Rotate counter clockwise with point of rotation

-    //

-    //!ex:

-    //!code:           |  cos(r) -sin(r)    x(1-cos(r))+y(sin(r)|

-    //!code: matrix' = |  sin(r)  cos(r)    y(1-cos(r))-x(sin(r)| x matrix

-    //!code:           |   0          0                       1 |

-    wxTransformMatrix&  Rotate(const double &r, const double &x, const double &y);

-

-    // Transform X value from logical to device

-    inline double TransformX(double x) const;

-

-    // Transform Y value from logical to device

-    inline double TransformY(double y) const;

-

-    // Transform a point from logical to device coordinates

-    bool TransformPoint(double x, double y, double& tx, double& ty) const;

-

-    // Transform a point from device to logical coordinates.

-    // Example of use:

-    //   wxTransformMatrix mat = dc.GetTransformation();

-    //   mat.Invert();

-    //   mat.InverseTransformPoint(x, y, x1, y1);

-    // OR (shorthand:)

-    //   dc.LogicalToDevice(x, y, x1, y1);

-    // The latter is slightly less efficient if we're doing several

-    // conversions, since the matrix is inverted several times.

-    // N.B. 'this' matrix is the inverse at this point

-    bool InverseTransformPoint(double x, double y, double& tx, double& ty) const;

-

-    double Get_scaleX();

-    double Get_scaleY();

-    double GetRotation();

-    void   SetRotation(double rotation);

-

-

-public:

-    double  m_matrix[3][3];

-    bool    m_isIdentity;

-};

-

-

-/*

-Chris Breeze reported, that

-some functions of wxTransformMatrix cannot work because it is not

-known if he matrix has been inverted. Be careful when using it.

-*/

-

-// Transform X value from logical to device

-// warning: this function can only be used for this purpose

-// because no rotation is involved when mapping logical to device coordinates

-// mirror and scaling for x and y will be part of the matrix

-// if you have a matrix that is rotated, eg a shape containing a matrix to place

-// it in the logical coordinate system, use TransformPoint

-inline double wxTransformMatrix::TransformX(double x) const

-{

-    //normally like this, but since no rotation is involved (only mirror and scale)

-    //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero

-    //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0]))

-    return (m_isIdentity ? x : (x * m_matrix[0][0] +  m_matrix[2][0]));

-}

-

-// Transform Y value from logical to device

-// warning: this function can only be used for this purpose

-// because no rotation is involved when mapping logical to device coordinates

-// mirror and scaling for x and y will be part of the matrix

-// if you have a matrix that is rotated, eg a shape containing a matrix to place

-// it in the logical coordinate system, use TransformPoint

-inline double wxTransformMatrix::TransformY(double y) const

-{

-    //normally like this, but since no rotation is involved (only mirror and scale)

-    //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero

-    //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1]))

-    return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1]));

-}

-

-

-// Is the matrix the identity matrix?

-// Each operation checks whether the result is still the identity matrix and sets a flag.

-inline bool wxTransformMatrix::IsIdentity1(void) const

-{

-    return

-    ( wxIsSameDouble(m_matrix[0][0], 1.0) &&

-      wxIsSameDouble(m_matrix[1][1], 1.0) &&

-      wxIsSameDouble(m_matrix[2][2], 1.0) &&

-      wxIsSameDouble(m_matrix[1][0], 0.0) &&

-      wxIsSameDouble(m_matrix[2][0], 0.0) &&

-      wxIsSameDouble(m_matrix[0][1], 0.0) &&

-      wxIsSameDouble(m_matrix[2][1], 0.0) &&

-      wxIsSameDouble(m_matrix[0][2], 0.0) &&

-      wxIsSameDouble(m_matrix[1][2], 0.0) );

-}

-

-// Calculates the determinant of a 2 x 2 matrix

-inline double wxCalculateDet(double a11, double a21, double a12, double a22)

-{

-    return a11 * a22 - a12 * a21;

-}
-

-#endif // _WX_MATRIXH__

diff --git a/compiler/c2nim/tests/struct_anonym.h b/compiler/c2nim/tests/struct_anonym.h
deleted file mode 100644
index 859bfc206..000000000
--- a/compiler/c2nim/tests/struct_anonym.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-struct normal{
-	int a;
-	int b;
-};
-
-typedef struct outerStruct {
-	struct normal a_nomal_one;
-	
-	int a;
-	
-	struct {
-		union {
-			int b;
-		} a_union_in_the_struct;
-		
-		int c;
-	};
-	
-	union {
-		int d;
-		
-		struct {
-			int e;
-		} a_struct_in_the_union;
-	} a_union;
-};
\ No newline at end of file
diff --git a/compiler/c2nim/tests/systest.c b/compiler/c2nim/tests/systest.c
deleted file mode 100644
index 51509e253..000000000
--- a/compiler/c2nim/tests/systest.c
+++ /dev/null
@@ -1,622 +0,0 @@
-/* This file has been written by Blablub.
- *
- * Another comment line.
- */
-
-#ifdef __cplusplus
-#  ifdef __SOME_OTHER_CRAP
-extern "C" {
-#  endif
-#endif
-
-#define interrupts() sei()
-
-enum
-{
-/* 8bit, color or not */
-    CV_LOAD_IMAGE_UNCHANGED  =-1,
-/* 8bit, gray */
-    CV_LOAD_IMAGE_GRAYSCALE  =0,
-/* ?, color */
-    CV_LOAD_IMAGE_COLOR      =1,
-/* any depth, ? */
-    CV_LOAD_IMAGE_ANYDEPTH   =2,
-/* ?, any color */
-    CV_LOAD_IMAGE_ANYCOLOR   =4
-};
-
-typedef void (*callback_t) (int rc);
-typedef const char* (*callback2)(int rc, long L, const char* buffer);
-
-int   aw_callback_set (AW_CALLBACK c, callback_t callback );
-int   aw_instance_callback_set (AW_CALLBACK c, callback_t callback);
-
-unsigned long int wawa;
-
-#define MAX(x, y) ((x) < (y)? (y) : (x))
-
-#define AW_BUILD 85 // AW 5.0
-// Limits
-#define AW_MAX_AVCHANGE_PER_SECOND 10
-
-#private expatDll
-
-#if !defined(expatDll)
-#  if defined(windows)
-#    define expatDll "expat.dll"
-#  elif defined(macosx)
-#    define expatDll "libexpat.dynlib"
-#  else
-#    define expatDll "libexpat.so(.1|)"
-#  endif
-#endif
-
-#mangle "'XML_'{.*}" "$1"
-#private "'XML_ParserStruct'"
-
-#mangle cuint cint
-
-unsigned int uiVar;
-
-#private "@('_'!.)"
-unsigned int myPrivateVar__;
-
-
-struct XML_ParserStruct;
-
-#def XMLCALL __cdecl
-
-typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
-                                                const XML_Char *name,
-                                                XML_Content *model);
-
-
-void* x;
-void* fn(void);
-void (*fn)(void);
-void* (*fn)(void);
-void* (*fn)(void*);
-
-/*
- * Very ugly real world code ahead:
- */
-
-#def JMETHOD(rettype, name, params) rettype (*name) params
-
-typedef struct cjpeg_source_struct * cjpeg_source_ptr;
-
-struct cjpeg_source_struct {
-  JMETHOD(void, start_input, (j_compress_ptr cinfo,
-			      cjpeg_source_ptr sinfo));
-  JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo,
-				       cjpeg_source_ptr sinfo));
-  JMETHOD(void, finish_input, (j_compress_ptr cinfo,
-			       cjpeg_source_ptr sinfo));
-
-  FILE *input_file;
-
-  JSAMPARRAY buffer;
-  JDIMENSION buffer_height;
-};
-
-// Test standalone structs: 
-
-union myunion {
-  char x, y, *z;
-  myint a, b;  
-} u;
-
-struct mystruct {
-  char x, y, *z;
-  myint a, b;
-}; 
-
-struct mystruct fn(i32 x, i64 y);
-
-struct mystruct {
-  char x, y, *z;
-  myint a, b;
-} *myvar = NULL, **myvar2 = NULL; 
-
-// anonymous struct: 
-
-struct {
-  char x, y, *z;
-  myint a, b;  
-} varX, **varY;
-
-// empty anonymous struct: 
-
-struct {
-
-} varX, **varY;
-
-// Test C2NIM skipping:
-
-#define MASK(x) ((x) & 0xff)
-#define CAST1(x) ((int) &x)
-#define CAST2(x) (typ*) &x
-#define CAST3(x) ((const unsigned char**) &x)
-
-#ifndef C2NIM 
-  #if someNestedCond
-    This is an invalid text that should generate a parser error, if not 
-  #endif
-    skipped correctly.
-#endif
-
-#ifndef C2NIM
-  #if someNestedCond
-    This is an invalid text that should generate a parser error, if not 
-  #endif
-    skipped correctly.
-#else
-typedef char gchar;
-typedef unsigned int gunsignedint;
-typedef unsigned char guchar;
-#endif
-
-#ifdef C2NIM
-# mangle "'those'" "these"
-int those;
-#elif abc
-  #if someNestedCond
-    This is an invalid text that should generate a parser error, if not 
-  #else
-    skipped correctly.
-  #endif
-#else
-  Another crappy input line.
-#endif
-
-point* newPoint(void) {  
-  for (int i = 0; i < 89; ++i) echo("test" " string "  "concatenation");
-  for (; j < 54; j++) {}
-  for (;; j--) ;
-  for (;;) {}
-  mytype * x = y * z;
- 
-  if (**p == ' ') {
-    --p;
-  } else if (**p == '\t') {
-    p += 3;
-  } else { 
-    p = 45 + (mytype*)45;
-    p = 45 + ((mytype*)45);
-    p = 45 + ((mytype)45);
-    // BUG: This does not parse:
-    // p = 45 + (mytype)45;
-  }
-
-  while (x >= 6 && x <= 20) 
-    --x;
-  
-  switch (*p) {
-    case 'A'...'Z':
-    case 'a'...'z':
-      ++p;
-      break;
-    case '0':
-      ++p;
-      break;
-    default:
-      return NULL;
-  }
-}
-
-enum {
-  a1, a2 = 4, a3
-};
-
-typedef enum crazyTAG {
-  x1, x2, x3 = 8, x4, x5
-} myEnum, *pMyEnum;
-
-typedef enum {
-  x1, x2, x3 = 8, x4, x5
-} myEnum, *pMyEnum;
-
-// Test multi-line macro: 
-
-#define MUILTILINE "abc" \ 
-  "xyz" \
-  "def"
-
-#define MULTILINE(x, y) do { \
-  ++y; ++x; \
-} while (0)
-
-#ifdef C2NIM
-#  dynlib iupdll
-#  cdecl
-#  mangle "'GTK_'{.*}" "TGtk$1"
-#  mangle "'PGTK_'{.*}" "PGtk$1"
-#  if defined(windows)
-#    define iupdll "iup.dll"
-#  elif defined(macosx)
-#    define iupdll "libiup.dynlib"
-#  else
-#    define iupdll "libiup.so"
-#  endif
-#endif
-
-typedef struct stupidTAG {
-  mytype a, b;
-} GTK_MyStruct, *PGTK_MyStruct;
-
-typedef struct  {
-  mytype a, b;
-} GTK_MyStruct, *PGTK_MyStruct;
-
-int IupConvertXYToPos(PIhandle ih, int x, int y);
-
-#ifdef DEBUG
-#  define OUT(x) printf("%s\n", x)
-#else
-#  define OUT(x)
-#endif
-
-
-  #ifdef C2NIM
-  #  def EXTERN(x) static x
-  #  def TWO_ARGS(x, y) x* y
-  #endif
-  // parses now!
-  EXTERN(int) f(void);
-  EXTERN(int) g(void);
-
-
-  #def EXPORT
-  // does parse now!
-  EXPORT int f(void);
-  EXPORT int g(void); 
-
-  static TWO_ARGS(int, x) = TWO_ARGS(56, 45);
-
-
-#  define abc 34
-#  define xyz 42
-
-#  define wuseldusel "my string\nconstant"
-
-#undef ignoreThis
-
-char* x;
-
-typedef struct {
-  char x, y, *z;
-} point;
-
-char* __stdcall printf(char* frmt, const char* const** ptrToStrArray,
-             const int* const dummy, ...);
-
-inline char* myinlineProc(char* frmt, const char* const* strArray,
-             const int* const dummy, ...);
-
-// Test void parameter list:
-void myVoidProc(void);
-
-void emptyReturn(void) { return; }
-
-// POSIX stuff:
-
-#ifdef C2NIM
-#prefix posix_
-int c2nimBranch;
-#elif defined(MACOSX)
-int* x, y, z;
-#else
-int dummy;
-#endif
-
-#ifndef C2NIM
-int dontTranslateThis;
-#elif defined(Windows)
-int WindowsTrue = true;
-#endif
-
-int   posix_spawn(pid_t *restrict, const char *restrict,
-          const posix_spawn_file_actions_t *,
-          const posix_spawnattr_t *restrict, char *const [restrict],
-          char *const [restrict]);
-int   posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *,
-          int);
-int   posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *,
-          int, int);
-int   posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *restrict,
-          int, const char *restrict, int, mode_t);
-int   posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *);
-int   posix_spawn_file_actions_init(posix_spawn_file_actions_t *);
-int   posix_spawnattr_destroy(posix_spawnattr_t *);
-int   posix_spawnattr_getsigdefault(const posix_spawnattr_t *restrict,
-          sigset_t *restrict);
-int   posix_spawnattr_getflags(const posix_spawnattr_t *restrict,
-          short *restrict);
-int   posix_spawnattr_getpgroup(const posix_spawnattr_t *restrict,
-          pid_t *restrict);
-int   posix_spawnattr_getschedparam(const posix_spawnattr_t *restrict,
-          struct sched_param *restrict);
-int   posix_spawnattr_getschedpolicy(const posix_spawnattr_t *restrict,
-          int *restrict);
-int   posix_spawnattr_getsigmask(const posix_spawnattr_t *restrict,
-          sigset_t *restrict);
-int   posix_spawnattr_init(posix_spawnattr_t *);
-int   posix_spawnattr_setsigdefault(posix_spawnattr_t *restrict,
-          const sigset_t *restrict);
-int   posix_spawnattr_setflags(posix_spawnattr_t *, short);
-int   posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t);
-
-
-int   posix_spawnattr_setschedparam(posix_spawnattr_t *restrict,
-          const struct sched_param *restrict);
-int   posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int);
-int   posix_spawnattr_setsigmask(posix_spawnattr_t *restrict,
-          const sigset_t *restrict);
-int   posix_spawnp(pid_t *restrict, const char *restrict,
-          const posix_spawn_file_actions_t *,
-          const posix_spawnattr_t *restrict,
-          char *const [restrict], char *const [restrict]);
-
-typedef struct
-{
-  float R, G, B;
-}
-RGBType;
-typedef struct
-{
-  float H, W, B;
-}
-HWBType;
-
-static HWBType *
-RGB_to_HWB (RGBType RGB, HWBType * HWB)
-{
-  HWBType* myArray[20];
-  /*
-   * RGB are each on [0, 1]. W and B are returned on [0, 1] and H is  
-   * returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B.  
-   */
-
-  float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f;
-  int i;
-
-  w = MIN3 (R, G, B);
-  v = MAX3 (R, G, B);
-  b &= 1 - v;
-  if (v == w)
-    RETURN_HWB (HWB_UNDEFINED, w, b);
-  f = (R == w) ? G - B : ((G == w) ? B - R : R - G);
-  i = (R == w) ? 3 : ((G == w) ? 5 : 1);
-  RETURN_HWB (i - f / (v - w), w, b);
-
-}
-
-static int
-clip_1d (int *x0, int *y0, int *x1, int *y1, int mindim, int maxdim)
-{
-  double m;                        // gradient of line
-  if (*x0 < mindim)
-    {                                // start of line is left of window 
-      if (*x1 < mindim) // as is the end, so the line never cuts the window 
-        return 0;
-      m = (*y1 - *y0) / (double) (*x1 - *x0); // calculate the slope of the line
-      // adjust x0 to be on the left boundary (ie to be zero), and y0 to match 
-      *y0 -= m * (*x0 - mindim);
-      *x0 = mindim;
-      // now, perhaps, adjust the far end of the line as well
-      if (*x1 > maxdim)
-        {
-          *y1 += m * (maxdim - *x1);
-          *x1 = maxdim;
-        }
-      return 1;
-    }
-  if (*x0 > maxdim)
-    { // start of line is right of window - complement of above 
-      if (*x1 > maxdim) // as is the end, so the line misses the window 
-        return 0;
-      m = (*y1 - *y0) / (double) (*x1 - *x0); // calculate the slope of the line
-      *y0 += m * (maxdim - *x0);        // adjust so point is on the right
-                                        // boundary
-      *x0 = maxdim;
-      // now, perhaps, adjust the end of the line
-      if (*x1 < mindim)
-        {
-          *y1 -= m * (*x1 - mindim);
-          *x1 = mindim;
-        }
-      return 1;
-    }
-  // the final case - the start of the line is inside the window
-  if (*x1 > maxdim)
-    {                                // other end is outside to the right
-      m = (*y1 - *y0) / (double) (*x1 - *x0); // calculate the slope of the line 
-      *y1 += m * (maxdim - *x1);
-      *x1 = maxdim;
-      return 1;
-    }
-  if (*x1 < mindim)
-    {                                // other end is outside to the left 
-      m = (*y1 - *y0) / (double) (*x1 - *x0); // calculate the slope of line 
-             *y1 -= m * (*x1 - mindim);
-      *x1 = mindim;
-      return 1;
-    }
-  // only get here if both points are inside the window
-  return 1;
-}
-
-// end of line clipping code
-
-static void
-gdImageBrushApply (gdImagePtr im, int x, int y)
-{
-  int lx, ly;
-  int hy;
-  int hx;
-  int x1, y1, x2, y2;
-  int srcx, srcy;
-  if (!im->brush)
-    {
-      return;
-    }
-  hy = gdImageSY (im->brush) / 2;
-  y1 = y - hy;
-  y2 = y1 + gdImageSY (im->brush);
-  hx = gdImageSX (im->brush) / 2;
-  x1 = x - hx;
-  x2 = x1 + gdImageSX (im->brush);
-  srcy = 0;
-  if (im->trueColor)
-    {
-      if (im->brush->trueColor)
-        {
-          for (ly = y1; (ly < y2); ly++)
-            {
-              srcx = 0;
-              for (lx = x1; (lx < x2); lx++)
-                {
-                  int p;
-                  p = gdImageGetTrueColorPixel (im->brush, srcx, srcy);
-                  // 2.0.9, Thomas Winzig: apply simple full transparency
-                  if (p != gdImageGetTransparent (im->brush))
-                    {
-                      gdImageSetPixel (im, lx, ly, p);
-                    }
-                  srcx++;
-                }
-              srcy++;
-            }
-        }
-      else
-        {
-          // 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger
-          // for pointing out the issue)
-          for (ly = y1; (ly < y2); ly++)
-            {
-              srcx = 0;
-              for (lx = x1; (lx < x2); lx++)
-                {
-                  int p, tc;
-                  p = gdImageGetPixel (im->brush, srcx, srcy);
-                  tc = gdImageGetTrueColorPixel (im->brush, srcx, srcy);
-                  // 2.0.9, Thomas Winzig: apply simple full transparency 
-                  if (p != gdImageGetTransparent (im->brush))
-                    {
-                      gdImageSetPixel (im, lx, ly, tc);
-                    }
-                  srcx++;
-                }
-              srcy++;
-            }
-        }
-    }
-  else
-    {
-      for (ly = y1; (ly < y2); ly++)
-        {
-          srcx = 0;
-          for (lx = x1; (lx < x2); lx++)
-            {
-              int p;
-              p = gdImageGetPixel (im->brush, srcx, srcy);
-              // Allow for non-square brushes!
-              if (p != gdImageGetTransparent (im->brush))
-                {
-                  // Truecolor brush. Very slow
-                  // on a palette destination.
-                  if (im->brush->trueColor)
-                    {
-                      gdImageSetPixel (im, lx, ly,
-                                       gdImageColorResolveAlpha(im,
-                                       gdTrueColorGetRed(p),
-                                       gdTrueColorGetGreen(p),
-                                       gdTrueColorGetBlue(p),
-                                       gdTrueColorGetAlpha(p)));
-                    }
-                  else
-                    {
-                      gdImageSetPixel (im, lx, ly, im->brushColorMap[p]);
-                    }
-                }
-              srcx++;
-            }
-          srcy++;
-        }
-    } 
-}
-
-
-void gdImageSetPixel (gdImagePtr im, int x, int y, int color)
-{
-  int p;
-  switch (color)
-    {
-    case gdStyled:
-      if (!im->style)
-        {
-          // Refuse to draw if no style is set.
-          return;
-        }
-      else
-        {
-          p = im->style[im->stylePos++];
-        }
-      if (p != (gdTransparent))
-        {
-          gdImageSetPixel (im, x, y, p);
-        }
-      im->stylePos = im->stylePos % im->styleLength;
-      break;
-    case gdStyledBrushed:
-      if (!im->style)
-        {
-          // Refuse to draw if no style is set.
-          return;
-        }
-      p = im->style[im->stylePos++];
-      if ((p != gdTransparent) && (p != 0))
-        {
-          gdImageSetPixel (im, x, y, gdBrushed);
-        }
-      im->stylePos = im->stylePos % im->styleLength;
-      break;
-    case gdBrushed:
-      gdImageBrushApply (im, x, y);
-      break;
-    case gdTiled:
-      gdImageTileApply (im, x, y);
-      break;
-    case gdAntiAliased:
-      // This shouldn't happen (2.0.26) because we just call
-      // gdImageAALine now, but do something sane.
-      gdImageSetPixel(im, x, y, im->AA_color);
-      break;
-    default:
-      if (gdImageBoundsSafeMacro (im, x, y))
-        {
-          if (im->trueColor)
-            {
-              if (im->alphaBlendingFlag)
-                {
-                  im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color);
-                }
-              else
-                {
-                  im->tpixels[y][x] = color;
-                }
-            }
-          else
-            {
-              im->pixels[y][x] = color;
-            }
-        }
-      break;
-    }
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-
diff --git a/compiler/c2nim/tests/systest2.c b/compiler/c2nim/tests/systest2.c
deleted file mode 100644
index bf3027cfc..000000000
--- a/compiler/c2nim/tests/systest2.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifdef C2NIM
-#  header "iup.h"
-#  cdecl
-#  mangle "'GTK_'{.*}" "TGtk$1"
-#  mangle "'PGTK_'{.*}" "PGtk$1"
-#endif
-
-typedef struct stupidTAG {
-  mytype a, b;
-} GTK_MyStruct, *PGTK_MyStruct;
-
-typedef struct  {
-  mytype a, b;
-} GTK_MyStruct, *PGTK_MyStruct;
-
-int IupConvertXYToPos(PIhandle ih, int x, int y);
-
diff --git a/compiler/c2nim/tests/vincent.c b/compiler/c2nim/tests/vincent.c
deleted file mode 100644
index 24c6d6425..000000000
--- a/compiler/c2nim/tests/vincent.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-int rand(void);
-
-int id2(void) {
-    return (int *)1;
-}
-
-int id(void (*f)(void)) {
-    f();
-    ((void (*)(int))f)(10);
-    return 10;
-    return (20+1);
-    return (int *)id;
-}
-
-int main() {
-    float f = .2,
-          g = 2.,
-          h = 1.0+rand(),
-          i = 1.0e+3;
-    int j, a;
-    for(j = 0, a = 10; j < 0; j++, a++) ;
-    do {
-        printf("howdy");
-    } while(--i, 0);
-    if(1)
-        printf("1"); // error from this comment
-    else
-        printf("2");
-    return '\x00';
-}
diff --git a/compiler/c2nim/tests/vincent.h b/compiler/c2nim/tests/vincent.h
deleted file mode 100644
index b4e761ee1..000000000
--- a/compiler/c2nim/tests/vincent.h
+++ /dev/null
@@ -1,3 +0,0 @@
-struct foo {
-    int x,y,z;
-};
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 4698082f1..3fe6140a3 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -359,6 +359,32 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
   else: internalError("genAssignment: " & $ty.kind)
 
+proc genDeepCopy(p: BProc; dest, src: TLoc) =
+  var ty = skipTypes(dest.t, abstractVarRange)
+  case ty.kind
+  of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray, tyArrayConstr:
+    # XXX optimize this
+    linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
+            addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
+  of tySequence, tyString:
+    linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
+            addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
+  of tyOpenArray, tyVarargs:
+    linefmt(p, cpsStmts,
+         "#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
+         addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
+  of tySet:
+    if mapType(ty) == ctArray:
+      useStringh(p.module)
+      linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
+              rdLoc(dest), rdLoc(src), toRope(getSize(dest.t)))
+    else:
+      linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
+  of tyPointer, tyChar, tyBool, tyEnum, tyCString,
+     tyInt..tyUInt64, tyRange, tyVar:
+    linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
+  else: internalError("genDeepCopy: " & $ty.kind)
+
 proc getDestLoc(p: BProc, d: var TLoc, typ: PType) =
   if d.k == locNone: getTemp(p, typ, d)
 
@@ -1260,6 +1286,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)")
     else: unaryExpr(p, e, d, "$1Len0")
   of tyCString:
+    useStringh(p.module)
     if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
     else: unaryExpr(p, e, d, "strlen($1)")
   of tyString, tySequence:
@@ -1578,25 +1605,25 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mGetTypeInfo: genGetTypeInfo(p, e, d)
   of mSwap: genSwap(p, e, d)
   of mUnaryLt: 
-    if not (optOverflowCheck in p.options): unaryExpr(p, e, d, "$1 - 1")
+    if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
     else: unaryExpr(p, e, d, "#subInt($1, 1)")
   of mPred:
     # XXX: range checking?
-    if not (optOverflowCheck in p.options): binaryExpr(p, e, d, "$1 - $2")
+    if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 - $2)")
     else: binaryExpr(p, e, d, "#subInt($1, $2)")
   of mSucc:
     # XXX: range checking?
-    if not (optOverflowCheck in p.options): binaryExpr(p, e, d, "$1 + $2")
+    if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 + $2)")
     else: binaryExpr(p, e, d, "#addInt($1, $2)")
   of mInc:
-    if not (optOverflowCheck in p.options):
+    if optOverflowCheck notin p.options:
       binaryStmt(p, e, d, "$1 += $2;$n")
     elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
       binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n")
     else:
       binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n")
   of ast.mDec:
-    if not (optOverflowCheck in p.options):
+    if optOverflowCheck notin p.options:
       binaryStmt(p, e, d, "$1 -= $2;$n")
     elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
       binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n")
@@ -1640,7 +1667,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
      mInSet:
     genSetOp(p, e, d, op)
-  of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit:
+  of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit,
+      mParseBiggestFloat:
     var opr = e.sons[0].sym
     if lfNoDecl notin opr.loc.flags:
       discard cgsym(p.module, opr.loc.r.ropeToStr)
@@ -1658,6 +1686,12 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mParallel:
     let n = semparallel.liftParallel(p.module.module, e)
     expr(p, n, d)
+  of mDeepCopy:
+    var a, b: TLoc
+    let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1]
+    initLocExpr(p, x, a)
+    initLocExpr(p, e.sons[2], b)
+    genDeepCopy(p, a, b)
   else: internalError(e.info, "genMagicExpr: " & $op)
 
 proc genConstExpr(p: BProc, n: PNode): PRope
@@ -1877,7 +1911,8 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
     of skVar, skForVar, skResult, skLet:
       if sfGlobal in sym.flags: genVarPrototype(p.module, sym)
       if sym.loc.r == nil or sym.loc.t == nil:
-        internalError(n.info, "expr: var not init " & sym.name.s)
+        #echo "FAILED FOR PRCO ", p.prc.name.s
+        internalError n.info, "expr: var not init " & sym.name.s & "_" & $sym.id
       if sfThread in sym.flags:
         accessThreadLocalVar(p, sym)
         if emulatedThreadVars(): 
@@ -1888,11 +1923,14 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
         putLocIntoDest(p, d, sym.loc)
     of skTemp:
       if sym.loc.r == nil or sym.loc.t == nil:
-        internalError(n.info, "expr: temp not init " & sym.name.s)
+        #echo "FAILED FOR PRCO ", p.prc.name.s
+        #echo renderTree(p.prc.ast, {renderIds})
+        internalError(n.info, "expr: temp not init " & sym.name.s & "_" & $sym.id)
       putLocIntoDest(p, d, sym.loc)
     of skParam:
       if sym.loc.r == nil or sym.loc.t == nil:
-        internalError(n.info, "expr: param not init " & sym.name.s)
+        #echo "FAILED FOR PRCO ", p.prc.name.s
+        internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
       putLocIntoDest(p, d, sym.loc)
     else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol")
   of nkNilLit:
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 8e762ce27..4c71c6ff7 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -453,7 +453,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
     appf(result, " {$n", [name])
 
   var desc = getRecordFields(m, typ, check)
-  if (desc == nil) and not hasField: 
+  if desc == nil and not hasField: 
     appf(result, "char dummy;$n", [])
   else: 
     app(result, desc)
@@ -895,11 +895,20 @@ type
 
 include ccgtrav
 
-proc genTypeInfo(m: BModule, t: PType): PRope = 
+proc genDeepCopyProc(m: BModule; s: PSym; result: PRope) =
+  genProc(m, s)
+  appf(m.s[cfsTypeInit3], "$1.deepcopy = (N_NIMCALL_PTR(void*, void*)) $2;$n",
+     [result, s.loc.r])
+
+proc genTypeInfo(m: BModule, t: PType): PRope =
+  let origType = t
   var t = getUniqueType(t)
   result = ropef("NTI$1", [toRope(t.id)])
   if containsOrIncl(m.typeInfoMarker, t.id):
     return con("(&".toRope, result, ")".toRope)
+  
+  # getUniqueType doesn't skip tyDistinct when that has an overriden operation:
+  while t.kind == tyDistinct: t = t.lastSon
   let owner = t.skipTypes(typedescPtrs).owner.getModule
   if owner != m.module:
     # make sure the type info is created in the owner module
@@ -936,6 +945,10 @@ proc genTypeInfo(m: BModule, t: PType): PRope =
     # results are not deterministic!
     genTupleInfo(m, t, result)
   else: internalError("genTypeInfo(" & $t.kind & ')')
+  if t.deepCopy != nil:
+    genDeepCopyProc(m, t.deepCopy, result)
+  elif origType.deepCopy != nil:
+    genDeepCopyProc(m, origType.deepCopy, result)  
   result = con("(&".toRope, result, ")".toRope)
 
 proc genTypeSection(m: BModule, n: PNode) = 
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index 04983d6a4..6af6a857c 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -89,8 +89,10 @@ proc getUniqueType*(key: PType): PType =
   of tyTypeDesc, tyTypeClasses, tyGenericParam,
      tyFromExpr, tyFieldAccessor:
     internalError("GetUniqueType")
-  of tyGenericInst, tyDistinct, tyOrdinal, tyMutable,
-     tyConst, tyIter, tyStatic:
+  of tyDistinct:
+    if key.deepCopy != nil: result = key
+    else: result = getUniqueType(lastSon(key))
+  of tyGenericInst, tyOrdinal, tyMutable, tyConst, tyIter, tyStatic:
     result = getUniqueType(lastSon(key))
   of tyArrayConstr, tyGenericInvokation, tyGenericBody,
      tyOpenArray, tyArray, tySet, tyRange, tyTuple,
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index e2f3b5ab0..b930bea8d 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -295,6 +295,7 @@ proc postStmtActions(p: BProc) {.inline.} =
 
 proc accessThreadLocalVar(p: BProc, s: PSym)
 proc emulatedThreadVars(): bool {.inline.}
+proc genProc(m: BModule, prc: PSym)
 
 include "ccgtypes.nim"
 
@@ -574,7 +575,6 @@ proc fixLabel(p: BProc, labl: TLabel) =
 
 proc genVarPrototype(m: BModule, sym: PSym)
 proc requestConstImpl(p: BProc, sym: PSym)
-proc genProc(m: BModule, prc: PSym)
 proc genStmts(p: BProc, t: PNode)
 proc expr(p: BProc, n: PNode, d: var TLoc)
 proc genProcPrototype(m: BModule, sym: PSym)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 38c8dd294..7219c168a 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -291,8 +291,12 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
   of "excludepath":
     expectArg(switch, arg, pass, info)
     let path = processPath(arg)
-    lists.excludeStr(options.searchPaths, path)
-    lists.excludeStr(options.lazyPaths, path)
+    lists.excludePath(options.searchPaths, path)
+    lists.excludePath(options.lazyPaths, path)
+    if (len(path) > 0) and (path[len(path) - 1] == DirSep):
+      let strippedPath = path[0 .. (len(path) - 2)]
+      lists.excludePath(options.searchPaths, strippedPath)
+      lists.excludePath(options.lazyPaths, strippedPath)
   of "nimcache":
     expectArg(switch, arg, pass, info)
     options.nimcacheDir = processPath(arg)
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 17bb5db55..76026a59d 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -50,6 +50,7 @@ proc initDefines*() =
   defineSymbol("nimunion")
   defineSymbol("nimnewshared")
   defineSymbol("nimrequiresnimframe")
+  defineSymbol("nimparsebiggestfloatmagic")
   
   # add platform specific symbols:
   case targetCPU
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 6687e2e8e..96d8b3d11 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -1321,7 +1321,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
   of mLengthSeq, mLengthOpenArray, mLengthArray:
     unaryExpr(p, n, r, "", "$1.length")
   of mHigh:
-    if skipTypes(n.sons[0].typ, abstractVar).kind == tyString:
+    if skipTypes(n.sons[1].typ, abstractVar).kind == tyString:
       unaryExpr(p, n, r, "", "($1.length-2)")
     else:
       unaryExpr(p, n, r, "", "($1.length-1)")
@@ -1532,6 +1532,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
     genSym(p, n, r)
   of nkCharLit..nkInt64Lit:
     r.res = toRope(n.intVal)
+    r.kind = resExpr
   of nkNilLit:
     if isEmptyType(n.typ):
       discard
@@ -1539,8 +1540,10 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
       r.typ = etyBaseIndex
       r.address = toRope"null" | toRope"nil"
       r.res = toRope"0"
+      r.kind = resExpr
     else:
       r.res = toRope"null" | toRope"nil"
+      r.kind = resExpr
   of nkStrLit..nkTripleStrLit:
     if skipTypes(n.typ, abstractVarRange).kind == tyString: 
       useMagic(p, "cstrToNimstr")
@@ -1556,6 +1559,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
       if f > 0.0: r.res = toRope"Infinity"
       else: r.res = toRope"-Infinity"
     else: r.res = toRope(f.toStrMaxPrecision)
+    r.kind = resExpr
   of nkCallKinds:
     if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic != mNone): 
       genMagic(p, n, r)
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index c5b9d0f00..6c650eee3 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -103,43 +103,51 @@ discard """
 
 """
 
+# Important things to keep in mind:
+# * Don't base the analysis on nkProcDef et al. This doesn't work for
+#   instantiated (formerly generic) procs. The analysis has to look at nkSym.
+#   This also means we need to prevent the same proc is processed multiple
+#   times via the 'processed' set.
+# * Keep in mind that the owner of some temporaries used to be unreliable.
+# * For closure iterators we merge the "real" potential closure with the
+#   local storage requirements for efficiency. This means closure iterators
+#   have slightly different semantics from ordinary closures.
+
+
 const
   upName* = ":up" # field name for the 'up' reference
-  paramName* = ":env"
+  paramName* = ":envP"
   envName* = ":env"
 
 type
-  PInnerContext = ref TInnerContext
   POuterContext = ref TOuterContext
 
+  TIter = object
+    fn, closureParam, state, resultSym: PSym # most are only valid if
+                                             # fn.kind == skClosureIterator
+    obj: PType
+    
   PEnv = ref TEnv
-  TDep = tuple[e: PEnv, field: PSym]
   TEnv {.final.} = object of TObject
-    attachedNode: PNode
-    createdVar: PSym        # if != nil it is a used environment
+    attachedNode, replacementNode: PNode
+    createdVar: PNode        # if != nil it is a used environment; for closure
+                             # iterators this can be 'envParam.env'
     createdVarComesFromIter: bool
     capturedVars: seq[PSym] # captured variables in this environment
-    deps: seq[TDep]         # dependencies
-    up: PEnv
+    up, next: PEnv          # outer scope and next to keep all in a list
+    upField: PSym        # if != nil the dependency to the outer scope is used
     obj: PType
-  
-  TInnerContext = object
-    fn: PSym
-    closureParam: PSym
-    localsToAccess: TIdNodeTable
+    fn: PSym                # function that belongs to this scope;
+                            # if up.fn != fn then we cross function boundaries.
+                            # This is an important case to consider.
+    vars: TIntSet           # variables belonging to this environment
     
   TOuterContext = object
     fn: PSym # may also be a module!
-    currentEnv: PEnv
-    isIter: bool   # first class iterator?
+    head: PEnv
     capturedVars, processed: TIntSet
-    localsToEnv: TIdTable # PSym->PEnv mapping
     localsToAccess: TIdNodeTable
     lambdasToEnv: TIdTable # PSym->PEnv mapping
-    up: POuterContext
-
-    closureParam, state, resultSym: PSym # only if isIter
-    obj: PType # only if isIter
 
 proc getStateType(iter: PSym): PType =
   var n = newNodeI(nkRange, iter.info)
@@ -147,12 +155,20 @@ proc getStateType(iter: PSym): PType =
   addSon(n, newIntNode(nkIntLit, 0))
   result = newType(tyRange, iter)
   result.n = n
-  rawAddSon(result, getSysType(tyInt))
+  var intType = nilOrSysInt()
+  if intType.isNil: intType = newType(tyInt, iter)
+  rawAddSon(result, intType)
 
 proc createStateField(iter: PSym): PSym =
   result = newSym(skField, getIdent(":state"), iter, iter.info)
   result.typ = getStateType(iter)
 
+proc createEnvObj(owner: PSym): PType =
+  # YYY meh, just add the state field for every closure for now, it's too
+  # hard to figure out if it comes from a closure iterator:
+  result = createObj(owner, owner.info)
+  rawAddField(result, createStateField(owner))
+
 proc newIterResult(iter: PSym): PSym =
   if resultPos < iter.ast.len:
     result = iter.ast.sons[resultPos].sym
@@ -164,6 +180,7 @@ proc newIterResult(iter: PSym): PSym =
     iter.ast.add newSymNode(result)
 
 proc addHiddenParam(routine: PSym, param: PSym) =
+  assert param.kind == skParam
   var params = routine.ast.sons[paramsPos]
   # -1 is correct here as param.position is 0 based but we have at position 0
   # some nkEffect node:
@@ -175,7 +192,7 @@ proc addHiddenParam(routine: PSym, param: PSym) =
 proc getHiddenParam(routine: PSym): PSym =
   let params = routine.ast.sons[paramsPos]
   let hidden = lastSon(params)
-  assert hidden.kind == nkSym
+  internalAssert hidden.kind == nkSym and hidden.sym.kind == skParam
   result = hidden.sym
 
 proc getEnvParam(routine: PSym): PSym =
@@ -184,161 +201,191 @@ proc getEnvParam(routine: PSym): PSym =
   if hidden.kind == nkSym and hidden.sym.name.s == paramName:
     result = hidden.sym
 
-proc initIterContext(c: POuterContext, iter: PSym) =
-  c.fn = iter
-  c.capturedVars = initIntSet()
-
-  var cp = getEnvParam(iter)
-  if cp == nil:
-    c.obj = createObj(iter, iter.info)
-
-    cp = newSym(skParam, getIdent(paramName), iter, iter.info)
-    incl(cp.flags, sfFromGeneric)
-    cp.typ = newType(tyRef, iter)
-    rawAddSon(cp.typ, c.obj)
-    addHiddenParam(iter, cp)
-
-    c.state = createStateField(iter)
-    addField(c.obj, c.state)
-  else:
-    c.obj = cp.typ.sons[0]
-    assert c.obj.kind == tyObject
-    if c.obj.n.len > 0:
-      c.state = c.obj.n[0].sym
+proc initIter(iter: PSym): TIter =
+  result.fn = iter
+  if iter.kind == skClosureIterator:
+    var cp = getEnvParam(iter)
+    if cp == nil:
+      result.obj = createEnvObj(iter)
+
+      cp = newSym(skParam, getIdent(paramName), iter, iter.info)
+      incl(cp.flags, sfFromGeneric)
+      cp.typ = newType(tyRef, iter)
+      rawAddSon(cp.typ, result.obj)
+      addHiddenParam(iter, cp)
     else:
-      c.state = createStateField(iter)
-      addField(c.obj, c.state)
-
-  c.closureParam = cp
-  if iter.typ.sons[0] != nil:
-    c.resultSym = newIterResult(iter)
-    #iter.ast.add(newSymNode(c.resultSym))
-
-proc newOuterContext(fn: PSym, up: POuterContext = nil): POuterContext =
+      result.obj = cp.typ.sons[0]
+      assert result.obj.kind == tyObject
+    internalAssert result.obj.n.len > 0
+    result.state = result.obj.n[0].sym
+    result.closureParam = cp
+    if iter.typ.sons[0] != nil:
+      result.resultSym = newIterResult(iter)
+      #iter.ast.add(newSymNode(c.resultSym))
+
+proc newOuterContext(fn: PSym): POuterContext =
   new(result)
   result.fn = fn
   result.capturedVars = initIntSet()
   result.processed = initIntSet()
   initIdNodeTable(result.localsToAccess)
-  initIdTable(result.localsToEnv)
   initIdTable(result.lambdasToEnv)
-  result.isIter = fn.kind == skClosureIterator
-  if result.isIter: initIterContext(result, fn)
 
-proc newInnerContext(fn: PSym): PInnerContext =
+proc newEnv(o: POuterContext; up: PEnv, n: PNode; owner: PSym): PEnv =
   new(result)
-  result.fn = fn
-  initIdNodeTable(result.localsToAccess)
-
-proc newEnv(outerProc: PSym, up: PEnv, n: PNode): PEnv =
-  new(result)
-  result.deps = @[]
   result.capturedVars = @[]
-  result.obj = createObj(outerProc, outerProc.info)
   result.up = up
   result.attachedNode = n
+  result.fn = owner
+  result.vars = initIntSet()
+  result.next = o.head
+  o.head = result
+  if owner.kind != skModule and (up == nil or up.fn != owner):
+    let param = getEnvParam(owner)
+    if param != nil:
+      result.obj = param.typ.sons[0]
+      assert result.obj.kind == tyObject
+  if result.obj.isNil:
+    result.obj = createEnvObj(owner)
 
 proc addCapturedVar(e: PEnv, v: PSym) =
   for x in e.capturedVars:
     if x == v: return
-  # XXX meh, just add the state field for every closure for now, it's too
-  # hard to figure out if it comes from a closure iterator:
-  if e.obj.n.len == 0: addField(e.obj, createStateField(v.owner))
   e.capturedVars.add(v)
   addField(e.obj, v)
-  
-proc addDep(e, d: PEnv, owner: PSym): PSym =
-  for x, field in items(e.deps):
-    if x == d: return field
-  var pos = sonsLen(e.obj.n)
-  result = newSym(skField, getIdent(upName & $pos), owner, owner.info)
-  result.typ = newType(tyRef, owner)
-  result.position = pos
-  assert d.obj != nil
-  rawAddSon(result.typ, d.obj)
-  addField(e.obj, result)
-  e.deps.add((d, result))
 
-proc newCall(a, b: PSym): PNode =
+proc newCall(a: PSym, b: PNode): PNode =
   result = newNodeI(nkCall, a.info)
   result.add newSymNode(a)
-  result.add newSymNode(b)
-
-proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
-  result = s.kind in {skProc, skMethod, skConverter, skClosureIterator} and
-           s.skipGenericOwner == outerProc
+  result.add b
+
+proc isInnerProc(s, outerProc: PSym): bool =
+  if s.kind in {skProc, skMethod, skConverter, skClosureIterator}:
+    var owner = s.skipGenericOwner
+    while true:
+      if owner.isNil: return false
+      if owner == outerProc: return true
+      owner = owner.owner
   #s.typ.callConv == ccClosure
 
-proc addClosureParam(i: PInnerContext, e: PEnv) =
-  var cp = getEnvParam(i.fn)
+proc addClosureParam(fn: PSym; e: PEnv) =
+  var cp = getEnvParam(fn)
   if cp == nil:
-    cp = newSym(skParam, getIdent(paramName), i.fn, i.fn.info)
+    cp = newSym(skParam, getIdent(paramName), fn, fn.info)
     incl(cp.flags, sfFromGeneric)
-    cp.typ = newType(tyRef, i.fn)
+    cp.typ = newType(tyRef, fn)
     rawAddSon(cp.typ, e.obj)
-    addHiddenParam(i.fn, cp)
-  else:
-    e.obj = cp.typ.sons[0]
-    assert e.obj.kind == tyObject
-  i.closureParam = cp
-  #echo "closure param added for ", i.fn.name.s, " ", i.fn.id
-
-proc dummyClosureParam(o: POuterContext, i: PInnerContext) =
-  var e = o.currentEnv
-  if idTableGet(o.lambdasToEnv, i.fn) == nil:
-    idTablePut(o.lambdasToEnv, i.fn, e)
-  if i.closureParam == nil: addClosureParam(i, e)
+    addHiddenParam(fn, cp)
+    #else:
+    #cp.typ.sons[0] = e.obj
+    #assert e.obj.kind == tyObject
 
 proc illegalCapture(s: PSym): bool {.inline.} =
   result = skipTypes(s.typ, abstractInst).kind in 
                    {tyVar, tyOpenArray, tyVarargs} or
       s.kind == skResult
 
-proc captureVar(o: POuterContext, i: PInnerContext, local: PSym, 
-                info: TLineInfo) =
-  # for inlined variables the owner is still wrong, so it can happen that it's
-  # not a captured variable at all ... *sigh* 
-  var it = PEnv(idTableGet(o.localsToEnv, local))
-  if it == nil: return
-  
-  if illegalCapture(local) or o.fn.id != local.owner.id or 
-      i.fn.typ.callConv notin {ccClosure, ccDefault}:
-    # Currently captures are restricted to a single level of nesting:
-    localError(info, errIllegalCaptureX, local.name.s)
-  i.fn.typ.callConv = ccClosure
-  #echo "captureVar ", i.fn.name.s, i.fn.id, " ", local.name.s, local.id
-
-  incl(i.fn.typ.flags, tfCapturesEnv)
-
-  # we need to remember which inner most closure belongs to this lambda:
-  var e = o.currentEnv
-  if idTableGet(o.lambdasToEnv, i.fn) == nil:
-    idTablePut(o.lambdasToEnv, i.fn, e)
-
-  # variable already captured:
-  if idNodeTableGet(i.localsToAccess, local) != nil: return
-  if i.closureParam == nil: addClosureParam(i, e)
-  
-  # check which environment `local` belongs to:
-  var access = newSymNode(i.closureParam)
-  addCapturedVar(it, local)
-  if it == e:
-    # common case: local directly in current environment:
-    discard
-  else:
-    # it's in some upper environment:
-    access = indirectAccess(access, addDep(e, it, i.fn), info)
-  access = indirectAccess(access, local, info)
-  if o.isIter:
-    if not containsOrIncl(o.capturedVars, local.id): addField(o.obj, local)
-  else:
-    incl(o.capturedVars, local.id)
-  idNodeTablePut(i.localsToAccess, local, access)
-
 proc interestingVar(s: PSym): bool {.inline.} =
   result = s.kind in {skVar, skLet, skTemp, skForVar, skParam, skResult} and
     sfGlobal notin s.flags
 
+proc nestedAccess(top: PEnv; local: PSym): PNode =
+  # Parts after the transformation are in []:
+  #
+  #  proc main =
+  #    var [:env.]foo = 23
+  #    proc outer(:paramO) =
+  #      [var :envO; createClosure(:envO); :envO.up = paramO]
+  #      proc inner(:paramI) =
+  #        echo [:paramI.up.]foo
+  #      inner([:envO])
+  #    outer([:env])
+  if not interestingVar(local) or top.fn == local.owner:
+    return nil
+  # check it's in fact a captured variable:
+  var it = top
+  while it != nil:
+    if it.vars.contains(local.id): break
+    it = it.up
+  if it == nil: return nil
+  let envParam = top.fn.getEnvParam
+  internalAssert(not envParam.isNil)
+  var access = newSymNode(envParam)
+  it = top.up
+  while it != nil:
+    if it.vars.contains(local.id):
+      access = indirectAccess(access, local, local.info)
+      return access
+    internalAssert it.upField != nil
+    access = indirectAccess(access, it.upField, local.info)
+    it = it.up
+  when false:
+    # Type based expression construction works too, but turned out to hide
+    # other bugs:
+    while true:
+      let obj = access.typ.sons[0]
+      let field = getFieldFromObj(obj, local)
+      if field != nil:
+        return rawIndirectAccess(access, field, local.info)
+      let upField = lookupInRecord(obj.n, getIdent(upName))
+      if upField == nil: break
+      access = rawIndirectAccess(access, upField, local.info)
+  return nil
+
+proc createUpField(obj, fieldType: PType): PSym =
+  let pos = obj.n.len
+  result = newSym(skField, getIdent(upName), obj.owner, obj.owner.info)
+  result.typ = newType(tyRef, obj.owner)
+  result.position = pos
+  rawAddSon(result.typ, fieldType)
+  #rawAddField(obj, result)
+  addField(obj, result)
+
+proc captureVar(o: POuterContext; top: PEnv; local: PSym; 
+                info: TLineInfo): bool =
+  # first check if we should be concerned at all:
+  var it = top
+  while it != nil:
+    if it.vars.contains(local.id): break
+    it = it.up
+  if it == nil: return false
+  # yes, so mark every 'up' pointer as taken:
+  if illegalCapture(local) or top.fn.typ.callConv notin {ccClosure, ccDefault}:
+    localError(info, errIllegalCaptureX, local.name.s)
+  it = top
+  while it != nil:
+    if it.vars.contains(local.id): break
+    # keep in mind that the first element of the chain belong to top.fn itself
+    # and these don't need any upFields
+    if it.upField == nil and it.up != nil and it.fn != top.fn:
+      it.upField = createUpField(it.obj, it.up.obj)
+
+    if it.fn != local.owner:
+      it.fn.typ.callConv = ccClosure
+      incl(it.fn.typ.flags, tfCapturesEnv)
+
+      var u = it.up
+      while u != nil and u.fn == it.fn: u = u.up
+      addClosureParam(it.fn, u)
+
+      if idTableGet(o.lambdasToEnv, it.fn) == nil:
+        if u != nil: idTablePut(o.lambdasToEnv, it.fn, u)
+
+    it = it.up
+  # don't do this: 'top' might not require a closure:
+  #if idTableGet(o.lambdasToEnv, it.fn) == nil:
+  #  idTablePut(o.lambdasToEnv, it.fn, top)
+
+  # mark as captured:
+  #if top.iter != nil:
+  #  if not containsOrIncl(o.capturedVars, local.id):
+  #    #addField(top.iter.obj, local)
+  #    addCapturedVar(it, local)
+  #else:
+  incl(o.capturedVars, local.id)
+  addCapturedVar(it, local)
+  result = true
+
 proc semCaptureSym*(s, owner: PSym) =
   if interestingVar(s) and owner.id != s.owner.id and s.kind != skResult:
     if owner.typ != nil and not isGenericRoutine(owner):
@@ -350,28 +397,20 @@ proc semCaptureSym*(s, owner: PSym) =
     # since the analysis is not entirely correct, we don't set 'tfCapturesEnv'
     # here
 
-proc gatherVars(o: POuterContext, i: PInnerContext, n: PNode) = 
-  # gather used vars for closure generation
-  if n == nil: return
+proc gatherVars(o: POuterContext; e: PEnv; n: PNode): int =
+  # gather used vars for closure generation; returns number of captured vars
+  if n == nil: return 0
   case n.kind
   of nkSym:
     var s = n.sym
-    if interestingVar(s) and i.fn.id != s.owner.id:
-      captureVar(o, i, s, n.info)
-    elif s.kind in {skProc, skMethod, skConverter} and
-            s.skipGenericOwner == o.fn and 
-            tfCapturesEnv in s.typ.flags and s != i.fn:
-      # call to some other inner proc; we need to track the dependencies for
-      # this:
-      let env = PEnv(idTableGet(o.lambdasToEnv, i.fn))
-      if env == nil: internalError(n.info, "no environment computed")
-      if o.currentEnv != env:
-        discard addDep(o.currentEnv, env, i.fn)
-        internalError(n.info, "too complex environment handling required")
-  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkClosure: discard
+    if interestingVar(s) and e.fn != s.owner:
+      if captureVar(o, e, s, n.info): result = 1
+  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkClosure, nkProcDef, 
+     nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, nkTypeSection:
+    discard
   else:
-    for k in countup(0, sonsLen(n) - 1): 
-      gatherVars(o, i, n.sons[k])
+    for k in countup(0, sonsLen(n) - 1):
+      result += gatherVars(o, e, n.sons[k])
 
 proc generateThunk(prc: PNode, dest: PType): PNode =
   ## Converts 'prc' into '(thunk, nil)' so that it's compatible with
@@ -395,84 +434,143 @@ proc transformOuterConv(n: PNode): PNode =
     if dest.callConv == ccClosure and source.callConv == ccDefault:
       result = generateThunk(n.sons[1], dest)
 
-proc makeClosure(prc, env: PSym, info: TLineInfo): PNode =
+proc makeClosure(prc: PSym; env: PNode; info: TLineInfo): PNode =
   result = newNodeIT(nkClosure, info, prc.typ)
   result.add(newSymNode(prc))
   if env == nil:
     result.add(newNodeIT(nkNilLit, info, getSysType(tyNil)))
   else:
-    result.add(newSymNode(env))
+    result.add(env)
+
+proc newClosureCreationVar(e: PEnv): PNode =
+  var v = newSym(skVar, getIdent(envName), e.fn, e.attachedNode.info)
+  incl(v.flags, sfShadowed)
+  v.typ = newType(tyRef, e.fn)
+  v.typ.rawAddSon(e.obj)
+  if e.fn.kind == skClosureIterator:
+    let it = initIter(e.fn)
+    addUniqueField(it.obj, v)
+    result = indirectAccess(newSymNode(it.closureParam), v, v.info)
+  else:
+    result = newSymNode(v)
+
+proc getClosureVar(e: PEnv): PNode =
+  if e.createdVar == nil:
+    result = newClosureCreationVar(e)
+    e.createdVar = result
+  else:
+    result = e.createdVar
+
+proc findEnv(o: POuterContext; s: PSym): PEnv =
+  var env = o.head
+  while env != nil:
+    if env.fn == s: break
+    env = env.next
+  internalAssert env != nil and env.up != nil
+  result = env.up
+  while result.fn == s: result = result.up
 
-proc transformInnerProc(o: POuterContext, i: PInnerContext, n: PNode): PNode =
+proc transformInnerProc(o: POuterContext; e: PEnv, n: PNode): PNode =
   case n.kind
   of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: discard
   of nkSym:
     let s = n.sym
-    if s == i.fn: 
+    if s == e.fn:
       # recursive calls go through (lambda, hiddenParam):
-      assert i.closureParam != nil, i.fn.name.s
-      result = makeClosure(s, i.closureParam, n.info)
+      result = makeClosure(s, getEnvParam(s).newSymNode, n.info)
     elif isInnerProc(s, o.fn) and s.typ.callConv == ccClosure:
-      # ugh: call to some other inner proc; 
-      assert i.closureParam != nil
-      # XXX this is not correct in general! may also be some 'closure.upval'
-      result = makeClosure(s, i.closureParam, n.info)
+      # ugh: call to some other inner proc;
+      result = makeClosure(s, findEnv(o, s).getClosureVar, n.info)
     else:
       # captured symbol?
-      result = idNodeTableGet(i.localsToAccess, n.sym)
-  of nkLambdaKinds, nkIteratorDef:
-    if n.typ != nil:
-      result = transformInnerProc(o, i, n.sons[namePos])
+      result = nestedAccess(e, n.sym)
+      #result = idNodeTableGet(i.localsToAccess, n.sym)
+    #of nkLambdaKinds, nkIteratorDef:
+    #  if n.typ != nil:
+    #    result = transformInnerProc(o, e, n.sons[namePos])
+    #of nkClosure:
+    #  let x = transformInnerProc(o, e, n.sons[0])
+    #  if x != nil: n.sons[0] = x
   of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
-      nkClosure:
+     nkLambdaKinds, nkIteratorDef, nkClosure:
     # don't recurse here:
     discard
   else:
     for j in countup(0, sonsLen(n) - 1):
-      let x = transformInnerProc(o, i, n.sons[j])
+      let x = transformInnerProc(o, e, n.sons[j])
       if x != nil: n.sons[j] = x
 
 proc closureCreationPoint(n: PNode): PNode =
-  result = newNodeI(nkStmtList, n.info)
-  result.add(emptyNode)
-  result.add(n)
-
-proc searchForInnerProcs(o: POuterContext, n: PNode) =
+  if n.kind == nkStmtList and n.len >= 1 and n[0].kind == nkEmpty:
+    # we already have a free slot
+    result = n
+  else:
+    result = newNodeI(nkStmtList, n.info)
+    result.add(emptyNode)
+    result.add(n)
+  #result.flags.incl nfLL
+
+proc addParamsToEnv(fn: PSym; env: PEnv) =
+  let params = fn.typ.n
+  for i in 1.. <params.len: 
+    if params.sons[i].kind != nkSym:
+      internalError(params.info, "liftLambdas: strange params")
+    let param = params.sons[i].sym
+    env.vars.incl(param.id)
+  # put the 'result' into the environment so it can be captured:
+  let ast = fn.ast
+  if resultPos < sonsLen(ast) and ast.sons[resultPos].kind == nkSym:
+    env.vars.incl(ast.sons[resultPos].sym.id)
+
+proc searchForInnerProcs(o: POuterContext, n: PNode, env: PEnv) =
   if n == nil: return
   case n.kind
-  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: 
+  of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
     discard
   of nkSym:
-    if isInnerProc(n.sym, o.fn) and not containsOrIncl(o.processed, n.sym.id):
-      var inner = newInnerContext(n.sym)
-      let body = n.sym.getBody
-      gatherVars(o, inner, body)
+    let fn = n.sym
+    if isInnerProc(fn, o.fn) and not containsOrIncl(o.processed, fn.id):
+      let body = fn.getBody
+
+      # handle deeply nested captures:
+      let ex = closureCreationPoint(body)
+      let envB = newEnv(o, env, ex, fn)
+      addParamsToEnv(fn, envB)
+      searchForInnerProcs(o, body, envB)
+      fn.ast.sons[bodyPos] = ex
+      
+      let capturedCounter = gatherVars(o, envB, body)
       # dummy closure param needed?
-      if inner.closureParam == nil and n.sym.typ.callConv == ccClosure:
+      if capturedCounter == 0 and fn.typ.callConv == ccClosure:
         #assert tfCapturesEnv notin n.sym.typ.flags
-        dummyClosureParam(o, inner)
-      # only transform if it really needs a closure:
-      if inner.closureParam != nil:
-        let ti = transformInnerProc(o, inner, body)
-        if ti != nil: n.sym.ast.sons[bodyPos] = ti
+        if idTableGet(o.lambdasToEnv, fn) == nil:
+          idTablePut(o.lambdasToEnv, fn, env)
+        addClosureParam(fn, env)
+
+      elif fn.getEnvParam != nil:
+        # only transform if it really needs a closure:
+        let ti = transformInnerProc(o, envB, body)
+        if ti != nil: fn.ast.sons[bodyPos] = ti
   of nkLambdaKinds, nkIteratorDef:
     if n.typ != nil:
-      searchForInnerProcs(o, n.sons[namePos])
+      searchForInnerProcs(o, n.sons[namePos], env)
   of nkWhileStmt, nkForStmt, nkParForStmt, nkBlockStmt:
     # some nodes open a new scope, so they are candidates for the insertion
     # of closure creation; however for simplicity we merge closures between
     # branches, in fact, only loop bodies are of interest here as only they 
     # yield observable changes in semantics. For Zahary we also
-    # include ``nkBlock``.
-    var body = n.len-1
-    for i in countup(0, body - 1): searchForInnerProcs(o, n.sons[i])
-    # special handling for the loop body:
-    let oldEnv = o.currentEnv
-    let ex = closureCreationPoint(n.sons[body])
-    o.currentEnv = newEnv(o.fn, oldEnv, ex)
-    searchForInnerProcs(o, n.sons[body])
-    n.sons[body] = ex
-    o.currentEnv = oldEnv
+    # include ``nkBlock``. We don't do this for closure iterators because
+    # 'yield' can produce wrong code otherwise (XXX show example):
+    if env.fn.kind != skClosureIterator:
+      var body = n.len-1
+      for i in countup(0, body - 1): searchForInnerProcs(o, n.sons[i], env)
+      # special handling for the loop body:
+      let ex = closureCreationPoint(n.sons[body])
+      searchForInnerProcs(o, n.sons[body], newEnv(o, env, ex, env.fn))
+      n.sons[body] = ex
+    else:
+      for i in countup(0, sonsLen(n) - 1):
+        searchForInnerProcs(o, n.sons[i], env)
   of nkVarSection, nkLetSection:
     # we need to compute a mapping var->declaredBlock. Note: The definition
     # counts, not the block where it is captured!
@@ -481,26 +579,29 @@ proc searchForInnerProcs(o: POuterContext, n: PNode) =
       if it.kind == nkCommentStmt: discard
       elif it.kind == nkIdentDefs:
         var L = sonsLen(it)
-        if it.sons[0].kind != nkSym: internalError(it.info, "transformOuter")
-        #echo "set: ", it.sons[0].sym.name.s, " ", o.currentBlock == nil
-        idTablePut(o.localsToEnv, it.sons[0].sym, o.currentEnv)
-        searchForInnerProcs(o, it.sons[L-1])
+        if it.sons[0].kind == nkSym:
+          # this can be false for recursive invokations that already
+          # transformed it into 'env.varName':
+          env.vars.incl(it.sons[0].sym.id)
+        searchForInnerProcs(o, it.sons[L-1], env)
       elif it.kind == nkVarTuple:
         var L = sonsLen(it)
         for j in countup(0, L-3):
           #echo "set: ", it.sons[j].sym.name.s, " ", o.currentBlock == nil
-          idTablePut(o.localsToEnv, it.sons[j].sym, o.currentEnv)
-        searchForInnerProcs(o, it.sons[L-1])
+          if it.sons[j].kind == nkSym:
+            env.vars.incl(it.sons[j].sym.id)
+        searchForInnerProcs(o, it.sons[L-1], env)
       else:
-        internalError(it.info, "transformOuter")
+        internalError(it.info, "searchForInnerProcs")
+  of nkClosure:
+    searchForInnerProcs(o, n.sons[0], env)
   of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, 
-     nkClosure, nkTypeSection:
+     nkTypeSection:
     # don't recurse here:
-    # XXX recurse here and setup 'up' pointers
     discard
   else:
     for i in countup(0, sonsLen(n) - 1):
-      searchForInnerProcs(o, n.sons[i])
+      searchForInnerProcs(o, n.sons[i], env)
 
 proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode = 
   # Bugfix: unfortunately we cannot use 'nkFastAsgn' here as that would
@@ -512,24 +613,12 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
   result.sons[0] = le
   result.sons[1] = ri
 
-proc newClosureCreationVar(o: POuterContext; e: PEnv): PSym =
-  result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
-  incl(result.flags, sfShadowed)
-  result.typ = newType(tyRef, o.fn)
-  result.typ.rawAddSon(e.obj)
-
-proc getClosureVar(o: POuterContext; e: PEnv): PSym =
-  if e.createdVar == nil:
-    result = newClosureCreationVar(o, e)
-    e.createdVar = result
-  else:
-    result = e.createdVar
-
-proc rawClosureCreation(o: POuterContext, scope: PEnv; env: PSym): PNode =
+proc rawClosureCreation(o: POuterContext, scope: PEnv; env: PNode): PNode =
   result = newNodeI(nkStmtList, env.info)
-  var v = newNodeI(nkVarSection, env.info)
-  addVar(v, newSymNode(env))
-  result.add(v)
+  if env.kind == nkSym:
+    var v = newNodeI(nkVarSection, env.info)
+    addVar(v, env)
+    result.add(v)
   # add 'new' statement:
   result.add(newCall(getSysSym"internalNew", env))
   
@@ -548,21 +637,25 @@ proc rawClosureCreation(o: POuterContext, scope: PEnv; env: PSym): PNode =
       idNodeTablePut(o.localsToAccess, local, fieldAccess)
     else:
       result.add(newAsgnStmt(fieldAccess, existing, env.info))
-  # add support for 'up' references:
-  for e, field in items(scope.deps):
-    # add ``env.up = env2``
-    result.add(newAsgnStmt(indirectAccess(env, field, env.info),
-               newSymNode(getClosureVar(o, e)), env.info))
-  
+  if scope.upField != nil:
+    # "up" chain has been used:
+    if scope.up.fn != scope.fn:
+      # crosses function boundary:
+      result.add(newAsgnStmt(indirectAccess(env, scope.upField, env.info),
+                 newSymNode(getEnvParam(scope.fn)), env.info))
+    else:
+      result.add(newAsgnStmt(indirectAccess(env, scope.upField, env.info),
+                 getClosureVar(scope.up), env.info))
+
 proc generateClosureCreation(o: POuterContext, scope: PEnv): PNode =
-  var env = getClosureVar(o, scope)
+  var env = getClosureVar(scope)
   result = rawClosureCreation(o, scope, env)
 
 proc generateIterClosureCreation(o: POuterContext; env: PEnv;
-                                 scope: PNode): PSym =
+                                 scope: PNode): PNode =
   if env.createdVarComesFromIter or env.createdVar.isNil:
     # we have to create a new closure:
-    result = newClosureCreationVar(o, env)
+    result = newClosureCreationVar(env)
     let cc = rawClosureCreation(o, env, result)
     var insertPoint = scope.sons[0]
     if insertPoint.kind == nkEmpty: scope.sons[0] = cc
@@ -577,21 +670,25 @@ proc generateIterClosureCreation(o: POuterContext; env: PEnv;
 proc interestingIterVar(s: PSym): bool {.inline.} =
   result = s.kind in {skVar, skLet, skTemp, skForVar} and sfGlobal notin s.flags
 
-proc transformOuterProc(o: POuterContext, n: PNode): PNode
+proc transformOuterProc(o: POuterContext, n: PNode, it: TIter): PNode
 
-proc transformYield(c: POuterContext, n: PNode): PNode =
-  inc c.state.typ.n.sons[1].intVal
-  let stateNo = c.state.typ.n.sons[1].intVal
+proc transformYield(c: POuterContext, n: PNode, it: TIter): PNode =
+  assert it.state != nil
+  assert it.state.typ != nil
+  assert it.state.typ.n != nil
+  inc it.state.typ.n.sons[1].intVal
+  let stateNo = it.state.typ.n.sons[1].intVal
 
   var stateAsgnStmt = newNodeI(nkAsgn, n.info)
-  stateAsgnStmt.add(indirectAccess(newSymNode(c.closureParam),c.state,n.info))
+  stateAsgnStmt.add(rawIndirectAccess(newSymNode(it.closureParam),
+                    it.state, n.info))
   stateAsgnStmt.add(newIntTypeNode(nkIntLit, stateNo, getSysType(tyInt)))
 
   var retStmt = newNodeI(nkReturnStmt, n.info)
   if n.sons[0].kind != nkEmpty:
     var a = newNodeI(nkAsgn, n.sons[0].info)
-    var retVal = transformOuterProc(c, n.sons[0])
-    addSon(a, newSymNode(c.resultSym))
+    var retVal = transformOuterProc(c, n.sons[0], it)
+    addSon(a, newSymNode(it.resultSym))
     addSon(a, if retVal.isNil: n.sons[0] else: retVal)
     retStmt.add(a)
   else:
@@ -605,17 +702,18 @@ proc transformYield(c: POuterContext, n: PNode): PNode =
   result.add(retStmt)
   result.add(stateLabelStmt)
 
-proc transformReturn(c: POuterContext, n: PNode): PNode =
+proc transformReturn(c: POuterContext, n: PNode, it: TIter): PNode =
   result = newNodeI(nkStmtList, n.info)
   var stateAsgnStmt = newNodeI(nkAsgn, n.info)
-  stateAsgnStmt.add(indirectAccess(newSymNode(c.closureParam),c.state,n.info))
+  stateAsgnStmt.add(rawIndirectAccess(newSymNode(it.closureParam), it.state,
+                    n.info))
   stateAsgnStmt.add(newIntTypeNode(nkIntLit, -1, getSysType(tyInt)))
   result.add(stateAsgnStmt)
   result.add(n)
 
-proc outerProcSons(o: POuterContext, n: PNode) =
+proc outerProcSons(o: POuterContext, n: PNode, it: TIter) =
   for i in countup(0, sonsLen(n) - 1):
-    let x = transformOuterProc(o, n.sons[i])
+    let x = transformOuterProc(o, n.sons[i], it)
     if x != nil: n.sons[i] = x
 
 proc liftIterSym*(n: PNode): PNode =
@@ -631,27 +729,137 @@ proc liftIterSym*(n: PNode): PNode =
   addVar(v, newSymNode(env))
   result.add(v)
   # add 'new' statement:
-  result.add(newCall(getSysSym"internalNew", env))
-  result.add makeClosure(iter, env, n.info)
+  let envAsNode = env.newSymNode
+  result.add newCall(getSysSym"internalNew", envAsNode)
+  result.add makeClosure(iter, envAsNode, n.info)
+
+when false:
+  proc transformRemainingLocals(n: PNode; it: TIter): PNode =
+    assert it.fn.kind == skClosureIterator
+    result = n
+    case n.kind
+    of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: discard
+    of nkSym:
+      let local = n.sym
+      if interestingIterVar(local) and it.fn == local.owner:
+        addUniqueField(it.obj, local)
+        result = indirectAccess(newSymNode(it.closureParam), local, n.info)
+    else:
+      result = newNodeI(n.kind, n.info, n.len)
+      for i in 0.. <n.safeLen:
+        result.sons[i] = transformRemainingLocals(n.sons[i], it)
+
+template envActive(env): expr =
+  (env.capturedVars.len > 0 or env.upField != nil)
+
+# We have to split up environment creation in 2 steps:
+# 1. Generate it and store it in env.replacementNode
+# 2. Insert replacementNode into its forseen slot.
+# This split is necessary so that assignments belonging to closure
+# creation like 'env.param = param' are not transformed
+# into 'env.param = env.param'.
+proc createEnvironments(o: POuterContext) =
+  var env = o.head
+  while env != nil:
+    if envActive(env):
+      var scope = env.attachedNode
+      assert scope.kind == nkStmtList
+      if scope.sons[0].kind == nkEmpty:
+        # prepare for closure construction:
+        env.replacementNode = generateClosureCreation(o, env)
+    env = env.next
+
+proc finishEnvironments(o: POuterContext) =
+  var env = o.head
+  while env != nil:
+    if env.replacementNode != nil:
+      var scope = env.attachedNode
+      assert scope.kind == nkStmtList
+      if scope.sons[0].kind == nkEmpty:
+        # change the empty node to contain the closure construction:
+        scope.sons[0] = env.replacementNode
+        when false:
+          if env.fn.kind == skClosureIterator:
+            scope.sons[0] = transformRemainingLocals(env.replacementNode,
+                                                     initIter(env.fn))
+          else:
+            scope.sons[0] = env.replacementNode
+    env = env.next
+
+proc transformOuterProcBody(o: POuterContext, n: PNode; it: TIter): PNode =
+  if nfLL in n.flags:
+    result = nil
+  elif it.fn.kind == skClosureIterator:
+    # unfortunately control flow is still convoluted and we can end up
+    # multiple times here for the very same iterator. We shield against this
+    # with some rather primitive check for now:
+    if n.kind == nkStmtList and n.len > 0:
+      if n.sons[0].kind == nkGotoState: return nil
+      if n.len > 1 and n[1].kind == nkStmtList and n[1].len > 0 and 
+          n[1][0].kind == nkGotoState:
+        return nil
+    result = newNodeI(nkStmtList, it.fn.info)
+    var gs = newNodeI(nkGotoState, it.fn.info)
+    assert it.closureParam != nil
+    assert it.state != nil
+    gs.add(rawIndirectAccess(newSymNode(it.closureParam), it.state, it.fn.info))
+    result.add(gs)
+    var state0 = newNodeI(nkState, it.fn.info)
+    state0.add(newIntNode(nkIntLit, 0))
+    result.add(state0)
+    
+    let newBody = transformOuterProc(o, n, it)
+    if newBody != nil:
+      result.add(newBody)
+    else:
+      result.add(n)
+
+    var stateAsgnStmt = newNodeI(nkAsgn, it.fn.info)
+    stateAsgnStmt.add(rawIndirectAccess(newSymNode(it.closureParam),
+                      it.state, it.fn.info))
+    stateAsgnStmt.add(newIntTypeNode(nkIntLit, -1, getSysType(tyInt)))
+    result.add(stateAsgnStmt)
+    result.flags.incl nfLL
+  else:
+    result = transformOuterProc(o, n, it)
+    if result != nil: result.flags.incl nfLL
 
-proc transformOuterProc(o: POuterContext, n: PNode): PNode =
-  if n == nil: return nil
+proc transformOuterProc(o: POuterContext, n: PNode; it: TIter): PNode =
+  if n == nil or nfLL in n.flags: return nil
   case n.kind
   of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: discard
   of nkSym:
     var local = n.sym
 
-    if o.isIter and interestingIterVar(local) and o.fn.id == local.owner.id:
-      if not containsOrIncl(o.capturedVars, local.id): addField(o.obj, local)
-      return indirectAccess(newSymNode(o.closureParam), local, n.info)
+    if isInnerProc(local, o.fn) and o.processed.contains(local.id):
+      o.processed.excl(local.id)
+      let body = local.getBody
+      let newBody = transformOuterProcBody(o, body, initIter(local))
+      if newBody != nil:
+        local.ast.sons[bodyPos] = newBody
+
+    if it.fn.kind == skClosureIterator and interestingIterVar(local) and
+        it.fn == local.owner:
+      # every local goes through the closure:
+      #if not containsOrIncl(o.capturedVars, local.id):
+      #  addField(it.obj, local)
+      if contains(o.capturedVars, local.id):
+        # change 'local' to 'closure.local', unless it's a 'byCopy' variable:
+        # if sfByCopy notin local.flags:
+        result = idNodeTableGet(o.localsToAccess, local)
+        assert result != nil, "cannot find: " & local.name.s
+        return result
+      else:
+        addUniqueField(it.obj, local)
+        return indirectAccess(newSymNode(it.closureParam), local, n.info)
 
     var closure = PEnv(idTableGet(o.lambdasToEnv, local))
-
     if local.kind == skClosureIterator:
       # consider: [i1, i2, i1]  Since we merged the iterator's closure
       # with the captured owning variables, we need to generate the
       # closure generation code again:
-      if local == o.fn: message(n.info, errRecursiveDependencyX, local.name.s)
+      if local == o.fn or local == it.fn:
+        message(n.info, errRecursiveDependencyX, local.name.s)
       # XXX why doesn't this work?
       if closure.isNil:
         return liftIterSym(n)
@@ -662,7 +870,6 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode =
 
     if closure != nil:
       # we need to replace the lambda with '(lambda, env)':
-      
       let a = closure.createdVar
       if a != nil:
         return makeClosure(local, a, n.info)
@@ -678,14 +885,6 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode =
         return makeClosure(local, x, n.info)
     
     if not contains(o.capturedVars, local.id): return
-    var env = PEnv(idTableGet(o.localsToEnv, local))
-    if env == nil: return
-    var scope = env.attachedNode
-    assert scope.kind == nkStmtList
-    if scope.sons[0].kind == nkEmpty:
-      # change the empty node to contain the closure construction:
-      scope.sons[0] = generateClosureCreation(o, env)
-    
     # change 'local' to 'closure.local', unless it's a 'byCopy' variable:
     # if sfByCopy notin local.flags:
     result = idNodeTableGet(o.localsToAccess, local)
@@ -694,73 +893,64 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode =
     # to access the local as a local.
   of nkLambdaKinds, nkIteratorDef:
     if n.typ != nil:
-      result = transformOuterProc(o, n.sons[namePos])
-  of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
-      nkClosure:
+      result = transformOuterProc(o, n.sons[namePos], it)
+  of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef:
     # don't recurse here:
     discard
+  of nkClosure:
+    if n.sons[0].kind == nkSym:
+      var local = n.sons[0].sym
+      if isInnerProc(local, o.fn) and o.processed.contains(local.id):
+        o.processed.excl(local.id)
+        let body = local.getBody
+        let newBody = transformOuterProcBody(o, body, initIter(local))
+        if newBody != nil:
+          local.ast.sons[bodyPos] = newBody
+    when false:
+      if n.sons[1].kind == nkSym:
+        var local = n.sons[1].sym
+        if it.fn.kind == skClosureIterator and interestingIterVar(local) and
+            it.fn == local.owner:
+          # every local goes through the closure:
+          addUniqueField(it.obj, local)
+          n.sons[1] = indirectAccess(newSymNode(it.closureParam), local, n.info)
   of nkHiddenStdConv, nkHiddenSubConv, nkConv:
-    let x = transformOuterProc(o, n.sons[1])
+    let x = transformOuterProc(o, n.sons[1], it)
     if x != nil: n.sons[1] = x
     result = transformOuterConv(n)
   of nkYieldStmt:
-    if o.isIter: result = transformYield(o, n)
-    else: outerProcSons(o, n)
+    if it.fn.kind == skClosureIterator: result = transformYield(o, n, it)
+    else: outerProcSons(o, n, it)
   of nkReturnStmt:
-    if o.isIter: result = transformReturn(o, n)
-    else: outerProcSons(o, n)
-  else:
-    outerProcSons(o, n)
-
-proc liftIterator(c: POuterContext, body: PNode): PNode =
-  let iter = c.fn
-  result = newNodeI(nkStmtList, iter.info)
-  var gs = newNodeI(nkGotoState, iter.info)
-  gs.add(indirectAccess(newSymNode(c.closureParam), c.state, iter.info))
-  result.add(gs)
-  var state0 = newNodeI(nkState, iter.info)
-  state0.add(newIntNode(nkIntLit, 0))
-  result.add(state0)
-  
-  let newBody = transformOuterProc(c, body)
-  if newBody != nil:
-    result.add(newBody)
+    if it.fn.kind == skClosureIterator: result = transformReturn(o, n, it)
+    else: outerProcSons(o, n, it)
   else:
-    result.add(body)
-
-  var stateAsgnStmt = newNodeI(nkAsgn, iter.info)
-  stateAsgnStmt.add(indirectAccess(newSymNode(c.closureParam),
-                    c.state,iter.info))
-  stateAsgnStmt.add(newIntTypeNode(nkIntLit, -1, getSysType(tyInt)))
-  result.add(stateAsgnStmt)
+    outerProcSons(o, n, it)
 
 proc liftLambdas*(fn: PSym, body: PNode): PNode =
   # XXX gCmd == cmdCompileToJS does not suffice! The compiletime stuff needs
   # the transformation even when compiling to JS ...
-  if body.kind == nkEmpty or gCmd == cmdCompileToJS:
+  if body.kind == nkEmpty or gCmd == cmdCompileToJS or 
+      fn.skipGenericOwner.kind != skModule:
     # ignore forward declaration:
     result = body
   else:
+    #if fn.name.s == "cbOuter":
+    #  echo rendertree(fn.ast, {renderIds})
     var o = newOuterContext(fn)
     let ex = closureCreationPoint(body)
-    o.currentEnv = newEnv(fn, nil, ex)
-    # put all params into the environment so they can be captured:
-    let params = fn.typ.n
-    for i in 1.. <params.len: 
-      if params.sons[i].kind != nkSym:
-        internalError(params.info, "liftLambdas: strange params")
-      let param = params.sons[i].sym
-      idTablePut(o.localsToEnv, param, o.currentEnv)
-    # put the 'result' into the environment so it can be captured:
-    let ast = fn.ast
-    if resultPos < sonsLen(ast) and ast.sons[resultPos].kind == nkSym:
-      idTablePut(o.localsToEnv, ast.sons[resultPos].sym, o.currentEnv)
-    searchForInnerProcs(o, body)
-    if o.isIter:
-      result = liftIterator(o, ex)
+    let env = newEnv(o, nil, ex, fn)
+    addParamsToEnv(fn, env)
+    searchForInnerProcs(o, body, env)
+    createEnvironments(o)
+    if fn.kind == skClosureIterator:
+      result = transformOuterProcBody(o, body, initIter(fn))
     else:
-      discard transformOuterProc(o, body)
+      discard transformOuterProcBody(o, body, initIter(fn))
       result = ex
+    finishEnvironments(o)
+    #if fn.name.s == "cbOuter":
+    #  echo rendertree(result, {renderIds})
 
 proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =
   if body.kind == nkEmpty or gCmd == cmdCompileToJS:
@@ -768,9 +958,11 @@ proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =
   else:
     var o = newOuterContext(module)
     let ex = closureCreationPoint(body)
-    o.currentEnv = newEnv(module, nil, ex)
-    searchForInnerProcs(o, body)
-    discard transformOuterProc(o, body)
+    let env = newEnv(o, nil, ex, module)
+    searchForInnerProcs(o, body, env)
+    createEnvironments(o)
+    discard transformOuterProc(o, body, initIter(module))
+    finishEnvironments(o)
     result = ex
 
 # ------------------- iterator transformation --------------------------------
@@ -821,7 +1013,7 @@ proc liftForLoop*(body: PNode): PNode =
     addVar(v, newSymNode(env))
     result.add(v)
     # add 'new' statement:
-    result.add(newCall(getSysSym"internalNew", env))
+    result.add(newCall(getSysSym"internalNew", env.newSymNode))
   
   var loopBody = newNodeI(nkStmtList, body.info, 3)
   var whileLoop = newNodeI(nkWhileStmt, body.info, 2)
@@ -840,16 +1032,12 @@ proc liftForLoop*(body: PNode): PNode =
 
   addSon(vpart, ast.emptyNode) # no explicit type
   if not env.isNil:
-    call.sons[0] = makeClosure(call.sons[0].sym, env, body.info)
+    call.sons[0] = makeClosure(call.sons[0].sym, env.newSymNode, body.info)
   addSon(vpart, call)
   addSon(v2, vpart)
 
   loopBody.sons[0] = v2
   var bs = newNodeI(nkBreakState, body.info)
-  #if not env.isNil:
-  #  bs.addSon(indirectAccess(env, 
-  #    newSym(skField, getIdent":state", env, env.info), body.info))
-  #else:
   bs.addSon(call.sons[0])
   loopBody.sons[1] = bs
   loopBody.sons[2] = body[L-1]
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 0e4dfc2ac..ea51a1399 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -40,7 +40,7 @@ type
     tkFinally, tkFor, tkFrom,
     tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, 
     tkIs, tkIsnot, tkIterator,
-    tkLambda, tkLet,
+    tkLet,
     tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin, 
     tkObject, tkOf, tkOr, tkOut, 
     tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkStatic,
@@ -75,7 +75,7 @@ const
     "elif", "else", "end", "enum", "except", "export",
     "finally", "for", "from", "generic", "if", 
     "import", "in", "include", "interface", "is", "isnot", "iterator",
-    "lambda", "let", 
+    "let", 
     "macro", "method", "mixin", "mod", 
     "nil", "not", "notin", "object", "of", "or", 
     "out", "proc", "ptr", "raise", "ref", "return", 
diff --git a/compiler/lists.nim b/compiler/lists.nim
index dd4f5d6be..efffe60fe 100644
--- a/compiler/lists.nim
+++ b/compiler/lists.nim
@@ -8,7 +8,8 @@
 #
 
 # This module implements a generic doubled linked list.
-
+# TODO Remove this and replace it with something sensible
+import os
 type 
   PListEntry* = ref TListEntry
   TListEntry* = object of TObject
@@ -103,11 +104,12 @@ proc bringToFront*(list: var TLinkedList, entry: PListEntry) =
     entry.next = list.head
     list.head = entry
 
-proc excludeStr*(list: var TLinkedList, data: string) =
+proc excludePath*(list: var TLinkedList, data: string) =
   var it = list.head
   while it != nil:
     let nxt = it.next
-    if PStrEntry(it).data == data: remove(list, it)
+    if cmpPaths(PStrEntry(it).data, data) == 0:
+      remove(list, it)
     it = nxt
 
 proc find*(list: TLinkedList, fn: TCompareProc, closure: pointer): PListEntry = 
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index e2afa4362..ddfcb4f01 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -64,6 +64,22 @@ proc createObj*(owner: PSym, info: TLineInfo): PType =
   incl result.flags, tfFinal
   result.n = newNodeI(nkRecList, info)
 
+proc rawAddField*(obj: PType; field: PSym) =
+  assert field.kind == skField
+  field.position = sonsLen(obj.n)
+  addSon(obj.n, newSymNode(field))
+
+proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode = 
+  # returns a[].field as a node
+  assert field.kind == skField
+  var deref = newNodeI(nkHiddenDeref, info)
+  deref.typ = a.typ.skipTypes(abstractInst).sons[0]
+  addSon(deref, a)
+  result = newNodeI(nkDotExpr, info)
+  addSon(result, deref)
+  addSon(result, newSymNode(field))
+  result.typ = field.typ
+
 proc addField*(obj: PType; s: PSym) =
   # because of 'gensym' support, we have to mangle the name with its ID.
   # This is hacky but the clean solution is much more complex than it looks.
@@ -74,6 +90,16 @@ proc addField*(obj: PType; s: PSym) =
   field.position = sonsLen(obj.n)
   addSon(obj.n, newSymNode(field))
 
+proc addUniqueField*(obj: PType; s: PSym) =
+  let fieldName = getIdent(s.name.s & $s.id)
+  if lookupInRecord(obj.n, fieldName) == nil:
+    var field = newSym(skField, fieldName, s.owner, s.info)
+    let t = skipIntLit(s.typ)
+    field.typ = t
+    assert t.kind != tyStmt
+    field.position = sonsLen(obj.n)
+    addSon(obj.n, newSymNode(field))
+
 proc newDotExpr(obj, b: PSym): PNode =
   result = newNodeI(nkDotExpr, obj.info)
   let field = getSymFromList(obj.typ.n, getIdent(b.name.s & $b.id))
@@ -95,13 +121,28 @@ proc indirectAccess*(a: PNode, b: string, info: TLineInfo): PNode =
     t = t.sons[0]
     if t == nil: break
     t = t.skipTypes(abstractInst)
-  assert field != nil, b
+  #if field == nil:
+  #  echo "FIELD ", b
+  #  debug deref.typ
+  internalAssert field != nil
   addSon(deref, a)
   result = newNodeI(nkDotExpr, info)
   addSon(result, deref)
   addSon(result, newSymNode(field))
   result.typ = field.typ
 
+proc getFieldFromObj*(t: PType; v: PSym): PSym =
+  assert v.kind != skField
+  let fieldName = getIdent(v.name.s & $v.id)
+  var t = t
+  while true:
+    assert t.kind == tyObject
+    result = getSymFromList(t.n, fieldName)
+    if result != nil: break
+    t = t.sons[0]
+    if t == nil: break
+    t = t.skipTypes(abstractInst)
+
 proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode = 
   # returns a[].b as a node
   result = indirectAccess(a, b.name.s & $b.id, info)
@@ -144,14 +185,14 @@ proc callProc(a: PNode): PNode =
 # - a proc returning non GC'ed memory --> pass as hidden 'var' parameter
 # - not in a parallel environment --> requires a flowVar for memory safety
 type
-  TSpawnResult = enum
+  TSpawnResult* = enum
     srVoid, srFlowVar, srByVar
   TFlowVarKind = enum
     fvInvalid # invalid type T for 'FlowVar[T]'
     fvGC      # FlowVar of a GC'ed type
     fvBlob    # FlowVar of a blob type
 
-proc spawnResult(t: PType; inParallel: bool): TSpawnResult =
+proc spawnResult*(t: PType; inParallel: bool): TSpawnResult =
   if t.isEmptyType: srVoid
   elif inParallel and not containsGarbageCollectedRef(t): srByVar
   else: srFlowVar
@@ -161,7 +202,8 @@ proc flowVarKind(t: PType): TFlowVarKind =
   elif containsGarbageCollectedRef(t): fvInvalid
   else: fvBlob
 
-proc addLocalVar(varSection: PNode; owner: PSym; typ: PType; v: PNode): PSym =
+proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType;
+                 v: PNode): PSym =
   result = newSym(skTemp, getIdent(genPrefix), owner, varSection.info)
   result.typ = typ
   incl(result.flags, sfFromGeneric)
@@ -169,8 +211,14 @@ proc addLocalVar(varSection: PNode; owner: PSym; typ: PType; v: PNode): PSym =
   var vpart = newNodeI(nkIdentDefs, varSection.info, 3)
   vpart.sons[0] = newSymNode(result)
   vpart.sons[1] = ast.emptyNode
-  vpart.sons[2] = v
+  vpart.sons[2] = if varInit.isNil: v else: ast.emptyNode
   varSection.add vpart
+  if varInit != nil:
+    let deepCopyCall = newNodeI(nkCall, varInit.info, 3)
+    deepCopyCall.sons[0] = newSymNode(createMagic("deepCopy", mDeepCopy))
+    deepCopyCall.sons[1] = newSymNode(result)
+    deepCopyCall.sons[2] = v
+    varInit.add deepCopyCall
 
 discard """
 We generate roughly this:
@@ -203,24 +251,24 @@ stmtList:
 """
 
 proc createWrapperProc(f: PNode; threadParam, argsParam: PSym;
-                       varSection, call, barrier, fv: PNode;
+                       varSection, varInit, call, barrier, fv: PNode;
                        spawnKind: TSpawnResult): PSym =
   var body = newNodeI(nkStmtList, f.info)
   var threadLocalBarrier: PSym
   if barrier != nil:
-    var varSection = newNodeI(nkVarSection, barrier.info)
-    threadLocalBarrier = addLocalVar(varSection, argsParam.owner, 
+    var varSection2 = newNodeI(nkVarSection, barrier.info)
+    threadLocalBarrier = addLocalVar(varSection2, nil, argsParam.owner, 
                                      barrier.typ, barrier)
-    body.add varSection
+    body.add varSection2
     body.add callCodeGenProc("barrierEnter", threadLocalBarrier.newSymNode)
   var threadLocalProm: PSym
   if spawnKind == srByVar:
-    threadLocalProm = addLocalVar(varSection, argsParam.owner, fv.typ, fv)
+    threadLocalProm = addLocalVar(varSection, nil, argsParam.owner, fv.typ, fv)
   elif fv != nil:
     internalAssert fv.typ.kind == tyGenericInst
-    threadLocalProm = addLocalVar(varSection, argsParam.owner, fv.typ, fv)
-    
+    threadLocalProm = addLocalVar(varSection, nil, argsParam.owner, fv.typ, fv)
   body.add varSection
+  body.add varInit
   if fv != nil and spawnKind != srByVar:
     # generate:
     #   fv.owner = threadParam
@@ -273,7 +321,8 @@ proc createCastExpr(argsParam: PSym; objType: PType): PNode =
   result.typ.rawAddSon(objType)
 
 proc setupArgsForConcurrency(n: PNode; objType: PType; scratchObj: PSym, 
-                             castExpr, call, varSection, result: PNode) =
+                             castExpr, call, 
+                             varSection, varInit, result: PNode) =
   let formals = n[0].typ.n
   let tmpName = getIdent(genPrefix)
   for i in 1 .. <n.len:
@@ -282,8 +331,8 @@ proc setupArgsForConcurrency(n: PNode; objType: PType; scratchObj: PSym,
     var argType = n[i].typ.skipTypes(abstractInst)
     if i < formals.len and formals[i].typ.kind == tyVar:
       localError(n[i].info, "'spawn'ed function cannot have a 'var' parameter")
-    elif containsTyRef(argType):
-      localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
+    #elif containsTyRef(argType):
+    #  localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
 
     let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
     var field = newSym(skField, fieldname, objType.owner, n.info)
@@ -291,8 +340,8 @@ proc setupArgsForConcurrency(n: PNode; objType: PType; scratchObj: PSym,
     objType.addField(field)
     result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i])
 
-    let temp = addLocalVar(varSection, objType.owner, argType,
-                           indirectAccess(castExpr, field, n.info))    
+    let temp = addLocalVar(varSection, varInit, objType.owner, argType,
+                           indirectAccess(castExpr, field, n.info))
     call.add(newSymNode(temp))
 
 proc getRoot*(n: PNode): PSym =
@@ -326,7 +375,8 @@ proc genHigh(n: PNode): PNode =
     result.sons[1] = n
 
 proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
-                             castExpr, call, varSection, result: PNode) =
+                             castExpr, call, 
+                             varSection, varInit, result: PNode) =
   let formals = n[0].typ.n
   let tmpName = getIdent(genPrefix)
   # we need to copy the foreign scratch object fields into local variables
@@ -335,8 +385,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
     let n = n[i]
     let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ,
                             abstractInst)
-    if containsTyRef(argType):
-      localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
+    #if containsTyRef(argType):
+    #  localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
 
     let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
     var field = newSym(skField, fieldname, objType.owner, n.info)
@@ -362,7 +412,7 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
         result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2])
         result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3])
 
-        let threadLocal = addLocalVar(varSection, objType.owner, fieldA.typ,
+        let threadLocal = addLocalVar(varSection,nil, objType.owner, fieldA.typ,
                                       indirectAccess(castExpr, fieldA, n.info))
         slice.sons[2] = threadLocal.newSymNode
       else:
@@ -376,7 +426,7 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
       # the array itself does not need to go through a thread local variable:
       slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info))
 
-      let threadLocal = addLocalVar(varSection, objType.owner, fieldB.typ,
+      let threadLocal = addLocalVar(varSection,nil, objType.owner, fieldB.typ,
                                     indirectAccess(castExpr, fieldB, n.info))
       slice.sons[3] = threadLocal.newSymNode
       call.add slice
@@ -387,7 +437,7 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
       field.typ = a.typ
       objType.addField(field)
       result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
-      let threadLocal = addLocalVar(varSection, objType.owner, field.typ,
+      let threadLocal = addLocalVar(varSection,nil, objType.owner, field.typ,
                                     indirectAccess(castExpr, field, n.info))
       call.add(genDeref(threadLocal.newSymNode))
     else:
@@ -395,7 +445,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym;
       field.typ = argType
       objType.addField(field)
       result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n)
-      let threadLocal = addLocalVar(varSection, objType.owner, field.typ,
+      let threadLocal = addLocalVar(varSection, varInit,
+                                    objType.owner, field.typ,
                                     indirectAccess(castExpr, field, n.info))
       call.add(threadLocal.newSymNode)
 
@@ -463,10 +514,13 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType;
 
   call.add(fn)
   var varSection = newNodeI(nkVarSection, n.info)
+  var varInit = newNodeI(nkStmtList, n.info)
   if barrier.isNil:
-    setupArgsForConcurrency(n, objType, scratchObj, castExpr, call, varSection, result)
-  else: 
-    setupArgsForParallelism(n, objType, scratchObj, castExpr, call, varSection, result)
+    setupArgsForConcurrency(n, objType, scratchObj, castExpr, call, 
+                            varSection, varInit, result)
+  else:
+    setupArgsForParallelism(n, objType, scratchObj, castExpr, call, 
+                            varSection, varInit, result)
 
   var barrierAsExpr: PNode = nil
   if barrier != nil:
@@ -498,7 +552,8 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType;
     fvAsExpr = indirectAccess(castExpr, field, n.info)
     result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
 
-  let wrapper = createWrapperProc(fn, threadParam, argsParam, varSection, call,
+  let wrapper = createWrapperProc(fn, threadParam, argsParam, 
+                                  varSection, varInit, call,
                                   barrierAsExpr, fvAsExpr, spawnKind)
   result.add callCodeGenProc("nimSpawn", wrapper.newSymNode,
                              genAddrOf(scratchObj.newSymNode))
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim
index b4f6e043d..475326161 100644
--- a/compiler/magicsys.nim
+++ b/compiler/magicsys.nim
@@ -27,6 +27,8 @@ var
   gSysTypes: array[TTypeKind, PType]
   compilerprocs: TStrTable
 
+proc nilOrSysInt*: PType = gSysTypes[tyInt]
+
 proc registerSysType(t: PType) = 
   if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
   
diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim
index efe3d83bf..ea7621b09 100644
--- a/compiler/nimrod.nim
+++ b/compiler/nimrod.nim
@@ -58,7 +58,7 @@ proc handleCmdLine() =
     if msgs.gErrorCounter == 0:
       when hasTinyCBackend:
         if gCmd == cmdRun:
-          tccgen.run()
+          tccgen.run(service.arguments)
       if optRun in gGlobalOptions:
         if gCmd == cmdCompileToJS:
           var ex: string
diff --git a/compiler/pas2nim/nimrod.cfg b/compiler/pas2nim/nimrod.cfg
deleted file mode 100644
index cfeda63ed..000000000
--- a/compiler/pas2nim/nimrod.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# Use the modules of the compiler
-
-path: "$nimrod/compiler"
-
diff --git a/compiler/pas2nim/pas2nim.nim b/compiler/pas2nim/pas2nim.nim
deleted file mode 100644
index d10028167..000000000
--- a/compiler/pas2nim/pas2nim.nim
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-#
-#      Pas2nim - Pascal to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-import
-  strutils, os, parseopt, llstream, ast, renderer, options, msgs,
-  paslex, pasparse
-
-const
-  Version = "0.8"
-  Usage = """
-pas2nim - Pascal to Nimrod source converter
-  (c) 2012 Andreas Rumpf
-Usage: pas2nim [options] inputfile [options]
-Options:
-  -o, --out:FILE         set output filename
-  --ref                  convert ^typ to ref typ (default: ptr typ)
-  --boot                 use special translation rules for the Nimrod compiler
-  -v, --version          write pas2nim's version
-  -h, --help             show this help
-"""
-
-proc main(infile, outfile: string, flags: set[TParserFlag]) =
-  var stream = llStreamOpen(infile, fmRead)
-  if stream == nil: rawMessage(errCannotOpenFile, infile)
-  var p: TParser
-  openParser(p, infile, stream, flags)
-  var module = parseUnit(p)
-  closeParser(p)
-  renderModule(module, outfile)
-
-var
-  infile = ""
-  outfile = ""
-  flags: set[TParserFlag] = {}
-for kind, key, val in getopt():
-  case kind
-  of cmdArgument: infile = key
-  of cmdLongOption, cmdShortOption:
-    case key
-    of "help", "h":
-      stdout.write(Usage)
-      quit(0)
-    of "version", "v":
-      stdout.write(Version & "\n")
-      quit(0)
-    of "o", "out": outfile = val
-    of "ref": incl(flags, pfRefs)
-    of "boot": flags = flags + {pfRefs, pfMoreReplacements, pfImportBlackList}
-    else: stdout.writeln("[Error] unknown option: " & key)
-  of cmdEnd: assert(false)
-if infile.len == 0:
-  # no filename has been given, so we show the help:
-  stdout.write(Usage)
-else:
-  if outfile.len == 0:
-    outfile = changeFileExt(infile, "nim")
-  infile = addFileExt(infile, "pas")
-  main(infile, outfile, flags)
diff --git a/compiler/pas2nim/paslex.nim b/compiler/pas2nim/paslex.nim
deleted file mode 100644
index f24b0c420..000000000
--- a/compiler/pas2nim/paslex.nim
+++ /dev/null
@@ -1,570 +0,0 @@
-#
-#
-#      Pas2nim - Pascal to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# This module implements a FreePascal scanner. This is an adaption from
-# the scanner module.
-
-import
-  hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream
-
-const
-  MaxLineLength* = 80         # lines longer than this lead to a warning
-  numChars*: TCharSet = {'0'..'9', 'a'..'z', 'A'..'Z'}
-  SymChars*: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'}
-  SymStartChars*: TCharSet = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
-  OpChars*: TCharSet = {'+', '-', '*', '/', '<', '>', '!', '?', '^', '.', '|',
-    '=', ':', '%', '&', '$', '@', '~', '\x80'..'\xFF'}
-
-# keywords are sorted!
-
-type
-  TTokKind* = enum
-    pxInvalid, pxEof,
-    pxAnd, pxArray, pxAs, pxAsm, pxBegin, pxCase, pxClass, pxConst,
-    pxConstructor, pxDestructor, pxDiv, pxDo, pxDownto, pxElse, pxEnd, pxExcept,
-    pxExports, pxFinalization, pxFinally, pxFor, pxFunction, pxGoto, pxIf,
-    pxImplementation, pxIn, pxInherited, pxInitialization, pxInline,
-    pxInterface, pxIs, pxLabel, pxLibrary, pxMod, pxNil, pxNot, pxObject, pxOf,
-    pxOr, pxOut, pxPacked, pxProcedure, pxProgram, pxProperty, pxRaise,
-    pxRecord, pxRepeat, pxResourcestring, pxSet, pxShl, pxShr, pxThen,
-    pxThreadvar, pxTo, pxTry, pxType, pxUnit, pxUntil, pxUses, pxVar, pxWhile,
-    pxWith, pxXor,
-    pxComment,                # ordinary comment
-    pxCommand,                # {@}
-    pxAmp,                    # {&}
-    pxPer,                    # {%}
-    pxStrLit, pxSymbol,       # a symbol
-    pxIntLit, pxInt64Lit, # long constant like 0x70fffffff or out of int range
-    pxFloatLit, pxParLe, pxParRi, pxBracketLe, pxBracketRi, pxComma,
-    pxSemiColon, pxColon,     # operators
-    pxAsgn, pxEquals, pxDot, pxDotDot, pxHat, pxPlus, pxMinus, pxStar, pxSlash,
-    pxLe, pxLt, pxGe, pxGt, pxNeq, pxAt, pxStarDirLe, pxStarDirRi, pxCurlyDirLe,
-    pxCurlyDirRi
-  TTokKinds* = set[TTokKind]
-
-const
-  Keywords = ["and", "array", "as", "asm", "begin", "case", "class", "const",
-    "constructor", "destructor", "div", "do", "downto", "else", "end", "except",
-    "exports", "finalization", "finally", "for", "function", "goto", "if",
-    "implementation", "in", "inherited", "initialization", "inline",
-    "interface", "is", "label", "library", "mod", "nil", "not", "object", "of",
-    "or", "out", "packed", "procedure", "program", "property", "raise",
-    "record", "repeat", "resourcestring", "set", "shl", "shr", "then",
-    "threadvar", "to", "try", "type", "unit", "until", "uses", "var", "while",
-    "with", "xor"]
-
-  firstKeyword = pxAnd
-  lastKeyword = pxXor
-
-type
-  TNumericalBase* = enum base10, base2, base8, base16
-  TToken* = object
-    xkind*: TTokKind          # the type of the token
-    ident*: PIdent            # the parsed identifier
-    iNumber*: BiggestInt      # the parsed integer literal
-    fNumber*: BiggestFloat    # the parsed floating point literal
-    base*: TNumericalBase     # the numerical base; only valid for int
-                              # or float literals
-    literal*: string          # the parsed (string) literal
-
-  TLexer* = object of TBaseLexer
-    filename*: string
-
-
-proc getTok*(L: var TLexer, tok: var TToken)
-proc printTok*(tok: TToken)
-proc `$`*(tok: TToken): string
-# implementation
-
-var
-  dummyIdent: PIdent
-  gLinesCompiled: int
-
-proc fillToken(L: var TToken) =
-  L.xkind = pxInvalid
-  L.iNumber = 0
-  L.literal = ""
-  L.fNumber = 0.0
-  L.base = base10
-  L.ident = dummyIdent        # this prevents many bugs!
-
-proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) =
-  openBaseLexer(lex, inputstream)
-  lex.filename = filename
-
-proc closeLexer*(lex: var TLexer) =
-  inc(gLinesCompiled, lex.LineNumber)
-  closeBaseLexer(lex)
-
-proc getColumn(L: TLexer): int =
-  result = getColNumber(L, L.bufPos)
-
-proc getLineInfo*(L: TLexer): TLineInfo =
-  result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos))
-
-proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") =
-  msgs.globalError(getLineInfo(L), msg, arg)
-
-proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") =
-  var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart)
-  msgs.globalError(info, msg, arg)
-
-proc tokKindToStr*(k: TTokKind): string =
-  case k
-  of pxEof: result = "[EOF]"
-  of firstKeyword..lastKeyword:
-    result = Keywords[ord(k)-ord(firstKeyword)]
-  of pxInvalid, pxComment, pxStrLit: result = "string literal"
-  of pxCommand: result = "{@"
-  of pxAmp: result = "{&"
-  of pxPer: result = "{%"
-  of pxSymbol: result = "identifier"
-  of pxIntLit, pxInt64Lit: result = "integer literal"
-  of pxFloatLit: result = "floating point literal"
-  of pxParLe: result = "("
-  of pxParRi: result = ")"
-  of pxBracketLe: result = "["
-  of pxBracketRi: result = "]"
-  of pxComma: result = ","
-  of pxSemiColon: result = ";"
-  of pxColon: result = ":"
-  of pxAsgn: result = ":="
-  of pxEquals: result = "="
-  of pxDot: result = "."
-  of pxDotDot: result = ".."
-  of pxHat: result = "^"
-  of pxPlus: result = "+"
-  of pxMinus: result = "-"
-  of pxStar: result = "*"
-  of pxSlash: result = "/"
-  of pxLe: result = "<="
-  of pxLt: result = "<"
-  of pxGe: result = ">="
-  of pxGt: result = ">"
-  of pxNeq: result = "<>"
-  of pxAt: result = "@"
-  of pxStarDirLe: result = "(*$"
-  of pxStarDirRi: result = "*)"
-  of pxCurlyDirLe: result = "{$"
-  of pxCurlyDirRi: result = "}"
-
-proc `$`(tok: TToken): string =
-  case tok.xkind
-  of pxInvalid, pxComment, pxStrLit: result = tok.literal
-  of pxSymbol: result = tok.ident.s
-  of pxIntLit, pxInt64Lit: result = $tok.iNumber
-  of pxFloatLit: result = $tok.fNumber
-  else: result = tokKindToStr(tok.xkind)
-
-proc printTok(tok: TToken) =
-  writeln(stdout, $tok)
-
-proc setKeyword(L: var TLexer, tok: var TToken) =
-  var x = binaryStrSearch(keywords, toLower(tok.ident.s))
-  if x < 0: tok.xkind = pxSymbol
-  else: tok.xKind = TTokKind(x + ord(firstKeyword))
-
-proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) =
-  # matches ([chars]_)*
-  var pos = L.bufpos              # use registers for pos, buf
-  var buf = L.buf
-  while true:
-    if buf[pos] in chars:
-      add(tok.literal, buf[pos])
-      inc(pos)
-    else:
-      break
-    if buf[pos] == '_':
-      add(tok.literal, '_')
-      inc(pos)
-  L.bufPos = pos
-
-proc isFloatLiteral(s: string): bool =
-  for i in countup(0, len(s)-1):
-    if s[i] in {'.', 'e', 'E'}:
-      return true
-
-proc getNumber2(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos + 1 # skip %
-  if not (L.buf[pos] in {'0'..'1'}):
-    # BUGFIX for %date%
-    tok.xkind = pxInvalid
-    add(tok.literal, '%')
-    inc(L.bufpos)
-    return
-  tok.base = base2
-  var xi: BiggestInt = 0
-  var bits = 0
-  while true:
-    case L.buf[pos]
-    of 'A'..'Z', 'a'..'z', '2'..'9', '.':
-      lexMessage(L, errInvalidNumber)
-      inc(pos)
-    of '_':
-      inc(pos)
-    of '0', '1':
-      xi = `shl`(xi, 1) or (ord(L.buf[pos]) - ord('0'))
-      inc(pos)
-      inc(bits)
-    else: break
-  tok.iNumber = xi
-  if (bits > 32): tok.xkind = pxInt64Lit
-  else: tok.xkind = pxIntLit
-  L.bufpos = pos
-
-proc getNumber16(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos + 1          # skip $
-  tok.base = base16
-  var xi: BiggestInt = 0
-  var bits = 0
-  while true:
-    case L.buf[pos]
-    of 'G'..'Z', 'g'..'z', '.':
-      lexMessage(L, errInvalidNumber)
-      inc(pos)
-    of '_': inc(pos)
-    of '0'..'9':
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('0'))
-      inc(pos)
-      inc(bits, 4)
-    of 'a'..'f':
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('a') + 10)
-      inc(pos)
-      inc(bits, 4)
-    of 'A'..'F':
-      xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('A') + 10)
-      inc(pos)
-      inc(bits, 4)
-    else: break
-  tok.iNumber = xi
-  if (bits > 32):
-    tok.xkind = pxInt64Lit
-  else:
-    tok.xkind = pxIntLit
-  L.bufpos = pos
-
-proc getNumber10(L: var TLexer, tok: var TToken) =
-  tok.base = base10
-  matchUnderscoreChars(L, tok, {'0'..'9'})
-  if (L.buf[L.bufpos] == '.') and (L.buf[L.bufpos + 1] in {'0'..'9'}):
-    add(tok.literal, '.')
-    inc(L.bufpos)
-    matchUnderscoreChars(L, tok, {'e', 'E', '+', '-', '0'..'9'})
-  try:
-    if isFloatLiteral(tok.literal):
-      tok.fnumber = parseFloat(tok.literal)
-      tok.xkind = pxFloatLit
-    else:
-      tok.iNumber = parseInt(tok.literal)
-      if (tok.iNumber < low(int32)) or (tok.iNumber > high(int32)):
-        tok.xkind = pxInt64Lit
-      else:
-        tok.xkind = pxIntLit
-  except EInvalidValue:
-    lexMessage(L, errInvalidNumber, tok.literal)
-  except EOverflow:
-    lexMessage(L, errNumberOutOfRange, tok.literal)
-
-proc handleCRLF(L: var TLexer, pos: int): int =
-  case L.buf[pos]
-  of CR: result = nimlexbase.handleCR(L, pos)
-  of LF: result = nimlexbase.handleLF(L, pos)
-  else: result = pos
-
-proc getString(L: var TLexer, tok: var TToken) =
-  var xi: int
-  var pos = L.bufPos
-  var buf = L.buf
-  while true:
-    if buf[pos] == '\'':
-      inc(pos)
-      while true:
-        case buf[pos]
-        of CR, LF, nimlexbase.EndOfFile:
-          lexMessage(L, errClosingQuoteExpected)
-          break
-        of '\'':
-          inc(pos)
-          if buf[pos] == '\'':
-            inc(pos)
-            add(tok.literal, '\'')
-          else:
-            break
-        else:
-          add(tok.literal, buf[pos])
-          inc(pos)
-    elif buf[pos] == '#':
-      inc(pos)
-      xi = 0
-      case buf[pos]
-      of '$':
-        inc(pos)
-        xi = 0
-        while true:
-          case buf[pos]
-          of '0'..'9': xi = (xi shl 4) or (ord(buf[pos]) - ord('0'))
-          of 'a'..'f': xi = (xi shl 4) or (ord(buf[pos]) - ord('a') + 10)
-          of 'A'..'F': xi = (xi shl 4) or (ord(buf[pos]) - ord('A') + 10)
-          else: break
-          inc(pos)
-      of '0'..'9':
-        xi = 0
-        while buf[pos] in {'0'..'9'}:
-          xi = (xi * 10) + (ord(buf[pos]) - ord('0'))
-          inc(pos)
-      else: lexMessage(L, errInvalidCharacterConstant)
-      if (xi <= 255): add(tok.literal, chr(xi))
-      else: lexMessage(L, errInvalidCharacterConstant)
-    else:
-      break
-  tok.xkind = pxStrLit
-  L.bufpos = pos
-
-proc getSymbol(L: var TLexer, tok: var TToken) =
-  var h: THash = 0
-  var pos = L.bufpos
-  var buf = L.buf
-  while true:
-    var c = buf[pos]
-    case c
-    of 'a'..'z', '0'..'9', '\x80'..'\xFF':
-      h = h +% ord(c)
-      h = h +% h shl 10
-      h = h xor (h shr 6)
-    of 'A'..'Z':
-      c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
-      h = h +% ord(c)
-      h = h +% h shl 10
-      h = h xor (h shr 6)
-    of '_': discard
-    else: break
-    inc(pos)
-  h = h +% h shl 3
-  h = h xor (h shr 11)
-  h = h +% h shl 15
-  tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
-  L.bufpos = pos
-  setKeyword(L, tok)
-
-proc scanLineComment(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos
-  var buf = L.buf
-  # a comment ends if the next line does not start with the // on the same
-  # column after only whitespace
-  tok.xkind = pxComment
-  var col = getColNumber(L, pos)
-  while true:
-    inc(pos, 2)               # skip //
-    add(tok.literal, '#')
-    while not (buf[pos] in {CR, LF, nimlexbase.EndOfFile}):
-      add(tok.literal, buf[pos])
-      inc(pos)
-    pos = handleCRLF(L, pos)
-    buf = L.buf
-    var indent = 0
-    while buf[pos] == ' ':
-      inc(pos)
-      inc(indent)
-    if (col == indent) and (buf[pos] == '/') and (buf[pos + 1] == '/'):
-      tok.literal = tok.literal & "\n"
-    else:
-      break
-  L.bufpos = pos
-
-proc scanCurlyComment(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos
-  var buf = L.buf
-  tok.literal = "#"
-  tok.xkind = pxComment
-  while true:
-    case buf[pos]
-    of CR, LF:
-      pos = handleCRLF(L, pos)
-      buf = L.buf
-      add(tok.literal, "\n#")
-    of '}':
-      inc(pos)
-      break
-    of nimlexbase.EndOfFile: lexMessage(L, errTokenExpected, "}")
-    else:
-      add(tok.literal, buf[pos])
-      inc(pos)
-  L.bufpos = pos
-
-proc scanStarComment(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos
-  var buf = L.buf
-  tok.literal = "#"
-  tok.xkind = pxComment
-  while true:
-    case buf[pos]
-    of CR, LF:
-      pos = handleCRLF(L, pos)
-      buf = L.buf
-      add(tok.literal, "\n#")
-    of '*':
-      inc(pos)
-      if buf[pos] == ')':
-        inc(pos)
-        break
-      else:
-        add(tok.literal, '*')
-    of nimlexbase.EndOfFile:
-      lexMessage(L, errTokenExpected, "*)")
-    else:
-      add(tok.literal, buf[pos])
-      inc(pos)
-  L.bufpos = pos
-
-proc skip(L: var TLexer, tok: var TToken) =
-  var pos = L.bufpos
-  var buf = L.buf
-  while true:
-    case buf[pos]
-    of ' ', Tabulator:
-      inc(pos)                # newline is special:
-    of CR, LF:
-      pos = handleCRLF(L, pos)
-      buf = L.buf
-    else:
-      break                   # EndOfFile also leaves the loop
-  L.bufpos = pos
-
-proc getTok(L: var TLexer, tok: var TToken) =
-  tok.xkind = pxInvalid
-  fillToken(tok)
-  skip(L, tok)
-  var c = L.buf[L.bufpos]
-  if c in SymStartChars:
-    getSymbol(L, tok)
-  elif c in {'0'..'9'}:
-    getNumber10(L, tok)
-  else:
-    case c
-    of ';':
-      tok.xkind = pxSemicolon
-      inc(L.bufpos)
-    of '/':
-      if L.buf[L.bufpos + 1] == '/':
-        scanLineComment(L, tok)
-      else:
-        tok.xkind = pxSlash
-        inc(L.bufpos)
-    of ',':
-      tok.xkind = pxComma
-      inc(L.bufpos)
-    of '(':
-      inc(L.bufpos)
-      if (L.buf[L.bufPos] == '*'):
-        if (L.buf[L.bufPos + 1] == '$'):
-          inc(L.bufpos, 2)
-          skip(L, tok)
-          getSymbol(L, tok)
-          tok.xkind = pxStarDirLe
-        else:
-          inc(L.bufpos)
-          scanStarComment(L, tok)
-      else:
-        tok.xkind = pxParLe
-    of '*':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == ')':
-        inc(L.bufpos)
-        tok.xkind = pxStarDirRi
-      else:
-        tok.xkind = pxStar
-    of ')':
-      tok.xkind = pxParRi
-      inc(L.bufpos)
-    of '[':
-      inc(L.bufpos)
-      tok.xkind = pxBracketLe
-    of ']':
-      inc(L.bufpos)
-      tok.xkind = pxBracketRi
-    of '.':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '.':
-        tok.xkind = pxDotDot
-        inc(L.bufpos)
-      else:
-        tok.xkind = pxDot
-    of '{':
-      inc(L.bufpos)
-      case L.buf[L.bufpos]
-      of '$':
-        inc(L.bufpos)
-        skip(L, tok)
-        getSymbol(L, tok)
-        tok.xkind = pxCurlyDirLe
-      of '&':
-        inc(L.bufpos)
-        tok.xkind = pxAmp
-      of '%':
-        inc(L.bufpos)
-        tok.xkind = pxPer
-      of '@':
-        inc(L.bufpos)
-        tok.xkind = pxCommand
-      else: scanCurlyComment(L, tok)
-    of '+':
-      tok.xkind = pxPlus
-      inc(L.bufpos)
-    of '-':
-      tok.xkind = pxMinus
-      inc(L.bufpos)
-    of ':':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        inc(L.bufpos)
-        tok.xkind = pxAsgn
-      else:
-        tok.xkind = pxColon
-    of '<':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '>':
-        inc(L.bufpos)
-        tok.xkind = pxNeq
-      elif L.buf[L.bufpos] == '=':
-        inc(L.bufpos)
-        tok.xkind = pxLe
-      else:
-        tok.xkind = pxLt
-    of '>':
-      inc(L.bufpos)
-      if L.buf[L.bufpos] == '=':
-        inc(L.bufpos)
-        tok.xkind = pxGe
-      else:
-        tok.xkind = pxGt
-    of '=':
-      tok.xkind = pxEquals
-      inc(L.bufpos)
-    of '@':
-      tok.xkind = pxAt
-      inc(L.bufpos)
-    of '^':
-      tok.xkind = pxHat
-      inc(L.bufpos)
-    of '}':
-      tok.xkind = pxCurlyDirRi
-      inc(L.bufpos)
-    of '\'', '#':
-      getString(L, tok)
-    of '$':
-      getNumber16(L, tok)
-    of '%':
-      getNumber2(L, tok)
-    of nimlexbase.EndOfFile:
-      tok.xkind = pxEof
-    else:
-      tok.literal = c & ""
-      tok.xkind = pxInvalid
-      lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')')
-      inc(L.bufpos)
diff --git a/compiler/pas2nim/pasparse.nim b/compiler/pas2nim/pasparse.nim
deleted file mode 100644
index a6f8363f6..000000000
--- a/compiler/pas2nim/pasparse.nim
+++ /dev/null
@@ -1,1513 +0,0 @@
-#
-#
-#      Pas2nim - Pascal to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# This module implements the parser of the Pascal variant Nimrod is written in.
-# It transfers a Pascal module into a Nimrod AST. Then the renderer can be
-# used to convert the AST to its text representation.
-
-import 
-  os, llstream, paslex, idents, strutils, ast, astalgo, msgs, options
-
-type 
-  TSection = enum 
-    seImplementation, seInterface
-  TContext = enum 
-    conExpr, conStmt, conTypeDesc
-  TParserFlag* = enum
-    pfRefs,             ## use "ref" instead of "ptr" for Pascal's ^typ
-    pfMoreReplacements, ## use more than the default replacements
-    pfImportBlackList   ## use import blacklist
-  TParser*{.final.} = object
-    section: TSection
-    inParamList: bool
-    context: TContext     # needed for the @emit command
-    lastVarSection: PNode
-    lex: TLexer
-    tok: TToken
-    repl: TIdTable           # replacements
-    flags: set[TParserFlag]
-  
-  TReplaceTuple* = array[0..1, string]
-
-const 
-  ImportBlackList*: array[1..3, string] = ["nsystem", "sysutils", "charsets"]
-  stdReplacements*: array[1..19, TReplaceTuple] = [["include", "incl"], 
-    ["exclude", "excl"], ["pchar", "cstring"], ["assignfile", "open"], 
-    ["integer", "int"], ["longword", "int32"], ["cardinal", "int"], 
-    ["boolean", "bool"], ["shortint", "int8"], ["smallint", "int16"], 
-    ["longint", "int32"], ["byte", "int8"], ["word", "int16"], 
-    ["single", "float32"], ["double", "float64"], ["real", "float"], 
-    ["length", "len"], ["len", "length"], ["setlength", "setlen"]]
-  nimReplacements*: array[1..35, TReplaceTuple] = [["nimread", "read"], 
-    ["nimwrite", "write"], ["nimclosefile", "close"], ["closefile", "close"], 
-    ["openfile", "open"], ["nsystem", "system"], ["ntime", "times"], 
-    ["nos", "os"], ["nmath", "math"], ["ncopy", "copy"], ["addChar", "add"], 
-    ["halt", "quit"], ["nobject", "TObject"], ["eof", "EndOfFile"], 
-    ["input", "stdin"], ["output", "stdout"], ["addu", "`+%`"], 
-    ["subu", "`-%`"], ["mulu", "`*%`"], ["divu", "`/%`"], ["modu", "`%%`"], 
-    ["ltu", "`<%`"], ["leu", "`<=%`"], ["shlu", "`shl`"], ["shru", "`shr`"], 
-    ["assigned", "not isNil"], ["eintoverflow", "EOverflow"], ["format", "`%`"], 
-    ["snil", "nil"], ["tostringf", "$"], ["ttextfile", "tfile"], 
-    ["tbinaryfile", "tfile"], ["strstart", "0"], ["nl", "\"\\n\""],
-    ["tostring", "$"]]
-
-proc parseUnit*(p: var TParser): PNode
-proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
-                 flags: set[TParserFlag] = {})
-proc closeParser*(p: var TParser)
-proc exSymbol*(n: var PNode)
-proc fixRecordDef*(n: var PNode)
-  # XXX: move these two to an auxiliary module
-
-# implementation
-
-proc openParser(p: var TParser, filename: string, 
-                inputStream: PLLStream, flags: set[TParserFlag] = {}) = 
-  openLexer(p.lex, filename, inputStream)
-  initIdTable(p.repl)
-  for i in countup(low(stdReplacements), high(stdReplacements)): 
-    idTablePut(p.repl, getIdent(stdReplacements[i][0]), 
-               getIdent(stdReplacements[i][1]))
-  if pfMoreReplacements in flags: 
-    for i in countup(low(nimReplacements), high(nimReplacements)): 
-      idTablePut(p.repl, getIdent(nimReplacements[i][0]), 
-                 getIdent(nimReplacements[i][1]))
-  p.flags = flags
-  
-proc closeParser(p: var TParser) = closeLexer(p.lex)
-proc getTok(p: var TParser) = getTok(p.lex, p.tok)
-
-proc parMessage(p: TParser, msg: TMsgKind, arg = "") = 
-  lexMessage(p.lex, msg, arg)
-
-proc parLineInfo(p: TParser): TLineInfo = 
-  result = getLineInfo(p.lex)
-
-proc skipCom(p: var TParser, n: PNode) = 
-  while p.tok.xkind == pxComment: 
-    if (n != nil): 
-      if n.comment == nil: n.comment = p.tok.literal
-      else: add(n.comment, "\n" & p.tok.literal)
-    else: 
-      parMessage(p, warnCommentXIgnored, p.tok.literal)
-    getTok(p)
-
-proc expectIdent(p: TParser) = 
-  if p.tok.xkind != pxSymbol: 
-    lexMessage(p.lex, errIdentifierExpected, $(p.tok))
-  
-proc eat(p: var TParser, xkind: TTokKind) = 
-  if p.tok.xkind == xkind: getTok(p)
-  else: lexMessage(p.lex, errTokenExpected, tokKindToStr(xkind))
-  
-proc opt(p: var TParser, xkind: TTokKind) = 
-  if p.tok.xkind == xkind: getTok(p)
-  
-proc newNodeP(kind: TNodeKind, p: TParser): PNode = 
-  result = newNodeI(kind, getLineInfo(p.lex))
-
-proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.intVal = intVal
-
-proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, 
-                   p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.floatVal = floatVal
-
-proc newStrNodeP(kind: TNodeKind, strVal: string, p: TParser): PNode = 
-  result = newNodeP(kind, p)
-  result.strVal = strVal
-
-proc newIdentNodeP(ident: PIdent, p: TParser): PNode = 
-  result = newNodeP(nkIdent, p)
-  result.ident = ident
-
-proc createIdentNodeP(ident: PIdent, p: TParser): PNode = 
-  result = newNodeP(nkIdent, p)
-  var x = PIdent(idTableGet(p.repl, ident))
-  if x != nil: result.ident = x
-  else: result.ident = ident
-  
-proc parseExpr(p: var TParser): PNode
-proc parseStmt(p: var TParser): PNode
-proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode
-
-proc parseEmit(p: var TParser, definition: PNode): PNode = 
-  getTok(p)                   # skip 'emit'
-  result = ast.emptyNode
-  if p.tok.xkind != pxCurlyDirRi: 
-    case p.context
-    of conExpr: 
-      result = parseExpr(p)
-    of conStmt: 
-      result = parseStmt(p)
-      if p.tok.xkind != pxCurlyDirRi: 
-        var a = result
-        result = newNodeP(nkStmtList, p)
-        addSon(result, a)
-        while p.tok.xkind != pxCurlyDirRi: 
-          addSon(result, parseStmt(p))
-    of conTypeDesc: 
-      result = parseTypeDesc(p, definition)
-  eat(p, pxCurlyDirRi)
-
-proc parseCommand(p: var TParser, definition: PNode = nil): PNode = 
-  result = ast.emptyNode
-  getTok(p)
-  if p.tok.ident.id == getIdent("discard").id: 
-    result = newNodeP(nkDiscardStmt, p)
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-    addSon(result, parseExpr(p))
-  elif p.tok.ident.id == getIdent("set").id: 
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-    result = parseExpr(p)
-    if result.kind == nkEmpty: internalError("emptyNode modified")
-    result.kind = nkCurly
-  elif p.tok.ident.id == getIdent("cast").id: 
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-    var a = parseExpr(p)
-    if (a.kind == nkCall) and (sonsLen(a) == 2): 
-      result = newNodeP(nkCast, p)
-      addSon(result, a.sons[0])
-      addSon(result, a.sons[1])
-    else: 
-      parMessage(p, errInvalidDirectiveX, $p.tok)
-      result = a
-  elif p.tok.ident.id == getIdent("emit").id: 
-    result = parseEmit(p, definition)
-  elif p.tok.ident.id == getIdent("ignore").id: 
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-    while true: 
-      case p.tok.xkind
-      of pxEof: 
-        parMessage(p, errTokenExpected, "{@emit}")
-      of pxCommand: 
-        getTok(p)
-        if p.tok.ident.id == getIdent("emit").id: 
-          result = parseEmit(p, definition)
-          break 
-        else: 
-          while (p.tok.xkind != pxCurlyDirRi) and (p.tok.xkind != pxEof): 
-            getTok(p)
-          eat(p, pxCurlyDirRi)
-      else: 
-        getTok(p)             # skip token
-  elif p.tok.ident.id == getIdent("ptr").id: 
-    result = newNodeP(nkPtrTy, p)
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-  elif p.tok.ident.id == getIdent("tuple").id: 
-    result = newNodeP(nkTupleTy, p)
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-  elif p.tok.ident.id == getIdent("acyclic").id: 
-    result = newIdentNodeP(p.tok.ident, p)
-    getTok(p)
-    eat(p, pxCurlyDirRi)
-  else: 
-    parMessage(p, errInvalidDirectiveX, $p.tok)
-    while true: 
-      getTok(p)
-      if p.tok.xkind == pxCurlyDirRi or p.tok.xkind == pxEof: break 
-    eat(p, pxCurlyDirRi)
-    result = ast.emptyNode
-
-proc getPrecedence(kind: TTokKind): int = 
-  case kind
-  of pxDiv, pxMod, pxStar, pxSlash, pxShl, pxShr, pxAnd: result = 5
-  of pxPlus, pxMinus, pxOr, pxXor: result = 4
-  of pxIn, pxEquals, pxLe, pxLt, pxGe, pxGt, pxNeq, pxIs: result = 3
-  else: result = -1
-  
-proc rangeExpr(p: var TParser): PNode = 
-  var a = parseExpr(p)
-  if p.tok.xkind == pxDotDot: 
-    result = newNodeP(nkRange, p)
-    addSon(result, a)
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseExpr(p))
-  else: 
-    result = a
-  
-proc bracketExprList(p: var TParser, first: PNode): PNode = 
-  result = newNodeP(nkBracketExpr, p)
-  addSon(result, first)
-  getTok(p)
-  skipCom(p, result)
-  while true: 
-    if p.tok.xkind == pxBracketRi: 
-      getTok(p)
-      break 
-    if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, tokKindToStr(pxBracketRi))
-      break 
-    var a = rangeExpr(p)
-    skipCom(p, a)
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-
-proc exprColonEqExpr(p: var TParser, kind: TNodeKind, 
-                     tok: TTokKind): PNode = 
-  var a = parseExpr(p)
-  if p.tok.xkind == tok: 
-    result = newNodeP(kind, p)
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, a)
-    addSon(result, parseExpr(p))
-  else: 
-    result = a
-  
-proc exprListAux(p: var TParser, elemKind: TNodeKind, 
-                 endTok, sepTok: TTokKind, result: PNode) = 
-  getTok(p)
-  skipCom(p, result)
-  while true: 
-    if p.tok.xkind == endTok: 
-      getTok(p)
-      break 
-    if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, tokKindToStr(endTok))
-      break 
-    var a = exprColonEqExpr(p, elemKind, sepTok)
-    skipCom(p, a)
-    if (p.tok.xkind == pxComma) or (p.tok.xkind == pxSemicolon): 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-
-proc qualifiedIdent(p: var TParser): PNode = 
-  if p.tok.xkind == pxSymbol: 
-    result = createIdentNodeP(p.tok.ident, p)
-  else: 
-    parMessage(p, errIdentifierExpected, $p.tok)
-    return ast.emptyNode
-  getTok(p)
-  skipCom(p, result)
-  if p.tok.xkind == pxDot: 
-    getTok(p)
-    skipCom(p, result)
-    if p.tok.xkind == pxSymbol: 
-      var a = result
-      result = newNodeI(nkDotExpr, a.info)
-      addSon(result, a)
-      addSon(result, createIdentNodeP(p.tok.ident, p))
-      getTok(p)
-    else: 
-      parMessage(p, errIdentifierExpected, $p.tok)
-  
-proc qualifiedIdentListAux(p: var TParser, endTok: TTokKind, 
-                           result: PNode) = 
-  getTok(p)
-  skipCom(p, result)
-  while true: 
-    if p.tok.xkind == endTok: 
-      getTok(p)
-      break 
-    if p.tok.xkind == pxEof: 
-      parMessage(p, errTokenExpected, tokKindToStr(endTok))
-      break 
-    var a = qualifiedIdent(p)
-    skipCom(p, a)
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-
-proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind, 
-                         endTok, sepTok: TTokKind): PNode = 
-  result = newNodeP(kind, p)
-  exprListAux(p, elemKind, endTok, sepTok, result)
-
-proc setBaseFlags(n: PNode, base: TNumericalBase) = 
-  case base
-  of base10: discard
-  of base2: incl(n.flags, nfBase2)
-  of base8: incl(n.flags, nfBase8)
-  of base16: incl(n.flags, nfBase16)
-  
-proc identOrLiteral(p: var TParser): PNode = 
-  case p.tok.xkind
-  of pxSymbol: 
-    result = createIdentNodeP(p.tok.ident, p)
-    getTok(p)
-  of pxIntLit: 
-    result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
-    setBaseFlags(result, p.tok.base)
-    getTok(p)
-  of pxInt64Lit: 
-    result = newIntNodeP(nkInt64Lit, p.tok.iNumber, p)
-    setBaseFlags(result, p.tok.base)
-    getTok(p)
-  of pxFloatLit: 
-    result = newFloatNodeP(nkFloatLit, p.tok.fNumber, p)
-    setBaseFlags(result, p.tok.base)
-    getTok(p)
-  of pxStrLit: 
-    if len(p.tok.literal) != 1: result = newStrNodeP(nkStrLit, p.tok.literal, p)
-    else: result = newIntNodeP(nkCharLit, ord(p.tok.literal[0]), p)
-    getTok(p)
-  of pxNil: 
-    result = newNodeP(nkNilLit, p)
-    getTok(p)
-  of pxParLe: 
-    # () constructor
-    result = exprColonEqExprList(p, nkPar, nkExprColonExpr, pxParRi, pxColon)
-    #if hasSonWith(result, nkExprColonExpr) then
-    #  replaceSons(result, nkExprColonExpr, nkExprEqExpr)
-    if (sonsLen(result) > 1) and not hasSonWith(result, nkExprColonExpr): 
-      result.kind = nkBracket # is an array constructor
-  of pxBracketLe: 
-    # [] constructor
-    result = newNodeP(nkBracket, p)
-    getTok(p)
-    skipCom(p, result)
-    while (p.tok.xkind != pxBracketRi) and (p.tok.xkind != pxEof): 
-      var a = rangeExpr(p)
-      if a.kind == nkRange: 
-        result.kind = nkCurly # it is definitely a set literal
-      opt(p, pxComma)
-      skipCom(p, a)
-      assert(a != nil)
-      addSon(result, a)
-    eat(p, pxBracketRi)
-  of pxCommand: 
-    result = parseCommand(p)
-  else: 
-    parMessage(p, errExprExpected, $(p.tok))
-    getTok(p) # we must consume a token here to prevend endless loops!
-    result = ast.emptyNode
-  if result.kind != nkEmpty: skipCom(p, result)
-  
-proc primary(p: var TParser): PNode = 
-  # prefix operator?
-  if (p.tok.xkind == pxNot) or (p.tok.xkind == pxMinus) or
-      (p.tok.xkind == pxPlus): 
-    result = newNodeP(nkPrefix, p)
-    var a = newIdentNodeP(getIdent($p.tok), p)
-    addSon(result, a)
-    getTok(p)
-    skipCom(p, a)
-    addSon(result, primary(p))
-    return 
-  elif p.tok.xkind == pxAt: 
-    result = newNodeP(nkAddr, p)
-    var a = newIdentNodeP(getIdent($p.tok), p)
-    getTok(p)
-    if p.tok.xkind == pxBracketLe: 
-      result = newNodeP(nkPrefix, p)
-      addSon(result, a)
-      addSon(result, identOrLiteral(p))
-    else: 
-      addSon(result, primary(p))
-    return 
-  result = identOrLiteral(p)
-  while true: 
-    case p.tok.xkind
-    of pxParLe: 
-      var a = result
-      result = newNodeP(nkCall, p)
-      addSon(result, a)
-      exprListAux(p, nkExprEqExpr, pxParRi, pxEquals, result)
-    of pxDot: 
-      var a = result
-      result = newNodeP(nkDotExpr, p)
-      addSon(result, a)
-      getTok(p)               # skip '.'
-      skipCom(p, result)
-      if p.tok.xkind == pxSymbol: 
-        addSon(result, createIdentNodeP(p.tok.ident, p))
-        getTok(p)
-      else: 
-        parMessage(p, errIdentifierExpected, $p.tok)
-    of pxHat: 
-      var a = result
-      result = newNodeP(nkBracketExpr, p)
-      addSon(result, a)
-      getTok(p)
-    of pxBracketLe: 
-      result = bracketExprList(p, result)
-    else: break 
-  
-proc lowestExprAux(p: var TParser, v: var PNode, limit: int): TTokKind = 
-  var 
-    nextop: TTokKind
-    v2, node, opNode: PNode
-  v = primary(p) # expand while operators have priorities higher than 'limit'
-  var op = p.tok.xkind
-  var opPred = getPrecedence(op)
-  while (opPred > limit): 
-    node = newNodeP(nkInfix, p)
-    opNode = newIdentNodeP(getIdent($(p.tok)), p) # skip operator:
-    getTok(p)
-    case op
-    of pxPlus: 
-      case p.tok.xkind
-      of pxPer: 
-        getTok(p)
-        eat(p, pxCurlyDirRi)
-        opNode.ident = getIdent("+%")
-      of pxAmp: 
-        getTok(p)
-        eat(p, pxCurlyDirRi)
-        opNode.ident = getIdent("&")
-      else: 
-        discard
-    of pxMinus: 
-      if p.tok.xkind == pxPer: 
-        getTok(p)
-        eat(p, pxCurlyDirRi)
-        opNode.ident = getIdent("-%")
-    of pxEquals: 
-      opNode.ident = getIdent("==")
-    of pxNeq: 
-      opNode.ident = getIdent("!=")
-    else: 
-      discard
-    skipCom(p, opNode)        # read sub-expression with higher priority
-    nextop = lowestExprAux(p, v2, opPred)
-    addSon(node, opNode)
-    addSon(node, v)
-    addSon(node, v2)
-    v = node
-    op = nextop
-    opPred = getPrecedence(nextop)
-  result = op                 # return first untreated operator
-  
-proc fixExpr(n: PNode): PNode = 
-  result = n
-  case n.kind
-  of nkInfix: 
-    if n.sons[1].kind == nkBracket: n.sons[1].kind = nkCurly
-    if n.sons[2].kind == nkBracket: n.sons[2].kind = nkCurly
-    if (n.sons[0].kind == nkIdent): 
-      if (n.sons[0].ident.id == getIdent("+").id): 
-        if (n.sons[1].kind == nkCharLit) and (n.sons[2].kind == nkStrLit) and
-            (n.sons[2].strVal == ""): 
-          result = newStrNode(nkStrLit, chr(int(n.sons[1].intVal)) & "")
-          result.info = n.info
-          return              # do not process sons as they don't exist anymore
-        elif (n.sons[1].kind in {nkCharLit, nkStrLit}) or
-            (n.sons[2].kind in {nkCharLit, nkStrLit}): 
-          n.sons[0].ident = getIdent("&") # fix operator
-  else: 
-    discard
-  if not (n.kind in {nkEmpty..nkNilLit}): 
-    for i in countup(0, sonsLen(n) - 1): result.sons[i] = fixExpr(n.sons[i])
-  
-proc parseExpr(p: var TParser): PNode = 
-  var oldcontext = p.context
-  p.context = conExpr
-  if p.tok.xkind == pxCommand: 
-    result = parseCommand(p)
-  else: 
-    discard lowestExprAux(p, result, - 1)
-    result = fixExpr(result)
-  p.context = oldcontext
-
-proc parseExprStmt(p: var TParser): PNode = 
-  var info = parLineInfo(p)
-  var a = parseExpr(p)
-  if p.tok.xkind == pxAsgn: 
-    getTok(p)
-    skipCom(p, a)
-    var b = parseExpr(p)
-    result = newNodeI(nkAsgn, info)
-    addSon(result, a)
-    addSon(result, b)
-  else: 
-    result = a
-  
-proc inImportBlackList(ident: PIdent): bool = 
-  for i in countup(low(ImportBlackList), high(ImportBlackList)): 
-    if ident.id == getIdent(ImportBlackList[i]).id: 
-      return true
-
-proc parseUsesStmt(p: var TParser): PNode = 
-  var a: PNode
-  result = newNodeP(nkImportStmt, p)
-  getTok(p)                   # skip `import`
-  skipCom(p, result)
-  while true: 
-    case p.tok.xkind
-    of pxEof: break 
-    of pxSymbol: a = newIdentNodeP(p.tok.ident, p)
-    else: 
-      parMessage(p, errIdentifierExpected, $(p.tok))
-      break 
-    getTok(p)                 # skip identifier, string
-    skipCom(p, a)
-    if pfImportBlackList notin p.flags or not inImportBlackList(a.ident): 
-      addSon(result, createIdentNodeP(a.ident, p))
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    else: 
-      break 
-  if sonsLen(result) == 0: result = ast.emptyNode
-  
-proc parseIncludeDir(p: var TParser): PNode = 
-  result = newNodeP(nkIncludeStmt, p)
-  getTok(p)                   # skip `include`
-  var filename = ""
-  while true: 
-    case p.tok.xkind
-    of pxSymbol, pxDot, pxDotDot, pxSlash: 
-      add(filename, $p.tok)
-      getTok(p)
-    of pxStrLit: 
-      filename = p.tok.literal
-      getTok(p)
-      break 
-    of pxCurlyDirRi: 
-      break 
-    else: 
-      parMessage(p, errIdentifierExpected, $p.tok)
-      break 
-  addSon(result, newStrNodeP(nkStrLit, changeFileExt(filename, "nim"), p))
-  if filename == "config.inc": result = ast.emptyNode
-  
-proc definedExprAux(p: var TParser): PNode = 
-  result = newNodeP(nkCall, p)
-  addSon(result, newIdentNodeP(getIdent("defined"), p))
-  expectIdent(p)
-  addSon(result, createIdentNodeP(p.tok.ident, p))
-  getTok(p)
-
-proc isHandledDirective(p: TParser): bool = 
-  if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
-    case toLower(p.tok.ident.s)
-    of "else", "endif": result = false
-    else: result = true
-  
-proc parseStmtList(p: var TParser): PNode = 
-  result = newNodeP(nkStmtList, p)
-  while true: 
-    case p.tok.xkind
-    of pxEof: 
-      break 
-    of pxCurlyDirLe, pxStarDirLe: 
-      if not isHandledDirective(p): break 
-    else: 
-      discard
-    addSon(result, parseStmt(p))
-  if sonsLen(result) == 1: result = result.sons[0]
-  
-proc parseIfDirAux(p: var TParser, result: PNode) = 
-  addSon(result.sons[0], parseStmtList(p))
-  if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
-    var endMarker = succ(p.tok.xkind)
-    if toLower(p.tok.ident.s) == "else": 
-      var s = newNodeP(nkElse, p)
-      while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
-      eat(p, endMarker)
-      addSon(s, parseStmtList(p))
-      addSon(result, s)
-    if p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}: 
-      endMarker = succ(p.tok.xkind)
-      if toLower(p.tok.ident.s) == "endif": 
-        while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
-        eat(p, endMarker)
-      else: 
-        parMessage(p, errXExpected, "{$endif}")
-  else: 
-    parMessage(p, errXExpected, "{$endif}")
-  
-proc parseIfdefDir(p: var TParser, endMarker: TTokKind): PNode = 
-  result = newNodeP(nkWhenStmt, p)
-  addSon(result, newNodeP(nkElifBranch, p))
-  getTok(p)
-  addSon(result.sons[0], definedExprAux(p))
-  eat(p, endMarker)
-  parseIfDirAux(p, result)
-
-proc parseIfndefDir(p: var TParser, endMarker: TTokKind): PNode = 
-  result = newNodeP(nkWhenStmt, p)
-  addSon(result, newNodeP(nkElifBranch, p))
-  getTok(p)
-  var e = newNodeP(nkCall, p)
-  addSon(e, newIdentNodeP(getIdent("not"), p))
-  addSon(e, definedExprAux(p))
-  eat(p, endMarker)
-  addSon(result.sons[0], e)
-  parseIfDirAux(p, result)
-
-proc parseIfDir(p: var TParser, endMarker: TTokKind): PNode = 
-  result = newNodeP(nkWhenStmt, p)
-  addSon(result, newNodeP(nkElifBranch, p))
-  getTok(p)
-  addSon(result.sons[0], parseExpr(p))
-  eat(p, endMarker)
-  parseIfDirAux(p, result)
-
-proc parseDirective(p: var TParser): PNode = 
-  result = ast.emptyNode
-  if not (p.tok.xkind in {pxCurlyDirLe, pxStarDirLe}): return 
-  var endMarker = succ(p.tok.xkind)
-  if p.tok.ident != nil: 
-    case toLower(p.tok.ident.s)
-    of "include": 
-      result = parseIncludeDir(p)
-      eat(p, endMarker)
-    of "if": result = parseIfDir(p, endMarker)
-    of "ifdef": result = parseIfdefDir(p, endMarker)
-    of "ifndef": result = parseIfndefDir(p, endMarker)
-    else: 
-      # skip unknown compiler directive
-      while p.tok.xkind != pxEof and p.tok.xkind != endMarker: getTok(p)
-      eat(p, endMarker)
-  else: 
-    eat(p, endMarker)
-  
-proc parseRaise(p: var TParser): PNode = 
-  result = newNodeP(nkRaiseStmt, p)
-  getTok(p)
-  skipCom(p, result)
-  if p.tok.xkind != pxSemicolon: addSon(result, parseExpr(p))
-  else: addSon(result, ast.emptyNode)
-  
-proc parseIf(p: var TParser): PNode = 
-  result = newNodeP(nkIfStmt, p)
-  while true: 
-    getTok(p)                 # skip ``if``
-    var branch = newNodeP(nkElifBranch, p)
-    skipCom(p, branch)
-    addSon(branch, parseExpr(p))
-    eat(p, pxThen)
-    skipCom(p, branch)
-    addSon(branch, parseStmt(p))
-    skipCom(p, branch)
-    addSon(result, branch)
-    if p.tok.xkind == pxElse: 
-      getTok(p)
-      if p.tok.xkind != pxIf: 
-        # ordinary else part:
-        branch = newNodeP(nkElse, p)
-        skipCom(p, result)    # BUGFIX
-        addSon(branch, parseStmt(p))
-        addSon(result, branch)
-        break 
-    else: 
-      break 
-  
-proc parseWhile(p: var TParser): PNode = 
-  result = newNodeP(nkWhileStmt, p)
-  getTok(p)
-  skipCom(p, result)
-  addSon(result, parseExpr(p))
-  eat(p, pxDo)
-  skipCom(p, result)
-  addSon(result, parseStmt(p))
-
-proc parseRepeat(p: var TParser): PNode = 
-  result = newNodeP(nkWhileStmt, p)
-  getTok(p)
-  skipCom(p, result)
-  addSon(result, newIdentNodeP(getIdent("true"), p))
-  var s = newNodeP(nkStmtList, p)
-  while p.tok.xkind != pxEof and p.tok.xkind != pxUntil: 
-    addSon(s, parseStmt(p))
-  eat(p, pxUntil)
-  var a = newNodeP(nkIfStmt, p)
-  skipCom(p, a)
-  var b = newNodeP(nkElifBranch, p)
-  var c = newNodeP(nkBreakStmt, p)
-  addSon(c, ast.emptyNode)
-  addSon(b, parseExpr(p))
-  skipCom(p, a)
-  addSon(b, c)
-  addSon(a, b)
-  if b.sons[0].kind == nkIdent and b.sons[0].ident.id == getIdent("false").id: 
-    discard
-  else: 
-    addSon(s, a)
-  addSon(result, s)
-
-proc parseCase(p: var TParser): PNode = 
-  var b: PNode
-  result = newNodeP(nkCaseStmt, p)
-  getTok(p)
-  addSon(result, parseExpr(p))
-  eat(p, pxOf)
-  skipCom(p, result)
-  while (p.tok.xkind != pxEnd) and (p.tok.xkind != pxEof): 
-    if p.tok.xkind == pxElse: 
-      b = newNodeP(nkElse, p)
-      getTok(p)
-    else: 
-      b = newNodeP(nkOfBranch, p)
-      while (p.tok.xkind != pxEof) and (p.tok.xkind != pxColon): 
-        addSon(b, rangeExpr(p))
-        opt(p, pxComma)
-        skipCom(p, b)
-      eat(p, pxColon)
-    skipCom(p, b)
-    addSon(b, parseStmt(p))
-    addSon(result, b)
-    if b.kind == nkElse: break 
-  eat(p, pxEnd)
-
-proc parseTry(p: var TParser): PNode = 
-  result = newNodeP(nkTryStmt, p)
-  getTok(p)
-  skipCom(p, result)
-  var b = newNodeP(nkStmtList, p)
-  while not (p.tok.xkind in {pxFinally, pxExcept, pxEof, pxEnd}): 
-    addSon(b, parseStmt(p))
-  addSon(result, b)
-  if p.tok.xkind == pxExcept: 
-    getTok(p)
-    while p.tok.ident.id == getIdent("on").id: 
-      b = newNodeP(nkExceptBranch, p)
-      getTok(p)
-      var e = qualifiedIdent(p)
-      if p.tok.xkind == pxColon: 
-        getTok(p)
-        e = qualifiedIdent(p)
-      addSon(b, e)
-      eat(p, pxDo)
-      addSon(b, parseStmt(p))
-      addSon(result, b)
-      if p.tok.xkind == pxCommand: discard parseCommand(p)
-    if p.tok.xkind == pxElse: 
-      b = newNodeP(nkExceptBranch, p)
-      getTok(p)
-      addSon(b, parseStmt(p))
-      addSon(result, b)
-  if p.tok.xkind == pxFinally: 
-    b = newNodeP(nkFinally, p)
-    getTok(p)
-    var e = newNodeP(nkStmtList, p)
-    while (p.tok.xkind != pxEof) and (p.tok.xkind != pxEnd): 
-      addSon(e, parseStmt(p))
-    if sonsLen(e) == 0: addSon(e, newNodeP(nkNilLit, p))
-    addSon(result, e)
-  eat(p, pxEnd)
-
-proc parseFor(p: var TParser): PNode = 
-  result = newNodeP(nkForStmt, p)
-  getTok(p)
-  skipCom(p, result)
-  expectIdent(p)
-  addSon(result, createIdentNodeP(p.tok.ident, p))
-  getTok(p)
-  eat(p, pxAsgn)
-  var a = parseExpr(p)
-  var b = ast.emptyNode
-  var c = newNodeP(nkCall, p)
-  if p.tok.xkind == pxTo: 
-    addSon(c, newIdentNodeP(getIdent("countup"), p))
-    getTok(p)
-    b = parseExpr(p)
-  elif p.tok.xkind == pxDownto: 
-    addSon(c, newIdentNodeP(getIdent("countdown"), p))
-    getTok(p)
-    b = parseExpr(p)
-  else: 
-    parMessage(p, errTokenExpected, tokKindToStr(pxTo))
-  addSon(c, a)
-  addSon(c, b)
-  eat(p, pxDo)
-  skipCom(p, result)
-  addSon(result, c)
-  addSon(result, parseStmt(p))
-
-proc parseParam(p: var TParser): PNode = 
-  var a: PNode
-  result = newNodeP(nkIdentDefs, p)
-  var v = ast.emptyNode
-  case p.tok.xkind
-  of pxConst: 
-    getTok(p)
-  of pxVar: 
-    getTok(p)
-    v = newNodeP(nkVarTy, p)
-  of pxOut: 
-    getTok(p)
-    v = newNodeP(nkVarTy, p)
-  else: 
-    discard
-  while true: 
-    case p.tok.xkind
-    of pxSymbol: a = createIdentNodeP(p.tok.ident, p)
-    of pxColon, pxEof, pxParRi, pxEquals: break 
-    else: 
-      parMessage(p, errIdentifierExpected, $p.tok)
-      return 
-    getTok(p)                 # skip identifier
-    skipCom(p, a)
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-  if p.tok.xkind == pxColon: 
-    getTok(p)
-    skipCom(p, result)
-    if v.kind != nkEmpty: addSon(v, parseTypeDesc(p))
-    else: v = parseTypeDesc(p)
-    addSon(result, v)
-  else: 
-    addSon(result, ast.emptyNode)
-    if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, $p.tok)
-  if p.tok.xkind == pxEquals: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseExpr(p))
-  else: 
-    addSon(result, ast.emptyNode)
-  
-proc parseParamList(p: var TParser): PNode = 
-  var a: PNode
-  result = newNodeP(nkFormalParams, p)
-  addSon(result, ast.emptyNode)         # return type
-  if p.tok.xkind == pxParLe: 
-    p.inParamList = true
-    getTok(p)
-    skipCom(p, result)
-    while true: 
-      case p.tok.xkind
-      of pxSymbol, pxConst, pxVar, pxOut: 
-        a = parseParam(p)
-      of pxParRi: 
-        getTok(p)
-        break 
-      else: 
-        parMessage(p, errTokenExpected, ")")
-        break 
-      skipCom(p, a)
-      if p.tok.xkind == pxSemicolon: 
-        getTok(p)
-        skipCom(p, a)
-      addSon(result, a)
-    p.inParamList = false
-  if p.tok.xkind == pxColon: 
-    getTok(p)
-    skipCom(p, result)
-    result.sons[0] = parseTypeDesc(p)
-
-proc parseCallingConvention(p: var TParser): PNode = 
-  result = ast.emptyNode
-  if p.tok.xkind == pxSymbol: 
-    case toLower(p.tok.ident.s)
-    of "stdcall", "cdecl", "safecall", "syscall", "inline", "fastcall": 
-      result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(p.tok.ident, p))
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "register": 
-      result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(getIdent("fastcall"), p))
-      getTok(p)
-      opt(p, pxSemicolon)
-    else: 
-      discard
-
-proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = 
-  var e: PNode
-  result = parseCallingConvention(p)
-  noBody = false
-  while p.tok.xkind == pxSymbol: 
-    case toLower(p.tok.ident.s)
-    of "assembler", "overload", "far": 
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "forward": 
-      noBody = true
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "importc": 
-      # This is a fake for platform module. There is no ``importc``
-      # directive in Pascal.
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(getIdent("importc"), p))
-      noBody = true
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "noconv": 
-      # This is a fake for platform module. There is no ``noconv``
-      # directive in Pascal.
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(getIdent("noconv"), p))
-      noBody = true
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "procvar": 
-      # This is a fake for the Nimrod compiler. There is no ``procvar``
-      # directive in Pascal.
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(getIdent("procvar"), p))
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "varargs": 
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      addSon(result, newIdentNodeP(getIdent("varargs"), p))
-      getTok(p)
-      opt(p, pxSemicolon)
-    of "external": 
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      getTok(p)
-      noBody = true
-      e = newNodeP(nkExprColonExpr, p)
-      addSon(e, newIdentNodeP(getIdent("dynlib"), p))
-      addSon(e, parseExpr(p))
-      addSon(result, e)
-      opt(p, pxSemicolon)
-      if (p.tok.xkind == pxSymbol) and
-          (p.tok.ident.id == getIdent("name").id): 
-        e = newNodeP(nkExprColonExpr, p)
-        getTok(p)
-        addSon(e, newIdentNodeP(getIdent("importc"), p))
-        addSon(e, parseExpr(p))
-        addSon(result, e)
-      else: 
-        addSon(result, newIdentNodeP(getIdent("importc"), p))
-      opt(p, pxSemicolon)
-    else: 
-      e = parseCallingConvention(p)
-      if e.kind == nkEmpty: break 
-      if result.kind == nkEmpty: result = newNodeP(nkPragma, p)
-      addSon(result, e.sons[0])
-
-proc parseRoutineType(p: var TParser): PNode = 
-  result = newNodeP(nkProcTy, p)
-  getTok(p)
-  skipCom(p, result)
-  addSon(result, parseParamList(p))
-  opt(p, pxSemicolon)
-  addSon(result, parseCallingConvention(p))
-  skipCom(p, result)
-
-proc parseEnum(p: var TParser): PNode = 
-  var a: PNode
-  result = newNodeP(nkEnumTy, p)
-  getTok(p)
-  skipCom(p, result)
-  addSon(result, ast.emptyNode) # it does not inherit from any enumeration
-  while true: 
-    case p.tok.xkind
-    of pxEof, pxParRi: break 
-    of pxSymbol: a = newIdentNodeP(p.tok.ident, p)
-    else: 
-      parMessage(p, errIdentifierExpected, $(p.tok))
-      break 
-    getTok(p)                 # skip identifier
-    skipCom(p, a)
-    if (p.tok.xkind == pxEquals) or (p.tok.xkind == pxAsgn): 
-      getTok(p)
-      skipCom(p, a)
-      var b = a
-      a = newNodeP(nkEnumFieldDef, p)
-      addSon(a, b)
-      addSon(a, parseExpr(p))
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-  eat(p, pxParRi)
-
-proc identVis(p: var TParser): PNode = 
-  # identifier with visability
-  var a = createIdentNodeP(p.tok.ident, p)
-  if p.section == seInterface: 
-    result = newNodeP(nkPostfix, p)
-    addSon(result, newIdentNodeP(getIdent("*"), p))
-    addSon(result, a)
-  else: 
-    result = a
-  getTok(p)
-
-type 
-  TSymbolParser = proc (p: var TParser): PNode {.nimcall.}
-
-proc rawIdent(p: var TParser): PNode = 
-  result = createIdentNodeP(p.tok.ident, p)
-  getTok(p)
-
-proc parseIdentColonEquals(p: var TParser, 
-                           identParser: TSymbolParser): PNode = 
-  var a: PNode
-  result = newNodeP(nkIdentDefs, p)
-  while true: 
-    case p.tok.xkind
-    of pxSymbol: a = identParser(p)
-    of pxColon, pxEof, pxParRi, pxEquals: break 
-    else: 
-      parMessage(p, errIdentifierExpected, $(p.tok))
-      return 
-    skipCom(p, a)
-    if p.tok.xkind == pxComma: 
-      getTok(p)
-      skipCom(p, a)
-    addSon(result, a)
-  if p.tok.xkind == pxColon: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseTypeDesc(p))
-  else: 
-    addSon(result, ast.emptyNode)
-    if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, $(p.tok))
-  if p.tok.xkind == pxEquals: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseExpr(p))
-  else: 
-    addSon(result, ast.emptyNode)
-  if p.tok.xkind == pxSemicolon: 
-    getTok(p)
-    skipCom(p, result)
-
-proc parseRecordCase(p: var TParser): PNode = 
-  var b, c: PNode
-  result = newNodeP(nkRecCase, p)
-  getTok(p)
-  var a = newNodeP(nkIdentDefs, p)
-  addSon(a, rawIdent(p))
-  eat(p, pxColon)
-  addSon(a, parseTypeDesc(p))
-  addSon(a, ast.emptyNode)
-  addSon(result, a)
-  eat(p, pxOf)
-  skipCom(p, result)
-  while true: 
-    case p.tok.xkind
-    of pxEof, pxEnd: 
-      break 
-    of pxElse: 
-      b = newNodeP(nkElse, p)
-      getTok(p)
-    else: 
-      b = newNodeP(nkOfBranch, p)
-      while (p.tok.xkind != pxEof) and (p.tok.xkind != pxColon): 
-        addSon(b, rangeExpr(p))
-        opt(p, pxComma)
-        skipCom(p, b)
-      eat(p, pxColon)
-    skipCom(p, b)
-    c = newNodeP(nkRecList, p)
-    eat(p, pxParLe)
-    while (p.tok.xkind != pxParRi) and (p.tok.xkind != pxEof): 
-      addSon(c, parseIdentColonEquals(p, rawIdent))
-      opt(p, pxSemicolon)
-      skipCom(p, lastSon(c))
-    eat(p, pxParRi)
-    opt(p, pxSemicolon)
-    if sonsLen(c) > 0: skipCom(p, lastSon(c))
-    else: addSon(c, newNodeP(nkNilLit, p))
-    addSon(b, c)
-    addSon(result, b)
-    if b.kind == nkElse: break 
-  
-proc parseRecordPart(p: var TParser): PNode = 
-  result = ast.emptyNode
-  while (p.tok.xkind != pxEof) and (p.tok.xkind != pxEnd): 
-    if result.kind == nkEmpty: result = newNodeP(nkRecList, p)
-    case p.tok.xkind
-    of pxSymbol: 
-      addSon(result, parseIdentColonEquals(p, rawIdent))
-      opt(p, pxSemicolon)
-      skipCom(p, lastSon(result))
-    of pxCase: 
-      addSon(result, parseRecordCase(p))
-    of pxComment: 
-      skipCom(p, lastSon(result))
-    else: 
-      parMessage(p, errIdentifierExpected, $p.tok)
-      break
-
-proc exSymbol(n: var PNode) = 
-  case n.kind
-  of nkPostfix: 
-    discard
-  of nkPragmaExpr: 
-    exSymbol(n.sons[0])
-  of nkIdent, nkAccQuoted: 
-    var a = newNodeI(nkPostFix, n.info)
-    addSon(a, newIdentNode(getIdent("*"), n.info))
-    addSon(a, n)
-    n = a
-  else: internalError(n.info, "exSymbol(): " & $n.kind)
-  
-proc fixRecordDef(n: var PNode) = 
-  case n.kind
-  of nkRecCase: 
-    fixRecordDef(n.sons[0])
-    for i in countup(1, sonsLen(n) - 1): 
-      var length = sonsLen(n.sons[i])
-      fixRecordDef(n.sons[i].sons[length - 1])
-  of nkRecList, nkRecWhen, nkElse, nkOfBranch, nkElifBranch, nkObjectTy: 
-    for i in countup(0, sonsLen(n) - 1): fixRecordDef(n.sons[i])
-  of nkIdentDefs: 
-    for i in countup(0, sonsLen(n) - 3): exSymbol(n.sons[i])
-  of nkNilLit, nkEmpty: discard
-  else: internalError(n.info, "fixRecordDef(): " & $n.kind)
-  
-proc addPragmaToIdent(ident: var PNode, pragma: PNode) = 
-  var pragmasNode: PNode
-  if ident.kind != nkPragmaExpr: 
-    pragmasNode = newNodeI(nkPragma, ident.info)
-    var e = newNodeI(nkPragmaExpr, ident.info)
-    addSon(e, ident)
-    addSon(e, pragmasNode)
-    ident = e
-  else: 
-    pragmasNode = ident.sons[1]
-    if pragmasNode.kind != nkPragma: 
-      internalError(ident.info, "addPragmaToIdent")
-  addSon(pragmasNode, pragma)
-
-proc parseRecordBody(p: var TParser, result, definition: PNode) = 
-  skipCom(p, result)
-  var a = parseRecordPart(p)
-  if result.kind != nkTupleTy: fixRecordDef(a)
-  addSon(result, a)
-  eat(p, pxEnd)
-  case p.tok.xkind
-  of pxSymbol: 
-    if p.tok.ident.id == getIdent("acyclic").id: 
-      if definition != nil: 
-        addPragmaToIdent(definition.sons[0], newIdentNodeP(p.tok.ident, p))
-      else: 
-        internalError(result.info, "anonymous record is not supported")
-      getTok(p)
-    else: 
-      internalError(result.info, "parseRecordBody")
-  of pxCommand: 
-    if definition != nil: addPragmaToIdent(definition.sons[0], parseCommand(p))
-    else: internalError(result.info, "anonymous record is not supported")
-  else: 
-    discard
-  opt(p, pxSemicolon)
-  skipCom(p, result)
-
-proc parseRecordOrObject(p: var TParser, kind: TNodeKind, 
-                         definition: PNode): PNode = 
-  result = newNodeP(kind, p)
-  getTok(p)
-  addSon(result, ast.emptyNode)
-  if p.tok.xkind == pxParLe: 
-    var a = newNodeP(nkOfInherit, p)
-    getTok(p)
-    addSon(a, parseTypeDesc(p))
-    addSon(result, a)
-    eat(p, pxParRi)
-  else: 
-    addSon(result, ast.emptyNode)
-  parseRecordBody(p, result, definition)
-
-proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = 
-  var oldcontext = p.context
-  p.context = conTypeDesc
-  if p.tok.xkind == pxPacked: getTok(p)
-  case p.tok.xkind
-  of pxCommand: 
-    result = parseCommand(p, definition)
-  of pxProcedure, pxFunction: 
-    result = parseRoutineType(p)
-  of pxRecord: 
-    getTok(p)
-    if p.tok.xkind == pxCommand: 
-      result = parseCommand(p)
-      if result.kind != nkTupleTy: internalError(result.info, "parseTypeDesc")
-      parseRecordBody(p, result, definition)
-      var a = lastSon(result)     # embed nkRecList directly into nkTupleTy
-      for i in countup(0, sonsLen(a) - 1): 
-        if i == 0: result.sons[sonsLen(result) - 1] = a.sons[0]
-        else: addSon(result, a.sons[i])
-    else: 
-      result = newNodeP(nkObjectTy, p)
-      addSon(result, ast.emptyNode)
-      addSon(result, ast.emptyNode)
-      parseRecordBody(p, result, definition)
-      if definition != nil: 
-        addPragmaToIdent(definition.sons[0], newIdentNodeP(getIdent("final"), p))
-      else: 
-        internalError(result.info, "anonymous record is not supported")
-  of pxObject: result = parseRecordOrObject(p, nkObjectTy, definition)
-  of pxParLe: result = parseEnum(p)
-  of pxArray: 
-    result = newNodeP(nkBracketExpr, p)
-    getTok(p)
-    if p.tok.xkind == pxBracketLe: 
-      addSon(result, newIdentNodeP(getIdent("array"), p))
-      getTok(p)
-      addSon(result, rangeExpr(p))
-      eat(p, pxBracketRi)
-    else: 
-      if p.inParamList: addSon(result, newIdentNodeP(getIdent("openarray"), p))
-      else: addSon(result, newIdentNodeP(getIdent("seq"), p))
-    eat(p, pxOf)
-    addSon(result, parseTypeDesc(p))
-  of pxSet: 
-    result = newNodeP(nkBracketExpr, p)
-    getTok(p)
-    eat(p, pxOf)
-    addSon(result, newIdentNodeP(getIdent("set"), p))
-    addSon(result, parseTypeDesc(p))
-  of pxHat: 
-    getTok(p)
-    if p.tok.xkind == pxCommand: result = parseCommand(p)
-    elif pfRefs in p.flags: result = newNodeP(nkRefTy, p)
-    else: result = newNodeP(nkPtrTy, p)
-    addSon(result, parseTypeDesc(p))
-  of pxType: 
-    getTok(p)
-    result = parseTypeDesc(p)
-  else: 
-    var a = primary(p)
-    if p.tok.xkind == pxDotDot: 
-      result = newNodeP(nkBracketExpr, p)
-      var r = newNodeP(nkRange, p)
-      addSon(result, newIdentNodeP(getIdent("range"), p))
-      getTok(p)
-      addSon(r, a)
-      addSon(r, parseExpr(p))
-      addSon(result, r)
-    else: 
-      result = a
-  p.context = oldcontext
-
-proc parseTypeDef(p: var TParser): PNode = 
-  result = newNodeP(nkTypeDef, p)
-  addSon(result, identVis(p))
-  addSon(result, ast.emptyNode)         # generic params
-  if p.tok.xkind == pxEquals: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseTypeDesc(p, result))
-  else: 
-    addSon(result, ast.emptyNode)
-  if p.tok.xkind == pxSemicolon: 
-    getTok(p)
-    skipCom(p, result)
-
-proc parseTypeSection(p: var TParser): PNode = 
-  result = newNodeP(nkTypeSection, p)
-  getTok(p)
-  skipCom(p, result)
-  while p.tok.xkind == pxSymbol: 
-    addSon(result, parseTypeDef(p))
-
-proc parseConstant(p: var TParser): PNode = 
-  result = newNodeP(nkConstDef, p)
-  addSon(result, identVis(p))
-  if p.tok.xkind == pxColon: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseTypeDesc(p))
-  else: 
-    addSon(result, ast.emptyNode)
-    if p.tok.xkind != pxEquals: 
-      parMessage(p, errColonOrEqualsExpected, $(p.tok))
-  if p.tok.xkind == pxEquals: 
-    getTok(p)
-    skipCom(p, result)
-    addSon(result, parseExpr(p))
-  else: 
-    addSon(result, ast.emptyNode)
-  if p.tok.xkind == pxSemicolon: 
-    getTok(p)
-    skipCom(p, result)
-
-proc parseConstSection(p: var TParser): PNode = 
-  result = newNodeP(nkConstSection, p)
-  getTok(p)
-  skipCom(p, result)
-  while p.tok.xkind == pxSymbol: 
-    addSon(result, parseConstant(p))
-
-proc parseVar(p: var TParser): PNode = 
-  result = newNodeP(nkVarSection, p)
-  getTok(p)
-  skipCom(p, result)
-  while p.tok.xkind == pxSymbol:
-    addSon(result, parseIdentColonEquals(p, identVis))
-  p.lastVarSection = result
-
-proc parseRoutine(p: var TParser): PNode = 
-  var noBody: bool
-  result = newNodeP(nkProcDef, p)
-  getTok(p)
-  skipCom(p, result)
-  expectIdent(p)
-  addSon(result, identVis(p))
-  # patterns, generic parameters:
-  addSon(result, ast.emptyNode)
-  addSon(result, ast.emptyNode)   
-  addSon(result, parseParamList(p))
-  opt(p, pxSemicolon)
-  addSon(result, parseRoutineSpecifiers(p, noBody))
-  addSon(result, ast.emptyNode)
-  if (p.section == seInterface) or noBody: 
-    addSon(result, ast.emptyNode)
-  else: 
-    var stmts = newNodeP(nkStmtList, p)
-    while true: 
-      case p.tok.xkind
-      of pxVar: addSon(stmts, parseVar(p))
-      of pxConst: addSon(stmts, parseConstSection(p))
-      of pxType: addSon(stmts, parseTypeSection(p))
-      of pxComment: skipCom(p, result)
-      of pxBegin: break 
-      else: 
-        parMessage(p, errTokenExpected, "begin")
-        break 
-    var a = parseStmt(p)
-    for i in countup(0, sonsLen(a) - 1): addSon(stmts, a.sons[i])
-    addSon(result, stmts)
-
-proc fixExit(p: var TParser, n: PNode): bool = 
-  if (p.tok.ident.id == getIdent("exit").id): 
-    var length = sonsLen(n)
-    if (length <= 0): return 
-    var a = n.sons[length-1]
-    if (a.kind == nkAsgn) and (a.sons[0].kind == nkIdent) and
-        (a.sons[0].ident.id == getIdent("result").id): 
-      delSon(a, 0)
-      a.kind = nkReturnStmt
-      result = true
-      getTok(p)
-      opt(p, pxSemicolon)
-      skipCom(p, a)
-
-proc fixVarSection(p: var TParser, counter: PNode) = 
-  if p.lastVarSection == nil: return 
-  assert(counter.kind == nkIdent)
-  for i in countup(0, sonsLen(p.lastVarSection) - 1): 
-    var v = p.lastVarSection.sons[i]
-    for j in countup(0, sonsLen(v) - 3): 
-      if v.sons[j].ident.id == counter.ident.id: 
-        delSon(v, j)
-        if sonsLen(v) <= 2: 
-          delSon(p.lastVarSection, i)
-        return 
-
-proc exSymbols(n: PNode) = 
-  case n.kind
-  of nkEmpty..nkNilLit: discard
-  of nkProcDef..nkIteratorDef: exSymbol(n.sons[namePos])
-  of nkWhenStmt, nkStmtList: 
-    for i in countup(0, sonsLen(n) - 1): exSymbols(n.sons[i])
-  of nkVarSection, nkConstSection: 
-    for i in countup(0, sonsLen(n) - 1): exSymbol(n.sons[i].sons[0])
-  of nkTypeSection: 
-    for i in countup(0, sonsLen(n) - 1): 
-      exSymbol(n.sons[i].sons[0])
-      if n.sons[i].sons[2].kind == nkObjectTy: 
-        fixRecordDef(n.sons[i].sons[2])
-  else: discard
-
-proc parseBegin(p: var TParser, result: PNode) = 
-  getTok(p)
-  while true: 
-    case p.tok.xkind
-    of pxComment: addSon(result, parseStmt(p))
-    of pxSymbol: 
-      if not fixExit(p, result): addSon(result, parseStmt(p))
-    of pxEnd: 
-      getTok(p)
-      break 
-    of pxSemicolon: getTok(p)
-    of pxEof: parMessage(p, errExprExpected)
-    else: 
-      var a = parseStmt(p)
-      if a.kind != nkEmpty: addSon(result, a)
-  if sonsLen(result) == 0: addSon(result, newNodeP(nkNilLit, p))
-  
-proc parseStmt(p: var TParser): PNode = 
-  var oldcontext = p.context
-  p.context = conStmt
-  result = ast.emptyNode
-  case p.tok.xkind
-  of pxBegin: 
-    result = newNodeP(nkStmtList, p)
-    parseBegin(p, result)
-  of pxCommand: result = parseCommand(p)
-  of pxCurlyDirLe, pxStarDirLe: 
-    if isHandledDirective(p): result = parseDirective(p)
-  of pxIf: result = parseIf(p)
-  of pxWhile: result = parseWhile(p)
-  of pxRepeat: result = parseRepeat(p)
-  of pxCase: result = parseCase(p)
-  of pxTry: result = parseTry(p)
-  of pxProcedure, pxFunction: result = parseRoutine(p)
-  of pxType: result = parseTypeSection(p)
-  of pxConst: result = parseConstSection(p)
-  of pxVar: result = parseVar(p)
-  of pxFor: 
-    result = parseFor(p)
-    fixVarSection(p, result.sons[0])
-  of pxRaise: result = parseRaise(p)
-  of pxUses: result = parseUsesStmt(p)
-  of pxProgram, pxUnit, pxLibrary: 
-    # skip the pointless header
-    while not (p.tok.xkind in {pxSemicolon, pxEof}): getTok(p)
-    getTok(p)
-  of pxInitialization: getTok(p) # just skip the token
-  of pxImplementation: 
-    p.section = seImplementation
-    result = newNodeP(nkCommentStmt, p)
-    result.comment = "# implementation"
-    getTok(p)
-  of pxInterface: 
-    p.section = seInterface
-    getTok(p)
-  of pxComment: 
-    result = newNodeP(nkCommentStmt, p)
-    skipCom(p, result)
-  of pxSemicolon: getTok(p)
-  of pxSymbol: 
-    if p.tok.ident.id == getIdent("break").id: 
-      result = newNodeP(nkBreakStmt, p)
-      getTok(p)
-      skipCom(p, result)
-      addSon(result, ast.emptyNode)
-    elif p.tok.ident.id == getIdent("continue").id: 
-      result = newNodeP(nkContinueStmt, p)
-      getTok(p)
-      skipCom(p, result)
-      addSon(result, ast.emptyNode)
-    elif p.tok.ident.id == getIdent("exit").id: 
-      result = newNodeP(nkReturnStmt, p)
-      getTok(p)
-      skipCom(p, result)
-      addSon(result, ast.emptyNode)
-    else: 
-      result = parseExprStmt(p)
-  of pxDot: getTok(p) # BUGFIX for ``end.`` in main program
-  else: result = parseExprStmt(p)
-  opt(p, pxSemicolon)
-  if result.kind != nkEmpty: skipCom(p, result)
-  p.context = oldcontext
-
-proc parseUnit(p: var TParser): PNode = 
-  result = newNodeP(nkStmtList, p)
-  getTok(p)                   # read first token
-  while true: 
-    case p.tok.xkind
-    of pxEof, pxEnd: break 
-    of pxBegin: parseBegin(p, result)
-    of pxCurlyDirLe, pxStarDirLe: 
-      if isHandledDirective(p): addSon(result, parseDirective(p))
-      else: parMessage(p, errXNotAllowedHere, p.tok.ident.s)
-    else: addSon(result, parseStmt(p))
-  opt(p, pxEnd)
-  opt(p, pxDot)
-  if p.tok.xkind != pxEof: 
-    addSon(result, parseStmt(p)) # comments after final 'end.'
-  
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index a17773aa4..024401b86 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -24,7 +24,8 @@ const
     wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
     wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
     wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
-    wGensym, wInject, wRaises, wTags, wUses, wOperator, wDelegator, wGcSafe}
+    wGensym, wInject, wRaises, wTags, wUses, wOperator, wDelegator, wGcSafe,
+    wOverride}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
@@ -628,11 +629,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           # implies nodecl, because otherwise header would not make sense
           if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
         of wDestructor:
-          if sym.typ.sons.len == 2:
-            sym.flags.incl sfDestructor
-          else:
-            invalidPragma(it)
-        of wNosideeffect: 
+          sym.flags.incl sfOverriden
+          if sym.name.s.normalize != "destroy":
+            localError(n.info, errGenerated, "destructor has to be named 'destroy'")
+        of wOverride:
+          sym.flags.incl sfOverriden
+        of wNosideeffect:
           noVal(it)
           incl(sym.flags, sfNoSideEffect)
           if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect)
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 0b1312ccc..c97b2f321 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -925,7 +925,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
   of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref: 
     gsub(g, n.sons[0])
   of nkLambda:
-    putWithSpace(g, tkLambda, "proc")
+    putWithSpace(g, tkProc, "proc")
     gsub(g, n.sons[paramsPos])
     gsub(g, n.sons[pragmasPos])
     put(g, tkSpaces, Space)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 8025ef70d..26a59334c 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -16,7 +16,7 @@ import
   procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
   intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
   evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity,
-  semparallel
+  semparallel, lowerings
 
 # implementation
 
diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim
index 791bef823..3c30dc1bd 100644
--- a/compiler/semdestruct.nim
+++ b/compiler/semdestruct.nim
@@ -125,8 +125,7 @@ proc instantiateDestructor(c: PContext, typ: PType): PType =
   # The destructor is either user-defined or automatically
   # generated by the compiler in a member-wise fashion.
   var t = skipTypes(typ, {tyConst, tyMutable}).skipGenericAlias
-  let typeHoldingUserDefinition = if t.kind == tyGenericInst: t.base
-                                  else: t
+  let typeHoldingUserDefinition = if t.kind == tyGenericInst: t.base else: t
   
   if typeHoldingUserDefinition.destructor != nil:
     # XXX: This is not entirely correct for recursive types, but we need
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7f97124e1..b81d53d41 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -82,7 +82,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
     case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind
     of  tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128, 
         tyTuple, tySet, tyUInt..tyUInt64:
-      result = inlineConst(n, s)
+      if s.magic == mNone: result = inlineConst(n, s)
+      else: result = newSymNode(s, n.info)
     of tyArrayConstr, tySequence:
       # Consider::
       #     const x = []
@@ -591,7 +592,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
   const 
     FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, 
       mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, 
-      mAppendSeqElem, mNewSeq, mReset, mShallowCopy}
+      mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy}
   
   # get the real type of the callee
   # it may be a proc var with a generic alias type, so we skip over them
@@ -1642,10 +1643,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
     result = setMs(n, s)
     result.sons[1] = semExpr(c, n.sons[1])
     if not result[1].typ.isEmptyType:
-      if c.inParallelStmt > 0:
-        result.typ = result[1].typ
-      else:
+      if spawnResult(result[1].typ, c.inParallelStmt > 0) == srFlowVar:
         result.typ = createFlowVar(c, result[1].typ, n.info)
+      else:
+        result.typ = result[1].typ
       result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode
   else: result = semDirectOp(c, n, flags)
 
diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim
index c594a4788..7c489c3b6 100644
--- a/compiler/semparallel.nim
+++ b/compiler/semparallel.nim
@@ -23,7 +23,7 @@
 
 import
   ast, astalgo, idents, lowerings, magicsys, guards, sempass2, msgs,
-  renderer
+  renderer, types
 from trees import getMagic
 from strutils import `%`
 
@@ -406,12 +406,17 @@ proc transformSpawn(owner: PSym; n, barrier: PNode): PNode =
         if result.isNil:
           result = newNodeI(nkStmtList, n.info)
           result.add n
-        result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0])
-        it.sons[it.len-1] = emptyNode
+        let t = b[1][0].typ.sons[0]
+        if spawnResult(t, true) == srByVar:
+          result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0])
+          it.sons[it.len-1] = emptyNode
+        else:
+          it.sons[it.len-1] = wrapProcForSpawn(owner, m, b.typ, barrier, nil)
     if result.isNil: result = n
   of nkAsgn, nkFastAsgn:
     let b = n[1]
-    if getMagic(b) == mSpawn:
+    if getMagic(b) == mSpawn and (let t = b[1][0].typ.sons[0];
+        spawnResult(t, true) == srByVar):
       let m = transformSlices(b)
       return wrapProcForSpawn(owner, m, b.typ, barrier, n[0])
     result = transformSpawnSons(owner, n, barrier)
@@ -462,4 +467,3 @@ proc liftParallel*(owner: PSym; n: PNode): PNode =
   result.add callCodeGenProc("openBarrier", barrier)
   result.add transformSpawn(owner, body, barrier)
   result.add callCodeGenProc("closeBarrier", barrier)
-
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 3cb9691eb..583185048 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -661,7 +661,8 @@ proc semFor(c: PContext, n: PNode): PNode =
   n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
   var call = n.sons[length-2]
   let isCallExpr = call.kind in nkCallKinds
-  if isCallExpr and call[0].kind == nkSym and call[0].sym.magic != mNone:
+  if isCallExpr and call[0].kind == nkSym and
+      call[0].sym.magic in {mFields, mFieldPairs, mOmpParFor}:
     if call.sons[0].sym.magic == mOmpParFor:
       result = semForVars(c, n)
       result.kind = nkParForStmt
@@ -1008,6 +1009,31 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
     addResult(c, s.typ.sons[0], n.info, s.kind)
     addResultNode(c, n)
 
+proc semOverride(c: PContext, s: PSym, n: PNode) =
+  case s.name.s.normalize
+  of "destroy": doDestructorStuff(c, s, n)
+  of "deepcopy":
+    if s.typ.len == 2 and
+        s.typ.sons[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and
+        sameType(s.typ.sons[1], s.typ.sons[0]):
+      # Note: we store the deepCopy in the base of the pointer to mitigate
+      # the problem that pointers are structural types:
+      let t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
+      if t.kind in {tyObject, tyDistinct, tyEnum}:
+        if t.deepCopy.isNil: t.deepCopy = s
+        else: 
+          localError(n.info, errGenerated,
+                     "cannot bind another 'deepCopy' to: " & typeToString(t))
+      else:
+        localError(n.info, errGenerated,
+                   "cannot bind 'deepCopy' to: " & typeToString(t))
+    else:
+      localError(n.info, errGenerated,
+                 "signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T")
+  of "=": discard
+  else: localError(n.info, errGenerated,
+                   "'destroy' or 'deepCopy' expected for 'override'")
+
 type
   TProcCompilationSteps = enum
     stepRegisterSymbol,
@@ -1124,7 +1150,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     popOwner()
     pushOwner(s)
   s.options = gOptions
-  if sfDestructor in s.flags: doDestructorStuff(c, s, n)
+  if sfOverriden in s.flags: semOverride(c, s, n)
   if n.sons[bodyPos].kind != nkEmpty:
     # for DLL generation it is annoying to check for sfImportc!
     if sfBorrow in s.flags:
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 33de40f34..eeaf53649 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -137,7 +137,7 @@ proc hasGenericArguments*(n: PNode): bool =
     return false
 
 proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode =
-  # This is needed fo tgenericshardcases
+  # This is needed for tgenericshardcases
   # It's possible that a generic param will be used in a proc call to a
   # typedesc accepting proc. After generic param substitution, such procs
   # should be optionally instantiated with the correct type. In order to
diff --git a/compiler/service.nim b/compiler/service.nim
index 2b861e1c7..22f5c6e33 100644
--- a/compiler/service.nim
+++ b/compiler/service.nim
@@ -59,7 +59,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
       inc argsCount
           
   if pass == passCmd2:
-    if optRun notin gGlobalOptions and arguments != "":
+    if optRun notin gGlobalOptions and arguments != "" and options.command.normalize != "run":
       rawMessage(errArgsNeedRunOption, [])
 
 proc serve*(action: proc (){.nimcall.}) =
diff --git a/compiler/tccgen.nim b/compiler/tccgen.nim
index 9ed6db8a1..a571d416e 100644
--- a/compiler/tccgen.nim
+++ b/compiler/tccgen.nim
@@ -68,11 +68,9 @@ proc compileCCode*(ccode: string) =
     setupEnvironment()
   discard compileString(gTinyC, ccode)
   
-proc run*() =
-  var a: array[0..1, cstring]
-  a[0] = ""
-  a[1] = ""
-  var err = tinyc.run(gTinyC, 0'i32, cast[cstringArray](addr(a))) != 0'i32
+proc run*(args: string) =
+  var s = @[cstring(gProjectName)] & map(split(args), proc(x: string): cstring = cstring(x))
+  var err = tinyc.run(gTinyC, cint(len(s)), cast[cstringArray](addr(s[0]))) != 0'i32
   closeCCState(gTinyC)
   if err: rawMessage(errExecutionOfProgramFailed, "")
 
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 66595856a..aedbb92b4 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -16,7 +16,7 @@ import ast except getstr
 
 import
   strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned,
-  parser, vmdeps, idents, trees, renderer, options, transf
+  parser, vmdeps, idents, trees, renderer, options, transf, parseutils
 
 from semfold import leValueConv, ordinalValToString
 from evaltempl import evalTemplate
@@ -776,6 +776,18 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       createStr regs[ra]
       regs[ra].node.strVal = substr(regs[rb].node.strVal, 
                                     regs[rc].intVal.int, regs[rd].intVal.int)
+    of opcParseFloat:
+      decodeBC(rkInt)
+      inc pc
+      assert c.code[pc].opcode == opcParseFloat
+      let rd = c.code[pc].regA
+      var rcAddr = addr(regs[rc])
+      if rcAddr.kind == rkRegisterAddr: rcAddr = rcAddr.regAddr
+      elif regs[rc].kind != rkFloat:
+        myreset(regs[rc])
+        regs[rc].kind = rkFloat
+      regs[ra].intVal = parseBiggestFloat(regs[rb].node.strVal,
+                                          rcAddr.floatVal, regs[rd].intVal.int)
     of opcRangeChck:
       let rb = instr.regB
       let rc = instr.regC
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index c391d8415..873d8eebd 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -66,7 +66,7 @@ type
     opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
     opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
     opcSwap, opcIsNil, opcOf, opcIs,
-    opcSubStr, opcConv, opcCast, opcQuit, opcReset,
+    opcSubStr, opcParseFloat, opcConv, opcCast, opcQuit, opcReset,
     opcNarrowS, opcNarrowU,
     
     opcAddStrCh,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index c1ec637dd..fd0c3fc69 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -852,6 +852,24 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
     c.freeTemp(tmp1)
     c.freeTemp(tmp2)
     c.freeTemp(tmp3)
+  of mParseBiggestFloat:
+    if dest < 0: dest = c.getTemp(n.typ)
+    var d2: TRegister
+    # skip 'nkHiddenAddr':
+    let d2AsNode = n.sons[2].sons[0]
+    if needsAsgnPatch(d2AsNode):
+      d2 = c.getTemp(getSysType(tyFloat))
+    else:
+      d2 = c.genx(d2AsNode)
+    var
+      tmp1 = c.genx(n.sons[1])
+      tmp3 = c.genx(n.sons[3])
+    c.gABC(n, opcParseFloat, dest, tmp1, d2)
+    c.gABC(n, opcParseFloat, tmp3)
+    c.freeTemp(tmp1)
+    c.freeTemp(tmp3)
+    c.genAsgnPatch(d2AsNode, d2)
+    c.freeTemp(d2)    
   of mReset:
     unused(n, dest)
     var d = c.genx(n.sons[1])
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index fbe005031..96056eb6f 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -27,7 +27,7 @@ type
     wContinue, wConverter, wDiscard, wDistinct, wDiv, wDo, 
     wElif, wElse, wEnd, wEnum, wExcept, wExport,
     wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, 
-    wInclude, wInterface, wIs, wIsnot, wIterator, wLambda, wLet,
+    wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
     wMacro, wMethod, wMixin, wMod, wNil, 
     wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, 
     wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar, 
@@ -39,7 +39,7 @@ type
 
     wDestroy,
     
-    wImmediate, wDestructor, wDelegator,
+    wImmediate, wDestructor, wDelegator, wOverride,
     wImportCpp, wImportObjC,
     wImportCompilerProc,
     wImportc, wExportc, wIncompleteStruct, wRequiresInit,
@@ -107,7 +107,7 @@ const
     "elif", "else", "end", "enum", "except", "export", 
     "finally", "for", "from", "generic", "if", 
     "import", "in", "include", "interface", "is", "isnot", "iterator",
-    "lambda", "let",
+    "let",
     "macro", "method", "mixin", "mod", "nil", "not", "notin",
     "object", "of", "or", 
     "out", "proc", "ptr", "raise", "ref", "return",
@@ -122,7 +122,7 @@ const
 
     "destroy",
     
-    "immediate", "destructor", "delegator",
+    "immediate", "destructor", "delegator", "override",
     "importcpp", "importobjc",
     "importcompilerproc", "importc", "exportc", "incompletestruct",
     "requiresinit", "align", "nodecl", "pure", "sideeffect",
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 08465e457..7a11e9041 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -12,6 +12,7 @@ Advanced commands:
                             module dependency graph
   //dump                    dump all defined conditionals and search paths
   //check                   checks the project for syntax and semantic
+  //pretty                  homogenizes source code style
   //idetools                compiler support for IDEs: possible options:
     --track:FILE,LINE,COL   track a file/cursor position
     --trackDirty:DIRTY_FILE,ORIG_FILE,LINE,COL
diff --git a/doc/c2nim.txt b/doc/c2nim.txt
deleted file mode 100644
index 237af7fb2..000000000
--- a/doc/c2nim.txt
+++ /dev/null
@@ -1,295 +0,0 @@
-=======================
-  c2nim User's manual
-=======================
-
-:Author: Andreas Rumpf
-:Version: |nimrodversion|
-
-.. contents::
-
-Introduction
-============
-
-  "We all make choices. But in the end our choices make us."
-
-
-c2nim is a tool to translate Ansi C code to Nimrod. The output is 
-human-readable Nimrod code that is meant to be tweaked by hand after the 
-translation process. c2nim is no real compiler!
-
-c2nim is preliminary meant to translate C header files. Because of this, the 
-preprocessor is part of the parser. For example:
-
-.. code-block:: C
-  #define abc 123
-  #define xyz 789
-  
-Is translated into:
-
-.. code-block:: Nimrod
-  const
-    abc* = 123
-    xyz* = 789
-    
-
-c2nim is meant to translate fragments of C code and thus does not follow 
-include files. c2nim cannot parse all of Ansi C and many constructs cannot
-be represented in Nimrod: for example `duff's device`:idx: cannot be translated
-to Nimrod. 
-
-
-Preprocessor support
-====================
-
-Even though the translation process is not perfect, it is often the case that
-the translated Nimrod code does not need any tweaking by hand. In other cases
-it may be preferable to modify the input file instead of the generated Nimrod
-code so that c2nim can parse it properly. c2nim's preprocessor defines the 
-symbol ``C2NIM`` that can be used to mark code sections: 
-
-.. code-block:: C
-  #ifndef C2NIM
-    // C2NIM should ignore this prototype:
-    int fprintf(FILE* f, const char* frmt, ...);
-  #endif
-  
-The ``C2NIM`` symbol is only recognized in ``#ifdef`` and ``#ifndef`` 
-constructs! ``#if defined(C2NIM)`` does **not** work. 
-
-c2nim *processes* ``#ifdef C2NIM`` and ``#ifndef C2NIM`` directives, but other
-``#if[def]`` directives are *translated* into Nimrod's ``when`` construct: 
-
-.. code-block:: C
-  #ifdef DEBUG
-  #  define OUT(x) printf("%s\n", x)
-  #else
-  #  define OUT(x)
-  #endif
-  
-Is translated into:
-
-.. code-block:: Nimrod
-  when defined(debug):
-    template OUT*(x: expr): expr = 
-      printf("%s\x0A", x)
-  else:
-    template OUT*(x: expr): stmt = 
-      discard
-  
-As can been seen from the example, C's macros with parameters are mapped
-to Nimrod's templates. This mapping is the best one can do, but it is of course
-not accurate: Nimrod's templates operate on syntax trees whereas C's 
-macros work on the token level. c2nim cannot translate any macro that contains
-the ``##`` token concatenation operator.
-
-c2nim's preprocessor supports special directives that affect how the output
-is generated. They should be put into a ``#ifdef C2NIM`` section so that 
-ordinary C compilers ignore them.
-
-
-``#skipinclude`` directive
---------------------------
-**Note**: There is also a ``--skipinclude`` command line option that can be 
-used for the same purpose.
-
-By default, c2nim translates an ``#include`` that is not followed by ``<`` 
-(like in ``#include <stdlib>``) to a Nimrod ``import`` statement. This 
-directive tells c2nim to just skip any ``#include``. 
-
-
-``#stdcall`` and ``#cdecl`` directives
---------------------------------------
-**Note**: There are also ``--stdcall`` and ``--cdecl`` command line options
-that can be used for the same purpose.
-
-These directives tell c2nim that it should annotate every proc (or proc type)
-with the ``stdcall`` / ``cdecl`` calling convention.
-
-
-``#dynlib`` directive
----------------------
-**Note**: There is also a ``--dynlib`` command line option that can be used for
-the same purpose.
-
-This directive tells c2nim that it should annotate every proc that resulted
-from a C function prototype with the ``dynlib`` pragma:
- 
-.. code-block:: C
-  
-  #ifdef C2NIM
-  #  dynlib iupdll
-  #  cdecl
-  #  if defined(windows)
-  #    define iupdll "iup.dll"
-  #  elif defined(macosx)
-  #    define iupdll "libiup.dylib"
-  #  else
-  #    define iupdll "libiup.so"
-  #  endif
-  #endif
-  
-  int IupConvertXYToPos(PIhandle ih, int x, int y);
-
-Is translated to:
-  
-.. code-block:: Nimrod
-  when defined(windows):
-    const iupdll* = "iup.dll"
-  elif defined(macosx):
-    const iupdll* = "libiup.dylib"
-  else:
-    const iupdll* = "libiup.so"
-  
-  proc IupConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {.
-    importc: "IupConvertXYToPos", cdecl, dynlib: iupdll.}
-
-Note how the example contains extra C code to declare the ``iupdll`` symbol
-in the generated Nimrod code.
-
-
-``#header`` directive
----------------------
-**Note**: There is also a ``--header`` command line option that can be used for
-the same purpose.
-
-The ``#header`` directive tells c2nim that it should annotate every proc that
-resulted from a C function prototype and every exported variable and type with
-the ``header`` pragma:
-
-.. code-block:: C
-  
-  #ifdef C2NIM
-  #  header "iup.h"
-  #endif
-  
-  int IupConvertXYToPos(PIhandle ih, int x, int y);
-
-Is translated to:
-  
-.. code-block:: Nimrod
-  proc IupConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {.
-    importc: "IupConvertXYToPos", header: "iup.h".}
-
-The ``#header`` and the ``#dynlib`` directives are mutually exclusive. 
-A binding that uses ``dynlib`` is much more preferable over one that uses
-``header``! The Nimrod compiler might drop support for the ``header`` pragma
-in the future as it cannot work for backends that do not generate C code.
-
-
-``#prefix`` and ``#suffix`` directives
---------------------------------------
-
-**Note**: There are also ``--prefix`` and ``--suffix`` command line options
-that can be used for the same purpose.
-
-c2nim does not do any name mangling by default. However the 
-``#prefix`` and ``#suffix`` directives can be used to strip prefixes and
-suffixes from the identifiers in the C code: 
- 
-.. code-block:: C
-  
-  #ifdef C2NIM
-  #  prefix Iup
-  #  dynlib dllname
-  #  cdecl
-  #endif
-  
-  int IupConvertXYToPos(PIhandle ih, int x, int y);
-
-Is translated to:
-  
-.. code-block:: Nimrod
-
-  proc ConvertXYToPos*(ih: PIhandle, x: cint, y: cint): cint {.
-    importc: "IupConvertXYToPos", cdecl, dynlib: dllname.}
-
-
-``#mangle`` directive
----------------------
-
-Even more sophisticated name mangling can be achieved by the ``#mangle`` 
-directive: It takes a PEG pattern and format string that specify how the
-identifier should be converted: 
-
-.. code-block:: C
-  #mangle "'GTK_'{.*}" "TGtk$1"
-
-For convenience the PEG pattern and the replacement can be single identifiers
-too, there is no need to quote them: 
-
-.. code-block:: C
-  #mangle ssize_t  int
-  // is short for:
-  #mangle "'ssize_t'" "int"
-
-
-``#private`` directive
-----------------------
-
-By default c2nim marks every top level identifier (proc name, variable, etc.)
-as exported (the export marker is ``*`` in Nimrod). With the ``#private`` 
-directive identifiers can be marked as private so that the resulting Nimrod
-module does not export them. The ``#private`` directive takes a PEG pattern:
-
-.. code-block:: C
-  #private "@('_'!.)" // all identifiers ending in '_' are private
-  
-Note: The pattern refers to the original C identifiers, not to the resulting
-identifiers after mangling!
-
-
-``#skipcomments`` directive
----------------------------
-**Note**: There is also a ``--skipcomments`` command line option that can be
-used for the same purpose.
-
-The ``#skipcomments`` directive can be put into the C code to make c2nim
-ignore comments and not copy them into the generated Nimrod file.
-
-
-``#typeprefixes`` directive
----------------------------
-**Note**: There is also a ``--typeprefixes`` command line option that can be
-used for the same purpose.
-
-The ``#typeprefixes`` directive can be put into the C code to make c2nim
-generate the ``T`` or ``P`` prefix for every defined type.
-
-
-``#def`` directive
-------------------
-
-Often C code contains special macros that affect the declaration of a function
-prototype but confuse c2nim's parser:
-
-.. code-block:: C
-  // does not parse!
-  EXTERN(int) f(void);
-  EXTERN(int) g(void);
-
-Instead of removing ``EXTERN()`` from the input source file (which cannot be 
-done reliably even with a regular expression!), one can tell c2nim
-that ``EXPORT`` is a macro that should be expanded by c2nim too:
-
-.. code-block:: C
-  #ifdef C2NIM
-  #  def EXTERN(x) static x
-  #endif
-  // parses now!
-  EXTERN(int) f(void);
-  EXTERN(int) g(void);
-  
-``#def`` is very similar to C's ``#define``, so in general the macro definition
-can be copied and pasted into a ``#def`` directive.
-
-
-Limitations
-===========
-
-* C's ``,`` operator (comma operator) is not supported.
-* C's ``union`` are translated to Nimrod's objects and only the first field
-  is included in the object type. This way there is a high chance that it is
-  binary compatible to the union.
-* The condition in a ``do while(condition)`` statement must be ``0``.
-* Lots of other small issues...
-
diff --git a/doc/exception_hierarchy_fragment.txt b/doc/exception_hierarchy_fragment.txt
new file mode 100644
index 000000000..6ca68921f
--- /dev/null
+++ b/doc/exception_hierarchy_fragment.txt
@@ -0,0 +1,31 @@
+* `E_Base <system.html#E_Base>`_
+  * `EAccessViolation <system.html#EAccessViolation>`_
+  * `EArithmetic <system.html#EArithmetic>`_
+    * `EDivByZero <system.html#EDivByZero>`_
+    * `EOverflow <system.html#EOverflow>`_
+  * `EAssertionFailed <system.html#EAssertionFailed>`_
+  * `EAsynch <system.html#EAsynch>`_
+    * `EControlC <system.html#EControlC>`_
+  * `EDeadThread <system.html#EDeadThread>`_
+  * `EFloatingPoint <system.html#EFloatingPoint>`_
+    * `EFloatDivByZero <system.html#EFloatDivByZero>`_
+    * `EFloatInexact <system.html#EFloatInexact>`_
+    * `EFloatInvalidOp <system.html#EFloatInvalidOp>`_
+    * `EFloatOverflow <system.html#EFloatOverflow>`_
+    * `EFloatUnderflow <system.html#EFloatUnderflow>`_
+  * `EInvalidField <system.html#EInvalidField>`_
+  * `EInvalidIndex <system.html#EInvalidIndex>`_
+  * `EInvalidObjectAssignment <system.html#EInvalidObjectAssignment>`_
+  * `EInvalidObjectConversion <system.html#EInvalidObjectConversion>`_
+  * `EInvalidValue <system.html#EInvalidValue>`_
+    * `EInvalidKey <system.html#EInvalidKey>`_
+  * `ENoExceptionToReraise <system.html#ENoExceptionToReraise>`_
+  * `EOutOfRange <system.html#EOutOfRange>`_
+  * `ESynch <system.html#ESynch>`_
+    * `EOutOfMemory <system.html#EOutOfMemory>`_
+    * `EResourceExhausted <system.html#EResourceExhausted>`_
+    * `EStackOverflow <system.html#EStackOverflow>`_
+    * `ESystem <system.html#ESystem>`_
+      * `EIO <system.html#EIO>`_
+      * `EOS <system.html#EOS>`_
+        * `EInvalidLibrary <system.html#EInvalidLibrary>`_
diff --git a/doc/keywords.txt b/doc/keywords.txt
index 60b100398..a43b35475 100644
--- a/doc/keywords.txt
+++ b/doc/keywords.txt
@@ -6,7 +6,7 @@ elif else end enum except export
 finally for from
 generic
 if import in include interface is isnot iterator
-lambda let
+let
 macro method mixin mod
 nil not notin
 object of or out
diff --git a/doc/lib.txt b/doc/lib.txt
index 2da753007..76e7354e0 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -56,7 +56,10 @@ Core
 
 * `typeinfo <typeinfo.html>`_
   Provides (unsafe) access to Nimrod's run time type information. 
-  
+
+* `typetraits <typetraits.html>`_
+  This module defines compile-time reflection procs for working with types.
+
 * `actors <actors.html>`_
   Actor support for Nimrod; implemented as a layer on top of the threads and
   channels modules.
@@ -594,7 +597,8 @@ compiler.
 
 .. raw:: html
 
-  <div id="officialPkgList"></div>
+  <div id="officialPkgList"><b>If you are reading this you are missing
+  babelpkglist.js or have javascript disabled in your browser.</b></div>
 
 Unofficial packages
 -------------------
@@ -605,7 +609,8 @@ Nimrod programming language.
 
 .. raw:: html
 
-  <div id="unofficialPkgList"></div>
+  <div id="unofficialPkgList"><b>If you are reading this you are missing
+  babelpkglist.js or have javascript disabled in your browser.</b></div>
 
   <script type="text/javascript" src="babelpkglist.js"></script>
   <script type="text/javascript" src="http://build.nimrod-lang.org/packages?callback=gotPackageList"></script>
diff --git a/doc/manual.txt b/doc/manual.txt
index 32b0541e9..6d49bcd32 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -1221,38 +1221,8 @@ branch switch ``system.reset`` has to be used.
 
 Set type
 --------
-The set type models the mathematical notion of a set. The set's
-basetype can only be an ordinal type. The reason is that sets are implemented
-as high performance bit vectors.
-
-Sets can be constructed via the set constructor: ``{}`` is the empty set. The
-empty set is type compatible with any special set type. The constructor
-can also be used to include elements (and ranges of elements) in the set:
-
-.. code-block:: nimrod
-
-  {'a'..'z', '0'..'9'} # This constructs a set that contains the
-                       # letters from 'a' to 'z' and the digits
-                       # from '0' to '9'
-
-These operations are supported by sets:
-
-==================    ========================================================
-operation             meaning
-==================    ========================================================
-``A + B``             union of two sets
-``A * B``             intersection of two sets
-``A - B``             difference of two sets (A without B's elements)
-``A == B``            set equality
-``A <= B``            subset relation (A is subset of B or equal to B)
-``A < B``             strong subset relation (A is a real subset of B)
-``e in A``            set membership (A contains element e)
-``A -+- B``           symmetric set difference (= (A - B) + (B - A))
-``card(A)``           the cardinality of A (number of elements in A)
-``incl(A, elem)``     same as A = A + {elem}
-``excl(A, elem)``     same as A = A - {elem}
-==================    ========================================================
 
+.. include:: sets_fragment.txt
 
 Reference and pointer types
 ---------------------------
@@ -2497,7 +2467,7 @@ variable to use:
 
 When the compiler reaches the second ``add`` call, both ``a`` and ``b`` could
 be used with the proc, so one gets ``Error: expression '(a|b)' has no type (or
-is ambiguous)``. To solve this you would need to nest ``using`` with a
+is ambiguous)``. To solve this one would need to nest ``using`` with a
 ``block`` statement so as to control the reach of the ``using`` statement.
 
 If expression
@@ -4347,7 +4317,7 @@ Nimrod offers a special family of dot operators that can be used to
 intercept and rewrite proc call and field access attempts, referring
 to previously undeclared symbol names. They can be used to provide a
 fluent interface to objects lying outside the static confines of the
-Nimrod's type system such as values from dynamic scripting languages
+type system such as values from dynamic scripting languages
 or dynamic file formats such as JSON or XML.
 
 When Nimrod encounters an expression that cannot be resolved by the
@@ -4379,8 +4349,8 @@ This operator will be matched against both field accesses and method calls.
 operator `.()`
 ---------------
 This operator will be matched exclusively against method calls. It has higher
-precedence than the `.` operator and this allows you to handle expressions like
-`x.y` and `x.y()` differently if you are interfacing with a scripting language
+precedence than the `.` operator and this allows one to handle expressions like
+`x.y` and `x.y()` differently if one is interfacing with a scripting language
 for example.
 
 operator `.=`
@@ -4391,6 +4361,115 @@ This operator will be matched against assignments to missing fields.
   a.b = c # becomes `.=`(a, "b", c)
 
 
+Type bound operations
+=====================
+
+There are 3 operations that are bound to a type:
+
+1. Assignment
+2. Destruction
+3. Deep copying for communication between threads
+
+These operations can be *overriden* instead of *overloaded*. This means the
+implementation is automatically lifted to structured types. For instance if type
+``T`` has an overriden assignment operator ``=`` this operator is also used
+for assignments of the type ``seq[T]``. Since these operations are bound to a
+type they have to be bound to a nominal type for reasons of simplicity of
+implementation: This means an overriden ``deepCopy`` for ``ref T`` is really
+bound to ``T`` and not to ``ref T``. This also means that one cannot override
+``deepCopy`` for both ``ptr T`` and ``ref T`` at the same time; instead a
+helper distinct or object type has to be used for one pointer type.
+
+
+operator `=`
+------------
+
+This operator is the assignment operator. Note that in the contexts 
+like ``let v = expr``, ``var v = expr``, ``parameter = defaultValue`` or for
+parameter passing no assignment is performed. The ``override`` pragma is
+optional for overriding ``=``.
+
+
+destructors
+-----------
+
+A destructor must have a single parameter with a concrete type (the name of a
+generic type is allowed too). The name of the destructor has to be ``destroy``
+and it need to be annotated with the ``override`` pragma.
+
+``destroy(v)`` will be automatically invoked for every local stack 
+variable ``v`` that goes out of scope.
+
+If a structured type features a field with destructable type and 
+the user has not provided an explicit implementation, a destructor for the
+structured type will be automatically generated. Calls to any base class 
+destructors in both user-defined and generated destructors will be inserted.
+
+A destructor is attached to the type it destructs; expressions of this type
+can then only be used in *destructible contexts* and as parameters:
+
+.. code-block:: nimrod
+  type
+    TMyObj = object
+      x, y: int
+      p: pointer
+      
+  proc destroy(o: var TMyObj) {.override.} =
+    if o.p != nil: dealloc o.p
+    
+  proc open: TMyObj =
+    result = TMyObj(x: 1, y: 2, p: alloc(3))
+ 
+  proc work(o: TMyObj) =
+    echo o.x
+    # No destructor invoked here for 'o' as 'o' is a parameter.
+
+  proc main() =
+    # destructor automatically invoked at the end of the scope:
+    var x = open()
+    # valid: pass 'x' to some other proc:
+    work(x)
+    
+    # Error: usage of a type with a destructor in a non destructible context
+    echo open()
+
+A destructible context is currently only the following:
+
+1. The ``expr`` in ``var x = expr``.
+2. The ``expr`` in ``let x = expr``.
+3. The ``expr`` in ``return expr``.
+4. The ``expr`` in ``result = expr`` where ``result`` is the special symbol
+   introduced by the compiler.
+
+These rules ensure that the construction is tied to a variable and can easily
+be destructed at its scope exit. Later versions of the language will improve
+the support of destructors.
+
+Be aware that destructors are not called for objects allocated with ``new``.
+This may change in future versions of language, but for now the ``finalizer``
+parameter to ``new`` has to be used.
+
+
+deepCopy
+--------
+
+``deepCopy`` is a builtin that is invoked whenever data is passed to
+a ``spawn``'ed proc to ensure memory safety. The programmer can override its
+behaviour for a specific ``ref`` or ``ptr`` type ``T``. (Later versions of the
+language may weaken this restriction.)
+
+The signature has to be:
+
+.. code-block:: nimrod
+  proc deepCopy(x: T): T {.override.}
+
+This mechanism is used by most data structures that support shared memory like
+channels to implement thread safe automatic memory management.
+
+The builtin ``deepCopy`` can even clone closures and their environments. See
+the documentation of `spawn`_ for details.
+
+
 Term rewriting macros
 =====================
 
@@ -4970,9 +5049,9 @@ or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static
 error to mark a proc/iterator to have no side effect if the compiler cannot
 verify this.
 
-As a special semantic rule, the built-in ``debugEcho`` pretends to be free of 
-side effects, so that it can be used for debugging routines marked as
-``noSideEffect``.
+As a special semantic rule, the built-in `debugEcho <system.html#debugEcho>`_
+pretends to be free of side effects, so that it can be used for debugging
+routines marked as ``noSideEffect``.
 
 **Future directions**: ``func`` may become a keyword and syntactic sugar for a
 proc with no side effects:
@@ -4985,62 +5064,14 @@ destructor pragma
 -----------------
 
 The ``destructor`` pragma is used to mark a proc to act as a type destructor.
-The proc must have a single parameter with a concrete type (the name of a
-generic type is allowed too).
+Its usage is deprecated, use the ``override`` pragma instead.
+See `type bound operations`_.
 
-Destructors will be automatically invoked when a local stack variable goes 
-out of scope.
 
-If a record type features a field with destructable type and 
-the user have not provided explicit implementation, Nimrod will automatically
-generate a destructor for the record type. Nimrod will automatically insert
-calls to any base class destructors in both user-defined and generated
-destructors.
-
-A destructor is attached to the type it destructs; expressions of this type
-can then only be used in *destructible contexts* and as parameters:
-
-.. code-block:: nimrod
-  type
-    TMyObj = object
-      x, y: int
-      p: pointer
-      
-  proc destruct(o: var TMyObj) {.destructor.} =
-    if o.p != nil: dealloc o.p
-    
-  proc open: TMyObj =
-    result = TMyObj(x: 1, y: 2, p: alloc(3))
- 
-  proc work(o: TMyObj) =
-    echo o.x
-    # No destructor invoked here for 'o' as 'o' is a parameter.
-
-  proc main() =
-    # destructor automatically invoked at the end of the scope:
-    var x = open()
-    # valid: pass 'x' to some other proc:
-    work(x)
-    
-    # Error: usage of a type with a destructor in a non destructible context
-    echo open()
-
-A destructible context is currently only the following:
-
-1. The ``expr`` in ``var x = expr``.
-2. The ``expr`` in ``let x = expr``.
-3. The ``expr`` in ``return expr``.
-4. The ``expr`` in ``result = expr`` where ``result`` is the special symbol
-   introduced by the compiler.
-
-These rules ensure that the construction is tied to a variable and can easily
-be destructed at its scope exit. Later versions of the language will improve
-the support of destructors.
-
-Be aware that destructors are not called for objects allocated with ``new``.
-This may change in future versions of language, but for now use 
-the ``finalizer`` parameter to ``new``.
+override pragma
+---------------
 
+See `type bound operations`_ instead.
 
 procvar pragma
 --------------
@@ -5490,10 +5521,10 @@ spelled*:
   proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
 
 Note that this pragma is somewhat of a misnomer: Other backends will provide
-the same feature under the same name. Also, if you are interfacing with C++
-you can use the `ImportCpp pragma <nimrodc.html#importcpp-pragma>`_ and
+the same feature under the same name. Also, if one is interfacing with C++
+the `ImportCpp pragma <nimrodc.html#importcpp-pragma>`_ and
 interfacing with Objective-C the `ImportObjC pragma
-<nimrodc.html#importobjc-pragma>`_.
+<nimrodc.html#importobjc-pragma>`_ can be used.
 
 
 Exportc pragma
@@ -5781,12 +5812,14 @@ used instead. `spawn`:idx: is used to pass a task to the thread pool:
 
 Currently the expression that ``spawn`` takes is however quite restricted: 
 
-* It must be a call expresion ``f(a, ...)``.
+* It must be a call expression ``f(a, ...)``.
 * ``f`` must be ``gcsafe``.
 * ``f`` must not have the calling convention ``closure``.
-* ``f``'s parameters may not be of type ``var`` nor may they contain ``ref``.
-  This means you have to use raw ``ptr``'s for data passing reminding the
+* ``f``'s parameters may not be of type ``var``.
+  This means one has to use raw ``ptr``'s for data passing reminding the
   programmer to be careful.
+* ``ref`` parameters are deeply copied which is a subtle semantic change and
+  can cause performance problems but ensures memory safety.
 * For *safe* data exchange between ``f`` and the caller a global ``TChannel``
   needs to be used. Other means will be provided soon.
 
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 428c42f39..90fad7f9c 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -540,6 +540,58 @@ in C/C++).
 **Note**: This pragma will not exist for the LLVM backend.

 
 
+Source code style
+=================
+
+Nimrod allows you to `mix freely case and underscores as identifier separators
+<manual.html#identifiers-keywords>`_, so variables named ``MyPrecioussInt`` and
+``my_preciouss_int`` are equivalent:
+
+.. code-block:: Nimrod
+  var MyPrecioussInt = 3
+  # Following line compiles fine!
+  echo my_preciouss_int
+
+Since this can lead to many variants of the same source code (you can use
+`nimgrep <nimgrep.html>`_ instead of your typical ``grep`` to ignore style
+problems) the compiler provides the command ``pretty`` to help unifying the
+style of source code.  Running ``nimrod pretty ugly_test.nim`` with this
+example will generate a secondary file named ``ugly_test.pretty.nim`` with the
+following content:
+
+.. code-block:: Nimrod
+  var MyPrecioussInt = 3
+  # Following line compiles fine!
+  echo MyPrecioussInt
+
+During execution the ``pretty`` command will also run on Nimrod's standard
+library, since it doesn't differentiate the standard library as something
+special, and hence will warn of many *errors* which are out of your hand to
+fix, creating respective ``.pretty.nim`` files all the way. You can ignore
+these errors if they don't belong to your source and simply compare your
+original version to the new pretty one. In fact, running ``pretty`` on our test
+file will show the following::
+
+  Hint: ugly_test [Processing]
+  ugly_test.nim(1, 4) Error: name should be: myPrecioussInt
+  ugly_test.nim(1, 4) Error: name should be: myPrecioussInt
+
+At the moment ``pretty`` will homogenize the style of symbols but will leave
+important changes for you to review. In this case the command is warning that a
+variable name should not start with a capital letter, which is usually reserved
+to `object types <tut2.html#objects>`_. To learn about the accepted `camel case
+style <https://en.wikipedia.org/wiki/Camelcase>`_ read `Coding Guidelines in
+the Internals of Nimrod Compiler <intern.html#coding-guidelines>`_ or `Coding
+Guidelines <https://github.com/Araq/Nimrod/wiki/Coding-Guidelines>`_ and `NEP 1
+: Style Guide for Nimrod Code
+<https://github.com/Araq/Nimrod/wiki/NEP-1-:-Style-Guide-for-Nimrod-Code>`_
+from the Nimrod `GitHub wiki<https://github.com/Araq/Nimrod/wiki>`_.
+
+This command is safe to run because it will never attempt to overwrite your
+existing sources, but the respective ``.pretty.nim`` files **will** be
+overwritten without notice.
+
+
 DynlibOverride
 ==============
 
diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt
new file mode 100644
index 000000000..fba355269
--- /dev/null
+++ b/doc/sets_fragment.txt
@@ -0,0 +1,40 @@
+The set type models the mathematical notion of a set. The set's
+basetype can only be an ordinal type. The reason is that sets are implemented
+as high performance bit vectors.
+
+Sets can be constructed via the set constructor: ``{}`` is the empty set. The
+empty set is type compatible with any concrete set type. The constructor
+can also be used to include elements (and ranges of elements):
+
+.. code-block:: nimrod
+  type
+    TCharSet = set[char]
+  var
+    x: TCharSet
+  x = {'a'..'z', '0'..'9'} # This constructs a set that contains the
+                           # letters from 'a' to 'z' and the digits
+                           # from '0' to '9'
+
+These operations are supported by sets:
+
+==================    ========================================================
+operation             meaning
+==================    ========================================================
+``A + B``             union of two sets
+``A * B``             intersection of two sets
+``A - B``             difference of two sets (A without B's elements)
+``A == B``            set equality
+``A <= B``            subset relation (A is subset of B or equal to B)
+``A < B``             strong subset relation (A is a real subset of B)
+``e in A``            set membership (A contains element e)
+``e notin A``         A does not contain element e
+``contains(A, e)``    A contains element e
+``A -+- B``           symmetric set difference (= (A - B) + (B - A))
+``card(A)``           the cardinality of A (number of elements in A)
+``incl(A, elem)``     same as ``A = A + {elem}``
+``excl(A, elem)``     same as ``A = A - {elem}``
+==================    ========================================================
+
+Sets are often used to define a type for the *flags* of a procedure. This is
+a much cleaner (and type safe) solution than just defining integer
+constants that should be ``or``'ed together.
diff --git a/doc/spawn.txt b/doc/spawn.txt
index ed500f3a5..c5c96ecf8 100644
--- a/doc/spawn.txt
+++ b/doc/spawn.txt
@@ -53,13 +53,13 @@ restrictions / changes:
 * ``spawn`` within a ``parallel`` section has special semantics.
 * Every location of the form ``a[i]`` and ``a[i..j]`` and ``dest`` where
   ``dest`` is part of the pattern ``dest = spawn f(...)`` has to be
-  provable disjoint. This is called the *disjoint check*.
+  provably disjoint. This is called the *disjoint check*.
 * Every other complex location ``loc`` that is used in a spawned
   proc (``spawn f(loc)``) has to be immutable for the duration of
   the ``parallel`` section. This is called the *immutability check*. Currently
   it is not specified what exactly "complex location" means. We need to make
   this an optimization!
-* Every array access has to be provable within bounds. This is called 
+* Every array access has to be provably within bounds. This is called 
   the *bounds check*.
 * Slices are optimized so that no copy is performed. This optimization is not
   yet performed for ordinary slices outside of a ``parallel`` section. Slices
diff --git a/doc/tut1.txt b/doc/tut1.txt
index a2aa835ee..ee642ce17 100644
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -17,10 +17,9 @@ Introduction
 
 
 This document is a tutorial for the programming language *Nimrod*. 
-This tutorial assumes that you are familiar with basic programming concepts 
-like variables, types or statements but is kept very basic. The manual 
-contains many more examples of the advanced language features.
-
+This tutorial assumes that you are familiar with basic programming concepts
+like variables, types or statements but is kept very basic. The `manual
+<manual.html>`_ contains many more examples of the advanced language features.
 
 
 
@@ -40,9 +39,9 @@ Save this code to the file "greetings.nim". Now compile and run it::
 
   nimrod compile --run greetings.nim
 
-With the ``--run`` switch Nimrod executes the file automatically
-after compilation. You can give your program command line arguments by
-appending them after the filename::
+With the ``--run`` `switch <nimrodc.html#command-line-switches>`_ Nimrod
+executes the file automatically after compilation. You can give your program
+command line arguments by appending them after the filename::
 
   nimrod compile --run greetings.nim arg1 arg2
 
@@ -54,9 +53,10 @@ To compile a release version use::
   
   nimrod c -d:release greetings.nim
 
-By default the Nimrod compiler generates a large amount of runtime checks 
-aiming for your debugging pleasure. With ``-d:release`` these checks are 
-turned off and optimizations are turned on.
+By default the Nimrod compiler generates a large amount of runtime checks
+aiming for your debugging pleasure. With ``-d:release`` these checks are
+`turned off and optimizations are turned on
+<nimrodc.html#compile-time-symbols>`_.
 
 Though it should be pretty obvious what the program does, I will explain the
 syntax: statements which are not indented are executed when the program
@@ -65,9 +65,10 @@ done with spaces only, tabulators are not allowed.
 
 String literals are enclosed in double quotes. The ``var`` statement declares
 a new variable named ``name`` of type ``string`` with the value that is
-returned by the ``readLine`` procedure. Since the compiler knows that
-``readLine`` returns a string, you can leave out the type in the declaration
-(this is called `local type inference`:idx:). So this will work too:
+returned by the `readLine <system.html#readLine,TFile>`_ procedure. Since the
+compiler knows that `readLine <system.html#readLine,TFile>`_ returns a string,
+you can leave out the type in the declaration (this is called `local type
+inference`:idx:). So this will work too:
 
 .. code-block:: Nimrod
   var name = readLine(stdin)
@@ -75,10 +76,10 @@ returned by the ``readLine`` procedure. Since the compiler knows that
 Note that this is basically the only form of type inference that exists in
 Nimrod: it is a good compromise between brevity and readability.
 
-The "hello world" program contains several identifiers that are already
-known to the compiler: ``echo``, ``readLine``, etc. These built-ins are
-declared in the system_ module which is implicitly imported by any other
-module.
+The "hello world" program contains several identifiers that are already known
+to the compiler: ``echo``, `readLine <system.html#readLine,TFile>`_, etc.
+These built-ins are declared in the system_ module which is implicitly
+imported by any other module.
 
 
 Lexical elements
@@ -154,11 +155,11 @@ the syntax, watch their indentation:
   when false:
     brokenCode()
 
-Another option is to use the `discard`_ statement together with
-*long string literals* to create block comments:
+Another option is to use the `discard statement`_ together with *long string
+literals* to create block comments:
 
 .. code-block:: nimrod
-  discard """ You can have any nimrod code text commented 
+  discard """ You can have any Nimrod code text commented
   out inside this with no indentation restrictions.
         yes("May I ask a pointless question?") """
 
@@ -257,10 +258,10 @@ that can not be re-assigned, ``const`` means "enforce compile time evaluation
 and put it into a data section":
 
 .. code-block::
-  const input = readline(stdin) # Error: constant expression expected
+  const input = readLine(stdin) # Error: constant expression expected
   
 .. code-block::
-  let input = readline(stdin)   # works
+  let input = readLine(stdin)   # works
 
 
 Control flow statements
@@ -285,9 +286,10 @@ The if statement is one way to branch the control flow:
   else:
     echo("Hi, ", name, "!")
 
-There can be zero or more elif parts, and the else part is optional. The
-keyword ``elif`` is short for ``else if``, and is useful to avoid excessive
-indentation. (The ``""`` is the empty string. It contains no characters.)
+There can be zero or more ``elif`` parts, and the ``else`` part is optional.
+The keyword ``elif`` is short for ``else if``, and is useful to avoid
+excessive indentation. (The ``""`` is the empty string. It contains no
+characters.)
 
 
 Case statement
@@ -338,7 +340,7 @@ the compiler that for every other value nothing should be done:
   of 3, 8: echo("The number is 3 or 8")
   else: discard
 
-The empty ``discard`` statement is a *do nothing* statement. The compiler knows
+The empty `discard statement`_ is a *do nothing* statement. The compiler knows
 that a case statement with an else part cannot fail and thus the error 
 disappears. Note that it is impossible to cover all possible string values: 
 that is why there is no such check for string cases.
@@ -370,7 +372,8 @@ For statement
 -------------
 
 The ``for`` statement is a construct to loop over any element an *iterator*
-provides. The example uses the built-in ``countup`` iterator:
+provides. The example uses the built-in `countup <system.html#countup>`_
+iterator:
 
 .. code-block:: nimrod
   echo("Counting to ten: ")
@@ -378,11 +381,11 @@ provides. The example uses the built-in ``countup`` iterator:
     echo($i)
   # --> Outputs 1 2 3 4 5 6 7 8 9 10 on different lines
 
-The built-in ``$`` operator turns an integer (``int``) and many other types
-into a string. The variable ``i`` is implicitly declared by the ``for`` loop
-and has the type ``int``, because that is what ``countup`` returns. ``i`` runs
-through the values 1, 2, .., 10. Each value is ``echo``-ed. This code does
-the same:
+The built-in `$ <system.html#$>`_ operator turns an integer (``int``) and many
+other types into a string. The variable ``i`` is implicitly declared by the
+``for`` loop and has the type ``int``, because that is what `countup
+<system.html#countup>`_ returns. ``i`` runs through the values 1, 2, .., 10.
+Each value is ``echo``-ed. This code does the same:
 
 .. code-block:: nimrod
   echo("Counting to 10: ")
@@ -400,8 +403,8 @@ Counting down can be achieved as easily (but is less often needed):
     echo($i)
   # --> Outputs 10 9 8 7 6 5 4 3 2 1 on different lines
 
-Since counting up occurs so often in programs, Nimrod also has a ``..`` iterator
-that does the same:
+Since counting up occurs so often in programs, Nimrod also has a `..
+<system.html#...i,S,T>`_ iterator that does the same:
 
 .. code-block:: nimrod
   for i in 1..10:
@@ -553,9 +556,10 @@ an expression is allowed:
 Procedures
 ==========
 
-To define new commands like ``echo``, ``readline`` in the examples, the concept
-of a `procedure` is needed. (Some languages call them *methods* or
-*functions*.) In Nimrod new procedures are defined with the ``proc`` keyword:
+To define new commands like `echo <system.html#echo>`_ and `readLine
+<system.html#readLine,TFile>`_ in the examples, the concept of a `procedure`
+is needed. (Some languages call them *methods* or *functions*.) In Nimrod new
+procedures are defined with the ``proc`` keyword:
 
 .. code-block:: nimrod
   proc yes(question: string): bool =
@@ -649,7 +653,7 @@ a tuple as a return value instead of using var parameters.
 Discard statement
 -----------------
 To call a procedure that returns a value just for its side effects and ignoring
-its return value, a discard statement **has** to be used. Nimrod does not
+its return value, a ``discard`` statement **has** to be used. Nimrod does not
 allow to silently throw away a return value:
 
 .. code-block:: nimrod
@@ -665,8 +669,8 @@ been declared with the ``discardable`` pragma:
     
   p(3, 4) # now valid
 
-The discard statement can also be used to create block comments as described
-in the `Comments`_.
+The ``discard`` statement can also be used to create block comments as
+described in the `Comments`_ section.
 
 
 Named arguments
@@ -730,12 +734,12 @@ Nimrod provides the ability to overload procedures similar to C++:
   echo(toString(13))   # calls the toString(x: int) proc
   echo(toString(true)) # calls the toString(x: bool) proc
 
-(Note that ``toString`` is usually the ``$`` operator in Nimrod.)
-The compiler chooses the most appropriate proc for the ``toString`` calls. How
-this overloading resolution algorithm works exactly is not discussed here
-(it will be specified in the manual soon).
-However, it does not lead to nasty surprises and is based on a quite simple
-unification algorithm. Ambiguous calls are reported as errors.
+(Note that ``toString`` is usually the `$ <system.html#$>`_ operator in
+Nimrod.) The compiler chooses the most appropriate proc for the ``toString``
+calls. How this overloading resolution algorithm works exactly is not
+discussed here (it will be specified in the manual soon).  However, it does
+not lead to nasty surprises and is based on a quite simple unification
+algorithm. Ambiguous calls are reported as errors.
 
 
 Operators
@@ -758,7 +762,7 @@ User defined operators are allowed. Nothing stops you from defining your own
 The operator's precedence is determined by its first character. The details
 can be found in the manual.
 
-To define a new operator enclose the operator in "``":
+To define a new operator enclose the operator in backticks "``":
 
 .. code-block:: nimrod
   proc `$` (x: myDataType): string = ...
@@ -811,7 +815,8 @@ Let's return to the boring counting example:
   for i in countup(1, 10):
     echo($i)
 
-Can a ``countup`` proc be written that supports this loop? Lets try:
+Can a `countup <system.html#countup>`_ proc be written that supports this
+loop? Lets try:
 
 .. code-block:: nimrod
   proc countup(a, b: int): int =
@@ -976,24 +981,25 @@ type:
 The common operators ``+ - * /  <  <=  ==  !=  >  >=`` are defined for
 floats and follow the IEEE standard.
 
-Automatic type conversion in expressions with different kinds
-of floating point types is performed: the smaller type is
-converted to the larger. Integer types are **not** converted to floating point
-types automatically and vice versa. The ``toInt`` and ``toFloat`` procs can be
-used for these conversions.
+Automatic type conversion in expressions with different kinds of floating
+point types is performed: the smaller type is converted to the larger. Integer
+types are **not** converted to floating point types automatically and vice
+versa. The `toInt <system.html#toInt>`_ and `toFloat <system.html#toFloat>`_
+procs can be used for these conversions.
 
 
 Internal type representation
 ============================
 
-As mentioned earlier, the built-in ``$`` (stringify) operator turns any basic
-type into a string, which you can then print to the screen with the ``echo``
-proc. However, advanced types, or types you may define yourself won't work with
-the ``$`` operator until you define one for them. Sometimes you just want to
-debug the current value of a complex type without having to write its ``$``
-operator.  You can use then the ``repr`` proc which works with any type and
-even complex data graphs with cycles. The following example shows that even for
-basic types there is a difference between the ``$`` and ``repr`` outputs:
+As mentioned earlier, the built-in `$ <system.html#$>`_ (stringify) operator
+turns any basic type into a string, which you can then print to the screen
+with the ``echo`` proc. However, advanced types, or types you may define
+yourself won't work with the ``$`` operator until you define one for them.
+Sometimes you just want to debug the current value of a complex type without
+having to write its ``$`` operator.  You can use then the `repr
+<system.html#repr>`_ proc which works with any type and even complex data
+graphs with cycles. The following example shows that even for basic types
+there is a difference between the ``$`` and ``repr`` outputs:
 
 .. code-block:: nimrod
   var
@@ -1087,9 +1093,10 @@ Operation             Comment
 ``pred(x, n)``        returns the `n`'th predecessor of `x`
 -----------------     --------------------------------------------------------
 
-The ``inc dec succ pred`` operations can fail by raising an `EOutOfRange` or
-`EOverflow` exception. (If the code has been compiled with the proper runtime
-checks turned on.)
+The `inc <system.html#inc>`_, `dec <system.html#dec>`_, `succ
+<system.html#succ>`_ and `pred <system.html#pred>`_ operations can fail by
+raising an `EOutOfRange` or `EOverflow` exception. (If the code has been
+compiled with the proper runtime checks turned on.)
 
 
 Subranges
@@ -1107,57 +1114,18 @@ to 5. Assigning any other value to a variable of type ``TSubrange`` is a
 compile-time or runtime error. Assignments from the base type to one of its
 subrange types (and vice versa) are allowed.
 
-The ``system`` module defines the important ``natural`` type as
-``range[0..high(int)]`` (``high`` returns the maximal value). Other programming
-languages mandate the usage of unsigned integers for natural numbers. This is
-often **wrong**: you don't want unsigned arithmetic (which wraps around) just
-because the numbers cannot be negative. Nimrod's ``natural`` type helps to
-avoid this common programming error.
+The ``system`` module defines the important `Natural <system.html#Natural>`_
+type as ``range[0..high(int)]`` (`high <system.html#high>`_ returns the
+maximal value). Other programming languages mandate the usage of unsigned
+integers for natural numbers. This is often **wrong**: you don't want unsigned
+arithmetic (which wraps around) just because the numbers cannot be negative.
+Nimrod's ``Natural`` type helps to avoid this common programming error.
 
 
 Sets
 ----
-The set type models the mathematical notion of a set. The set's
-basetype can only be an ordinal type. The reason is that sets are implemented
-as high performance bit vectors.
-
-Sets can be constructed via the set constructor: ``{}`` is the empty set. The
-empty set is type compatible with any concrete set type. The constructor
-can also be used to include elements (and ranges of elements):
-
-.. code-block:: nimrod
-  type
-    TCharSet = set[char]
-  var
-    x: TCharSet
-  x = {'a'..'z', '0'..'9'} # This constructs a set that contains the
-                           # letters from 'a' to 'z' and the digits
-                           # from '0' to '9'
-
-These operations are supported by sets:
-
-==================    ========================================================
-operation             meaning
-==================    ========================================================
-``A + B``             union of two sets
-``A * B``             intersection of two sets
-``A - B``             difference of two sets (A without B's elements)
-``A == B``            set equality
-``A <= B``            subset relation (A is subset of B or equal to B)
-``A < B``             strong subset relation (A is a real subset of B)
-``e in A``            set membership (A contains element e)
-``e notin A``         A does not contain element e
-``contains(A, e)``    A contains element e
-``A -+- B``           symmetric set difference (= (A - B) + (B - A))
-``card(A)``           the cardinality of A (number of elements in A)
-``incl(A, elem)``     same as ``A = A + {elem}``
-``excl(A, elem)``     same as ``A = A - {elem}``
-==================    ========================================================
-
-Sets are often used to define a type for the *flags* of a procedure. This is
-a much cleaner (and type safe) solution than just defining integer
-constants that should be ``or``'ed together.
 
+.. include:: sets_fragment.txt
 
 Arrays
 ------
@@ -1184,8 +1152,9 @@ checks can be disabled via pragmas or invoking the compiler with the
 Arrays are value types, like any other Nimrod type. The assignment operator
 copies the whole array contents.
 
-The built-in ``len`` proc returns the array's length. ``low(a)`` returns the
-lowest valid index for the array `a` and ``high(a)`` the highest valid index.
+The built-in `len <system.html#len,TOpenArray>`_ proc returns the array's
+length. `low(a) <system.html#low>`_ returns the lowest valid index for the
+array `a` and `high(a) <system.html#high>`_ the highest valid index.
 
 .. code-block:: nimrod
   type
@@ -1257,13 +1226,14 @@ Sequences are similar to arrays but of dynamic length which may change
 during runtime (like strings). Since sequences are resizable they are always
 allocated on the heap and garbage collected.
 
-Sequences are always indexed with an ``int`` starting at position 0.
-The ``len``, ``low`` and ``high`` operations are available for sequences too.
-The notation ``x[i]`` can be used to access the i-th element of ``x``.
+Sequences are always indexed with an ``int`` starting at position 0.  The `len
+<system.html#len,seq[T]>`_, `low <system.html#low>`_ and `high
+<system.html#high>`_ operations are available for sequences too.  The notation
+``x[i]`` can be used to access the i-th element of ``x``.
 
 Sequences can be constructed by the array constructor ``[]`` in conjunction
 with the array to sequence operator ``@``. Another way to allocate space for
-a sequence is to call the built-in ``newSeq`` procedure.
+a sequence is to call the built-in `newSeq <system.html#newSeq>`_ procedure.
 
 A sequence may be passed to an openarray parameter.
 
@@ -1284,10 +1254,11 @@ object on the heap, so there is a trade-off to be made here.
 The ``for`` statement can be used with one or two variables when used with a
 sequence. When you use the one variable form, the variable will hold the value
 provided by the sequence. The ``for`` statement is looping over the results
-from the ``items()`` iterator from the `system <system.html>`_ module.  But if
-you use the two variable form, the first variable will hold the index position
-and the second variable will hold the value. Here the ``for`` statement is
-looping over the results from the ``pairs()`` iterator from the `system
+from the `items() <system.html#items.i,seq[T]>`_ iterator from the `system
+<system.html>`_ module.  But if you use the two variable form, the first
+variable will hold the index position and the second variable will hold the
+value. Here the ``for`` statement is looping over the results from the
+`pairs() <system.html#pairs.i,seq[T]>`_ iterator from the `system
 <system.html>`_ module.  Examples:
 
 .. code-block:: nimrod
@@ -1308,12 +1279,13 @@ Open arrays
 -----------
 **Note**: Openarrays can only be used for parameters.
 
-Often fixed size arrays turn out to be too inflexible; procedures should
-be able to deal with arrays of different sizes. The `openarray`:idx: type
-allows this. Openarrays are always indexed with an ``int`` starting at
-position 0. The ``len``, ``low`` and ``high`` operations are available
-for open arrays too. Any array with a compatible base type can be passed to
-an openarray parameter, the index type does not matter.
+Often fixed size arrays turn out to be too inflexible; procedures should be
+able to deal with arrays of different sizes. The `openarray`:idx: type allows
+this. Openarrays are always indexed with an ``int`` starting at position 0.
+The `len <system.html#len,TOpenArray>`_, `low <system.html#low>`_ and `high
+<system.html#high>`_ operations are available for open arrays too.  Any array
+with a compatible base type can be passed to an openarray parameter, the index
+type does not matter.
 
 The openarray type cannot be nested: multidimensional openarrays are not
 supported because this is seldom needed and cannot be done efficiently.
@@ -1351,8 +1323,9 @@ type conversions in this context:
   # is transformed by the compiler to:
   myWriteln(stdout, [$123, $"def", $4.0])
 
-In this example ``$`` is applied to any argument that is passed to the 
-parameter ``a``. Note that ``$`` applied to strings is a nop.
+In this example `$ <system.html#$>`_ is applied to any argument that is passed
+to the parameter ``a``. Note that `$ <system.html#$>`_ applied to strings is a
+nop.
 
 
 Slices
@@ -1431,11 +1404,12 @@ having the same field types.
 
 Tuples can be *unpacked* during variable assignment (and only then!). This can
 be handy to assign directly the fields of the tuples to individually named
-variables. An example of this is the ``splitFile`` proc from the `os module
-<os.html>`_ which returns the directory, name and extension of a path at the
-same time. For tuple unpacking to work you have to use parenthesis around the
-values you want to assign the unpacking to, otherwise you will be assigning the
-same value to all the individual variables! Example:
+variables. An example of this is the `splitFile <os.html#splitFile>`_ proc
+from the `os module <os.html>`_ which returns the directory, name and
+extension of a path at the same time. For tuple unpacking to work you have to
+use parenthesis around the values you want to assign the unpacking to,
+otherwise you will be assigning the same value to all the individual
+variables! Example:
 
 .. code-block:: nimrod
 
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 1e23618e0..2f42bcefc 100644
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -23,11 +23,13 @@ features.**
 
 Pragmas
 =======
+
 Pragmas are Nimrod's method to give the compiler additional information/
-commands without introducing a massive number of new keywords. Pragmas are 
-enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial 
-does not cover pragmas. See the `manual <manual.html>`_ 
-or `user guide <nimrodc.html>`_ for a description of the available pragmas.
+commands without introducing a massive number of new keywords. Pragmas are
+enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial
+does not cover pragmas. See the `manual <manual.html#pragmas>`_ or `user guide
+<nimrodc.html#additional-features>`_ for a description of the available
+pragmas.
 
 
 Object Oriented Programming
@@ -421,9 +423,10 @@ the rest of the procedure - that is not within a ``finally`` clause -
 is not executed (if an exception occurs).
 
 If you need to *access* the actual exception object or message inside an
-``except`` branch you can use the getCurrentException() and
-getCurrentExceptionMsg() procs from the `system <system.html>`_ module.
-Example:
+``except`` branch you can use the `getCurrentException()
+<system.html#getCurrentException>`_ and `getCurrentExceptionMsg()
+<system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_
+module.  Example:
 
 .. code-block:: nimrod
   try:
@@ -440,39 +443,9 @@ Exception hierarchy
 
 If you want to create your own exceptions you can inherit from E_Base, but you
 can also inherit from one of the existing exceptions if they fit your purpose.
-The exception tree is::
-
-  * E_Base
-    * EAsynch
-      * EControlC
-    * ESynch
-      * ESystem
-        * EIO
-        * EOS
-          * EInvalidLibrary
-      * EResourceExhausted
-      * EOutOfMemory
-      * EStackOverflow
-    * EArithmetic
-      * EDivByZero
-      * EOverflow
-    * EAccessViolation
-    * EAssertionFailed
-    * EInvalidValue
-      * EInvalidKey
-    * EInvalidIndex
-    * EInvalidField
-    * EOutOfRange
-    * ENoExceptionToReraise
-    * EInvalidObjectAssignment
-    * EInvalidObjectConversion
-    * EFloatingPoint
-      * EFloatInvalidOp
-      * EFloatDivByZero
-      * EFloatOverflow
-      * EFloatUnderflow
-      * EFloatInexact
-    * EDeadThread
+The exception tree is:
+
+.. include:: exception_hierarchy_fragment.txt
 
 See the `system <system.html>`_ module for a description of each exception.
 
@@ -663,8 +636,8 @@ statement:
   declareInNewScope(b, int)
   b = 42  # does not work, `b` is unknown
 
-(The manual explains why the ``immediate`` pragma is needed for these 
-templates.)
+(The `manual explains <manual.html#ordinary-vs-immediate-templates>`_  why the
+``immediate`` pragma is needed for these templates.)
 
 If there is a ``stmt`` parameter it should be the last in the template
 declaration. The reason is that statements can be passed to a template
diff --git a/koch.nim b/koch.nim
index 15ee3732d..dff6ede98 100644
--- a/koch.nim
+++ b/koch.nim
@@ -93,10 +93,9 @@ proc buildTool(toolname, args: string) =
   copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
 
 proc inno(args: string) =
-  # make sure we have generated the c2nim and niminst executables:
+  # make sure we have generated the niminst executables:
   buildTool("tools/niminst/niminst", args)
   buildTool("tools/nimgrep", args)
-  buildTool("compiler/c2nim/c2nim", args)  
   exec("tools" / "niminst" / "niminst --var:version=$# inno compiler/nimrod" % 
        NimrodVersion)
 
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index edb4d1188..57e11664b 100644
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -420,6 +420,59 @@ proc setBiggestInt*(x: TAny, y: biggestInt) =
   of tyUInt32: cast[ptr uint32](x.value)[] = uint32(y)
   else: assert false
 
+proc getUInt*(x: TAny): uint =
+  ## retrieve the uint value out of `x`, `x` needs to represent an uint.
+  assert skipRange(x.rawtype).kind == tyUInt
+  result = cast[ptr uint](x.value)[]
+
+proc getUInt8*(x: TAny): uint8 =
+  ## retrieve the uint8 value out of `x`, `x` needs to represent an
+  ## uint8.
+  assert skipRange(x.rawtype).kind == tyUInt8
+  result = cast[ptr uint8](x.value)[]
+
+proc getUInt16*(x: TAny): uint16 =
+  ## retrieve the uint16 value out of `x`, `x` needs to represent an
+  ## uint16.
+  assert skipRange(x.rawtype).kind == tyUInt16
+  result = cast[ptr uint16](x.value)[]
+
+proc getUInt32*(x: TAny): uint32 =
+  ## retrieve the uint32 value out of `x`, `x` needs to represent an
+  ## uint32.
+  assert skipRange(x.rawtype).kind == tyUInt32
+  result = cast[ptr uint32](x.value)[]
+
+proc getUInt64*(x: TAny): uint64 =
+  ## retrieve the uint64 value out of `x`, `x` needs to represent an
+  ## uint64.
+  assert skipRange(x.rawtype).kind == tyUInt64
+  result = cast[ptr uint64](x.value)[]
+
+proc getBiggestUint*(x: TAny): uint64 =
+  ## retrieve the unsigned integer value out of `x`. `x` needs to
+  ## represent an unsigned integer.
+  var t = skipRange(x.rawtype)
+  case t.kind
+  of tyUInt: result = uint64(cast[ptr uint](x.value)[])
+  of tyUInt8: result = uint64(cast[ptr uint8](x.value)[])
+  of tyUInt16: result = uint64(cast[ptr uint16](x.value)[])
+  of tyUInt32: result = uint64(cast[ptr uint32](x.value)[])
+  of tyUInt64: result = uint64(cast[ptr uint64](x.value)[])
+  else: assert false
+
+proc setBiggestUint*(x: TAny; y: uint64) =
+  ## sets the unsigned integer value of `c`. `c` needs to represent an
+  ## unsigned integer.
+  var t = skipRange(x.rawtype)
+  case t.kind:
+  of tyUInt: cast[ptr uint](x.value)[] = uint(y)
+  of tyUInt8: cast[ptr uint8](x.value)[] = uint8(y)
+  of tyUInt16: cast[ptr uint16](x.value)[] = uint16(y)
+  of tyUInt32: cast[ptr uint32](x.value)[] = uint32(y)
+  of tyUInt64: cast[ptr uint64](x.value)[] = uint64(y)
+  else: assert false
+
 proc getChar*(x: TAny): char =
   ## retrieve the char value out of `x`. `x` needs to represent a char.
   var t = skipRange(x.rawtype)
diff --git a/lib/nimbase.h b/lib/nimbase.h
index cfd33dca1..b43094227 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -328,7 +328,8 @@ struct TFrame {
   NCSTRING procname;
   NI line;
   NCSTRING filename;
-  NI len;
+  NI16 len;
+  NI16 calldepth;
 };
 
 #define nimfr(proc, file) \
diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim
index 80fbf3a51..ff371f4e1 100644
--- a/lib/packages/docutils/highlite.nim
+++ b/lib/packages/docutils/highlite.nim
@@ -50,7 +50,7 @@ const
     "break", "case", "cast", "const", "continue", "converter", "discard",
     "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export",
     "finally", "for", "from", "generic", "if", "import", "in", "include",
-    "interface", "is", "isnot", "iterator", "lambda", "let", "macro", "method",
+    "interface", "is", "isnot", "iterator", "let", "macro", "method",
     "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
     "ptr", "raise", "ref", "return", "shl", "shr", "static",
     "template", "try", "tuple", "type", "using", "var", "when", "while", "with",
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index fdbca4ca8..e9bae69b5 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -775,7 +775,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
   dispA(d.target, result, "<pre>", "\\begin{rstpre}\n", [])
   if lang == langNone:
     d.msgHandler(d.filename, 1, 0, mwUnsupportedLanguage, langstr)
-    result.add(m.text)
+    for letter in m.text: escChar(d.target, result, letter)
   else:
     var g: TGeneralTokenizer
     initGeneralTokenizer(g, m.text)
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index 8e66336c2..a5ee05abb 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -90,7 +90,7 @@ type
     d_ino*: Tino  ## File serial number.
     d_name*: array [0..255, char] ## Name of entry.
 
-  Tflock* {.importc: "flock", final, pure,
+  Tflock* {.importc: "struct flock", final, pure,
             header: "<fcntl.h>".} = object ## flock type
     l_type*: cshort   ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
     l_whence*: cshort ## Flag for starting offset.
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 86d329763..89c83a8a4 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -34,6 +34,20 @@ proc reverse*[T](a: var openArray[T]) =
   ## reverses the array `a`.
   reverse(a, 0, a.high)
 
+proc reversed*[T](a: openArray[T], first, last: int): seq[T] =
+  ## returns the reverse of the array `a[first..last]`.
+  result = newSeq[T](last - first + 1)
+  var x = first
+  var y = last
+  while x <= last:
+    result[x] = a[y]
+    dec(y)
+    inc(x)
+
+proc reversed*[T](a: openArray[T]): seq[T] =
+  ## returns the reverse of the array `a`.
+  reversed(a, 0, a.high)
+
 proc binarySearch*[T](a: openArray[T], key: T): int =
   ## binary search for `key` in `a`. Returns -1 if not found.
   var b = len(a)
diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim
index 4e59a6ca6..7b3b0e6f5 100644
--- a/lib/pure/base64.nim
+++ b/lib/pure/base64.nim
@@ -58,7 +58,7 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat
     if r+4 != result.len:

       setLen(result, r+4)

   else:

-    assert(r == result.len)

+    #assert(r == result.len)

 

 proc encode*[T:TInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = 

   ## encodes `s` into base64 representation. After `lineLen` characters, a 

diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim
index 40a02b651..1fde1f419 100644
--- a/lib/pure/collections/critbits.nim
+++ b/lib/pure/collections/critbits.nim
@@ -131,7 +131,7 @@ proc `[]=`*[T](c: var TCritBitTree[T], key: string, val: T) =
   var n = rawInsert(c, key)
   n.val = val
 
-proc `[]`*[T](c: var TCritBitTree[T], key: string): T {.inline.} =
+proc `[]`*[T](c: TCritBitTree[T], key: string): T {.inline.} =
   ## retrieves the value at ``c[key]``. If `key` is not in `t`,
   ## default empty value for the type `B` is returned
   ## and no exception is raised. One can check with ``hasKey`` whether the key
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index e760c5e02..c50c4165b 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -186,7 +186,7 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) =
   ##
   ## .. code-block:: nimrod
   ##   var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1]
-  ##   filter(floats, proc(x: float): bool = x > 10)
+  ##   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):
@@ -388,6 +388,7 @@ template mapIt*(seq1, typ, pred: expr): expr =
   ##   let
   ##     nums = @[1, 2, 3, 4]
   ##     strings = nums.mapIt(string, $(4 * it))
+  ##   assert strings == @["4", "8", "12", "16"]
   var result {.gensym.}: seq[typ] = @[]
   for it {.inject.} in items(seq1):
     result.add(pred)
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 4ba67cb2e..42cdc682f 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -9,6 +9,10 @@
 
 ## The ``sets`` module implements an efficient hash set and ordered hash set.
 ##
+## Hash sets are different from the `built in set type
+## <manual.html#set-type>`_. Sets allow you to store any value that can be
+## `hashed <hashes.html>`_ and they don't contain duplicate entries.
+##
 ## **Note**: The data types declared here have *value semantics*: This means
 ## that ``=`` performs a copy of the set.
 
@@ -23,20 +27,69 @@ type
   TSlotEnum = enum seEmpty, seFilled, seDeleted
   TKeyValuePair[A] = tuple[slot: TSlotEnum, key: A]
   TKeyValuePairSeq[A] = seq[TKeyValuePair[A]]
-  TSet* {.final, myShallow.}[A] = object ## a generic hash set
+  TSet* {.final, myShallow.}[A] = object ## \
+    ## A generic hash set.
+    ##
+    ## Use `init() <#init,TSet[A],int>`_ or `initSet[type]() <#initSet>`_
+    ## before calling other procs on it.
     data: TKeyValuePairSeq[A]
     counter: int
 
+proc isValid*[A](s: TSet[A]): bool =
+  ## Returns `true` if the set has been initialized with `initSet <#initSet>`_.
+  ##
+  ## Most operations over an uninitialized set will crash at runtime and
+  ## `assert <system.html#assert>`_ in debug builds. You can use this proc in
+  ## your own procs to verify that sets passed to your procs are correctly
+  ## initialized. Example:
+  ##
+  ## .. code-block :: nimrod
+  ##   proc savePreferences(options: TSet[string]) =
+  ##     assert options.isValid, "Pass an initialized set!"
+  ##     # Do stuff here, may crash in release builds!
+  result = not s.data.isNil
+
 proc len*[A](s: TSet[A]): int =
-  ## returns the number of keys in `s`.
+  ## Returns the number of keys in `s`.
+  ##
+  ## Due to an implementation detail you can call this proc on variables which
+  ## have not been initialized yet. The proc will return zero as the length
+  ## then. Example:
+  ##
+  ## .. code-block::
+  ##
+  ##   var values: TSet[int]
+  ##   assert(not values.isValid)
+  ##   assert values.len == 0
   result = s.counter
 
 proc card*[A](s: TSet[A]): int =
-  ## alias for `len`.
+  ## Alias for `len() <#len,TSet[A]>`_.
+  ##
+  ## Card stands for the `cardinality
+  ## <http://en.wikipedia.org/wiki/Cardinality>`_ of a set.
   result = s.counter
 
 iterator items*[A](s: TSet[A]): A =
-  ## iterates over any key in the table `t`.
+  ## Iterates over keys in the set `s`.
+  ##
+  ## If you need a sequence with the keys you can use `sequtils.toSeq()
+  ## <sequtils.html#toSeq>`_ on the iterator. Usage example:
+  ##
+  ## .. code-block::
+  ##   type
+  ##     pair = tuple[a, b: int]
+  ##   var
+  ##     a, b = initSet[pair]()
+  ##   a.incl((2, 3))
+  ##   a.incl((3, 2))
+  ##   a.incl((2, 3))
+  ##   for x, y in a.items:
+  ##     b.incl((x - 2, y + 1))
+  ##   assert a.len == 2
+  ##   echo b
+  ##   # --> {(a: 1, b: 3), (a: 0, b: 4)}
+  assert s.isValid, "The set needs to be initialized."
   for h in 0..high(s.data):
     if s.data[h].slot == seFilled: yield s.data[h].key
 
@@ -73,12 +126,24 @@ proc mget*[A](s: var TSet[A], key: A): var A =
   ## value as 'key' or raises the ``EInvalidKey`` exception. This is useful
   ## when one overloaded 'hash' and '==' but still needs reference semantics
   ## for sharing.
+  assert s.isValid, "The set needs to be initialized."
   var index = rawGet(s, key)
   if index >= 0: result = t.data[index].key
   else: raise newException(EInvalidKey, "key not found: " & $key)
 
 proc contains*[A](s: TSet[A], key: A): bool =
-  ## returns true iff `key` is in `s`.
+  ## Returns true iff `key` is in `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var values = initSet[int]()
+  ##   assert(not values.contains(2))
+  ##   values.incl(2)
+  ##   assert values.contains(2)
+  ##   values.excl(2)
+  ##   assert(not values.contains(2))
+  assert s.isValid, "The set needs to be initialized."
   var index = rawGet(s, key)
   result = index >= 0
 
@@ -109,38 +174,124 @@ template containsOrInclImpl() {.dirty.} =
     inc(s.counter)
 
 proc incl*[A](s: var TSet[A], key: A) =
-  ## includes an element `key` in `s`.
+  ## Includes an element `key` in `s`.
+  ##
+  ## This doesn't do anything if `key` is already in `s`. Example:
+  ##
+  ## .. code-block::
+  ##   var values = initSet[int]()
+  ##   values.incl(2)
+  ##   values.incl(2)
+  ##   assert values.len == 1
+  assert s.isValid, "The set needs to be initialized."
   inclImpl()
 
 proc incl*[A](s: var TSet[A], other: TSet[A]) =
-  ## includes everything in `other` in `s`
+  ## Includes all elements from `other` into `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var values = initSet[int]()
+  ##   values.incl(2)
+  ##   var others = toSet([6, 7])
+  ##   values.incl(others)
+  ##   assert values.len == 3
+  assert s.isValid, "The set `s` needs to be initialized."
+  assert other.isValid, "The set `other` needs to be initialized."
   for item in other: incl(s, item)
 
 proc excl*[A](s: var TSet[A], key: A) =
-  ## excludes `key` from the set `s`.
+  ## Excludes `key` from the set `s`.
+  ##
+  ## This doesn't do anything if `key` is not found in `s`. Example:
+  ##
+  ## .. code-block::
+  ##   var s = toSet([2, 3, 6, 7])
+  ##   s.excl(2)
+  ##   s.excl(2)
+  ##   assert s.len == 3
+  assert s.isValid, "The set needs to be initialized."
   var index = rawGet(s, key)
   if index >= 0:
     s.data[index].slot = seDeleted
     dec(s.counter)
 
 proc excl*[A](s: var TSet[A], other: TSet[A]) =
-  ## excludes everything in `other` from `s`.
+  ## Excludes everything in `other` from `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     numbers = toSet([1, 2, 3, 4, 5])
+  ##     even = toSet([2, 4, 6, 8])
+  ##   numbers.excl(even)
+  ##   echo numbers
+  ##   # --> {1, 3, 5}
+  assert s.isValid, "The set `s` needs to be initialized."
+  assert other.isValid, "The set `other` needs to be initialized."
   for item in other: excl(s, item)
 
 proc containsOrIncl*[A](s: var TSet[A], key: A): bool =
-  ## returns true if `s` contains `key`, otherwise `key` is included in `s`
-  ## and false is returned.
+  ## Includes `key` in the set `s` and tells if `key` was added to `s`.
+  ##
+  ## The difference with regards to the `incl() <#incl,TSet[A],A>`_ proc is
+  ## that this proc returns `true` if `key` was already present in `s`. The
+  ## proc will return false if `key` was added as a new value to `s` during
+  ## this call. Example:
+  ##
+  ## .. code-block::
+  ##   var values = initSet[int]()
+  ##   assert values.containsOrIncl(2) == false
+  ##   assert values.containsOrIncl(2) == true
+  assert s.isValid, "The set needs to be initialized."
   containsOrInclImpl()
 
-proc initSet*[A](initialSize=64): TSet[A] =
-  ## creates a new hash set that is empty. `initialSize` needs to be
-  ## a power of two.
+proc init*[A](s: var TSet[A], initialSize=64) =
+  ## Initializes a hash set.
+  ##
+  ## The `initialSize` parameter needs to be a power of too. You can use
+  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ to guarantee that at
+  ## runtime. All set variables have to be initialized before you can use them
+  ## with other procs from this module with the exception of `isValid()
+  ## <#isValid,TSet[A]>`_ and `len() <#len,TSet[A]>`_.
+  ##
+  ## You can call this proc on a previously initialized hash set, which will
+  ## discard all its values. This might be more convenient than iterating over
+  ## existing values and calling `excl() <#excl,TSet[A],A>`_ on them. Example:
+  ##
+  ## .. code-block ::
+  ##   var a: TSet[int]
+  ##   a.init(4)
+  ##   a.incl(2)
+  ##   a.init
+  ##   assert a.len == 0 and a.isValid
   assert isPowerOfTwo(initialSize)
-  result.counter = 0
-  newSeq(result.data, initialSize)
+  s.counter = 0
+  newSeq(s.data, initialSize)
+
+proc initSet*[A](initialSize=64): TSet[A] =
+  ## Wrapper around `init() <#init,TSet[A],int>`_ for initialization of hash
+  ## sets.
+  ##
+  ## Returns an empty hash set you can assign directly in ``var`` blocks in a
+  ## single line. Example:
+  ##
+  ## .. code-block ::
+  ##   var a = initSet[int](4)
+  ##   a.incl(2)
+  result.init(initialSize)
 
 proc toSet*[A](keys: openArray[A]): TSet[A] =
-  ## creates a new hash set that contains the given `keys`.
+  ## Creates a new hash set that contains the given `keys`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var numbers = toSet([1, 2, 3, 4, 5])
+  ##   assert numbers.contains(2)
+  ##   assert numbers.contains(4)
   result = initSet[A](nextPowerOfTwo(keys.len+10))
   for key in items(keys): result.incl(key)
 
@@ -152,46 +303,190 @@ template dollarImpl(): stmt {.dirty.} =
   result.add("}")
 
 proc `$`*[A](s: TSet[A]): string =
-  ## The `$` operator for hash sets.
+  ## Converts the set `s` to a string, mostly for logging purposes.
+  ##
+  ## Don't use this proc for serialization, the representation may change at
+  ## any moment and values are not escaped. Example:
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   echo toSet([2, 4, 5])
+  ##   # --> {2, 4, 5}
+  ##   echo toSet(["no", "esc'aping", "is \" provided"])
+  ##   # --> {no, esc'aping, is " provided}
+  assert s.isValid, "The set needs to be initialized."
   dollarImpl()
 
 proc union*[A](s1, s2: TSet[A]): TSet[A] =
-  ## returns a new set of all items that are contained in at
-  ## least one of `s1` and `s2`
+  ## Returns the union of the sets `s1` and `s2`.
+  ##
+  ## The union of two sets is represented mathematically as *A ∪ B* and is the
+  ## set of all objects that are members of `s1`, `s2` or both. Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = union(a, b)
+  ##   assert c == toSet(["a", "b", "c"])
+  assert s1.isValid, "The set `s1` needs to be initialized."
+  assert s2.isValid, "The set `s2` needs to be initialized."
   result = s1
   incl(result, s2)
 
 proc intersection*[A](s1, s2: TSet[A]): TSet[A] =
-  ## returns a new set of all items that are contained in both `s1` and `s2`
+  ## Returns the intersection of the sets `s1` and `s2`.
+  ##
+  ## The intersection of two sets is represented mathematically as *A ∩ B* and
+  ## is the set of all objects that are members of `s1` and `s2` at the same
+  ## time. Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = intersection(a, b)
+  ##   assert c == toSet(["b"])
+  assert s1.isValid, "The set `s1` needs to be initialized."
+  assert s2.isValid, "The set `s2` needs to be initialized."
   result = initSet[A](min(s1.data.len, s2.data.len))
   for item in s1:
     if item in s2: incl(result, item)
 
+proc difference*[A](s1, s2: TSet[A]): TSet[A] =
+  ## Returns the difference of the sets `s1` and `s2`.
+  ##
+  ## The difference of two sets is represented mathematically as *A \ B* and is
+  ## the set of all objects that are members of `s1` and not members of `s2`.
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = difference(a, b)
+  ##   assert c == toSet(["a"])
+  assert s1.isValid, "The set `s1` needs to be initialized."
+  assert s2.isValid, "The set `s2` needs to be initialized."
+  result = initSet[A]()
+  for item in s1:
+    if not contains(s2, item):
+      incl(result, item)
+
 proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] =
-  ## returns a new set of all items that are contained in either
-  ## `s1` or `s2`, but not both
+  ## Returns the symmetric difference of the sets `s1` and `s2`.
+  ##
+  ## The symmetric difference of two sets is represented mathematically as *A â–³
+  ## B* or *A ⊖ B* and is the set of all objects that are members of `s1` or
+  ## `s2` but not both at the same time. Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = symmetricDifference(a, b)
+  ##   assert c == toSet(["a", "c"])
+  assert s1.isValid, "The set `s1` needs to be initialized."
+  assert s2.isValid, "The set `s2` needs to be initialized."
   result = s1
   for item in s2:
     if containsOrIncl(result, item): excl(result, item)
 
 proc `+`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
-  ## alias for `union`
+  ## Alias for `union(s1, s2) <#union>`_.
   result = union(s1, s2)
 
 proc `*`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
-  ## alias for `intersection`
+  ## Alias for `intersection(s1, s2) <#intersection>`_.
   result = intersection(s1, s2)
 
+proc `-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
+  ## Alias for `difference(s1, s2) <#difference>`_.
+  result = difference(s1, s2)
+
 proc `-+-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
-  ## alias for `symmetricDifference`
+  ## Alias for `symmetricDifference(s1, s2) <#symmetricDifference>`_.
   result = symmetricDifference(s1, s2)
 
 proc disjoint*[A](s1, s2: TSet[A]): bool =
-  ## returns true iff `s1` and `s2` have no items in common
+  ## Returns true iff the sets `s1` and `s2` have no items in common.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##   assert disjoint(a, b) == false
+  ##   assert disjoint(a, b - a) == true
+  assert s1.isValid, "The set `s1` needs to be initialized."
+  assert s2.isValid, "The set `s2` needs to be initialized."
   for item in s1:
     if item in s2: return false
   return true
 
+proc `<`*[A](s, t: TSet[A]): bool =
+  ## Returns true if `s` is a strict or proper subset of `t`.
+  ##
+  ## A strict or proper subset `s` has all of its members in `t` but `t` has
+  ## more elements than `s`. Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = intersection(a, b)
+  ##   assert c < a and c < b
+  ##   assert((a < a) == false)
+  s.counter != t.counter and s <= t
+
+proc `<=`*[A](s, t: TSet[A]): bool =
+  ## Returns true if `s` is subset of `t`.
+  ##
+  ## A subset `s` has all of its members in `t` and `t` doesn't necessarily
+  ## have more members than `s`. That is, `s` can be equal to `t`. Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet(["a", "b"])
+  ##     b = toSet(["b", "c"])
+  ##     c = intersection(a, b)
+  ##   assert c <= a and c <= b
+  ##   assert((a <= a))
+  result = false
+  if s.counter > t.counter: return
+  result = true
+  for item in s:
+    if not(t.contains(item)):
+      result = false
+      return
+
+proc `==`*[A](s, t: TSet[A]): bool =
+  ## Returns true if both `s` and `t` have the same members and set size.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var
+  ##     a = toSet([1, 2])
+  ##     b = toSet([1])
+  ##   b.incl(2)
+  ##   assert a == b
+  s.counter == t.counter and s <= t
+
+proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] =
+  ## Returns a new set after applying `op` on each of the elements of `data`.
+  ##
+  ## You can use this proc to transform the elements from a set. Example:
+  ##
+  ## .. code-block::
+  ##   var a = toSet([1, 2, 3])
+  ##   var b = a.map(proc (x: int): string = $x)
+  ##   assert b == toSet(["1", "2", "3"])
+  result = initSet[B]()
+  for item in data: result.incl(op(item))
+
 # ------------------------------ ordered set ------------------------------
 
 type
@@ -199,16 +494,48 @@ type
     slot: TSlotEnum, next: int, key: A]
   TOrderedKeyValuePairSeq[A] = seq[TOrderedKeyValuePair[A]]
   TOrderedSet* {.
-      final, myShallow.}[A] = object ## set that remembers insertion order
+      final, myShallow.}[A] = object ## \
+    ## A generic hash set that remembers insertion order.
+    ##
+    ## Use `init() <#init,TOrderedSet[A],int>`_ or `initOrderedSet[type]()
+    ## <#initOrderedSet>`_ before calling other procs on it.
     data: TOrderedKeyValuePairSeq[A]
     counter, first, last: int
 
+proc isValid*[A](s: TOrderedSet[A]): bool =
+  ## Returns `true` if the ordered set has been initialized with `initSet
+  ## <#initOrderedSet>`_.
+  ##
+  ## Most operations over an uninitialized ordered set will crash at runtime
+  ## and `assert <system.html#assert>`_ in debug builds. You can use this proc
+  ## in your own procs to verify that ordered sets passed to your procs are
+  ## correctly initialized. Example:
+  ##
+  ## .. code-block :: nimrod
+  ##   proc saveTarotCards(cards: TOrderedSet[int]) =
+  ##     assert cards.isValid, "Pass an initialized set!"
+  ##     # Do stuff here, may crash in release builds!
+  result = not s.data.isNil
+
 proc len*[A](s: TOrderedSet[A]): int {.inline.} =
-  ## returns the number of keys in `s`.
+  ## Returns the number of keys in `s`.
+  ##
+  ## Due to an implementation detail you can call this proc on variables which
+  ## have not been initialized yet. The proc will return zero as the length
+  ## then. Example:
+  ##
+  ## .. code-block::
+  ##
+  ##   var values: TOrderedSet[int]
+  ##   assert(not values.isValid)
+  ##   assert values.len == 0
   result = s.counter
 
 proc card*[A](s: TOrderedSet[A]): int {.inline.} =
-  ## alias for `len`.
+  ## Alias for `len() <#len,TOrderedSet[A]>`_.
+  ##
+  ## Card stands for the `cardinality
+  ## <http://en.wikipedia.org/wiki/Cardinality>`_ of a set.
   result = s.counter
 
 template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
@@ -219,7 +546,24 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
     h = nxt
 
 iterator items*[A](s: TOrderedSet[A]): A =
-  ## iterates over any key in the set `s` in insertion order.
+  ## Iterates over keys in the ordered set `s` in insertion order.
+  ##
+  ## If you need a sequence with the keys you can use `sequtils.toSeq()
+  ## <sequtils.html#toSeq>`_ on the iterator. Usage example:
+  ##
+  ## .. code-block::
+  ##   var a = initOrderedSet[int]()
+  ##   for value in [9, 2, 1, 5, 1, 8, 4, 2]:
+  ##     a.incl(value)
+  ##   for value in a.items:
+  ##     echo "Got ", value
+  ##   # --> Got 9
+  ##   # --> Got 2
+  ##   # --> Got 1
+  ##   # --> Got 5
+  ##   # --> Got 8
+  ##   # --> Got 4
+  assert s.isValid, "The set needs to be initialized."
   forAllOrderedPairs:
     yield s.data[h].key
 
@@ -227,7 +571,16 @@ proc rawGet[A](s: TOrderedSet[A], key: A): int =
   rawGetImpl()
 
 proc contains*[A](s: TOrderedSet[A], key: A): bool =
-  ## returns true iff `key` is in `s`.
+  ## Returns true iff `key` is in `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var values = initOrderedSet[int]()
+  ##   assert(not values.contains(2))
+  ##   values.incl(2)
+  ##   assert values.contains(2)
+  assert s.isValid, "The set needs to be initialized."
   var index = rawGet(s, key)
   result = index >= 0
 
@@ -253,53 +606,279 @@ proc enlarge[A](s: var TOrderedSet[A]) =
   swap(s.data, n)
 
 proc incl*[A](s: var TOrderedSet[A], key: A) =
-  ## includes an element `key` in `s`.
+  ## Includes an element `key` in `s`.
+  ##
+  ## This doesn't do anything if `key` is already in `s`. Example:
+  ##
+  ## .. code-block::
+  ##   var values = initOrderedSet[int]()
+  ##   values.incl(2)
+  ##   values.incl(2)
+  ##   assert values.len == 1
+  assert s.isValid, "The set needs to be initialized."
   inclImpl()
 
 proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) =
-  ## includes everything in `other` in `s`
+  ## Includes all elements from `other` into `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var values = initOrderedSet[int]()
+  ##   values.incl(2)
+  ##   var others = toOrderedSet([6, 7])
+  ##   values.incl(others)
+  ##   assert values.len == 3
+  assert s.isValid, "The set `s` needs to be initialized."
+  assert other.isValid, "The set `other` needs to be initialized."
   for item in other: incl(s, item)
 
 proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool =
-  ## returns true if `s` contains `key`, otherwise `key` is included in `s`
-  ## and false is returned.
+  ## Includes `key` in the set `s` and tells if `key` was added to `s`.
+  ##
+  ## The difference with regards to the `incl() <#incl,TOrderedSet[A],A>`_ proc
+  ## is that this proc returns `true` if `key` was already present in `s`. The
+  ## proc will return false if `key` was added as a new value to `s` during
+  ## this call. Example:
+  ##
+  ## .. code-block::
+  ##   var values = initOrderedSet[int]()
+  ##   assert values.containsOrIncl(2) == false
+  ##   assert values.containsOrIncl(2) == true
+  assert s.isValid, "The set needs to be initialized."
   containsOrInclImpl()
 
-proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] =
-  ## creates a new ordered hash set that is empty. `initialSize` needs to be
-  ## a power of two.
+proc init*[A](s: var TOrderedSet[A], initialSize=64) =
+  ## Initializes an ordered hash set.
+  ##
+  ## The `initialSize` parameter needs to be a power of too. You can use
+  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ to guarantee that at
+  ## runtime. All set variables have to be initialized before you can use them
+  ## with other procs from this module with the exception of `isValid()
+  ## <#isValid,TOrderedSet[A]>`_ and `len() <#len,TOrderedSet[A]>`_.
+  ##
+  ## You can call this proc on a previously initialized ordered hash set to
+  ## discard its values. At the moment this is the only proc to remove elements
+  ## from an ordered hash set. Example:
+  ##
+  ## .. code-block ::
+  ##   var a: TOrderedSet[int]
+  ##   a.init(4)
+  ##   a.incl(2)
+  ##   a.init
+  ##   assert a.len == 0 and a.isValid
   assert isPowerOfTwo(initialSize)
-  result.counter = 0
-  result.first = -1
-  result.last = -1
-  newSeq(result.data, initialSize)
+  s.counter = 0
+  s.first = -1
+  s.last = -1
+  newSeq(s.data, initialSize)
+
+proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] =
+  ## Wrapper around `init() <#init,TOrderedSet[A],int>`_ for initialization of
+  ## ordered hash sets.
+  ##
+  ## Returns an empty ordered hash set you can assign directly in ``var``
+  ## blocks in a single line. Example:
+  ##
+  ## .. code-block ::
+  ##   var a = initOrderedSet[int](4)
+  ##   a.incl(2)
+  result.init(initialSize)
 
 proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] =
-  ## creates a new ordered hash set that contains the given `keys`.
+  ## Creates a new ordered hash set that contains the given `keys`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   var numbers = toOrderedSet([1, 2, 3, 4, 5])
+  ##   assert numbers.contains(2)
+  ##   assert numbers.contains(4)
   result = initOrderedSet[A](nextPowerOfTwo(keys.len+10))
   for key in items(keys): result.incl(key)
 
 proc `$`*[A](s: TOrderedSet[A]): string =
-  ## The `$` operator for ordered hash sets.
+  ## Converts the ordered hash set `s` to a string, mostly for logging purposes.
+  ##
+  ## Don't use this proc for serialization, the representation may change at
+  ## any moment and values are not escaped. Example:
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   echo toOrderedSet([2, 4, 5])
+  ##   # --> {2, 4, 5}
+  ##   echo toOrderedSet(["no", "esc'aping", "is \" provided"])
+  ##   # --> {no, esc'aping, is " provided}
+  assert s.isValid, "The set needs to be initialized."
   dollarImpl()
 
-proc `<`*[A](s, t: TSet[A]): bool =
-  ## Is s a strict subset of t?
-  s.counter != t.counter and s <= t
-
-proc `<=`*[A](s, t: TSet[A]): bool =
-  ## Is s a subset of t?
-  result = false
-  if s.counter > t.counter: return
-  result = true
-  for item in s:
-    if not(t.contains(item)):
-      result = false
-      return
-      
-proc `==`*[A](s, t: TSet[A]): bool =
-  s.counter == t.counter and s <= t
-
-proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] =
-  result = initSet[B]()
-  for item in data: result.incl(op(item))
+proc testModule() =
+  ## Internal micro test to validate docstrings and such.
+  block isValidTest:
+    var options: TSet[string]
+    proc savePreferences(options: TSet[string]) =
+      assert options.isValid, "Pass an initialized set!"
+    options = initSet[string]()
+    options.savePreferences
+
+  block lenTest:
+    var values: TSet[int]
+    assert(not values.isValid)
+    assert values.len == 0
+    assert values.card == 0
+
+  block setIterator:
+    type pair = tuple[a, b: int]
+    var a, b = initSet[pair]()
+    a.incl((2, 3))
+    a.incl((3, 2))
+    a.incl((2, 3))
+    for x, y in a.items:
+      b.incl((x - 2, y + 1))
+    assert a.len == b.card
+    assert a.len == 2
+    #echo b
+
+  block setContains:
+    var values = initSet[int]()
+    assert(not values.contains(2))
+    values.incl(2)
+    assert values.contains(2)
+    values.excl(2)
+    assert(not values.contains(2))
+
+    values.incl(4)
+    var others = toSet([6, 7])
+    values.incl(others)
+    assert values.len == 3
+
+    values.init
+    assert values.containsOrIncl(2) == false
+    assert values.containsOrIncl(2) == true
+    var
+      a = toSet([1, 2])
+      b = toSet([1])
+    b.incl(2)
+    assert a == b
+
+  block exclusions:
+    var s = toSet([2, 3, 6, 7])
+    s.excl(2)
+    s.excl(2)
+    assert s.len == 3
+
+    var
+      numbers = toSet([1, 2, 3, 4, 5])
+      even = toSet([2, 4, 6, 8])
+    numbers.excl(even)
+    #echo numbers
+    # --> {1, 3, 5}
+
+  block toSeqAndString:
+    var a = toSet([2, 4, 5])
+    var b = initSet[int]()
+    for x in [2, 4, 5]: b.incl(x)
+    assert($a == $b)
+    #echo a
+    #echo toSet(["no", "esc'aping", "is \" provided"])
+
+  #block orderedToSeqAndString:
+  #  echo toOrderedSet([2, 4, 5])
+  #  echo toOrderedSet(["no", "esc'aping", "is \" provided"])
+
+  block setOperations:
+    var
+      a = toSet(["a", "b"])
+      b = toSet(["b", "c"])
+      c = union(a, b)
+    assert c == toSet(["a", "b", "c"])
+    var d = intersection(a, b)
+    assert d == toSet(["b"])
+    var e = difference(a, b)
+    assert e == toSet(["a"])
+    var f = symmetricDifference(a, b)
+    assert f == toSet(["a", "c"])
+    assert d < a and d < b
+    assert((a < a) == false)
+    assert d <= a and d <= b
+    assert((a <= a))
+    # Alias test.
+    assert a + b == toSet(["a", "b", "c"])
+    assert a * b == toSet(["b"])
+    assert a - b == toSet(["a"])
+    assert a -+- b == toSet(["a", "c"])
+    assert disjoint(a, b) == false
+    assert disjoint(a, b - a) == true
+
+  block mapSet:
+    var a = toSet([1, 2, 3])
+    var b = a.map(proc (x: int): string = $x)
+    assert b == toSet(["1", "2", "3"])
+
+  block isValidTest:
+    var cards: TOrderedSet[string]
+    proc saveTarotCards(cards: TOrderedSet[string]) =
+      assert cards.isValid, "Pass an initialized set!"
+    cards = initOrderedSet[string]()
+    cards.saveTarotCards
+
+  block lenTest:
+    var values: TOrderedSet[int]
+    assert(not values.isValid)
+    assert values.len == 0
+    assert values.card == 0
+
+  block setIterator:
+    type pair = tuple[a, b: int]
+    var a, b = initOrderedSet[pair]()
+    a.incl((2, 3))
+    a.incl((3, 2))
+    a.incl((2, 3))
+    for x, y in a.items:
+      b.incl((x - 2, y + 1))
+    assert a.len == b.card
+    assert a.len == 2
+
+  #block orderedSetIterator:
+  #  var a = initOrderedSet[int]()
+  #  for value in [9, 2, 1, 5, 1, 8, 4, 2]:
+  #    a.incl(value)
+  #  for value in a.items:
+  #    echo "Got ", value
+
+  block setContains:
+    var values = initOrderedSet[int]()
+    assert(not values.contains(2))
+    values.incl(2)
+    assert values.contains(2)
+
+  block toSeqAndString:
+    var a = toOrderedSet([2, 4, 5])
+    var b = initOrderedSet[int]()
+    for x in [2, 4, 5]: b.incl(x)
+    assert($a == $b)
+    # assert(a == b) # https://github.com/Araq/Nimrod/issues/1413
+
+  block initBlocks:
+    var a: TOrderedSet[int]
+    a.init(4)
+    a.incl(2)
+    a.init
+    assert a.len == 0 and a.isValid
+    a = initOrderedSet[int](4)
+    a.incl(2)
+    assert a.len == 1
+
+    var b: TSet[int]
+    b.init(4)
+    b.incl(2)
+    b.init
+    assert b.len == 0 and b.isValid
+    b = initSet[int](4)
+    b.incl(2)
+    assert b.len == 1
+
+  echo "Micro tests run successfully."
+
+when isMainModule and not defined(release): testModule()
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index ce9df09e1..dcf2ab481 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -246,7 +246,8 @@ template equalsImpl() =
     # different insertion orders mean different 'data' seqs, so we have
     # to use the slow route here:
     for key, val in s:
-      if not hasKey(t, key): return false
+      # prefix notation leads to automatic dereference in case of PTable
+      if not t.hasKey(key): return false
       if t[key] != val: return false
     return true
   
@@ -332,7 +333,9 @@ proc `$`*[A, B](t: PTable[A, B]): string =
   dollarImpl()
 
 proc `==`*[A, B](s, t: PTable[A, B]): bool =
-  equalsImpl()
+  if isNil(s): result = isNil(t)
+  elif isNil(t): result = false
+  else: result = equalsImpl()
 
 proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): PTable[C, B] =
   ## Index the collection with the proc provided.
diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim
index df08ace72..1392b73aa 100644
--- a/lib/pure/complex.nim
+++ b/lib/pure/complex.nim
@@ -113,6 +113,45 @@ proc `*` *(x: TComplex, y: float): TComplex =
   result.im = x.im * y
 
 
+proc `+=` *(x: var TComplex, y: TComplex) =
+  ## Add `y` to `x`.
+  x.re += y.re
+  x.im += y.im
+
+proc `+=` *(x: var TComplex, y: float) =
+  ## Add `y` to the complex number `x`.
+  x.re += y
+
+proc `-=` *(x: var TComplex, y: TComplex) =
+  ## Subtract `y` from `x`.
+  x.re -= y.re
+  x.im -= y.im
+
+proc `-=` *(x: var TComplex, y: float) =
+  ## Subtract `y` from the complex number `x`.
+  x.re -= y
+
+proc `*=` *(x: var TComplex, y: TComplex) =
+  ## Multiply `y` to `x`.
+  let im = x.im * y.re + x.re * y.im
+  x.re = x.re * y.re - x.im * y.im
+  x.im = im
+
+proc `*=` *(x: var TComplex, y: float) =
+  ## Multiply `y` to the complex number `x`.
+  x.re *= y
+  x.im *= y
+
+proc `/=` *(x: var TComplex, y: TComplex) =
+  ## Divide `x` by `y` in place.
+  x = x / y
+
+proc `/=` *(x : var TComplex, y: float) =
+  ## Divide complex `x` by float `y` in place.
+  x.re /= y
+  x.im /= y
+
+
 proc abs*(z: TComplex): float =
   ## Return the distance from (0,0) to `z`.
 
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index fd1041918..e0a2ac678 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -9,6 +9,9 @@
 
 ## Implements Nimrod's 'spawn'.
 
+when not compileOption("threads"):
+  {.error: "Threadpool requires --threads:on option.".}
+
 import cpuinfo, cpuload, locks
 
 {.push stackTrace:off.}
@@ -134,7 +137,7 @@ proc await*(fv: FlowVarBase) =
 proc finished(fv: FlowVarBase) =
   doAssert fv.ai.isNil, "flowVar is still attached to an 'awaitAny'"
   # we have to protect against the rare cases where the owner of the flowVar
-  # simply disregards the flowVar and yet the "flowVarr" has not yet written
+  # simply disregards the flowVar and yet the "flowVar" has not yet written
   # anything to it:
   await(fv)
   if fv.data.isNil: return
@@ -207,6 +210,7 @@ proc `^`*[T](fv: FlowVar[T]): T =
   ## blocks until the value is available and then returns this value.
   await(fv)
   when T is string or T is seq:
+    # XXX closures? deepCopy?
     result = cast[T](fv.data)
   else:
     result = fv.blob
@@ -264,6 +268,10 @@ proc slave(w: ptr Worker) {.thread.} =
       w.shutdown = false
       atomicDec currentPoolSize
 
+var
+  workers: array[MaxThreadPoolSize, TThread[ptr Worker]]
+  workersData: array[MaxThreadPoolSize, Worker]
+
 proc setMinPoolSize*(size: range[1..MaxThreadPoolSize]) =
   ## sets the minimal thread pool size. The default value of this is 4.
   minPoolSize = size
@@ -272,10 +280,10 @@ proc setMaxPoolSize*(size: range[1..MaxThreadPoolSize]) =
   ## sets the minimal thread pool size. The default value of this
   ## is ``MaxThreadPoolSize``.
   maxPoolSize = size
-
-var
-  workers: array[MaxThreadPoolSize, TThread[ptr Worker]]
-  workersData: array[MaxThreadPoolSize, Worker]
+  if currentPoolSize > maxPoolSize:
+    for i in maxPoolSize..currentPoolSize-1:
+      let w = addr(workersData[i])
+      w.shutdown = true
 
 proc activateThread(i: int) {.noinline.} =
   workersData[i].taskArrived = createCondVar()
diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim
index 94d21ed4e..633ea6020 100644
--- a/lib/pure/encodings.nim
+++ b/lib/pure/encodings.nim
@@ -41,6 +41,7 @@ when defined(windows):
 
   const 
     winEncodings = [
+      (1,   "OEMCP"), # current OEM codepage
       (037, "IBM037"), # IBM EBCDIC US-Canada 
       (437, "IBM437"), # OEM United States 
       (500, "IBM500"), # IBM EBCDIC International 
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 508e564c5..a45900f29 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -621,9 +621,13 @@ proc `%`*(elements: openArray[PJsonNode]): PJsonNode =
 
 proc `==`* (a,b: PJsonNode): bool =
   ## Check two nodes for equality
-  if a.kind != b.kind: false
+  if a.isNil:
+    if b.isNil: return true
+    return false
+  elif b.isNil or a.kind != b.kind: 
+    return false
   else:
-    case a.kind
+    return case a.kind
     of JString:
       a.str == b.str
     of JInt:
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 0b4538abc..44673d3e0 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -955,11 +955,12 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
   ##
   ## If this fails, `EOS` is raised. On the Windows platform this proc will
   ## copy the source file's attributes into dest. On other platforms you need
-  ## to use getFilePermissions and setFilePermissions to copy them by hand (or
-  ## use the convenience copyFileWithPermissions() proc), otherwise `dest` will
-  ## inherit the default permissions of a newly created file for the user. If
-  ## `dest` already exists, the file attributes will be preserved and the
-  ## content overwritten.
+  ## to use `getFilePermissions() <#getFilePermissions>`_ and
+  ## `setFilePermissions() <#setFilePermissions>`_ to copy them by hand (or use
+  ## the convenience `copyFileWithPermissions() <#copyFileWithPermissions>`_
+  ## proc), otherwise `dest` will inherit the default permissions of a newly
+  ## created file for the user. If `dest` already exists, the file attributes
+  ## will be preserved and the content overwritten.
   when defined(Windows):
     when useWinUnicode:
       let s = newWideCString(source)
@@ -1363,7 +1364,13 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
 
 proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
   tags: [FWriteIO, FReadIO].} =
-  ## Copies a directory from `source` to `dest`. If this fails, `EOS` is raised.
+  ## Copies a directory from `source` to `dest`.
+  ##
+  ## If this fails, `EOS` is raised. On the Windows platform this proc will
+  ## copy the attributes from `source` into `dest`. On other platforms created
+  ## files and directories will inherit the default permissions of a newly
+  ## created file/directory for the user. To preserve attributes recursively on
+  ## these platforms use `copyDirWithPermissions() <#copyDirWithPermissions>`_.
   createDir(dest)
   for kind, path in walkDir(source):
     var noSource = path.substr(source.len()+1)
@@ -1450,7 +1457,8 @@ proc parseCmdLine*(c: string): seq[string] {.
   var a = ""
   while true:
     setLen(a, 0)
-    while c[i] == ' ' or c[i] == '\t': inc(i)
+    # eat all delimiting whitespace
+    while c[i] == ' ' or c[i] == '\t' or c [i] == '\l' or c [i] == '\r' : inc(i)
     when defined(windows):
       # parse a single argument according to the above rules:
       if c[i] == '\0': break
@@ -1507,14 +1515,17 @@ proc copyFileWithPermissions*(source, dest: string,
                               ignorePermissionErrors = true) =
   ## Copies a file from `source` to `dest` preserving file permissions.
   ##
-  ## This is a wrapper proc around copyFile, getFilePermissions and
-  ## setFilePermissions on non Windows platform. On windows this proc is just a
-  ## wrapper for copyFile since that proc already copies attributes.
+  ## This is a wrapper proc around `copyFile() <#copyFile>`_,
+  ## `getFilePermissions() <#getFilePermissions>`_ and `setFilePermissions()
+  ## <#setFilePermissions>`_ on non Windows platform. On Windows this proc is
+  ## just a wrapper for `copyFile() <#copyFile>`_ since that proc already
+  ## copies attributes.
   ##
-  ## On non windows systems permissions are copied after the file itself has
+  ## On non Windows systems permissions are copied after the file itself has
   ## been copied, which won't happen atomically and could lead to a race
-  ## condition. If ignorePermissionErrors is true, errors while reading/setting
-  ## file attributes will be ignored, otherwise will raise `OSError`.
+  ## condition. If `ignorePermissionErrors` is true, errors while
+  ## reading/setting file attributes will be ignored, otherwise will raise
+  ## `OSError`.
   copyFile(source, dest)
   when not defined(Windows):
     try:
@@ -1523,6 +1534,37 @@ proc copyFileWithPermissions*(source, dest: string,
       if not ignorePermissionErrors:
         raise
 
+proc copyDirWithPermissions*(source, dest: string,
+    ignorePermissionErrors = true) {.rtl, extern: "nos$1",
+    tags: [FWriteIO, FReadIO].} =
+  ## Copies a directory from `source` to `dest` preserving file permissions.
+  ##
+  ## If this fails, `EOS` is raised. This is a wrapper proc around `copyDir()
+  ## <#copyDir>`_ and `copyFileWithPermissions() <#copyFileWithPermissions>`_
+  ## on non Windows platforms. On Windows this proc is just a wrapper for
+  ## `copyDir() <#copyDir>`_ since that proc already copies attributes.
+  ##
+  ## On non Windows systems permissions are copied after the file or directory
+  ## itself has been copied, which won't happen atomically and could lead to a
+  ## race condition. If `ignorePermissionErrors` is true, errors while
+  ## reading/setting file attributes will be ignored, otherwise will raise
+  ## `OSError`.
+  createDir(dest)
+  when not defined(Windows):
+    try:
+      setFilePermissions(dest, getFilePermissions(source))
+    except:
+      if not ignorePermissionErrors:
+        raise
+  for kind, path in walkDir(source):
+    var noSource = path.substr(source.len()+1)
+    case kind
+    of pcFile:
+      copyFileWithPermissions(path, dest / noSource, ignorePermissionErrors)
+    of pcDir:
+      copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors)
+    else: discard
+
 proc inclFilePermissions*(filename: string,
                           permissions: set[TFilePermission]) {.
   rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} =
@@ -1560,7 +1602,52 @@ proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} =
   when defined(windows): return string(getEnv("TEMP")) & "\\"
   else: return "/tmp/"
 
-when defined(windows):
+when defined(nimdoc):
+  # Common forward declaration docstring block for parameter retrieval procs.
+  proc paramCount*(): int {.tags: [FReadIO].} =
+    ## Returns the number of `command line arguments`:idx: given to the
+    ## application.
+    ##
+    ## If your binary was called without parameters this will return zero.  You
+    ## can later query each individual paramater with `paramStr() <#paramStr>`_
+    ## or retrieve all of them in one go with `commandLineParams()
+    ## <#commandLineParams>`_.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(paramCount):
+    ##     # Use paramCount() here
+    ##   else:
+    ##     # Do something else!
+
+  proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} =
+    ## Returns the `i`-th `command line argument`:idx: given to the application.
+    ##
+    ## `i` should be in the range `1..paramCount()`, the `EInvalidIndex`
+    ## exception will be raised for invalid values.  Instead of iterating over
+    ## `paramCount() <#paramCount>`_ with this proc you can call the
+    ## convenience `commandLineParams() <#commandLineParams>`_.
+    ##
+    ## It is possible to call ``paramStr(0)`` but this will return OS specific
+    ## contents (usually the name of the invoked executable). You should avoid
+    ## this and call `getAppFilename() <#getAppFilename>`_ instead.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(paramStr):
+    ##     # Use paramStr() here
+    ##   else:
+    ##     # Do something else!
+
+elif defined(windows):
   # Since we support GUI applications with Nimrod, we sometimes generate
   # a WinMain entry proc. But a WinMain proc has no access to the parsed
   # command line arguments. The way to get them differs. Thus we parse them
@@ -1570,18 +1657,13 @@ when defined(windows):
     ownArgv {.threadvar.}: seq[string]
 
   proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} =
-    ## Returns the number of `command line arguments`:idx: given to the
-    ## application.
+    # Docstring in nimdoc block.
     if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
     result = ownArgv.len-1
 
   proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1",
     tags: [FReadIO].} =
-    ## Returns the `i`-th `command line argument`:idx: given to the
-    ## application.
-    ##
-    ## `i` should be in the range `1..paramCount()`, else
-    ## the `EOutOfIndex` exception is raised.
+    # Docstring in nimdoc block.
     if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
     return TaintedString(ownArgv[i])
 
@@ -1592,13 +1674,31 @@ elif not defined(createNimRtl):
     cmdLine {.importc: "cmdLine".}: cstringArray
 
   proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} =
+    # Docstring in nimdoc block.
     if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
     raise newException(EInvalidIndex, "invalid index")
 
-  proc paramCount*(): int {.tags: [FReadIO].} = return cmdCount-1
+  proc paramCount*(): int {.tags: [FReadIO].} =
+    # Docstring in nimdoc block.
+    result = cmdCount-1
 
-when defined(paramCount):
+when defined(paramCount) or defined(nimdoc):
   proc commandLineParams*(): seq[TaintedString] =
+    ## Convenience proc which returns the command line parameters.
+    ##
+    ## This returns **only** the parameters. If you want to get the application
+    ## executable filename, call `getAppFilename() <#getAppFilename>`_.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(commandLineParams):
+    ##     # Use commandLineParams() here
+    ##   else:
+    ##     # Do something else!
     result = @[]
     for i in 1..paramCount():
       result.add(paramStr(i))
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 04a0c2403..c74fa1ceb 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -763,7 +763,7 @@ elif not defined(useNimRtl):
     discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
     exitnow(1)
 
-  when defined(macosx):
+  when defined(macosx) or defined(freebsd):
     var environ {.importc.}: cstringArray
 
   proc startProcessAfterFork(data: ptr TStartProcessData) =
@@ -793,7 +793,7 @@ elif not defined(useNimRtl):
     discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC)
 
     if data.optionPoUsePath:
-      when defined(macosx):
+      when defined(macosx) or defined(freebsd):
         # MacOSX doesn't have execvpe, so we need workaround.
         # On MacOSX we can arrive here only from fork, so this is safe:
         environ = data.sysEnv
diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim
index 727a8efd8..1d61a967b 100644
--- a/lib/pure/parsecfg.nim
+++ b/lib/pure/parsecfg.nim
@@ -350,7 +350,8 @@ proc next*(c: var TCfgParser): TCfgEvent {.rtl, extern: "npc$1".} =
     rawGetTok(c, c.tok)
     if c.tok.kind == tkBracketRi: 
       rawGetTok(c, c.tok)
-    else: 
+    else:
+      reset(result)
       result.kind = cfgError
       result.msg = errorStr(c, "']' expected, but found: " & c.tok.literal)
   of tkInvalid, tkEquals, tkColon, tkBracketRi: 
diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim
index 357d1df0f..67c6de905 100644
--- a/lib/pure/parseurl.nim
+++ b/lib/pure/parseurl.nim
@@ -20,7 +20,7 @@ type
     scheme, username, password, 
     hostname, port, path, query, anchor: string]
     
-proc parseUrl*(url: string): TUrl =
+proc parseUrl*(url: string): TUrl {.deprecated.} =
   var i = 0
 
   var scheme, username, password: string = ""
@@ -86,7 +86,7 @@ proc parseUrl*(url: string): TUrl =
     
   return (scheme, username, password, hostname, port, path, query, anchor)
 
-proc `$`*(u: TUrl): string =
+proc `$`*(u: TUrl): string {.deprecated.} =
   ## turns the URL `u` into its string representation.
   result = ""
   if u.scheme.len > 0:
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 484ba5184..06ee07aa8 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -231,88 +231,96 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
   else:
     number = int(res)
 
-proc tenToThePowerOf(b: int): BiggestFloat =
-  var b = b
-  var a = 10.0
-  result = 1.0
-  while true:
-    if (b and 1) == 1:
-      result *= a
-    b = b shr 1
-    if b == 0: break
-    a *= a
+when defined(nimParseBiggestFloatMagic):
+  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
+    magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.}
+    ## parses a float starting at `start` and stores the value into `number`.
+    ## Result is the number of processed chars or 0 if a parsing error
+    ## occurred.
+else:
+  proc tenToThePowerOf(b: int): BiggestFloat =
+    var b = b
+    var a = 10.0
+    result = 1.0
+    while true:
+      if (b and 1) == 1:
+        result *= a
+      b = b shr 1
+      if b == 0: break
+      a *= a
 
-proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
-  rtl, extern: "npuParseBiggestFloat", noSideEffect.} =
-  ## parses a float starting at `start` and stores the value into `number`.
-  ## Result is the number of processed chars or 0 if there occured a parsing
-  ## error.
-  var
-    esign = 1.0
-    sign = 1.0
-    i = start
-    exponent: int
-    flags: int
-  number = 0.0
-  if s[i] == '+': inc(i)
-  elif s[i] == '-':
-    sign = -1.0
-    inc(i)
-  if s[i] == 'N' or s[i] == 'n':
-    if s[i+1] == 'A' or s[i+1] == 'a':
-      if s[i+2] == 'N' or s[i+2] == 'n':
-        if s[i+3] notin IdentChars:
-          number = NaN
-          return i+3 - start
-    return 0
-  if s[i] == 'I' or s[i] == 'i':
-    if s[i+1] == 'N' or s[i+1] == 'n':
-      if s[i+2] == 'F' or s[i+2] == 'f':
-        if s[i+3] notin IdentChars: 
-          number = Inf*sign
-          return i+3 - start
-    return 0
-  while s[i] in {'0'..'9'}:
-    # Read integer part
-    flags = flags or 1
-    number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-    inc(i)
-    while s[i] == '_': inc(i)
-  # Decimal?
-  if s[i] == '.':
-    var hd = 1.0
-    inc(i)
-    while s[i] in {'0'..'9'}:
-      # Read fractional part
-      flags = flags or 2
-      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-      hd = hd * 10.0
-      inc(i)
-      while s[i] == '_': inc(i)
-    number = number / hd # this complicated way preserves precision
-  # Again, read integer and fractional part
-  if flags == 0: return 0
-  # Exponent?
-  if s[i] in {'e', 'E'}:
-    inc(i)
-    if s[i] == '+':
-      inc(i)
+  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
+    rtl, extern: "npuParseBiggestFloat", noSideEffect.} =
+    ## parses a float starting at `start` and stores the value into `number`.
+    ## Result is the number of processed chars or 0 if there occured a parsing
+    ## error.
+    var
+      esign = 1.0
+      sign = 1.0
+      i = start
+      exponent: int
+      flags: int
+    number = 0.0
+    if s[i] == '+': inc(i)
     elif s[i] == '-':
-      esign = -1.0
+      sign = -1.0
       inc(i)
-    if s[i] notin {'0'..'9'}:
+    if s[i] == 'N' or s[i] == 'n':
+      if s[i+1] == 'A' or s[i+1] == 'a':
+        if s[i+2] == 'N' or s[i+2] == 'n':
+          if s[i+3] notin IdentChars:
+            number = NaN
+            return i+3 - start
+      return 0
+    if s[i] == 'I' or s[i] == 'i':
+      if s[i+1] == 'N' or s[i+1] == 'n':
+        if s[i+2] == 'F' or s[i+2] == 'f':
+          if s[i+3] notin IdentChars: 
+            number = Inf*sign
+            return i+3 - start
       return 0
     while s[i] in {'0'..'9'}:
-      exponent = exponent * 10 + ord(s[i]) - ord('0')
+      # Read integer part
+      flags = flags or 1
+      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
       inc(i)
       while s[i] == '_': inc(i)
-  # Calculate Exponent
-  let hd = tenToThePowerOf(exponent)
-  if esign > 0.0: number = number * hd
-  else:           number = number / hd
-  # evaluate sign
-  number = number * sign
-  result = i - start
+    # Decimal?
+    if s[i] == '.':
+      var hd = 1.0
+      inc(i)
+      while s[i] in {'0'..'9'}:
+        # Read fractional part
+        flags = flags or 2
+        number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
+        hd = hd * 10.0
+        inc(i)
+        while s[i] == '_': inc(i)
+      number = number / hd # this complicated way preserves precision
+    # Again, read integer and fractional part
+    if flags == 0: return 0
+    # Exponent?
+    if s[i] in {'e', 'E'}:
+      inc(i)
+      if s[i] == '+':
+        inc(i)
+      elif s[i] == '-':
+        esign = -1.0
+        inc(i)
+      if s[i] notin {'0'..'9'}:
+        return 0
+      while s[i] in {'0'..'9'}:
+        exponent = exponent * 10 + ord(s[i]) - ord('0')
+        inc(i)
+        while s[i] == '_': inc(i)
+    # Calculate Exponent
+    let hd = tenToThePowerOf(exponent)
+    if esign > 0.0: number = number * hd
+    else:           number = number / hd
+    # evaluate sign
+    number = number * sign
+    result = i - start
+
 
 proc parseFloat*(s: string, number: var float, start = 0): int {.
   rtl, extern: "npuParseFloat", noSideEffect.} =
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index e642f6a99..6f8924d83 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -48,9 +48,11 @@ const
     ## the set of characters a newline terminator can start with
 
   AllChars* = {'\x00'..'\xFF'}
-    ## A set with all the possible characters. Not very useful by its own, you
-    ## can use it to create *inverted* sets to make the ``find()`` proc find
-    ## **invalid** characters in strings. Example:
+    ## A set with all the possible characters.
+    ##
+    ## Not very useful by its own, you can use it to create *inverted* sets to
+    ## make the `find() proc <#find,string,set[char],int>`_ find **invalid**
+    ## characters in strings.  Example:
     ##
     ## .. code-block:: nimrod
     ##   let invalid = AllChars - Digits
@@ -59,8 +61,11 @@ const
 
 proc toLower*(c: char): char {.noSideEffect, procvar,
   rtl, extern: "nsuToLowerChar".} =
-  ## Converts `c` into lower case. This works only for the letters A-Z.
-  ## See `unicode.toLower` for a version that works for any Unicode character.
+  ## Converts `c` into lower case.
+  ##
+  ## This works only for the letters ``A-Z``. See `unicode.toLower
+  ## <unicode.html#toLower>`_ for a version that works for any Unicode
+  ## character.
   if c in {'A'..'Z'}:
     result = chr(ord(c) + (ord('a') - ord('A')))
   else:
@@ -68,16 +73,22 @@ proc toLower*(c: char): char {.noSideEffect, procvar,
 
 proc toLower*(s: string): string {.noSideEffect, procvar,
   rtl, extern: "nsuToLowerStr".} =
-  ## Converts `s` into lower case. This works only for the letters A-Z.
-  ## See `unicode.toLower` for a version that works for any Unicode character.
+  ## Converts `s` into lower case.
+  ##
+  ## This works only for the letters ``A-Z``. See `unicode.toLower
+  ## <unicode.html#toLower>`_ for a version that works for any Unicode
+  ## character.
   result = newString(len(s))
   for i in 0..len(s) - 1:
     result[i] = toLower(s[i])
 
 proc toUpper*(c: char): char {.noSideEffect, procvar,
   rtl, extern: "nsuToUpperChar".} =
-  ## Converts `c` into upper case. This works only for the letters a-z.
-  ## See `unicode.toUpper` for a version that works for any Unicode character.
+  ## Converts `c` into upper case.
+  ##
+  ## This works only for the letters ``A-Z``.  See `unicode.toUpper
+  ## <unicode.html#toUpper>`_ for a version that works for any Unicode
+  ## character.
   if c in {'a'..'z'}:
     result = chr(ord(c) - (ord('a') - ord('A')))
   else:
@@ -85,8 +96,11 @@ proc toUpper*(c: char): char {.noSideEffect, procvar,
 
 proc toUpper*(s: string): string {.noSideEffect, procvar,
   rtl, extern: "nsuToUpperStr".} =
-  ## Converts `s` into upper case. This works only for the letters a-z.
-  ## See `unicode.toUpper` for a version that works for any Unicode character.
+  ## Converts `s` into upper case.
+  ##
+  ## This works only for the letters ``A-Z``.  See `unicode.toUpper
+  ## <unicode.html#toUpper>`_ for a version that works for any Unicode
+  ## character.
   result = newString(len(s))
   for i in 0..len(s) - 1:
     result[i] = toUpper(s[i])
@@ -94,13 +108,16 @@ proc toUpper*(s: string): string {.noSideEffect, procvar,
 proc capitalize*(s: string): string {.noSideEffect, procvar,
   rtl, extern: "nsuCapitalize".} =
   ## Converts the first character of `s` into upper case.
-  ## This works only for the letters a-z.
+  ##
+  ## This works only for the letters ``A-Z``.
   result = toUpper(s[0]) & substr(s, 1)
 
 proc normalize*(s: string): string {.noSideEffect, procvar,
   rtl, extern: "nsuNormalize".} =
-  ## Normalizes the string `s`. That means to convert it to lower case and
-  ## remove any '_'. This is needed for Nimrod identifiers for example.
+  ## Normalizes the string `s`.
+  ##
+  ## That means to convert it to lower case and remove any '_'. This is needed
+  ## for Nimrod identifiers for example.
   result = newString(s.len)
   var j = 0
   for i in 0..len(s) - 1:
@@ -155,6 +172,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
 proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
   rtl, extern: "nsuStrip", operator: 5.} =
   ## Strips whitespace from `s` and returns the resulting string.
+  ##
   ## If `leading` is true, leading whitespace is stripped.
   ## If `trailing` is true, trailing whitespace is stripped.
   const
@@ -169,8 +187,10 @@ proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
   result = substr(s, first, last)
 
 proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} =
-  ## Converts a character `c` to its octal representation. The resulting
-  ## string may not have a leading zero. Its length is always exactly 3.
+  ## Converts a character `c` to its octal representation.
+  ##
+  ## The resulting string may not have a leading zero. Its length is always
+  ## exactly 3.
   result = newString(3)
   var val = ord(c)
   for i in countdown(2, 0):
@@ -280,9 +300,11 @@ iterator split*(s: string, sep: string): string =
       inc(last, sep.len)
 
 iterator splitLines*(s: string): string =
-  ## Splits the string `s` into its containing lines. Every newline
-  ## combination (CR, LF, CR-LF) is supported. The result strings contain
-  ## no trailing ``\n``.
+  ## Splits the string `s` into its containing lines.
+  ##
+  ## Every `character literal <manual.html#character-literals>`_ newline
+  ## combination (CR, LF, CR-LF) is supported. The result strings contain no
+  ## trailing ``\n``.
   ##
   ## Example:
   ##
@@ -315,13 +337,25 @@ iterator splitLines*(s: string): string =
 
 proc splitLines*(s: string): seq[string] {.noSideEffect,
   rtl, extern: "nsuSplitLines".} =
-  ## The same as the `splitLines` iterator, but is a proc that returns a
-  ## sequence of substrings.
+  ## The same as the `splitLines <#splitLines.i,string>`_ iterator, but is a
+  ## proc that returns a sequence of substrings.
   accumulateResult(splitLines(s))
 
 proc countLines*(s: string): int {.noSideEffect,
   rtl, extern: "nsuCountLines".} =
-  ## same as ``len(splitLines(s))``, but much more efficient.
+  ## Returns the number of new line separators in the string `s`.
+  ##
+  ## This is the same as ``len(splitLines(s))``, but much more efficient
+  ## because it doesn't modify the string creating temporal objects. Every
+  ## `character literal <manual.html#character-literals>`_ newline combination
+  ## (CR, LF, CR-LF) is supported.
+  ##
+  ## Despite its name this proc might not actually return the *number of lines*
+  ## in `s` because the concept of what a line is can vary. For example, a
+  ## string like ``Hello world`` is a line of text, but the proc will return a
+  ## value of zero because there are no newline separators.  Also, text editors
+  ## usually don't count trailing newline characters in a text file as a new
+  ## empty line, but this proc will.
   var i = 0
   while i < s.len:
     case s[i]
@@ -334,28 +368,30 @@ proc countLines*(s: string): int {.noSideEffect,
 
 proc split*(s: string, seps: set[char] = Whitespace): seq[string] {.
   noSideEffect, rtl, extern: "nsuSplitCharSet".} =
-  ## The same as the `split` iterator, but is a proc that returns a
-  ## sequence of substrings.
+  ## The same as the `split iterator <#split.i,string,set[char]>`_, but is a
+  ## proc that returns a sequence of substrings.
   accumulateResult(split(s, seps))
 
 proc split*(s: string, sep: char): seq[string] {.noSideEffect,
   rtl, extern: "nsuSplitChar".} =
-  ## The same as the `split` iterator, but is a proc that returns a sequence
-  ## of substrings.
+  ## The same as the `split iterator <#split.i,string,char>`_, but is a proc
+  ## that returns a sequence of substrings.
   accumulateResult(split(s, sep))
 
 proc split*(s: string, sep: string): seq[string] {.noSideEffect,
   rtl, extern: "nsuSplitString".} =
   ## Splits the string `s` into substrings using a string separator.
   ##
-  ## Substrings are separated by the string `sep`.
+  ## Substrings are separated by the string `sep`. This is a wrapper around the
+  ## `split iterator <#split.i,string,string>`_.
   accumulateResult(split(s, sep))
 
 proc toHex*(x: BiggestInt, len: int): string {.noSideEffect,
   rtl, extern: "nsuToHex".} =
-  ## Converts `x` to its hexadecimal representation. The resulting string
-  ## will be exactly `len` characters long. No prefix like ``0x``
-  ## is generated. `x` is treated as an unsigned value.
+  ## Converts `x` to its hexadecimal representation.
+  ##
+  ## The resulting string will be exactly `len` characters long. No prefix like
+  ## ``0x`` is generated. `x` is treated as an unsigned value.
   const
     HexChars = "0123456789ABCDEF"
   var
@@ -367,9 +403,10 @@ proc toHex*(x: BiggestInt, len: int): string {.noSideEffect,
 
 proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect,
   rtl, extern: "nsuIntToStr".} =
-  ## Converts `x` to its decimal representation. The resulting string
-  ## will be minimally `minchars` characters long. This is achieved by
-  ## adding leading zeros.
+  ## Converts `x` to its decimal representation.
+  ##
+  ## The resulting string will be minimally `minchars` characters long. This is
+  ## achieved by adding leading zeros.
   result = $abs(x)
   for i in 1 .. minchars - len(result):
     result = '0' & result
@@ -378,16 +415,18 @@ proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect,
 
 proc parseInt*(s: string): int {.noSideEffect, procvar,
   rtl, extern: "nsuParseInt".} =
-  ## Parses a decimal integer value contained in `s`. If `s` is not
-  ## a valid integer, `EInvalidValue` is raised.
+  ## Parses a decimal integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `EInvalidValue` is raised.
   var L = parseutils.parseInt(s, result, 0)
   if L != s.len or L == 0:
     raise newException(EInvalidValue, "invalid integer: " & s)
 
 proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar,
   rtl, extern: "nsuParseBiggestInt".} =
-  ## Parses a decimal integer value contained in `s`. If `s` is not
-  ## a valid integer, `EInvalidValue` is raised.
+  ## Parses a decimal integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `EInvalidValue` is raised.
   var L = parseutils.parseBiggestInt(s, result, 0)
   if L != s.len or L == 0:
     raise newException(EInvalidValue, "invalid integer: " & s)
@@ -403,10 +442,11 @@ proc parseFloat*(s: string): float {.noSideEffect, procvar,
 
 proc parseHexInt*(s: string): int {.noSideEffect, procvar,
   rtl, extern: "nsuParseHexInt".} =
-  ## Parses a hexadecimal integer value contained in `s`. If `s` is not
-  ## a valid integer, `EInvalidValue` is raised. `s` can have one of the
-  ## following optional prefixes: ``0x``, ``0X``, ``#``.
-  ## Underscores within `s` are ignored.
+  ## Parses a hexadecimal integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one
+  ## of the following optional prefixes: ``0x``, ``0X``, ``#``.  Underscores
+  ## within `s` are ignored.
   var i = 0
   if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2)
   elif s[i] == '#': inc(i)
@@ -426,26 +466,32 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar,
     else: raise newException(EInvalidValue, "invalid integer: " & s)
 
 proc parseBool*(s: string): bool =
-  ## Parses a value into a `bool`. If ``s`` is one of the following values:
-  ## ``y, yes, true, 1, on``, then returns `true`. If ``s`` is one of the
-  ## following values: ``n, no, false, 0, off``, then returns `false`.
-  ## If ``s`` is something else a ``EInvalidValue`` exception is raised.
+  ## Parses a value into a `bool`.
+  ##
+  ## If ``s`` is one of the following values: ``y, yes, true, 1, on``, then
+  ## returns `true`. If ``s`` is one of the following values: ``n, no, false,
+  ## 0, off``, then returns `false`.  If ``s`` is something else a
+  ## ``EInvalidValue`` exception is raised.
   case normalize(s)
   of "y", "yes", "true", "1", "on": result = true
   of "n", "no", "false", "0", "off": result = false
   else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s)
 
 proc parseEnum*[T: enum](s: string): T =
-  ## parses an enum ``T``. Raises ``EInvalidValue`` for an invalid value in 
-  ## `s`. The comparison is done in a style insensitive way.
+  ## Parses an enum ``T``.
+  ##
+  ## Raises ``EInvalidValue`` for an invalid value in `s`. The comparison is
+  ## done in a style insensitive way.
   for e in low(T)..high(T):
     if cmpIgnoreStyle(s, $e) == 0:
       return e
   raise newException(EInvalidValue, "invalid enum value: " & s)
 
 proc parseEnum*[T: enum](s: string, default: T): T =
-  ## parses an enum ``T``. Uses `default` for an invalid value in 
-  ## `s`. The comparison is done in a style insensitive way.
+  ## Parses an enum ``T``.
+  ##
+  ## Uses `default` for an invalid value in `s`. The comparison is done in a
+  ## style insensitive way.
   for e in low(T)..high(T):
     if cmpIgnoreStyle(s, $e) == 0:
       return e
@@ -475,10 +521,11 @@ proc repeatStr*(count: int, s: string): string {.noSideEffect,
 proc align*(s: string, count: int, padding = ' '): string {.
   noSideEffect, rtl, extern: "nsuAlignString".} =
   ## Aligns a string `s` with `padding`, so that is of length `count`.
+  ##
   ## `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. Example:
+  ## returned unchanged. If you need to left align a string use the `repeatChar
+  ## proc <#repeatChar>`_. Example:
   ##
   ## .. code-block:: nimrod
   ##   assert align("abc", 4) == " abc"
@@ -532,10 +579,15 @@ proc wordWrap*(s: string, maxLineWidth = 80,
                seps: set[char] = Whitespace,
                newLine = "\n"): string {.
                noSideEffect, rtl, extern: "nsuWordWrap".} =
-  ## word wraps `s`.
+  ## Word wraps `s`.
   result = newStringOfCap(s.len + s.len shr 6)
   var spaceLeft = maxLineWidth
+  var lastSep = ""
   for word, isSep in tokenize(s, seps):
+    if isSep:
+      lastSep = word
+      spaceLeft = spaceLeft - len(word)
+      continue
     if len(word) > spaceLeft:
       if splitLongWords and len(word) > maxLineWidth:
         result.add(substr(word, 0, spaceLeft-1))
@@ -554,11 +606,12 @@ proc wordWrap*(s: string, maxLineWidth = 80,
         result.add(word)
     else:
       spaceLeft = spaceLeft - len(word)
-      result.add(word)
+      result.add(lastSep & word)
+      lastSep.setLen(0)
 
 proc unindent*(s: string, eatAllIndent = false): string {.
                noSideEffect, rtl, extern: "nsuUnindent".} =
-  ## unindents `s`.
+  ## Unindents `s`.
   result = newStringOfCap(s.len)
   var i = 0
   var pattern = true
@@ -586,6 +639,7 @@ proc unindent*(s: string, eatAllIndent = false): string {.
 proc startsWith*(s, prefix: string): bool {.noSideEffect,
   rtl, extern: "nsuStartsWith".} =
   ## Returns true iff ``s`` starts with ``prefix``.
+  ##
   ## If ``prefix == ""`` true is returned.
   var i = 0
   while true:
@@ -596,6 +650,7 @@ proc startsWith*(s, prefix: string): bool {.noSideEffect,
 proc endsWith*(s, suffix: string): bool {.noSideEffect,
   rtl, extern: "nsuEndsWith".} =
   ## Returns true iff ``s`` ends with ``suffix``.
+  ##
   ## If ``suffix == ""`` true is returned.
   var i = 0
   var j = len(s) - len(suffix)
@@ -607,6 +662,7 @@ proc endsWith*(s, suffix: string): bool {.noSideEffect,
 proc continuesWith*(s, substr: string, start: int): bool {.noSideEffect,
   rtl, extern: "nsuContinuesWith".} =
   ## Returns true iff ``s`` continues with ``substr`` at position ``start``.
+  ##
   ## If ``substr == ""`` true is returned.
   var i = 0
   while true:
@@ -616,6 +672,8 @@ proc continuesWith*(s, substr: string, start: int): bool {.noSideEffect,
 
 proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect,
                                                            inline.} =
+  ## Adds a separator to `dest` only if its length is bigger than `startLen`.
+  ##
   ## A shorthand for:
   ##
   ## .. code-block:: nimrod
@@ -635,15 +693,15 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect,
   if dest.len > startLen: add(dest, sep)
 
 proc allCharsInSet*(s: string, theSet: TCharSet): bool =
-  ## returns true iff each character of `s` is in the set `theSet`.
+  ## Returns true iff each character of `s` is in the set `theSet`.
   for c in items(s):
     if c notin theSet: return false
   return true
 
 proc abbrev*(s: string, possibilities: openArray[string]): int =
-  ## returns the index of the first item in `possibilities` if not
-  ## ambiguous; -1 if no item has been found; -2 if multiple items
-  ## match.
+  ## Returns the index of the first item in `possibilities` if not ambiguous.
+  ##
+  ## Returns -1 if no item has been found and -2 if multiple items match.
   result = -1 # none found
   for i in 0..possibilities.len-1:
     if possibilities[i].startsWith(s):
@@ -657,7 +715,7 @@ proc abbrev*(s: string, possibilities: openArray[string]): int =
 
 proc join*(a: openArray[string], sep: string): string {.
   noSideEffect, rtl, extern: "nsuJoinSep".} =
-  ## concatenates all strings in `a` separating them with `sep`.
+  ## Concatenates all strings in `a` separating them with `sep`.
   if len(a) > 0:
     var L = sep.len * (a.len-1)
     for i in 0..high(a): inc(L, a[i].len)
@@ -671,7 +729,7 @@ proc join*(a: openArray[string], sep: string): string {.
 
 proc join*(a: openArray[string]): string {.
   noSideEffect, rtl, extern: "nsuJoin".} =
-  ## concatenates all strings in `a`.
+  ## Concatenates all strings in `a`.
   if len(a) > 0:
     var L = 0
     for i in 0..high(a): inc(L, a[i].len)
@@ -689,7 +747,7 @@ proc preprocessSub(sub: string, a: var TSkipTable) =
   for i in 0..m-1: a[sub[i]] = m-i
 
 proc findAux(s, sub: string, start: int, a: TSkipTable): int =
-  # fast "quick search" algorithm:
+  # Fast "quick search" algorithm:
   var
     m = len(sub)
     n = len(s)
@@ -705,32 +763,36 @@ proc findAux(s, sub: string, start: int, a: TSkipTable): int =
 
 proc find*(s, sub: string, start: int = 0): int {.noSideEffect,
   rtl, extern: "nsuFindStr", operator: 6.} =
-  ## Searches for `sub` in `s` starting at position `start`. Searching is
-  ## case-sensitive. If `sub` is not in `s`, -1 is returned.
+  ## Searches for `sub` in `s` starting at position `start`.
+  ##
+  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
   var a {.noinit.}: TSkipTable
   preprocessSub(sub, a)
   result = findAux(s, sub, start, a)
 
 proc find*(s: string, sub: char, start: int = 0): int {.noSideEffect,
   rtl, extern: "nsuFindChar".} =
-  ## Searches for `sub` in `s` starting at position `start`. Searching is
-  ## case-sensitive. If `sub` is not in `s`, -1 is returned.
+  ## Searches for `sub` in `s` starting at position `start`.
+  ##
+  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
   for i in start..len(s)-1:
     if sub == s[i]: return i
   return -1
 
 proc find*(s: string, chars: set[char], start: int = 0): int {.noSideEffect,
   rtl, extern: "nsuFindCharSet".} =
-  ## Searches for `chars` in `s` starting at position `start`. If `s` contains
-  ## none of the characters in `chars`, -1 is returned.
+  ## Searches for `chars` in `s` starting at position `start`.
+  ##
+  ## If `s` contains none of the characters in `chars`, -1 is returned.
   for i in start..s.len-1:
     if s[i] in chars: return i
   return -1
 
 proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} =
   ## Searches for `sub` in `s` in reverse, starting at `start` and going
-  ## backwards to 0. Searching is case-sensitive. If `sub` is not in `s`, -1 is
-  ## returned.
+  ## backwards to 0.
+  ##
+  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
   let realStart = if start == -1: s.len else: start
   for i in countdown(realStart-sub.len, 0):
     for j in 0..sub.len-1:
@@ -742,10 +804,11 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} =
   return -1
 
 proc quoteIfContainsWhite*(s: string): string {.deprecated.} =
-  ## returns ``'"' & s & '"'`` if `s` contains a space and does not
-  ## start with a quote, else returns `s`
-  ## DEPRECATED as it was confused for shell quoting function.
-  ## For this application use osproc.quoteShell.
+  ## Returns ``'"' & s & '"'`` if `s` contains a space and does not
+  ## start with a quote, else returns `s`.
+  ##
+  ## **DEPRECATED** as it was confused for shell quoting function.  For this
+  ## application use `osproc.quoteShell <osproc.html#quoteShell>`_.
   if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
     result = '"' & s & '"'
   else:
@@ -781,7 +844,9 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect,
 
 proc replace*(s: string, sub, by: char): string {.noSideEffect,
   rtl, extern: "nsuReplaceChar".} =
-  ## optimized version for characters.
+  ## Replaces `sub` in `s` by the character `by`.
+  ##
+  ## Optimized version of `replace <#replace,string,string>`_ for characters.
   result = newString(s.len)
   var i = 0
   while i < s.len:
@@ -791,9 +856,11 @@ proc replace*(s: string, sub, by: char): string {.noSideEffect,
 
 proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
   rtl, extern: "nsuReplaceWord".} =
-  ## Replaces `sub` in `s` by the string `by`. Each occurance of `sub`
-  ## has to be surrounded by word boundaries (comparable to ``\\w`` in
-  ## regular expressions), otherwise it is not replaced.
+  ## Replaces `sub` in `s` by the string `by`.
+  ##
+  ## Each occurance of `sub` has to be surrounded by word boundaries
+  ## (comparable to ``\\w`` in regular expressions), otherwise it is not
+  ## replaced.
   const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
   var a {.noinit.}: TSkipTable
   result = ""
@@ -816,8 +883,9 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
 
 proc delete*(s: var string, first, last: int) {.noSideEffect,
   rtl, extern: "nsuDelete".} =
-  ## Deletes in `s` the characters at position `first` .. `last`. This modifies
-  ## `s` itself, it does not return a copy.
+  ## Deletes in `s` the characters at position `first` .. `last`.
+  ##
+  ## This modifies `s` itself, it does not return a copy.
   var i = first
   var j = last+1
   var newLen = len(s)-j+i
@@ -829,10 +897,11 @@ proc delete*(s: var string, first, last: int) {.noSideEffect,
 
 proc parseOctInt*(s: string): int {.noSideEffect,
   rtl, extern: "nsuParseOctInt".} =
-  ## Parses an octal integer value contained in `s`. If `s` is not
-  ## a valid integer, `EInvalidValue` is raised. `s` can have one of the
-  ## following optional prefixes: ``0o``, ``0O``.
-  ## Underscores within `s` are ignored.
+  ## Parses an octal integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one
+  ## of the following optional prefixes: ``0o``, ``0O``.  Underscores within
+  ## `s` are ignored.
   var i = 0
   if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2)
   while true:
@@ -846,8 +915,10 @@ proc parseOctInt*(s: string): int {.noSideEffect,
 
 proc toOct*(x: BiggestInt, len: int): string {.noSideEffect,
   rtl, extern: "nsuToOct".} =
-  ## converts `x` into its octal representation. The resulting string is
-  ## always `len` characters long. No leading ``0o`` prefix is generated.
+  ## Converts `x` into its octal representation.
+  ##
+  ## The resulting string is always `len` characters long. No leading ``0o``
+  ## prefix is generated.
   var
     mask: BiggestInt = 7
     shift: BiggestInt = 0
@@ -860,8 +931,10 @@ proc toOct*(x: BiggestInt, len: int): string {.noSideEffect,
 
 proc toBin*(x: BiggestInt, len: int): string {.noSideEffect,
   rtl, extern: "nsuToBin".} =
-  ## converts `x` into its binary representation. The resulting string is
-  ## always `len` characters long. No leading ``0b`` prefix is generated.
+  ## Converts `x` into its binary representation.
+  ##
+  ## The resulting string is always `len` characters long. No leading ``0b``
+  ## prefix is generated.
   var
     mask: BiggestInt = 1
     shift: BiggestInt = 0
@@ -874,7 +947,8 @@ proc toBin*(x: BiggestInt, len: int): string {.noSideEffect,
 
 proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect,
   rtl, extern: "nsuInsertSep".} =
-  ## inserts the separator `sep` after `digits` digits from right to left.
+  ## Inserts the separator `sep` after `digits` digits from right to left.
+  ##
   ## Even though the algorithm works with any string `s`, it is only useful
   ## if `s` contains a number.
   ## Example: ``insertSep("1000000") == "1_000_000"``
@@ -893,7 +967,9 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect,
 
 proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
   rtl, extern: "nsuEscape".} =
-  ## Escapes a string `s`. This does these operations (at the same time):
+  ## Escapes a string `s`.
+  ##
+  ## This does these operations (at the same time):
   ## * replaces any ``\`` by ``\\``
   ## * replaces any ``'`` by ``\'``
   ## * replaces any ``"`` by ``\"``
@@ -917,11 +993,13 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
 
 proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
   rtl, extern: "nsuUnescape".} =
-  ## Unescapes a string `s`. This complements ``escape`` as it performs the
-  ## opposite operations.
+  ## Unescapes a string `s`.
+  ##
+  ## This complements `escape <#escape>`_ as it performs the opposite
+  ## operations.
   ##
-  ## If `s` does not begin with ``prefix`` and end with ``suffix`` a EInvalidValue
-  ## exception will be raised.
+  ## If `s` does not begin with ``prefix`` and end with ``suffix`` a
+  ## EInvalidValue exception will be raised.
   result = newStringOfCap(s.len)
   var i = 0
   if s[0 .. prefix.len-1] != prefix:
@@ -955,9 +1033,10 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
 
 proc validIdentifier*(s: string): bool {.noSideEffect,
   rtl, extern: "nsuValidIdentifier".} =
-  ## returns true if `s` is a valid identifier. A valid identifier starts
-  ## with a character of the set `IdentStartChars` and is followed by any
-  ## number of characters of the set `IdentChars`.
+  ## Returns true if `s` is a valid identifier.
+  ##
+  ## A valid identifier starts with a character of the set `IdentStartChars`
+  ## and is followed by any number of characters of the set `IdentChars`.
   if s[0] in IdentStartChars:
     for i in 1..s.len-1:
       if s[i] notin IdentChars: return false
@@ -965,9 +1044,10 @@ proc validIdentifier*(s: string): bool {.noSideEffect,
 
 proc editDistance*(a, b: string): int {.noSideEffect,
   rtl, extern: "nsuEditDistance".} =
-  ## returns the edit distance between `a` and `b`. This uses the 
-  ## `Levenshtein`:idx: distance algorithm with only a linear memory overhead.
-  ## This implementation is highly optimized!
+  ## Returns the edit distance between `a` and `b`.
+  ##
+  ## This uses the `Levenshtein`:idx: distance algorithm with only a linear
+  ## memory overhead.  This implementation is highly optimized!
   var len1 = a.len
   var len2 = b.len
   if len1 > len2:
@@ -1066,7 +1146,7 @@ type
 proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
                          precision: range[0..32] = 16): string {.
                          noSideEffect, operator: 2, rtl, extern: "nsu$1".} =
-  ## converts a floating point value `f` to a string.
+  ## Converts a floating point value `f` to a string.
   ##
   ## If ``format == ffDecimal`` then precision is the number of digits to
   ## be printed after the decimal point.
@@ -1097,7 +1177,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
 proc formatFloat*(f: float, format: TFloatFormat = ffDefault,
                   precision: range[0..32] = 16): string {.
                   noSideEffect, operator: 2, rtl, extern: "nsu$1".} =
-  ## converts a floating point value `f` to a string.
+  ## Converts a floating point value `f` to a string.
   ##
   ## If ``format == ffDecimal`` then precision is the number of digits to
   ## be printed after the decimal point.
@@ -1192,6 +1272,8 @@ proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {.
 
 proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect,
   rtl, extern: "nsuFormatOpenArray".} =
+  ## Interpolates a format string with the values from `a`.
+  ##
   ## The `substitution`:idx: operator performs string substitutions in
   ## `formatstr` and returns a modified `formatstr`. This is often called
   ## `string interpolation`:idx:.
diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim
index e7bd363cf..3203ee699 100644
--- a/lib/pure/typetraits.nim
+++ b/lib/pure/typetraits.nim
@@ -11,7 +11,26 @@
 ## working with types
 
 proc name*(t: typedesc): string {.magic: "TypeTrait".}
-  ## Returns the name of the given type
+  ## Returns the name of the given type.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##
+  ##   import typetraits
+  ##
+  ##   proc `$`*[T](some:typedesc[T]): string = name(T)
+  ##
+  ##   template test(x): stmt =
+  ##     echo "type: ", type(x), ", value: ", x
+  ##
+  ##   test 42
+  ##   # --> type: int, value: 42
+  ##   test "Foo"
+  ##   # --> type: string, value: Foo
+  ##   test(@['A','B'])
+  ##   # --> type: seq[char], value: @[A, B]
+
 
 proc arity*(t: typedesc): int {.magic: "TypeTrait".}
-  ## Returns the arity of the given type
\ No newline at end of file
+  ## Returns the arity of the given type
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index ee1226a35..7ec823033 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -7,17 +7,24 @@
 #    distribution, for details about the copyright.
 #
 
-## **Note**: This module will be deprecated in the future and merged into a
-## new ``url`` module.
+## This module implements URI parsing as specified by RFC 3986.
 
-import strutils
+import strutils, parseutils
 type
   TUrl* = distinct string
 
-proc `$`*(url: TUrl): string = return string(url)
+  TUri* = object
+    scheme*, username*, password*: string 
+    hostname*, port*, path*, query*, anchor*: string
 
-proc `/`*(a, b: TUrl): TUrl =
+proc `$`*(url: TUrl): string {.deprecated.} =
+  ## **Deprecated since 0.9.6**: Use ``TUri`` instead.
+  return string(url)
+
+proc `/`*(a, b: TUrl): TUrl {.deprecated.} =
   ## Joins two URLs together, separating them with / if needed.
+  ##
+  ## **Deprecated since 0.9.6**: Use ``TUri`` instead.
   var urlS = $a
   var bS = $b
   if urlS == "": return b
@@ -29,9 +36,338 @@ proc `/`*(a, b: TUrl): TUrl =
     urlS.add(bs)
   result = TUrl(urlS)
 
-proc add*(url: var TUrl, a: TUrl) =
+proc add*(url: var TUrl, a: TUrl) {.deprecated.} =
   ## Appends url to url.
+  ##
+  ## **Deprecated since 0.9.6**: Use ``TUri`` instead.
   url = url / a
 
+proc parseAuthority(authority: string, result: var TUri) =
+  var i = 0
+  var inPort = false
+  while true:
+    case authority[i]
+    of '@':
+      result.password = result.port
+      result.port = ""
+      result.username = result.hostname
+      result.hostname = ""
+      inPort = false
+    of ':':
+      inPort = true
+    of '\0': break
+    else:
+      if inPort:
+        result.port.add(authority[i])
+      else:
+        result.hostname.add(authority[i])
+    i.inc
+
+proc parsePath(uri: string, i: var int, result: var TUri) =
+  
+  i.inc parseUntil(uri, result.path, {'?', '#'}, i)
+
+  # The 'mailto' scheme's PATH actually contains the hostname/username
+  if result.scheme.ToLower() == "mailto":
+    parseAuthority(result.path, result)
+    result.path = ""
+
+  if uri[i] == '?':
+    i.inc # Skip '?'
+    i.inc parseUntil(uri, result.query, {'#'}, i)
+
+  if uri[i] == '#':
+    i.inc # Skip '#'
+    i.inc parseUntil(uri, result.anchor, {}, i)
+
+proc initUri(): TUri =
+  result = TUri(scheme: "", username: "", password: "", hostname: "", port: "",
+                path: "", query: "", anchor: "")
+
+proc parseUri*(uri: string): TUri =
+  ## Parses a URI.
+  result = initUri()
+
+  var i = 0
+
+  # Check if this is a reference URI (relative URI)
+  if uri[i] == '/':
+    parsePath(uri, i, result)
+    return
+
+  # Scheme
+  i.inc parseWhile(uri, result.scheme, Letters + Digits + {'+', '-', '.'}, i)
+  if uri[i] != ':':
+    # Assume this is a reference URI (relative URI)
+    i = 0
+    result.scheme = ""
+    parsePath(uri, i, result)
+    return
+  i.inc # Skip ':'
+
+  # Authority
+  if uri[i] == '/' and uri[i+1] == '/':
+    i.inc(2) # Skip //
+    var authority = ""
+    i.inc parseUntil(uri, authority, {'/', '?', '#'}, i)
+    if authority == "":
+      raise newException(EInvalidValue, "Expected authority got nothing.")
+    parseAuthority(authority, result)
+
+  # Path
+  parsePath(uri, i, result)
+
+proc removeDotSegments(path: string): string =
+  var collection: seq[string] = @[]
+  let endsWithSlash = path[path.len-1] == '/'
+  var i = 0
+  var currentSegment = ""
+  while true:
+    case path[i]
+    of '/':
+      collection.add(currentSegment)
+      currentSegment = ""
+    of '.':
+      if path[i+1] == '.' and path[i+2] == '/':
+        if collection.len > 0:
+          discard collection.pop()
+          i.inc 3
+          continue
+      elif path[i+1] == '/':
+        i.inc 2
+        continue
+      currentSegment.add path[i]
+    of '\0':
+      if currentSegment != "":
+        collection.add currentSegment
+      break
+    else:
+      currentSegment.add path[i]
+    i.inc
+
+  result = collection.join("/")
+  if endsWithSlash: result.add '/'
+
+proc merge(base, reference: TUri): string =
+  # http://tools.ietf.org/html/rfc3986#section-5.2.3
+  if base.hostname != "" and base.path == "":
+    '/' & reference.path
+  else:
+    let lastSegment = rfind(base.path, "/")
+    if lastSegment == -1:
+      reference.path
+    else:
+      base.path[0 .. lastSegment] & reference.path
+
+proc combine*(base: TUri, reference: TUri): TUri =
+  ## Combines a base URI with a reference URI.
+  ##
+  ## This uses the algorithm specified in
+  ## `section 5.2.2 of RFC 3986 <http://tools.ietf.org/html/rfc3986#section-5.2.2>`_.
+  ##
+  ## This means that the slashes inside the base URI's path as well as reference
+  ## URI's path affect the resulting URI.
+  ##
+  ## For building URIs you may wish to use \`/\` instead.
+  ##
+  ## Examples:
+  ##
+  ## .. code-block:: nimrod
+  ##   let foo = combine(parseUri("http://example.com/foo/bar"), parseUri("/baz"))
+  ##   assert foo.path == "/baz"
+  ##
+  ##   let bar = combine(parseUri("http://example.com/foo/bar"), parseUri("baz"))
+  ##   assert foo.path == "/foo/baz"
+  ##
+  ##   let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
+  ##   assert foo.path == "/foo/bar/baz"
+  
+  template setAuthority(dest, src: expr): stmt =
+    dest.hostname = src.hostname
+    dest.username = src.username
+    dest.port = src.port
+    dest.password = src.password
+
+  result = initUri()
+  if reference.scheme != base.scheme and reference.scheme != "":
+    result = reference
+    result.path = removeDotSegments(result.path)
+  else:
+    if reference.hostname != "":
+      setAuthority(result, reference)
+      result.path = removeDotSegments(reference.path)
+      result.query = reference.query
+    else:
+      if reference.path == "":
+        result.path = base.path
+        if reference.query != "":
+          result.query = reference.query
+        else:
+          result.query = base.query
+      else:
+        if reference.path.startsWith("/"):
+          result.path = removeDotSegments(reference.path)
+        else:
+          result.path = removeDotSegments(merge(base, reference))
+        result.query = reference.query
+      setAuthority(result, base)
+    result.scheme = base.scheme
+  result.anchor = reference.anchor
+
+proc combine*(uris: varargs[TUri]): TUri =
+  ## Combines multiple URIs together.
+  result = uris[0]
+  for i in 1 .. <uris.len:
+    result = combine(result, uris[i])
+
+proc `/`*(x: TUri, path: string): TUri =
+  ## Concatenates the path specified to the specified URI's path.
+  ##
+  ## Contrary to the ``combine`` procedure you do not have to worry about
+  ## the slashes at the beginning and end of the path and URI's path
+  ## respectively.
+  ##
+  ## Examples:
+  ##
+  ## .. code-block:: nimrod
+  ##   let foo = parseUri("http://example.com/foo/bar") / parseUri("/baz")
+  ##   assert foo.path == "/foo/bar/baz"
+  ##
+  ##   let bar = parseUri("http://example.com/foo/bar") / parseUri("baz")
+  ##   assert foo.path == "/foo/bar/baz"
+  ##
+  ##   let bar = parseUri("http://example.com/foo/bar/") / parseUri("baz")
+  ##   assert foo.path == "/foo/bar/baz"
+  result = x
+  if result.path[result.path.len-1] == '/':
+    if path[0] == '/':
+      result.path.add(path[1 .. path.len-1])
+    else:
+      result.path.add(path)
+  else:
+    if path[0] != '/':
+      result.path.add '/'
+    result.path.add(path)
+
+proc `$`*(u: TUri): string =
+  ## Returns the string representation of the specified URI object.
+  result = ""
+  if u.scheme.len > 0:
+    result.add(u.scheme)
+    result.add("://")
+  if u.username.len > 0:
+    result.add(u.username)
+    if u.password.len > 0:
+      result.add(":")
+      result.add(u.password)
+    result.add("@")
+  result.add(u.hostname)
+  if u.port.len > 0:
+    result.add(":")
+    result.add(u.port)
+  if u.path.len > 0:
+    if u.path[0] != '/': result.add("/")
+    result.add(u.path)
+  result.add(u.query)
+  result.add(u.anchor)
+
 when isMainModule:
-  assert($("http://".TUrl / "localhost:5000".TUrl) == "http://localhost:5000")
+  block:
+    let test = parseUri("http://localhost:8080/test")
+    doAssert test.scheme == "http"
+    doAssert test.port == "8080"
+    doAssert test.path == "/test"
+    doAssert test.hostname == "localhost"
+
+  block:
+    let test = parseUri("foo://username:password@example.com:8042/over/there" &
+                        "/index.dtb?type=animal&name=narwhal#nose")
+    doAssert test.scheme == "foo"
+    doAssert test.username == "username"
+    doAssert test.password == "password"
+    doAssert test.hostname == "example.com"
+    doAssert test.port == "8042"
+    doAssert test.path == "/over/there/index.dtb"
+    doAssert test.query == "type=animal&name=narwhal"
+    doAssert test.anchor == "nose"
+
+  block:
+    let test = parseUri("urn:example:animal:ferret:nose")
+    doAssert test.scheme == "urn"
+    doAssert test.path == "example:animal:ferret:nose"
+
+  block:
+    let test = parseUri("mailto:username@example.com?subject=Topic")
+    doAssert test.scheme == "mailto"
+    doAssert test.username == "username"
+    doAssert test.hostname == "example.com"
+    doAssert test.query == "subject=Topic"
+
+  block:
+    let test = parseUri("magnet:?xt=urn:sha1:72hsga62ba515sbd62&dn=foobar")
+    doAssert test.scheme == "magnet"
+    doAssert test.query == "xt=urn:sha1:72hsga62ba515sbd62&dn=foobar"
+
+  block:
+    let test = parseUri("/test/foo/bar?q=2#asdf")
+    doAssert test.scheme == ""
+    doAssert test.path == "/test/foo/bar"
+    doAssert test.query == "q=2"
+    doAssert test.anchor == "asdf"
+
+  block:
+    let test = parseUri("test/no/slash")
+    doAssert test.path == "test/no/slash"
+
+  # Remove dot segments tests
+  block:
+    doAssert removeDotSegments("/foo/bar/baz") == "/foo/bar/baz"
+
+  # Combine tests
+  block:
+    let concat = combine(parseUri("http://google.com/foo/bar/"), parseUri("baz"))
+    doAssert concat.path == "/foo/bar/baz"
+    doAssert concat.hostname == "google.com"
+    doAssert concat.scheme == "http"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo"), parseUri("/baz"))
+    doAssert concat.path == "/baz"
+    doAssert concat.hostname == "google.com"
+    doAssert concat.scheme == "http"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
+    doAssert concat.path == "/foo/bar"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test"), parseUri("/bar"))
+    doAssert concat.path == "/bar"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test"), parseUri("bar"))
+    doAssert concat.path == "/foo/bar"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar"))
+    doAssert concat.path == "/foo/test/bar"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"))
+    doAssert concat.path == "/foo/test/bar/"
+
+  block:
+    let concat = combine(parseUri("http://google.com/foo/test/"), parseUri("bar/"),
+                         parseUri("baz"))
+    doAssert concat.path == "/foo/test/bar/baz"
+
+  # `/` tests
+  block:
+    let test = parseUri("http://example.com/foo") / "bar/asd"
+    doAssert test.path == "/foo/bar/asd"
+
+  block:
+    let test = parseUri("http://example.com/foo/") / "/bar/asd"
+    doAssert test.path == "/foo/bar/asd"
+
+  
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 47e94243e..d63b6c5dd 100644
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -45,7 +45,7 @@ const
   DocumentFragmentNode* = 11
 
   # Nodes which are childless - Not sure about AttributeNode
-  childlessObjects = {DocumentNode, AttributeNode, TextNode, 
+  childlessObjects = {DocumentNode, AttributeNode, TextNode,
     CDataSectionNode, ProcessingInstructionNode, CommentNode}
   # Illegal characters
   illegalChars = {'>', '<', '&', '"'}
@@ -69,21 +69,21 @@ type
     FOwnerDocument: PDocument # Read-Only
     FParentNode: PNode # Read-Only
     prefix*: string # Setting this should change some values... TODO!
-  
+
   PElement* = ref Element
   Element = object of Node
     FTagName: string # Read-only
-  
+
   PCharacterData* = ref CharacterData
   CharacterData = object of Node
     data*: string
-    
+
   PDocument* = ref Document
   Document = object of Node
     FImplementation: PDOMImplementation # Read-only
     FDocumentElement: PElement # Read-only
-    
-  PAttr* = ref Attr  
+
+  PAttr* = ref Attr
   Attr = object of Node
     FName: string # Read-only
     FSpecified: bool # Read-only
@@ -95,13 +95,13 @@ type
 
   PText* = ref Text
   Text = object of CharacterData
-  
+
   PComment* = ref comment
   Comment = object of CharacterData
-  
+
   PCDataSection* = ref CDataSection
   CDataSection = object of Text
-    
+
   PProcessingInstruction* = ref ProcessingInstruction
   ProcessingInstruction = object of Node
     data*: string
@@ -111,8 +111,8 @@ type
 proc getDOM*(): PDOMImplementation =
   ## Returns a DOMImplementation
   new(result)
-  result.Features = @[(name: "core", version: "2.0"), 
-                      (name: "core", version: "1.0"), 
+  result.Features = @[(name: "core", version: "2.0"),
+                      (name: "core", version: "1.0"),
                       (name: "XML", version: "2.0")]
 
 proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedName: string): PDocument =
@@ -121,28 +121,28 @@ proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedNam
   new(doc)
   doc.FNamespaceURI = namespaceURI
   doc.FImplementation = dom
-  
+
   var elTag: PElement
   new(elTag)
   elTag.FTagName = qualifiedName
   elTag.FNodeName = qualifiedName
   doc.FDocumentElement = elTag
   doc.FNodeType = DocumentNode
-  
+
   return doc
-  
+
 proc createDocument*(dom: PDOMImplementation, n: PElement): PDocument =
   ## Creates an XML Document object of the specified type with its document element.
-  
+
   # This procedure is not in the specification, it's provided for the parser.
   var doc: PDocument
   new(doc)
   doc.FDocumentElement = n
   doc.FImplementation = dom
   doc.FNodeType = DocumentNode
-  
+
   return doc
-  
+
 proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = ""): bool =
   ## Returns ``true`` if this ``version`` of the DomImplementation implements ``feature``, otherwise ``false``
   for iName, iVersion in items(dom.Features):
@@ -157,11 +157,11 @@ proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = "")
 
 # Document
 # Attributes
-  
+
 proc implementation*(doc: PDocument): PDOMImplementation =
   return doc.FImplementation
-  
-proc documentElement*(doc: PDocument): PElement = 
+
+proc documentElement*(doc: PDocument): PElement =
   return doc.FDocumentElement
 
 # Internal procedures
@@ -175,13 +175,13 @@ proc findNodes(nl: PNode, name: string): seq[PNode] =
     if i.FNodeType == ElementNode:
       if i.FNodeName == name or name == "*":
         r.add(i)
-        
+
       if not isNil(i.childNodes):
         if i.childNodes.len() != 0:
           r.add(findNodes(i, name))
-    
+
   return r
-  
+
 proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] =
   # Made for getElementsByTagNameNS
   var r: seq[PNode] = @[]
@@ -192,23 +192,23 @@ proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode]
     if i.FNodeType == ElementNode:
       if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"):
         r.add(i)
-        
+
       if not isNil(i.childNodes):
         if i.childNodes.len() != 0:
           r.add(findNodesNS(i, namespaceURI, localName))
-    
+
   return r
-    
+
 
 #Procedures
 proc createAttribute*(doc: PDocument, name: string): PAttr =
   ## Creates an Attr of the given name. Note that the Attr instance can then be set on an Element using the setAttributeNode method.
-  ## To create an attribute with a qualified name and namespace URI, use the createAttributeNS method. 
-  
+  ## To create an attribute with a qualified name and namespace URI, use the createAttributeNS method.
+
   # Check if name contains illegal characters
   if illegalChars in name:
     raise newException(EInvalidCharacterErr, "Invalid character")
-  
+
   var AttrNode: PAttr
   new(AttrNode)
   AttrNode.FName = name
@@ -222,21 +222,21 @@ proc createAttribute*(doc: PDocument, name: string): PAttr =
 
 proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PAttr =
   ## Creates an attribute of the given qualified name and namespace URI
-  
+
   # Check if name contains illegal characters
   if illegalChars in namespaceURI or illegalChars in qualifiedName:
     raise newException(EInvalidCharacterErr, "Invalid character")
   # Exceptions
   if qualifiedName.contains(':'):
-    if namespaceURI == nil:
+    if isNil(namespaceURI):
       raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
     elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
-      raise newException(ENamespaceErr, 
+      raise newException(ENamespaceErr,
         "When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
     elif qualifiedName.split(':')[1].toLower() == "xmlns" and namespaceURI != "http://www.w3.org/2000/xmlns/":
-      raise newException(ENamespaceErr, 
+      raise newException(ENamespaceErr,
         "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
-  
+
   var AttrNode: PAttr
   new(AttrNode)
   AttrNode.FName = qualifiedName
@@ -250,7 +250,7 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str
     AttrNode.prefix = nil
     AttrNode.FLocalName = qualifiedName
   AttrNode.value = ""
-  
+
   AttrNode.FNodeType = AttributeNode
   return AttrNode
 
@@ -265,12 +265,12 @@ proc createCDATASection*(doc: PDocument, data: string): PCDATASection =
   return CData
 
 proc createComment*(doc: PDocument, data: string): PComment =
-  ## Creates a Comment node given the specified string. 
+  ## Creates a Comment node given the specified string.
   var Comm: PComment
   new(Comm)
   Comm.data = data
   Comm.nodeValue = data
-  
+
   Comm.FNodeType = CommentNode
   return Comm
 
@@ -282,11 +282,11 @@ proc createDocumentFragment*(doc: PDocument): PDocumentFragment =
 
 proc createElement*(doc: PDocument, tagName: string): PElement =
   ## Creates an element of the type specified.
-  
+
   # Check if name contains illegal characters
   if illegalChars in tagName:
     raise newException(EInvalidCharacterErr, "Invalid character")
-    
+
   var elNode: PElement
   new(elNode)
   elNode.FTagName = tagName
@@ -296,24 +296,24 @@ proc createElement*(doc: PDocument, tagName: string): PElement =
   elNode.FNamespaceURI = nil
   elNode.childNodes = @[]
   elNode.attributes = @[]
-  
+
   elNode.FNodeType = ElementNode
-  
+
   return elNode
 
 proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement =
   ## Creates an element of the given qualified name and namespace URI.
   if qualifiedName.contains(':'):
-    if namespaceURI == nil:
+    if isNIl(namespaceURI):
       raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
     elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
-      raise newException(ENamespaceErr, 
+      raise newException(ENamespaceErr,
         "When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
-        
+
   # Check if name contains illegal characters
   if illegalChars in namespaceURI or illegalChars in qualifiedName:
     raise newException(EInvalidCharacterErr, "Invalid character")
-    
+
   var elNode: PElement
   new(elNode)
   elNode.FTagName = qualifiedName
@@ -327,18 +327,18 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin
   elNode.FNamespaceURI = namespaceURI
   elNode.childNodes = @[]
   elNode.attributes = @[]
-  
+
   elNode.FNodeType = ElementNode
-  
+
   return elNode
 
-proc createProcessingInstruction*(doc: PDocument, target: string, data: string): PProcessingInstruction = 
-  ## Creates a ProcessingInstruction node given the specified name and data strings. 
-  
+proc createProcessingInstruction*(doc: PDocument, target: string, data: string): PProcessingInstruction =
+  ## Creates a ProcessingInstruction node given the specified name and data strings.
+
   #Check if name contains illegal characters
   if illegalChars in target:
     raise newException(EInvalidCharacterErr, "Invalid character")
-    
+
   var PI: PProcessingInstruction
   new(PI)
   PI.FTarget = target
@@ -347,13 +347,13 @@ proc createProcessingInstruction*(doc: PDocument, target: string, data: string):
   return PI
 
 proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode
-  ## Creates a Text node given the specified string. 
+  ## Creates a Text node given the specified string.
   var txtNode: PText
   new(txtNode)
   txtNode.data = data
   txtNode.nodeValue = data
   txtNode.FNodeName = "#text"
-  
+
   txtNode.FNodeType = TextNode
   return txtNode
 
@@ -363,22 +363,22 @@ discard """proc getElementById*(doc: PDocument, elementId: string): PElement =
 
 proc getElementsByTagName*(doc: PDocument, tagName: string): seq[PNode] =
   ## Returns a NodeList of all the Elements with a given tag name in
-  ## the order in which they are encountered in a preorder traversal of the Document tree. 
+  ## the order in which they are encountered in a preorder traversal of the Document tree.
   var result: seq[PNode] = @[]
   if doc.FDocumentElement.FNodeName == tagName or tagName == "*":
     result.add(doc.FDocumentElement)
-  
+
   result.add(doc.FDocumentElement.findNodes(tagName))
   return result
-  
+
 proc getElementsByTagNameNS*(doc: PDocument, namespaceURI: string, localName: string): seq[PNode] =
   ## Returns a NodeList of all the Elements with a given localName and namespaceURI
-  ## in the order in which they are encountered in a preorder traversal of the Document tree. 
+  ## in the order in which they are encountered in a preorder traversal of the Document tree.
   var result: seq[PNode] = @[]
   if doc.FDocumentElement.FLocalName == localName or localName == "*":
     if doc.FDocumentElement.FNamespaceURI == namespaceURI or namespaceURI == "*":
       result.add(doc.FDocumentElement)
-      
+
   result.add(doc.FDocumentElement.findNodesNS(namespaceURI, localName))
   return result
 
@@ -406,7 +406,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     if deep:
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(importNode(doc, tmp[i], deep))
-        
+
     return n
   of ElementNode:
     var n: PNode
@@ -414,7 +414,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     n = importedNode
     n.FOwnerDocument = doc
     n.FParentNode = nil
-    
+
     var tmpA: seq[PAttr] = n.attributes
     n.attributes = @[]
     # Import the Element node's attributes
@@ -426,7 +426,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     if deep:
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(importNode(doc, tmp[i], deep))
-        
+
     return n
   of ProcessingInstructionNode, TextNode, CDataSectionNode, CommentNode:
     var n: PNode
@@ -437,27 +437,27 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
     return n
   else:
     raise newException(ENotSupportedErr, "The type of node being imported is not supported")
-  
+
 
 # Node
 # Attributes
-  
+
 proc firstChild*(n: PNode): PNode =
   ## Returns this node's first child
 
-  if n.childNodes.len() > 0:
+  if not isNil(n.childNodes) and n.childNodes.len() > 0:
     return n.childNodes[0]
   else:
     return nil
-  
+
 proc lastChild*(n: PNode): PNode =
   ## Returns this node's last child
 
-  if n.childNodes.len() > 0:
+  if not isNil(n.childNodes) and n.childNodes.len() > 0:
     return n.childNodes[n.childNodes.len() - 1]
   else:
     return nil
-  
+
 proc localName*(n: PNode): string =
   ## Returns this nodes local name
 
@@ -465,15 +465,17 @@ proc localName*(n: PNode): string =
 
 proc namespaceURI*(n: PNode): string =
   ## Returns this nodes namespace URI
-  
+
   return n.FNamespaceURI
-  
-proc `namespaceURI=`*(n: PNode, value: string) = 
+
+proc `namespaceURI=`*(n: PNode, value: string) =
   n.FNamespaceURI = value
 
 proc nextSibling*(n: PNode): PNode =
   ## Returns the next sibling of this node
 
+  if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes):
+    return nil
   var nLow: int = low(n.FParentNode.childNodes)
   var nHigh: int = high(n.FParentNode.childNodes)
   for i in nLow..nHigh:
@@ -500,17 +502,19 @@ proc parentNode*(n: PNode): PNode =
   ## Returns the parent node of this node
 
   return n.FParentNode
-  
+
 proc previousSibling*(n: PNode): PNode =
   ## Returns the previous sibling of this node
 
+  if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes):
+    return nil
   var nLow: int = low(n.FParentNode.childNodes)
   var nHigh: int = high(n.FParentNode.childNodes)
   for i in nLow..nHigh:
     if n.FParentNode.childNodes[i] == n:
       return n.FParentNode.childNodes[i - 1]
   return nil
-  
+
 proc `prefix=`*(n: PNode, value: string) =
   ## Modifies the prefix of this node
 
@@ -519,13 +523,13 @@ proc `prefix=`*(n: PNode, value: string) =
   if illegalChars in value:
     raise newException(EInvalidCharacterErr, "Invalid character")
 
-  if n.FNamespaceURI == nil:
+  if isNil(n.FNamespaceURI):
     raise newException(ENamespaceErr, "namespaceURI cannot be nil")
   elif value.toLower() == "xml" and n.FNamespaceURI != "http://www.w3.org/XML/1998/namespace":
-    raise newException(ENamespaceErr, 
+    raise newException(ENamespaceErr,
       "When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
   elif value.toLower() == "xmlns" and n.FNamespaceURI != "http://www.w3.org/2000/xmlns/":
-    raise newException(ENamespaceErr, 
+    raise newException(ENamespaceErr,
       "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
   elif value.toLower() == "xmlns" and n.FNodeType == AttributeNode:
     raise newException(ENamespaceErr, "An AttributeNode cannot have a prefix of \"xmlns\"")
@@ -543,33 +547,33 @@ proc `prefix=`*(n: PNode, value: string) =
 proc appendChild*(n: PNode, newChild: PNode) =
   ## Adds the node newChild to the end of the list of children of this node.
   ## If the newChild is already in the tree, it is first removed.
-  
+
   # Check if n contains newChild
-  if not IsNil(n.childNodes):
+  if not isNil(n.childNodes):
     for i in low(n.childNodes)..high(n.childNodes):
       if n.childNodes[i] == newChild:
         raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.")
-  
+
   # Check if newChild is from this nodes document
   if n.FOwnerDocument != newChild.FOwnerDocument:
     raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
-  
+
   if n == newChild:
     raise newException(EHierarchyRequestErr, "You can't add a node into itself")
-  
+
   if n.nodeType in childlessObjects:
     raise newException(ENoModificationAllowedErr, "Cannot append children to a childless node")
-  
+
   if isNil(n.childNodes): n.childNodes = @[]
-    
+
   newChild.FParentNode = n
   for i in low(n.childNodes)..high(n.childNodes):
     if n.childNodes[i] == newChild:
       n.childNodes[i] = newChild
-    
+
   n.childNodes.add(newChild)
 
-proc cloneNode*(n: PNode, deep: bool): PNode = 
+proc cloneNode*(n: PNode, deep: bool): PNode =
   ## Returns a duplicate of this node, if ``deep`` is `true`, Element node's children are copied
   case n.FNodeType
   of AttributeNode:
@@ -586,7 +590,7 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
     # Import the childNodes
     var tmp: seq[PNode] = n.childNodes
     n.childNodes = @[]
-    if deep:
+    if deep and not isNil(tmp):
       for i in low(tmp.len())..high(tmp.len()):
         n.childNodes.add(cloneNode(tmp[i], deep))
     return newNode
@@ -597,34 +601,39 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
     return newNode
 
 proc hasAttributes*(n: PNode): bool =
-  ## Returns whether this node (if it is an element) has any attributes. 
-  return n.attributes.len() > 0
+  ## Returns whether this node (if it is an element) has any attributes.
+  return not isNil(n.attributes) and n.attributes.len() > 0
 
-proc hasChildNodes*(n: PNode): bool = 
+proc hasChildNodes*(n: PNode): bool =
   ## Returns whether this node has any children.
-  return n.childNodes.len() > 0
+  return not isNil(n.childNodes) and n.childNodes.len() > 0
 
 proc insertBefore*(n: PNode, newChild: PNode, refChild: PNode): PNode =
   ## Inserts the node ``newChild`` before the existing child node ``refChild``.
   ## If ``refChild`` is nil, insert ``newChild`` at the end of the list of children.
-  
+
   # Check if newChild is from this nodes document
   if n.FOwnerDocument != newChild.FOwnerDocument:
     raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
-    
+
+  if isNil(n.childNodes):
+    n.ChildNodes = @[]
+
   for i in low(n.childNodes)..high(n.childNodes):
     if n.childNodes[i] == refChild:
       n.childNodes.insert(newChild, i - 1)
-    return
+      return
+
+  n.ChildNodes.add(newChild)
 
 proc isSupported*(n: PNode, feature: string, version: string): bool =
-  ## Tests whether the DOM implementation implements a specific 
-  ## feature and that feature is supported by this node. 
+  ## Tests whether the DOM implementation implements a specific
+  ## feature and that feature is supported by this node.
   return n.FOwnerDocument.FImplementation.hasFeature(feature, version)
 
 proc isEmpty(s: string): bool =
 
-  if s == "" or s == nil:
+  if isNil(s) or s == "":
     return True
   for i in items(s):
     if i != ' ':
@@ -635,18 +644,18 @@ proc normalize*(n: PNode) =
   ## Merges all seperated TextNodes together, and removes any empty TextNodes
   var curTextNode: PNode = nil
   var i: int = 0
-  
+
   var newChildNodes: seq[PNode] = @[]
   while True:
-    if i >= n.childNodes.len:
+    if isNil(n.childNodes) or i >= n.childNodes.len:
       break
     if n.childNodes[i].nodeType == TextNode:
-      
+
       #If the TextNode is empty, remove it
       if PText(n.childNodes[i]).data.isEmpty():
         inc(i)
-      
-      if curTextNode == nil:
+
+      if isNil(curTextNode):
         curTextNode = n.childNodes[i]
       else:
         PText(curTextNode).data.add(PText(n.childNodes[i]).data)
@@ -656,35 +665,37 @@ proc normalize*(n: PNode) =
       newChildNodes.add(curTextNode)
       newChildNodes.add(n.childNodes[i])
       curTextNode = nil
-    
+
     inc(i)
   n.childNodes = newChildNodes
 
 proc removeChild*(n: PNode, oldChild: PNode): PNode =
   ## Removes the child node indicated by ``oldChild`` from the list of children, and returns it.
-  for i in low(n.childNodes)..high(n.childNodes):
-    if n.childNodes[i] == oldChild:
-      result = n.childNodes[i]
-      n.childNodes.delete(i)
-      return result
-      
+  if not isNil(n.childNodes):
+    for i in low(n.childNodes)..high(n.childNodes):
+      if n.childNodes[i] == oldChild:
+        result = n.childNodes[i]
+        n.childNodes.delete(i)
+        return result
+
   raise newException(ENotFoundErr, "Node not found")
-    
+
 proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode =
   ## Replaces the child node ``oldChild`` with ``newChild`` in the list of children, and returns the ``oldChild`` node.
-  
+
   # Check if newChild is from this nodes document
   if n.FOwnerDocument != newChild.FOwnerDocument:
     raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
-  
-  for i in low(n.childNodes)..high(n.childNodes):
-    if n.childNodes[i] == oldChild:
-      result = n.childNodes[i]
-      n.childNodes[i] = newChild
-      return result
-  
+
+  if not isNil(n.childNodes):
+    for i in low(n.childNodes)..high(n.childNodes):
+      if n.childNodes[i] == oldChild:
+        result = n.childNodes[i]
+        n.childNodes[i] = newChild
+        return result
+
   raise newException(ENotFoundErr, "Node not found")
-  
+
 # NamedNodeMap
 
 proc getNamedItem*(NList: seq[PNode], name: string): PNode =
@@ -693,22 +704,22 @@ proc getNamedItem*(NList: seq[PNode], name: string): PNode =
     if i.nodeName() == name:
       return i
   return nil
-  
+
 proc getNamedItem*(NList: seq[PAttr], name: string): PAttr =
   ## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil``
   for i in items(NList):
     if i.nodeName() == name:
       return i
   return nil
-      
+
 proc getNamedItemNS*(NList: seq[PNode], namespaceURI: string, localName: string): PNode =
   ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
   for i in items(NList):
     if i.namespaceURI() == namespaceURI and i.localName() == localName:
       return i
   return nil
-  
-proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr = 
+
+proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr =
   ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
   for i in items(NList):
     if i.NamespaceURI() == namespaceURI and i.LocalName() == localName:
@@ -716,7 +727,7 @@ proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string)
   return nil
 
 proc item*(NList: seq[PNode], index: int): PNode =
-  ## Returns the ``index`` th item in the map. 
+  ## Returns the ``index`` th item in the map.
   ## If ``index`` is greater than or equal to the number of nodes in this map, this returns ``nil``.
   if index >= NList.len(): return nil
   else: return NList[index]
@@ -729,9 +740,9 @@ proc removeNamedItem*(NList: var seq[PNode], name: string): PNode =
       result = NList[i]
       NList.delete(i)
       return result
-  
+
   raise newException(ENotFoundErr, "Node not found")
-  
+
 proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName: string): PNode =
   ## Removes a node specified by local name and namespace URI
   for i in low(NList)..high(NList):
@@ -739,7 +750,7 @@ proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName:
       result = NList[i]
       NList.delete(i)
       return result
-  
+
   raise newException(ENotFoundErr, "Node not found")
 
 proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
@@ -751,9 +762,9 @@ proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
         raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
   #Exceptions End
-  
+
   var item: PNode = NList.getNamedItem(arg.NodeName())
-  if item == nil:
+  if isNil(item):
     NList.add(arg)
     return nil
   else:
@@ -765,22 +776,22 @@ proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
         break
     NList[index] = arg
     return item # Return the replaced node
-    
+
 proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
   ## Adds ``arg`` as a ``Node`` to the ``NList``
   ## If a node with the same name is already present in this map, it is replaced by the new one.
-  if not IsNil(NList):
+  if not isNil(NList):
     if NList.len() > 0:
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
         raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
-        
-  if arg.FOwnerElement != nil:
+
+  if not isNil(arg.FOwnerElement):
     raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
-        
+
   # Exceptions end
   var item: PAttr = NList.getNamedItem(arg.nodeName())
-  if item == nil:
+  if isNil(item):
     NList.add(arg)
     return nil
   else:
@@ -792,18 +803,18 @@ proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
         break
     NList[index] = arg
     return item # Return the replaced node
-    
+
 proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
   ## Adds a node using its ``namespaceURI`` and ``localName``
-  if not IsNil(NList):
+  if not isNil(NList):
     if NList.len() > 0:
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
         raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
   #Exceptions end
-        
+
   var item: PNode = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
-  if item == nil:
+  if isNil(item):
     NList.add(arg)
     return nil
   else:
@@ -815,7 +826,7 @@ proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
         break
     NList[index] = arg
     return item # Return the replaced node
-    
+
 proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
   ## Adds a node using its ``namespaceURI`` and ``localName``
   if not isNil(NList):
@@ -823,13 +834,13 @@ proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
       # Check if newChild is from this nodes document
       if NList[0].FOwnerDocument != arg.FOwnerDocument:
         raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
-        
-  if arg.FOwnerElement != nil:
+
+  if not isNil(arg.FOwnerElement):
     raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
-        
+
   # Exceptions end
   var item: PAttr = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
-  if item == nil:
+  if isNil(item):
     NList.add(arg)
     return nil
   else:
@@ -841,8 +852,8 @@ proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
         break
     NList[index] = arg
     return item # Return the replaced node
-    
-# CharacterData - Decided to implement this, 
+
+# CharacterData - Decided to implement this,
 # Didn't add the procedures, because you can just edit .data
 
 # Attr
@@ -851,13 +862,13 @@ proc name*(a: PAttr): string =
   ## Returns the name of the Attribute
 
   return a.FName
-  
+
 proc specified*(a: PAttr): bool =
   ## Specifies whether this attribute was specified in the original document
 
   return a.FSpecified
-  
-proc ownerElement*(a: PAttr): PElement = 
+
+proc ownerElement*(a: PAttr): PElement =
   ## Returns this Attributes owner element
 
   return a.FOwnerElement
@@ -873,27 +884,35 @@ proc tagName*(el: PElement): string =
 # Procedures
 proc getAttribute*(el: PElement, name: string): string =
   ## Retrieves an attribute value by ``name``
+  if isNil(el.attributes):
+    return nil
   var attribute = el.attributes.getNamedItem(name)
-  if attribute != nil:
+  if not isNil(attribute):
     return attribute.value
   else:
     return nil
 
 proc getAttributeNS*(el: PElement, namespaceURI: string, localName: string): string =
   ## Retrieves an attribute value by ``localName`` and ``namespaceURI``
+  if isNil(el.attributes):
+    return nil
   var attribute = el.attributes.getNamedItemNS(namespaceURI, localName)
-  if attribute != nil:
+  if not isNil(attribute):
     return attribute.value
   else:
     return nil
-    
+
 proc getAttributeNode*(el: PElement, name: string): PAttr =
   ## Retrieves an attribute node by ``name``
   ## To retrieve an attribute node by qualified name and namespace URI, use the `getAttributeNodeNS` method
+  if isNil(el.attributes):
+    return nil
   return el.attributes.getNamedItem(name)
 
 proc getAttributeNodeNS*(el: PElement, namespaceURI: string, localName: string): PAttr =
   ## Retrieves an `Attr` node by ``localName`` and ``namespaceURI``
+  if isNil(el.attributes):
+    return nil
   return el.attributes.getNamedItemNS(namespaceURI, localName)
 
 proc getElementsByTagName*(el: PElement, name: string): seq[PNode] =
@@ -909,103 +928,110 @@ proc getElementsByTagNameNS*(el: PElement, namespaceURI: string, localName: stri
   result = el.findNodesNS(namespaceURI, localName)
 
 proc hasAttribute*(el: PElement, name: string): bool =
-  ## Returns ``true`` when an attribute with a given ``name`` is specified 
-  ## on this element , ``false`` otherwise. 
-  return el.attributes.getNamedItem(name) != nil
+  ## Returns ``true`` when an attribute with a given ``name`` is specified
+  ## on this element , ``false`` otherwise.
+  if isNil(el.attributes):
+    return false
+  return not isNil(el.attributes.getNamedItem(name))
 
 proc hasAttributeNS*(el: PElement, namespaceURI: string, localName: string): bool =
   ## Returns ``true`` when an attribute with a given ``localName`` and
-  ## ``namespaceURI`` is specified on this element , ``false`` otherwise 
-  return el.attributes.getNamedItemNS(namespaceURI, localName) != nil
+  ## ``namespaceURI`` is specified on this element , ``false`` otherwise
+  if isNil(el.attributes):
+    return false
+  return not isNil(el.attributes.getNamedItemNS(namespaceURI, localName))
 
 proc removeAttribute*(el: PElement, name: string) =
   ## Removes an attribute by ``name``
-  for i in low(el.attributes)..high(el.attributes):
-    if el.attributes[i].FName == name:
-      el.attributes.delete(i)
-      
+  if not isNil(el.attributes):
+    for i in low(el.attributes)..high(el.attributes):
+      if el.attributes[i].FName == name:
+        el.attributes.delete(i)
+
 proc removeAttributeNS*(el: PElement, namespaceURI: string, localName: string) =
   ## Removes an attribute by ``localName`` and ``namespaceURI``
-  for i in low(el.attributes)..high(el.attributes):
-    if el.attributes[i].FNamespaceURI == namespaceURI and 
-        el.attributes[i].FLocalName == localName:
-      el.attributes.delete(i)
-  
+  if not isNil(el.attributes):
+    for i in low(el.attributes)..high(el.attributes):
+      if el.attributes[i].FNamespaceURI == namespaceURI and
+          el.attributes[i].FLocalName == localName:
+        el.attributes.delete(i)
+
 proc removeAttributeNode*(el: PElement, oldAttr: PAttr): PAttr =
   ## Removes the specified attribute node
   ## If the attribute node cannot be found raises ``ENotFoundErr``
-  for i in low(el.attributes)..high(el.attributes):
-    if el.attributes[i] == oldAttr:
-      result = el.attributes[i]
-      el.attributes.delete(i)
-      return result
-  
+  if not isNil(el.attributes):
+    for i in low(el.attributes)..high(el.attributes):
+      if el.attributes[i] == oldAttr:
+        result = el.attributes[i]
+        el.attributes.delete(i)
+        return result
+
   raise newException(ENotFoundErr, "oldAttr is not a member of el's Attributes")
 
 proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr =
   ## Adds a new attribute node, if an attribute with the same `nodeName` is
   ## present, it is replaced by the new one and the replaced attribute is
   ## returned, otherwise ``nil`` is returned.
-  
+
   # Check if newAttr is from this nodes document
   if el.FOwnerDocument != newAttr.FOwnerDocument:
-    raise newException(EWrongDocumentErr, 
+    raise newException(EWrongDocumentErr,
       "This node belongs to a different document, use importNode.")
-        
-  if newAttr.FOwnerElement != nil:
-    raise newException(EInuseAttributeErr, 
+
+  if not isNil(newAttr.FOwnerElement):
+    raise newException(EInuseAttributeErr,
       "This attribute is in use by another element, use cloneNode")
   # Exceptions end
-  
+
   if isNil(el.attributes): el.attributes = @[]
   return el.attributes.setNamedItem(newAttr)
-  
+
 proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
-  ## Adds a new attribute node, if an attribute with the localName and 
+  ## Adds a new attribute node, if an attribute with the localName and
   ## namespaceURI of ``newAttr`` is present, it is replaced by the new one
   ## and the replaced attribute is returned, otherwise ``nil`` is returned.
-  
+
   # Check if newAttr is from this nodes document
   if el.FOwnerDocument != newAttr.FOwnerDocument:
-    raise newException(EWrongDocumentErr, 
+    raise newException(EWrongDocumentErr,
       "This node belongs to a different document, use importNode.")
-        
-  if newAttr.FOwnerElement != nil:
-    raise newException(EInuseAttributeErr, 
+
+  if not isNil(newAttr.FOwnerElement):
+    raise newException(EInuseAttributeErr,
       "This attribute is in use by another element, use cloneNode")
   # Exceptions end
-  
+
   if isNil(el.attributes): el.attributes = @[]
   return el.attributes.setNamedItemNS(newAttr)
 
 proc setAttribute*(el: PElement, name: string, value: string) =
   ## Adds a new attribute, as specified by ``name`` and ``value``
-  ## If an attribute with that name is already present in the element, its 
+  ## If an attribute with that name is already present in the element, its
   ## value is changed to be that of the value parameter
-  ## Raises the EInvalidCharacterErr if the specified ``name`` contains 
+  ## Raises the EInvalidCharacterErr if the specified ``name`` contains
   ## illegal characters
   var AttrNode = el.FOwnerDocument.createAttribute(name)
   # Check if name contains illegal characters
   if illegalChars in name:
     raise newException(EInvalidCharacterErr, "Invalid character")
-    
+
   discard el.setAttributeNode(AttrNode)
   # Set the info later, the setAttributeNode checks
   # if FOwnerElement is nil, and if it isn't it raises an exception
   AttrNode.FOwnerElement = el
   AttrNode.FSpecified = True
   AttrNode.value = value
-  
+
 proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) =
-  ## Adds a new attribute, as specified by ``namespaceURI``, ``localName`` 
+  ## Adds a new attribute, as specified by ``namespaceURI``, ``localName``
   ## and ``value``.
-  
+
   # Check if name contains illegal characters
   if illegalChars in namespaceURI or illegalChars in localName:
     raise newException(EInvalidCharacterErr, "Invalid character")
-    
+
   var AttrNode = el.FOwnerDocument.createAttributeNS(namespaceURI, localName)
-    
+
   discard el.setAttributeNodeNS(AttrNode)
   # Set the info later, the setAttributeNode checks
   # if FOwnerElement is nil, and if it isn't it raises an exception
@@ -1013,19 +1039,19 @@ proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) =
   AttrNode.FSpecified = True
   AttrNode.value = value
 
-# Text  
+# Text
 proc splitData*(TextNode: PText, offset: int): PText =
-  ## Breaks this node into two nodes at the specified offset, 
+  ## Breaks this node into two nodes at the specified offset,
   ## keeping both in the tree as siblings.
-  
+
   if offset > TextNode.data.len():
     raise newException(EIndexSizeErr, "Index out of bounds")
-  
+
   var left: string = TextNode.data.substr(0, offset)
   TextNode.data = left
   var right: string = TextNode.data.substr(offset, TextNode.data.len())
-  
-  if TextNode.FParentNode != nil:
+
+  if not isNil(TextNode.FParentNode) and not isNil(TextNode.FParentNode.childNodes):
     for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes):
       if TextNode.FParentNode.childNodes[i] == TextNode:
         var newNode: PText = TextNode.FOwnerDocument.createTextNode(right)
@@ -1042,10 +1068,10 @@ proc target*(PI: PProcessingInstruction): string =
 
   return PI.FTarget
 
-    
+
 # --Other stuff--
 # Writer
-proc addEscaped(s: string): string = 
+proc addEscaped(s: string): string =
   result = ""
   for c in items(s):
     case c
@@ -1057,10 +1083,11 @@ proc addEscaped(s: string): string =
 
 proc nodeToXml(n: PNode, indent: int = 0): string =
   result = repeatChar(indent, ' ') & "<" & n.nodeName
-  for i in items(n.Attributes):
-    result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
-  
-  if n.childNodes.len() == 0:
+  if not isNil(n.attributes):
+    for i in items(n.attributes):
+      result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
+
+  if isNil(n.childNodes) or n.childNodes.len() == 0:
     result.add("/>") # No idea why this doesn't need a \n :O
   else:
     # End the beginning of this tag
diff --git a/lib/system.nim b/lib/system.nim
index 3bb632536..1f09a6d2b 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -13,6 +13,21 @@
 ## Each module implicitly imports the System module; it must not be listed
 ## explicitly. Because of this there cannot be a user-defined module named
 ## ``system``.
+##
+## Exception hierarchy
+## ===================
+##
+## For visual convenience here is the exception inheritance hierarchy
+## represented as a tree:
+##
+## .. include:: ../doc/exception_hierarchy_fragment.txt
+##
+## Module system
+## =============
+##
+
+# That lonesome header above is to prevent :idx: entries from being mentioned
+# in the global index as part of the previous header (Exception hierarchy).
 
 type
   int* {.magic: Int.} ## default integer type; bitwidth depends on
@@ -301,9 +316,11 @@ type
   FWriteIO* = object of FIO    ## Effect describing a write IO operation.
   FExecIO* = object of FIO     ## Effect describing an executing IO operation.
 
-  E_Base* {.compilerproc.} = object of TObject ## base exception class;
-                                               ## each exception has to
-                                               ## inherit from `E_Base`.
+  E_Base* {.compilerproc.} = object of TObject ## \
+    ## Base exception class.
+    ##
+    ## Each exception has to inherit from `E_Base`. See the full `exception
+    ## hierarchy`_.
     parent: ref E_Base        ## parent exception (can be used as a stack)
     name: cstring             ## The exception's name is its Nimrod identifier.
                               ## This field is filled automatically in the
@@ -313,99 +330,142 @@ type
                                         ## is bad style.
     trace: string
 
-  EAsynch* = object of E_Base ## Abstract exception class for
-                              ## *asynchronous exceptions* (interrupts).
-                              ## This is rarely needed: Most
-                              ## exception types inherit from `ESynch`
-  ESynch* = object of E_Base  ## Abstract exception class for
-                              ## *synchronous exceptions*. Most exceptions
-                              ## should be inherited (directly or indirectly)
-                              ## from ESynch.
-  ESystem* = object of ESynch ## Abstract class for exceptions that the runtime
-                              ## system raises.
-  EIO* = object of ESystem    ## raised if an IO error occured.
-  EOS* = object of ESystem    ## raised if an operating system service failed.
+  EAsynch* = object of E_Base ## \
+    ## Abstract exception class for *asynchronous exceptions* (interrupts).
+    ##
+    ## This is rarely needed: most exception types inherit from `ESynch
+    ## <#ESynch>`_. See the full `exception hierarchy`_.
+  EControlC* = object of EAsynch ## \
+    ## Raised for Ctrl+C key presses in console applications.
+    ##
+    ## See the full `exception hierarchy`_.
+  ESynch* = object of E_Base ## \
+    ## Abstract exception class for *synchronous exceptions*.
+    ##
+    ## Most exceptions should be inherited (directly or indirectly) from
+    ## `ESynch` instead of from `EAsynch <#EAsynch>`_. See the full `exception
+    ## hierarchy`_.
+  ESystem* = object of ESynch ## \
+    ## Abstract class for exceptions that the runtime system raises.
+    ##
+    ## See the full `exception hierarchy`_.
+  EIO* = object of ESystem ## \
+    ## Raised if an IO error occured.
+    ##
+    ## See the full `exception hierarchy`_.
+  EOS* = object of ESystem ## \
+    ## Raised if an operating system service failed.
+    ##
+    ## See the full `exception hierarchy`_.
     errorCode*: int32 ## OS-defined error code describing this error.
-  EInvalidLibrary* = object of EOS ## raised if a dynamic library
-                                   ## could not be loaded.
-  EResourceExhausted* = object of ESystem ## raised if a resource request
-                                          ## could not be fullfilled.
-  EArithmetic* = object of ESynch       ## raised if any kind of arithmetic
-                                        ## error occured.
-  EDivByZero* {.compilerproc.} =
-    object of EArithmetic ## is the exception class for integer divide-by-zero
-                          ## errors.
-  EOverflow* {.compilerproc.} =
-    object of EArithmetic  ## is the exception class for integer calculations
-                           ## whose results are too large to fit in the
-                           ## provided bits.
-
-  EAccessViolation* {.compilerproc.} =
-    object of ESynch ## the exception class for invalid memory access errors
-
-  EAssertionFailed* {.compilerproc.} =
-    object of ESynch  ## is the exception class for Assert
-                      ## procedures that is raised if the
-                      ## assertion proves wrong
-
-  EControlC* = object of EAsynch        ## is the exception class for Ctrl+C
-                                        ## key presses in console applications.
-
-  EInvalidValue* = object of ESynch     ## is the exception class for string
-                                        ## and object conversion errors.
-  EInvalidKey* = object of EInvalidValue ## is the exception class if a key
-                                         ## cannot be found in a table.
-
-  EOutOfMemory* = object of ESystem     ## is the exception class for
-                                        ## unsuccessful attempts to allocate
-                                        ## memory.
-
-  EInvalidIndex* = object of ESynch     ## is raised if an array index is out
-                                        ## of bounds.
-  EInvalidField* = object of ESynch     ## is raised if a record field is not
-                                        ## accessible because its dicriminant's
-                                        ## value does not fit.
-
-  EOutOfRange* = object of ESynch       ## is raised if a range check error
-                                        ## occurred.
-
-  EStackOverflow* = object of ESystem   ## is raised if the hardware stack
-                                        ## used for subroutine calls overflowed.
-
-  ENoExceptionToReraise* = object of ESynch ## is raised if there is no
-                                            ## exception to reraise.
-
-  EInvalidObjectAssignment* =
-    object of ESynch ## is raised if an object gets assigned to its
-                     ## parent's object.
-
-  EInvalidObjectConversion* =
-    object of ESynch ## is raised if an object is converted to an incompatible
-                     ## object type.
-
-  EFloatingPoint* = object of ESynch ## base class for floating point exceptions
-  EFloatInvalidOp* {.compilerproc.} = 
-    object of EFloatingPoint ## Invalid operation according to IEEE: Raised by 
-                             ## 0.0/0.0, for example.
-  EFloatDivByZero* {.compilerproc.} = 
-    object of EFloatingPoint ## Division by zero. Divisor is zero and dividend 
-                             ## is a finite nonzero number.
-  EFloatOverflow* {.compilerproc.} = 
-    object of EFloatingPoint ## Overflow. Operation produces a result 
-                             ## that exceeds the range of the exponent
-  EFloatUnderflow* {.compilerproc.} = 
-    object of EFloatingPoint ## Underflow. Operation produces a result 
-                             ## that is too small to be represented as 
-                             ## a normal number
-  EFloatInexact* {.compilerproc.} = 
-    object of EFloatingPoint ## Inexact. Operation produces a result
-                             ## that cannot be represented with infinite
-                             ## precision -- for example, 2.0 / 3.0, log(1.1) 
-                             ## NOTE: Nimrod currently does not detect these!
-  EDeadThread* =
-    object of ESynch ## is raised if it is attempted to send a message to a
-                     ## dead thread.
-                     
+  EInvalidLibrary* = object of EOS ## \
+    ## Raised if a dynamic library could not be loaded.
+    ##
+    ## See the full `exception hierarchy`_.
+  EResourceExhausted* = object of ESystem ## \
+    ## Raised if a resource request could not be fullfilled.
+    ##
+    ## See the full `exception hierarchy`_.
+  EArithmetic* = object of ESynch ## \
+    ## Raised if any kind of arithmetic error occured.
+    ##
+    ## See the full `exception hierarchy`_.
+  EDivByZero* {.compilerproc.} = object of EArithmetic ## \
+    ## Raised for runtime integer divide-by-zero errors.
+    ##
+    ## See the full `exception hierarchy`_.
+  EOverflow* {.compilerproc.} = object of EArithmetic ## \
+    ## Raised for runtime integer overflows.
+    ##
+    ## This happens for calculations whose results are too large to fit in the
+    ## provided bits.  See the full `exception hierarchy`_.
+  EAccessViolation* {.compilerproc.} = object of ESynch ## \
+    ## Raised for invalid memory access errors
+    ##
+    ## See the full `exception hierarchy`_.
+  EAssertionFailed* {.compilerproc.} = object of ESynch ## \
+    ## Raised when assertion is proved wrong.
+    ##
+    ## Usually the result of using the `assert() template <#assert>`_.  See the
+    ## full `exception hierarchy`_.
+  EInvalidValue* = object of ESynch ## \
+    ## Raised for string and object conversion errors.
+  EInvalidKey* = object of EInvalidValue ## \
+    ## Raised if a key cannot be found in a table.
+    ##
+    ## Mostly used by the `tables <tables.html>`_ module, it can also be raised
+    ## by other collection modules like `sets <sets.html>`_ or `strtabs
+    ## <strtabs.html>`_. See the full `exception hierarchy`_.
+  EOutOfMemory* = object of ESystem ## \
+    ## Raised for unsuccessful attempts to allocate memory.
+    ##
+    ## See the full `exception hierarchy`_.
+  EInvalidIndex* = object of ESynch ## \
+    ## Raised if an array index is out of bounds.
+    ##
+    ## See the full `exception hierarchy`_.
+  EInvalidField* = object of ESynch ## \
+    ## Raised if a record field is not accessible because its dicriminant's
+    ## value does not fit.
+    ##
+    ## See the full `exception hierarchy`_.
+  EOutOfRange* = object of ESynch ## \
+    ## Raised if a range check error occurred.
+    ##
+    ## See the full `exception hierarchy`_.
+  EStackOverflow* = object of ESystem ## \
+    ## Raised if the hardware stack used for subroutine calls overflowed.
+    ##
+    ## See the full `exception hierarchy`_.
+  ENoExceptionToReraise* = object of ESynch ## \
+    ## Raised if there is no exception to reraise.
+    ##
+    ## See the full `exception hierarchy`_.
+  EInvalidObjectAssignment* = object of ESynch ## \
+    ## Raised if an object gets assigned to its parent's object.
+    ##
+    ## See the full `exception hierarchy`_.
+  EInvalidObjectConversion* = object of ESynch ## \
+    ## Raised if an object is converted to an incompatible object type.
+    ##
+    ## See the full `exception hierarchy`_.
+  EFloatingPoint* = object of ESynch ## \
+    ## Base class for floating point exceptions.
+    ##
+    ## See the full `exception hierarchy`_.
+  EFloatInvalidOp* {.compilerproc.} = object of EFloatingPoint ## \
+    ## Raised by invalid operations according to IEEE.
+    ##
+    ## Raised by ``0.0/0.0``, for example.  See the full `exception
+    ## hierarchy`_.
+  EFloatDivByZero* {.compilerproc.} = object of EFloatingPoint ## \
+    ## Raised by division by zero.
+    ##
+    ## Divisor is zero and dividend is a finite nonzero number.  See the full
+    ## `exception hierarchy`_.
+  EFloatOverflow* {.compilerproc.} = object of EFloatingPoint ## \
+    ## Raised for overflows.
+    ##
+    ## The operation produced a result that exceeds the range of the exponent.
+    ## See the full `exception hierarchy`_.
+  EFloatUnderflow* {.compilerproc.} = object of EFloatingPoint ## \
+    ## Raised for underflows.
+    ##
+    ## The operation produced a result that is too small to be represented as a
+    ## normal number. See the full `exception hierarchy`_.
+  EFloatInexact* {.compilerproc.} = object of EFloatingPoint ## \
+    ## Raised for inexact results.
+    ##
+    ## The operation produced a result that cannot be represented with infinite
+    ## precision -- for example: ``2.0 / 3.0, log(1.1)``
+    ##
+    ## **NOTE**: Nimrod currently does not detect these!  See the full
+    ## `exception hierarchy`_.
+  EDeadThread* = object of ESynch ## \
+    ## Raised if it is attempted to send a message to a dead thread.
+    ##
+    ## See the full `exception hierarchy`_.
+
   TResult* = enum Failure, Success
 
 proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.}
@@ -783,7 +843,7 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
   result = s.a <= value and value <= s.b
 
 template `in` * (x, y: expr): expr {.immediate.} = contains(y, x)
-  ## Suger for contains
+  ## Sugar for contains
   ##
   ## .. code-block:: Nimrod
   ##   assert(1 in (1..3) == true)
@@ -814,9 +874,9 @@ proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.}
   ## Checks if `x` has a type of `y`
   ##
   ## .. code-block:: Nimrod
-  ##   assert(EFloatingPoint is EBase)
-  ##   assert(EIO is ESystem)
-  ##   assert(EDivByZero is EBase)
+  ##   assert(EFloatingPoint of EBase)
+  ##   assert(EIO of ESystem)
+  ##   assert(EDivByZero of EBase)
 
 proc cmp*[T](x, y: T): int {.procvar.} =
   ## Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y
@@ -1052,7 +1112,7 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =
   ## containers should also call their adding proc `add` for consistency.
   ## Generic code becomes much easier to write if the Nimrod naming scheme is
   ## respected.
-  var xl = x.len
+  let xl = x.len
   setLen(x, xl + y.len)
   for i in 0..high(y): x[xl+i] = y[i]
 
@@ -1066,20 +1126,20 @@ proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
 proc del*[T](x: var seq[T], i: int) {.noSideEffect.} = 
   ## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`.
   ## This is an O(1) operation.
-  var xl = x.len
+  let xl = x.len
   shallowCopy(x[i], x[xl-1])
   setLen(x, xl-1)
   
 proc delete*[T](x: var seq[T], i: int) {.noSideEffect.} = 
   ## deletes the item at index `i` by moving ``x[i+1..]`` by one position.
   ## This is an O(n) operation.
-  var xl = x.len
+  let xl = x.len
   for j in i..xl-2: shallowCopy(x[j], x[j+1]) 
   setLen(x, xl-1)
   
 proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} = 
   ## inserts `item` into `x` at position `i`.
-  var xl = x.len
+  let xl = x.len
   setLen(x, xl+1)
   var j = xl-1
   while j >= i:
@@ -2001,7 +2061,8 @@ type
     procname*: cstring  ## name of the proc that is currently executing
     line*: int          ## line number of the proc that is currently executing
     filename*: cstring  ## filename of the proc that is currently executing
-    len*: int           ## length of the inspectable slots
+    len*: int16         ## length of the inspectable slots
+    calldepth*: int16   ## used for max call depth checking
 
 when defined(JS):
   proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
@@ -2025,19 +2086,25 @@ elif hostOS != "standalone":
   {.pop.}
 
 proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO], gcsafe.}
-  ## special built-in that takes a variable number of arguments. Each argument
+  ## Writes and flushes the parameters to the standard output.
+  ##
+  ## Special built-in that takes a variable number of arguments. Each argument
   ## is converted to a string via ``$``, so it works for user-defined
   ## types that have an overloaded ``$`` operator.
-  ## It is roughly equivalent to ``writeln(stdout, x); flush(stdout)``, but
+  ## It is roughly equivalent to ``writeln(stdout, x); flushFile(stdout)``, but
   ## available for the JavaScript target too.
+  ##
   ## Unlike other IO operations this is guaranteed to be thread-safe as
-  ## ``echo`` is very often used for debugging convenience.
+  ## ``echo`` is very often used for debugging convenience. If you want to use
+  ## ``echo`` inside a `proc without side effects
+  ## <manual.html#nosideeffect-pragma>`_ you can use `debugEcho <#debugEcho>`_
+  ## instead.
 
 proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect, 
                                          tags: [], raises: [].}
-  ## Same as ``echo``, but as a special semantic rule, ``debugEcho`` pretends
-  ## to be free of side effects, so that it can be used for debugging routines
-  ## marked as ``noSideEffect``.
+  ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho``
+  ## pretends to be free of side effects, so that it can be used for debugging
+  ## routines marked as `noSideEffect <manual.html#nosideeffect-pragma>`_.
 
 template newException*(exceptn: typedesc, message: string): expr =
   ## creates an exception object of type ``exceptn`` and sets its ``msg`` field
@@ -2990,9 +3057,13 @@ proc locals*(): TObject {.magic: "Locals", noSideEffect.} =
   ##   # -> B is 1
   discard
 
-proc deepCopy*[T](x: T): T {.magic: "DeepCopy", noSideEffect.} = discard
-  ## performs a deep copy of `x`. This is also used by the code generator
-  ## for the implementation of ``spawn``.
+when hostOS != "standalone" and not defined(NimrodVM) and not defined(JS):
+  proc deepCopy*[T](x: var T, y: T) {.noSideEffect, magic: "DeepCopy".} =
+    ## performs a deep copy of `x`. This is also used by the code generator
+    ## for the implementation of ``spawn``.
+    discard
+
+  include "system/deepcopy"
 
 {.pop.} #{.push warning[GcMem]: off.}
 
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 5111bc3cf..511a006d3 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -106,7 +106,7 @@ proc c_fopen(filename, mode: cstring): C_TextFileStar {.
   importc: "fopen", header: "<stdio.h>".}
 proc c_fclose(f: C_TextFileStar) {.importc: "fclose", header: "<stdio.h>".}
 
-proc c_sprintf(buf, frmt: cstring) {.header: "<stdio.h>", 
+proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>", 
   importc: "sprintf", varargs, noSideEffect.}
   # we use it only in a way that cannot lead to security issues
 
diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim
index 43b3f0438..82ec5dbde 100644
--- a/lib/system/atomics.nim
+++ b/lib/system/atomics.nim
@@ -7,7 +7,7 @@
 #    distribution, for details about the copyright.
 #
 
-## Atomic operations for Nimrod.
+# Atomic operations for Nimrod.
 {.push stackTrace:off.}
 
 const someGcc = defined(gcc) or defined(llvm_gcc) or defined(clang)
diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim
new file mode 100644
index 000000000..bd8d00527
--- /dev/null
+++ b/lib/system/deepcopy.nim
@@ -0,0 +1,141 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2014 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.gcsafe.}
+proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.gcsafe.} =
+  var
+    d = cast[TAddress](dest)
+    s = cast[TAddress](src)
+  case n.kind
+  of nkSlot:
+    genericDeepCopyAux(cast[pointer](d +% n.offset), 
+                       cast[pointer](s +% n.offset), n.typ)
+  of nkList:
+    for i in 0..n.len-1:
+      genericDeepCopyAux(dest, src, n.sons[i])
+  of nkCase:
+    var dd = selectBranch(dest, n)
+    var m = selectBranch(src, n)
+    # reset if different branches are in use; note different branches also
+    # imply that's not self-assignment (``x = x``)!
+    if m != dd and dd != nil: 
+      genericResetAux(dest, dd)
+    copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
+            n.typ.size)
+    if m != nil:
+      genericDeepCopyAux(dest, src, m)
+  of nkNone: sysAssert(false, "genericDeepCopyAux")
+
+proc copyDeepString(src: NimString): NimString {.inline.} =
+  if src != nil:
+    result = rawNewString(src.space)
+    result.len = src.len
+    c_memcpy(result.data, src.data, (src.len + 1) * sizeof(char))
+
+proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) =
+  var
+    d = cast[TAddress](dest)
+    s = cast[TAddress](src)
+  sysAssert(mt != nil, "genericDeepCopyAux 2")
+  case mt.kind
+  of tyString:
+    var x = cast[PPointer](dest)
+    var s2 = cast[PPointer](s)[]
+    if s2 == nil:
+      unsureAsgnRef(x, s2)
+    else:
+      unsureAsgnRef(x, copyDeepString(cast[NimString](s2)))
+  of tySequence:
+    var s2 = cast[PPointer](src)[]
+    var seq = cast[PGenericSeq](s2)
+    var x = cast[PPointer](dest)
+    if s2 == nil:
+      unsureAsgnRef(x, s2)
+      return
+    sysAssert(dest != nil, "genericDeepCopyAux 3")
+    unsureAsgnRef(x, newSeq(mt, seq.len))
+    var dst = cast[TAddress](cast[PPointer](dest)[])
+    for i in 0..seq.len-1:
+      genericDeepCopyAux(
+        cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
+        cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +%
+                     GenericSeqSize),
+        mt.base)
+  of tyObject:
+    # we need to copy m_type field for tyObject, as it could be empty for
+    # sequence reallocations:
+    var pint = cast[ptr PNimType](dest)
+    pint[] = cast[ptr PNimType](src)[]
+    if mt.base != nil:
+      genericDeepCopyAux(dest, src, mt.base)
+    genericDeepCopyAux(dest, src, mt.node)
+  of tyTuple:
+    genericDeepCopyAux(dest, src, mt.node)
+  of tyArray, tyArrayConstr:
+    for i in 0..(mt.size div mt.base.size)-1:
+      genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size),
+                         cast[pointer](s +% i*% mt.base.size), mt.base)
+  of tyRef:
+    if mt.base.deepCopy != nil:
+      let z = mt.base.deepCopy(cast[PPointer](src)[])
+      unsureAsgnRef(cast[PPointer](dest), z)
+    else:
+      # we modify the header of the cell temporarily; instead of the type
+      # field we store a forwarding pointer. XXX This is bad when the cloning
+      # fails due to OOM etc.
+      let s2 = cast[PPointer](src)[]
+      if s2 == nil:
+        unsureAsgnRef(cast[PPointer](dest), s2)
+        return
+      when defined(usrToCell):
+        # unfortunately we only have cycle detection for our native GCs.
+        let x = usrToCell(s2)
+        let forw = cast[int](x.typ)
+        if (forw and 1) == 1:
+          # we stored a forwarding pointer, so let's use that:
+          let z = cast[pointer](forw and not 1)
+          unsureAsgnRef(cast[PPointer](dest), z)
+        else:
+          let realType = x.typ
+          let z = newObj(realType, realType.base.size)
+          
+          unsureAsgnRef(cast[PPointer](dest), z)
+          x.typ = cast[PNimType](cast[int](z) or 1)
+          genericDeepCopyAux(z, s2, realType.base)
+          x.typ = realType
+      else:
+        let realType = mt
+        let z = newObj(realType, realType.base.size)        
+        unsureAsgnRef(cast[PPointer](dest), z)
+        genericDeepCopyAux(z, s2, realType.base)        
+  of tyPtr:
+    # no cycle check here, but also not really required
+    if mt.base.deepCopy != nil:
+      cast[PPointer](dest)[] = mt.base.deepCopy(cast[PPointer](s)[])
+    else:
+      cast[PPointer](dest)[] = cast[PPointer](s)[]
+  else:
+    copyMem(dest, src, mt.size)
+
+proc genericDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
+  genericDeepCopyAux(dest, src, mt)
+
+proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} =
+  # also invoked for 'string'
+  var src = src
+  genericDeepCopy(dest, addr(src), mt)
+
+proc genericDeepCopyOpenArray(dest, src: pointer, len: int,
+                            mt: PNimType) {.compilerproc.} =
+  var
+    d = cast[TAddress](dest)
+    s = cast[TAddress](src)
+  for i in 0..len-1:
+    genericDeepCopy(cast[pointer](d +% i*% mt.base.size),
+                    cast[pointer](s +% i*% mt.base.size), mt.base)
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 63a61183f..e1a5a958f 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2014 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -44,16 +44,6 @@ var
     # a global variable for the root of all try blocks
   currException {.rtlThreadVar.}: ref E_Base
 
-when defined(nimRequiresNimFrame):
-  proc nimFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} =
-    s.prev = framePtr
-    framePtr = s
-else:
-  proc pushFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} =
-    # XXX only for backwards compatibility
-    s.prev = framePtr
-    framePtr = s
-
 proc popFrame {.compilerRtl, inl.} =
   framePtr = framePtr.prev
 
@@ -280,6 +270,23 @@ proc getStackTrace(e: ref E_Base): string =
   else:
     result = ""
 
+when defined(nimRequiresNimFrame):
+  proc stackOverflow() {.noinline.} =
+    writeStackTrace()
+    showErrorMessage("Stack overflow\n")
+    quitOrDebug()
+
+  proc nimFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} =
+    s.calldepth = if framePtr == nil: 0 else: framePtr.calldepth+1
+    s.prev = framePtr
+    framePtr = s
+    if s.calldepth == 2000: stackOverflow()
+else:
+  proc pushFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} =
+    # XXX only for backwards compatibility
+    s.prev = framePtr
+    framePtr = s
+
 when defined(endb):
   var
     dbgAborting: bool # whether the debugger wants to abort
diff --git a/lib/system/hti.nim b/lib/system/hti.nim
index 64174e60f..5689f92b3 100644
--- a/lib/system/hti.nim
+++ b/lib/system/hti.nim
@@ -86,6 +86,7 @@ type
     node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
     finalizer: pointer # the finalizer for the type
     marker: proc (p: pointer, op: int) {.nimcall, gcsafe.} # marker proc for GC
+    deepcopy: proc (p: pointer): pointer {.nimcall, gcsafe.}
   PNimType = ptr TNimType
   
 # node.len may be the ``first`` element of a set
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index 52f8873cf..8766906e3 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -639,3 +639,87 @@ proc addChar(x: string, c: char) {.compilerproc, asmNoStackFrame.} =
   """
 
 {.pop.}
+
+proc tenToThePowerOf(b: int): BiggestFloat =
+  var b = b
+  var a = 10.0
+  result = 1.0
+  while true:
+    if (b and 1) == 1:
+      result = result * a
+    b = b shr 1
+    if b == 0: break
+    a = a * a
+
+const
+  IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
+
+# XXX use JS's native way here
+proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start = 0): int {.
+                          compilerProc.} =
+  var
+    esign = 1.0
+    sign = 1.0
+    i = start
+    exponent: int
+    flags: int
+  number = 0.0
+  if s[i] == '+': inc(i)
+  elif s[i] == '-':
+    sign = -1.0
+    inc(i)
+  if s[i] == 'N' or s[i] == 'n':
+    if s[i+1] == 'A' or s[i+1] == 'a':
+      if s[i+2] == 'N' or s[i+2] == 'n':
+        if s[i+3] notin IdentChars:
+          number = NaN
+          return i+3 - start
+    return 0
+  if s[i] == 'I' or s[i] == 'i':
+    if s[i+1] == 'N' or s[i+1] == 'n':
+      if s[i+2] == 'F' or s[i+2] == 'f':
+        if s[i+3] notin IdentChars: 
+          number = Inf*sign
+          return i+3 - start
+    return 0
+  while s[i] in {'0'..'9'}:
+    # Read integer part
+    flags = flags or 1
+    number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
+    inc(i)
+    while s[i] == '_': inc(i)
+  # Decimal?
+  if s[i] == '.':
+    var hd = 1.0
+    inc(i)
+    while s[i] in {'0'..'9'}:
+      # Read fractional part
+      flags = flags or 2
+      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
+      hd = hd * 10.0
+      inc(i)
+      while s[i] == '_': inc(i)
+    number = number / hd # this complicated way preserves precision
+  # Again, read integer and fractional part
+  if flags == 0: return 0
+  # Exponent?
+  if s[i] in {'e', 'E'}:
+    inc(i)
+    if s[i] == '+':
+      inc(i)
+    elif s[i] == '-':
+      esign = -1.0
+      inc(i)
+    if s[i] notin {'0'..'9'}:
+      return 0
+    while s[i] in {'0'..'9'}:
+      exponent = exponent * 10 + ord(s[i]) - ord('0')
+      inc(i)
+      while s[i] == '_': inc(i)
+  # Calculate Exponent
+  let hd = tenToThePowerOf(exponent)
+  if esign > 0.0: number = number * hd
+  else:           number = number / hd
+  # evaluate sign
+  number = number * sign
+  result = i - start
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index 487bac052..f8f949668 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -17,12 +17,12 @@ proc reprFloat(x: float): string {.compilerproc.} = return $x
 
 proc reprPointer(x: pointer): string {.compilerproc.} =
   var buf: array [0..59, char]
-  c_sprintf(buf, "%p", x)
+  discard c_sprintf(buf, "%p", x)
   return $buf
 
 proc `$`(x: uint64): string =
   var buf: array [0..59, char]
-  c_sprintf(buf, "%llu", x)
+  discard c_sprintf(buf, "%llu", x)
   return $buf
 
 proc reprStrAux(result: var string, s: string) =
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 4244bae4c..9db8ce378 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -250,10 +250,115 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
   for j in 0..i div 2 - 1:
     swap(result[j], result[i-j-1])
 
-proc nimFloatToStr(x: float): string {.compilerproc.} =
-  var buf: array [0..59, char]
-  c_sprintf(buf, "%#.16e", x)
-  return $buf
+proc nimFloatToStr(f: float): string {.compilerproc.} =
+  var buf: array [0..64, char]
+  var n: int = c_sprintf(buf, "%.16g", f)
+  var hasDot = false
+  for i in 0..n-1:
+    if buf[i] == ',':
+      buf[i] = '.'
+      hasDot = true
+    elif buf[i] in {'a'..'z', 'A'..'Z', '.'}: 
+      hasDot = true
+  if not hasDot:
+    buf[n] = '.'
+    buf[n+1] = '0'
+    buf[n+2] = '\0'
+  result = $buf
+
+proc strtod(buf: cstring, endptr: ptr cstring): float64 {.importc,
+  header: "<stdlib.h>", noSideEffect.}
+
+var decimalPoint: char
+
+proc getDecimalPoint(): char =
+  result = decimalPoint
+  if result == '\0':
+    if strtod("0,5", nil) == 0.5: result = ','
+    else: result = '.'
+    # yes this is threadsafe in practice, spare me:
+    decimalPoint = result
+
+const
+  IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
+
+proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
+                          start = 0): int {.compilerProc.} =
+  # This routine leverages `strtod()` for the non-trivial task of
+  # parsing floating point numbers correctly. Because `strtod()` is
+  # locale-dependent with respect to the radix character, we create
+  # a copy where the decimal point is replaced with the locale's
+  # radix character.
+  var
+    i = start
+    sign = 1.0
+    t: array[128, char]
+    ti = 0
+    hasdigits = false
+
+  template addToBuf(c) =
+    if ti < t.high:
+      t[ti] = c; inc(ti)
+  
+  # Sign?
+  if s[i] == '+' or s[i] == '-':
+    if s[i] == '-':
+      sign = -1.0
+    t[ti] = s[i]
+    inc(i); inc(ti)
+
+  # NaN?
+  if s[i] == 'N' or s[i] == 'n':
+    if s[i+1] == 'A' or s[i+1] == 'a':
+      if s[i+2] == 'N' or s[i+2] == 'n':
+        if s[i+3] notin IdentChars:
+          number = NaN
+          return i+3 - start
+    return 0
+
+  # Inf?
+  if s[i] == 'I' or s[i] == 'i':
+    if s[i+1] == 'N' or s[i+1] == 'n':
+      if s[i+2] == 'F' or s[i+2] == 'f':
+        if s[i+3] notin IdentChars: 
+          number = Inf*sign
+          return i+3 - start
+    return 0
+
+  # Integer part?
+  while s[i] in {'0'..'9'}:
+    hasdigits = true
+    addToBuf(s[i])
+    inc(i);
+    while s[i] == '_': inc(i)
+
+  # Fractional part?
+  if s[i] == '.':
+    addToBuf(getDecimalPoint())
+    inc(i)
+    while s[i] in {'0'..'9'}:
+      hasdigits = true
+      addToBuf(s[i])
+      inc(i)
+      while s[i] == '_': inc(i)
+  if not hasdigits:
+    return 0
+
+  # Exponent?
+  if s[i] in {'e', 'E'}:
+    addToBuf(s[i])
+    inc(i)
+    if s[i] in {'+', '-'}:
+      addToBuf(s[i])
+      inc(i)
+    if s[i] notin {'0'..'9'}:
+      return 0
+    while s[i] in {'0'..'9'}:
+      addToBuf(s[i])
+      inc(i)
+      while s[i] == '_': inc(i)
+  number = strtod(t, nil)
+  result = i - start
 
 proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
   result = newString(sizeof(x)*4)
diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim
index e2a5d87e9..e9673888c 100644
--- a/lib/system/widestrs.nim
+++ b/lib/system/widestrs.nim
@@ -7,8 +7,8 @@
 #    distribution, for details about the copyright.
 #
 
-## Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system
-## module! Do not import it directly!
+# Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system
+# module! Do not import it directly!
 
 when not defined(NimString):
   {.error: "You must not import this module explicitly".}
diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim
index d9e7b8ee4..764aaa97d 100644
--- a/tests/closure/tclosure.nim
+++ b/tests/closure/tclosure.nim
@@ -1,7 +1,6 @@
 discard """
   file: "tclosure.nim"
-  output: "2 4 6 8 10"
-  disabled: true
+  output: "1 3 6 11 20"
 """
 # Test the closure implementation
 
@@ -30,7 +29,8 @@ proc testA() =
 testA()
 
 myData.each do (x: int):
-  write(stout, x)
+  write(stdout, x)
+  write(stdout, " ")
 
 #OUT 2 4 6 8 10
 
@@ -42,6 +42,6 @@ type
 proc getInterf(): ITest =
   var shared: int
   
-  return (setter: proc (x) = shared = x,
+  return (setter: proc (x: int) = shared = x,
           getter: proc (): int = return shared)
 
diff --git a/tests/closure/tforum.nim b/tests/closure/tforum.nim
new file mode 100644
index 000000000..4f6a16ff7
--- /dev/null
+++ b/tests/closure/tforum.nim
@@ -0,0 +1,44 @@
+discard """
+  output: '''asdas
+processClient end
+false
+'''
+"""
+
+type
+  PAsyncHttpServer = ref object
+    value: string
+  PFutureBase = ref object
+    callback: proc () {.closure.}
+    value: string
+    failed: bool
+
+proc accept(server: PAsyncHttpServer): PFutureBase =
+  new(result)
+  result.callback = proc () =
+    discard
+  server.value = "hahaha"
+
+proc processClient(): PFutureBase =
+  new(result)
+
+proc serve(server: PAsyncHttpServer): PFutureBase =
+  iterator serveIter(): PFutureBase {.closure.} =
+    echo server.value
+    while true:
+      var acceptAddrFut = server.accept()
+      yield acceptAddrFut
+      var fut = acceptAddrFut.value
+
+      var f = processClient()
+      f.callback =
+        proc () =
+          echo("processClient end")
+          echo(f.failed)
+      yield f
+  var x = serveIter
+  for i in 0 .. 1:
+    result = x()
+    result.callback()
+
+discard serve(PAsyncHttpServer(value: "asdas"))
diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim
new file mode 100644
index 000000000..48e5186f0
--- /dev/null
+++ b/tests/closure/tjester.nim
@@ -0,0 +1,32 @@
+discard """
+  output: '''baro0'''
+"""
+
+type
+  Future[T] = ref object
+    data: T
+    callback: proc () {.closure.}
+
+proc cbOuter(response: string) {.closure, discardable.} =
+  iterator cbIter(): Future[int] {.closure.} =
+    for i in 0..7:
+      proc foo(): int =
+        iterator fooIter(): Future[int] {.closure.} =
+          echo response, i
+          yield Future[int](data: 17)
+        var iterVar = fooIter
+        iterVar().data
+      yield Future[int](data: foo())
+      
+  var iterVar2 = cbIter
+  proc cb2() {.closure.} =
+    try:
+      if not finished(iterVar2):
+        let next = iterVar2()
+        if next != nil:
+          next.callback = cb2
+    except:
+      echo "WTF"
+  cb2()
+
+cbOuter "baro"
diff --git a/tests/closure/tnestedclosure.nim b/tests/closure/tnestedclosure.nim
new file mode 100644
index 000000000..c8f1e231b
--- /dev/null
+++ b/tests/closure/tnestedclosure.nim
@@ -0,0 +1,51 @@
+discard """
+  output: '''foo88
+23 24foo 88
+foo88
+23 24foo 88
+hohoho'''
+"""
+
+# test nested closure
+proc main(param: int) =
+  var foo = 23
+  proc outer(outerParam: string) =
+    var outerVar = 88
+    echo outerParam, outerVar
+    proc inner() =
+      block Test:
+        echo foo, " ", param, outerParam, " ", outerVar
+    inner()
+  outer("foo")
+
+# test simple closure within dummy 'main':
+proc dummy =
+  proc main2(param: int) =
+    var foo = 23
+    proc outer(outerParam: string) =
+      var outerVar = 88
+      echo outerParam, outerVar
+      proc inner() =
+        block Test:
+          echo foo, " ", param, outerParam, " ", outerVar
+      inner()
+    outer("foo")
+  main2(24)
+
+dummy()
+
+main(24)
+
+# Jester + async triggered this bug:
+proc cbOuter() =
+  var response = "hohoho"
+  block:
+    proc cbIter() =
+      block:
+        proc fooIter() =
+          echo response
+        fooIter()
+        
+    cbIter()
+
+cbOuter()
diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim
index e5236aaab..f0ea3c5c6 100644
--- a/tests/destructor/tdestructor.nim
+++ b/tests/destructor/tdestructor.nim
@@ -55,14 +55,14 @@ type
         q: TMyGeneric3[TMyObj, int, int]
       r: string
 
-proc destruct(o: var TMyObj) {.destructor.} =
+proc destroy(o: var TMyObj) {.override.} =
   if o.p != nil: dealloc o.p
   echo "myobj destroyed"
 
-proc destroy(o: var TMyGeneric1) {.destructor.} =
+proc destroy(o: var TMyGeneric1) {.override.} =
   echo "mygeneric1 destroyed"
 
-proc destroy[A, B](o: var TMyGeneric2[A, B]) {.destructor.} =
+proc destroy[A, B](o: var TMyGeneric2[A, B]) {.override.} =
   echo "mygeneric2 destroyed"
 
 proc open: TMyObj =
diff --git a/tests/destructor/tdestructor2.nim b/tests/destructor/tdestructor2.nim
index da9192a3f..a5b62860c 100644
--- a/tests/destructor/tdestructor2.nim
+++ b/tests/destructor/tdestructor2.nim
@@ -8,7 +8,7 @@ type
     x, y: int
     p: pointer
     
-proc destruct(o: var TMyObj) {.destructor.} =
+proc destroy(o: var TMyObj) {.override.} =
   if o.p != nil: dealloc o.p
   
 proc open: TMyObj =
diff --git a/tests/float/tfloat4.nim b/tests/float/tfloat4.nim
new file mode 100644
index 000000000..960c4e5f7
--- /dev/null
+++ b/tests/float/tfloat4.nim
@@ -0,0 +1,42 @@
+import math, strutils
+
+proc c_sprintf(buf, fmt: cstring) {.importc:"sprintf", header: "<stdio.h>", varargs.}
+
+proc floatToStr(f: float64): string =
+  var buffer: array[128, char]
+  c_sprintf(buffer, "%.16e", f)
+  result = ""
+  for ch in buffer:
+    if ch == '\0':
+      return
+    add(result, ch)
+
+let testFloats = [
+  "0", "-1", "1", "1.", ".3", "3.3", "-.3", "-99.99",
+  "1.1e10", "-2e100", "1.234e-10", "1.234e+10",
+  "-inf", "inf", "+inf",
+  "3.14159265358979323846264338327950288",
+  "1.57079632679489661923132169163975144",
+  "0.785398163397448309615660845819875721",
+  "1.41421356237309504880168872420969808",
+  "0.707106781186547524400844362104849039",
+  "2.71828182845904523536028747135266250",
+  "0.00097656250000000021684043449710088680149056017398834228515625"
+]
+
+for num in testFloats:
+  assert num.parseFloat.floatToStr.parseFloat == num.parseFloat
+
+assert "0".parseFloat == 0.0
+assert "-.1".parseFloat == -0.1
+assert "2.5e1".parseFloat == 25.0
+assert "1e10".parseFloat == 10_000_000_000.0
+assert "0.000_005".parseFloat == 5.000_000e-6
+assert "1.234_567e+2".parseFloat == 123.4567
+assert "1e1_00".parseFloat == "1e100".parseFloat
+assert "3.1415926535897932384626433".parseFloat ==
+       3.1415926535897932384626433
+assert "2.71828182845904523536028747".parseFloat ==
+       2.71828182845904523536028747
+assert 0.00097656250000000021684043449710088680149056017398834228515625 ==
+     "0.00097656250000000021684043449710088680149056017398834228515625".parseFloat
diff --git a/tests/manyloc/keineschweine/lib/gl.nim b/tests/manyloc/keineschweine/lib/gl.nim
new file mode 100644
index 000000000..9387b5bc9
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/gl.nim
@@ -0,0 +1,1536 @@
+#
+#
+#  Adaption of the delphi3d.net OpenGL units to FreePascal
+#  Sebastian Guenther (sg@freepascal.org) in 2002
+#  These units are free to use
+#
+#******************************************************************************
+# Converted to Delphi by Tom Nuydens (tom@delphi3d.net)                        
+# For the latest updates, visit Delphi3D: http://www.delphi3d.net              
+#******************************************************************************
+
+when defined(windows): 
+  {.push, callconv: stdcall.}
+else: 
+  {.push, callconv: cdecl.}
+when defined(windows): 
+  const 
+    dllname* = "opengl32.dll"
+elif defined(macosx): 
+  const 
+    dllname* = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
+else: 
+  const 
+    dllname* = "libGL.so.1"
+type 
+  PGLenum* = ptr TGLenum
+  PGLboolean* = ptr TGLboolean
+  PGLbitfield* = ptr TGLbitfield
+  TGLbyte* = int8
+  PGLbyte* = ptr TGlbyte
+  PGLshort* = ptr TGLshort
+  PGLint* = ptr TGLint
+  PGLsizei* = ptr TGLsizei
+  PGLubyte* = ptr TGLubyte
+  PGLushort* = ptr TGLushort
+  PGLuint* = ptr TGLuint
+  PGLfloat* = ptr TGLfloat
+  PGLclampf* = ptr TGLclampf
+  PGLdouble* = ptr TGLdouble
+  PGLclampd* = ptr TGLclampd
+  PGLvoid* = Pointer
+  PPGLvoid* = ptr PGLvoid
+  TGLenum* = cint
+  TGLboolean* = bool
+  TGLbitfield* = cint
+  TGLshort* = int16
+  TGLint* = cint
+  TGLsizei* = int
+  TGLubyte* = int8
+  TGLushort* = int16
+  TGLuint* = cint
+  TGLfloat* = float32
+  TGLclampf* = float32
+  TGLdouble* = float
+  TGLclampd* = float
+
+const                         # Version
+  GL_VERSION_1_1* = 1         # AccumOp
+  constGL_ACCUM* = 0x00000100
+  GL_LOAD* = 0x00000101
+  GL_RETURN* = 0x00000102
+  GL_MULT* = 0x00000103
+  GL_ADD* = 0x00000104        # AlphaFunction
+  GL_NEVER* = 0x00000200
+  GL_LESS* = 0x00000201
+  GL_EQUAL* = 0x00000202
+  GL_LEQUAL* = 0x00000203
+  GL_GREATER* = 0x00000204
+  GL_NOTEQUAL* = 0x00000205
+  GL_GEQUAL* = 0x00000206
+  GL_ALWAYS* = 0x00000207     # AttribMask
+  GL_CURRENT_BIT* = 0x00000001
+  GL_POINT_BIT* = 0x00000002
+  GL_LINE_BIT* = 0x00000004
+  GL_POLYGON_BIT* = 0x00000008
+  GL_POLYGON_STIPPLE_BIT* = 0x00000010
+  GL_PIXEL_MODE_BIT* = 0x00000020
+  GL_LIGHTING_BIT* = 0x00000040
+  GL_FOG_BIT* = 0x00000080
+  GL_DEPTH_BUFFER_BIT* = 0x00000100
+  GL_ACCUM_BUFFER_BIT* = 0x00000200
+  GL_STENCIL_BUFFER_BIT* = 0x00000400
+  GL_VIEWPORT_BIT* = 0x00000800
+  GL_TRANSFORM_BIT* = 0x00001000
+  GL_ENABLE_BIT* = 0x00002000
+  GL_COLOR_BUFFER_BIT* = 0x00004000
+  GL_HINT_BIT* = 0x00008000
+  GL_EVAL_BIT* = 0x00010000
+  GL_LIST_BIT* = 0x00020000
+  GL_TEXTURE_BIT* = 0x00040000
+  GL_SCISSOR_BIT* = 0x00080000
+  GL_ALL_ATTRIB_BITS* = 0x000FFFFF # BeginMode
+  GL_POINTS* = 0x00000000
+  GL_LINES* = 0x00000001
+  GL_LINE_LOOP* = 0x00000002
+  GL_LINE_STRIP* = 0x00000003
+  GL_TRIANGLES* = 0x00000004
+  GL_TRIANGLE_STRIP* = 0x00000005
+  GL_TRIANGLE_FAN* = 0x00000006
+  GL_QUADS* = 0x00000007
+  GL_QUAD_STRIP* = 0x00000008
+  GL_POLYGON* = 0x00000009    # BlendingFactorDest
+  GL_ZERO* = 0
+  GL_ONE* = 1
+  GL_SRC_COLOR* = 0x00000300
+  GL_ONE_MINUS_SRC_COLOR* = 0x00000301
+  GL_SRC_ALPHA* = 0x00000302
+  GL_ONE_MINUS_SRC_ALPHA* = 0x00000303
+  GL_DST_ALPHA* = 0x00000304
+  GL_ONE_MINUS_DST_ALPHA* = 0x00000305 # BlendingFactorSrc
+                                       #      GL_ZERO
+                                       #      GL_ONE
+  GL_DST_COLOR* = 0x00000306
+  GL_ONE_MINUS_DST_COLOR* = 0x00000307
+  GL_SRC_ALPHA_SATURATE* = 0x00000308 #      GL_SRC_ALPHA
+                                      #      GL_ONE_MINUS_SRC_ALPHA
+                                      #      GL_DST_ALPHA
+                                      #      GL_ONE_MINUS_DST_ALPHA
+                                      # Boolean
+  GL_TRUE* = 1
+  GL_FALSE* = 0               # ClearBufferMask
+                              #      GL_COLOR_BUFFER_BIT
+                              #      GL_ACCUM_BUFFER_BIT
+                              #      GL_STENCIL_BUFFER_BIT
+                              #      GL_DEPTH_BUFFER_BIT
+                              # ClientArrayType
+                              #      GL_VERTEX_ARRAY
+                              #      GL_NORMAL_ARRAY
+                              #      GL_COLOR_ARRAY
+                              #      GL_INDEX_ARRAY
+                              #      GL_TEXTURE_COORD_ARRAY
+                              #      GL_EDGE_FLAG_ARRAY
+                              # ClipPlaneName
+  GL_CLIP_PLANE0* = 0x00003000
+  GL_CLIP_PLANE1* = 0x00003001
+  GL_CLIP_PLANE2* = 0x00003002
+  GL_CLIP_PLANE3* = 0x00003003
+  GL_CLIP_PLANE4* = 0x00003004
+  GL_CLIP_PLANE5* = 0x00003005 # ColorMaterialFace
+                               #      GL_FRONT
+                               #      GL_BACK
+                               #      GL_FRONT_AND_BACK
+                               # ColorMaterialParameter
+                               #      GL_AMBIENT
+                               #      GL_DIFFUSE
+                               #      GL_SPECULAR
+                               #      GL_EMISSION
+                               #      GL_AMBIENT_AND_DIFFUSE
+                               # ColorPointerType
+                               #      GL_BYTE
+                               #      GL_UNSIGNED_BYTE
+                               #      GL_SHORT
+                               #      GL_UNSIGNED_SHORT
+                               #      GL_INT
+                               #      GL_UNSIGNED_INT
+                               #      GL_FLOAT
+                               #      GL_DOUBLE
+                               # CullFaceMode
+                               #      GL_FRONT
+                               #      GL_BACK
+                               #      GL_FRONT_AND_BACK
+                               # DataType
+  GL_BYTE* = 0x00001400
+  GL_UNSIGNED_BYTE* = 0x00001401
+  GL_SHORT* = 0x00001402
+  GL_UNSIGNED_SHORT* = 0x00001403
+  GL_INT* = 0x00001404
+  GL_UNSIGNED_INT* = 0x00001405
+  GL_FLOAT* = 0x00001406
+  GL_2_BYTES* = 0x00001407
+  GL_3_BYTES* = 0x00001408
+  GL_4_BYTES* = 0x00001409
+  GL_DOUBLE* = 0x0000140A     # DepthFunction
+                              #      GL_NEVER
+                              #      GL_LESS
+                              #      GL_EQUAL
+                              #      GL_LEQUAL
+                              #      GL_GREATER
+                              #      GL_NOTEQUAL
+                              #      GL_GEQUAL
+                              #      GL_ALWAYS
+                              # DrawBufferMode
+  GL_NONE* = 0
+  GL_FRONT_LEFT* = 0x00000400
+  GL_FRONT_RIGHT* = 0x00000401
+  GL_BACK_LEFT* = 0x00000402
+  GL_BACK_RIGHT* = 0x00000403
+  GL_FRONT* = 0x00000404
+  GL_BACK* = 0x00000405
+  GL_LEFT* = 0x00000406
+  GL_RIGHT* = 0x00000407
+  GL_FRONT_AND_BACK* = 0x00000408
+  GL_AUX0* = 0x00000409
+  GL_AUX1* = 0x0000040A
+  GL_AUX2* = 0x0000040B
+  GL_AUX3* = 0x0000040C       # Enable
+                              #      GL_FOG
+                              #      GL_LIGHTING
+                              #      GL_TEXTURE_1D
+                              #      GL_TEXTURE_2D
+                              #      GL_LINE_STIPPLE
+                              #      GL_POLYGON_STIPPLE
+                              #      GL_CULL_FACE
+                              #      GL_ALPHA_TEST
+                              #      GL_BLEND
+                              #      GL_INDEX_LOGIC_OP
+                              #      GL_COLOR_LOGIC_OP
+                              #      GL_DITHER
+                              #      GL_STENCIL_TEST
+                              #      GL_DEPTH_TEST
+                              #      GL_CLIP_PLANE0
+                              #      GL_CLIP_PLANE1
+                              #      GL_CLIP_PLANE2
+                              #      GL_CLIP_PLANE3
+                              #      GL_CLIP_PLANE4
+                              #      GL_CLIP_PLANE5
+                              #      GL_LIGHT0
+                              #      GL_LIGHT1
+                              #      GL_LIGHT2
+                              #      GL_LIGHT3
+                              #      GL_LIGHT4
+                              #      GL_LIGHT5
+                              #      GL_LIGHT6
+                              #      GL_LIGHT7
+                              #      GL_TEXTURE_GEN_S
+                              #      GL_TEXTURE_GEN_T
+                              #      GL_TEXTURE_GEN_R
+                              #      GL_TEXTURE_GEN_Q
+                              #      GL_MAP1_VERTEX_3
+                              #      GL_MAP1_VERTEX_4
+                              #      GL_MAP1_COLOR_4
+                              #      GL_MAP1_INDEX
+                              #      GL_MAP1_NORMAL
+                              #      GL_MAP1_TEXTURE_COORD_1
+                              #      GL_MAP1_TEXTURE_COORD_2
+                              #      GL_MAP1_TEXTURE_COORD_3
+                              #      GL_MAP1_TEXTURE_COORD_4
+                              #      GL_MAP2_VERTEX_3
+                              #      GL_MAP2_VERTEX_4
+                              #      GL_MAP2_COLOR_4
+                              #      GL_MAP2_INDEX
+                              #      GL_MAP2_NORMAL
+                              #      GL_MAP2_TEXTURE_COORD_1
+                              #      GL_MAP2_TEXTURE_COORD_2
+                              #      GL_MAP2_TEXTURE_COORD_3
+                              #      GL_MAP2_TEXTURE_COORD_4
+                              #      GL_POINT_SMOOTH
+                              #      GL_LINE_SMOOTH
+                              #      GL_POLYGON_SMOOTH
+                              #      GL_SCISSOR_TEST
+                              #      GL_COLOR_MATERIAL
+                              #      GL_NORMALIZE
+                              #      GL_AUTO_NORMAL
+                              #      GL_VERTEX_ARRAY
+                              #      GL_NORMAL_ARRAY
+                              #      GL_COLOR_ARRAY
+                              #      GL_INDEX_ARRAY
+                              #      GL_TEXTURE_COORD_ARRAY
+                              #      GL_EDGE_FLAG_ARRAY
+                              #      GL_POLYGON_OFFSET_POINT
+                              #      GL_POLYGON_OFFSET_LINE
+                              #      GL_POLYGON_OFFSET_FILL
+                              # ErrorCode
+  GL_NO_ERROR* = 0
+  GL_INVALID_ENUM* = 0x00000500
+  GL_INVALID_VALUE* = 0x00000501
+  GL_INVALID_OPERATION* = 0x00000502
+  GL_STACK_OVERFLOW* = 0x00000503
+  GL_STACK_UNDERFLOW* = 0x00000504
+  GL_OUT_OF_MEMORY* = 0x00000505 # FeedBackMode
+  GL_2D* = 0x00000600
+  GL_3D* = 0x00000601
+  GL_3D_COLOR* = 0x00000602
+  GL_3D_COLOR_TEXTURE* = 0x00000603
+  GL_4D_COLOR_TEXTURE* = 0x00000604 # FeedBackToken
+  GL_PASS_THROUGH_TOKEN* = 0x00000700
+  GL_POINT_TOKEN* = 0x00000701
+  GL_LINE_TOKEN* = 0x00000702
+  GL_POLYGON_TOKEN* = 0x00000703
+  GL_BITMAP_TOKEN* = 0x00000704
+  GL_DRAW_PIXEL_TOKEN* = 0x00000705
+  GL_COPY_PIXEL_TOKEN* = 0x00000706
+  GL_LINE_RESET_TOKEN* = 0x00000707 # FogMode
+                                    #      GL_LINEAR
+  GL_EXP* = 0x00000800
+  GL_EXP2* = 0x00000801       # FogParameter
+                              #      GL_FOG_COLOR
+                              #      GL_FOG_DENSITY
+                              #      GL_FOG_END
+                              #      GL_FOG_INDEX
+                              #      GL_FOG_MODE
+                              #      GL_FOG_START
+                              # FrontFaceDirection
+  GL_CW* = 0x00000900
+  GL_CCW* = 0x00000901        # GetMapTarget
+  GL_COEFF* = 0x00000A00
+  GL_ORDER* = 0x00000A01
+  GL_DOMAIN* = 0x00000A02     # GetPixelMap
+                              #      GL_PIXEL_MAP_I_TO_I
+                              #      GL_PIXEL_MAP_S_TO_S
+                              #      GL_PIXEL_MAP_I_TO_R
+                              #      GL_PIXEL_MAP_I_TO_G
+                              #      GL_PIXEL_MAP_I_TO_B
+                              #      GL_PIXEL_MAP_I_TO_A
+                              #      GL_PIXEL_MAP_R_TO_R
+                              #      GL_PIXEL_MAP_G_TO_G
+                              #      GL_PIXEL_MAP_B_TO_B
+                              #      GL_PIXEL_MAP_A_TO_A
+                              # GetPointerTarget
+                              #      GL_VERTEX_ARRAY_POINTER
+                              #      GL_NORMAL_ARRAY_POINTER
+                              #      GL_COLOR_ARRAY_POINTER
+                              #      GL_INDEX_ARRAY_POINTER
+                              #      GL_TEXTURE_COORD_ARRAY_POINTER
+                              #      GL_EDGE_FLAG_ARRAY_POINTER
+                              # GetTarget
+  GL_CURRENT_COLOR* = 0x00000B00
+  GL_CURRENT_INDEX* = 0x00000B01
+  GL_CURRENT_NORMAL* = 0x00000B02
+  GL_CURRENT_TEXTURE_COORDS* = 0x00000B03
+  GL_CURRENT_RASTER_COLOR* = 0x00000B04
+  GL_CURRENT_RASTER_INDEX* = 0x00000B05
+  GL_CURRENT_RASTER_TEXTURE_COORDS* = 0x00000B06
+  GL_CURRENT_RASTER_POSITION* = 0x00000B07
+  GL_CURRENT_RASTER_POSITION_VALID* = 0x00000B08
+  GL_CURRENT_RASTER_DISTANCE* = 0x00000B09
+  GL_POINT_SMOOTH* = 0x00000B10
+  constGL_POINT_SIZE* = 0x00000B11
+  GL_POINT_SIZE_RANGE* = 0x00000B12
+  GL_POINT_SIZE_GRANULARITY* = 0x00000B13
+  GL_LINE_SMOOTH* = 0x00000B20
+  constGL_LINE_WIDTH* = 0x00000B21
+  GL_LINE_WIDTH_RANGE* = 0x00000B22
+  GL_LINE_WIDTH_GRANULARITY* = 0x00000B23
+  constGL_LINE_STIPPLE* = 0x00000B24
+  GL_LINE_STIPPLE_PATTERN* = 0x00000B25
+  GL_LINE_STIPPLE_REPEAT* = 0x00000B26
+  GL_LIST_MODE* = 0x00000B30
+  GL_MAX_LIST_NESTING* = 0x00000B31
+  constGL_LIST_BASE* = 0x00000B32
+  GL_LIST_INDEX* = 0x00000B33
+  constGL_POLYGON_MODE* = 0x00000B40
+  GL_POLYGON_SMOOTH* = 0x00000B41
+  constGL_POLYGON_STIPPLE* = 0x00000B42
+  constGL_EDGE_FLAG* = 0x00000B43
+  constGL_CULL_FACE* = 0x00000B44
+  GL_CULL_FACE_MODE* = 0x00000B45
+  constGL_FRONT_FACE* = 0x00000B46
+  GL_LIGHTING* = 0x00000B50
+  GL_LIGHT_MODEL_LOCAL_VIEWER* = 0x00000B51
+  GL_LIGHT_MODEL_TWO_SIDE* = 0x00000B52
+  GL_LIGHT_MODEL_AMBIENT* = 0x00000B53
+  constGL_SHADE_MODEL* = 0x00000B54
+  GL_COLOR_MATERIAL_FACE* = 0x00000B55
+  GL_COLOR_MATERIAL_PARAMETER* = 0x00000B56
+  constGL_COLOR_MATERIAL* = 0x00000B57
+  GL_FOG* = 0x00000B60
+  GL_FOG_INDEX* = 0x00000B61
+  GL_FOG_DENSITY* = 0x00000B62
+  GL_FOG_START* = 0x00000B63
+  GL_FOG_END* = 0x00000B64
+  GL_FOG_MODE* = 0x00000B65
+  GL_FOG_COLOR* = 0x00000B66
+  constGL_DEPTH_RANGE* = 0x00000B70
+  GL_DEPTH_TEST* = 0x00000B71
+  GL_DEPTH_WRITEMASK* = 0x00000B72
+  GL_DEPTH_CLEAR_VALUE* = 0x00000B73
+  constGL_DEPTH_FUNC* = 0x00000B74
+  GL_ACCUM_CLEAR_VALUE* = 0x00000B80
+  GL_STENCIL_TEST* = 0x00000B90
+  GL_STENCIL_CLEAR_VALUE* = 0x00000B91
+  constGL_STENCIL_FUNC* = 0x00000B92
+  GL_STENCIL_VALUE_MASK* = 0x00000B93
+  GL_STENCIL_FAIL* = 0x00000B94
+  GL_STENCIL_PASS_DEPTH_FAIL* = 0x00000B95
+  GL_STENCIL_PASS_DEPTH_PASS* = 0x00000B96
+  GL_STENCIL_REF* = 0x00000B97
+  GL_STENCIL_WRITEMASK* = 0x00000B98
+  constGL_MATRIX_MODE* = 0x00000BA0
+  GL_NORMALIZE* = 0x00000BA1
+  constGL_VIEWPORT* = 0x00000BA2
+  GL_MODELVIEW_STACK_DEPTH* = 0x00000BA3
+  GL_PROJECTION_STACK_DEPTH* = 0x00000BA4
+  GL_TEXTURE_STACK_DEPTH* = 0x00000BA5
+  GL_MODELVIEW_MATRIX* = 0x00000BA6
+  GL_PROJECTION_MATRIX* = 0x00000BA7
+  GL_TEXTURE_MATRIX* = 0x00000BA8
+  GL_ATTRIB_STACK_DEPTH* = 0x00000BB0
+  GL_CLIENT_ATTRIB_STACK_DEPTH* = 0x00000BB1
+  GL_ALPHA_TEST* = 0x00000BC0
+  GL_ALPHA_TEST_FUNC* = 0x00000BC1
+  GL_ALPHA_TEST_REF* = 0x00000BC2
+  GL_DITHER* = 0x00000BD0
+  GL_BLEND_DST* = 0x00000BE0
+  GL_BLEND_SRC* = 0x00000BE1
+  GL_BLEND* = 0x00000BE2
+  GL_LOGIC_OP_MODE* = 0x00000BF0
+  GL_INDEX_LOGIC_OP* = 0x00000BF1
+  GL_COLOR_LOGIC_OP* = 0x00000BF2
+  GL_AUX_BUFFERS* = 0x00000C00
+  constGL_DRAW_BUFFER* = 0x00000C01
+  constGL_READ_BUFFER* = 0x00000C02
+  GL_SCISSOR_BOX* = 0x00000C10
+  GL_SCISSOR_TEST* = 0x00000C11
+  GL_INDEX_CLEAR_VALUE* = 0x00000C20
+  GL_INDEX_WRITEMASK* = 0x00000C21
+  GL_COLOR_CLEAR_VALUE* = 0x00000C22
+  GL_COLOR_WRITEMASK* = 0x00000C23
+  GL_INDEX_MODE* = 0x00000C30
+  GL_RGBA_MODE* = 0x00000C31
+  GL_DOUBLEBUFFER* = 0x00000C32
+  GL_STEREO* = 0x00000C33
+  constGL_RENDER_MODE* = 0x00000C40
+  GL_PERSPECTIVE_CORRECTION_HINT* = 0x00000C50
+  GL_POINT_SMOOTH_HINT* = 0x00000C51
+  GL_LINE_SMOOTH_HINT* = 0x00000C52
+  GL_POLYGON_SMOOTH_HINT* = 0x00000C53
+  GL_FOG_HINT* = 0x00000C54
+  GL_TEXTURE_GEN_S* = 0x00000C60
+  GL_TEXTURE_GEN_T* = 0x00000C61
+  GL_TEXTURE_GEN_R* = 0x00000C62
+  GL_TEXTURE_GEN_Q* = 0x00000C63
+  GL_PIXEL_MAP_I_TO_I* = 0x00000C70
+  GL_PIXEL_MAP_S_TO_S* = 0x00000C71
+  GL_PIXEL_MAP_I_TO_R* = 0x00000C72
+  GL_PIXEL_MAP_I_TO_G* = 0x00000C73
+  GL_PIXEL_MAP_I_TO_B* = 0x00000C74
+  GL_PIXEL_MAP_I_TO_A* = 0x00000C75
+  GL_PIXEL_MAP_R_TO_R* = 0x00000C76
+  GL_PIXEL_MAP_G_TO_G* = 0x00000C77
+  GL_PIXEL_MAP_B_TO_B* = 0x00000C78
+  GL_PIXEL_MAP_A_TO_A* = 0x00000C79
+  GL_PIXEL_MAP_I_TO_I_SIZE* = 0x00000CB0
+  GL_PIXEL_MAP_S_TO_S_SIZE* = 0x00000CB1
+  GL_PIXEL_MAP_I_TO_R_SIZE* = 0x00000CB2
+  GL_PIXEL_MAP_I_TO_G_SIZE* = 0x00000CB3
+  GL_PIXEL_MAP_I_TO_B_SIZE* = 0x00000CB4
+  GL_PIXEL_MAP_I_TO_A_SIZE* = 0x00000CB5
+  GL_PIXEL_MAP_R_TO_R_SIZE* = 0x00000CB6
+  GL_PIXEL_MAP_G_TO_G_SIZE* = 0x00000CB7
+  GL_PIXEL_MAP_B_TO_B_SIZE* = 0x00000CB8
+  GL_PIXEL_MAP_A_TO_A_SIZE* = 0x00000CB9
+  GL_UNPACK_SWAP_BYTES* = 0x00000CF0
+  GL_UNPACK_LSB_FIRST* = 0x00000CF1
+  GL_UNPACK_ROW_LENGTH* = 0x00000CF2
+  GL_UNPACK_SKIP_ROWS* = 0x00000CF3
+  GL_UNPACK_SKIP_PIXELS* = 0x00000CF4
+  GL_UNPACK_ALIGNMENT* = 0x00000CF5
+  GL_PACK_SWAP_BYTES* = 0x00000D00
+  GL_PACK_LSB_FIRST* = 0x00000D01
+  GL_PACK_ROW_LENGTH* = 0x00000D02
+  GL_PACK_SKIP_ROWS* = 0x00000D03
+  GL_PACK_SKIP_PIXELS* = 0x00000D04
+  GL_PACK_ALIGNMENT* = 0x00000D05
+  GL_MAP_COLOR* = 0x00000D10
+  GL_MAP_STENCIL* = 0x00000D11
+  GL_INDEX_SHIFT* = 0x00000D12
+  GL_INDEX_OFFSET* = 0x00000D13
+  GL_RED_SCALE* = 0x00000D14
+  GL_RED_BIAS* = 0x00000D15
+  GL_ZOOM_X* = 0x00000D16
+  GL_ZOOM_Y* = 0x00000D17
+  GL_GREEN_SCALE* = 0x00000D18
+  GL_GREEN_BIAS* = 0x00000D19
+  GL_BLUE_SCALE* = 0x00000D1A
+  GL_BLUE_BIAS* = 0x00000D1B
+  GL_ALPHA_SCALE* = 0x00000D1C
+  GL_ALPHA_BIAS* = 0x00000D1D
+  GL_DEPTH_SCALE* = 0x00000D1E
+  GL_DEPTH_BIAS* = 0x00000D1F
+  GL_MAX_EVAL_ORDER* = 0x00000D30
+  GL_MAX_LIGHTS* = 0x00000D31
+  GL_MAX_CLIP_PLANES* = 0x00000D32
+  GL_MAX_TEXTURE_SIZE* = 0x00000D33
+  GL_MAX_PIXEL_MAP_TABLE* = 0x00000D34
+  GL_MAX_ATTRIB_STACK_DEPTH* = 0x00000D35
+  GL_MAX_MODELVIEW_STACK_DEPTH* = 0x00000D36
+  GL_MAX_NAME_STACK_DEPTH* = 0x00000D37
+  GL_MAX_PROJECTION_STACK_DEPTH* = 0x00000D38
+  GL_MAX_TEXTURE_STACK_DEPTH* = 0x00000D39
+  GL_MAX_VIEWPORT_DIMS* = 0x00000D3A
+  GL_MAX_CLIENT_ATTRIB_STACK_DEPTH* = 0x00000D3B
+  GL_SUBPIXEL_BITS* = 0x00000D50
+  GL_INDEX_BITS* = 0x00000D51
+  GL_RED_BITS* = 0x00000D52
+  GL_GREEN_BITS* = 0x00000D53
+  GL_BLUE_BITS* = 0x00000D54
+  GL_ALPHA_BITS* = 0x00000D55
+  GL_DEPTH_BITS* = 0x00000D56
+  GL_STENCIL_BITS* = 0x00000D57
+  GL_ACCUM_RED_BITS* = 0x00000D58
+  GL_ACCUM_GREEN_BITS* = 0x00000D59
+  GL_ACCUM_BLUE_BITS* = 0x00000D5A
+  GL_ACCUM_ALPHA_BITS* = 0x00000D5B
+  GL_NAME_STACK_DEPTH* = 0x00000D70
+  GL_AUTO_NORMAL* = 0x00000D80
+  GL_MAP1_COLOR_4* = 0x00000D90
+  GL_MAP1_INDEX* = 0x00000D91
+  GL_MAP1_NORMAL* = 0x00000D92
+  GL_MAP1_TEXTURE_COORD_1* = 0x00000D93
+  GL_MAP1_TEXTURE_COORD_2* = 0x00000D94
+  GL_MAP1_TEXTURE_COORD_3* = 0x00000D95
+  GL_MAP1_TEXTURE_COORD_4* = 0x00000D96
+  GL_MAP1_VERTEX_3* = 0x00000D97
+  GL_MAP1_VERTEX_4* = 0x00000D98
+  GL_MAP2_COLOR_4* = 0x00000DB0
+  GL_MAP2_INDEX* = 0x00000DB1
+  GL_MAP2_NORMAL* = 0x00000DB2
+  GL_MAP2_TEXTURE_COORD_1* = 0x00000DB3
+  GL_MAP2_TEXTURE_COORD_2* = 0x00000DB4
+  GL_MAP2_TEXTURE_COORD_3* = 0x00000DB5
+  GL_MAP2_TEXTURE_COORD_4* = 0x00000DB6
+  GL_MAP2_VERTEX_3* = 0x00000DB7
+  GL_MAP2_VERTEX_4* = 0x00000DB8
+  GL_MAP1_GRID_DOMAIN* = 0x00000DD0
+  GL_MAP1_GRID_SEGMENTS* = 0x00000DD1
+  GL_MAP2_GRID_DOMAIN* = 0x00000DD2
+  GL_MAP2_GRID_SEGMENTS* = 0x00000DD3
+  GL_TEXTURE_1D* = 0x00000DE0
+  GL_TEXTURE_2D* = 0x00000DE1
+  GL_FEEDBACK_BUFFER_POINTER* = 0x00000DF0
+  GL_FEEDBACK_BUFFER_SIZE* = 0x00000DF1
+  GL_FEEDBACK_BUFFER_TYPE* = 0x00000DF2
+  GL_SELECTION_BUFFER_POINTER* = 0x00000DF3
+  GL_SELECTION_BUFFER_SIZE* = 0x00000DF4 #      GL_TEXTURE_BINDING_1D
+                                         #      GL_TEXTURE_BINDING_2D
+                                         #      GL_VERTEX_ARRAY
+                                         #      GL_NORMAL_ARRAY
+                                         #      GL_COLOR_ARRAY
+                                         #      GL_INDEX_ARRAY
+                                         #      GL_TEXTURE_COORD_ARRAY
+                                         #      GL_EDGE_FLAG_ARRAY
+                                         #      GL_VERTEX_ARRAY_SIZE
+                                         #      GL_VERTEX_ARRAY_TYPE
+                                         #      GL_VERTEX_ARRAY_STRIDE
+                                         #      GL_NORMAL_ARRAY_TYPE
+                                         #      GL_NORMAL_ARRAY_STRIDE
+                                         #      GL_COLOR_ARRAY_SIZE
+                                         #      GL_COLOR_ARRAY_TYPE
+                                         #      GL_COLOR_ARRAY_STRIDE
+                                         #      GL_INDEX_ARRAY_TYPE
+                                         #      GL_INDEX_ARRAY_STRIDE
+                                         #      GL_TEXTURE_COORD_ARRAY_SIZE
+                                         #      GL_TEXTURE_COORD_ARRAY_TYPE
+                                         #      GL_TEXTURE_COORD_ARRAY_STRIDE
+                                         #      GL_EDGE_FLAG_ARRAY_STRIDE
+                                         #      GL_POLYGON_OFFSET_FACTOR
+                                         #      GL_POLYGON_OFFSET_UNITS
+                                         # GetTextureParameter
+                                         #      GL_TEXTURE_MAG_FILTER
+                                         #      GL_TEXTURE_MIN_FILTER
+                                         #      GL_TEXTURE_WRAP_S
+                                         #      GL_TEXTURE_WRAP_T
+  GL_TEXTURE_WIDTH* = 0x00001000
+  GL_TEXTURE_HEIGHT* = 0x00001001
+  GL_TEXTURE_INTERNAL_FORMAT* = 0x00001003
+  GL_TEXTURE_BORDER_COLOR* = 0x00001004
+  GL_TEXTURE_BORDER* = 0x00001005 #      GL_TEXTURE_RED_SIZE
+                                  #      GL_TEXTURE_GREEN_SIZE
+                                  #      GL_TEXTURE_BLUE_SIZE
+                                  #      GL_TEXTURE_ALPHA_SIZE
+                                  #      GL_TEXTURE_LUMINANCE_SIZE
+                                  #      GL_TEXTURE_INTENSITY_SIZE
+                                  #      GL_TEXTURE_PRIORITY
+                                  #      GL_TEXTURE_RESIDENT
+                                  # HintMode
+  GL_DONT_CARE* = 0x00001100
+  GL_FASTEST* = 0x00001101
+  GL_NICEST* = 0x00001102     # HintTarget
+                              #      GL_PERSPECTIVE_CORRECTION_HINT
+                              #      GL_POINT_SMOOTH_HINT
+                              #      GL_LINE_SMOOTH_HINT
+                              #      GL_POLYGON_SMOOTH_HINT
+                              #      GL_FOG_HINT
+                              # IndexPointerType
+                              #      GL_SHORT
+                              #      GL_INT
+                              #      GL_FLOAT
+                              #      GL_DOUBLE
+                              # LightModelParameter
+                              #      GL_LIGHT_MODEL_AMBIENT
+                              #      GL_LIGHT_MODEL_LOCAL_VIEWER
+                              #      GL_LIGHT_MODEL_TWO_SIDE
+                              # LightName
+  GL_LIGHT0* = 0x00004000
+  GL_LIGHT1* = 0x00004001
+  GL_LIGHT2* = 0x00004002
+  GL_LIGHT3* = 0x00004003
+  GL_LIGHT4* = 0x00004004
+  GL_LIGHT5* = 0x00004005
+  GL_LIGHT6* = 0x00004006
+  GL_LIGHT7* = 0x00004007     # LightParameter
+  GL_AMBIENT* = 0x00001200
+  GL_DIFFUSE* = 0x00001201
+  GL_SPECULAR* = 0x00001202
+  GL_POSITION* = 0x00001203
+  GL_SPOT_DIRECTION* = 0x00001204
+  GL_SPOT_EXPONENT* = 0x00001205
+  GL_SPOT_CUTOFF* = 0x00001206
+  GL_CONSTANT_ATTENUATION* = 0x00001207
+  GL_LINEAR_ATTENUATION* = 0x00001208
+  GL_QUADRATIC_ATTENUATION* = 0x00001209 # InterleavedArrays
+                                         #      GL_V2F
+                                         #      GL_V3F
+                                         #      GL_C4UB_V2F
+                                         #      GL_C4UB_V3F
+                                         #      GL_C3F_V3F
+                                         #      GL_N3F_V3F
+                                         #      GL_C4F_N3F_V3F
+                                         #      GL_T2F_V3F
+                                         #      GL_T4F_V4F
+                                         #      GL_T2F_C4UB_V3F
+                                         #      GL_T2F_C3F_V3F
+                                         #      GL_T2F_N3F_V3F
+                                         #      GL_T2F_C4F_N3F_V3F
+                                         #      GL_T4F_C4F_N3F_V4F
+                                         # ListMode
+  GL_COMPILE* = 0x00001300
+  GL_COMPILE_AND_EXECUTE* = 0x00001301 # ListNameType
+                                       #      GL_BYTE
+                                       #      GL_UNSIGNED_BYTE
+                                       #      GL_SHORT
+                                       #      GL_UNSIGNED_SHORT
+                                       #      GL_INT
+                                       #      GL_UNSIGNED_INT
+                                       #      GL_FLOAT
+                                       #      GL_2_BYTES
+                                       #      GL_3_BYTES
+                                       #      GL_4_BYTES
+                                       # LogicOp
+  constGL_CLEAR* = 0x00001500
+  GL_AND* = 0x00001501
+  GL_AND_REVERSE* = 0x00001502
+  GL_COPY* = 0x00001503
+  GL_AND_INVERTED* = 0x00001504
+  GL_NOOP* = 0x00001505
+  GL_XOR* = 0x00001506
+  GL_OR* = 0x00001507
+  GL_NOR* = 0x00001508
+  GL_EQUIV* = 0x00001509
+  GL_INVERT* = 0x0000150A
+  GL_OR_REVERSE* = 0x0000150B
+  GL_COPY_INVERTED* = 0x0000150C
+  GL_OR_INVERTED* = 0x0000150D
+  GL_NAND* = 0x0000150E
+  GL_SET* = 0x0000150F        # MapTarget
+                              #      GL_MAP1_COLOR_4
+                              #      GL_MAP1_INDEX
+                              #      GL_MAP1_NORMAL
+                              #      GL_MAP1_TEXTURE_COORD_1
+                              #      GL_MAP1_TEXTURE_COORD_2
+                              #      GL_MAP1_TEXTURE_COORD_3
+                              #      GL_MAP1_TEXTURE_COORD_4
+                              #      GL_MAP1_VERTEX_3
+                              #      GL_MAP1_VERTEX_4
+                              #      GL_MAP2_COLOR_4
+                              #      GL_MAP2_INDEX
+                              #      GL_MAP2_NORMAL
+                              #      GL_MAP2_TEXTURE_COORD_1
+                              #      GL_MAP2_TEXTURE_COORD_2
+                              #      GL_MAP2_TEXTURE_COORD_3
+                              #      GL_MAP2_TEXTURE_COORD_4
+                              #      GL_MAP2_VERTEX_3
+                              #      GL_MAP2_VERTEX_4
+                              # MaterialFace
+                              #      GL_FRONT
+                              #      GL_BACK
+                              #      GL_FRONT_AND_BACK
+                              # MaterialParameter
+  GL_EMISSION* = 0x00001600
+  GL_SHININESS* = 0x00001601
+  GL_AMBIENT_AND_DIFFUSE* = 0x00001602
+  GL_COLOR_INDEXES* = 0x00001603 #      GL_AMBIENT
+                                 #      GL_DIFFUSE
+                                 #      GL_SPECULAR
+                                 # MatrixMode
+  GL_MODELVIEW* = 0x00001700
+  GL_PROJECTION* = 0x00001701
+  GL_TEXTURE* = 0x00001702    # MeshMode1
+                              #      GL_POINT
+                              #      GL_LINE
+                              # MeshMode2
+                              #      GL_POINT
+                              #      GL_LINE
+                              #      GL_FILL
+                              # NormalPointerType
+                              #      GL_BYTE
+                              #      GL_SHORT
+                              #      GL_INT
+                              #      GL_FLOAT
+                              #      GL_DOUBLE
+                              # PixelCopyType
+  GL_COLOR* = 0x00001800
+  GL_DEPTH* = 0x00001801
+  GL_STENCIL* = 0x00001802    # PixelFormat
+  GL_COLOR_INDEX* = 0x00001900
+  GL_STENCIL_INDEX* = 0x00001901
+  GL_DEPTH_COMPONENT* = 0x00001902
+  GL_RED* = 0x00001903
+  GL_GREEN* = 0x00001904
+  GL_BLUE* = 0x00001905
+  GL_ALPHA* = 0x00001906
+  GL_RGB* = 0x00001907
+  GL_RGBA* = 0x00001908
+  GL_LUMINANCE* = 0x00001909
+  GL_LUMINANCE_ALPHA* = 0x0000190A # PixelMap
+                                   #      GL_PIXEL_MAP_I_TO_I
+                                   #      GL_PIXEL_MAP_S_TO_S
+                                   #      GL_PIXEL_MAP_I_TO_R
+                                   #      GL_PIXEL_MAP_I_TO_G
+                                   #      GL_PIXEL_MAP_I_TO_B
+                                   #      GL_PIXEL_MAP_I_TO_A
+                                   #      GL_PIXEL_MAP_R_TO_R
+                                   #      GL_PIXEL_MAP_G_TO_G
+                                   #      GL_PIXEL_MAP_B_TO_B
+                                   #      GL_PIXEL_MAP_A_TO_A
+                                   # PixelStore
+                                   #      GL_UNPACK_SWAP_BYTES
+                                   #      GL_UNPACK_LSB_FIRST
+                                   #      GL_UNPACK_ROW_LENGTH
+                                   #      GL_UNPACK_SKIP_ROWS
+                                   #      GL_UNPACK_SKIP_PIXELS
+                                   #      GL_UNPACK_ALIGNMENT
+                                   #      GL_PACK_SWAP_BYTES
+                                   #      GL_PACK_LSB_FIRST
+                                   #      GL_PACK_ROW_LENGTH
+                                   #      GL_PACK_SKIP_ROWS
+                                   #      GL_PACK_SKIP_PIXELS
+                                   #      GL_PACK_ALIGNMENT
+                                   # PixelTransfer
+                                   #      GL_MAP_COLOR
+                                   #      GL_MAP_STENCIL
+                                   #      GL_INDEX_SHIFT
+                                   #      GL_INDEX_OFFSET
+                                   #      GL_RED_SCALE
+                                   #      GL_RED_BIAS
+                                   #      GL_GREEN_SCALE
+                                   #      GL_GREEN_BIAS
+                                   #      GL_BLUE_SCALE
+                                   #      GL_BLUE_BIAS
+                                   #      GL_ALPHA_SCALE
+                                   #      GL_ALPHA_BIAS
+                                   #      GL_DEPTH_SCALE
+                                   #      GL_DEPTH_BIAS
+                                   # PixelType
+  constGL_BITMAP* = 0x00001A00
+  GL_POINT* = 0x00001B00
+  GL_LINE* = 0x00001B01
+  GL_FILL* = 0x00001B02       # ReadBufferMode
+                              #      GL_FRONT_LEFT
+                              #      GL_FRONT_RIGHT
+                              #      GL_BACK_LEFT
+                              #      GL_BACK_RIGHT
+                              #      GL_FRONT
+                              #      GL_BACK
+                              #      GL_LEFT
+                              #      GL_RIGHT
+                              #      GL_AUX0
+                              #      GL_AUX1
+                              #      GL_AUX2
+                              #      GL_AUX3
+                              # RenderingMode
+  GL_RENDER* = 0x00001C00
+  GL_FEEDBACK* = 0x00001C01
+  GL_SELECT* = 0x00001C02     # ShadingModel
+  GL_FLAT* = 0x00001D00
+  GL_SMOOTH* = 0x00001D01     # StencilFunction
+                              #      GL_NEVER
+                              #      GL_LESS
+                              #      GL_EQUAL
+                              #      GL_LEQUAL
+                              #      GL_GREATER
+                              #      GL_NOTEQUAL
+                              #      GL_GEQUAL
+                              #      GL_ALWAYS
+                              # StencilOp
+                              #      GL_ZERO
+  GL_KEEP* = 0x00001E00
+  GL_REPLACE* = 0x00001E01
+  GL_INCR* = 0x00001E02
+  GL_DECR* = 0x00001E03       #      GL_INVERT
+                              # StringName
+  GL_VENDOR* = 0x00001F00
+  GL_RENDERER* = 0x00001F01
+  GL_VERSION* = 0x00001F02
+  GL_EXTENSIONS* = 0x00001F03 # TextureCoordName
+  GL_S* = 0x00002000
+  GL_T* = 0x00002001
+  GL_R* = 0x00002002
+  GL_Q* = 0x00002003          # TexCoordPointerType
+                              #      GL_SHORT
+                              #      GL_INT
+                              #      GL_FLOAT
+                              #      GL_DOUBLE
+                              # TextureEnvMode
+  GL_MODULATE* = 0x00002100
+  GL_DECAL* = 0x00002101      #      GL_BLEND
+                              #      GL_REPLACE
+                              # TextureEnvParameter
+  GL_TEXTURE_ENV_MODE* = 0x00002200
+  GL_TEXTURE_ENV_COLOR* = 0x00002201 # TextureEnvTarget
+  GL_TEXTURE_ENV* = 0x00002300 # TextureGenMode
+  GL_EYE_LINEAR* = 0x00002400
+  GL_OBJECT_LINEAR* = 0x00002401
+  GL_SPHERE_MAP* = 0x00002402 # TextureGenParameter
+  GL_TEXTURE_GEN_MODE* = 0x00002500
+  GL_OBJECT_PLANE* = 0x00002501
+  GL_EYE_PLANE* = 0x00002502  # TextureMagFilter
+  GL_NEAREST* = 0x00002600
+  GL_LINEAR* = 0x00002601     # TextureMinFilter
+                              #      GL_NEAREST
+                              #      GL_LINEAR
+  GL_NEAREST_MIPMAP_NEAREST* = 0x00002700
+  GL_LINEAR_MIPMAP_NEAREST* = 0x00002701
+  GL_NEAREST_MIPMAP_LINEAR* = 0x00002702
+  GL_LINEAR_MIPMAP_LINEAR* = 0x00002703 # TextureParameterName
+  GL_TEXTURE_MAG_FILTER* = 0x00002800
+  GL_TEXTURE_MIN_FILTER* = 0x00002801
+  GL_TEXTURE_WRAP_S* = 0x00002802
+  GL_TEXTURE_WRAP_T* = 0x00002803 #      GL_TEXTURE_BORDER_COLOR
+                                  #      GL_TEXTURE_PRIORITY
+                                  # TextureTarget
+                                  #      GL_TEXTURE_1D
+                                  #      GL_TEXTURE_2D
+                                  #      GL_PROXY_TEXTURE_1D
+                                  #      GL_PROXY_TEXTURE_2D
+                                  # TextureWrapMode
+  GL_CLAMP* = 0x00002900
+  GL_REPEAT* = 0x00002901     # VertexPointerType
+                              #      GL_SHORT
+                              #      GL_INT
+                              #      GL_FLOAT
+                              #      GL_DOUBLE
+                              # ClientAttribMask
+  GL_CLIENT_PIXEL_STORE_BIT* = 0x00000001
+  GL_CLIENT_VERTEX_ARRAY_BIT* = 0x00000002
+  GL_CLIENT_ALL_ATTRIB_BITS* = 0xFFFFFFFF # polygon_offset
+  GL_POLYGON_OFFSET_FACTOR* = 0x00008038
+  GL_POLYGON_OFFSET_UNITS* = 0x00002A00
+  GL_POLYGON_OFFSET_POINT* = 0x00002A01
+  GL_POLYGON_OFFSET_LINE* = 0x00002A02
+  GL_POLYGON_OFFSET_FILL* = 0x00008037 # texture
+  GL_ALPHA4* = 0x0000803B
+  GL_ALPHA8* = 0x0000803C
+  GL_ALPHA12* = 0x0000803D
+  GL_ALPHA16* = 0x0000803E
+  GL_LUMINANCE4* = 0x0000803F
+  GL_LUMINANCE8* = 0x00008040
+  GL_LUMINANCE12* = 0x00008041
+  GL_LUMINANCE16* = 0x00008042
+  GL_LUMINANCE4_ALPHA4* = 0x00008043
+  GL_LUMINANCE6_ALPHA2* = 0x00008044
+  GL_LUMINANCE8_ALPHA8* = 0x00008045
+  GL_LUMINANCE12_ALPHA4* = 0x00008046
+  GL_LUMINANCE12_ALPHA12* = 0x00008047
+  GL_LUMINANCE16_ALPHA16* = 0x00008048
+  GL_INTENSITY* = 0x00008049
+  GL_INTENSITY4* = 0x0000804A
+  GL_INTENSITY8* = 0x0000804B
+  GL_INTENSITY12* = 0x0000804C
+  GL_INTENSITY16* = 0x0000804D
+  GL_R3_G3_B2* = 0x00002A10
+  GL_RGB4* = 0x0000804F
+  GL_RGB5* = 0x00008050
+  GL_RGB8* = 0x00008051
+  GL_RGB10* = 0x00008052
+  GL_RGB12* = 0x00008053
+  GL_RGB16* = 0x00008054
+  GL_RGBA2* = 0x00008055
+  GL_RGBA4* = 0x00008056
+  GL_RGB5_A1* = 0x00008057
+  GL_RGBA8* = 0x00008058
+  GL_RGB10_A2* = 0x00008059
+  GL_RGBA12* = 0x0000805A
+  GL_RGBA16* = 0x0000805B
+  GL_TEXTURE_RED_SIZE* = 0x0000805C
+  GL_TEXTURE_GREEN_SIZE* = 0x0000805D
+  GL_TEXTURE_BLUE_SIZE* = 0x0000805E
+  GL_TEXTURE_ALPHA_SIZE* = 0x0000805F
+  GL_TEXTURE_LUMINANCE_SIZE* = 0x00008060
+  GL_TEXTURE_INTENSITY_SIZE* = 0x00008061
+  GL_PROXY_TEXTURE_1D* = 0x00008063
+  GL_PROXY_TEXTURE_2D* = 0x00008064 # texture_object
+  GL_TEXTURE_PRIORITY* = 0x00008066
+  GL_TEXTURE_RESIDENT* = 0x00008067
+  GL_TEXTURE_BINDING_1D* = 0x00008068
+  GL_TEXTURE_BINDING_2D* = 0x00008069 # vertex_array
+  GL_VERTEX_ARRAY* = 0x00008074
+  GL_NORMAL_ARRAY* = 0x00008075
+  GL_COLOR_ARRAY* = 0x00008076
+  GL_INDEX_ARRAY* = 0x00008077
+  GL_TEXTURE_COORD_ARRAY* = 0x00008078
+  GL_EDGE_FLAG_ARRAY* = 0x00008079
+  GL_VERTEX_ARRAY_SIZE* = 0x0000807A
+  GL_VERTEX_ARRAY_TYPE* = 0x0000807B
+  GL_VERTEX_ARRAY_STRIDE* = 0x0000807C
+  GL_NORMAL_ARRAY_TYPE* = 0x0000807E
+  GL_NORMAL_ARRAY_STRIDE* = 0x0000807F
+  GL_COLOR_ARRAY_SIZE* = 0x00008081
+  GL_COLOR_ARRAY_TYPE* = 0x00008082
+  GL_COLOR_ARRAY_STRIDE* = 0x00008083
+  GL_INDEX_ARRAY_TYPE* = 0x00008085
+  GL_INDEX_ARRAY_STRIDE* = 0x00008086
+  GL_TEXTURE_COORD_ARRAY_SIZE* = 0x00008088
+  GL_TEXTURE_COORD_ARRAY_TYPE* = 0x00008089
+  GL_TEXTURE_COORD_ARRAY_STRIDE* = 0x0000808A
+  GL_EDGE_FLAG_ARRAY_STRIDE* = 0x0000808C
+  GL_VERTEX_ARRAY_POINTER* = 0x0000808E
+  GL_NORMAL_ARRAY_POINTER* = 0x0000808F
+  GL_COLOR_ARRAY_POINTER* = 0x00008090
+  GL_INDEX_ARRAY_POINTER* = 0x00008091
+  GL_TEXTURE_COORD_ARRAY_POINTER* = 0x00008092
+  GL_EDGE_FLAG_ARRAY_POINTER* = 0x00008093
+  GL_V2F* = 0x00002A20
+  GL_V3F* = 0x00002A21
+  GL_C4UB_V2F* = 0x00002A22
+  GL_C4UB_V3F* = 0x00002A23
+  GL_C3F_V3F* = 0x00002A24
+  GL_N3F_V3F* = 0x00002A25
+  GL_C4F_N3F_V3F* = 0x00002A26
+  GL_T2F_V3F* = 0x00002A27
+  GL_T4F_V4F* = 0x00002A28
+  GL_T2F_C4UB_V3F* = 0x00002A29
+  GL_T2F_C3F_V3F* = 0x00002A2A
+  GL_T2F_N3F_V3F* = 0x00002A2B
+  GL_T2F_C4F_N3F_V3F* = 0x00002A2C
+  GL_T4F_C4F_N3F_V4F* = 0x00002A2D # Extensions
+  GL_EXT_vertex_array* = 1
+  GL_WIN_swap_hint* = 1
+  GL_EXT_bgra* = 1
+  GL_EXT_paletted_texture* = 1 # EXT_vertex_array
+  GL_VERTEX_ARRAY_EXT* = 0x00008074
+  GL_NORMAL_ARRAY_EXT* = 0x00008075
+  GL_COLOR_ARRAY_EXT* = 0x00008076
+  GL_INDEX_ARRAY_EXT* = 0x00008077
+  GL_TEXTURE_COORD_ARRAY_EXT* = 0x00008078
+  GL_EDGE_FLAG_ARRAY_EXT* = 0x00008079
+  GL_VERTEX_ARRAY_SIZE_EXT* = 0x0000807A
+  GL_VERTEX_ARRAY_TYPE_EXT* = 0x0000807B
+  GL_VERTEX_ARRAY_STRIDE_EXT* = 0x0000807C
+  GL_VERTEX_ARRAY_COUNT_EXT* = 0x0000807D
+  GL_NORMAL_ARRAY_TYPE_EXT* = 0x0000807E
+  GL_NORMAL_ARRAY_STRIDE_EXT* = 0x0000807F
+  GL_NORMAL_ARRAY_COUNT_EXT* = 0x00008080
+  GL_COLOR_ARRAY_SIZE_EXT* = 0x00008081
+  GL_COLOR_ARRAY_TYPE_EXT* = 0x00008082
+  GL_COLOR_ARRAY_STRIDE_EXT* = 0x00008083
+  GL_COLOR_ARRAY_COUNT_EXT* = 0x00008084
+  GL_INDEX_ARRAY_TYPE_EXT* = 0x00008085
+  GL_INDEX_ARRAY_STRIDE_EXT* = 0x00008086
+  GL_INDEX_ARRAY_COUNT_EXT* = 0x00008087
+  GL_TEXTURE_COORD_ARRAY_SIZE_EXT* = 0x00008088
+  GL_TEXTURE_COORD_ARRAY_TYPE_EXT* = 0x00008089
+  GL_TEXTURE_COORD_ARRAY_STRIDE_EXT* = 0x0000808A
+  GL_TEXTURE_COORD_ARRAY_COUNT_EXT* = 0x0000808B
+  GL_EDGE_FLAG_ARRAY_STRIDE_EXT* = 0x0000808C
+  GL_EDGE_FLAG_ARRAY_COUNT_EXT* = 0x0000808D
+  GL_VERTEX_ARRAY_POINTER_EXT* = 0x0000808E
+  GL_NORMAL_ARRAY_POINTER_EXT* = 0x0000808F
+  GL_COLOR_ARRAY_POINTER_EXT* = 0x00008090
+  GL_INDEX_ARRAY_POINTER_EXT* = 0x00008091
+  GL_TEXTURE_COORD_ARRAY_POINTER_EXT* = 0x00008092
+  GL_EDGE_FLAG_ARRAY_POINTER_EXT* = 0x00008093
+  GL_DOUBLE_EXT* = GL_DOUBLE  # EXT_bgra
+  GL_BGR_EXT* = 0x000080E0
+  GL_BGRA_EXT* = 0x000080E1   # EXT_paletted_texture
+                              # These must match the GL_COLOR_TABLE_*_SGI enumerants
+  GL_COLOR_TABLE_FORMAT_EXT* = 0x000080D8
+  GL_COLOR_TABLE_WIDTH_EXT* = 0x000080D9
+  GL_COLOR_TABLE_RED_SIZE_EXT* = 0x000080DA
+  GL_COLOR_TABLE_GREEN_SIZE_EXT* = 0x000080DB
+  GL_COLOR_TABLE_BLUE_SIZE_EXT* = 0x000080DC
+  GL_COLOR_TABLE_ALPHA_SIZE_EXT* = 0x000080DD
+  GL_COLOR_TABLE_LUMINANCE_SIZE_EXT* = 0x000080DE
+  GL_COLOR_TABLE_INTENSITY_SIZE_EXT* = 0x000080DF
+  GL_COLOR_INDEX1_EXT* = 0x000080E2
+  GL_COLOR_INDEX2_EXT* = 0x000080E3
+  GL_COLOR_INDEX4_EXT* = 0x000080E4
+  GL_COLOR_INDEX8_EXT* = 0x000080E5
+  GL_COLOR_INDEX12_EXT* = 0x000080E6
+  GL_COLOR_INDEX16_EXT* = 0x000080E7 # For compatibility with OpenGL v1.0
+  constGL_LOGIC_OP* = GL_INDEX_LOGIC_OP
+  GL_TEXTURE_COMPONENTS* = GL_TEXTURE_INTERNAL_FORMAT
+
+proc glAccum*(op: TGLenum, value: TGLfloat){.dynlib: dllname, importc: "glAccum".}
+proc glAlphaFunc*(func: TGLenum, theref: TGLclampf){.dynlib: dllname, 
+    importc: "glAlphaFunc".}
+proc glAreTexturesResident*(n: TGLsizei, textures: PGLuint, 
+                            residences: PGLboolean): TGLboolean{.
+    dynlib: dllname, importc: "glAreTexturesResident".}
+proc glArrayElement*(i: TGLint){.dynlib: dllname, importc: "glArrayElement".}
+proc glBegin*(mode: TGLenum){.dynlib: dllname, importc: "glBegin".}
+proc glBindTexture*(target: TGLenum, texture: TGLuint){.dynlib: dllname, 
+    importc: "glBindTexture".}
+proc glBitmap*(width, height: TGLsizei, xorig, yorig: TGLfloat, 
+               xmove, ymove: TGLfloat, bitmap: PGLubyte){.dynlib: dllname, 
+    importc: "glBitmap".}
+proc glBlendFunc*(sfactor, dfactor: TGLenum){.dynlib: dllname, 
+    importc: "glBlendFunc".}
+proc glCallList*(list: TGLuint){.dynlib: dllname, importc: "glCallList".}
+proc glCallLists*(n: TGLsizei, atype: TGLenum, lists: Pointer){.dynlib: dllname, 
+    importc: "glCallLists".}
+proc glClear*(mask: TGLbitfield){.dynlib: dllname, importc: "glClear".}
+proc glClearAccum*(red, green, blue, alpha: TGLfloat){.dynlib: dllname, 
+    importc: "glClearAccum".}
+proc glClearColor*(red, green, blue, alpha: TGLclampf){.dynlib: dllname, 
+    importc: "glClearColor".}
+proc glClearDepth*(depth: TGLclampd){.dynlib: dllname, importc: "glClearDepth".}
+proc glClearIndex*(c: TGLfloat){.dynlib: dllname, importc: "glClearIndex".}
+proc glClearStencil*(s: TGLint){.dynlib: dllname, importc: "glClearStencil".}
+proc glClipPlane*(plane: TGLenum, equation: PGLdouble){.dynlib: dllname, 
+    importc: "glClipPlane".}
+proc glColor3b*(red, green, blue: TGlbyte){.dynlib: dllname, 
+    importc: "glColor3b".}
+proc glColor3bv*(v: PGLbyte){.dynlib: dllname, importc: "glColor3bv".}
+proc glColor3d*(red, green, blue: TGLdouble){.dynlib: dllname, 
+    importc: "glColor3d".}
+proc glColor3dv*(v: PGLdouble){.dynlib: dllname, importc: "glColor3dv".}
+proc glColor3f*(red, green, blue: TGLfloat){.dynlib: dllname, 
+    importc: "glColor3f".}
+proc glColor3fv*(v: PGLfloat){.dynlib: dllname, importc: "glColor3fv".}
+proc glColor3i*(red, green, blue: TGLint){.dynlib: dllname, importc: "glColor3i".}
+proc glColor3iv*(v: PGLint){.dynlib: dllname, importc: "glColor3iv".}
+proc glColor3s*(red, green, blue: TGLshort){.dynlib: dllname, 
+    importc: "glColor3s".}
+proc glColor3sv*(v: PGLshort){.dynlib: dllname, importc: "glColor3sv".}
+proc glColor3ub*(red, green, blue: TGLubyte){.dynlib: dllname, 
+    importc: "glColor3ub".}
+proc glColor3ubv*(v: PGLubyte){.dynlib: dllname, importc: "glColor3ubv".}
+proc glColor3ui*(red, green, blue: TGLuint){.dynlib: dllname, 
+    importc: "glColor3ui".}
+proc glColor3uiv*(v: PGLuint){.dynlib: dllname, importc: "glColor3uiv".}
+proc glColor3us*(red, green, blue: TGLushort){.dynlib: dllname, 
+    importc: "glColor3us".}
+proc glColor3usv*(v: PGLushort){.dynlib: dllname, importc: "glColor3usv".}
+proc glColor4b*(red, green, blue, alpha: TGlbyte){.dynlib: dllname, 
+    importc: "glColor4b".}
+proc glColor4bv*(v: PGLbyte){.dynlib: dllname, importc: "glColor4bv".}
+proc glColor4d*(red, green, blue, alpha: TGLdouble){.dynlib: dllname, 
+    importc: "glColor4d".}
+proc glColor4dv*(v: PGLdouble){.dynlib: dllname, importc: "glColor4dv".}
+proc glColor4f*(red, green, blue, alpha: TGLfloat){.dynlib: dllname, 
+    importc: "glColor4f".}
+proc glColor4fv*(v: PGLfloat){.dynlib: dllname, importc: "glColor4fv".}
+proc glColor4i*(red, green, blue, alpha: TGLint){.dynlib: dllname, 
+    importc: "glColor4i".}
+proc glColor4iv*(v: PGLint){.dynlib: dllname, importc: "glColor4iv".}
+proc glColor4s*(red, green, blue, alpha: TGLshort){.dynlib: dllname, 
+    importc: "glColor4s".}
+proc glColor4sv*(v: PGLshort){.dynlib: dllname, importc: "glColor4sv".}
+proc glColor4ub*(red, green, blue, alpha: TGLubyte){.dynlib: dllname, 
+    importc: "glColor4ub".}
+proc glColor4ubv*(v: PGLubyte){.dynlib: dllname, importc: "glColor4ubv".}
+proc glColor4ui*(red, green, blue, alpha: TGLuint){.dynlib: dllname, 
+    importc: "glColor4ui".}
+proc glColor4uiv*(v: PGLuint){.dynlib: dllname, importc: "glColor4uiv".}
+proc glColor4us*(red, green, blue, alpha: TGLushort){.dynlib: dllname, 
+    importc: "glColor4us".}
+proc glColor4usv*(v: PGLushort){.dynlib: dllname, importc: "glColor4usv".}
+proc glColorMask*(red, green, blue, alpha: TGLboolean){.dynlib: dllname, 
+    importc: "glColorMask".}
+proc glColorMaterial*(face, mode: TGLenum){.dynlib: dllname, 
+    importc: "glColorMaterial".}
+proc glColorPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei, 
+                     pointer: Pointer){.dynlib: dllname, 
+                                        importc: "glColorPointer".}
+proc glCopyPixels*(x, y: TGLint, width, height: TGLsizei, atype: TGLenum){.
+    dynlib: dllname, importc: "glCopyPixels".}
+proc glCopyTexImage1D*(target: TGLenum, level: TGLint, internalFormat: TGLenum, 
+                       x, y: TGLint, width: TGLsizei, border: TGLint){.
+    dynlib: dllname, importc: "glCopyTexImage1D".}
+proc glCopyTexImage2D*(target: TGLenum, level: TGLint, internalFormat: TGLenum, 
+                       x, y: TGLint, width, height: TGLsizei, border: TGLint){.
+    dynlib: dllname, importc: "glCopyTexImage2D".}
+proc glCopyTexSubImage1D*(target: TGLenum, level, xoffset, x, y: TGLint, 
+                          width: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyTexSubImage1D".}
+proc glCopyTexSubImage2D*(target: TGLenum, 
+                          level, xoffset, yoffset, x, y: TGLint, 
+                          width, height: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyTexSubImage2D".}
+proc glCullFace*(mode: TGLenum){.dynlib: dllname, importc: "glCullFace".}
+proc glDeleteLists*(list: TGLuint, range: TGLsizei){.dynlib: dllname, 
+    importc: "glDeleteLists".}
+proc glDeleteTextures*(n: TGLsizei, textures: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteTextures".}
+proc glDepthFunc*(func: TGLenum){.dynlib: dllname, importc: "glDepthFunc".}
+proc glDepthMask*(flag: TGLboolean){.dynlib: dllname, importc: "glDepthMask".}
+proc glDepthRange*(zNear, zFar: TGLclampd){.dynlib: dllname, 
+    importc: "glDepthRange".}
+proc glDisable*(cap: TGLenum){.dynlib: dllname, importc: "glDisable".}
+proc glDisableClientState*(aarray: TGLenum){.dynlib: dllname, 
+    importc: "glDisableClientState".}
+proc glDrawArrays*(mode: TGLenum, first: TGLint, count: TGLsizei){.
+    dynlib: dllname, importc: "glDrawArrays".}
+proc glDrawBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glDrawBuffer".}
+proc glDrawElements*(mode: TGLenum, count: TGLsizei, atype: TGLenum, 
+                     indices: Pointer){.dynlib: dllname, 
+                                        importc: "glDrawElements".}
+proc glDrawPixels*(width, height: TGLsizei, format, atype: TGLenum, 
+                   pixels: Pointer){.dynlib: dllname, importc: "glDrawPixels".}
+proc glEdgeFlag*(flag: TGLboolean){.dynlib: dllname, importc: "glEdgeFlag".}
+proc glEdgeFlagPointer*(stride: TGLsizei, pointer: Pointer){.dynlib: dllname, 
+    importc: "glEdgeFlagPointer".}
+proc glEdgeFlagv*(flag: PGLboolean){.dynlib: dllname, importc: "glEdgeFlagv".}
+proc glEnable*(cap: TGLenum){.dynlib: dllname, importc: "glEnable".}
+proc glEnableClientState*(aarray: TGLenum){.dynlib: dllname, 
+    importc: "glEnableClientState".}
+proc glEnd*(){.dynlib: dllname, importc: "glEnd".}
+proc glEndList*(){.dynlib: dllname, importc: "glEndList".}
+proc glEvalCoord1d*(u: TGLdouble){.dynlib: dllname, importc: "glEvalCoord1d".}
+proc glEvalCoord1dv*(u: PGLdouble){.dynlib: dllname, importc: "glEvalCoord1dv".}
+proc glEvalCoord1f*(u: TGLfloat){.dynlib: dllname, importc: "glEvalCoord1f".}
+proc glEvalCoord1fv*(u: PGLfloat){.dynlib: dllname, importc: "glEvalCoord1fv".}
+proc glEvalCoord2d*(u, v: TGLdouble){.dynlib: dllname, importc: "glEvalCoord2d".}
+proc glEvalCoord2dv*(u: PGLdouble){.dynlib: dllname, importc: "glEvalCoord2dv".}
+proc glEvalCoord2f*(u, v: TGLfloat){.dynlib: dllname, importc: "glEvalCoord2f".}
+proc glEvalCoord2fv*(u: PGLfloat){.dynlib: dllname, importc: "glEvalCoord2fv".}
+proc glEvalMesh1*(mode: TGLenum, i1, i2: TGLint){.dynlib: dllname, 
+    importc: "glEvalMesh1".}
+proc glEvalMesh2*(mode: TGLenum, i1, i2, j1, j2: TGLint){.dynlib: dllname, 
+    importc: "glEvalMesh2".}
+proc glEvalPoint1*(i: TGLint){.dynlib: dllname, importc: "glEvalPoint1".}
+proc glEvalPoint2*(i, j: TGLint){.dynlib: dllname, importc: "glEvalPoint2".}
+proc glFeedbackBuffer*(size: TGLsizei, atype: TGLenum, buffer: PGLfloat){.
+    dynlib: dllname, importc: "glFeedbackBuffer".}
+proc glFinish*(){.dynlib: dllname, importc: "glFinish".}
+proc glFlush*(){.dynlib: dllname, importc: "glFlush".}
+proc glFogf*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glFogf".}
+proc glFogfv*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glFogfv".}
+proc glFogi*(pname: TGLenum, param: TGLint){.dynlib: dllname, importc: "glFogi".}
+proc glFogiv*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glFogiv".}
+proc glFrontFace*(mode: TGLenum){.dynlib: dllname, importc: "glFrontFace".}
+proc glFrustum*(left, right, bottom, top, zNear, zFar: TGLdouble){.
+    dynlib: dllname, importc: "glFrustum".}
+proc glGenLists*(range: TGLsizei): TGLuint{.dynlib: dllname, 
+    importc: "glGenLists".}
+proc glGenTextures*(n: TGLsizei, textures: PGLuint){.dynlib: dllname, 
+    importc: "glGenTextures".}
+proc glGetBooleanv*(pname: TGLenum, params: PGLboolean){.dynlib: dllname, 
+    importc: "glGetBooleanv".}
+proc glGetClipPlane*(plane: TGLenum, equation: PGLdouble){.dynlib: dllname, 
+    importc: "glGetClipPlane".}
+proc glGetDoublev*(pname: TGLenum, params: PGLdouble){.dynlib: dllname, 
+    importc: "glGetDoublev".}
+proc glGetError*(): TGLenum{.dynlib: dllname, importc: "glGetError".}
+proc glGetFloatv*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetFloatv".}
+proc glGetIntegerv*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetIntegerv".}
+proc glGetLightfv*(light, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetLightfv".}
+proc glGetLightiv*(light, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetLightiv".}
+proc glGetMapdv*(target, query: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glGetMapdv".}
+proc glGetMapfv*(target, query: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glGetMapfv".}
+proc glGetMapiv*(target, query: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glGetMapiv".}
+proc glGetMaterialfv*(face, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetMaterialfv".}
+proc glGetMaterialiv*(face, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetMaterialiv".}
+proc glGetPixelMapfv*(map: TGLenum, values: PGLfloat){.dynlib: dllname, 
+    importc: "glGetPixelMapfv".}
+proc glGetPixelMapuiv*(map: TGLenum, values: PGLuint){.dynlib: dllname, 
+    importc: "glGetPixelMapuiv".}
+proc glGetPixelMapusv*(map: TGLenum, values: PGLushort){.dynlib: dllname, 
+    importc: "glGetPixelMapusv".}
+proc glGetPointerv*(pname: TGLenum, params: Pointer){.dynlib: dllname, 
+    importc: "glGetPointerv".}
+proc glGetPolygonStipple*(mask: PGLubyte){.dynlib: dllname, 
+    importc: "glGetPolygonStipple".}
+proc glGetString*(name: TGLenum): cstring{.dynlib: dllname, 
+    importc: "glGetString".}
+proc glGetTexEnvfv*(target, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetTexEnvfv".}
+proc glGetTexEnviv*(target, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetTexEnviv".}
+proc glGetTexGendv*(coord, pname: TGLenum, params: PGLdouble){.dynlib: dllname, 
+    importc: "glGetTexGendv".}
+proc glGetTexGenfv*(coord, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetTexGenfv".}
+proc glGetTexGeniv*(coord, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetTexGeniv".}
+proc glGetTexImage*(target: TGLenum, level: TGLint, format: TGLenum, 
+                    atype: TGLenum, pixels: Pointer){.dynlib: dllname, 
+    importc: "glGetTexImage".}
+proc glGetTexLevelParameterfv*(target: TGLenum, level: TGLint, pname: TGLenum, 
+                               params: Pointer){.dynlib: dllname, 
+    importc: "glGetTexLevelParameterfv".}
+proc glGetTexLevelParameteriv*(target: TGLenum, level: TGLint, pname: TGLenum, 
+                               params: PGLint){.dynlib: dllname, 
+    importc: "glGetTexLevelParameteriv".}
+proc glGetTexParameterfv*(target, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetTexParameterfv".}
+proc glGetTexParameteriv*(target, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetTexParameteriv".}
+proc glHint*(target, mode: TGLenum){.dynlib: dllname, importc: "glHint".}
+proc glIndexMask*(mask: TGLuint){.dynlib: dllname, importc: "glIndexMask".}
+proc glIndexPointer*(atype: TGLenum, stride: TGLsizei, pointer: Pointer){.
+    dynlib: dllname, importc: "glIndexPointer".}
+proc glIndexd*(c: TGLdouble){.dynlib: dllname, importc: "glIndexd".}
+proc glIndexdv*(c: PGLdouble){.dynlib: dllname, importc: "glIndexdv".}
+proc glIndexf*(c: TGLfloat){.dynlib: dllname, importc: "glIndexf".}
+proc glIndexfv*(c: PGLfloat){.dynlib: dllname, importc: "glIndexfv".}
+proc glIndexi*(c: TGLint){.dynlib: dllname, importc: "glIndexi".}
+proc glIndexiv*(c: PGLint){.dynlib: dllname, importc: "glIndexiv".}
+proc glIndexs*(c: TGLshort){.dynlib: dllname, importc: "glIndexs".}
+proc glIndexsv*(c: PGLshort){.dynlib: dllname, importc: "glIndexsv".}
+proc glIndexub*(c: TGLubyte){.dynlib: dllname, importc: "glIndexub".}
+proc glIndexubv*(c: PGLubyte){.dynlib: dllname, importc: "glIndexubv".}
+proc glInitNames*(){.dynlib: dllname, importc: "glInitNames".}
+proc glInterleavedArrays*(format: TGLenum, stride: TGLsizei, pointer: Pointer){.
+    dynlib: dllname, importc: "glInterleavedArrays".}
+proc glIsEnabled*(cap: TGLenum): TGLboolean{.dynlib: dllname, 
+    importc: "glIsEnabled".}
+proc glIsList*(list: TGLuint): TGLboolean{.dynlib: dllname, importc: "glIsList".}
+proc glIsTexture*(texture: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsTexture".}
+proc glLightModelf*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glLightModelf".}
+proc glLightModelfv*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glLightModelfv".}
+proc glLightModeli*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glLightModeli".}
+proc glLightModeliv*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glLightModeliv".}
+proc glLightf*(light, pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glLightf".}
+proc glLightfv*(light, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glLightfv".}
+proc glLighti*(light, pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glLighti".}
+proc glLightiv*(light, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glLightiv".}
+proc glLineStipple*(factor: TGLint, pattern: TGLushort){.dynlib: dllname, 
+    importc: "glLineStipple".}
+proc glLineWidth*(width: TGLfloat){.dynlib: dllname, importc: "glLineWidth".}
+proc glListBase*(base: TGLuint){.dynlib: dllname, importc: "glListBase".}
+proc glLoadIdentity*(){.dynlib: dllname, importc: "glLoadIdentity".}
+proc glLoadMatrixd*(m: PGLdouble){.dynlib: dllname, importc: "glLoadMatrixd".}
+proc glLoadMatrixf*(m: PGLfloat){.dynlib: dllname, importc: "glLoadMatrixf".}
+proc glLoadName*(name: TGLuint){.dynlib: dllname, importc: "glLoadName".}
+proc glLogicOp*(opcode: TGLenum){.dynlib: dllname, importc: "glLogicOp".}
+proc glMap1d*(target: TGLenum, u1, u2: TGLdouble, stride, order: TGLint, 
+              points: PGLdouble){.dynlib: dllname, importc: "glMap1d".}
+proc glMap1f*(target: TGLenum, u1, u2: TGLfloat, stride, order: TGLint, 
+              points: PGLfloat){.dynlib: dllname, importc: "glMap1f".}
+proc glMap2d*(target: TGLenum, u1, u2: TGLdouble, ustride, uorder: TGLint, 
+              v1, v2: TGLdouble, vstride, vorder: TGLint, points: PGLdouble){.
+    dynlib: dllname, importc: "glMap2d".}
+proc glMap2f*(target: TGLenum, u1, u2: TGLfloat, ustride, uorder: TGLint, 
+              v1, v2: TGLfloat, vstride, vorder: TGLint, points: PGLfloat){.
+    dynlib: dllname, importc: "glMap2f".}
+proc glMapGrid1d*(un: TGLint, u1, u2: TGLdouble){.dynlib: dllname, 
+    importc: "glMapGrid1d".}
+proc glMapGrid1f*(un: TGLint, u1, u2: TGLfloat){.dynlib: dllname, 
+    importc: "glMapGrid1f".}
+proc glMapGrid2d*(un: TGLint, u1, u2: TGLdouble, vn: TGLint, v1, v2: TGLdouble){.
+    dynlib: dllname, importc: "glMapGrid2d".}
+proc glMapGrid2f*(un: TGLint, u1, u2: TGLfloat, vn: TGLint, v1, v2: TGLfloat){.
+    dynlib: dllname, importc: "glMapGrid2f".}
+proc glMaterialf*(face, pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glMaterialf".}
+proc glMaterialfv*(face, pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glMaterialfv".}
+proc glMateriali*(face, pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glMateriali".}
+proc glMaterialiv*(face, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glMaterialiv".}
+proc glMatrixMode*(mode: TGLenum){.dynlib: dllname, importc: "glMatrixMode".}
+proc glMultMatrixd*(m: PGLdouble){.dynlib: dllname, importc: "glMultMatrixd".}
+proc glMultMatrixf*(m: PGLfloat){.dynlib: dllname, importc: "glMultMatrixf".}
+proc glNewList*(list: TGLuint, mode: TGLenum){.dynlib: dllname, 
+    importc: "glNewList".}
+proc glNormal3b*(nx, ny, nz: TGlbyte){.dynlib: dllname, importc: "glNormal3b".}
+proc glNormal3bv*(v: PGLbyte){.dynlib: dllname, importc: "glNormal3bv".}
+proc glNormal3d*(nx, ny, nz: TGLdouble){.dynlib: dllname, importc: "glNormal3d".}
+proc glNormal3dv*(v: PGLdouble){.dynlib: dllname, importc: "glNormal3dv".}
+proc glNormal3f*(nx, ny, nz: TGLfloat){.dynlib: dllname, importc: "glNormal3f".}
+proc glNormal3fv*(v: PGLfloat){.dynlib: dllname, importc: "glNormal3fv".}
+proc glNormal3i*(nx, ny, nz: TGLint){.dynlib: dllname, importc: "glNormal3i".}
+proc glNormal3iv*(v: PGLint){.dynlib: dllname, importc: "glNormal3iv".}
+proc glNormal3s*(nx, ny, nz: TGLshort){.dynlib: dllname, importc: "glNormal3s".}
+proc glNormal3sv*(v: PGLshort){.dynlib: dllname, importc: "glNormal3sv".}
+proc glNormalPointer*(atype: TGLenum, stride: TGLsizei, pointer: Pointer){.
+    dynlib: dllname, importc: "glNormalPointer".}
+proc glOrtho*(left, right, bottom, top, zNear, zFar: TGLdouble){.
+    dynlib: dllname, importc: "glOrtho".}
+proc glPassThrough*(token: TGLfloat){.dynlib: dllname, importc: "glPassThrough".}
+proc glPixelMapfv*(map: TGLenum, mapsize: TGLsizei, values: PGLfloat){.
+    dynlib: dllname, importc: "glPixelMapfv".}
+proc glPixelMapuiv*(map: TGLenum, mapsize: TGLsizei, values: PGLuint){.
+    dynlib: dllname, importc: "glPixelMapuiv".}
+proc glPixelMapusv*(map: TGLenum, mapsize: TGLsizei, values: PGLushort){.
+    dynlib: dllname, importc: "glPixelMapusv".}
+proc glPixelStoref*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPixelStoref".}
+proc glPixelStorei*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glPixelStorei".}
+proc glPixelTransferf*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPixelTransferf".}
+proc glPixelTransferi*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glPixelTransferi".}
+proc glPixelZoom*(xfactor, yfactor: TGLfloat){.dynlib: dllname, 
+    importc: "glPixelZoom".}
+proc glPointSize*(size: TGLfloat){.dynlib: dllname, importc: "glPointSize".}
+proc glPolygonMode*(face, mode: TGLenum){.dynlib: dllname, 
+    importc: "glPolygonMode".}
+proc glPolygonOffset*(factor, units: TGLfloat){.dynlib: dllname, 
+    importc: "glPolygonOffset".}
+proc glPolygonStipple*(mask: PGLubyte){.dynlib: dllname, 
+                                        importc: "glPolygonStipple".}
+proc glPopAttrib*(){.dynlib: dllname, importc: "glPopAttrib".}
+proc glPopClientAttrib*(){.dynlib: dllname, importc: "glPopClientAttrib".}
+proc glPopMatrix*(){.dynlib: dllname, importc: "glPopMatrix".}
+proc glPopName*(){.dynlib: dllname, importc: "glPopName".}
+proc glPrioritizeTextures*(n: TGLsizei, textures: PGLuint, priorities: PGLclampf){.
+    dynlib: dllname, importc: "glPrioritizeTextures".}
+proc glPushAttrib*(mask: TGLbitfield){.dynlib: dllname, importc: "glPushAttrib".}
+proc glPushClientAttrib*(mask: TGLbitfield){.dynlib: dllname, 
+    importc: "glPushClientAttrib".}
+proc glPushMatrix*(){.dynlib: dllname, importc: "glPushMatrix".}
+proc glPushName*(name: TGLuint){.dynlib: dllname, importc: "glPushName".}
+proc glRasterPos2d*(x, y: TGLdouble){.dynlib: dllname, importc: "glRasterPos2d".}
+proc glRasterPos2dv*(v: PGLdouble){.dynlib: dllname, importc: "glRasterPos2dv".}
+proc glRasterPos2f*(x, y: TGLfloat){.dynlib: dllname, importc: "glRasterPos2f".}
+proc glRasterPos2fv*(v: PGLfloat){.dynlib: dllname, importc: "glRasterPos2fv".}
+proc glRasterPos2i*(x, y: TGLint){.dynlib: dllname, importc: "glRasterPos2i".}
+proc glRasterPos2iv*(v: PGLint){.dynlib: dllname, importc: "glRasterPos2iv".}
+proc glRasterPos2s*(x, y: TGLshort){.dynlib: dllname, importc: "glRasterPos2s".}
+proc glRasterPos2sv*(v: PGLshort){.dynlib: dllname, importc: "glRasterPos2sv".}
+proc glRasterPos3d*(x, y, z: TGLdouble){.dynlib: dllname, 
+    importc: "glRasterPos3d".}
+proc glRasterPos3dv*(v: PGLdouble){.dynlib: dllname, importc: "glRasterPos3dv".}
+proc glRasterPos3f*(x, y, z: TGLfloat){.dynlib: dllname, 
+                                        importc: "glRasterPos3f".}
+proc glRasterPos3fv*(v: PGLfloat){.dynlib: dllname, importc: "glRasterPos3fv".}
+proc glRasterPos3i*(x, y, z: TGLint){.dynlib: dllname, importc: "glRasterPos3i".}
+proc glRasterPos3iv*(v: PGLint){.dynlib: dllname, importc: "glRasterPos3iv".}
+proc glRasterPos3s*(x, y, z: TGLshort){.dynlib: dllname, 
+                                        importc: "glRasterPos3s".}
+proc glRasterPos3sv*(v: PGLshort){.dynlib: dllname, importc: "glRasterPos3sv".}
+proc glRasterPos4d*(x, y, z, w: TGLdouble){.dynlib: dllname, 
+    importc: "glRasterPos4d".}
+proc glRasterPos4dv*(v: PGLdouble){.dynlib: dllname, importc: "glRasterPos4dv".}
+proc glRasterPos4f*(x, y, z, w: TGLfloat){.dynlib: dllname, 
+    importc: "glRasterPos4f".}
+proc glRasterPos4fv*(v: PGLfloat){.dynlib: dllname, importc: "glRasterPos4fv".}
+proc glRasterPos4i*(x, y, z, w: TGLint){.dynlib: dllname, 
+    importc: "glRasterPos4i".}
+proc glRasterPos4iv*(v: PGLint){.dynlib: dllname, importc: "glRasterPos4iv".}
+proc glRasterPos4s*(x, y, z, w: TGLshort){.dynlib: dllname, 
+    importc: "glRasterPos4s".}
+proc glRasterPos4sv*(v: PGLshort){.dynlib: dllname, importc: "glRasterPos4sv".}
+proc glReadBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glReadBuffer".}
+proc glReadPixels*(x, y: TGLint, width, height: TGLsizei, 
+                   format, atype: TGLenum, pixels: Pointer){.dynlib: dllname, 
+    importc: "glReadPixels".}
+proc glRectd*(x1, y1, x2, y2: TGLdouble){.dynlib: dllname, importc: "glRectd".}
+proc glRectdv*(v1: PGLdouble, v2: PGLdouble){.dynlib: dllname, 
+    importc: "glRectdv".}
+proc glRectf*(x1, y1, x2, y2: TGLfloat){.dynlib: dllname, importc: "glRectf".}
+proc glRectfv*(v1: PGLfloat, v2: PGLfloat){.dynlib: dllname, importc: "glRectfv".}
+proc glRecti*(x1, y1, x2, y2: TGLint){.dynlib: dllname, importc: "glRecti".}
+proc glRectiv*(v1: PGLint, v2: PGLint){.dynlib: dllname, importc: "glRectiv".}
+proc glRects*(x1, y1, x2, y2: TGLshort){.dynlib: dllname, importc: "glRects".}
+proc glRectsv*(v1: PGLshort, v2: PGLshort){.dynlib: dllname, importc: "glRectsv".}
+proc glRenderMode*(mode: TGLint): TGLint{.dynlib: dllname, 
+    importc: "glRenderMode".}
+proc glRotated*(angle, x, y, z: TGLdouble){.dynlib: dllname, 
+    importc: "glRotated".}
+proc glRotatef*(angle, x, y, z: TGLfloat){.dynlib: dllname, importc: "glRotatef".}
+proc glScaled*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glScaled".}
+proc glScalef*(x, y, z: TGLfloat){.dynlib: dllname, importc: "glScalef".}
+proc glScissor*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname, 
+    importc: "glScissor".}
+proc glSelectBuffer*(size: TGLsizei, buffer: PGLuint){.dynlib: dllname, 
+    importc: "glSelectBuffer".}
+proc glShadeModel*(mode: TGLenum){.dynlib: dllname, importc: "glShadeModel".}
+proc glStencilFunc*(func: TGLenum, theref: TGLint, mask: TGLuint){.
+    dynlib: dllname, importc: "glStencilFunc".}
+proc glStencilMask*(mask: TGLuint){.dynlib: dllname, importc: "glStencilMask".}
+proc glStencilOp*(fail, zfail, zpass: TGLenum){.dynlib: dllname, 
+    importc: "glStencilOp".}
+proc glTexCoord1d*(s: TGLdouble){.dynlib: dllname, importc: "glTexCoord1d".}
+proc glTexCoord1dv*(v: PGLdouble){.dynlib: dllname, importc: "glTexCoord1dv".}
+proc glTexCoord1f*(s: TGLfloat){.dynlib: dllname, importc: "glTexCoord1f".}
+proc glTexCoord1fv*(v: PGLfloat){.dynlib: dllname, importc: "glTexCoord1fv".}
+proc glTexCoord1i*(s: TGLint){.dynlib: dllname, importc: "glTexCoord1i".}
+proc glTexCoord1iv*(v: PGLint){.dynlib: dllname, importc: "glTexCoord1iv".}
+proc glTexCoord1s*(s: TGLshort){.dynlib: dllname, importc: "glTexCoord1s".}
+proc glTexCoord1sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord1sv".}
+proc glTexCoord2d*(s, t: TGLdouble){.dynlib: dllname, importc: "glTexCoord2d".}
+proc glTexCoord2dv*(v: PGLdouble){.dynlib: dllname, importc: "glTexCoord2dv".}
+proc glTexCoord2f*(s, t: TGLfloat){.dynlib: dllname, importc: "glTexCoord2f".}
+proc glTexCoord2fv*(v: PGLfloat){.dynlib: dllname, importc: "glTexCoord2fv".}
+proc glTexCoord2i*(s, t: TGLint){.dynlib: dllname, importc: "glTexCoord2i".}
+proc glTexCoord2iv*(v: PGLint){.dynlib: dllname, importc: "glTexCoord2iv".}
+proc glTexCoord2s*(s, t: TGLshort){.dynlib: dllname, importc: "glTexCoord2s".}
+proc glTexCoord2sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord2sv".}
+proc glTexCoord3d*(s, t, r: TGLdouble){.dynlib: dllname, importc: "glTexCoord3d".}
+proc glTexCoord3dv*(v: PGLdouble){.dynlib: dllname, importc: "glTexCoord3dv".}
+proc glTexCoord3f*(s, t, r: TGLfloat){.dynlib: dllname, importc: "glTexCoord3f".}
+proc glTexCoord3fv*(v: PGLfloat){.dynlib: dllname, importc: "glTexCoord3fv".}
+proc glTexCoord3i*(s, t, r: TGLint){.dynlib: dllname, importc: "glTexCoord3i".}
+proc glTexCoord3iv*(v: PGLint){.dynlib: dllname, importc: "glTexCoord3iv".}
+proc glTexCoord3s*(s, t, r: TGLshort){.dynlib: dllname, importc: "glTexCoord3s".}
+proc glTexCoord3sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord3sv".}
+proc glTexCoord4d*(s, t, r, q: TGLdouble){.dynlib: dllname, 
+    importc: "glTexCoord4d".}
+proc glTexCoord4dv*(v: PGLdouble){.dynlib: dllname, importc: "glTexCoord4dv".}
+proc glTexCoord4f*(s, t, r, q: TGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord4f".}
+proc glTexCoord4fv*(v: PGLfloat){.dynlib: dllname, importc: "glTexCoord4fv".}
+proc glTexCoord4i*(s, t, r, q: TGLint){.dynlib: dllname, importc: "glTexCoord4i".}
+proc glTexCoord4iv*(v: PGLint){.dynlib: dllname, importc: "glTexCoord4iv".}
+proc glTexCoord4s*(s, t, r, q: TGLshort){.dynlib: dllname, 
+    importc: "glTexCoord4s".}
+proc glTexCoord4sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord4sv".}
+proc glTexCoordPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei, 
+                        pointer: Pointer){.dynlib: dllname, 
+    importc: "glTexCoordPointer".}
+proc glTexEnvf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
+    dynlib: dllname, importc: "glTexEnvf".}
+proc glTexEnvfv*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glTexEnvfv".}
+proc glTexEnvi*(target: TGLenum, pname: TGLenum, param: TGLint){.
+    dynlib: dllname, importc: "glTexEnvi".}
+proc glTexEnviv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glTexEnviv".}
+proc glTexGend*(coord: TGLenum, pname: TGLenum, param: TGLdouble){.
+    dynlib: dllname, importc: "glTexGend".}
+proc glTexGendv*(coord: TGLenum, pname: TGLenum, params: PGLdouble){.
+    dynlib: dllname, importc: "glTexGendv".}
+proc glTexGenf*(coord: TGLenum, pname: TGLenum, param: TGLfloat){.
+    dynlib: dllname, importc: "glTexGenf".}
+proc glTexGenfv*(coord: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glTexGenfv".}
+proc glTexGeni*(coord: TGLenum, pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glTexGeni".}
+proc glTexGeniv*(coord: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glTexGeniv".}
+proc glTexImage1D*(target: TGLenum, level, internalformat: TGLint, 
+                   width: TGLsizei, border: TGLint, format, atype: TGLenum, 
+                   pixels: Pointer){.dynlib: dllname, importc: "glTexImage1D".}
+proc glTexImage2D*(target: TGLenum, level, internalformat: TGLint, 
+                   width, height: TGLsizei, border: TGLint, 
+                   format, atype: TGLenum, pixels: Pointer){.dynlib: dllname, 
+    importc: "glTexImage2D".}
+proc glTexParameterf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
+    dynlib: dllname, importc: "glTexParameterf".}
+proc glTexParameterfv*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glTexParameterfv".}
+proc glTexParameteri*(target: TGLenum, pname: TGLenum, param: TGLint){.
+    dynlib: dllname, importc: "glTexParameteri".}
+proc glTexParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glTexParameteriv".}
+proc glTexSubImage1D*(target: TGLenum, level, xoffset: TGLint, width: TGLsizei, 
+                      format, atype: TGLenum, pixels: Pointer){.dynlib: dllname, 
+    importc: "glTexSubImage1D".}
+proc glTexSubImage2D*(target: TGLenum, level, xoffset, yoffset: TGLint, 
+                      width, height: TGLsizei, format, atype: TGLenum, 
+                      pixels: Pointer){.dynlib: dllname, 
+                                        importc: "glTexSubImage2D".}
+proc glTranslated*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glTranslated".}
+proc glTranslatef*(x, y, z: TGLfloat){.dynlib: dllname, importc: "glTranslatef".}
+proc glVertex2d*(x, y: TGLdouble){.dynlib: dllname, importc: "glVertex2d".}
+proc glVertex2dv*(v: PGLdouble){.dynlib: dllname, importc: "glVertex2dv".}
+proc glVertex2f*(x, y: TGLfloat){.dynlib: dllname, importc: "glVertex2f".}
+proc glVertex2fv*(v: PGLfloat){.dynlib: dllname, importc: "glVertex2fv".}
+proc glVertex2i*(x, y: TGLint){.dynlib: dllname, importc: "glVertex2i".}
+proc glVertex2iv*(v: PGLint){.dynlib: dllname, importc: "glVertex2iv".}
+proc glVertex2s*(x, y: TGLshort){.dynlib: dllname, importc: "glVertex2s".}
+proc glVertex2sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex2sv".}
+proc glVertex3d*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glVertex3d".}
+proc glVertex3dv*(v: PGLdouble){.dynlib: dllname, importc: "glVertex3dv".}
+proc glVertex3f*(x, y, z: TGLfloat){.dynlib: dllname, importc: "glVertex3f".}
+proc glVertex3fv*(v: PGLfloat){.dynlib: dllname, importc: "glVertex3fv".}
+proc glVertex3i*(x, y, z: TGLint){.dynlib: dllname, importc: "glVertex3i".}
+proc glVertex3iv*(v: PGLint){.dynlib: dllname, importc: "glVertex3iv".}
+proc glVertex3s*(x, y, z: TGLshort){.dynlib: dllname, importc: "glVertex3s".}
+proc glVertex3sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex3sv".}
+proc glVertex4d*(x, y, z, w: TGLdouble){.dynlib: dllname, importc: "glVertex4d".}
+proc glVertex4dv*(v: PGLdouble){.dynlib: dllname, importc: "glVertex4dv".}
+proc glVertex4f*(x, y, z, w: TGLfloat){.dynlib: dllname, importc: "glVertex4f".}
+proc glVertex4fv*(v: PGLfloat){.dynlib: dllname, importc: "glVertex4fv".}
+proc glVertex4i*(x, y, z, w: TGLint){.dynlib: dllname, importc: "glVertex4i".}
+proc glVertex4iv*(v: PGLint){.dynlib: dllname, importc: "glVertex4iv".}
+proc glVertex4s*(x, y, z, w: TGLshort){.dynlib: dllname, importc: "glVertex4s".}
+proc glVertex4sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex4sv".}
+proc glVertexPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei, 
+                      pointer: Pointer){.dynlib: dllname, 
+    importc: "glVertexPointer".}
+proc glViewport*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname, 
+    importc: "glViewport".}
+type 
+  PFN_GLARRAY_ELEMENT_EXTPROC* = proc (i: TGLint)
+  PFN_GLDRAW_ARRAYS_EXTPROC* = proc (mode: TGLenum, first: TGLint, 
+                                     count: TGLsizei)
+  PFN_GLVERTEX_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum, 
+                                        stride, count: TGLsizei, 
+                                        pointer: Pointer)
+  PFN_GLNORMAL_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei, 
+                                        pointer: Pointer)
+  PFN_GLCOLOR_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum, 
+                                       stride, count: TGLsizei, pointer: Pointer)
+  PFN_GLINDEX_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei, 
+                                       pointer: Pointer)
+  PFN_GLTEXCOORD_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum, 
+      stride, count: TGLsizei, pointer: Pointer)
+  PFN_GLEDGEFLAG_POINTER_EXTPROC* = proc (stride, count: TGLsizei, 
+      pointer: PGLboolean)
+  PFN_GLGET_POINTER_VEXT_PROC* = proc (pname: TGLenum, params: Pointer)
+  PFN_GLARRAY_ELEMENT_ARRAY_EXTPROC* = proc (mode: TGLenum, count: TGLsizei, 
+      pi: Pointer)            # WIN_swap_hint
+  PFN_GLADDSWAPHINT_RECT_WINPROC* = proc (x, y: TGLint, width, height: TGLsizei)
+  PFN_GLCOLOR_TABLE_EXTPROC* = proc (target, internalFormat: TGLenum, 
+                                     width: TGLsizei, format, atype: TGLenum, 
+                                     data: Pointer)
+  PFN_GLCOLOR_SUBTABLE_EXTPROC* = proc (target: TGLenum, start, count: TGLsizei, 
+                                        format, atype: TGLenum, data: Pointer)
+  PFN_GLGETCOLOR_TABLE_EXTPROC* = proc (target, format, atype: TGLenum, 
+                                        data: Pointer)
+  PFN_GLGETCOLOR_TABLE_PARAMETER_IVEXTPROC* = proc (target, pname: TGLenum, 
+      params: PGLint)
+  PFN_GLGETCOLOR_TABLE_PARAMETER_FVEXTPROC* = proc (target, pname: TGLenum, 
+      params: PGLfloat)
+
+{.pop.}
+# implementation
diff --git a/tests/manyloc/keineschweine/lib/glext.nim b/tests/manyloc/keineschweine/lib/glext.nim
new file mode 100644
index 000000000..32871df0e
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/glext.nim
@@ -0,0 +1,4673 @@
+#
+#
+#  Adaption of the delphi3d.net OpenGL units to FreePascal
+#  Sebastian Guenther (sg@freepascal.org) in 2002
+#  These units are free to use
+#
+#
+
+#*************************************************
+# *        OpenGL extension loading library        *
+# * Generated by MetaGLext, written by Tom Nuydens *
+# *  (tom@delphi3d.net -- http://www.delphi3d.net  *
+# *************************************************
+#*** Generated on 10/11/2002
+
+when defined(windows): 
+  {.push, callconv: stdcall.}
+else: 
+  {.push, callconv: cdecl.}
+import 
+  gl
+
+type 
+  GLcharARB* = Char
+  TGLcharARB* = GLcharARB
+  PGLcharARB* = ptr GLcharARB
+  GLhandleARB* = int
+  TGLhandleARB* = GLhandleARB
+  PGLhandleARB* = ptr GLhandleARB
+  GLintptr* = int
+  TGLintptr* = GLintptr
+  PGLintptr* = ptr GLintptr
+  GLsizeiptr* = int
+  TGLsizeiptr* = GLsizeiptr
+  PGLsizeiptr* = ptr GLsizeiptr
+  GLchar* = Char
+  TGLchar* = GLchar
+  PGLchar* = cstring          #***** GL_version_1_2 *****//
+
+const 
+  GL_UNSIGNED_BYTE_3_3_2* = 0x00008032
+  GL_UNSIGNED_SHORT_4_4_4_4* = 0x00008033
+  GL_UNSIGNED_SHORT_5_5_5_1* = 0x00008034
+  GL_UNSIGNED_INT_8_8_8_8* = 0x00008035
+  GL_UNSIGNED_INT_10_10_10_2* = 0x00008036
+  GL_RESCALE_NORMAL* = 0x0000803A
+  GL_UNSIGNED_BYTE_2_3_3_REV* = 0x00008362
+  GL_UNSIGNED_SHORT_5_6_5* = 0x00008363
+  GL_UNSIGNED_SHORT_5_6_5_REV* = 0x00008364
+  GL_UNSIGNED_SHORT_4_4_4_4_REV* = 0x00008365
+  GL_UNSIGNED_SHORT_1_5_5_5_REV* = 0x00008366
+  GL_UNSIGNED_INT_8_8_8_8_REV* = 0x00008367
+  GL_UNSIGNED_INT_2_10_10_10_REV* = 0x00008368
+  GL_BGR* = 0x000080E0
+  GL_BGRA* = 0x000080E1
+  GL_MAX_ELEMENTS_VERTICES* = 0x000080E8
+  GL_MAX_ELEMENTS_INDICES* = 0x000080E9
+  GL_CLAMP_TO_EDGE* = 0x0000812F
+  GL_TEXTURE_MIN_LOD* = 0x0000813A
+  GL_TEXTURE_MAX_LOD* = 0x0000813B
+  GL_TEXTURE_BASE_LEVEL* = 0x0000813C
+  GL_TEXTURE_MAX_LEVEL* = 0x0000813D
+  GL_LIGHT_MODEL_COLOR_CONTROL* = 0x000081F8
+  GL_SINGLE_COLOR* = 0x000081F9
+  GL_SEPARATE_SPECULAR_COLOR* = 0x000081FA
+  GL_SMOOTH_POINT_SIZE_RANGE* = 0x00000B12
+  GL_SMOOTH_POINT_SIZE_GRANULARITY* = 0x00000B13
+  GL_SMOOTH_LINE_WIDTH_RANGE* = 0x00000B22
+  GL_SMOOTH_LINE_WIDTH_GRANULARITY* = 0x00000B23
+  GL_ALIASED_POINT_SIZE_RANGE* = 0x0000846D
+  GL_ALIASED_LINE_WIDTH_RANGE* = 0x0000846E
+  GL_PACK_SKIP_IMAGES* = 0x0000806B
+  GL_PACK_IMAGE_HEIGHT* = 0x0000806C
+  GL_UNPACK_SKIP_IMAGES* = 0x0000806D
+  GL_UNPACK_IMAGE_HEIGHT* = 0x0000806E
+  GL_TEXTURE_3D* = 0x0000806F
+  GL_PROXY_TEXTURE_3D* = 0x00008070
+  GL_TEXTURE_DEPTH* = 0x00008071
+  GL_TEXTURE_WRAP_R* = 0x00008072
+  GL_MAX_3D_TEXTURE_SIZE* = 0x00008073
+
+proc glBlendColor*(red: TGLclampf, green: TGLclampf, blue: TGLclampf, 
+                   alpha: TGLclampf){.dynlib: dllname, importc: "glBlendColor".}
+proc glBlendEquation*(mode: TGLenum){.dynlib: dllname, 
+                                      importc: "glBlendEquation".}
+proc glDrawRangeElements*(mode: TGLenum, start: TGLuint, theend: TGLuint, 
+                          count: TGLsizei, thetype: TGLenum, indices: PGLvoid){.
+    dynlib: dllname, importc: "glDrawRangeElements".}
+proc glColorTable*(target: TGLenum, internalformat: TGLenum, width: TGLsizei, 
+                   format: TGLenum, thetype: TGLenum, table: PGLvoid){.
+    dynlib: dllname, importc: "glColorTable".}
+proc glColorTableParameterfv*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glColorTableParameterfv".}
+proc glColorTableParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glColorTableParameteriv".}
+proc glCopyColorTable*(target: TGLenum, internalformat: TGLenum, x: TGLint, 
+                       y: TGLint, width: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyColorTable".}
+proc glGetColorTable*(target: TGLenum, format: TGLenum, thetype: TGLenum, 
+                      table: PGLvoid){.dynlib: dllname, 
+                                       importc: "glGetColorTable".}
+proc glGetColorTableParameterfv*(target: TGLenum, pname: TGLenum, 
+                                 params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetColorTableParameterfv".}
+proc glGetColorTableParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetColorTableParameteriv".}
+proc glColorSubTable*(target: TGLenum, start: TGLsizei, count: TGLsizei, 
+                      format: TGLenum, thetype: TGLenum, data: PGLvoid){.
+    dynlib: dllname, importc: "glColorSubTable".}
+proc glCopyColorSubTable*(target: TGLenum, start: TGLsizei, x: TGLint, 
+                          y: TGLint, width: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyColorSubTable".}
+proc glConvolutionFilter1D*(target: TGLenum, internalformat: TGLenum, 
+                            width: TGLsizei, format: TGLenum, thetype: TGLenum, 
+                            image: PGLvoid){.dynlib: dllname, 
+    importc: "glConvolutionFilter1D".}
+proc glConvolutionFilter2D*(target: TGLenum, internalformat: TGLenum, 
+                            width: TGLsizei, height: TGLsizei, format: TGLenum, 
+                            thetype: TGLenum, image: PGLvoid){.dynlib: dllname, 
+    importc: "glConvolutionFilter2D".}
+proc glConvolutionParameterf*(target: TGLenum, pname: TGLenum, params: TGLfloat){.
+    dynlib: dllname, importc: "glConvolutionParameterf".}
+proc glConvolutionParameterfv*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glConvolutionParameterfv".}
+proc glConvolutionParameteri*(target: TGLenum, pname: TGLenum, params: TGLint){.
+    dynlib: dllname, importc: "glConvolutionParameteri".}
+proc glConvolutionParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glConvolutionParameteriv".}
+proc glCopyConvolutionFilter1D*(target: TGLenum, internalformat: TGLenum, 
+                                x: TGLint, y: TGLint, width: TGLsizei){.
+    dynlib: dllname, importc: "glCopyConvolutionFilter1D".}
+proc glCopyConvolutionFilter2D*(target: TGLenum, internalformat: TGLenum, 
+                                x: TGLint, y: TGLint, width: TGLsizei, 
+                                height: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyConvolutionFilter2D".}
+proc glGetConvolutionFilter*(target: TGLenum, format: TGLenum, thetype: TGLenum, 
+                             image: PGLvoid){.dynlib: dllname, 
+    importc: "glGetConvolutionFilter".}
+proc glGetConvolutionParameterfv*(target: TGLenum, pname: TGLenum, 
+                                  params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetConvolutionParameterfv".}
+proc glGetConvolutionParameteriv*(target: TGLenum, pname: TGLenum, 
+                                  params: PGLint){.dynlib: dllname, 
+    importc: "glGetConvolutionParameteriv".}
+proc glGetSeparableFilter*(target: TGLenum, format: TGLenum, thetype: TGLenum, 
+                           row: PGLvoid, column: PGLvoid, span: PGLvoid){.
+    dynlib: dllname, importc: "glGetSeparableFilter".}
+proc glSeparableFilter2D*(target: TGLenum, internalformat: TGLenum, 
+                          width: TGLsizei, height: TGLsizei, format: TGLenum, 
+                          thetype: TGLenum, row: PGLvoid, column: PGLvoid){.
+    dynlib: dllname, importc: "glSeparableFilter2D".}
+proc glGetHistogram*(target: TGLenum, reset: TGLboolean, format: TGLenum, 
+                     thetype: TGLenum, values: PGLvoid){.dynlib: dllname, 
+    importc: "glGetHistogram".}
+proc glGetHistogramParameterfv*(target: TGLenum, pname: TGLenum, 
+                                params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetHistogramParameterfv".}
+proc glGetHistogramParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetHistogramParameteriv".}
+proc glGetMinmax*(target: TGLenum, reset: TGLboolean, format: TGLenum, 
+                  thetype: TGLenum, values: PGLvoid){.dynlib: dllname, 
+    importc: "glGetMinmax".}
+proc glGetMinmaxParameterfv*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetMinmaxParameterfv".}
+proc glGetMinmaxParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetMinmaxParameteriv".}
+proc glHistogram*(target: TGLenum, width: TGLsizei, internalformat: TGLenum, 
+                  sink: TGLboolean){.dynlib: dllname, importc: "glHistogram".}
+proc glMinmax*(target: TGLenum, internalformat: TGLenum, sink: TGLboolean){.
+    dynlib: dllname, importc: "glMinmax".}
+proc glResetHistogram*(target: TGLenum){.dynlib: dllname, 
+    importc: "glResetHistogram".}
+proc glResetMinmax*(target: TGLenum){.dynlib: dllname, importc: "glResetMinmax".}
+proc glTexImage3D*(target: TGLenum, level: TGLint, internalformat: TGLint, 
+                   width: TGLsizei, height: TGLsizei, depth: TGLsizei, 
+                   border: TGLint, format: TGLenum, thetype: TGLenum, 
+                   pixels: PGLvoid){.dynlib: dllname, importc: "glTexImage3D".}
+proc glTexSubImage3D*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                      yoffset: TGLint, zoffset: TGLint, width: TGLsizei, 
+                      height: TGLsizei, depth: TGLsizei, format: TGLenum, 
+                      thetype: TGLenum, pixels: PGLvoid){.dynlib: dllname, 
+    importc: "glTexSubImage3D".}
+proc glCopyTexSubImage3D*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                          yoffset: TGLint, zoffset: TGLint, x: TGLint, 
+                          y: TGLint, width: TGLsizei, height: TGLsizei){.
+    dynlib: dllname, importc: "glCopyTexSubImage3D".}
+proc glActiveTextureARB*(texture: TGLenum){.dynlib: dllname, 
+    importc: "glActiveTextureARB".}
+proc glClientActiveTextureARB*(texture: TGLenum){.dynlib: dllname, 
+    importc: "glClientActiveTextureARB".}
+proc glMultiTexCoord1dARB*(target: TGLenum, s: TGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord1dARB".}
+proc glMultiTexCoord1dvARB*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord1dvARB".}
+proc glMultiTexCoord1fARB*(target: TGLenum, s: TGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord1fARB".}
+proc glMultiTexCoord1fvARB*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord1fvARB".}
+proc glMultiTexCoord1iARB*(target: TGLenum, s: TGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord1iARB".}
+proc glMultiTexCoord1ivARB*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord1ivARB".}
+proc glMultiTexCoord1sARB*(target: TGLenum, s: TGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1sARB".}
+proc glMultiTexCoord1svARB*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1svARB".}
+proc glMultiTexCoord2dARB*(target: TGLenum, s: TGLdouble, t: TGLdouble){.
+    dynlib: dllname, importc: "glMultiTexCoord2dARB".}
+proc glMultiTexCoord2dvARB*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord2dvARB".}
+proc glMultiTexCoord2fARB*(target: TGLenum, s: TGLfloat, t: TGLfloat){.
+    dynlib: dllname, importc: "glMultiTexCoord2fARB".}
+proc glMultiTexCoord2fvARB*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord2fvARB".}
+proc glMultiTexCoord2iARB*(target: TGLenum, s: TGLint, t: TGLint){.
+    dynlib: dllname, importc: "glMultiTexCoord2iARB".}
+proc glMultiTexCoord2ivARB*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord2ivARB".}
+proc glMultiTexCoord2sARB*(target: TGLenum, s: TGLshort, t: TGLshort){.
+    dynlib: dllname, importc: "glMultiTexCoord2sARB".}
+proc glMultiTexCoord2svARB*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord2svARB".}
+proc glMultiTexCoord3dARB*(target: TGLenum, s: TGLdouble, t: TGLdouble, 
+                           r: TGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord3dARB".}
+proc glMultiTexCoord3dvARB*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord3dvARB".}
+proc glMultiTexCoord3fARB*(target: TGLenum, s: TGLfloat, t: TGLfloat, 
+                           r: TGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord3fARB".}
+proc glMultiTexCoord3fvARB*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord3fvARB".}
+proc glMultiTexCoord3iARB*(target: TGLenum, s: TGLint, t: TGLint, r: TGLint){.
+    dynlib: dllname, importc: "glMultiTexCoord3iARB".}
+proc glMultiTexCoord3ivARB*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord3ivARB".}
+proc glMultiTexCoord3sARB*(target: TGLenum, s: TGLshort, t: TGLshort, 
+                           r: TGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord3sARB".}
+proc glMultiTexCoord3svARB*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord3svARB".}
+proc glMultiTexCoord4dARB*(target: TGLenum, s: TGLdouble, t: TGLdouble, 
+                           r: TGLdouble, q: TGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord4dARB".}
+proc glMultiTexCoord4dvARB*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord4dvARB".}
+proc glMultiTexCoord4fARB*(target: TGLenum, s: TGLfloat, t: TGLfloat, 
+                           r: TGLfloat, q: TGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord4fARB".}
+proc glMultiTexCoord4fvARB*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord4fvARB".}
+proc glMultiTexCoord4iARB*(target: TGLenum, s: TGLint, t: TGLint, r: TGLint, 
+                           q: TGLint){.dynlib: dllname, 
+                                       importc: "glMultiTexCoord4iARB".}
+proc glMultiTexCoord4ivARB*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord4ivARB".}
+proc glMultiTexCoord4sARB*(target: TGLenum, s: TGLshort, t: TGLshort, 
+                           r: TGLshort, q: TGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord4sARB".}
+proc glMultiTexCoord4svARB*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord4svARB".}
+proc glSampleCoverageARB*(value: TGLclampf, invert: TGLboolean){.
+    dynlib: dllname, importc: "glSampleCoverageARB".}
+  #***** GL_ARB_texture_env_add *****//
+proc glWeightbvARB*(size: TGLint, weights: PGLbyte){.dynlib: dllname, 
+    importc: "glWeightbvARB".}
+proc glWeightsvARB*(size: TGLint, weights: PGLshort){.dynlib: dllname, 
+    importc: "glWeightsvARB".}
+proc glWeightivARB*(size: TGLint, weights: PGLint){.dynlib: dllname, 
+    importc: "glWeightivARB".}
+proc glWeightfvARB*(size: TGLint, weights: PGLfloat){.dynlib: dllname, 
+    importc: "glWeightfvARB".}
+proc glWeightdvARB*(size: TGLint, weights: PGLdouble){.dynlib: dllname, 
+    importc: "glWeightdvARB".}
+proc glWeightvARB*(size: TGLint, weights: PGLdouble){.dynlib: dllname, 
+    importc: "glWeightvARB".}
+proc glWeightubvARB*(size: TGLint, weights: PGLubyte){.dynlib: dllname, 
+    importc: "glWeightubvARB".}
+proc glWeightusvARB*(size: TGLint, weights: PGLushort){.dynlib: dllname, 
+    importc: "glWeightusvARB".}
+proc glWeightuivARB*(size: TGLint, weights: PGLuint){.dynlib: dllname, 
+    importc: "glWeightuivARB".}
+proc glWeightPointerARB*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                         pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glWeightPointerARB".}
+proc glVertexBlendARB*(count: TGLint){.dynlib: dllname, 
+                                       importc: "glVertexBlendARB".}
+proc glVertexAttrib1sARB*(index: TGLuint, x: TGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1sARB".}
+proc glVertexAttrib1fARB*(index: TGLuint, x: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1fARB".}
+proc glVertexAttrib1dARB*(index: TGLuint, x: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1dARB".}
+proc glVertexAttrib2sARB*(index: TGLuint, x: TGLshort, y: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib2sARB".}
+proc glVertexAttrib2fARB*(index: TGLuint, x: TGLfloat, y: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib2fARB".}
+proc glVertexAttrib2dARB*(index: TGLuint, x: TGLdouble, y: TGLdouble){.
+    dynlib: dllname, importc: "glVertexAttrib2dARB".}
+proc glVertexAttrib3sARB*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib3sARB".}
+proc glVertexAttrib3fARB*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib3fARB".}
+proc glVertexAttrib3dARB*(index: TGLuint, x: TGLdouble, y: TGLdouble, 
+                          z: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib3dARB".}
+proc glVertexAttrib4sARB*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort, 
+                          w: TGLshort){.dynlib: dllname, 
+                                        importc: "glVertexAttrib4sARB".}
+proc glVertexAttrib4fARB*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat, 
+                          w: TGLfloat){.dynlib: dllname, 
+                                        importc: "glVertexAttrib4fARB".}
+proc glVertexAttrib4dARB*(index: TGLuint, x: TGLdouble, y: TGLdouble, 
+                          z: TGLdouble, w: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib4dARB".}
+proc glVertexAttrib4NubARB*(index: TGLuint, x: TGLubyte, y: TGLubyte, 
+                            z: TGLubyte, w: TGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4NubARB".}
+proc glVertexAttrib1svARB*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1svARB".}
+proc glVertexAttrib1fvARB*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1fvARB".}
+proc glVertexAttrib1dvARB*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1dvARB".}
+proc glVertexAttrib2svARB*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib2svARB".}
+proc glVertexAttrib2fvARB*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib2fvARB".}
+proc glVertexAttrib2dvARB*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib2dvARB".}
+proc glVertexAttrib3svARB*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib3svARB".}
+proc glVertexAttrib3fvARB*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib3fvARB".}
+proc glVertexAttrib3dvARB*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib3dvARB".}
+proc glVertexAttrib4bvARB*(index: TGLuint, v: PGLbyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4bvARB".}
+proc glVertexAttrib4svARB*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib4svARB".}
+proc glVertexAttrib4ivARB*(index: TGLuint, v: PGLint){.dynlib: dllname, 
+    importc: "glVertexAttrib4ivARB".}
+proc glVertexAttrib4ubvARB*(index: TGLuint, v: PGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4ubvARB".}
+proc glVertexAttrib4usvARB*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4usvARB".}
+proc glVertexAttrib4uivARB*(index: TGLuint, v: PGLuint){.dynlib: dllname, 
+    importc: "glVertexAttrib4uivARB".}
+proc glVertexAttrib4fvARB*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib4fvARB".}
+proc glVertexAttrib4dvARB*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib4dvARB".}
+proc glVertexAttrib4NbvARB*(index: TGLuint, v: PGLbyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4NbvARB".}
+proc glVertexAttrib4NsvARB*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib4NsvARB".}
+proc glVertexAttrib4NivARB*(index: TGLuint, v: PGLint){.dynlib: dllname, 
+    importc: "glVertexAttrib4NivARB".}
+proc glVertexAttrib4NubvARB*(index: TGLuint, v: PGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4NubvARB".}
+proc glVertexAttrib4NusvARB*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4NusvARB".}
+proc glVertexAttrib4NuivARB*(index: TGLuint, v: PGLuint){.dynlib: dllname, 
+    importc: "glVertexAttrib4NuivARB".}
+proc glVertexAttribPointerARB*(index: TGLuint, size: TGLint, thetype: TGLenum, 
+                               normalized: TGLboolean, stride: TGLsizei, 
+                               pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexAttribPointerARB".}
+proc glEnableVertexAttribArrayARB*(index: TGLuint){.dynlib: dllname, 
+    importc: "glEnableVertexAttribArrayARB".}
+proc glDisableVertexAttribArrayARB*(index: TGLuint){.dynlib: dllname, 
+    importc: "glDisableVertexAttribArrayARB".}
+proc glProgramStringARB*(target: TGLenum, format: TGLenum, length: TGLsizei, 
+                         str: PGLvoid){.dynlib: dllname, 
+                                        importc: "glProgramStringARB".}
+proc glBindProgramARB*(target: TGLenum, theProgram: TGLuint){.dynlib: dllname, 
+    importc: "glBindProgramARB".}
+proc glDeleteProgramsARB*(n: TGLsizei, programs: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteProgramsARB".}
+proc glGenProgramsARB*(n: TGLsizei, programs: PGLuint){.dynlib: dllname, 
+    importc: "glGenProgramsARB".}
+proc glProgramEnvParameter4dARB*(target: TGLenum, index: TGLuint, x: TGLdouble, 
+                                 y: TGLdouble, z: TGLdouble, w: TGLdouble){.
+    dynlib: dllname, importc: "glProgramEnvParameter4dARB".}
+proc glProgramEnvParameter4dvARB*(target: TGLenum, index: TGLuint, 
+                                  params: PGLdouble){.dynlib: dllname, 
+    importc: "glProgramEnvParameter4dvARB".}
+proc glProgramEnvParameter4fARB*(target: TGLenum, index: TGLuint, x: TGLfloat, 
+                                 y: TGLfloat, z: TGLfloat, w: TGLfloat){.
+    dynlib: dllname, importc: "glProgramEnvParameter4fARB".}
+proc glProgramEnvParameter4fvARB*(target: TGLenum, index: TGLuint, 
+                                  params: PGLfloat){.dynlib: dllname, 
+    importc: "glProgramEnvParameter4fvARB".}
+proc glProgramLocalParameter4dARB*(target: TGLenum, index: TGLuint, 
+                                   x: TGLdouble, y: TGLdouble, z: TGLdouble, 
+                                   w: TGLdouble){.dynlib: dllname, 
+    importc: "glProgramLocalParameter4dARB".}
+proc glProgramLocalParameter4dvARB*(target: TGLenum, index: TGLuint, 
+                                    params: PGLdouble){.dynlib: dllname, 
+    importc: "glProgramLocalParameter4dvARB".}
+proc glProgramLocalParameter4fARB*(target: TGLenum, index: TGLuint, x: TGLfloat, 
+                                   y: TGLfloat, z: TGLfloat, w: TGLfloat){.
+    dynlib: dllname, importc: "glProgramLocalParameter4fARB".}
+proc glProgramLocalParameter4fvARB*(target: TGLenum, index: TGLuint, 
+                                    params: PGLfloat){.dynlib: dllname, 
+    importc: "glProgramLocalParameter4fvARB".}
+proc glGetProgramEnvParameterdvARB*(target: TGLenum, index: TGLuint, 
+                                    params: PGLdouble){.dynlib: dllname, 
+    importc: "glGetProgramEnvParameterdvARB".}
+proc glGetProgramEnvParameterfvARB*(target: TGLenum, index: TGLuint, 
+                                    params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetProgramEnvParameterfvARB".}
+proc glGetProgramLocalParameterdvARB*(target: TGLenum, index: TGLuint, 
+                                      params: PGLdouble){.dynlib: dllname, 
+    importc: "glGetProgramLocalParameterdvARB".}
+proc glGetProgramLocalParameterfvARB*(target: TGLenum, index: TGLuint, 
+                                      params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetProgramLocalParameterfvARB".}
+proc glGetProgramivARB*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetProgramivARB".}
+proc glGetProgramStringARB*(target: TGLenum, pname: TGLenum, str: PGLvoid){.
+    dynlib: dllname, importc: "glGetProgramStringARB".}
+proc glGetVertexAttribdvARB*(index: TGLuint, pname: TGLenum, params: PGLdouble){.
+    dynlib: dllname, importc: "glGetVertexAttribdvARB".}
+proc glGetVertexAttribfvARB*(index: TGLuint, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetVertexAttribfvARB".}
+proc glGetVertexAttribivARB*(index: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetVertexAttribivARB".}
+proc glGetVertexAttribPointervARB*(index: TGLuint, pname: TGLenum, 
+                                   pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glGetVertexAttribPointervARB".}
+proc glIsProgramARB*(theProgram: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsProgramARB".}
+  #***** GL_ARB_window_pos *****//
+proc glWindowPos2dARB*(x: TGLdouble, y: TGLdouble){.dynlib: dllname, 
+    importc: "glWindowPos2dARB".}
+proc glWindowPos2fARB*(x: TGLfloat, y: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos2fARB".}
+proc glWindowPos2iARB*(x: TGLint, y: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos2iARB".}
+proc glWindowPos2sARB*(x: TGLshort, y: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos2sARB".}
+proc glWindowPos2dvARB*(p: PGLdouble){.dynlib: dllname, 
+                                       importc: "glWindowPos2dvARB".}
+proc glWindowPos2fvARB*(p: PGLfloat){.dynlib: dllname, 
+                                      importc: "glWindowPos2fvARB".}
+proc glWindowPos2ivARB*(p: PGLint){.dynlib: dllname, 
+                                    importc: "glWindowPos2ivARB".}
+proc glWindowPos2svARB*(p: PGLshort){.dynlib: dllname, 
+                                      importc: "glWindowPos2svARB".}
+proc glWindowPos3dARB*(x: TGLdouble, y: TGLdouble, z: TGLdouble){.
+    dynlib: dllname, importc: "glWindowPos3dARB".}
+proc glWindowPos3fARB*(x: TGLfloat, y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos3fARB".}
+proc glWindowPos3iARB*(x: TGLint, y: TGLint, z: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos3iARB".}
+proc glWindowPos3sARB*(x: TGLshort, y: TGLshort, z: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos3sARB".}
+proc glWindowPos3dvARB*(p: PGLdouble){.dynlib: dllname, 
+                                       importc: "glWindowPos3dvARB".}
+proc glWindowPos3fvARB*(p: PGLfloat){.dynlib: dllname, 
+                                      importc: "glWindowPos3fvARB".}
+proc glWindowPos3ivARB*(p: PGLint){.dynlib: dllname, 
+                                    importc: "glWindowPos3ivARB".}
+proc glWindowPos3svARB*(p: PGLshort){.dynlib: dllname, 
+                                      importc: "glWindowPos3svARB".}
+proc glBlendEquationSeparate*(modeRGB: TGLenum, modeAlpha: TGLenum){.
+    dynlib: dllname, importc: "glBlendEquationSeparate".}
+proc glDrawBuffers*(n: TGLsizei, bufs: PGLenum){.dynlib: dllname, 
+    importc: "glDrawBuffers".}
+proc glStencilOpSeparate*(face: TGLenum, sfail: TGLenum, dpfail: TGLenum, 
+                          dppass: TGLenum){.dynlib: dllname, 
+    importc: "glStencilOpSeparate".}
+proc glStencilFuncSeparate*(frontfunc: TGLenum, backfunc: TGLenum, 
+                            theRef: TGLint, mask: TGLuint){.dynlib: dllname, 
+    importc: "glStencilFuncSeparate".}
+proc glStencilMaskSeparate*(face: TGLenum, mask: TGLuint){.dynlib: dllname, 
+    importc: "glStencilMaskSeparate".}
+proc glAttachShader*(theProgram: TGLuint, shader: TGLuint){.dynlib: dllname, 
+    importc: "glAttachShader".}
+proc glBindAttribLocation*(theProgram: TGLuint, index: TGLuint, name: PGLchar){.
+    dynlib: dllname, importc: "glBindAttribLocation".}
+proc glCompileShader*(shader: TGLuint){.dynlib: dllname, 
+                                        importc: "glCompileShader".}
+proc glCreateProgram*(): TGLuint{.dynlib: dllname, importc: "glCreateProgram".}
+proc glCreateShader*(thetype: TGLenum): TGLuint{.dynlib: dllname, 
+    importc: "glCreateShader".}
+proc glDeleteProgram*(theProgram: TGLuint){.dynlib: dllname, 
+    importc: "glDeleteProgram".}
+proc glDeleteShader*(shader: TGLuint){.dynlib: dllname, 
+                                       importc: "glDeleteShader".}
+proc glDetachShader*(theProgram: TGLuint, shader: TGLuint){.dynlib: dllname, 
+    importc: "glDetachShader".}
+proc glDisableVertexAttribArray*(index: TGLuint){.dynlib: dllname, 
+    importc: "glDisableVertexAttribArray".}
+proc glEnableVertexAttribArray*(index: TGLuint){.dynlib: dllname, 
+    importc: "glEnableVertexAttribArray".}
+proc glGetActiveAttrib*(theProgram: TGLuint, index: TGLuint, bufSize: TGLsizei, 
+                        len: PGLsizei, size: PGLint, thetype: PGLenum, 
+                        name: PGLchar){.dynlib: dllname, 
+                                        importc: "glGetActiveAttrib".}
+proc glGetActiveUniform*(theProgram: TGLuint, index: TGLuint, bufSize: TGLsizei, 
+                         len: PGLsizei, size: PGLint, thetype: PGLenum, 
+                         name: PGLchar){.dynlib: dllname, 
+    importc: "glGetActiveUniform".}
+proc glGetAttachedShaders*(theProgram: TGLuint, maxCount: TGLsizei, 
+                           count: PGLsizei, obj: PGLuint){.dynlib: dllname, 
+    importc: "glGetAttachedShaders".}
+proc glGetAttribLocation*(theProgram: TGLuint, name: PGLchar): TGLint{.
+    dynlib: dllname, importc: "glGetAttribLocation".}
+proc glGetProgramiv*(theProgram: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetProgramiv".}
+proc glGetProgramInfoLog*(theProgram: TGLuint, bufSize: TGLsizei, len: PGLsizei, 
+                          infoLog: PGLchar){.dynlib: dllname, 
+    importc: "glGetProgramInfoLog".}
+proc glGetShaderiv*(shader: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetShaderiv".}
+proc glGetShaderInfoLog*(shader: TGLuint, bufSize: TGLsizei, len: PGLsizei, 
+                         infoLog: PGLchar){.dynlib: dllname, 
+    importc: "glGetShaderInfoLog".}
+proc glGetShaderSource*(shader: TGLuint, bufSize: TGLsizei, len: PGLsizei, 
+                        source: PGLchar){.dynlib: dllname, 
+    importc: "glGetShaderSource".}
+proc glGetUniformLocation*(theProgram: TGLuint, name: PGLchar): TGLint{.
+    dynlib: dllname, importc: "glGetUniformLocation".}
+proc glGetUniformfv*(theProgram: TGLuint, location: TGLint, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetUniformfv".}
+proc glGetUniformiv*(theProgram: TGLuint, location: TGLint, params: PGLint){.
+    dynlib: dllname, importc: "glGetUniformiv".}
+proc glGetVertexAttribdv*(index: TGLuint, pname: TGLenum, params: PGLdouble){.
+    dynlib: dllname, importc: "glGetVertexAttribdv".}
+proc glGetVertexAttribfv*(index: TGLuint, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetVertexAttribfv".}
+proc glGetVertexAttribiv*(index: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetVertexAttribiv".}
+proc glGetVertexAttribPointerv*(index: TGLuint, pname: TGLenum, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glGetVertexAttribPointerv".}
+proc glIsProgram*(theProgram: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsProgram".}
+proc glIsShader*(shader: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsShader".}
+proc glLinkProgram*(theProgram: TGLuint){.dynlib: dllname, 
+    importc: "glLinkProgram".}
+proc glShaderSource*(shader: TGLuint, count: TGLsizei, str: PGLchar, len: PGLint){.
+    dynlib: dllname, importc: "glShaderSource".}
+proc glUseProgram*(theProgram: TGLuint){.dynlib: dllname, 
+    importc: "glUseProgram".}
+proc glUniform1f*(location: TGLint, v0: TGLfloat){.dynlib: dllname, 
+    importc: "glUniform1f".}
+proc glUniform2f*(location: TGLint, v0: TGLfloat, v1: TGLfloat){.
+    dynlib: dllname, importc: "glUniform2f".}
+proc glUniform3f*(location: TGLint, v0: TGLfloat, v1: TGLfloat, v2: TGLfloat){.
+    dynlib: dllname, importc: "glUniform3f".}
+proc glUniform4f*(location: TGLint, v0: TGLfloat, v1: TGLfloat, v2: TGLfloat, 
+                  v3: TGLfloat){.dynlib: dllname, importc: "glUniform4f".}
+proc glUniform1i*(location: TGLint, v0: TGLint){.dynlib: dllname, 
+    importc: "glUniform1i".}
+proc glUniform2i*(location: TGLint, v0: TGLint, v1: TGLint){.dynlib: dllname, 
+    importc: "glUniform2i".}
+proc glUniform3i*(location: TGLint, v0: TGLint, v1: TGLint, v2: TGLint){.
+    dynlib: dllname, importc: "glUniform3i".}
+proc glUniform4i*(location: TGLint, v0: TGLint, v1: TGLint, v2: TGLint, 
+                  v3: TGLint){.dynlib: dllname, importc: "glUniform4i".}
+proc glUniform1fv*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform1fv".}
+proc glUniform2fv*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform2fv".}
+proc glUniform3fv*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform3fv".}
+proc glUniform4fv*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform4fv".}
+proc glUniform1iv*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform1iv".}
+proc glUniform2iv*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform2iv".}
+proc glUniform3iv*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform3iv".}
+proc glUniform4iv*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform4iv".}
+proc glUniformMatrix2fv*(location: TGLint, count: TGLsizei, 
+                         transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix2fv".}
+proc glUniformMatrix3fv*(location: TGLint, count: TGLsizei, 
+                         transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix3fv".}
+proc glUniformMatrix4fv*(location: TGLint, count: TGLsizei, 
+                         transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix4fv".}
+proc glValidateProgram*(theProgram: TGLuint){.dynlib: dllname, 
+    importc: "glValidateProgram".}
+proc glVertexAttrib1d*(index: TGLuint, x: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1d".}
+proc glVertexAttrib1dv*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1dv".}
+proc glVertexAttrib1f*(index: TGLuint, x: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1f".}
+proc glVertexAttrib1fv*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1fv".}
+proc glVertexAttrib1s*(index: TGLuint, x: TGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1s".}
+proc glVertexAttrib1sv*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1sv".}
+proc glVertexAttrib2d*(index: TGLuint, x: TGLdouble, y: TGLdouble){.
+    dynlib: dllname, importc: "glVertexAttrib2d".}
+proc glVertexAttrib2dv*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib2dv".}
+proc glVertexAttrib2f*(index: TGLuint, x: TGLfloat, y: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib2f".}
+proc glVertexAttrib2fv*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib2fv".}
+proc glVertexAttrib2s*(index: TGLuint, x: TGLshort, y: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib2s".}
+proc glVertexAttrib2sv*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib2sv".}
+proc glVertexAttrib3d*(index: TGLuint, x: TGLdouble, y: TGLdouble, z: TGLdouble){.
+    dynlib: dllname, importc: "glVertexAttrib3d".}
+proc glVertexAttrib3dv*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib3dv".}
+proc glVertexAttrib3f*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib3f".}
+proc glVertexAttrib3fv*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib3fv".}
+proc glVertexAttrib3s*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib3s".}
+proc glVertexAttrib3sv*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib3sv".}
+proc glVertexAttrib4Nbv*(index: TGLuint, v: PGLbyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4Nbv".}
+proc glVertexAttrib4Niv*(index: TGLuint, v: PGLint){.dynlib: dllname, 
+    importc: "glVertexAttrib4Niv".}
+proc glVertexAttrib4Nsv*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib4Nsv".}
+proc glVertexAttrib4Nub*(index: TGLuint, x: TGLubyte, y: TGLubyte, z: TGLubyte, 
+                         w: TGLubyte){.dynlib: dllname, 
+                                       importc: "glVertexAttrib4Nub".}
+proc glVertexAttrib4Nubv*(index: TGLuint, v: PGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4Nubv".}
+proc glVertexAttrib4Nuiv*(index: TGLuint, v: PGLuint){.dynlib: dllname, 
+    importc: "glVertexAttrib4Nuiv".}
+proc glVertexAttrib4Nusv*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4Nusv".}
+proc glVertexAttrib4bv*(index: TGLuint, v: PGLbyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4bv".}
+proc glVertexAttrib4d*(index: TGLuint, x: TGLdouble, y: TGLdouble, z: TGLdouble, 
+                       w: TGLdouble){.dynlib: dllname, 
+                                      importc: "glVertexAttrib4d".}
+proc glVertexAttrib4dv*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib4dv".}
+proc glVertexAttrib4f*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat, 
+                       w: TGLfloat){.dynlib: dllname, 
+                                     importc: "glVertexAttrib4f".}
+proc glVertexAttrib4fv*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib4fv".}
+proc glVertexAttrib4iv*(index: TGLuint, v: PGLint){.dynlib: dllname, 
+    importc: "glVertexAttrib4iv".}
+proc glVertexAttrib4s*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort, 
+                       w: TGLshort){.dynlib: dllname, 
+                                     importc: "glVertexAttrib4s".}
+proc glVertexAttrib4sv*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib4sv".}
+proc glVertexAttrib4ubv*(index: TGLuint, v: PGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4ubv".}
+proc glVertexAttrib4uiv*(index: TGLuint, v: PGLuint){.dynlib: dllname, 
+    importc: "glVertexAttrib4uiv".}
+proc glVertexAttrib4usv*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4usv".}
+proc glVertexAttribPointer*(index: TGLuint, size: TGLint, thetype: TGLenum, 
+                            normalized: TGLboolean, stride: TGLsizei, 
+                            pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexAttribPointer".}
+const 
+  GL_CONSTANT_COLOR* = 0x00008001
+  GL_ONE_MINUS_CONSTANT_COLOR* = 0x00008002
+  GL_CONSTANT_ALPHA* = 0x00008003
+  GL_ONE_MINUS_CONSTANT_ALPHA* = 0x00008004
+  constGL_BLEND_COLOR* = 0x00008005
+  GL_FUNC_ADD* = 0x00008006
+  GL_MIN* = 0x00008007
+  GL_MAX* = 0x00008008
+  constGL_BLEND_EQUATION* = 0x00008009
+  GL_FUNC_SUBTRACT* = 0x0000800A
+  GL_FUNC_REVERSE_SUBTRACT* = 0x0000800B
+  GL_CONVOLUTION_1D* = 0x00008010
+  GL_CONVOLUTION_2D* = 0x00008011
+  GL_SEPARABLE_2D* = 0x00008012
+  GL_CONVOLUTION_BORDER_MODE* = 0x00008013
+  GL_CONVOLUTION_FILTER_SCALE* = 0x00008014
+  GL_CONVOLUTION_FILTER_BIAS* = 0x00008015
+  GL_REDUCE* = 0x00008016
+  GL_CONVOLUTION_FORMAT* = 0x00008017
+  GL_CONVOLUTION_WIDTH* = 0x00008018
+  GL_CONVOLUTION_HEIGHT* = 0x00008019
+  GL_MAX_CONVOLUTION_WIDTH* = 0x0000801A
+  GL_MAX_CONVOLUTION_HEIGHT* = 0x0000801B
+  GL_POST_CONVOLUTION_RED_SCALE* = 0x0000801C
+  GL_POST_CONVOLUTION_GREEN_SCALE* = 0x0000801D
+  GL_POST_CONVOLUTION_BLUE_SCALE* = 0x0000801E
+  GL_POST_CONVOLUTION_ALPHA_SCALE* = 0x0000801F
+  GL_POST_CONVOLUTION_RED_BIAS* = 0x00008020
+  GL_POST_CONVOLUTION_GREEN_BIAS* = 0x00008021
+  GL_POST_CONVOLUTION_BLUE_BIAS* = 0x00008022
+  GL_POST_CONVOLUTION_ALPHA_BIAS* = 0x00008023
+  constGL_HISTOGRAM* = 0x00008024
+  GL_PROXY_HISTOGRAM* = 0x00008025
+  GL_HISTOGRAM_WIDTH* = 0x00008026
+  GL_HISTOGRAM_FORMAT* = 0x00008027
+  GL_HISTOGRAM_RED_SIZE* = 0x00008028
+  GL_HISTOGRAM_GREEN_SIZE* = 0x00008029
+  GL_HISTOGRAM_BLUE_SIZE* = 0x0000802A
+  GL_HISTOGRAM_ALPHA_SIZE* = 0x0000802B
+  GL_HISTOGRAM_LUMINANCE_SIZE* = 0x0000802C
+  GL_HISTOGRAM_SINK* = 0x0000802D
+  constGL_MINMAX* = 0x0000802E
+  GL_MINMAX_FORMAT* = 0x0000802F
+  GL_MINMAX_SINK* = 0x00008030
+  GL_TABLE_TOO_LARGE* = 0x00008031
+  GL_COLOR_MATRIX* = 0x000080B1
+  GL_COLOR_MATRIX_STACK_DEPTH* = 0x000080B2
+  GL_MAX_COLOR_MATRIX_STACK_DEPTH* = 0x000080B3
+  GL_POST_COLOR_MATRIX_RED_SCALE* = 0x000080B4
+  GL_POST_COLOR_MATRIX_GREEN_SCALE* = 0x000080B5
+  GL_POST_COLOR_MATRIX_BLUE_SCALE* = 0x000080B6
+  GL_POST_COLOR_MATRIX_ALPHA_SCALE* = 0x000080B7
+  GL_POST_COLOR_MATRIX_RED_BIAS* = 0x000080B8
+  GL_POST_COLOR_MATRIX_GREEN_BIAS* = 0x000080B9
+  GL_POST_COLOR_MATRIX_BLUE_BIAS* = 0x000080BA
+  GL_POST_COLOR_MATIX_ALPHA_BIAS* = 0x000080BB
+  constGL_COLOR_TABLE* = 0x000080D0
+  GL_POST_CONVOLUTION_COLOR_TABLE* = 0x000080D1
+  GL_POST_COLOR_MATRIX_COLOR_TABLE* = 0x000080D2
+  GL_PROXY_COLOR_TABLE* = 0x000080D3
+  GL_PROXY_POST_CONVOLUTION_COLOR_TABLE* = 0x000080D4
+  GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE* = 0x000080D5
+  GL_COLOR_TABLE_SCALE* = 0x000080D6
+  GL_COLOR_TABLE_BIAS* = 0x000080D7
+  GL_COLOR_TABLE_FORMAT* = 0x000080D8
+  GL_COLOR_TABLE_WIDTH* = 0x000080D9
+  GL_COLOR_TABLE_RED_SIZE* = 0x000080DA
+  GL_COLOR_TABLE_GREEN_SIZE* = 0x000080DB
+  GL_COLOR_TABLE_BLUE_SIZE* = 0x000080DC
+  GL_COLOR_TABLE_ALPHA_SIZE* = 0x000080DD
+  GL_COLOR_TABLE_LUMINANCE_SIZE* = 0x000080DE
+  GL_COLOR_TABLE_INTENSITY_SIZE* = 0x000080DF
+  GL_IGNORE_BORDER* = 0x00008150
+  GL_CONSTANT_BORDER* = 0x00008151
+  GL_WRAP_BORDER* = 0x00008152
+  GL_REPLICATE_BORDER* = 0x00008153
+  GL_CONVOLUTION_BORDER_COLOR* = 0x00008154
+
+proc glActiveTexture*(texture: TGLenum){.dynlib: dllname, 
+    importc: "glActiveTexture".}
+proc glClientActiveTexture*(texture: TGLenum){.dynlib: dllname, 
+    importc: "glClientActiveTexture".}
+proc glMultiTexCoord1d*(target: TGLenum, s: TGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord1d".}
+proc glMultiTexCoord1dv*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord1dv".}
+proc glMultiTexCoord1f*(target: TGLenum, s: TGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord1f".}
+proc glMultiTexCoord1fv*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord1fv".}
+proc glMultiTexCoord1i*(target: TGLenum, s: TGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord1i".}
+proc glMultiTexCoord1iv*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord1iv".}
+proc glMultiTexCoord1s*(target: TGLenum, s: TGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1s".}
+proc glMultiTexCoord1sv*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1sv".}
+proc glMultiTexCoord2d*(target: TGLenum, s: TGLdouble, t: TGLdouble){.
+    dynlib: dllname, importc: "glMultiTexCoord2d".}
+proc glMultiTexCoord2dv*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord2dv".}
+proc glMultiTexCoord2f*(target: TGLenum, s: TGLfloat, t: TGLfloat){.
+    dynlib: dllname, importc: "glMultiTexCoord2f".}
+proc glMultiTexCoord2fv*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord2fv".}
+proc glMultiTexCoord2i*(target: TGLenum, s: TGLint, t: TGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord2i".}
+proc glMultiTexCoord2iv*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord2iv".}
+proc glMultiTexCoord2s*(target: TGLenum, s: TGLshort, t: TGLshort){.
+    dynlib: dllname, importc: "glMultiTexCoord2s".}
+proc glMultiTexCoord2sv*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord2sv".}
+proc glMultiTexCoord3d*(target: TGLenum, s: TGLdouble, t: TGLdouble, 
+                        r: TGLdouble){.dynlib: dllname, 
+                                       importc: "glMultiTexCoord3d".}
+proc glMultiTexCoord3dv*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord3dv".}
+proc glMultiTexCoord3f*(target: TGLenum, s: TGLfloat, t: TGLfloat, r: TGLfloat){.
+    dynlib: dllname, importc: "glMultiTexCoord3f".}
+proc glMultiTexCoord3fv*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord3fv".}
+proc glMultiTexCoord3i*(target: TGLenum, s: TGLint, t: TGLint, r: TGLint){.
+    dynlib: dllname, importc: "glMultiTexCoord3i".}
+proc glMultiTexCoord3iv*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord3iv".}
+proc glMultiTexCoord3s*(target: TGLenum, s: TGLshort, t: TGLshort, r: TGLshort){.
+    dynlib: dllname, importc: "glMultiTexCoord3s".}
+proc glMultiTexCoord3sv*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord3sv".}
+proc glMultiTexCoord4d*(target: TGLenum, s: TGLdouble, t: TGLdouble, 
+                        r: TGLdouble, q: TGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord4d".}
+proc glMultiTexCoord4dv*(target: TGLenum, v: PGLdouble){.dynlib: dllname, 
+    importc: "glMultiTexCoord4dv".}
+proc glMultiTexCoord4f*(target: TGLenum, s: TGLfloat, t: TGLfloat, r: TGLfloat, 
+                        q: TGLfloat){.dynlib: dllname, 
+                                      importc: "glMultiTexCoord4f".}
+proc glMultiTexCoord4fv*(target: TGLenum, v: PGLfloat){.dynlib: dllname, 
+    importc: "glMultiTexCoord4fv".}
+proc glMultiTexCoord4i*(target: TGLenum, s: TGLint, t: TGLint, r: TGLint, 
+                        q: TGLint){.dynlib: dllname, 
+                                    importc: "glMultiTexCoord4i".}
+proc glMultiTexCoord4iv*(target: TGLenum, v: PGLint){.dynlib: dllname, 
+    importc: "glMultiTexCoord4iv".}
+proc glMultiTexCoord4s*(target: TGLenum, s: TGLshort, t: TGLshort, r: TGLshort, 
+                        q: TGLshort){.dynlib: dllname, 
+                                      importc: "glMultiTexCoord4s".}
+proc glMultiTexCoord4sv*(target: TGLenum, v: PGLshort){.dynlib: dllname, 
+    importc: "glMultiTexCoord4sv".}
+proc glLoadTransposeMatrixf*(m: PGLfloat){.dynlib: dllname, 
+    importc: "glLoadTransposeMatrixf".}
+proc glLoadTransposeMatrixd*(m: PGLdouble){.dynlib: dllname, 
+    importc: "glLoadTransposeMatrixd".}
+proc glMultTransposeMatrixf*(m: PGLfloat){.dynlib: dllname, 
+    importc: "glMultTransposeMatrixf".}
+proc glMultTransposeMatrixd*(m: PGLdouble){.dynlib: dllname, 
+    importc: "glMultTransposeMatrixd".}
+proc glSampleCoverage*(value: TGLclampf, invert: TGLboolean){.dynlib: dllname, 
+    importc: "glSampleCoverage".}
+proc glCompressedTexImage3D*(target: TGLenum, level: TGLint, 
+                             internalformat: TGLenum, width: TGLsizei, 
+                             height: TGLsizei, depth: TGLsizei, border: TGLint, 
+                             imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexImage3D".}
+proc glCompressedTexImage2D*(target: TGLenum, level: TGLint, 
+                             internalformat: TGLenum, width: TGLsizei, 
+                             height: TGLsizei, border: TGLint, 
+                             imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexImage2D".}
+proc glCompressedTexImage1D*(target: TGLenum, level: TGLint, 
+                             internalformat: TGLenum, width: TGLsizei, 
+                             border: TGLint, imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexImage1D".}
+proc glCompressedTexSubImage3D*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                                yoffset: TGLint, zoffset: TGLint, 
+                                width: TGLsizei, height: TGLsizei, 
+                                depth: TGLsizei, format: TGLenum, 
+                                imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexSubImage3D".}
+proc glCompressedTexSubImage2D*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                                yoffset: TGLint, width: TGLsizei, 
+                                height: TGLsizei, format: TGLenum, 
+                                imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexSubImage2D".}
+proc glCompressedTexSubImage1D*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                                width: TGLsizei, format: TGLenum, 
+                                imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexSubImage1D".}
+proc glGetCompressedTexImage*(target: TGLenum, level: TGLint, img: PGLvoid){.
+    dynlib: dllname, importc: "glGetCompressedTexImage".}
+  #***** GL_version_1_3 *****//
+const 
+  GL_TEXTURE0* = 0x000084C0
+  GL_TEXTURE1* = 0x000084C1
+  GL_TEXTURE2* = 0x000084C2
+  GL_TEXTURE3* = 0x000084C3
+  GL_TEXTURE4* = 0x000084C4
+  GL_TEXTURE5* = 0x000084C5
+  GL_TEXTURE6* = 0x000084C6
+  GL_TEXTURE7* = 0x000084C7
+  GL_TEXTURE8* = 0x000084C8
+  GL_TEXTURE9* = 0x000084C9
+  GL_TEXTURE10* = 0x000084CA
+  GL_TEXTURE11* = 0x000084CB
+  GL_TEXTURE12* = 0x000084CC
+  GL_TEXTURE13* = 0x000084CD
+  GL_TEXTURE14* = 0x000084CE
+  GL_TEXTURE15* = 0x000084CF
+  GL_TEXTURE16* = 0x000084D0
+  GL_TEXTURE17* = 0x000084D1
+  GL_TEXTURE18* = 0x000084D2
+  GL_TEXTURE19* = 0x000084D3
+  GL_TEXTURE20* = 0x000084D4
+  GL_TEXTURE21* = 0x000084D5
+  GL_TEXTURE22* = 0x000084D6
+  GL_TEXTURE23* = 0x000084D7
+  GL_TEXTURE24* = 0x000084D8
+  GL_TEXTURE25* = 0x000084D9
+  GL_TEXTURE26* = 0x000084DA
+  GL_TEXTURE27* = 0x000084DB
+  GL_TEXTURE28* = 0x000084DC
+  GL_TEXTURE29* = 0x000084DD
+  GL_TEXTURE30* = 0x000084DE
+  GL_TEXTURE31* = 0x000084DF
+  constGL_ACTIVE_TEXTURE* = 0x000084E0
+  constGL_CLIENT_ACTIVE_TEXTURE* = 0x000084E1
+  GL_MAX_TEXTURE_UNITS* = 0x000084E2
+  GL_TRANSPOSE_MODELVIEW_MATRIX* = 0x000084E3
+  GL_TRANSPOSE_PROJECTION_MATRIX* = 0x000084E4
+  GL_TRANSPOSE_TEXTURE_MATRIX* = 0x000084E5
+  GL_TRANSPOSE_COLOR_MATRIX* = 0x000084E6
+  GL_MULTISAMPLE* = 0x0000809D
+  GL_SAMPLE_ALPHA_TO_COVERAGE* = 0x0000809E
+  GL_SAMPLE_ALPHA_TO_ONE* = 0x0000809F
+  constGL_SAMPLE_COVERAGE* = 0x000080A0
+  GL_SAMPLE_BUFFERS* = 0x000080A8
+  GL_SAMPLES* = 0x000080A9
+  GL_SAMPLE_COVERAGE_VALUE* = 0x000080AA
+  GL_SAMPLE_COVERAGE_INVERT* = 0x000080AB
+  GL_MULTISAMPLE_BIT* = 0x20000000
+  GL_NORMAL_MAP* = 0x00008511
+  GL_REFLECTION_MAP* = 0x00008512
+  GL_TEXTURE_CUBE_MAP* = 0x00008513
+  GL_TEXTURE_BINDING_CUBE_MAP* = 0x00008514
+  GL_TEXTURE_CUBE_MAP_POSITIVE_X* = 0x00008515
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_X* = 0x00008516
+  GL_TEXTURE_CUBE_MAP_POSITIVE_Y* = 0x00008517
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y* = 0x00008518
+  GL_TEXTURE_CUBE_MAP_POSITIVE_Z* = 0x00008519
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z* = 0x0000851A
+  GL_PROXY_TEXTURE_CUBE_MAP* = 0x0000851B
+  GL_MAX_CUBE_MAP_TEXTURE_SIZE* = 0x0000851C
+  GL_COMPRESSED_ALPHA* = 0x000084E9
+  GL_COMPRESSED_LUMINANCE* = 0x000084EA
+  GL_COMPRESSED_LUMINANCE_ALPHA* = 0x000084EB
+  GL_COMPRESSED_INTENSITY* = 0x000084EC
+  GL_COMPRESSED_RGB* = 0x000084ED
+  GL_COMPRESSED_RGBA* = 0x000084EE
+  GL_TEXTURE_COMPRESSION_HINT* = 0x000084EF
+  GL_TEXTURE_COMPRESSED_IMAGE_SIZE* = 0x000086A0
+  GL_TEXTURE_COMPRESSED* = 0x000086A1
+  GL_NUM_COMPRESSED_TEXTURE_FORMATS* = 0x000086A2
+  GL_COMPRESSED_TEXTURE_FORMATS* = 0x000086A3
+  GL_CLAMP_TO_BORDER* = 0x0000812D
+  GL_CLAMP_TO_BORDER_SGIS* = 0x0000812D
+  GL_COMBINE* = 0x00008570
+  GL_COMBINE_RGB* = 0x00008571
+  GL_COMBINE_ALPHA* = 0x00008572
+  GL_SOURCE0_RGB* = 0x00008580
+  GL_SOURCE1_RGB* = 0x00008581
+  GL_SOURCE2_RGB* = 0x00008582
+  GL_SOURCE0_ALPHA* = 0x00008588
+  GL_SOURCE1_ALPHA* = 0x00008589
+  GL_SOURCE2_ALPHA* = 0x0000858A
+  GL_OPERAND0_RGB* = 0x00008590
+  GL_OPERAND1_RGB* = 0x00008591
+  GL_OPERAND2_RGB* = 0x00008592
+  GL_OPERAND0_ALPHA* = 0x00008598
+  GL_OPERAND1_ALPHA* = 0x00008599
+  GL_OPERAND2_ALPHA* = 0x0000859A
+  GL_RGB_SCALE* = 0x00008573
+  GL_ADD_SIGNED* = 0x00008574
+  GL_INTERPOLATE* = 0x00008575
+  GL_SUBTRACT* = 0x000084E7
+  GL_CONSTANT* = 0x00008576
+  GL_PRIMARY_COLOR* = 0x00008577
+  GL_PREVIOUS* = 0x00008578
+  GL_DOT3_RGB* = 0x000086AE
+  GL_DOT3_RGBA* = 0x000086AF
+
+const 
+  GL_TEXTURE0_ARB* = 0x000084C0
+  GL_TEXTURE1_ARB* = 0x000084C1
+  GL_TEXTURE2_ARB* = 0x000084C2
+  GL_TEXTURE3_ARB* = 0x000084C3
+  GL_TEXTURE4_ARB* = 0x000084C4
+  GL_TEXTURE5_ARB* = 0x000084C5
+  GL_TEXTURE6_ARB* = 0x000084C6
+  GL_TEXTURE7_ARB* = 0x000084C7
+  GL_TEXTURE8_ARB* = 0x000084C8
+  GL_TEXTURE9_ARB* = 0x000084C9
+  GL_TEXTURE10_ARB* = 0x000084CA
+  GL_TEXTURE11_ARB* = 0x000084CB
+  GL_TEXTURE12_ARB* = 0x000084CC
+  GL_TEXTURE13_ARB* = 0x000084CD
+  GL_TEXTURE14_ARB* = 0x000084CE
+  GL_TEXTURE15_ARB* = 0x000084CF
+  GL_TEXTURE16_ARB* = 0x000084D0
+  GL_TEXTURE17_ARB* = 0x000084D1
+  GL_TEXTURE18_ARB* = 0x000084D2
+  GL_TEXTURE19_ARB* = 0x000084D3
+  GL_TEXTURE20_ARB* = 0x000084D4
+  GL_TEXTURE21_ARB* = 0x000084D5
+  GL_TEXTURE22_ARB* = 0x000084D6
+  GL_TEXTURE23_ARB* = 0x000084D7
+  GL_TEXTURE24_ARB* = 0x000084D8
+  GL_TEXTURE25_ARB* = 0x000084D9
+  GL_TEXTURE26_ARB* = 0x000084DA
+  GL_TEXTURE27_ARB* = 0x000084DB
+  GL_TEXTURE28_ARB* = 0x000084DC
+  GL_TEXTURE29_ARB* = 0x000084DD
+  GL_TEXTURE30_ARB* = 0x000084DE
+  GL_TEXTURE31_ARB* = 0x000084DF
+  constGL_ACTIVE_TEXTURE_ARB* = 0x000084E0
+  constGL_CLIENT_ACTIVE_TEXTURE_ARB* = 0x000084E1
+  GL_MAX_TEXTURE_UNITS_ARB* = 0x000084E2
+  #***** GL_ARB_transpose_matrix *****//
+
+const 
+  GL_TRANSPOSE_MODELVIEW_MATRIX_ARB* = 0x000084E3
+  GL_TRANSPOSE_PROJECTION_MATRIX_ARB* = 0x000084E4
+  GL_TRANSPOSE_TEXTURE_MATRIX_ARB* = 0x000084E5
+  GL_TRANSPOSE_COLOR_MATRIX_ARB* = 0x000084E6
+
+proc glLoadTransposeMatrixfARB*(m: PGLfloat){.dynlib: dllname, 
+    importc: "glLoadTransposeMatrixfARB".}
+proc glLoadTransposeMatrixdARB*(m: PGLdouble){.dynlib: dllname, 
+    importc: "glLoadTransposeMatrixdARB".}
+proc glMultTransposeMatrixfARB*(m: PGLfloat){.dynlib: dllname, 
+    importc: "glMultTransposeMatrixfARB".}
+proc glMultTransposeMatrixdARB*(m: PGLdouble){.dynlib: dllname, 
+    importc: "glMultTransposeMatrixdARB".}
+const 
+  WGL_SAMPLE_BUFFERS_ARB* = 0x00002041
+  WGL_SAMPLES_ARB* = 0x00002042
+  GL_MULTISAMPLE_ARB* = 0x0000809D
+  GL_SAMPLE_ALPHA_TO_COVERAGE_ARB* = 0x0000809E
+  GL_SAMPLE_ALPHA_TO_ONE_ARB* = 0x0000809F
+  constGL_SAMPLE_COVERAGE_ARB* = 0x000080A0
+  GL_MULTISAMPLE_BIT_ARB* = 0x20000000
+  GL_SAMPLE_BUFFERS_ARB* = 0x000080A8
+  GL_SAMPLES_ARB* = 0x000080A9
+  GL_SAMPLE_COVERAGE_VALUE_ARB* = 0x000080AA
+  GL_SAMPLE_COVERAGE_INVERT_ARB* = 0x000080AB
+
+const 
+  GL_NORMAL_MAP_ARB* = 0x00008511
+  GL_REFLECTION_MAP_ARB* = 0x00008512
+  GL_TEXTURE_CUBE_MAP_ARB* = 0x00008513
+  GL_TEXTURE_BINDING_CUBE_MAP_ARB* = 0x00008514
+  GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB* = 0x00008515
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB* = 0x00008516
+  GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB* = 0x00008517
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB* = 0x00008518
+  GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB* = 0x00008519
+  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB* = 0x0000851A
+  GL_PROXY_TEXTURE_CUBE_MAP_ARB* = 0x0000851B
+  GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB* = 0x0000851C
+
+const 
+  GL_DEPTH_COMPONENT16_ARB* = 0x000081A5
+  GL_DEPTH_COMPONENT24_ARB* = 0x000081A6
+  GL_DEPTH_COMPONENT32_ARB* = 0x000081A7
+  GL_TEXTURE_DEPTH_SIZE_ARB* = 0x0000884A
+  GL_DEPTH_TEXTURE_MODE_ARB* = 0x0000884B
+  #***** GL_ARB_point_parameters *****//
+
+const 
+  GL_POINT_SIZE_MIN_ARB* = 0x00008126
+  GL_POINT_SIZE_MAX_ARB* = 0x00008127
+  GL_POINT_FADE_THRESHOLD_SIZE_ARB* = 0x00008128
+  GL_POINT_DISTANCE_ATTENUATION_ARB* = 0x00008129
+
+proc glPointParameterfARB*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterfARB".}
+proc glPointParameterfvARB*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterfvARB".}
+const 
+  GL_TEXTURE_COMPARE_MODE_ARB* = 0x0000884C
+  GL_TEXTURE_COMPARE_FUNC_ARB* = 0x0000884D
+  GL_COMPARE_R_TO_TEXTURE_ARB* = 0x0000884E
+
+const 
+  GL_TEXTURE_COMPARE_FAIL_VALUE_ARB* = 0x000080BF
+  GL_CLAMP_TO_BORDER_ARB* = 0x0000812D
+
+const 
+  GL_COMPRESSED_ALPHA_ARB* = 0x000084E9
+  GL_COMPRESSED_LUMINANCE_ARB* = 0x000084EA
+  GL_COMPRESSED_LUMINANCE_ALPHA_ARB* = 0x000084EB
+  GL_COMPRESSED_INTENSITY_ARB* = 0x000084EC
+  GL_COMPRESSED_RGB_ARB* = 0x000084ED
+  GL_COMPRESSED_RGBA_ARB* = 0x000084EE
+  GL_TEXTURE_COMPRESSION_HINT_ARB* = 0x000084EF
+  GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB* = 0x000086A0
+  GL_TEXTURE_COMPRESSED_ARB* = 0x000086A1
+  GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB* = 0x000086A2
+  GL_COMPRESSED_TEXTURE_FORMATS_ARB* = 0x000086A3
+
+proc glCompressedTexImage3DARB*(target: TGLenum, level: TGLint, 
+                                internalformat: TGLenum, width: TGLsizei, 
+                                height: TGLsizei, depth: TGLsizei, 
+                                border: TGLint, imageSize: TGLsizei, 
+                                data: PGLvoid){.dynlib: dllname, 
+    importc: "glCompressedTexImage3DARB".}
+proc glCompressedTexImage2DARB*(target: TGLenum, level: TGLint, 
+                                internalformat: TGLenum, width: TGLsizei, 
+                                height: TGLsizei, border: TGLint, 
+                                imageSize: TGLsizei, data: PGLvoid){.
+    dynlib: dllname, importc: "glCompressedTexImage2DARB".}
+proc glCompressedTexImage1DARB*(target: TGLenum, level: TGLint, 
+                                internalformat: TGLenum, width: TGLsizei, 
+                                border: TGLint, imageSize: TGLsizei, 
+                                data: PGLvoid){.dynlib: dllname, 
+    importc: "glCompressedTexImage1DARB".}
+proc glCompressedTexSubImage3DARB*(target: TGLenum, level: TGLint, 
+                                   xoffset: TGLint, yoffset: TGLint, 
+                                   zoffset: TGLint, width: TGLsizei, 
+                                   height: TGLsizei, depth: TGLsizei, 
+                                   format: TGLenum, imageSize: TGLsizei, 
+                                   data: PGLvoid){.dynlib: dllname, 
+    importc: "glCompressedTexSubImage3DARB".}
+proc glCompressedTexSubImage2DARB*(target: TGLenum, level: TGLint, 
+                                   xoffset: TGLint, yoffset: TGLint, 
+                                   width: TGLsizei, height: TGLsizei, 
+                                   format: TGLenum, imageSize: TGLsizei, 
+                                   data: PGLvoid){.dynlib: dllname, 
+    importc: "glCompressedTexSubImage2DARB".}
+proc glCompressedTexSubImage1DARB*(target: TGLenum, level: TGLint, 
+                                   xoffset: TGLint, width: TGLsizei, 
+                                   format: TGLenum, imageSize: TGLsizei, 
+                                   data: PGLvoid){.dynlib: dllname, 
+    importc: "glCompressedTexSubImage1DARB".}
+proc glGetCompressedTexImageARB*(target: TGLenum, lod: TGLint, img: PGLvoid){.
+    dynlib: dllname, importc: "glGetCompressedTexImageARB".}
+  #***** GL_ARB_texture_env_combine *****//
+const 
+  GL_COMBINE_ARB* = 0x00008570
+  GL_COMBINE_RGB_ARB* = 0x00008571
+  GL_COMBINE_ALPHA_ARB* = 0x00008572
+  GL_SOURCE0_RGB_ARB* = 0x00008580
+  GL_SOURCE1_RGB_ARB* = 0x00008581
+  GL_SOURCE2_RGB_ARB* = 0x00008582
+  GL_SOURCE0_ALPHA_ARB* = 0x00008588
+  GL_SOURCE1_ALPHA_ARB* = 0x00008589
+  GL_SOURCE2_ALPHA_ARB* = 0x0000858A
+  GL_OPERAND0_RGB_ARB* = 0x00008590
+  GL_OPERAND1_RGB_ARB* = 0x00008591
+  GL_OPERAND2_RGB_ARB* = 0x00008592
+  GL_OPERAND0_ALPHA_ARB* = 0x00008598
+  GL_OPERAND1_ALPHA_ARB* = 0x00008599
+  GL_OPERAND2_ALPHA_ARB* = 0x0000859A
+  GL_RGB_SCALE_ARB* = 0x00008573
+  GL_ADD_SIGNED_ARB* = 0x00008574
+  GL_INTERPOLATE_ARB* = 0x00008575
+  GL_SUBTRACT_ARB* = 0x000084E7
+  GL_CONSTANT_ARB* = 0x00008576
+  GL_PRIMARY_COLOR_ARB* = 0x00008577
+  GL_PREVIOUS_ARB* = 0x00008578
+  #***** GL_ARB_texture_env_crossbar *****//
+  #***** GL_ARB_texture_env_dot3 *****//
+
+const 
+  GL_DOT3_RGB_ARB* = 0x000086AE
+  GL_DOT3_RGBA_ARB* = 0x000086AF
+  #***** GL_ARB_texture_mirrored_repeat *****//
+
+const 
+  GL_MIRRORED_REPEAT_ARB* = 0x00008370
+  #***** GL_ARB_vertex_blend *****//
+
+const 
+  GL_MAX_VERTEX_UNITS_ARB* = 0x000086A4
+  GL_ACTIVE_VERTEX_UNITS_ARB* = 0x000086A5
+  GL_WEIGHT_SUM_UNITY_ARB* = 0x000086A6
+  constGL_VERTEX_BLEND_ARB* = 0x000086A7
+  GL_MODELVIEW0_ARB* = 0x00001700
+  GL_MODELVIEW1_ARB* = 0x0000850A
+  GL_MODELVIEW2_ARB* = 0x00008722
+  GL_MODELVIEW3_ARB* = 0x00008723
+  GL_MODELVIEW4_ARB* = 0x00008724
+  GL_MODELVIEW5_ARB* = 0x00008725
+  GL_MODELVIEW6_ARB* = 0x00008726
+  GL_MODELVIEW7_ARB* = 0x00008727
+  GL_MODELVIEW8_ARB* = 0x00008728
+  GL_MODELVIEW9_ARB* = 0x00008729
+  GL_MODELVIEW10_ARB* = 0x0000872A
+  GL_MODELVIEW11_ARB* = 0x0000872B
+  GL_MODELVIEW12_ARB* = 0x0000872C
+  GL_MODELVIEW13_ARB* = 0x0000872D
+  GL_MODELVIEW14_ARB* = 0x0000872E
+  GL_MODELVIEW15_ARB* = 0x0000872F
+  GL_MODELVIEW16_ARB* = 0x00008730
+  GL_MODELVIEW17_ARB* = 0x00008731
+  GL_MODELVIEW18_ARB* = 0x00008732
+  GL_MODELVIEW19_ARB* = 0x00008733
+  GL_MODELVIEW20_ARB* = 0x00008734
+  GL_MODELVIEW21_ARB* = 0x00008735
+  GL_MODELVIEW22_ARB* = 0x00008736
+  GL_MODELVIEW23_ARB* = 0x00008737
+  GL_MODELVIEW24_ARB* = 0x00008738
+  GL_MODELVIEW25_ARB* = 0x00008739
+  GL_MODELVIEW26_ARB* = 0x0000873A
+  GL_MODELVIEW27_ARB* = 0x0000873B
+  GL_MODELVIEW28_ARB* = 0x0000873C
+  GL_MODELVIEW29_ARB* = 0x0000873D
+  GL_MODELVIEW30_ARB* = 0x0000873E
+  GL_MODELVIEW31_ARB* = 0x0000873F
+  GL_CURRENT_WEIGHT_ARB* = 0x000086A8
+  GL_WEIGHT_ARRAY_TYPE_ARB* = 0x000086A9
+  GL_WEIGHT_ARRAY_STRIDE_ARB* = 0x000086AA
+  GL_WEIGHT_ARRAY_SIZE_ARB* = 0x000086AB
+  GL_WEIGHT_ARRAY_POINTER_ARB* = 0x000086AC
+  GL_WEIGHT_ARRAY_ARB* = 0x000086AD
+
+const 
+  GL_VERTEX_PROGRAM_ARB* = 0x00008620
+  GL_VERTEX_PROGRAM_POINT_SIZE_ARB* = 0x00008642
+  GL_VERTEX_PROGRAM_TWO_SIDE_ARB* = 0x00008643
+  GL_COLOR_SUM_ARB* = 0x00008458
+  GL_PROGRAM_FORMAT_ASCII_ARB* = 0x00008875
+  GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB* = 0x00008622
+  GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB* = 0x00008623
+  GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB* = 0x00008624
+  GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB* = 0x00008625
+  GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB* = 0x0000886A
+  GL_CURRENT_VERTEX_ATTRIB_ARB* = 0x00008626
+  GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB* = 0x00008645
+  GL_PROGRAM_LENGTH_ARB* = 0x00008627
+  GL_PROGRAM_FORMAT_ARB* = 0x00008876
+  GL_PROGRAM_BINDING_ARB* = 0x00008677
+  GL_PROGRAM_INSTRUCTIONS_ARB* = 0x000088A0
+  GL_MAX_PROGRAM_INSTRUCTIONS_ARB* = 0x000088A1
+  GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB* = 0x000088A2
+  GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB* = 0x000088A3
+  GL_PROGRAM_TEMPORARIES_ARB* = 0x000088A4
+  GL_MAX_PROGRAM_TEMPORARIES_ARB* = 0x000088A5
+  GL_PROGRAM_NATIVE_TEMPORARIES_ARB* = 0x000088A6
+  GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB* = 0x000088A7
+  GL_PROGRAM_PARAMETERS_ARB* = 0x000088A8
+  GL_MAX_PROGRAM_PARAMETERS_ARB* = 0x000088A9
+  GL_PROGRAM_NATIVE_PARAMETERS_ARB* = 0x000088AA
+  GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB* = 0x000088AB
+  GL_PROGRAM_ATTRIBS_ARB* = 0x000088AC
+  GL_MAX_PROGRAM_ATTRIBS_ARB* = 0x000088AD
+  GL_PROGRAM_NATIVE_ATTRIBS_ARB* = 0x000088AE
+  GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB* = 0x000088AF
+  GL_PROGRAM_ADDRESS_REGISTERS_ARB* = 0x000088B0
+  GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB* = 0x000088B1
+  GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB* = 0x000088B2
+  GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB* = 0x000088B3
+  GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB* = 0x000088B4
+  GL_MAX_PROGRAM_ENV_PARAMETERS_ARB* = 0x000088B5
+  GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB* = 0x000088B6
+  constGL_PROGRAM_STRING_ARB* = 0x00008628
+  GL_PROGRAM_ERROR_POSITION_ARB* = 0x0000864B
+  GL_CURRENT_MATRIX_ARB* = 0x00008641
+  GL_TRANSPOSE_CURRENT_MATRIX_ARB* = 0x000088B7
+  GL_CURRENT_MATRIX_STACK_DEPTH_ARB* = 0x00008640
+  GL_MAX_VERTEX_ATTRIBS_ARB* = 0x00008869
+  GL_MAX_PROGRAM_MATRICES_ARB* = 0x0000862F
+  GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB* = 0x0000862E
+  GL_PROGRAM_ERROR_STRING_ARB* = 0x00008874
+  GL_MATRIX0_ARB* = 0x000088C0
+  GL_MATRIX1_ARB* = 0x000088C1
+  GL_MATRIX2_ARB* = 0x000088C2
+  GL_MATRIX3_ARB* = 0x000088C3
+  GL_MATRIX4_ARB* = 0x000088C4
+  GL_MATRIX5_ARB* = 0x000088C5
+  GL_MATRIX6_ARB* = 0x000088C6
+  GL_MATRIX7_ARB* = 0x000088C7
+  GL_MATRIX8_ARB* = 0x000088C8
+  GL_MATRIX9_ARB* = 0x000088C9
+  GL_MATRIX10_ARB* = 0x000088CA
+  GL_MATRIX11_ARB* = 0x000088CB
+  GL_MATRIX12_ARB* = 0x000088CC
+  GL_MATRIX13_ARB* = 0x000088CD
+  GL_MATRIX14_ARB* = 0x000088CE
+  GL_MATRIX15_ARB* = 0x000088CF
+  GL_MATRIX16_ARB* = 0x000088D0
+  GL_MATRIX17_ARB* = 0x000088D1
+  GL_MATRIX18_ARB* = 0x000088D2
+  GL_MATRIX19_ARB* = 0x000088D3
+  GL_MATRIX20_ARB* = 0x000088D4
+  GL_MATRIX21_ARB* = 0x000088D5
+  GL_MATRIX22_ARB* = 0x000088D6
+  GL_MATRIX23_ARB* = 0x000088D7
+  GL_MATRIX24_ARB* = 0x000088D8
+  GL_MATRIX25_ARB* = 0x000088D9
+  GL_MATRIX26_ARB* = 0x000088DA
+  GL_MATRIX27_ARB* = 0x000088DB
+  GL_MATRIX28_ARB* = 0x000088DC
+  GL_MATRIX29_ARB* = 0x000088DD
+  GL_MATRIX30_ARB* = 0x000088DE
+  GL_MATRIX31_ARB* = 0x000088DF
+
+const 
+  GL_422_EXT* = 0x000080CC
+  GL_422_REV_EXT* = 0x000080CD
+  GL_422_AVERAGE_EXT* = 0x000080CE
+  GL_422_REV_AVERAGE_EXT* = 0x000080CF
+  #***** GL_EXT_abgr *****//
+
+const 
+  GL_ABGR_EXT* = 0x00008000
+  #***** GL_EXT_bgra *****//
+
+const 
+  GL_BGR_EXT* = 0x000080E0
+  GL_BGRA_EXT* = 0x000080E1
+  #***** GL_EXT_blend_color *****//
+
+const 
+  GL_CONSTANT_COLOR_EXT* = 0x00008001
+  GL_ONE_MINUS_CONSTANT_COLOR_EXT* = 0x00008002
+  GL_CONSTANT_ALPHA_EXT* = 0x00008003
+  GL_ONE_MINUS_CONSTANT_ALPHA_EXT* = 0x00008004
+  constGL_BLEND_COLOR_EXT* = 0x00008005
+
+proc glBlendColorEXT*(red: TGLclampf, green: TGLclampf, blue: TGLclampf, 
+                      alpha: TGLclampf){.dynlib: dllname, 
+    importc: "glBlendColorEXT".}
+  #***** GL_EXT_blend_func_separate *****//
+const 
+  GL_BLEND_DST_RGB_EXT* = 0x000080C8
+  GL_BLEND_SRC_RGB_EXT* = 0x000080C9
+  GL_BLEND_DST_ALPHA_EXT* = 0x000080CA
+  GL_BLEND_SRC_ALPHA_EXT* = 0x000080CB
+
+proc glBlendFuncSeparateEXT*(sfactorRGB: TGLenum, dfactorRGB: TGLenum, 
+                             sfactorAlpha: TGLenum, dfactorAlpha: TGLenum){.
+    dynlib: dllname, importc: "glBlendFuncSeparateEXT".}
+  #***** GL_EXT_blend_logic_op *****//
+  #***** GL_EXT_blend_minmax *****//
+const 
+  GL_FUNC_ADD_EXT* = 0x00008006
+  GL_MIN_EXT* = 0x00008007
+  GL_MAX_EXT* = 0x00008008
+  constGL_BLEND_EQUATION_EXT* = 0x00008009
+
+proc glBlendEquationEXT*(mode: TGLenum){.dynlib: dllname, 
+    importc: "glBlendEquationEXT".}
+  #***** GL_EXT_blend_subtract *****//
+const 
+  GL_FUNC_SUBTRACT_EXT* = 0x0000800A
+  GL_FUNC_REVERSE_SUBTRACT_EXT* = 0x0000800B
+  #***** GL_EXT_clip_volume_hint *****//
+
+const 
+  GL_CLIP_VOLUME_CLIPPING_HINT_EXT* = 0x000080F0
+  #***** GL_EXT_color_subtable *****//
+
+proc glColorSubTableEXT*(target: TGLenum, start: TGLsizei, count: TGLsizei, 
+                         format: TGLenum, thetype: TGLenum, data: PGLvoid){.
+    dynlib: dllname, importc: "glColorSubTableEXT".}
+proc glCopyColorSubTableEXT*(target: TGLenum, start: TGLsizei, x: TGLint, 
+                             y: TGLint, width: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyColorSubTableEXT".}
+  #***** GL_EXT_compiled_vertex_array *****//
+const 
+  GL_ARRAY_ELEMENT_LOCK_FIRST_EXT* = 0x000081A8
+  GL_ARRAY_ELEMENT_LOCK_COUNT_EXT* = 0x000081A9
+
+proc glLockArraysEXT*(first: TGLint, count: TGLsizei){.dynlib: dllname, 
+    importc: "glLockArraysEXT".}
+proc glUnlockArraysEXT*(){.dynlib: dllname, importc: "glUnlockArraysEXT".}
+  #***** GL_EXT_convolution *****//
+const 
+  GL_CONVOLUTION_1D_EXT* = 0x00008010
+  GL_CONVOLUTION_2D_EXT* = 0x00008011
+  GL_SEPARABLE_2D_EXT* = 0x00008012
+  GL_CONVOLUTION_BORDER_MODE_EXT* = 0x00008013
+  GL_CONVOLUTION_FILTER_SCALE_EXT* = 0x00008014
+  GL_CONVOLUTION_FILTER_BIAS_EXT* = 0x00008015
+  GL_REDUCE_EXT* = 0x00008016
+  GL_CONVOLUTION_FORMAT_EXT* = 0x00008017
+  GL_CONVOLUTION_WIDTH_EXT* = 0x00008018
+  GL_CONVOLUTION_HEIGHT_EXT* = 0x00008019
+  GL_MAX_CONVOLUTION_WIDTH_EXT* = 0x0000801A
+  GL_MAX_CONVOLUTION_HEIGHT_EXT* = 0x0000801B
+  GL_POST_CONVOLUTION_RED_SCALE_EXT* = 0x0000801C
+  GL_POST_CONVOLUTION_GREEN_SCALE_EXT* = 0x0000801D
+  GL_POST_CONVOLUTION_BLUE_SCALE_EXT* = 0x0000801E
+  GL_POST_CONVOLUTION_ALPHA_SCALE_EXT* = 0x0000801F
+  GL_POST_CONVOLUTION_RED_BIAS_EXT* = 0x00008020
+  GL_POST_CONVOLUTION_GREEN_BIAS_EXT* = 0x00008021
+  GL_POST_CONVOLUTION_BLUE_BIAS_EXT* = 0x00008022
+  GL_POST_CONVOLUTION_ALPHA_BIAS_EXT* = 0x00008023
+
+proc glConvolutionFilter1DEXT*(target: TGLenum, internalformat: TGLenum, 
+                               width: TGLsizei, format: TGLenum, 
+                               thetype: TGLenum, image: PGLvoid){.
+    dynlib: dllname, importc: "glConvolutionFilter1DEXT".}
+proc glConvolutionFilter2DEXT*(target: TGLenum, internalformat: TGLenum, 
+                               width: TGLsizei, height: TGLsizei, 
+                               format: TGLenum, thetype: TGLenum, image: PGLvoid){.
+    dynlib: dllname, importc: "glConvolutionFilter2DEXT".}
+proc glCopyConvolutionFilter1DEXT*(target: TGLenum, internalformat: TGLenum, 
+                                   x: TGLint, y: TGLint, width: TGLsizei){.
+    dynlib: dllname, importc: "glCopyConvolutionFilter1DEXT".}
+proc glCopyConvolutionFilter2DEXT*(target: TGLenum, internalformat: TGLenum, 
+                                   x: TGLint, y: TGLint, width: TGLsizei, 
+                                   height: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyConvolutionFilter2DEXT".}
+proc glGetConvolutionFilterEXT*(target: TGLenum, format: TGLenum, 
+                                thetype: TGLenum, image: PGLvoid){.
+    dynlib: dllname, importc: "glGetConvolutionFilterEXT".}
+proc glSeparableFilter2DEXT*(target: TGLenum, internalformat: TGLenum, 
+                             width: TGLsizei, height: TGLsizei, format: TGLenum, 
+                             thetype: TGLenum, row: PGLvoid, column: PGLvoid){.
+    dynlib: dllname, importc: "glSeparableFilter2DEXT".}
+proc glGetSeparableFilterEXT*(target: TGLenum, format: TGLenum, 
+                              thetype: TGLenum, row: PGLvoid, column: PGLvoid, 
+                              span: PGLvoid){.dynlib: dllname, 
+    importc: "glGetSeparableFilterEXT".}
+proc glConvolutionParameteriEXT*(target: TGLenum, pname: TGLenum, param: TGLint){.
+    dynlib: dllname, importc: "glConvolutionParameteriEXT".}
+proc glConvolutionParameterivEXT*(target: TGLenum, pname: TGLenum, 
+                                  params: PGLint){.dynlib: dllname, 
+    importc: "glConvolutionParameterivEXT".}
+proc glConvolutionParameterfEXT*(target: TGLenum, pname: TGLenum, 
+                                 param: TGLfloat){.dynlib: dllname, 
+    importc: "glConvolutionParameterfEXT".}
+proc glConvolutionParameterfvEXT*(target: TGLenum, pname: TGLenum, 
+                                  params: PGLfloat){.dynlib: dllname, 
+    importc: "glConvolutionParameterfvEXT".}
+proc glGetConvolutionParameterivEXT*(target: TGLenum, pname: TGLenum, 
+                                     params: PGLint){.dynlib: dllname, 
+    importc: "glGetConvolutionParameterivEXT".}
+proc glGetConvolutionParameterfvEXT*(target: TGLenum, pname: TGLenum, 
+                                     params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetConvolutionParameterfvEXT".}
+  #***** GL_EXT_fog_coord *****//
+const 
+  GL_FOG_COORDINATE_SOURCE_EXT* = 0x00008450
+  GL_FOG_COORDINATE_EXT* = 0x00008451
+  GL_FRAGMENT_DEPTH_EXT* = 0x00008452
+  GL_CURRENT_FOG_COORDINATE_EXT* = 0x00008453
+  GL_FOG_COORDINATE_ARRAY_TYPE_EXT* = 0x00008454
+  GL_FOG_COORDINATE_ARRAY_STRIDE_EXT* = 0x00008455
+  GL_FOG_COORDINATE_ARRAY_POINTER_EXT* = 0x00008456
+  GL_FOG_COORDINATE_ARRAY_EXT* = 0x00008457
+
+proc glFogCoordfEXfloat*(coord: TGLfloat){.dynlib: dllname, 
+    importc: "glFogCoordfEXfloat".}
+proc glFogCoorddEXdouble*(coord: TGLdouble){.dynlib: dllname, 
+    importc: "glFogCoorddEXdouble".}
+proc glFogCoordfvEXfloat*(coord: TGLfloat){.dynlib: dllname, 
+    importc: "glFogCoordfvEXfloat".}
+proc glFogCoorddvEXdouble*(coord: TGLdouble){.dynlib: dllname, 
+    importc: "glFogCoorddvEXdouble".}
+proc glFogCoordPointerEXT*(thetype: TGLenum, stride: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glFogCoordPointerEXT".}
+  #***** GL_EXT_histogram *****//
+const 
+  constGL_HISTOGRAM_EXT* = 0x00008024
+  GL_PROXY_HISTOGRAM_EXT* = 0x00008025
+  GL_HISTOGRAM_WIDTH_EXT* = 0x00008026
+  GL_HISTOGRAM_FORMAT_EXT* = 0x00008027
+  GL_HISTOGRAM_RED_SIZE_EXT* = 0x00008028
+  GL_HISTOGRAM_GREEN_SIZE_EXT* = 0x00008029
+  GL_HISTOGRAM_BLUE_SIZE_EXT* = 0x0000802A
+  GL_HISTOGRAM_ALPHA_SIZE_EXT* = 0x0000802B
+  GL_HISTOGRAM_LUMINANCE_SIZE_EXT* = 0x0000802C
+  GL_HISTOGRAM_SINK_EXT* = 0x0000802D
+  constGL_MINMAX_EXT* = 0x0000802E
+  GL_MINMAX_FORMAT_EXT* = 0x0000802F
+  GL_MINMAX_SINK_EXT* = 0x00008030
+
+proc glHistogramEXT*(target: TGLenum, width: TGLsizei, internalformat: TGLenum, 
+                     sink: TGLboolean){.dynlib: dllname, 
+                                        importc: "glHistogramEXT".}
+proc glResetHistogramEXT*(target: TGLenum){.dynlib: dllname, 
+    importc: "glResetHistogramEXT".}
+proc glGetHistogramEXT*(target: TGLenum, reset: TGLboolean, format: TGLenum, 
+                        thetype: TGLenum, values: PGLvoid){.dynlib: dllname, 
+    importc: "glGetHistogramEXT".}
+proc glGetHistogramParameterivEXT*(target: TGLenum, pname: TGLenum, 
+                                   params: PGLint){.dynlib: dllname, 
+    importc: "glGetHistogramParameterivEXT".}
+proc glGetHistogramParameterfvEXT*(target: TGLenum, pname: TGLenum, 
+                                   params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetHistogramParameterfvEXT".}
+proc glMinmaxEXT*(target: TGLenum, internalformat: TGLenum, sink: TGLboolean){.
+    dynlib: dllname, importc: "glMinmaxEXT".}
+proc glResetMinmaxEXT*(target: TGLenum){.dynlib: dllname, 
+    importc: "glResetMinmaxEXT".}
+proc glGetMinmaxEXT*(target: TGLenum, reset: TGLboolean, format: TGLenum, 
+                     thetype: TGLenum, values: PGLvoid){.dynlib: dllname, 
+    importc: "glGetMinmaxEXT".}
+proc glGetMinmaxParameterivEXT*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetMinmaxParameterivEXT".}
+proc glGetMinmaxParameterfvEXT*(target: TGLenum, pname: TGLenum, 
+                                params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetMinmaxParameterfvEXT".}
+  #***** GL_EXT_multi_draw_arrays *****//
+proc glMultiDrawArraysEXT*(mode: TGLenum, first: PGLint, count: PGLsizei, 
+                           primcount: TGLsizei){.dynlib: dllname, 
+    importc: "glMultiDrawArraysEXT".}
+proc glMultiDrawElementsEXT*(mode: TGLenum, count: PGLsizei, thetype: TGLenum, 
+                             indices: PGLvoid, primcount: TGLsizei){.
+    dynlib: dllname, importc: "glMultiDrawElementsEXT".}
+  #***** GL_EXT_packed_pixels *****//
+const 
+  GL_UNSIGNED_BYTE_3_3_2_EXT* = 0x00008032
+  GL_UNSIGNED_SHORT_4_4_4_4_EXT* = 0x00008033
+  GL_UNSIGNED_SHORT_5_5_5_1_EXT* = 0x00008034
+  GL_UNSIGNED_INT_8_8_8_8_EXT* = 0x00008035
+  GL_UNSIGNED_INT_10_10_10_2_EXT* = 0x00008036
+  #***** GL_EXT_paletted_texture *****//
+
+const 
+  GL_COLOR_INDEX1_EXT* = 0x000080E2
+  GL_COLOR_INDEX2_EXT* = 0x000080E3
+  GL_COLOR_INDEX4_EXT* = 0x000080E4
+  GL_COLOR_INDEX8_EXT* = 0x000080E5
+  GL_COLOR_INDEX12_EXT* = 0x000080E6
+  GL_COLOR_INDEX16_EXT* = 0x000080E7
+  GL_COLOR_TABLE_FORMAT_EXT* = 0x000080D8
+  GL_COLOR_TABLE_WIDTH_EXT* = 0x000080D9
+  GL_COLOR_TABLE_RED_SIZE_EXT* = 0x000080DA
+  GL_COLOR_TABLE_GREEN_SIZE_EXT* = 0x000080DB
+  GL_COLOR_TABLE_BLUE_SIZE_EXT* = 0x000080DC
+  GL_COLOR_TABLE_ALPHA_SIZE_EXT* = 0x000080DD
+  GL_COLOR_TABLE_LUMINANCE_SIZE_EXT* = 0x000080DE
+  GL_COLOR_TABLE_INTENSITY_SIZE_EXT* = 0x000080DF
+  GL_TEXTURE_INDEX_SIZE_EXT* = 0x000080ED
+  GL_TEXTURE_1D* = 0x00000DE0
+  GL_TEXTURE_2D* = 0x00000DE1
+  GL_TEXTURE_3D_EXT* = 0x0000806F # GL_TEXTURE_CUBE_MAP_ARB  { already defined }
+  GL_PROXY_TEXTURE_1D* = 0x00008063
+  GL_PROXY_TEXTURE_2D* = 0x00008064
+  GL_PROXY_TEXTURE_3D_EXT* = 0x00008070 # GL_PROXY_TEXTURE_CUBE_MAP_ARB  { already defined }
+                                        # GL_TEXTURE_1D  { already defined }
+                                        # GL_TEXTURE_2D  { already defined }
+                                        # GL_TEXTURE_3D_EXT  { already defined }
+                                        # GL_TEXTURE_CUBE_MAP_ARB  { already defined }
+
+proc glColorTableEXT*(target: TGLenum, internalFormat: TGLenum, width: TGLsizei, 
+                      format: TGLenum, thetype: TGLenum, data: PGLvoid){.
+    dynlib: dllname, importc: "glColorTableEXT".}
+  # glColorSubTableEXT  { already defined }
+proc glGetColorTableEXT*(target: TGLenum, format: TGLenum, thetype: TGLenum, 
+                         data: PGLvoid){.dynlib: dllname, 
+    importc: "glGetColorTableEXT".}
+proc glGetColorTableParameterivEXT*(target: TGLenum, pname: TGLenum, 
+                                    params: PGLint){.dynlib: dllname, 
+    importc: "glGetColorTableParameterivEXT".}
+proc glGetColorTableParameterfvEXT*(target: TGLenum, pname: TGLenum, 
+                                    params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetColorTableParameterfvEXT".}
+  #***** GL_EXT_point_parameters *****//
+const 
+  GL_POINT_SIZE_MIN_EXT* = 0x00008126
+  GL_POINT_SIZE_MAX_EXT* = 0x00008127
+  GL_POINT_FADE_THRESHOLD_SIZE_EXT* = 0x00008128
+  GL_DISTANCE_ATTENUATION_EXT* = 0x00008129
+
+proc glPointParameterfEXT*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterfEXT".}
+proc glPointParameterfvEXT*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterfvEXT".}
+  #***** GL_EXT_polygon_offset *****//
+const 
+  constGL_POLYGON_OFFSET_EXT* = 0x00008037
+  GL_POLYGON_OFFSET_FACTOR_EXT* = 0x00008038
+  GL_POLYGON_OFFSET_BIAS_EXT* = 0x00008039
+
+proc glPolygonOffsetEXT*(factor: TGLfloat, bias: TGLfloat){.dynlib: dllname, 
+    importc: "glPolygonOffsetEXT".}
+  #***** GL_EXT_secondary_color *****//
+const 
+  GL_COLOR_SUM_EXT* = 0x00008458
+  GL_CURRENT_SECONDARY_COLOR_EXT* = 0x00008459
+  GL_SECONDARY_COLOR_ARRAY_SIZE_EXT* = 0x0000845A
+  GL_SECONDARY_COLOR_ARRAY_TYPE_EXT* = 0x0000845B
+  GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT* = 0x0000845C
+  GL_SECONDARY_COLOR_ARRAY_POINTER_EXT* = 0x0000845D
+  GL_SECONDARY_COLOR_ARRAY_EXT* = 0x0000845E
+
+proc glSecondaryColor3bEXT*(components: TGLbyte){.dynlib: dllname, 
+    importc: "glSecondaryColor3bEXT".}
+proc glSecondaryColor3sEXT*(components: TGLshort){.dynlib: dllname, 
+    importc: "glSecondaryColor3sEXT".}
+proc glSecondaryColor3iEXT*(components: TGLint){.dynlib: dllname, 
+    importc: "glSecondaryColor3iEXT".}
+proc glSecondaryColor3fEXT*(components: TGLfloat){.dynlib: dllname, 
+    importc: "glSecondaryColor3fEXT".}
+proc glSecondaryColor3dEXT*(components: TGLdouble){.dynlib: dllname, 
+    importc: "glSecondaryColor3dEXT".}
+proc glSecondaryColor3ubEXT*(components: TGLubyte){.dynlib: dllname, 
+    importc: "glSecondaryColor3ubEXT".}
+proc glSecondaryColor3usEXT*(components: TGLushort){.dynlib: dllname, 
+    importc: "glSecondaryColor3usEXT".}
+proc glSecondaryColor3uiEXT*(components: TGLuint){.dynlib: dllname, 
+    importc: "glSecondaryColor3uiEXT".}
+proc glSecondaryColor3bvEXT*(components: TGLbyte){.dynlib: dllname, 
+    importc: "glSecondaryColor3bvEXT".}
+proc glSecondaryColor3svEXT*(components: TGLshort){.dynlib: dllname, 
+    importc: "glSecondaryColor3svEXT".}
+proc glSecondaryColor3ivEXT*(components: TGLint){.dynlib: dllname, 
+    importc: "glSecondaryColor3ivEXT".}
+proc glSecondaryColor3fvEXT*(components: TGLfloat){.dynlib: dllname, 
+    importc: "glSecondaryColor3fvEXT".}
+proc glSecondaryColor3dvEXT*(components: TGLdouble){.dynlib: dllname, 
+    importc: "glSecondaryColor3dvEXT".}
+proc glSecondaryColor3ubvEXT*(components: TGLubyte){.dynlib: dllname, 
+    importc: "glSecondaryColor3ubvEXT".}
+proc glSecondaryColor3usvEXT*(components: TGLushort){.dynlib: dllname, 
+    importc: "glSecondaryColor3usvEXT".}
+proc glSecondaryColor3uivEXT*(components: TGLuint){.dynlib: dllname, 
+    importc: "glSecondaryColor3uivEXT".}
+proc glSecondaryColorPointerEXT*(size: TGLint, thetype: TGLenum, 
+                                 stride: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glSecondaryColorPointerEXT".}
+  #***** GL_EXT_separate_specular_color *****//
+const 
+  GL_LIGHT_MODEL_COLOR_CONTROL_EXT* = 0x000081F8
+  GL_SINGLE_COLOR_EXT* = 0x000081F9
+  GL_SEPARATE_SPECULAR_COLOR_EXT* = 0x000081FA
+  #***** GL_EXT_shadow_funcs *****//
+  #***** GL_EXT_shared_texture_palette *****//
+
+const 
+  GL_SHARED_TEXTURE_PALETTE_EXT* = 0x000081FB
+  #***** GL_EXT_stencil_two_side *****//
+
+const 
+  GL_STENCIL_TEST_TWO_SIDE_EXT* = 0x00008910
+  constGL_ACTIVE_STENCIL_FACE_EXT* = 0x00008911
+
+proc glActiveStencilFaceEXT*(face: TGLenum){.dynlib: dllname, 
+    importc: "glActiveStencilFaceEXT".}
+  #***** GL_EXT_stencil_wrap *****//
+const 
+  GL_INCR_WRAP_EXT* = 0x00008507
+  GL_DECR_WRAP_EXT* = 0x00008508
+  #***** GL_EXT_subtexture *****//
+
+proc glTexSubImage1DEXT*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                         width: TGLsizei, format: TGLenum, thetype: TGLenum, 
+                         pixels: PGLvoid){.dynlib: dllname, 
+    importc: "glTexSubImage1DEXT".}
+proc glTexSubImage2DEXT*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                         yoffset: TGLint, width: TGLsizei, height: TGLsizei, 
+                         format: TGLenum, thetype: TGLenum, pixels: PGLvoid){.
+    dynlib: dllname, importc: "glTexSubImage2DEXT".}
+proc glTexSubImage3DEXT*(target: TGLenum, level: TGLint, xoffset: TGLint, 
+                         yoffset: TGLint, zoffset: TGLint, width: TGLsizei, 
+                         height: TGLsizei, depth: TGLsizei, format: TGLenum, 
+                         thetype: TGLenum, pixels: PGLvoid){.dynlib: dllname, 
+    importc: "glTexSubImage3DEXT".}
+  #***** GL_EXT_texture3D *****//
+const 
+  GL_PACK_SKIP_IMAGES_EXT* = 0x0000806B
+  GL_PACK_IMAGE_HEIGHT_EXT* = 0x0000806C
+  GL_UNPACK_SKIP_IMAGES_EXT* = 0x0000806D
+  GL_UNPACK_IMAGE_HEIGHT_EXT* = 0x0000806E # GL_TEXTURE_3D_EXT  { already defined }
+                                           # GL_PROXY_TEXTURE_3D_EXT  { already defined }
+  GL_TEXTURE_DEPTH_EXT* = 0x00008071
+  GL_TEXTURE_WRAP_R_EXT* = 0x00008072
+  GL_MAX_3D_TEXTURE_SIZE_EXT* = 0x00008073
+
+proc glTexImage3DEXT*(target: TGLenum, level: TGLint, internalformat: TGLenum, 
+                      width: TGLsizei, height: TGLsizei, depth: TGLsizei, 
+                      border: TGLint, format: TGLenum, thetype: TGLenum, 
+                      pixels: PGLvoid){.dynlib: dllname, 
+                                        importc: "glTexImage3DEXT".}
+  #***** GL_EXT_texture_compression_s3tc *****//
+const 
+  GL_COMPRESSED_RGB_S3TC_DXT1_EXT* = 0x000083F0
+  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT* = 0x000083F1
+  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT* = 0x000083F2
+  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT* = 0x000083F3
+  #***** GL_EXT_texture_env_add *****//
+  #***** GL_EXT_texture_env_combine *****//
+
+const 
+  GL_COMBINE_EXT* = 0x00008570
+  GL_COMBINE_RGB_EXT* = 0x00008571
+  GL_COMBINE_ALPHA_EXT* = 0x00008572
+  GL_SOURCE0_RGB_EXT* = 0x00008580
+  GL_SOURCE1_RGB_EXT* = 0x00008581
+  GL_SOURCE2_RGB_EXT* = 0x00008582
+  GL_SOURCE0_ALPHA_EXT* = 0x00008588
+  GL_SOURCE1_ALPHA_EXT* = 0x00008589
+  GL_SOURCE2_ALPHA_EXT* = 0x0000858A
+  GL_OPERAND0_RGB_EXT* = 0x00008590
+  GL_OPERAND1_RGB_EXT* = 0x00008591
+  GL_OPERAND2_RGB_EXT* = 0x00008592
+  GL_OPERAND0_ALPHA_EXT* = 0x00008598
+  GL_OPERAND1_ALPHA_EXT* = 0x00008599
+  GL_OPERAND2_ALPHA_EXT* = 0x0000859A
+  GL_RGB_SCALE_EXT* = 0x00008573
+  GL_ADD_SIGNED_EXT* = 0x00008574
+  GL_INTERPOLATE_EXT* = 0x00008575
+  GL_CONSTANT_EXT* = 0x00008576
+  GL_PRIMARY_COLOR_EXT* = 0x00008577
+  GL_PREVIOUS_EXT* = 0x00008578
+  #***** GL_EXT_texture_env_dot3 *****//
+
+const 
+  GL_DOT3_RGB_EXT* = 0x00008740
+  GL_DOT3_RGBA_EXT* = 0x00008741
+  #***** GL_EXT_texture_filter_anisotropic *****//
+
+const 
+  GL_TEXTURE_MAX_ANISOTROPY_EXT* = 0x000084FE
+  GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT* = 0x000084FF
+  #***** GL_EXT_texture_lod_bias *****//
+
+const 
+  GL_TEXTURE_FILTER_CONTROL_EXT* = 0x00008500
+  GL_TEXTURE_LOD_BIAS_EXT* = 0x00008501
+  GL_MAX_TEXTURE_LOD_BIAS_EXT* = 0x000084FD
+  #***** GL_EXT_texture_object *****//
+
+const 
+  GL_TEXTURE_PRIORITY_EXT* = 0x00008066
+  GL_TEXTURE_RESIDENT_EXT* = 0x00008067
+  GL_TEXTURE_1D_BINDING_EXT* = 0x00008068
+  GL_TEXTURE_2D_BINDING_EXT* = 0x00008069
+  GL_TEXTURE_3D_BINDING_EXT* = 0x0000806A
+
+proc glGenTexturesEXT*(n: TGLsizei, textures: PGLuint){.dynlib: dllname, 
+    importc: "glGenTexturesEXT".}
+proc glDeleteTexturesEXT*(n: TGLsizei, textures: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteTexturesEXT".}
+proc glBindTextureEXT*(target: TGLenum, texture: TGLuint){.dynlib: dllname, 
+    importc: "glBindTextureEXT".}
+proc glPrioritizeTexturesEXT*(n: TGLsizei, textures: PGLuint, 
+                              priorities: PGLclampf){.dynlib: dllname, 
+    importc: "glPrioritizeTexturesEXT".}
+proc glAreTexturesResidentEXT*(n: TGLsizei, textures: PGLuint, 
+                               residences: PGLboolean): TGLboolean{.
+    dynlib: dllname, importc: "glAreTexturesResidentEXT".}
+proc glIsTextureEXT*(texture: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsTextureEXT".}
+  #***** GL_EXT_vertex_array *****//
+const 
+  GL_VERTEX_ARRAY_EXT* = 0x00008074
+  GL_NORMAL_ARRAY_EXT* = 0x00008075
+  GL_COLOR_ARRAY_EXT* = 0x00008076
+  GL_INDEX_ARRAY_EXT* = 0x00008077
+  GL_TEXTURE_COORD_ARRAY_EXT* = 0x00008078
+  GL_EDGE_FLAG_ARRAY_EXT* = 0x00008079
+  GL_DOUBLE_EXT* = 0x0000140A
+  GL_VERTEX_ARRAY_SIZE_EXT* = 0x0000807A
+  GL_VERTEX_ARRAY_TYPE_EXT* = 0x0000807B
+  GL_VERTEX_ARRAY_STRIDE_EXT* = 0x0000807C
+  GL_VERTEX_ARRAY_COUNT_EXT* = 0x0000807D
+  GL_NORMAL_ARRAY_TYPE_EXT* = 0x0000807E
+  GL_NORMAL_ARRAY_STRIDE_EXT* = 0x0000807F
+  GL_NORMAL_ARRAY_COUNT_EXT* = 0x00008080
+  GL_COLOR_ARRAY_SIZE_EXT* = 0x00008081
+  GL_COLOR_ARRAY_TYPE_EXT* = 0x00008082
+  GL_COLOR_ARRAY_STRIDE_EXT* = 0x00008083
+  GL_COLOR_ARRAY_COUNT_EXT* = 0x00008084
+  GL_INDEX_ARRAY_TYPE_EXT* = 0x00008085
+  GL_INDEX_ARRAY_STRIDE_EXT* = 0x00008086
+  GL_INDEX_ARRAY_COUNT_EXT* = 0x00008087
+  GL_TEXTURE_COORD_ARRAY_SIZE_EXT* = 0x00008088
+  GL_TEXTURE_COORD_ARRAY_TYPE_EXT* = 0x00008089
+  GL_TEXTURE_COORD_ARRAY_STRIDE_EXT* = 0x0000808A
+  GL_TEXTURE_COORD_ARRAY_COUNT_EXT* = 0x0000808B
+  GL_EDGE_FLAG_ARRAY_STRIDE_EXT* = 0x0000808C
+  GL_EDGE_FLAG_ARRAY_COUNT_EXT* = 0x0000808D
+  GL_VERTEX_ARRAY_POINTER_EXT* = 0x0000808E
+  GL_NORMAL_ARRAY_POINTER_EXT* = 0x0000808F
+  GL_COLOR_ARRAY_POINTER_EXT* = 0x00008090
+  GL_INDEX_ARRAY_POINTER_EXT* = 0x00008091
+  GL_TEXTURE_COORD_ARRAY_POINTER_EXT* = 0x00008092
+  GL_EDGE_FLAG_ARRAY_POINTER_EXT* = 0x00008093
+
+proc glArrayElementEXT*(i: TGLint){.dynlib: dllname, 
+                                    importc: "glArrayElementEXT".}
+proc glDrawArraysEXT*(mode: TGLenum, first: TGLint, count: TGLsizei){.
+    dynlib: dllname, importc: "glDrawArraysEXT".}
+proc glVertexPointerEXT*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                         count: TGLsizei, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexPointerEXT".}
+proc glNormalPointerEXT*(thetype: TGLenum, stride: TGLsizei, count: TGLsizei, 
+                         pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glNormalPointerEXT".}
+proc glColorPointerEXT*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                        count: TGLsizei, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glColorPointerEXT".}
+proc glIndexPointerEXT*(thetype: TGLenum, stride: TGLsizei, count: TGLsizei, 
+                        pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glIndexPointerEXT".}
+proc glTexCoordPointerEXT*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                           count: TGLsizei, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glTexCoordPointerEXT".}
+proc glEdgeFlagPointerEXT*(stride: TGLsizei, count: TGLsizei, 
+                           pointer: PGLboolean){.dynlib: dllname, 
+    importc: "glEdgeFlagPointerEXT".}
+proc glGetPointervEXT*(pname: TGLenum, params: PGLvoid){.dynlib: dllname, 
+    importc: "glGetPointervEXT".}
+  #***** GL_EXT_vertex_shader *****//
+const 
+  GL_VERTEX_SHADER_EXT* = 0x00008780
+  GL_VARIANT_VALUE_EXT* = 0x000087E4
+  GL_VARIANT_DATATYPE_EXT* = 0x000087E5
+  GL_VARIANT_ARRAY_STRIDE_EXT* = 0x000087E6
+  GL_VARIANT_ARRAY_TYPE_EXT* = 0x000087E7
+  GL_VARIANT_ARRAY_EXT* = 0x000087E8
+  GL_VARIANT_ARRAY_POINTER_EXT* = 0x000087E9
+  GL_INVARIANT_VALUE_EXT* = 0x000087EA
+  GL_INVARIANT_DATATYPE_EXT* = 0x000087EB
+  GL_LOCAL_CONSTANT_VALUE_EXT* = 0x000087EC
+  GL_LOCAL_CONSTANT_DATATYPE_EXT* = 0x000087ED
+  GL_OP_INDEX_EXT* = 0x00008782
+  GL_OP_NEGATE_EXT* = 0x00008783
+  GL_OP_DOT3_EXT* = 0x00008784
+  GL_OP_DOT4_EXT* = 0x00008785
+  GL_OP_MUL_EXT* = 0x00008786
+  GL_OP_ADD_EXT* = 0x00008787
+  GL_OP_MADD_EXT* = 0x00008788
+  GL_OP_FRAC_EXT* = 0x00008789
+  GL_OP_MAX_EXT* = 0x0000878A
+  GL_OP_MIN_EXT* = 0x0000878B
+  GL_OP_SET_GE_EXT* = 0x0000878C
+  GL_OP_SET_LT_EXT* = 0x0000878D
+  GL_OP_CLAMP_EXT* = 0x0000878E
+  GL_OP_FLOOR_EXT* = 0x0000878F
+  GL_OP_ROUND_EXT* = 0x00008790
+  GL_OP_EXP_BASE_2_EXT* = 0x00008791
+  GL_OP_LOG_BASE_2_EXT* = 0x00008792
+  GL_OP_POWER_EXT* = 0x00008793
+  GL_OP_RECIP_EXT* = 0x00008794
+  GL_OP_RECIP_SQRT_EXT* = 0x00008795
+  GL_OP_SUB_EXT* = 0x00008796
+  GL_OP_CROSS_PRODUCT_EXT* = 0x00008797
+  GL_OP_MULTIPLY_MATRIX_EXT* = 0x00008798
+  GL_OP_MOV_EXT* = 0x00008799
+  GL_OUTPUT_VERTEX_EXT* = 0x0000879A
+  GL_OUTPUT_COLOR0_EXT* = 0x0000879B
+  GL_OUTPUT_COLOR1_EXT* = 0x0000879C
+  GL_OUTPUT_TEXTURE_COORD0_EXT* = 0x0000879D
+  GL_OUTPUT_TEXTURE_COORD1_EXT* = 0x0000879E
+  GL_OUTPUT_TEXTURE_COORD2_EXT* = 0x0000879F
+  GL_OUTPUT_TEXTURE_COORD3_EXT* = 0x000087A0
+  GL_OUTPUT_TEXTURE_COORD4_EXT* = 0x000087A1
+  GL_OUTPUT_TEXTURE_COORD5_EXT* = 0x000087A2
+  GL_OUTPUT_TEXTURE_COORD6_EXT* = 0x000087A3
+  GL_OUTPUT_TEXTURE_COORD7_EXT* = 0x000087A4
+  GL_OUTPUT_TEXTURE_COORD8_EXT* = 0x000087A5
+  GL_OUTPUT_TEXTURE_COORD9_EXT* = 0x000087A6
+  GL_OUTPUT_TEXTURE_COORD10_EXT* = 0x000087A7
+  GL_OUTPUT_TEXTURE_COORD11_EXT* = 0x000087A8
+  GL_OUTPUT_TEXTURE_COORD12_EXT* = 0x000087A9
+  GL_OUTPUT_TEXTURE_COORD13_EXT* = 0x000087AA
+  GL_OUTPUT_TEXTURE_COORD14_EXT* = 0x000087AB
+  GL_OUTPUT_TEXTURE_COORD15_EXT* = 0x000087AC
+  GL_OUTPUT_TEXTURE_COORD16_EXT* = 0x000087AD
+  GL_OUTPUT_TEXTURE_COORD17_EXT* = 0x000087AE
+  GL_OUTPUT_TEXTURE_COORD18_EXT* = 0x000087AF
+  GL_OUTPUT_TEXTURE_COORD19_EXT* = 0x000087B0
+  GL_OUTPUT_TEXTURE_COORD20_EXT* = 0x000087B1
+  GL_OUTPUT_TEXTURE_COORD21_EXT* = 0x000087B2
+  GL_OUTPUT_TEXTURE_COORD22_EXT* = 0x000087B3
+  GL_OUTPUT_TEXTURE_COORD23_EXT* = 0x000087B4
+  GL_OUTPUT_TEXTURE_COORD24_EXT* = 0x000087B5
+  GL_OUTPUT_TEXTURE_COORD25_EXT* = 0x000087B6
+  GL_OUTPUT_TEXTURE_COORD26_EXT* = 0x000087B7
+  GL_OUTPUT_TEXTURE_COORD27_EXT* = 0x000087B8
+  GL_OUTPUT_TEXTURE_COORD28_EXT* = 0x000087B9
+  GL_OUTPUT_TEXTURE_COORD29_EXT* = 0x000087BA
+  GL_OUTPUT_TEXTURE_COORD30_EXT* = 0x000087BB
+  GL_OUTPUT_TEXTURE_COORD31_EXT* = 0x000087BC
+  GL_OUTPUT_FOG_EXT* = 0x000087BD
+  GL_SCALAR_EXT* = 0x000087BE
+  GL_VECTOR_EXT* = 0x000087BF
+  GL_MATRIX_EXT* = 0x000087C0
+  GL_VARIANT_EXT* = 0x000087C1
+  GL_INVARIANT_EXT* = 0x000087C2
+  GL_LOCAL_CONSTANT_EXT* = 0x000087C3
+  GL_LOCAL_EXT* = 0x000087C4
+  GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT* = 0x000087C5
+  GL_MAX_VERTEX_SHADER_VARIANTS_EXT* = 0x000087C6
+  GL_MAX_VERTEX_SHADER_INVARIANTS_EXT* = 0x000087C7
+  GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT* = 0x000087C8
+  GL_MAX_VERTEX_SHADER_LOCALS_EXT* = 0x000087C9
+  GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT* = 0x000087CA
+  GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT* = 0x000087CB
+  GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT* = 0x000087CC
+  GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT* = 0x000087CD
+  GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT* = 0x000087CE
+  GL_VERTEX_SHADER_INSTRUCTIONS_EXT* = 0x000087CF
+  GL_VERTEX_SHADER_VARIANTS_EXT* = 0x000087D0
+  GL_VERTEX_SHADER_INVARIANTS_EXT* = 0x000087D1
+  GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT* = 0x000087D2
+  GL_VERTEX_SHADER_LOCALS_EXT* = 0x000087D3
+  GL_VERTEX_SHADER_BINDING_EXT* = 0x00008781
+  GL_VERTEX_SHADER_OPTIMIZED_EXT* = 0x000087D4
+  GL_X_EXT* = 0x000087D5
+  GL_Y_EXT* = 0x000087D6
+  GL_Z_EXT* = 0x000087D7
+  GL_W_EXT* = 0x000087D8
+  GL_NEGATIVE_X_EXT* = 0x000087D9
+  GL_NEGATIVE_Y_EXT* = 0x000087DA
+  GL_NEGATIVE_Z_EXT* = 0x000087DB
+  GL_NEGATIVE_W_EXT* = 0x000087DC
+  GL_ZERO_EXT* = 0x000087DD
+  GL_ONE_EXT* = 0x000087DE
+  GL_NEGATIVE_ONE_EXT* = 0x000087DF
+  GL_NORMALIZED_RANGE_EXT* = 0x000087E0
+  GL_FULL_RANGE_EXT* = 0x000087E1
+  GL_CURRENT_VERTEX_EXT* = 0x000087E2
+  GL_MVP_MATRIX_EXT* = 0x000087E3
+
+proc glBeginVertexShaderEXT*(){.dynlib: dllname, 
+                                importc: "glBeginVertexShaderEXT".}
+proc glEndVertexShaderEXT*(){.dynlib: dllname, importc: "glEndVertexShaderEXT".}
+proc glBindVertexShaderEXT*(id: TGLuint){.dynlib: dllname, 
+    importc: "glBindVertexShaderEXT".}
+proc glGenVertexShadersEXT*(range: TGLuint): TGLuint{.dynlib: dllname, 
+    importc: "glGenVertexShadersEXT".}
+proc glDeleteVertexShaderEXT*(id: TGLuint){.dynlib: dllname, 
+    importc: "glDeleteVertexShaderEXT".}
+proc glShaderOp1EXT*(op: TGLenum, res: TGLuint, arg1: TGLuint){.dynlib: dllname, 
+    importc: "glShaderOp1EXT".}
+proc glShaderOp2EXT*(op: TGLenum, res: TGLuint, arg1: TGLuint, arg2: TGLuint){.
+    dynlib: dllname, importc: "glShaderOp2EXT".}
+proc glShaderOp3EXT*(op: TGLenum, res: TGLuint, arg1: TGLuint, arg2: TGLuint, 
+                     arg3: TGLuint){.dynlib: dllname, importc: "glShaderOp3EXT".}
+proc glSwizzleEXT*(res: TGLuint, theIn: TGLuint, outX: TGLenum, outY: TGLenum, 
+                   outZ: TGLenum, outW: TGLenum){.dynlib: dllname, 
+    importc: "glSwizzleEXT".}
+proc glWriteMaskEXT*(res: TGLuint, theIn: TGLuint, outX: TGLenum, outY: TGLenum, 
+                     outZ: TGLenum, outW: TGLenum){.dynlib: dllname, 
+    importc: "glWriteMaskEXT".}
+proc glInsertComponentEXT*(res: TGLuint, src: TGLuint, num: TGLuint){.
+    dynlib: dllname, importc: "glInsertComponentEXT".}
+proc glExtractComponentEXT*(res: TGLuint, src: TGLuint, num: TGLuint){.
+    dynlib: dllname, importc: "glExtractComponentEXT".}
+proc glGenSymbolsEXT*(datatype: TGLenum, storagetype: TGLenum, range: TGLenum, 
+                      components: TGLuint): TGLuint{.dynlib: dllname, 
+    importc: "glGenSymbolsEXT".}
+proc glSetInvariantEXT*(id: TGLuint, thetype: TGLenum, address: PGLvoid){.
+    dynlib: dllname, importc: "glSetInvariantEXT".}
+proc glSetLocalConstantEXT*(id: TGLuint, thetype: TGLenum, address: PGLvoid){.
+    dynlib: dllname, importc: "glSetLocalConstantEXT".}
+proc glVariantbvEXT*(id: TGLuint, address: PGLbyte){.dynlib: dllname, 
+    importc: "glVariantbvEXT".}
+proc glVariantsvEXT*(id: TGLuint, address: PGLshort){.dynlib: dllname, 
+    importc: "glVariantsvEXT".}
+proc glVariantivEXT*(id: TGLuint, address: PGLint){.dynlib: dllname, 
+    importc: "glVariantivEXT".}
+proc glVariantfvEXT*(id: TGLuint, address: PGLfloat){.dynlib: dllname, 
+    importc: "glVariantfvEXT".}
+proc glVariantdvEXT*(id: TGLuint, address: PGLdouble){.dynlib: dllname, 
+    importc: "glVariantdvEXT".}
+proc glVariantubvEXT*(id: TGLuint, address: PGLubyte){.dynlib: dllname, 
+    importc: "glVariantubvEXT".}
+proc glVariantusvEXT*(id: TGLuint, address: PGLushort){.dynlib: dllname, 
+    importc: "glVariantusvEXT".}
+proc glVariantuivEXT*(id: TGLuint, address: PGLuint){.dynlib: dllname, 
+    importc: "glVariantuivEXT".}
+proc glVariantPointerEXT*(id: TGLuint, thetype: TGLenum, stride: TGLuint, 
+                          address: PGLvoid){.dynlib: dllname, 
+    importc: "glVariantPointerEXT".}
+proc glEnableVariantClientStateEXT*(id: TGLuint){.dynlib: dllname, 
+    importc: "glEnableVariantClientStateEXT".}
+proc glDisableVariantClientStateEXT*(id: TGLuint){.dynlib: dllname, 
+    importc: "glDisableVariantClientStateEXT".}
+proc glBindLightParameterEXT*(light: TGLenum, value: TGLenum): TGLuint{.
+    dynlib: dllname, importc: "glBindLightParameterEXT".}
+proc glBindMaterialParameterEXT*(face: TGLenum, value: TGLenum): TGLuint{.
+    dynlib: dllname, importc: "glBindMaterialParameterEXT".}
+proc glBindTexGenParameterEXT*(theunit: TGLenum, coord: TGLenum, value: TGLenum): TGLuint{.
+    dynlib: dllname, importc: "glBindTexGenParameterEXT".}
+proc glBindTextureUnitParameterEXT*(theunit: TGLenum, value: TGLenum): TGLuint{.
+    dynlib: dllname, importc: "glBindTextureUnitParameterEXT".}
+proc glBindParameterEXT*(value: TGLenum): TGLuint{.dynlib: dllname, 
+    importc: "glBindParameterEXT".}
+proc glIsVariantEnabledEXT*(id: TGLuint, cap: TGLenum): TGLboolean{.
+    dynlib: dllname, importc: "glIsVariantEnabledEXT".}
+proc glGetVariantBooleanvEXT*(id: TGLuint, value: TGLenum, data: PGLboolean){.
+    dynlib: dllname, importc: "glGetVariantBooleanvEXT".}
+proc glGetVariantIntegervEXT*(id: TGLuint, value: TGLenum, data: PGLint){.
+    dynlib: dllname, importc: "glGetVariantIntegervEXT".}
+proc glGetVariantFloatvEXT*(id: TGLuint, value: TGLenum, data: PGLfloat){.
+    dynlib: dllname, importc: "glGetVariantFloatvEXT".}
+proc glGetVariantPointervEXT*(id: TGLuint, value: TGLenum, data: PGLvoid){.
+    dynlib: dllname, importc: "glGetVariantPointervEXT".}
+proc glGetInvariantBooleanvEXT*(id: TGLuint, value: TGLenum, data: PGLboolean){.
+    dynlib: dllname, importc: "glGetInvariantBooleanvEXT".}
+proc glGetInvariantIntegervEXT*(id: TGLuint, value: TGLenum, data: PGLint){.
+    dynlib: dllname, importc: "glGetInvariantIntegervEXT".}
+proc glGetInvariantFloatvEXT*(id: TGLuint, value: TGLenum, data: PGLfloat){.
+    dynlib: dllname, importc: "glGetInvariantFloatvEXT".}
+proc glGetLocalConstantBooleanvEXT*(id: TGLuint, value: TGLenum, 
+                                    data: PGLboolean){.dynlib: dllname, 
+    importc: "glGetLocalConstantBooleanvEXT".}
+proc glGetLocalConstantIntegervEXT*(id: TGLuint, value: TGLenum, data: PGLint){.
+    dynlib: dllname, importc: "glGetLocalConstantIntegervEXT".}
+proc glGetLocalConstantFloatvEXT*(id: TGLuint, value: TGLenum, data: PGLfloat){.
+    dynlib: dllname, importc: "glGetLocalConstantFloatvEXT".}
+  #***** GL_EXT_vertex_weighting *****//
+const 
+  GL_VERTEX_WEIGHTING_EXT* = 0x00008509
+  GL_MODELVIEW0_EXT* = 0x00001700
+  GL_MODELVIEW1_EXT* = 0x0000850A
+  GL_MODELVIEW0_MATRIX_EXT* = 0x00000BA6
+  GL_MODELVIEW1_MATRIX_EXT* = 0x00008506
+  GL_CURRENT_VERTEX_WEIGHT_EXT* = 0x0000850B
+  GL_VERTEX_WEIGHT_ARRAY_EXT* = 0x0000850C
+  GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT* = 0x0000850D
+  GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT* = 0x0000850E
+  GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT* = 0x0000850F
+  GL_MODELVIEW0_STACK_DEPTH_EXT* = 0x00000BA3
+  GL_MODELVIEW1_STACK_DEPTH_EXT* = 0x00008502
+  GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT* = 0x00008510
+
+proc glVertexWeightfEXT*(weight: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexWeightfEXT".}
+proc glVertexWeightfvEXT*(weight: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexWeightfvEXT".}
+proc glVertexWeightPointerEXT*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                               pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexWeightPointerEXT".}
+  #***** GL_HP_occlusion_test *****//
+const 
+  GL_OCCLUSION_TEST_HP* = 0x00008165
+  GL_OCCLUSION_TEST_RESULT_HP* = 0x00008166
+  #***** GL_NV_blend_square *****//
+  #***** GL_NV_copy_depth_to_color *****//
+
+const 
+  GL_DEPTH_STENCIL_TO_RGBA_NV* = 0x0000886E
+  GL_DEPTH_STENCIL_TO_BGRA_NV* = 0x0000886F
+  #***** GL_NV_depth_clamp *****//
+
+const 
+  GL_DEPTH_CLAMP_NV* = 0x0000864F
+  #***** GL_NV_evaluators *****//
+
+const 
+  GL_EVAL_2D_NV* = 0x000086C0
+  GL_EVAL_TRIANGULAR_2D_NV* = 0x000086C1
+  GL_MAP_TESSELLATION_NV* = 0x000086C2
+  GL_MAP_ATTRIB_U_ORDER_NV* = 0x000086C3
+  GL_MAP_ATTRIB_V_ORDER_NV* = 0x000086C4
+  GL_EVAL_FRACTIONAL_TESSELLATION_NV* = 0x000086C5
+  GL_EVAL_VERTEX_ATTRIB0_NV* = 0x000086C6
+  GL_EVAL_VERTEX_ATTRIB1_NV* = 0x000086C7
+  GL_EVAL_VERTEX_ATTRIB2_NV* = 0x000086C8
+  GL_EVAL_VERTEX_ATTRIB3_NV* = 0x000086C9
+  GL_EVAL_VERTEX_ATTRIB4_NV* = 0x000086CA
+  GL_EVAL_VERTEX_ATTRIB5_NV* = 0x000086CB
+  GL_EVAL_VERTEX_ATTRIB6_NV* = 0x000086CC
+  GL_EVAL_VERTEX_ATTRIB7_NV* = 0x000086CD
+  GL_EVAL_VERTEX_ATTRIB8_NV* = 0x000086CE
+  GL_EVAL_VERTEX_ATTRIB9_NV* = 0x000086CF
+  GL_EVAL_VERTEX_ATTRIB10_NV* = 0x000086D0
+  GL_EVAL_VERTEX_ATTRIB11_NV* = 0x000086D1
+  GL_EVAL_VERTEX_ATTRIB12_NV* = 0x000086D2
+  GL_EVAL_VERTEX_ATTRIB13_NV* = 0x000086D3
+  GL_EVAL_VERTEX_ATTRIB14_NV* = 0x000086D4
+  GL_EVAL_VERTEX_ATTRIB15_NV* = 0x000086D5
+  GL_MAX_MAP_TESSELLATION_NV* = 0x000086D6
+  GL_MAX_RATIONAL_EVAL_ORDER_NV* = 0x000086D7
+
+proc glMapControlPointsNV*(target: TGLenum, index: TGLuint, thetype: TGLenum, 
+                           ustride: TGLsizei, vstride: TGLsizei, uorder: TGLint, 
+                           vorder: TGLint, thepacked: TGLboolean, 
+                           points: PGLvoid){.dynlib: dllname, 
+    importc: "glMapControlPointsNV".}
+proc glMapParameterivNV*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glMapParameterivNV".}
+proc glMapParameterfvNV*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glMapParameterfvNV".}
+proc glGetMapControlPointsNV*(target: TGLenum, index: TGLuint, thetype: TGLenum, 
+                              ustride: TGLsizei, vstride: TGLsizei, 
+                              thepacked: TGLboolean, points: PGLvoid){.
+    dynlib: dllname, importc: "glGetMapControlPointsNV".}
+proc glGetMapParameterivNV*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetMapParameterivNV".}
+proc glGetMapParameterfvNV*(target: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetMapParameterfvNV".}
+proc glGetMapAttribParameterivNV*(target: TGLenum, index: TGLuint, 
+                                  pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetMapAttribParameterivNV".}
+proc glGetMapAttribParameterfvNV*(target: TGLenum, index: TGLuint, 
+                                  pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetMapAttribParameterfvNV".}
+proc glEvalMapsNV*(target: TGLenum, mode: TGLenum){.dynlib: dllname, 
+    importc: "glEvalMapsNV".}
+  #***** GL_NV_fence *****//
+const 
+  GL_ALL_COMPLETED_NV* = 0x000084F2
+  GL_FENCE_STATUS_NV* = 0x000084F3
+  GL_FENCE_CONDITION_NV* = 0x000084F4
+
+proc glGenFencesNV*(n: TGLsizei, fences: PGLuint){.dynlib: dllname, 
+    importc: "glGenFencesNV".}
+proc glDeleteFencesNV*(n: TGLsizei, fences: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteFencesNV".}
+proc glSetFenceNV*(fence: TGLuint, condition: TGLenum){.dynlib: dllname, 
+    importc: "glSetFenceNV".}
+proc glTestFenceNV*(fence: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glTestFenceNV".}
+proc glFinishFenceNV*(fence: TGLuint){.dynlib: dllname, 
+                                       importc: "glFinishFenceNV".}
+proc glIsFenceNV*(fence: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsFenceNV".}
+proc glGetFenceivNV*(fence: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetFenceivNV".}
+  #***** GL_NV_fog_distance *****//
+const 
+  GL_FOG_DISTANCE_MODE_NV* = 0x0000855A
+  GL_EYE_RADIAL_NV* = 0x0000855B
+  GL_EYE_PLANE_ABSOLUTE_NV* = 0x0000855C
+  #***** GL_NV_light_max_exponent *****//
+
+const 
+  GL_MAX_SHININESS_NV* = 0x00008504
+  GL_MAX_SPOT_EXPONENT_NV* = 0x00008505
+  #***** GL_NV_multisample_filter_hint *****//
+
+const 
+  GL_MULTISAMPLE_FILTER_HINT_NV* = 0x00008534
+  #***** GL_NV_occlusion_query *****//
+  # GL_OCCLUSION_TEST_HP  { already defined }
+  # GL_OCCLUSION_TEST_RESULT_HP  { already defined }
+
+const 
+  GL_PIXEL_COUNTER_BITS_NV* = 0x00008864
+  GL_CURRENT_OCCLUSION_QUERY_ID_NV* = 0x00008865
+  GL_PIXEL_COUNT_NV* = 0x00008866
+  GL_PIXEL_COUNT_AVAILABLE_NV* = 0x00008867
+
+proc glGenOcclusionQueriesNV*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glGenOcclusionQueriesNV".}
+proc glDeleteOcclusionQueriesNV*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteOcclusionQueriesNV".}
+proc glIsOcclusionQueryNV*(id: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsOcclusionQueryNV".}
+proc glBeginOcclusionQueryNV*(id: TGLuint){.dynlib: dllname, 
+    importc: "glBeginOcclusionQueryNV".}
+proc glEndOcclusionQueryNV*(){.dynlib: dllname, importc: "glEndOcclusionQueryNV".}
+proc glGetOcclusionQueryivNV*(id: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetOcclusionQueryivNV".}
+proc glGetOcclusionQueryuivNV*(id: TGLuint, pname: TGLenum, params: PGLuint){.
+    dynlib: dllname, importc: "glGetOcclusionQueryuivNV".}
+  #***** GL_NV_packed_depth_stencil *****//
+const 
+  GL_DEPTH_STENCIL_NV* = 0x000084F9
+  GL_UNSIGNED_INT_24_8_NV* = 0x000084FA
+  #***** GL_NV_point_sprite *****//
+
+const 
+  GL_POINT_SPRITE_NV* = 0x00008861
+  GL_COORD_REPLACE_NV* = 0x00008862
+  GL_POINT_SPRITE_R_MODE_NV* = 0x00008863
+
+proc glPointParameteriNV*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glPointParameteriNV".}
+proc glPointParameterivNV*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glPointParameterivNV".}
+  #***** GL_NV_register_combiners *****//
+const 
+  GL_REGISTER_COMBINERS_NV* = 0x00008522
+  GL_COMBINER0_NV* = 0x00008550
+  GL_COMBINER1_NV* = 0x00008551
+  GL_COMBINER2_NV* = 0x00008552
+  GL_COMBINER3_NV* = 0x00008553
+  GL_COMBINER4_NV* = 0x00008554
+  GL_COMBINER5_NV* = 0x00008555
+  GL_COMBINER6_NV* = 0x00008556
+  GL_COMBINER7_NV* = 0x00008557
+  GL_VARIABLE_A_NV* = 0x00008523
+  GL_VARIABLE_B_NV* = 0x00008524
+  GL_VARIABLE_C_NV* = 0x00008525
+  GL_VARIABLE_D_NV* = 0x00008526
+  GL_VARIABLE_E_NV* = 0x00008527
+  GL_VARIABLE_F_NV* = 0x00008528
+  GL_VARIABLE_G_NV* = 0x00008529
+  GL_CONSTANT_COLOR0_NV* = 0x0000852A
+  GL_CONSTANT_COLOR1_NV* = 0x0000852B
+  GL_PRIMARY_COLOR_NV* = 0x0000852C
+  GL_SECONDARY_COLOR_NV* = 0x0000852D
+  GL_SPARE0_NV* = 0x0000852E
+  GL_SPARE1_NV* = 0x0000852F
+  GL_UNSIGNED_IDENTITY_NV* = 0x00008536
+  GL_UNSIGNED_INVERT_NV* = 0x00008537
+  GL_EXPAND_NORMAL_NV* = 0x00008538
+  GL_EXPAND_NEGATE_NV* = 0x00008539
+  GL_HALF_BIAS_NORMAL_NV* = 0x0000853A
+  GL_HALF_BIAS_NEGATE_NV* = 0x0000853B
+  GL_SIGNED_IDENTITY_NV* = 0x0000853C
+  GL_SIGNED_NEGATE_NV* = 0x0000853D
+  GL_E_TIMES_F_NV* = 0x00008531
+  GL_SPARE0_PLUS_SECONDARY_COLOR_NV* = 0x00008532
+  GL_SCALE_BY_TWO_NV* = 0x0000853E
+  GL_SCALE_BY_FOUR_NV* = 0x0000853F
+  GL_SCALE_BY_ONE_HALF_NV* = 0x00008540
+  GL_BIAS_BY_NEGATIVE_ONE_HALF_NV* = 0x00008541
+  GL_DISCARD_NV* = 0x00008530
+  constGL_COMBINER_INPUT_NV* = 0x00008542
+  GL_COMBINER_MAPPING_NV* = 0x00008543
+  GL_COMBINER_COMPONENT_USAGE_NV* = 0x00008544
+  GL_COMBINER_AB_DOT_PRODUCT_NV* = 0x00008545
+  GL_COMBINER_CD_DOT_PRODUCT_NV* = 0x00008546
+  GL_COMBINER_MUX_SUM_NV* = 0x00008547
+  GL_COMBINER_SCALE_NV* = 0x00008548
+  GL_COMBINER_BIAS_NV* = 0x00008549
+  GL_COMBINER_AB_OUTPUT_NV* = 0x0000854A
+  GL_COMBINER_CD_OUTPUT_NV* = 0x0000854B
+  GL_COMBINER_SUM_OUTPUT_NV* = 0x0000854C
+  GL_NUM_GENERAL_COMBINERS_NV* = 0x0000854E
+  GL_COLOR_SUM_CLAMP_NV* = 0x0000854F
+  GL_MAX_GENERAL_COMBINERS_NV* = 0x0000854D
+
+proc glCombinerParameterfvNV*(pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glCombinerParameterfvNV".}
+proc glCombinerParameterivNV*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glCombinerParameterivNV".}
+proc glCombinerParameterfNV*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glCombinerParameterfNV".}
+proc glCombinerParameteriNV*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glCombinerParameteriNV".}
+proc glCombinerInputNV*(stage: TGLenum, portion: TGLenum, variable: TGLenum, 
+                        input: TGLenum, mapping: TGLenum, 
+                        componentUsage: TGLenum){.dynlib: dllname, 
+    importc: "glCombinerInputNV".}
+proc glCombinerOutputNV*(stage: TGLenum, portion: TGLenum, abOutput: TGLenum, 
+                         cdOutput: TGLenum, sumOutput: TGLenum, scale: TGLenum, 
+                         bias: TGLenum, abDotProduct: TGLboolean, 
+                         cdDotProduct: TGLboolean, muxSum: TGLboolean){.
+    dynlib: dllname, importc: "glCombinerOutputNV".}
+proc glFinalCombinerInputNV*(variable: TGLenum, input: TGLenum, 
+                             mapping: TGLenum, componentUsage: TGLenum){.
+    dynlib: dllname, importc: "glFinalCombinerInputNV".}
+proc glGetCombinerInputParameterfvNV*(stage: TGLenum, portion: TGLenum, 
+                                      variable: TGLenum, pname: TGLenum, 
+                                      params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetCombinerInputParameterfvNV".}
+proc glGetCombinerInputParameterivNV*(stage: TGLenum, portion: TGLenum, 
+                                      variable: TGLenum, pname: TGLenum, 
+                                      params: PGLint){.dynlib: dllname, 
+    importc: "glGetCombinerInputParameterivNV".}
+proc glGetCombinerOutputParameterfvNV*(stage: TGLenum, portion: TGLenum, 
+                                       pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetCombinerOutputParameterfvNV".}
+proc glGetCombinerOutputParameterivNV*(stage: TGLenum, portion: TGLenum, 
+                                       pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetCombinerOutputParameterivNV".}
+proc glGetFinalCombinerInputParameterfvNV*(variable: TGLenum, pname: TGLenum, 
+    params: PGLfloat){.dynlib: dllname, 
+                       importc: "glGetFinalCombinerInputParameterfvNV".}
+proc glGetFinalCombinerInputParameterivNV*(variable: TGLenum, pname: TGLenum, 
+    params: PGLint){.dynlib: dllname, 
+                     importc: "glGetFinalCombinerInputParameterivNV".}
+  #***** GL_NV_register_combiners2 *****//
+const 
+  GL_PER_STAGE_CONSTANTS_NV* = 0x00008535
+
+proc glCombinerStageParameterfvNV*(stage: TGLenum, pname: TGLenum, 
+                                   params: PGLfloat){.dynlib: dllname, 
+    importc: "glCombinerStageParameterfvNV".}
+proc glGetCombinerStageParameterfvNV*(stage: TGLenum, pname: TGLenum, 
+                                      params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetCombinerStageParameterfvNV".}
+  #***** GL_NV_texgen_emboss *****//
+const 
+  GL_EMBOSS_MAP_NV* = 0x0000855F
+  GL_EMBOSS_LIGHT_NV* = 0x0000855D
+  GL_EMBOSS_CONSTANT_NV* = 0x0000855E
+  #***** GL_NV_texgen_reflection *****//
+
+const 
+  GL_NORMAL_MAP_NV* = 0x00008511
+  GL_REFLECTION_MAP_NV* = 0x00008512
+  #***** GL_NV_texture_compression_vtc *****//
+  # GL_COMPRESSED_RGB_S3TC_DXT1_EXT  { already defined }
+  # GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  { already defined }
+  # GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  { already defined }
+  # GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  { already defined }
+  #***** GL_NV_texture_env_combine4 *****//
+
+const 
+  GL_COMBINE4_NV* = 0x00008503
+  GL_SOURCE3_RGB_NV* = 0x00008583
+  GL_SOURCE3_ALPHA_NV* = 0x0000858B
+  GL_OPERAND3_RGB_NV* = 0x00008593
+  GL_OPERAND3_ALPHA_NV* = 0x0000859B
+  #***** GL_NV_texture_rectangle *****//
+
+const 
+  GL_TEXTURE_RECTANGLE_NV* = 0x000084F5
+  GL_TEXTURE_BINDING_RECTANGLE_NV* = 0x000084F6
+  GL_PROXY_TEXTURE_RECTANGLE_NV* = 0x000084F7
+  GL_MAX_RECTANGLE_TEXTURE_SIZE_NV* = 0x000084F8
+  #***** GL_NV_texture_shader *****//
+
+const 
+  GL_TEXTURE_SHADER_NV* = 0x000086DE
+  GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV* = 0x000086D9
+  GL_SHADER_OPERATION_NV* = 0x000086DF
+  GL_CULL_MODES_NV* = 0x000086E0
+  GL_OFFSET_TEXTURE_MATRIX_NV* = 0x000086E1
+  GL_OFFSET_TEXTURE_SCALE_NV* = 0x000086E2
+  GL_OFFSET_TEXTURE_BIAS_NV* = 0x000086E3
+  GL_PREVIOUS_TEXTURE_INPUT_NV* = 0x000086E4
+  GL_CONST_EYE_NV* = 0x000086E5
+  GL_SHADER_CONSISTENT_NV* = 0x000086DD
+  GL_PASS_THROUGH_NV* = 0x000086E6
+  GL_CULL_FRAGMENT_NV* = 0x000086E7
+  GL_OFFSET_TEXTURE_2D_NV* = 0x000086E8
+  GL_OFFSET_TEXTURE_RECTANGLE_NV* = 0x0000864C
+  GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV* = 0x0000864D
+  GL_DEPENDENT_AR_TEXTURE_2D_NV* = 0x000086E9
+  GL_DEPENDENT_GB_TEXTURE_2D_NV* = 0x000086EA
+  GL_DOT_PRODUCT_NV* = 0x000086EC
+  GL_DOT_PRODUCT_DEPTH_REPLACE_NV* = 0x000086ED
+  GL_DOT_PRODUCT_TEXTURE_2D_NV* = 0x000086EE
+  GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV* = 0x0000864E
+  GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV* = 0x000086F0
+  GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV* = 0x000086F1
+  GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV* = 0x000086F2
+  GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV* = 0x000086F3
+  GL_HILO_NV* = 0x000086F4
+  GL_DSDT_NV* = 0x000086F5
+  GL_DSDT_MAG_NV* = 0x000086F6
+  GL_DSDT_MAG_VIB_NV* = 0x000086F7
+  GL_UNSIGNED_INT_S8_S8_8_8_NV* = 0x000086DA
+  GL_UNSIGNED_INT_8_8_S8_S8_REV_NV* = 0x000086DB
+  GL_SIGNED_RGBA_NV* = 0x000086FB
+  GL_SIGNED_RGBA8_NV* = 0x000086FC
+  GL_SIGNED_RGB_NV* = 0x000086FE
+  GL_SIGNED_RGB8_NV* = 0x000086FF
+  GL_SIGNED_LUMINANCE_NV* = 0x00008701
+  GL_SIGNED_LUMINANCE8_NV* = 0x00008702
+  GL_SIGNED_LUMINANCE_ALPHA_NV* = 0x00008703
+  GL_SIGNED_LUMINANCE8_ALPHA8_NV* = 0x00008704
+  GL_SIGNED_ALPHA_NV* = 0x00008705
+  GL_SIGNED_ALPHA8_NV* = 0x00008706
+  GL_SIGNED_INTENSITY_NV* = 0x00008707
+  GL_SIGNED_INTENSITY8_NV* = 0x00008708
+  GL_SIGNED_RGB_UNSIGNED_ALPHA_NV* = 0x0000870C
+  GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV* = 0x0000870D
+  GL_HILO16_NV* = 0x000086F8
+  GL_SIGNED_HILO_NV* = 0x000086F9
+  GL_SIGNED_HILO16_NV* = 0x000086FA
+  GL_DSDT8_NV* = 0x00008709
+  GL_DSDT8_MAG8_NV* = 0x0000870A
+  GL_DSDT_MAG_INTENSITY_NV* = 0x000086DC
+  GL_DSDT8_MAG8_INTENSITY8_NV* = 0x0000870B
+  GL_HI_SCALE_NV* = 0x0000870E
+  GL_LO_SCALE_NV* = 0x0000870F
+  GL_DS_SCALE_NV* = 0x00008710
+  GL_DT_SCALE_NV* = 0x00008711
+  GL_MAGNITUDE_SCALE_NV* = 0x00008712
+  GL_VIBRANCE_SCALE_NV* = 0x00008713
+  GL_HI_BIAS_NV* = 0x00008714
+  GL_LO_BIAS_NV* = 0x00008715
+  GL_DS_BIAS_NV* = 0x00008716
+  GL_DT_BIAS_NV* = 0x00008717
+  GL_MAGNITUDE_BIAS_NV* = 0x00008718
+  GL_VIBRANCE_BIAS_NV* = 0x00008719
+  GL_TEXTURE_BORDER_VALUES_NV* = 0x0000871A
+  GL_TEXTURE_HI_SIZE_NV* = 0x0000871B
+  GL_TEXTURE_LO_SIZE_NV* = 0x0000871C
+  GL_TEXTURE_DS_SIZE_NV* = 0x0000871D
+  GL_TEXTURE_DT_SIZE_NV* = 0x0000871E
+  GL_TEXTURE_MAG_SIZE_NV* = 0x0000871F
+  #***** GL_NV_texture_shader2 *****//
+
+const 
+  GL_DOT_PRODUCT_TEXTURE_3D_NV* = 0x000086EF # GL_HILO_NV  { already defined }
+                                             # GL_DSDT_NV  { already defined }
+                                             # GL_DSDT_MAG_NV  { already defined }
+                                             # GL_DSDT_MAG_VIB_NV  { already defined }
+                                             # GL_UNSIGNED_INT_S8_S8_8_8_NV  { already defined }
+                                             # GL_UNSIGNED_INT_8_8_S8_S8_REV_NV  { already defined }
+                                             # GL_SIGNED_RGBA_NV  { already defined }
+                                             # GL_SIGNED_RGBA8_NV  { already defined }
+                                             # GL_SIGNED_RGB_NV  { already defined }
+                                             # GL_SIGNED_RGB8_NV  { already defined }
+                                             # GL_SIGNED_LUMINANCE_NV  { already defined }
+                                             # GL_SIGNED_LUMINANCE8_NV  { already defined }
+                                             # GL_SIGNED_LUMINANCE_ALPHA_NV  { already defined }
+                                             # GL_SIGNED_LUMINANCE8_ALPHA8_NV  { already defined }
+                                             # GL_SIGNED_ALPHA_NV  { already defined }
+                                             # GL_SIGNED_ALPHA8_NV  { already defined }
+                                             # GL_SIGNED_INTENSITY_NV  { already defined }
+                                             # GL_SIGNED_INTENSITY8_NV  { already defined }
+                                             # GL_SIGNED_RGB_UNSIGNED_ALPHA_NV  { already defined }
+                                             # GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV  { already defined }
+                                             # GL_HILO16_NV  { already defined }
+                                             # GL_SIGNED_HILO_NV  { already defined }
+                                             # GL_SIGNED_HILO16_NV  { already defined }
+                                             # GL_DSDT8_NV  { already defined }
+                                             # GL_DSDT8_MAG8_NV  { already defined }
+                                             # GL_DSDT_MAG_INTENSITY_NV  { already defined }
+                                             # GL_DSDT8_MAG8_INTENSITY8_NV  { already defined }
+  #***** GL_NV_texture_shader3 *****//
+
+const 
+  GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV* = 0x00008850
+  GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV* = 0x00008851
+  GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV* = 0x00008852
+  GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV* = 0x00008853
+  GL_OFFSET_HILO_TEXTURE_2D_NV* = 0x00008854
+  GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV* = 0x00008855
+  GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV* = 0x00008856
+  GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV* = 0x00008857
+  GL_DEPENDENT_HILO_TEXTURE_2D_NV* = 0x00008858
+  GL_DEPENDENT_RGB_TEXTURE_3D_NV* = 0x00008859
+  GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV* = 0x0000885A
+  GL_DOT_PRODUCT_PASS_THROUGH_NV* = 0x0000885B
+  GL_DOT_PRODUCT_TEXTURE_1D_NV* = 0x0000885C
+  GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV* = 0x0000885D
+  GL_HILO8_NV* = 0x0000885E
+  GL_SIGNED_HILO8_NV* = 0x0000885F
+  GL_FORCE_BLUE_TO_ONE_NV* = 0x00008860
+  #***** GL_NV_vertex_array_range *****//
+
+const 
+  constGL_VERTEX_ARRAY_RANGE_NV* = 0x0000851D
+  GL_VERTEX_ARRAY_RANGE_LENGTH_NV* = 0x0000851E
+  GL_VERTEX_ARRAY_RANGE_VALID_NV* = 0x0000851F
+  GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV* = 0x00008520
+  GL_VERTEX_ARRAY_RANGE_POINTER_NV* = 0x00008521
+
+proc glVertexArrayRangeNV*(len: TGLsizei, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexArrayRangeNV".}
+proc glFlushVertexArrayRangeNV*(){.dynlib: dllname, 
+                                   importc: "glFlushVertexArrayRangeNV".}
+  #***** GL_NV_vertex_array_range2 *****//
+const 
+  GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV* = 0x00008533
+  #***** GL_NV_vertex_program *****//
+
+const 
+  GL_VERTEX_PROGRAM_NV* = 0x00008620
+  GL_VERTEX_PROGRAM_POINT_SIZE_NV* = 0x00008642
+  GL_VERTEX_PROGRAM_TWO_SIDE_NV* = 0x00008643
+  GL_VERTEX_STATE_PROGRAM_NV* = 0x00008621
+  GL_ATTRIB_ARRAY_SIZE_NV* = 0x00008623
+  GL_ATTRIB_ARRAY_STRIDE_NV* = 0x00008624
+  GL_ATTRIB_ARRAY_TYPE_NV* = 0x00008625
+  GL_CURRENT_ATTRIB_NV* = 0x00008626
+  GL_PROGRAM_PARAMETER_NV* = 0x00008644
+  GL_ATTRIB_ARRAY_POINTER_NV* = 0x00008645
+  GL_PROGRAM_TARGET_NV* = 0x00008646
+  GL_PROGRAM_LENGTH_NV* = 0x00008627
+  GL_PROGRAM_RESIDENT_NV* = 0x00008647
+  GL_PROGRAM_STRING_NV* = 0x00008628
+  constGL_TRACK_MATRIX_NV* = 0x00008648
+  GL_TRACK_MATRIX_TRANSFORM_NV* = 0x00008649
+  GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV* = 0x0000862E
+  GL_MAX_TRACK_MATRICES_NV* = 0x0000862F
+  GL_CURRENT_MATRIX_STACK_DEPTH_NV* = 0x00008640
+  GL_CURRENT_MATRIX_NV* = 0x00008641
+  GL_VERTEX_PROGRAM_BINDING_NV* = 0x0000864A
+  GL_PROGRAM_ERROR_POSITION_NV* = 0x0000864B
+  GL_MODELVIEW_PROJECTION_NV* = 0x00008629
+  GL_MATRIX0_NV* = 0x00008630
+  GL_MATRIX1_NV* = 0x00008631
+  GL_MATRIX2_NV* = 0x00008632
+  GL_MATRIX3_NV* = 0x00008633
+  GL_MATRIX4_NV* = 0x00008634
+  GL_MATRIX5_NV* = 0x00008635
+  GL_MATRIX6_NV* = 0x00008636
+  GL_MATRIX7_NV* = 0x00008637
+  GL_IDENTITY_NV* = 0x0000862A
+  GL_INVERSE_NV* = 0x0000862B
+  GL_TRANSPOSE_NV* = 0x0000862C
+  GL_INVERSE_TRANSPOSE_NV* = 0x0000862D
+  GL_VERTEX_ATTRIB_ARRAY0_NV* = 0x00008650
+  GL_VERTEX_ATTRIB_ARRAY1_NV* = 0x00008651
+  GL_VERTEX_ATTRIB_ARRAY2_NV* = 0x00008652
+  GL_VERTEX_ATTRIB_ARRAY3_NV* = 0x00008653
+  GL_VERTEX_ATTRIB_ARRAY4_NV* = 0x00008654
+  GL_VERTEX_ATTRIB_ARRAY5_NV* = 0x00008655
+  GL_VERTEX_ATTRIB_ARRAY6_NV* = 0x00008656
+  GL_VERTEX_ATTRIB_ARRAY7_NV* = 0x00008657
+  GL_VERTEX_ATTRIB_ARRAY8_NV* = 0x00008658
+  GL_VERTEX_ATTRIB_ARRAY9_NV* = 0x00008659
+  GL_VERTEX_ATTRIB_ARRAY10_NV* = 0x0000865A
+  GL_VERTEX_ATTRIB_ARRAY11_NV* = 0x0000865B
+  GL_VERTEX_ATTRIB_ARRAY12_NV* = 0x0000865C
+  GL_VERTEX_ATTRIB_ARRAY13_NV* = 0x0000865D
+  GL_VERTEX_ATTRIB_ARRAY14_NV* = 0x0000865E
+  GL_VERTEX_ATTRIB_ARRAY15_NV* = 0x0000865F
+  GL_MAP1_VERTEX_ATTRIB0_4_NV* = 0x00008660
+  GL_MAP1_VERTEX_ATTRIB1_4_NV* = 0x00008661
+  GL_MAP1_VERTEX_ATTRIB2_4_NV* = 0x00008662
+  GL_MAP1_VERTEX_ATTRIB3_4_NV* = 0x00008663
+  GL_MAP1_VERTEX_ATTRIB4_4_NV* = 0x00008664
+  GL_MAP1_VERTEX_ATTRIB5_4_NV* = 0x00008665
+  GL_MAP1_VERTEX_ATTRIB6_4_NV* = 0x00008666
+  GL_MAP1_VERTEX_ATTRIB7_4_NV* = 0x00008667
+  GL_MAP1_VERTEX_ATTRIB8_4_NV* = 0x00008668
+  GL_MAP1_VERTEX_ATTRIB9_4_NV* = 0x00008669
+  GL_MAP1_VERTEX_ATTRIB10_4_NV* = 0x0000866A
+  GL_MAP1_VERTEX_ATTRIB11_4_NV* = 0x0000866B
+  GL_MAP1_VERTEX_ATTRIB12_4_NV* = 0x0000866C
+  GL_MAP1_VERTEX_ATTRIB13_4_NV* = 0x0000866D
+  GL_MAP1_VERTEX_ATTRIB14_4_NV* = 0x0000866E
+  GL_MAP1_VERTEX_ATTRIB15_4_NV* = 0x0000866F
+  GL_MAP2_VERTEX_ATTRIB0_4_NV* = 0x00008670
+  GL_MAP2_VERTEX_ATTRIB1_4_NV* = 0x00008671
+  GL_MAP2_VERTEX_ATTRIB2_4_NV* = 0x00008672
+  GL_MAP2_VERTEX_ATTRIB3_4_NV* = 0x00008673
+  GL_MAP2_VERTEX_ATTRIB4_4_NV* = 0x00008674
+  GL_MAP2_VERTEX_ATTRIB5_4_NV* = 0x00008675
+  GL_MAP2_VERTEX_ATTRIB6_4_NV* = 0x00008676
+  GL_MAP2_VERTEX_ATTRIB7_4_NV* = 0x00008677
+  GL_MAP2_VERTEX_ATTRIB8_4_NV* = 0x00008678
+  GL_MAP2_VERTEX_ATTRIB9_4_NV* = 0x00008679
+  GL_MAP2_VERTEX_ATTRIB10_4_NV* = 0x0000867A
+  GL_MAP2_VERTEX_ATTRIB11_4_NV* = 0x0000867B
+  GL_MAP2_VERTEX_ATTRIB12_4_NV* = 0x0000867C
+  GL_MAP2_VERTEX_ATTRIB13_4_NV* = 0x0000867D
+  GL_MAP2_VERTEX_ATTRIB14_4_NV* = 0x0000867E
+  GL_MAP2_VERTEX_ATTRIB15_4_NV* = 0x0000867F
+
+proc glBindProgramNV*(target: TGLenum, id: TGLuint){.dynlib: dllname, 
+    importc: "glBindProgramNV".}
+proc glDeleteProgramsNV*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteProgramsNV".}
+proc glExecuteProgramNV*(target: TGLenum, id: TGLuint, params: PGLfloat){.
+    dynlib: dllname, importc: "glExecuteProgramNV".}
+proc glGenProgramsNV*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glGenProgramsNV".}
+proc glAreProgramsResidentNV*(n: TGLsizei, ids: PGLuint, residences: PGLboolean): TGLboolean{.
+    dynlib: dllname, importc: "glAreProgramsResidentNV".}
+proc glRequestResidentProgramsNV*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glRequestResidentProgramsNV".}
+proc glGetProgramParameterfvNV*(target: TGLenum, index: TGLuint, pname: TGLenum, 
+                                params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetProgramParameterfvNV".}
+proc glGetProgramParameterdvNV*(target: TGLenum, index: TGLuint, pname: TGLenum, 
+                                params: PGLdouble){.dynlib: dllname, 
+    importc: "glGetProgramParameterdvNV".}
+proc glGetProgramivNV*(id: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetProgramivNV".}
+proc glGetProgramStringNV*(id: TGLuint, pname: TGLenum, theProgram: PGLubyte){.
+    dynlib: dllname, importc: "glGetProgramStringNV".}
+proc glGetTrackMatrixivNV*(target: TGLenum, address: TGLuint, pname: TGLenum, 
+                           params: PGLint){.dynlib: dllname, 
+    importc: "glGetTrackMatrixivNV".}
+proc glGetVertexAttribdvNV*(index: TGLuint, pname: TGLenum, params: PGLdouble){.
+    dynlib: dllname, importc: "glGetVertexAttribdvNV".}
+proc glGetVertexAttribfvNV*(index: TGLuint, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetVertexAttribfvNV".}
+proc glGetVertexAttribivNV*(index: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetVertexAttribivNV".}
+proc glGetVertexAttribPointervNV*(index: TGLuint, pname: TGLenum, 
+                                  pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glGetVertexAttribPointervNV".}
+proc glIsProgramNV*(id: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsProgramNV".}
+proc glLoadProgramNV*(target: TGLenum, id: TGLuint, length: TGLsizei, 
+                      theProgram: PGLubyte){.dynlib: dllname, 
+    importc: "glLoadProgramNV".}
+proc glProgramParameter4fNV*(target: TGLenum, index: TGLuint, x: TGLfloat, 
+                             y: TGLfloat, z: TGLfloat, w: TGLfloat){.
+    dynlib: dllname, importc: "glProgramParameter4fNV".}
+proc glProgramParameter4fvNV*(target: TGLenum, index: TGLuint, params: PGLfloat){.
+    dynlib: dllname, importc: "glProgramParameter4fvNV".}
+proc glProgramParameters4dvNV*(target: TGLenum, index: TGLuint, num: TGLuint, 
+                               params: PGLdouble){.dynlib: dllname, 
+    importc: "glProgramParameters4dvNV".}
+proc glProgramParameters4fvNV*(target: TGLenum, index: TGLuint, num: TGLuint, 
+                               params: PGLfloat){.dynlib: dllname, 
+    importc: "glProgramParameters4fvNV".}
+proc glTrackMatrixNV*(target: TGLenum, address: TGLuint, matrix: TGLenum, 
+                      transform: TGLenum){.dynlib: dllname, 
+    importc: "glTrackMatrixNV".}
+proc glVertexAttribPointerNV*(index: TGLuint, size: TGLint, thetype: TGLenum, 
+                              stride: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glVertexAttribPointerNV".}
+proc glVertexAttrib1sNV*(index: TGLuint, x: TGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1sNV".}
+proc glVertexAttrib1fNV*(index: TGLuint, x: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1fNV".}
+proc glVertexAttrib1dNV*(index: TGLuint, x: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1dNV".}
+proc glVertexAttrib2sNV*(index: TGLuint, x: TGLshort, y: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib2sNV".}
+proc glVertexAttrib2fNV*(index: TGLuint, x: TGLfloat, y: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib2fNV".}
+proc glVertexAttrib2dNV*(index: TGLuint, x: TGLdouble, y: TGLdouble){.
+    dynlib: dllname, importc: "glVertexAttrib2dNV".}
+proc glVertexAttrib3sNV*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort){.
+    dynlib: dllname, importc: "glVertexAttrib3sNV".}
+proc glVertexAttrib3fNV*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glVertexAttrib3fNV".}
+proc glVertexAttrib3dNV*(index: TGLuint, x: TGLdouble, y: TGLdouble, 
+                         z: TGLdouble){.dynlib: dllname, 
+                                        importc: "glVertexAttrib3dNV".}
+proc glVertexAttrib4sNV*(index: TGLuint, x: TGLshort, y: TGLshort, z: TGLshort, 
+                         w: TGLshort){.dynlib: dllname, 
+                                       importc: "glVertexAttrib4sNV".}
+proc glVertexAttrib4fNV*(index: TGLuint, x: TGLfloat, y: TGLfloat, z: TGLfloat, 
+                         w: TGLfloat){.dynlib: dllname, 
+                                       importc: "glVertexAttrib4fNV".}
+proc glVertexAttrib4dNV*(index: TGLuint, x: TGLdouble, y: TGLdouble, 
+                         z: TGLdouble, w: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib4dNV".}
+proc glVertexAttrib4ubNV*(index: TGLuint, x: TGLubyte, y: TGLubyte, z: TGLubyte, 
+                          w: TGLubyte){.dynlib: dllname, 
+                                        importc: "glVertexAttrib4ubNV".}
+proc glVertexAttrib1svNV*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib1svNV".}
+proc glVertexAttrib1fvNV*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib1fvNV".}
+proc glVertexAttrib1dvNV*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib1dvNV".}
+proc glVertexAttrib2svNV*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib2svNV".}
+proc glVertexAttrib2fvNV*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib2fvNV".}
+proc glVertexAttrib2dvNV*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib2dvNV".}
+proc glVertexAttrib3svNV*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib3svNV".}
+proc glVertexAttrib3fvNV*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib3fvNV".}
+proc glVertexAttrib3dvNV*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib3dvNV".}
+proc glVertexAttrib4svNV*(index: TGLuint, v: PGLshort){.dynlib: dllname, 
+    importc: "glVertexAttrib4svNV".}
+proc glVertexAttrib4fvNV*(index: TGLuint, v: PGLfloat){.dynlib: dllname, 
+    importc: "glVertexAttrib4fvNV".}
+proc glVertexAttrib4dvNV*(index: TGLuint, v: PGLdouble){.dynlib: dllname, 
+    importc: "glVertexAttrib4dvNV".}
+proc glVertexAttrib4ubvNV*(index: TGLuint, v: PGLubyte){.dynlib: dllname, 
+    importc: "glVertexAttrib4ubvNV".}
+proc glVertexAttribs1svNV*(index: TGLuint, n: TGLsizei, v: PGLshort){.
+    dynlib: dllname, importc: "glVertexAttribs1svNV".}
+proc glVertexAttribs1fvNV*(index: TGLuint, n: TGLsizei, v: PGLfloat){.
+    dynlib: dllname, importc: "glVertexAttribs1fvNV".}
+proc glVertexAttribs1dvNV*(index: TGLuint, n: TGLsizei, v: PGLdouble){.
+    dynlib: dllname, importc: "glVertexAttribs1dvNV".}
+proc glVertexAttribs2svNV*(index: TGLuint, n: TGLsizei, v: PGLshort){.
+    dynlib: dllname, importc: "glVertexAttribs2svNV".}
+proc glVertexAttribs2fvNV*(index: TGLuint, n: TGLsizei, v: PGLfloat){.
+    dynlib: dllname, importc: "glVertexAttribs2fvNV".}
+proc glVertexAttribs2dvNV*(index: TGLuint, n: TGLsizei, v: PGLdouble){.
+    dynlib: dllname, importc: "glVertexAttribs2dvNV".}
+proc glVertexAttribs3svNV*(index: TGLuint, n: TGLsizei, v: PGLshort){.
+    dynlib: dllname, importc: "glVertexAttribs3svNV".}
+proc glVertexAttribs3fvNV*(index: TGLuint, n: TGLsizei, v: PGLfloat){.
+    dynlib: dllname, importc: "glVertexAttribs3fvNV".}
+proc glVertexAttribs3dvNV*(index: TGLuint, n: TGLsizei, v: PGLdouble){.
+    dynlib: dllname, importc: "glVertexAttribs3dvNV".}
+proc glVertexAttribs4svNV*(index: TGLuint, n: TGLsizei, v: PGLshort){.
+    dynlib: dllname, importc: "glVertexAttribs4svNV".}
+proc glVertexAttribs4fvNV*(index: TGLuint, n: TGLsizei, v: PGLfloat){.
+    dynlib: dllname, importc: "glVertexAttribs4fvNV".}
+proc glVertexAttribs4dvNV*(index: TGLuint, n: TGLsizei, v: PGLdouble){.
+    dynlib: dllname, importc: "glVertexAttribs4dvNV".}
+proc glVertexAttribs4ubvNV*(index: TGLuint, n: TGLsizei, v: PGLubyte){.
+    dynlib: dllname, importc: "glVertexAttribs4ubvNV".}
+  #***** GL_NV_vertex_program1_1 *****//
+  #***** GL_ATI_element_array *****//
+const 
+  GL_ELEMENT_ARRAY_ATI* = 0x00008768
+  GL_ELEMENT_ARRAY_TYPE_ATI* = 0x00008769
+  GL_ELEMENT_ARRAY_POINTER_ATI* = 0x0000876A
+
+proc glElementPointerATI*(thetype: TGLenum, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glElementPointerATI".}
+proc glDrawElementArrayATI*(mode: TGLenum, count: TGLsizei){.dynlib: dllname, 
+    importc: "glDrawElementArrayATI".}
+proc glDrawRangeElementArrayATI*(mode: TGLenum, start: TGLuint, theend: TGLuint, 
+                                 count: TGLsizei){.dynlib: dllname, 
+    importc: "glDrawRangeElementArrayATI".}
+  #***** GL_ATI_envmap_bumpmap *****//
+const 
+  GL_BUMP_ROT_MATRIX_ATI* = 0x00008775
+  GL_BUMP_ROT_MATRIX_SIZE_ATI* = 0x00008776
+  GL_BUMP_NUM_TEX_UNITS_ATI* = 0x00008777
+  GL_BUMP_TEX_UNITS_ATI* = 0x00008778
+  GL_DUDV_ATI* = 0x00008779
+  GL_DU8DV8_ATI* = 0x0000877A
+  GL_BUMP_ENVMAP_ATI* = 0x0000877B
+  GL_BUMP_TARGET_ATI* = 0x0000877C
+
+proc glTexBumpParameterivATI*(pname: TGLenum, param: PGLint){.dynlib: dllname, 
+    importc: "glTexBumpParameterivATI".}
+proc glTexBumpParameterfvATI*(pname: TGLenum, param: PGLfloat){.dynlib: dllname, 
+    importc: "glTexBumpParameterfvATI".}
+proc glGetTexBumpParameterivATI*(pname: TGLenum, param: PGLint){.
+    dynlib: dllname, importc: "glGetTexBumpParameterivATI".}
+proc glGetTexBumpParameterfvATI*(pname: TGLenum, param: PGLfloat){.
+    dynlib: dllname, importc: "glGetTexBumpParameterfvATI".}
+  #***** GL_ATI_fragment_shader *****//
+const 
+  GL_FRAGMENT_SHADER_ATI* = 0x00008920
+  GL_REG_0_ATI* = 0x00008921
+  GL_REG_1_ATI* = 0x00008922
+  GL_REG_2_ATI* = 0x00008923
+  GL_REG_3_ATI* = 0x00008924
+  GL_REG_4_ATI* = 0x00008925
+  GL_REG_5_ATI* = 0x00008926
+  GL_CON_0_ATI* = 0x00008941
+  GL_CON_1_ATI* = 0x00008942
+  GL_CON_2_ATI* = 0x00008943
+  GL_CON_3_ATI* = 0x00008944
+  GL_CON_4_ATI* = 0x00008945
+  GL_CON_5_ATI* = 0x00008946
+  GL_CON_6_ATI* = 0x00008947
+  GL_CON_7_ATI* = 0x00008948
+  GL_MOV_ATI* = 0x00008961
+  GL_ADD_ATI* = 0x00008963
+  GL_MUL_ATI* = 0x00008964
+  GL_SUB_ATI* = 0x00008965
+  GL_DOT3_ATI* = 0x00008966
+  GL_DOT4_ATI* = 0x00008967
+  GL_MAD_ATI* = 0x00008968
+  GL_LERP_ATI* = 0x00008969
+  GL_CND_ATI* = 0x0000896A
+  GL_CND0_ATI* = 0x0000896B
+  GL_DOT2_ADD_ATI* = 0x0000896C
+  GL_SECONDARY_INTERPOLATOR_ATI* = 0x0000896D
+  GL_SWIZZLE_STR_ATI* = 0x00008976
+  GL_SWIZZLE_STQ_ATI* = 0x00008977
+  GL_SWIZZLE_STR_DR_ATI* = 0x00008978
+  GL_SWIZZLE_STQ_DQ_ATI* = 0x00008979
+  GL_RED_BIT_ATI* = 0x00000001
+  GL_GREEN_BIT_ATI* = 0x00000002
+  GL_BLUE_BIT_ATI* = 0x00000004
+  GL_2X_BIT_ATI* = 0x00000001
+  GL_4X_BIT_ATI* = 0x00000002
+  GL_8X_BIT_ATI* = 0x00000004
+  GL_HALF_BIT_ATI* = 0x00000008
+  GL_QUARTER_BIT_ATI* = 0x00000010
+  GL_EIGHTH_BIT_ATI* = 0x00000020
+  GL_SATURATE_BIT_ATI* = 0x00000040 # GL_2X_BIT_ATI  { already defined }
+  GL_COMP_BIT_ATI* = 0x00000002
+  GL_NEGATE_BIT_ATI* = 0x00000004
+  GL_BIAS_BIT_ATI* = 0x00000008
+
+proc glGenFragmentShadersATI*(range: TGLuint): TGLuint{.dynlib: dllname, 
+    importc: "glGenFragmentShadersATI".}
+proc glBindFragmentShaderATI*(id: TGLuint){.dynlib: dllname, 
+    importc: "glBindFragmentShaderATI".}
+proc glDeleteFragmentShaderATI*(id: TGLuint){.dynlib: dllname, 
+    importc: "glDeleteFragmentShaderATI".}
+proc glBeginFragmentShaderATI*(){.dynlib: dllname, 
+                                  importc: "glBeginFragmentShaderATI".}
+proc glEndFragmentShaderATI*(){.dynlib: dllname, 
+                                importc: "glEndFragmentShaderATI".}
+proc glPassTexCoordATI*(dst: TGLuint, coord: TGLuint, swizzle: TGLenum){.
+    dynlib: dllname, importc: "glPassTexCoordATI".}
+proc glSampleMapATI*(dst: TGLuint, interp: TGLuint, swizzle: TGLenum){.
+    dynlib: dllname, importc: "glSampleMapATI".}
+proc glColorFragmentOp1ATI*(op: TGLenum, dst: TGLuint, dstMask: TGLuint, 
+                            dstMod: TGLuint, arg1: TGLuint, arg1Rep: TGLuint, 
+                            arg1Mod: TGLuint){.dynlib: dllname, 
+    importc: "glColorFragmentOp1ATI".}
+proc glColorFragmentOp2ATI*(op: TGLenum, dst: TGLuint, dstMask: TGLuint, 
+                            dstMod: TGLuint, arg1: TGLuint, arg1Rep: TGLuint, 
+                            arg1Mod: TGLuint, arg2: TGLuint, arg2Rep: TGLuint, 
+                            arg2Mod: TGLuint){.dynlib: dllname, 
+    importc: "glColorFragmentOp2ATI".}
+proc glColorFragmentOp3ATI*(op: TGLenum, dst: TGLuint, dstMask: TGLuint, 
+                            dstMod: TGLuint, arg1: TGLuint, arg1Rep: TGLuint, 
+                            arg1Mod: TGLuint, arg2: TGLuint, arg2Rep: TGLuint, 
+                            arg2Mod: TGLuint, arg3: TGLuint, arg3Rep: TGLuint, 
+                            arg3Mod: TGLuint){.dynlib: dllname, 
+    importc: "glColorFragmentOp3ATI".}
+proc glAlphaFragmentOp1ATI*(op: TGLenum, dst: TGLuint, dstMod: TGLuint, 
+                            arg1: TGLuint, arg1Rep: TGLuint, arg1Mod: TGLuint){.
+    dynlib: dllname, importc: "glAlphaFragmentOp1ATI".}
+proc glAlphaFragmentOp2ATI*(op: TGLenum, dst: TGLuint, dstMod: TGLuint, 
+                            arg1: TGLuint, arg1Rep: TGLuint, arg1Mod: TGLuint, 
+                            arg2: TGLuint, arg2Rep: TGLuint, arg2Mod: TGLuint){.
+    dynlib: dllname, importc: "glAlphaFragmentOp2ATI".}
+proc glAlphaFragmentOp3ATI*(op: TGLenum, dst: TGLuint, dstMod: TGLuint, 
+                            arg1: TGLuint, arg1Rep: TGLuint, arg1Mod: TGLuint, 
+                            arg2: TGLuint, arg2Rep: TGLuint, arg2Mod: TGLuint, 
+                            arg3: TGLuint, arg3Rep: TGLuint, arg3Mod: TGLuint){.
+    dynlib: dllname, importc: "glAlphaFragmentOp3ATI".}
+proc glSetFragmentShaderConstantATI*(dst: TGLuint, value: PGLfloat){.
+    dynlib: dllname, importc: "glSetFragmentShaderConstantATI".}
+  #***** GL_ATI_pn_triangles *****//
+const 
+  GL_PN_TRIANGLES_ATI* = 0x000087F0
+  GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI* = 0x000087F1
+  GL_PN_TRIANGLES_POINT_MODE_ATI* = 0x000087F2
+  GL_PN_TRIANGLES_NORMAL_MODE_ATI* = 0x000087F3
+  GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI* = 0x000087F4
+  GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI* = 0x000087F5
+  GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI* = 0x000087F6
+  GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI* = 0x000087F7
+  GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI* = 0x000087F8
+
+proc glPNTrianglesiATI*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glPNTrianglesiATI".}
+proc glPNTrianglesfATI*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPNTrianglesfATI".}
+  #***** GL_ATI_texture_mirror_once *****//
+const 
+  GL_MIRROR_CLAMP_ATI* = 0x00008742
+  GL_MIRROR_CLAMP_TO_EDGE_ATI* = 0x00008743
+  #***** GL_ATI_vertex_array_object *****//
+
+const 
+  GL_STATIC_ATI* = 0x00008760
+  GL_DYNAMIC_ATI* = 0x00008761
+  GL_PRESERVE_ATI* = 0x00008762
+  GL_DISCARD_ATI* = 0x00008763
+  GL_OBJECT_BUFFER_SIZE_ATI* = 0x00008764
+  GL_OBJECT_BUFFER_USAGE_ATI* = 0x00008765
+  GL_ARRAY_OBJECT_BUFFER_ATI* = 0x00008766
+  GL_ARRAY_OBJECT_OFFSET_ATI* = 0x00008767
+
+proc glNewObjectBufferATI*(size: TGLsizei, pointer: PGLvoid, usage: TGLenum): TGLuint{.
+    dynlib: dllname, importc: "glNewObjectBufferATI".}
+proc glIsObjectBufferATI*(buffer: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsObjectBufferATI".}
+proc glUpdateObjectBufferATI*(buffer: TGLuint, offset: TGLuint, size: TGLsizei, 
+                              pointer: PGLvoid, preserve: TGLenum){.
+    dynlib: dllname, importc: "glUpdateObjectBufferATI".}
+proc glGetObjectBufferfvATI*(buffer: TGLuint, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetObjectBufferfvATI".}
+proc glGetObjectBufferivATI*(buffer: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetObjectBufferivATI".}
+proc glDeleteObjectBufferATI*(buffer: TGLuint){.dynlib: dllname, 
+    importc: "glDeleteObjectBufferATI".}
+proc glArrayObjectATI*(thearray: TGLenum, size: TGLint, thetype: TGLenum, 
+                       stride: TGLsizei, buffer: TGLuint, offset: TGLuint){.
+    dynlib: dllname, importc: "glArrayObjectATI".}
+proc glGetArrayObjectfvATI*(thearray: TGLenum, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetArrayObjectfvATI".}
+proc glGetArrayObjectivATI*(thearray: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetArrayObjectivATI".}
+proc glVariantArrayObjectATI*(id: TGLuint, thetype: TGLenum, stride: TGLsizei, 
+                              buffer: TGLuint, offset: TGLuint){.
+    dynlib: dllname, importc: "glVariantArrayObjectATI".}
+proc glGetVariantArrayObjectfvATI*(id: TGLuint, pname: TGLenum, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetVariantArrayObjectfvATI".}
+proc glGetVariantArrayObjectivATI*(id: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetVariantArrayObjectivATI".}
+  #***** GL_ATI_vertex_streams *****//
+const 
+  GL_MAX_VERTEX_STREAMS_ATI* = 0x0000876B
+  GL_VERTEX_STREAM0_ATI* = 0x0000876C
+  GL_VERTEX_STREAM1_ATI* = 0x0000876D
+  GL_VERTEX_STREAM2_ATI* = 0x0000876E
+  GL_VERTEX_STREAM3_ATI* = 0x0000876F
+  GL_VERTEX_STREAM4_ATI* = 0x00008770
+  GL_VERTEX_STREAM5_ATI* = 0x00008771
+  GL_VERTEX_STREAM6_ATI* = 0x00008772
+  GL_VERTEX_STREAM7_ATI* = 0x00008773
+  GL_VERTEX_SOURCE_ATI* = 0x00008774
+
+proc glVertexStream1s*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream1s".}
+proc glVertexStream1i*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream1i".}
+proc glVertexStream1f*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream1f".}
+proc glVertexStream1d*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream1d".}
+proc glVertexStream1sv*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream1sv".}
+proc glVertexStream1iv*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream1iv".}
+proc glVertexStream1fv*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream1fv".}
+proc glVertexStream1dv*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream1dv".}
+proc glVertexStream2s*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream2s".}
+proc glVertexStream2i*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream2i".}
+proc glVertexStream2f*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream2f".}
+proc glVertexStream2d*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream2d".}
+proc glVertexStream2sv*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream2sv".}
+proc glVertexStream2iv*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream2iv".}
+proc glVertexStream2fv*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream2fv".}
+proc glVertexStream2dv*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream2dv".}
+proc glVertexStream3s*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream3s".}
+proc glVertexStream3i*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream3i".}
+proc glVertexStream3f*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream3f".}
+proc glVertexStream3d*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream3d".}
+proc glVertexStream3sv*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream3sv".}
+proc glVertexStream3iv*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream3iv".}
+proc glVertexStream3fv*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream3fv".}
+proc glVertexStream3dv*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream3dv".}
+proc glVertexStream4s*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream4s".}
+proc glVertexStream4i*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream4i".}
+proc glVertexStream4f*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream4f".}
+proc glVertexStream4d*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream4d".}
+proc glVertexStream4sv*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glVertexStream4sv".}
+proc glVertexStream4iv*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glVertexStream4iv".}
+proc glVertexStream4fv*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexStream4fv".}
+proc glVertexStream4dv*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glVertexStream4dv".}
+proc glNormalStream3b*(stream: TGLenum, coords: TGLByte){.dynlib: dllname, 
+    importc: "glNormalStream3b".}
+proc glNormalStream3s*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glNormalStream3s".}
+proc glNormalStream3i*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glNormalStream3i".}
+proc glNormalStream3f*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glNormalStream3f".}
+proc glNormalStream3d*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glNormalStream3d".}
+proc glNormalStream3bv*(stream: TGLenum, coords: TGLByte){.dynlib: dllname, 
+    importc: "glNormalStream3bv".}
+proc glNormalStream3sv*(stream: TGLenum, coords: TGLshort){.dynlib: dllname, 
+    importc: "glNormalStream3sv".}
+proc glNormalStream3iv*(stream: TGLenum, coords: TGLint){.dynlib: dllname, 
+    importc: "glNormalStream3iv".}
+proc glNormalStream3fv*(stream: TGLenum, coords: TGLfloat){.dynlib: dllname, 
+    importc: "glNormalStream3fv".}
+proc glNormalStream3dv*(stream: TGLenum, coords: TGLdouble){.dynlib: dllname, 
+    importc: "glNormalStream3dv".}
+proc glClientActiveVertexStream*(stream: TGLenum){.dynlib: dllname, 
+    importc: "glClientActiveVertexStream".}
+proc glVertexBlendEnvi*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glVertexBlendEnvi".}
+proc glVertexBlendEnvf*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glVertexBlendEnvf".}
+  #***** GL_3DFX_texture_compression_FXT1 *****//
+const 
+  GL_COMPRESSED_RGB_FXT1_3DFX* = 0x000086B0
+  GL_COMPRESSED_RGBA_FXT1_3DFX* = 0x000086B1
+  #***** GL_IBM_cull_vertex *****//
+
+const 
+  GL_CULL_VERTEX_IBM* = 0x0001928A
+  #***** GL_IBM_multimode_draw_arrays *****//
+
+proc glMultiModeDrawArraysIBM*(mode: PGLenum, first: PGLint, count: PGLsizei, 
+                               primcount: TGLsizei, modestride: TGLint){.
+    dynlib: dllname, importc: "glMultiModeDrawArraysIBM".}
+proc glMultiModeDrawElementsIBM*(mode: PGLenum, count: PGLsizei, 
+                                 thetype: TGLenum, indices: PGLvoid, 
+                                 primcount: TGLsizei, modestride: TGLint){.
+    dynlib: dllname, importc: "glMultiModeDrawElementsIBM".}
+  #***** GL_IBM_raster_pos_clip *****//
+const 
+  GL_RASTER_POSITION_UNCLIPPED_IBM* = 0x00019262
+  #***** GL_IBM_texture_mirrored_repeat *****//
+
+const 
+  GL_MIRRORED_REPEAT_IBM* = 0x00008370
+  #***** GL_IBM_vertex_array_lists *****//
+
+const 
+  GL_VERTEX_ARRAY_LIST_IBM* = 0x0001929E
+  GL_NORMAL_ARRAY_LIST_IBM* = 0x0001929F
+  GL_COLOR_ARRAY_LIST_IBM* = 0x000192A0
+  GL_INDEX_ARRAY_LIST_IBM* = 0x000192A1
+  GL_TEXTURE_COORD_ARRAY_LIST_IBM* = 0x000192A2
+  GL_EDGE_FLAG_ARRAY_LIST_IBM* = 0x000192A3
+  GL_FOG_COORDINATE_ARRAY_LIST_IBM* = 0x000192A4
+  GL_SECONDARY_COLOR_ARRAY_LIST_IBM* = 0x000192A5
+  GL_VERTEX_ARRAY_LIST_STRIDE_IBM* = 0x000192A8
+  GL_NORMAL_ARRAY_LIST_STRIDE_IBM* = 0x000192A9
+  GL_COLOR_ARRAY_LIST_STRIDE_IBM* = 0x000192AA
+  GL_INDEX_ARRAY_LIST_STRIDE_IBM* = 0x000192AB
+  GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM* = 0x000192AC
+  GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM* = 0x000192AD
+  GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM* = 0x000192AE
+  GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM* = 0x000192AF
+
+proc glColorPointerListIBM*(size: TGLint, thetype: TGLenum, stride: TGLint, 
+                            pointer: PGLvoid, ptrstride: TGLint){.
+    dynlib: dllname, importc: "glColorPointerListIBM".}
+proc glSecondaryColorPointerListIBM*(size: TGLint, thetype: TGLenum, 
+                                     stride: TGLint, pointer: PGLvoid, 
+                                     ptrstride: TGLint){.dynlib: dllname, 
+    importc: "glSecondaryColorPointerListIBM".}
+proc glEdgeFlagPointerListIBM*(stride: TGLint, pointer: PGLboolean, 
+                               ptrstride: TGLint){.dynlib: dllname, 
+    importc: "glEdgeFlagPointerListIBM".}
+proc glFogCoordPointerListIBM*(thetype: TGLenum, stride: TGLint, 
+                               pointer: PGLvoid, ptrstride: TGLint){.
+    dynlib: dllname, importc: "glFogCoordPointerListIBM".}
+proc glNormalPointerListIBM*(thetype: TGLenum, stride: TGLint, pointer: PGLvoid, 
+                             ptrstride: TGLint){.dynlib: dllname, 
+    importc: "glNormalPointerListIBM".}
+proc glTexCoordPointerListIBM*(size: TGLint, thetype: TGLenum, stride: TGLint, 
+                               pointer: PGLvoid, ptrstride: TGLint){.
+    dynlib: dllname, importc: "glTexCoordPointerListIBM".}
+proc glVertexPointerListIBM*(size: TGLint, thetype: TGLenum, stride: TGLint, 
+                             pointer: PGLvoid, ptrstride: TGLint){.
+    dynlib: dllname, importc: "glVertexPointerListIBM".}
+  #***** GL_MESA_resize_buffers *****//
+proc glResizeBuffersMESA*(){.dynlib: dllname, importc: "glResizeBuffersMESA".}
+  #***** GL_MESA_window_pos *****//
+proc glWindowPos2dMESA*(x: TGLdouble, y: TGLdouble){.dynlib: dllname, 
+    importc: "glWindowPos2dMESA".}
+proc glWindowPos2fMESA*(x: TGLfloat, y: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos2fMESA".}
+proc glWindowPos2iMESA*(x: TGLint, y: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos2iMESA".}
+proc glWindowPos2sMESA*(x: TGLshort, y: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos2sMESA".}
+proc glWindowPos2ivMESA*(p: PGLint){.dynlib: dllname, 
+                                     importc: "glWindowPos2ivMESA".}
+proc glWindowPos2svMESA*(p: PGLshort){.dynlib: dllname, 
+                                       importc: "glWindowPos2svMESA".}
+proc glWindowPos2fvMESA*(p: PGLfloat){.dynlib: dllname, 
+                                       importc: "glWindowPos2fvMESA".}
+proc glWindowPos2dvMESA*(p: PGLdouble){.dynlib: dllname, 
+                                        importc: "glWindowPos2dvMESA".}
+proc glWindowPos3iMESA*(x: TGLint, y: TGLint, z: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos3iMESA".}
+proc glWindowPos3sMESA*(x: TGLshort, y: TGLshort, z: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos3sMESA".}
+proc glWindowPos3fMESA*(x: TGLfloat, y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos3fMESA".}
+proc glWindowPos3dMESA*(x: TGLdouble, y: TGLdouble, z: TGLdouble){.
+    dynlib: dllname, importc: "glWindowPos3dMESA".}
+proc glWindowPos3ivMESA*(p: PGLint){.dynlib: dllname, 
+                                     importc: "glWindowPos3ivMESA".}
+proc glWindowPos3svMESA*(p: PGLshort){.dynlib: dllname, 
+                                       importc: "glWindowPos3svMESA".}
+proc glWindowPos3fvMESA*(p: PGLfloat){.dynlib: dllname, 
+                                       importc: "glWindowPos3fvMESA".}
+proc glWindowPos3dvMESA*(p: PGLdouble){.dynlib: dllname, 
+                                        importc: "glWindowPos3dvMESA".}
+proc glWindowPos4iMESA*(x: TGLint, y: TGLint, z: TGLint, w: TGLint){.
+    dynlib: dllname, importc: "glWindowPos4iMESA".}
+proc glWindowPos4sMESA*(x: TGLshort, y: TGLshort, z: TGLshort, w: TGLshort){.
+    dynlib: dllname, importc: "glWindowPos4sMESA".}
+proc glWindowPos4fMESA*(x: TGLfloat, y: TGLfloat, z: TGLfloat, w: TGLfloat){.
+    dynlib: dllname, importc: "glWindowPos4fMESA".}
+proc glWindowPos4dMESA*(x: TGLdouble, y: TGLdouble, z: TGLdouble, w: TGLdouble){.
+    dynlib: dllname, importc: "glWindowPos4dMESA".}
+proc glWindowPos4ivMESA*(p: PGLint){.dynlib: dllname, 
+                                     importc: "glWindowPos4ivMESA".}
+proc glWindowPos4svMESA*(p: PGLshort){.dynlib: dllname, 
+                                       importc: "glWindowPos4svMESA".}
+proc glWindowPos4fvMESA*(p: PGLfloat){.dynlib: dllname, 
+                                       importc: "glWindowPos4fvMESA".}
+proc glWindowPos4dvMESA*(p: PGLdouble){.dynlib: dllname, 
+                                        importc: "glWindowPos4dvMESA".}
+  #***** GL_OML_interlace *****//
+const 
+  GL_INTERLACE_OML* = 0x00008980
+  GL_INTERLACE_READ_OML* = 0x00008981
+  #***** GL_OML_resample *****//
+
+const 
+  GL_PACK_RESAMPLE_OML* = 0x00008984
+  GL_UNPACK_RESAMPLE_OML* = 0x00008985
+  GL_RESAMPLE_REPLICATE_OML* = 0x00008986
+  GL_RESAMPLE_ZERO_FILL_OML* = 0x00008987
+  GL_RESAMPLE_AVERAGE_OML* = 0x00008988
+  GL_RESAMPLE_DECIMATE_OML* = 0x00008989 # GL_RESAMPLE_AVERAGE_OML  { already defined }
+  #***** GL_OML_subsample *****//
+
+const 
+  GL_FORMAT_SUBSAMPLE_24_24_OML* = 0x00008982
+  GL_FORMAT_SUBSAMPLE_244_244_OML* = 0x00008983
+  #***** GL_SGIS_generate_mipmap *****//
+
+const 
+  GL_GENERATE_MIPMAP_SGIS* = 0x00008191
+  GL_GENERATE_MIPMAP_HINT_SGIS* = 0x00008192
+  #***** GL_SGIS_multisample *****//
+
+const 
+  GLX_SAMPLE_BUFFERS_SGIS* = 0x000186A0
+  GLX_SAMPLES_SGIS* = 0x000186A1
+  GL_MULTISAMPLE_SGIS* = 0x0000809D
+  GL_SAMPLE_ALPHA_TO_MASK_SGIS* = 0x0000809E
+  GL_SAMPLE_ALPHA_TO_ONE_SGIS* = 0x0000809F
+  constGL_SAMPLE_MASK_SGIS* = 0x000080A0
+  GL_MULTISAMPLE_BIT_EXT* = 0x20000000
+  GL_1PASS_SGIS* = 0x000080A1
+  GL_2PASS_0_SGIS* = 0x000080A2
+  GL_2PASS_1_SGIS* = 0x000080A3
+  GL_4PASS_0_SGIS* = 0x000080A4
+  GL_4PASS_1_SGIS* = 0x000080A5
+  GL_4PASS_2_SGIS* = 0x000080A6
+  GL_4PASS_3_SGIS* = 0x000080A7
+  GL_SAMPLE_BUFFERS_SGIS* = 0x000080A8
+  GL_SAMPLES_SGIS* = 0x000080A9
+  GL_SAMPLE_MASK_VALUE_SGIS* = 0x000080AA
+  GL_SAMPLE_MASK_INVERT_SGIS* = 0x000080AB
+  constGL_SAMPLE_PATTERN_SGIS* = 0x000080AC
+
+proc glSampleMaskSGIS*(value: TGLclampf, invert: TGLboolean){.dynlib: dllname, 
+    importc: "glSampleMaskSGIS".}
+proc glSamplePatternSGIS*(pattern: TGLenum){.dynlib: dllname, 
+    importc: "glSamplePatternSGIS".}
+  #***** GL_SGIS_pixel_texture *****//
+const 
+  GL_PIXEL_TEXTURE_SGIS* = 0x00008353
+  GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS* = 0x00008354
+  GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS* = 0x00008355
+  GL_PIXEL_GROUP_COLOR_SGIS* = 0x00008356
+
+proc glPixelTexGenParameteriSGIS*(pname: TGLenum, param: TGLint){.
+    dynlib: dllname, importc: "glPixelTexGenParameteriSGIS".}
+proc glPixelTexGenParameterfSGIS*(pname: TGLenum, param: TGLfloat){.
+    dynlib: dllname, importc: "glPixelTexGenParameterfSGIS".}
+proc glGetPixelTexGenParameterivSGIS*(pname: TGLenum, params: TGLint){.
+    dynlib: dllname, importc: "glGetPixelTexGenParameterivSGIS".}
+proc glGetPixelTexGenParameterfvSGIS*(pname: TGLenum, params: TGLfloat){.
+    dynlib: dllname, importc: "glGetPixelTexGenParameterfvSGIS".}
+  #***** GL_SGIS_texture_border_clamp *****//
+  # GL_CLAMP_TO_BORDER_SGIS  { already defined }
+  #***** GL_SGIS_texture_color_mask *****//
+const 
+  GL_TEXTURE_COLOR_WRITEMASK_SGIS* = 0x000081EF
+
+proc glTextureColorMaskSGIS*(r: TGLboolean, g: TGLboolean, b: TGLboolean, 
+                             a: TGLboolean){.dynlib: dllname, 
+    importc: "glTextureColorMaskSGIS".}
+  #***** GL_SGIS_texture_edge_clamp *****//
+const 
+  GL_CLAMP_TO_EDGE_SGIS* = 0x0000812F
+  #***** GL_SGIS_texture_lod *****//
+
+const 
+  GL_TEXTURE_MIN_LOD_SGIS* = 0x0000813A
+  GL_TEXTURE_MAX_LOD_SGIS* = 0x0000813B
+  GL_TEXTURE_BASE_LEVEL_SGIS* = 0x0000813C
+  GL_TEXTURE_MAX_LEVEL_SGIS* = 0x0000813D
+  #***** GL_SGIS_depth_texture *****//
+
+const 
+  GL_DEPTH_COMPONENT16_SGIX* = 0x000081A5
+  GL_DEPTH_COMPONENT24_SGIX* = 0x000081A6
+  GL_DEPTH_COMPONENT32_SGIX* = 0x000081A7
+  #***** GL_SGIX_fog_offset *****//
+
+const 
+  GL_FOG_OFFSET_SGIX* = 0x00008198
+  GL_FOG_OFFSET_VALUE_SGIX* = 0x00008199
+  #***** GL_SGIX_interlace *****//
+
+const 
+  GL_INTERLACE_SGIX* = 0x00008094
+  #***** GL_SGIX_shadow_ambient *****//
+
+const 
+  GL_SHADOW_AMBIENT_SGIX* = 0x000080BF
+  #***** GL_SGI_color_matrix *****//
+
+const 
+  GL_COLOR_MATRIX_SGI* = 0x000080B1
+  GL_COLOR_MATRIX_STACK_DEPTH_SGI* = 0x000080B2
+  GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI* = 0x000080B3
+  GL_POST_COLOR_MATRIX_RED_SCALE_SGI* = 0x000080B4
+  GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI* = 0x000080B5
+  GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI* = 0x000080B6
+  GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI* = 0x000080B7
+  GL_POST_COLOR_MATRIX_RED_BIAS_SGI* = 0x000080B8
+  GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI* = 0x000080B9
+  GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI* = 0x000080BA
+  GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI* = 0x000080BB
+  #***** GL_SGI_color_table *****//
+
+const 
+  constGL_COLOR_TABLE_SGI* = 0x000080D0
+  GL_POST_CONVOLUTION_COLOR_TABLE_SGI* = 0x000080D1
+  GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI* = 0x000080D2
+  GL_PROXY_COLOR_TABLE_SGI* = 0x000080D3
+  GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI* = 0x000080D4
+  GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI* = 0x000080D5
+  GL_COLOR_TABLE_SCALE_SGI* = 0x000080D6
+  GL_COLOR_TABLE_BIAS_SGI* = 0x000080D7
+  GL_COLOR_TABLE_FORMAT_SGI* = 0x000080D8
+  GL_COLOR_TABLE_WIDTH_SGI* = 0x000080D9
+  GL_COLOR_TABLE_RED_SIZE_SGI* = 0x000080DA
+  GL_COLOR_TABLE_GREEN_SIZE_SGI* = 0x000080DB
+  GL_COLOR_TABLE_BLUE_SIZE_SGI* = 0x000080DC
+  GL_COLOR_TABLE_ALPHA_SIZE_SGI* = 0x000080DD
+  GL_COLOR_TABLE_LUMINANCE_SIZE_SGI* = 0x000080DE
+  GL_COLOR_TABLE_INTENSITY_SIZE_SGI* = 0x000080DF
+
+proc glColorTableSGI*(target: TGLenum, internalformat: TGLenum, width: TGLsizei, 
+                      format: TGLenum, thetype: TGLenum, table: PGLvoid){.
+    dynlib: dllname, importc: "glColorTableSGI".}
+proc glCopyColorTableSGI*(target: TGLenum, internalformat: TGLenum, x: TGLint, 
+                          y: TGLint, width: TGLsizei){.dynlib: dllname, 
+    importc: "glCopyColorTableSGI".}
+proc glColorTableParameterivSGI*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glColorTableParameterivSGI".}
+proc glColorTableParameterfvSGI*(target: TGLenum, pname: TGLenum, 
+                                 params: PGLfloat){.dynlib: dllname, 
+    importc: "glColorTableParameterfvSGI".}
+proc glGetColorTableSGI*(target: TGLenum, format: TGLenum, thetype: TGLenum, 
+                         table: PGLvoid){.dynlib: dllname, 
+    importc: "glGetColorTableSGI".}
+proc glGetColorTableParameterivSGI*(target: TGLenum, pname: TGLenum, 
+                                    params: PGLint){.dynlib: dllname, 
+    importc: "glGetColorTableParameterivSGI".}
+proc glGetColorTableParameterfvSGI*(target: TGLenum, pname: TGLenum, 
+                                    params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetColorTableParameterfvSGI".}
+  #***** GL_SGI_texture_color_table *****//
+const 
+  GL_TEXTURE_COLOR_TABLE_SGI* = 0x000080BC
+  GL_PROXY_TEXTURE_COLOR_TABLE_SGI* = 0x000080BD
+  #***** GL_SUN_vertex *****//
+
+proc glColor4ubVertex2fSUN*(r: TGLubyte, g: TGLubyte, b: TGLubyte, a: TGLubyte, 
+                            x: TGLfloat, y: TGLfloat){.dynlib: dllname, 
+    importc: "glColor4ubVertex2fSUN".}
+proc glColor4ubVertex2fvSUN*(c: PGLubyte, v: PGLfloat){.dynlib: dllname, 
+    importc: "glColor4ubVertex2fvSUN".}
+proc glColor4ubVertex3fSUN*(r: TGLubyte, g: TGLubyte, b: TGLubyte, a: TGLubyte, 
+                            x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glColor4ubVertex3fSUN".}
+proc glColor4ubVertex3fvSUN*(c: PGLubyte, v: PGLfloat){.dynlib: dllname, 
+    importc: "glColor4ubVertex3fvSUN".}
+proc glColor3fVertex3fSUN*(r: TGLfloat, g: TGLfloat, b: TGLfloat, x: TGLfloat, 
+                           y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glColor3fVertex3fSUN".}
+proc glColor3fVertex3fvSUN*(c: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glColor3fVertex3fvSUN".}
+proc glNormal3fVertex3fSUN*(nx: TGLfloat, ny: TGLfloat, nz: TGLfloat, 
+                            x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glNormal3fVertex3fSUN".}
+proc glNormal3fVertex3fvSUN*(n: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glNormal3fVertex3fvSUN".}
+proc glColor4fNormal3fVertex3fSUN*(r: TGLfloat, g: TGLfloat, b: TGLfloat, 
+                                   a: TGLfloat, nx: TGLfloat, ny: TGLfloat, 
+                                   nz: TGLfloat, x: TGLfloat, y: TGLfloat, 
+                                   z: TGLfloat){.dynlib: dllname, 
+    importc: "glColor4fNormal3fVertex3fSUN".}
+proc glColor4fNormal3fVertex3fvSUN*(c: PGLfloat, n: PGLfloat, v: PGLfloat){.
+    dynlib: dllname, importc: "glColor4fNormal3fVertex3fvSUN".}
+proc glTexCoord2fVertex3fSUN*(s: TGLfloat, t: TGLfloat, x: TGLfloat, 
+                              y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord2fVertex3fSUN".}
+proc glTexCoord2fVertex3fvSUN*(tc: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord2fVertex3fvSUN".}
+proc glTexCoord4fVertex4fSUN*(s: TGLfloat, t: TGLfloat, p: TGLfloat, 
+                              q: TGLfloat, x: TGLfloat, y: TGLfloat, 
+                              z: TGLfloat, w: TGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord4fVertex4fSUN".}
+proc glTexCoord4fVertex4fvSUN*(tc: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord4fVertex4fvSUN".}
+proc glTexCoord2fColor4ubVertex3fSUN*(s: TGLfloat, t: TGLfloat, r: TGLubyte, 
+                                      g: TGLubyte, b: TGLubyte, a: TGLubyte, 
+                                      x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fColor4ubVertex3fSUN".}
+proc glTexCoord2fColor4ubVertex3fvSUN*(tc: PGLfloat, c: PGLubyte, v: PGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fColor4ubVertex3fvSUN".}
+proc glTexCoord2fColor3fVertex3fSUN*(s: TGLfloat, t: TGLfloat, r: TGLfloat, 
+                                     g: TGLfloat, b: TGLfloat, x: TGLfloat, 
+                                     y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord2fColor3fVertex3fSUN".}
+proc glTexCoord2fColor3fVertex3fvSUN*(tc: PGLfloat, c: PGLfloat, v: PGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fColor3fVertex3fvSUN".}
+proc glTexCoord2fNormal3fVertex3fSUN*(s: TGLfloat, t: TGLfloat, nx: TGLfloat, 
+                                      ny: TGLfloat, nz: TGLfloat, x: TGLfloat, 
+                                      y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fNormal3fVertex3fSUN".}
+proc glTexCoord2fNormal3fVertex3fvSUN*(tc: PGLfloat, n: PGLfloat, v: PGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fNormal3fVertex3fvSUN".}
+proc glTexCoord2fColor4fNormal3fVertex3fSUN*(s: TGLfloat, t: TGLfloat, 
+    r: TGLfloat, g: TGLfloat, b: TGLfloat, a: TGLfloat, nx: TGLfloat, 
+    ny: TGLfloat, nz: TGLfloat, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glTexCoord2fColor4fNormal3fVertex3fSUN".}
+proc glTexCoord2fColor4fNormal3fVertex3fvSUN*(tc: PGLfloat, c: PGLfloat, 
+    n: PGLfloat, v: PGLfloat){.dynlib: dllname, importc: "glTexCoord2fColor4fNormal3fVertex3fvSUN".}
+proc glTexCoord4fColor4fNormal3fVertex4fSUN*(s: TGLfloat, t: TGLfloat, 
+    p: TGLfloat, q: TGLfloat, r: TGLfloat, g: TGLfloat, b: TGLfloat, 
+    a: TGLfloat, nx: TGLfloat, ny: TGLfloat, nz: TGLfloat, x: TGLfloat, 
+    y: TGLfloat, z: TGLfloat, w: TGLfloat){.dynlib: dllname, 
+    importc: "glTexCoord4fColor4fNormal3fVertex4fSUN".}
+proc glTexCoord4fColor4fNormal3fVertex4fvSUN*(tc: PGLfloat, c: PGLfloat, 
+    n: PGLfloat, v: PGLfloat){.dynlib: dllname, importc: "glTexCoord4fColor4fNormal3fVertex4fvSUN".}
+proc glReplacementCodeuiVertex3fSUN*(rc: TGLuint, x: TGLfloat, y: TGLfloat, 
+                                     z: TGLfloat){.dynlib: dllname, 
+    importc: "glReplacementCodeuiVertex3fSUN".}
+proc glReplacementCodeuiVertex3fvSUN*(rc: PGLuint, v: PGLfloat){.
+    dynlib: dllname, importc: "glReplacementCodeuiVertex3fvSUN".}
+proc glReplacementCodeuiColor4ubVertex3fSUN*(rc: TGLuint, r: TGLubyte, 
+    g: TGLubyte, b: TGLubyte, a: TGLubyte, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glReplacementCodeuiColor4ubVertex3fSUN".}
+proc glReplacementCodeuiColor4ubVertex3fvSUN*(rc: PGLuint, c: PGLubyte, 
+    v: PGLfloat){.dynlib: dllname, 
+                  importc: "glReplacementCodeuiColor4ubVertex3fvSUN".}
+proc glReplacementCodeuiColor3fVertex3fSUN*(rc: TGLuint, r: TGLfloat, 
+    g: TGLfloat, b: TGLfloat, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glReplacementCodeuiColor3fVertex3fSUN".}
+proc glReplacementCodeuiColor3fVertex3fvSUN*(rc: PGLuint, c: PGLfloat, 
+    v: PGLfloat){.dynlib: dllname, 
+                  importc: "glReplacementCodeuiColor3fVertex3fvSUN".}
+proc glReplacementCodeuiNormal3fVertex3fSUN*(rc: TGLuint, nx: TGLfloat, 
+    ny: TGLfloat, nz: TGLfloat, x: TGLfloat, y: TGLfloat, z: TGLfloat){.
+    dynlib: dllname, importc: "glReplacementCodeuiNormal3fVertex3fSUN".}
+proc glReplacementCodeuiNormal3fVertex3fvSUN*(rc: PGLuint, n: PGLfloat, 
+    v: PGLfloat){.dynlib: dllname, 
+                  importc: "glReplacementCodeuiNormal3fVertex3fvSUN".}
+proc glReplacementCodeuiColor4fNormal3fVertex3fSUN*(rc: TGLuint, r: TGLfloat, 
+    g: TGLfloat, b: TGLfloat, a: TGLfloat, nx: TGLfloat, ny: TGLfloat, 
+    nz: TGLfloat, x: TGLfloat, y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glReplacementCodeuiColor4fNormal3fVertex3fSUN".}
+proc glReplacementCodeuiColor4fNormal3fVertex3fvSUN*(rc: PGLuint, c: PGLfloat, 
+    n: PGLfloat, v: PGLfloat){.dynlib: dllname, importc: "glReplacementCodeuiColor4fNormal3fVertex3fvSUN".}
+proc glReplacementCodeuiTexCoord2fVertex3fSUN*(rc: TGLuint, s: TGLfloat, 
+    t: TGLfloat, x: TGLfloat, y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glReplacementCodeuiTexCoord2fVertex3fSUN".}
+proc glReplacementCodeuiTexCoord2fVertex3fvSUN*(rc: PGLuint, tc: PGLfloat, 
+    v: PGLfloat){.dynlib: dllname, 
+                  importc: "glReplacementCodeuiTexCoord2fVertex3fvSUN".}
+proc glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN*(rc: TGLuint, s: TGLfloat, 
+    t: TGLfloat, nx: TGLfloat, ny: TGLfloat, nz: TGLfloat, x: TGLfloat, 
+    y: TGLfloat, z: TGLfloat){.dynlib: dllname, importc: "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN".}
+proc glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN*(rc: PGLuint, 
+    tc: PGLfloat, n: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN".}
+proc glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN*(rc: TGLuint, 
+    s: TGLfloat, t: TGLfloat, r: TGLfloat, g: TGLfloat, b: TGLfloat, 
+    a: TGLfloat, nx: TGLfloat, ny: TGLfloat, nz: TGLfloat, x: TGLfloat, 
+    y: TGLfloat, z: TGLfloat){.dynlib: dllname, importc: "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN".}
+proc glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN*(rc: PGLuint, 
+    tc: PGLfloat, c: PGLfloat, n: PGLfloat, v: PGLfloat){.dynlib: dllname, 
+    importc: "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN".}
+  #***** GL_ARB_fragment_program *****//
+const 
+  GL_FRAGMENT_PROGRAM_ARB* = 0x00008804 # GL_PROGRAM_FORMAT_ASCII_ARB  { already defined }
+                                        # GL_PROGRAM_LENGTH_ARB  { already defined }
+                                        # GL_PROGRAM_FORMAT_ARB  { already defined }
+                                        # GL_PROGRAM_BINDING_ARB  { already defined }
+                                        # GL_PROGRAM_INSTRUCTIONS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_INSTRUCTIONS_ARB  { already defined }
+                                        # GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB  { already defined }
+                                        # GL_PROGRAM_TEMPORARIES_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_TEMPORARIES_ARB  { already defined }
+                                        # GL_PROGRAM_NATIVE_TEMPORARIES_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB  { already defined }
+                                        # GL_PROGRAM_PARAMETERS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_PARAMETERS_ARB  { already defined }
+                                        # GL_PROGRAM_NATIVE_PARAMETERS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB  { already defined }
+                                        # GL_PROGRAM_ATTRIBS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_ATTRIBS_ARB  { already defined }
+                                        # GL_PROGRAM_NATIVE_ATTRIBS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB  { already defined }
+                                        # GL_MAX_PROGRAM_ENV_PARAMETERS_ARB  { already defined }
+                                        # GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB  { already defined }
+  GL_PROGRAM_ALU_INSTRUCTIONS_ARB* = 0x00008805
+  GL_PROGRAM_TEX_INSTRUCTIONS_ARB* = 0x00008806
+  GL_PROGRAM_TEX_INDIRECTIONS_ARB* = 0x00008807
+  GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB* = 0x00008808
+  GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB* = 0x00008809
+  GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB* = 0x0000880A
+  GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB* = 0x0000880B
+  GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB* = 0x0000880C
+  GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB* = 0x0000880D
+  GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB* = 0x0000880E
+  GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB* = 0x0000880F
+  GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB* = 0x00008810 # GL_PROGRAM_STRING_ARB  { already defined }
+                                                           # 
+                                                           # 
+                                                           # GL_PROGRAM_ERROR_POSITION_ARB  { already defined }
+                                                           # GL_CURRENT_MATRIX_ARB  { already defined }
+                                                           # 
+                                                           # 
+                                                           # GL_TRANSPOSE_CURRENT_MATRIX_ARB  { already defined }
+                                                           # 
+                                                           # 
+                                                           # GL_CURRENT_MATRIX_STACK_DEPTH_ARB  { already defined }
+                                                           # 
+                                                           # 
+                                                           # GL_MAX_PROGRAM_MATRICES_ARB  { already defined }
+                                                           # 
+                                                           # 
+                                                           # GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB  { already defined }
+  GL_MAX_TEXTURE_COORDS_ARB* = 0x00008871
+  GL_MAX_TEXTURE_IMAGE_UNITS_ARB* = 0x00008872 # GL_PROGRAM_ERROR_STRING_ARB  { already defined }
+                                               # GL_MATRIX0_ARB  { already defined }
+                                               # GL_MATRIX1_ARB  { already defined }
+                                               # GL_MATRIX2_ARB  { already defined }
+                                               # GL_MATRIX3_ARB  { already defined }
+                                               # GL_MATRIX4_ARB  { already defined }
+                                               # GL_MATRIX5_ARB  { already defined }
+                                               # GL_MATRIX6_ARB  { already defined }
+                                               # GL_MATRIX7_ARB  { already defined }
+                                               # GL_MATRIX8_ARB  { already defined }
+                                               # GL_MATRIX9_ARB  { already defined }
+                                               # GL_MATRIX10_ARB  { already defined }
+                                               # GL_MATRIX11_ARB  { already defined }
+                                               # GL_MATRIX12_ARB  { already defined }
+                                               # GL_MATRIX13_ARB  { already defined }
+                                               # GL_MATRIX14_ARB  { already defined }
+                                               # GL_MATRIX15_ARB  { already defined }
+                                               # GL_MATRIX16_ARB  { already defined }
+                                               # GL_MATRIX17_ARB  { already defined }
+                                               # GL_MATRIX18_ARB  { already defined }
+                                               # GL_MATRIX19_ARB  { already defined }
+                                               # GL_MATRIX20_ARB  { already defined }
+                                               # GL_MATRIX21_ARB  { already defined }
+                                               # GL_MATRIX22_ARB  { already defined }
+                                               # GL_MATRIX23_ARB  { already defined }
+                                               # GL_MATRIX24_ARB  { already defined }
+                                               # GL_MATRIX25_ARB  { already defined }
+                                               # GL_MATRIX26_ARB  { already defined }
+                                               # GL_MATRIX27_ARB  { already defined }
+                                               # GL_MATRIX28_ARB  { already defined }
+                                               # GL_MATRIX29_ARB  { already defined }
+                                               # GL_MATRIX30_ARB  { already defined }
+                                               # GL_MATRIX31_ARB  { already defined }
+                                               # glProgramStringARB  { already defined }
+                                               # glBindProgramARB  { already defined }
+                                               # glDeleteProgramsARB  { already defined }
+                                               # glGenProgramsARB  { already defined }
+                                               # glProgramEnvParameter4dARB  { already defined }
+                                               # glProgramEnvParameter4dvARB  { already defined }
+                                               # glProgramEnvParameter4fARB  { already defined }
+                                               # glProgramEnvParameter4fvARB  { already defined }
+                                               # glProgramLocalParameter4dARB  { already defined }
+                                               # glProgramLocalParameter4dvARB  { already defined }
+                                               # glProgramLocalParameter4fARB  { already defined }
+                                               # glProgramLocalParameter4fvARB  { already defined }
+                                               # glGetProgramEnvParameterdvARB  { already defined }
+                                               # glGetProgramEnvParameterfvARB  { already defined }
+                                               # glGetProgramLocalParameterdvARB  { already defined }
+                                               # glGetProgramLocalParameterfvARB  { already defined }
+                                               # glGetProgramivARB  { already defined }
+                                               # glGetProgramStringARB  { already defined }
+                                               # glIsProgramARB  { already defined }
+  #***** GL_ATI_text_fragment_shader *****
+
+const 
+  GL_TEXT_FRAGMENT_SHADER_ATI* = 0x00008200 #***** GL_ARB_vertex_buffer_object *****
+
+const 
+  GL_BUFFER_SIZE_ARB* = 0x00008764
+  GL_BUFFER_USAGE_ARB* = 0x00008765
+  GL_ARRAY_BUFFER_ARB* = 0x00008892
+  GL_ELEMENT_ARRAY_BUFFER_ARB* = 0x00008893
+  GL_ARRAY_BUFFER_BINDING_ARB* = 0x00008894
+  GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB* = 0x00008895
+  GL_VERTEX_ARRAY_BUFFER_BINDING_ARB* = 0x00008896
+  GL_NORMAL_ARRAY_BUFFER_BINDING_ARB* = 0x00008897
+  GL_COLOR_ARRAY_BUFFER_BINDING_ARB* = 0x00008898
+  GL_INDEX_ARRAY_BUFFER_BINDING_ARB* = 0x00008899
+  GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB* = 0x0000889A
+  GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB* = 0x0000889B
+  GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB* = 0x0000889C
+  GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB* = 0x0000889D
+  GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB* = 0x0000889E
+  GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB* = 0x0000889F
+  GL_READ_ONLY_ARB* = 0x000088B8
+  GL_WRITE_ONLY_ARB* = 0x000088B9
+  GL_READ_WRITE_ARB* = 0x000088BA
+  GL_BUFFER_ACCESS_ARB* = 0x000088BB
+  GL_BUFFER_MAPPED_ARB* = 0x000088BC
+  GL_BUFFER_MAP_POINTER_ARB* = 0x000088BD
+  GL_STREAM_DRAW_ARB* = 0x000088E0
+  GL_STREAM_READ_ARB* = 0x000088E1
+  GL_STREAM_COPY_ARB* = 0x000088E2
+  GL_STATIC_DRAW_ARB* = 0x000088E4
+  GL_STATIC_READ_ARB* = 0x000088E5
+  GL_STATIC_COPY_ARB* = 0x000088E6
+  GL_DYNAMIC_DRAW_ARB* = 0x000088E8
+  GL_DYNAMIC_READ_ARB* = 0x000088E9
+  GL_DYNAMIC_COPY_ARB* = 0x000088EA
+
+proc glBindBufferARB*(target: TGLenum, buffer: TGLuint){.dynlib: dllname, 
+    importc: "glBindBufferARB".}
+proc glDeleteBuffersARB*(n: TGLsizei, buffers: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteBuffersARB".}
+proc glGenBuffersARB*(n: TGLsizei, buffers: PGLuint){.dynlib: dllname, 
+    importc: "glGenBuffersARB".}
+proc glIsBufferARB*(buffer: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsBufferARB".}
+proc glBufferDataARB*(target: TGLenum, size: TGLsizei, data: PGLvoid, 
+                      usage: TGLenum){.dynlib: dllname, 
+                                       importc: "glBufferDataARB".}
+proc glBufferSubDataARB*(target: TGLenum, offset: TGLint, size: TGLsizei, 
+                         data: PGLvoid){.dynlib: dllname, 
+    importc: "glBufferSubDataARB".}
+proc glGetBufferSubDataARB*(target: TGLenum, offset: TGLint, size: TGLsizei, 
+                            data: PGLvoid){.dynlib: dllname, 
+    importc: "glGetBufferSubDataARB".}
+proc glMapBufferARB*(target: TGLenum, access: TGLenum): PGLvoid{.
+    dynlib: dllname, importc: "glMapBufferARB".}
+proc glUnmapBufferARB*(target: TGLenum): TGLboolean{.dynlib: dllname, 
+    importc: "glUnmapBufferARB".}
+proc glGetBufferParameterivARB*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetBufferParameterivARB".}
+proc glGetBufferPointervARB*(target: TGLenum, pname: TGLenum, params: PPGLvoid){.
+    dynlib: dllname, importc: "glGetBufferPointervARB".}
+  #***** GL_APPLE_client_storage *****//
+const 
+  GL_UNPACK_CLIENT_STORAGE_APPLE* = 0x000085B2
+  #***** GL_APPLE_element_array *****//
+
+const 
+  GL_ELEMENT_ARRAY_APPLE* = 0x00008768
+  GL_ELEMENT_ARRAY_TYPE_APPLE* = 0x00008769
+  GL_ELEMENT_ARRAY_POINTER_APPLE* = 0x0000876A
+
+proc glElementPointerAPPLE*(thetype: TGLenum, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glElementPointerAPPLE".}
+proc glDrawElementArrayAPPLE*(mode: TGLenum, first: TGLint, count: TGLsizei){.
+    dynlib: dllname, importc: "glDrawElementArrayAPPLE".}
+proc glDrawRangeElementArrayAPPLE*(mode: TGLenum, start: TGLuint, 
+                                   theend: TGLuint, first: TGLint, 
+                                   count: TGLsizei){.dynlib: dllname, 
+    importc: "glDrawRangeElementArrayAPPLE".}
+proc glMultiDrawElementArrayAPPLE*(mode: TGLenum, first: PGLint, 
+                                   count: PGLsizei, primcount: TGLsizei){.
+    dynlib: dllname, importc: "glMultiDrawElementArrayAPPLE".}
+proc glMultiDrawRangeElementArrayAPPLE*(mode: TGLenum, start: TGLuint, 
+                                        theend: TGLuint, first: PGLint, 
+                                        count: PGLsizei, primcount: TGLsizei){.
+    dynlib: dllname, importc: "glMultiDrawRangeElementArrayAPPLE".}
+  #***** GL_APPLE_fence *****//
+const 
+  GL_DRAW_PIXELS_APPLE* = 0x00008A0A
+  GL_FENCE_APPLE* = 0x00008A0B
+
+proc glGenFencesAPPLE*(n: TGLsizei, fences: PGLuint){.dynlib: dllname, 
+    importc: "glGenFencesAPPLE".}
+proc glDeleteFencesAPPLE*(n: TGLsizei, fences: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteFencesAPPLE".}
+proc glSetFenceAPPLE*(fence: TGLuint){.dynlib: dllname, 
+                                       importc: "glSetFenceAPPLE".}
+proc glIsFenceAPPLE*(fence: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsFenceAPPLE".}
+proc glTestFenceAPPLE*(fence: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glTestFenceAPPLE".}
+proc glFinishFenceAPPLE*(fence: TGLuint){.dynlib: dllname, 
+    importc: "glFinishFenceAPPLE".}
+proc glTestObjectAPPLE*(theobject: TGLenum, name: TGLuint): TGLboolean{.
+    dynlib: dllname, importc: "glTestObjectAPPLE".}
+proc glFinishObjectAPPLE*(theobject: TGLenum, name: TGLint){.dynlib: dllname, 
+    importc: "glFinishObjectAPPLE".}
+  #***** GL_APPLE_vertex_array_object *****//
+const 
+  GL_VERTEX_ARRAY_BINDING_APPLE* = 0x000085B5
+
+proc glBindVertexArrayAPPLE*(thearray: TGLuint){.dynlib: dllname, 
+    importc: "glBindVertexArrayAPPLE".}
+proc glDeleteVertexArraysAPPLE*(n: TGLsizei, arrays: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteVertexArraysAPPLE".}
+proc glGenVertexArraysAPPLE*(n: TGLsizei, arrays: PGLuint){.dynlib: dllname, 
+    importc: "glGenVertexArraysAPPLE".}
+proc glIsVertexArrayAPPLE*(thearray: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsVertexArrayAPPLE".}
+  #***** GL_APPLE_vertex_array_range *****//
+const 
+  constGL_VERTEX_ARRAY_RANGE_APPLE* = 0x0000851D
+  GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE* = 0x0000851E
+  GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE* = 0x00008520
+  GL_VERTEX_ARRAY_RANGE_POINTER_APPLE* = 0x00008521
+  GL_VERTEX_ARRAY_STORAGE_HINT_APPLE* = 0x0000851F
+  GL_STORAGE_CACHED_APPLE* = 0x000085BE
+  GL_STORAGE_SHARED_APPLE* = 0x000085BF
+
+proc glVertexArrayRangeAPPLE*(len: TGLsizei, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glVertexArrayRangeAPPLE".}
+proc glFlushVertexArrayRangeAPPLE*(len: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glFlushVertexArrayRangeAPPLE".}
+proc glVertexArrayParameteriAPPLE*(pname: TGLenum, param: TGLint){.
+    dynlib: dllname, importc: "glVertexArrayParameteriAPPLE".}
+  #***** GL_ARB_matrix_palette *****//
+const 
+  GL_MATRIX_PALETTE_ARB* = 0x00008840
+  GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB* = 0x00008841
+  GL_MAX_PALETTE_MATRICES_ARB* = 0x00008842
+  constGL_CURRENT_PALETTE_MATRIX_ARB* = 0x00008843
+  GL_MATRIX_INDEX_ARRAY_ARB* = 0x00008844
+  GL_CURRENT_MATRIX_INDEX_ARB* = 0x00008845
+  GL_MATRIX_INDEX_ARRAY_SIZE_ARB* = 0x00008846
+  GL_MATRIX_INDEX_ARRAY_TYPE_ARB* = 0x00008847
+  GL_MATRIX_INDEX_ARRAY_STRIDE_ARB* = 0x00008848
+  GL_MATRIX_INDEX_ARRAY_POINTER_ARB* = 0x00008849
+
+proc glCurrentPaletteMatrixARB*(index: TGLint){.dynlib: dllname, 
+    importc: "glCurrentPaletteMatrixARB".}
+proc glMatrixIndexubvARB*(size: TGLint, indices: PGLubyte){.dynlib: dllname, 
+    importc: "glMatrixIndexubvARB".}
+proc glMatrixIndexusvARB*(size: TGLint, indices: PGLushort){.dynlib: dllname, 
+    importc: "glMatrixIndexusvARB".}
+proc glMatrixIndexuivARB*(size: TGLint, indices: PGLuint){.dynlib: dllname, 
+    importc: "glMatrixIndexuivARB".}
+proc glMatrixIndexPointerARB*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                              pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glMatrixIndexPointerARB".}
+  #***** GL_NV_element_array *****//
+const 
+  GL_ELEMENT_ARRAY_TYPE_NV* = 0x00008769
+  GL_ELEMENT_ARRAY_POINTER_NV* = 0x0000876A
+
+proc glElementPointerNV*(thetype: TGLenum, pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glElementPointerNV".}
+proc glDrawElementArrayNV*(mode: TGLenum, first: TGLint, count: TGLsizei){.
+    dynlib: dllname, importc: "glDrawElementArrayNV".}
+proc glDrawRangeElementArrayNV*(mode: TGLenum, start: TGLuint, theend: TGLuint, 
+                                first: TGLint, count: TGLsizei){.
+    dynlib: dllname, importc: "glDrawRangeElementArrayNV".}
+proc glMultiDrawElementArrayNV*(mode: TGLenum, first: PGLint, count: PGLsizei, 
+                                primcount: TGLsizei){.dynlib: dllname, 
+    importc: "glMultiDrawElementArrayNV".}
+proc glMultiDrawRangeElementArrayNV*(mode: TGLenum, start: TGLuint, 
+                                     theend: TGLuint, first: PGLint, 
+                                     count: PGLsizei, primcount: TGLsizei){.
+    dynlib: dllname, importc: "glMultiDrawRangeElementArrayNV".}
+  #***** GL_NV_float_buffer *****//
+const 
+  GL_FLOAT_R_NV* = 0x00008880
+  GL_FLOAT_RG_NV* = 0x00008881
+  GL_FLOAT_RGB_NV* = 0x00008882
+  GL_FLOAT_RGBA_NV* = 0x00008883
+  GL_FLOAT_R16_NV* = 0x00008884
+  GL_FLOAT_R32_NV* = 0x00008885
+  GL_FLOAT_RG16_NV* = 0x00008886
+  GL_FLOAT_RG32_NV* = 0x00008887
+  GL_FLOAT_RGB16_NV* = 0x00008888
+  GL_FLOAT_RGB32_NV* = 0x00008889
+  GL_FLOAT_RGBA16_NV* = 0x0000888A
+  GL_FLOAT_RGBA32_NV* = 0x0000888B
+  GL_TEXTURE_FLOAT_COMPONENTS_NV* = 0x0000888C
+  GL_FLOAT_CLEAR_COLOR_VALUE_NV* = 0x0000888D
+  GL_FLOAT_RGBA_MODE_NV* = 0x0000888E
+  #***** GL_NV_fragment_program *****//
+
+const 
+  GL_FRAGMENT_PROGRAM_NV* = 0x00008870
+  GL_MAX_TEXTURE_COORDS_NV* = 0x00008871
+  GL_MAX_TEXTURE_IMAGE_UNITS_NV* = 0x00008872
+  GL_FRAGMENT_PROGRAM_BINDING_NV* = 0x00008873
+  GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV* = 0x00008868
+  GL_PROGRAM_ERROR_STRING_NV* = 0x00008874
+
+proc glProgramNamedParameter4fNV*(id: TGLuint, length: TGLsizei, name: PGLubyte, 
+                                  x: TGLfloat, y: TGLfloat, z: TGLfloat, 
+                                  w: TGLfloat){.dynlib: dllname, 
+    importc: "glProgramNamedParameter4fNV".}
+proc glProgramNamedParameter4dNV*(id: TGLuint, length: TGLsizei, name: PGLubyte, 
+                                  x: TGLdouble, y: TGLdouble, z: TGLdouble, 
+                                  w: TGLdouble){.dynlib: dllname, 
+    importc: "glProgramNamedParameter4dNV".}
+proc glGetProgramNamedParameterfvNV*(id: TGLuint, length: TGLsizei, 
+                                     name: PGLubyte, params: PGLfloat){.
+    dynlib: dllname, importc: "glGetProgramNamedParameterfvNV".}
+proc glGetProgramNamedParameterdvNV*(id: TGLuint, length: TGLsizei, 
+                                     name: PGLubyte, params: PGLdouble){.
+    dynlib: dllname, importc: "glGetProgramNamedParameterdvNV".}
+  # glProgramLocalParameter4dARB  { already defined }
+  # glProgramLocalParameter4dvARB  { already defined }
+  # glProgramLocalParameter4fARB  { already defined }
+  # glProgramLocalParameter4fvARB  { already defined }
+  # glGetProgramLocalParameterdvARB  { already defined }
+  # glGetProgramLocalParameterfvARB  { already defined }
+  #***** GL_NV_primitive_restart *****//
+const 
+  constGL_PRIMITIVE_RESTART_NV* = 0x00008558
+  constGL_PRIMITIVE_RESTART_INDEX_NV* = 0x00008559
+
+proc glPrimitiveRestartNV*(){.dynlib: dllname, importc: "glPrimitiveRestartNV".}
+proc glPrimitiveRestartIndexNV*(index: TGLuint){.dynlib: dllname, 
+    importc: "glPrimitiveRestartIndexNV".}
+  #***** GL_NV_vertex_program2 *****//
+  #***** GL_NV_pixel_data_range *****//
+const 
+  GL_WRITE_PIXEL_DATA_RANGE_NV* = 0x00008878
+  GL_READ_PIXEL_DATA_RANGE_NV* = 0x00008879
+  GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV* = 0x0000887A
+  GL_READ_PIXEL_DATA_RANGE_LENGTH_NV* = 0x0000887B
+  GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV* = 0x0000887C
+  GL_READ_PIXEL_DATA_RANGE_POINTER_NV* = 0x0000887D
+
+proc glPixelDataRangeNV*(target: TGLenum, len: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glPixelDataRangeNV".}
+proc glFlushPixelDataRangeNV*(target: TGLenum){.dynlib: dllname, 
+    importc: "glFlushPixelDataRangeNV".}
+  # wglAllocateMemoryNV  { already defined }
+  # wglFreeMemoryNV  { already defined }
+  #***** GL_EXT_texture_rectangle *****//
+const 
+  GL_TEXTURE_RECTANGLE_EXT* = 0x000084F5
+  GL_TEXTURE_BINDING_RECTANGLE_EXT* = 0x000084F6
+  GL_PROXY_TEXTURE_RECTANGLE_EXT* = 0x000084F7
+  GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT* = 0x000084F8
+  #***** GL_S3_s3tc *****//
+
+const 
+  GL_RGB_S3TC* = 0x000083A0
+  GL_RGB4_S3TC* = 0x000083A1
+  GL_RGBA_S3TC* = 0x000083A2
+  GL_RGBA4_S3TC* = 0x000083A3
+  #***** GL_ATI_draw_buffers *****//
+
+const 
+  GL_MAX_DRAW_BUFFERS_ATI* = 0x00008824
+  GL_DRAW_BUFFER0_ATI* = 0x00008825
+  GL_DRAW_BUFFER1_ATI* = 0x00008826
+  GL_DRAW_BUFFER2_ATI* = 0x00008827
+  GL_DRAW_BUFFER3_ATI* = 0x00008828
+  GL_DRAW_BUFFER4_ATI* = 0x00008829
+  GL_DRAW_BUFFER5_ATI* = 0x0000882A
+  GL_DRAW_BUFFER6_ATI* = 0x0000882B
+  GL_DRAW_BUFFER7_ATI* = 0x0000882C
+  GL_DRAW_BUFFER8_ATI* = 0x0000882D
+  GL_DRAW_BUFFER9_ATI* = 0x0000882E
+  GL_DRAW_BUFFER10_ATI* = 0x0000882F
+  GL_DRAW_BUFFER11_ATI* = 0x00008830
+  GL_DRAW_BUFFER12_ATI* = 0x00008831
+  GL_DRAW_BUFFER13_ATI* = 0x00008832
+  GL_DRAW_BUFFER14_ATI* = 0x00008833
+  GL_DRAW_BUFFER15_ATI* = 0x00008834
+
+proc glDrawBuffersATI*(n: TGLsizei, bufs: PGLenum){.dynlib: dllname, 
+    importc: "glDrawBuffersATI".}
+  #***** GL_ATI_texture_env_combine3 *****//
+const 
+  GL_MODULATE_ADD_ATI* = 0x00008744
+  GL_MODULATE_SIGNED_ADD_ATI* = 0x00008745
+  GL_MODULATE_SUBTRACT_ATI* = 0x00008746
+  #***** GL_ATI_texture_float *****//
+
+const 
+  GL_RGBA_FLOAT32_ATI* = 0x00008814
+  GL_RGB_FLOAT32_ATI* = 0x00008815
+  GL_ALPHA_FLOAT32_ATI* = 0x00008816
+  GL_INTENSITY_FLOAT32_ATI* = 0x00008817
+  GL_LUMINANCE_FLOAT32_ATI* = 0x00008818
+  GL_LUMINANCE_ALPHA_FLOAT32_ATI* = 0x00008819
+  GL_RGBA_FLOAT16_ATI* = 0x0000881A
+  GL_RGB_FLOAT16_ATI* = 0x0000881B
+  GL_ALPHA_FLOAT16_ATI* = 0x0000881C
+  GL_INTENSITY_FLOAT16_ATI* = 0x0000881D
+  GL_LUMINANCE_FLOAT16_ATI* = 0x0000881E
+  GL_LUMINANCE_ALPHA_FLOAT16_ATI* = 0x0000881F
+  #***** GL_NV_texture_expand_normal *****//
+
+const 
+  GL_TEXTURE_UNSIGNED_REMAP_MODE_NV* = 0x0000888F
+  #***** GL_NV_half_float *****//
+
+const 
+  GL_HALF_FLOAT_NV* = 0x0000140B
+
+proc glVertex2hNV*(x: TGLushort, y: TGLushort){.dynlib: dllname, 
+    importc: "glVertex2hNV".}
+proc glVertex2hvNV*(v: PGLushort){.dynlib: dllname, importc: "glVertex2hvNV".}
+proc glVertex3hNV*(x: TGLushort, y: TGLushort, z: TGLushort){.dynlib: dllname, 
+    importc: "glVertex3hNV".}
+proc glVertex3hvNV*(v: PGLushort){.dynlib: dllname, importc: "glVertex3hvNV".}
+proc glVertex4hNV*(x: TGLushort, y: TGLushort, z: TGLushort, w: TGLushort){.
+    dynlib: dllname, importc: "glVertex4hNV".}
+proc glVertex4hvNV*(v: PGLushort){.dynlib: dllname, importc: "glVertex4hvNV".}
+proc glNormal3hNV*(nx: TGLushort, ny: TGLushort, nz: TGLushort){.
+    dynlib: dllname, importc: "glNormal3hNV".}
+proc glNormal3hvNV*(v: PGLushort){.dynlib: dllname, importc: "glNormal3hvNV".}
+proc glColor3hNV*(red: TGLushort, green: TGLushort, blue: TGLushort){.
+    dynlib: dllname, importc: "glColor3hNV".}
+proc glColor3hvNV*(v: PGLushort){.dynlib: dllname, importc: "glColor3hvNV".}
+proc glColor4hNV*(red: TGLushort, green: TGLushort, blue: TGLushort, 
+                  alpha: TGLushort){.dynlib: dllname, importc: "glColor4hNV".}
+proc glColor4hvNV*(v: PGLushort){.dynlib: dllname, importc: "glColor4hvNV".}
+proc glTexCoord1hNV*(s: TGLushort){.dynlib: dllname, importc: "glTexCoord1hNV".}
+proc glTexCoord1hvNV*(v: PGLushort){.dynlib: dllname, importc: "glTexCoord1hvNV".}
+proc glTexCoord2hNV*(s: TGLushort, t: TGLushort){.dynlib: dllname, 
+    importc: "glTexCoord2hNV".}
+proc glTexCoord2hvNV*(v: PGLushort){.dynlib: dllname, importc: "glTexCoord2hvNV".}
+proc glTexCoord3hNV*(s: TGLushort, t: TGLushort, r: TGLushort){.dynlib: dllname, 
+    importc: "glTexCoord3hNV".}
+proc glTexCoord3hvNV*(v: PGLushort){.dynlib: dllname, importc: "glTexCoord3hvNV".}
+proc glTexCoord4hNV*(s: TGLushort, t: TGLushort, r: TGLushort, q: TGLushort){.
+    dynlib: dllname, importc: "glTexCoord4hNV".}
+proc glTexCoord4hvNV*(v: PGLushort){.dynlib: dllname, importc: "glTexCoord4hvNV".}
+proc glMultiTexCoord1hNV*(target: TGLenum, s: TGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1hNV".}
+proc glMultiTexCoord1hvNV*(target: TGLenum, v: PGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord1hvNV".}
+proc glMultiTexCoord2hNV*(target: TGLenum, s: TGLushort, t: TGLushort){.
+    dynlib: dllname, importc: "glMultiTexCoord2hNV".}
+proc glMultiTexCoord2hvNV*(target: TGLenum, v: PGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord2hvNV".}
+proc glMultiTexCoord3hNV*(target: TGLenum, s: TGLushort, t: TGLushort, 
+                          r: TGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord3hNV".}
+proc glMultiTexCoord3hvNV*(target: TGLenum, v: PGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord3hvNV".}
+proc glMultiTexCoord4hNV*(target: TGLenum, s: TGLushort, t: TGLushort, 
+                          r: TGLushort, q: TGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord4hNV".}
+proc glMultiTexCoord4hvNV*(target: TGLenum, v: PGLushort){.dynlib: dllname, 
+    importc: "glMultiTexCoord4hvNV".}
+proc glFogCoordhNV*(fog: TGLushort){.dynlib: dllname, importc: "glFogCoordhNV".}
+proc glFogCoordhvNV*(fog: PGLushort){.dynlib: dllname, importc: "glFogCoordhvNV".}
+proc glSecondaryColor3hNV*(red: TGLushort, green: TGLushort, blue: TGLushort){.
+    dynlib: dllname, importc: "glSecondaryColor3hNV".}
+proc glSecondaryColor3hvNV*(v: PGLushort){.dynlib: dllname, 
+    importc: "glSecondaryColor3hvNV".}
+proc glVertexWeighthNV*(weight: TGLushort){.dynlib: dllname, 
+    importc: "glVertexWeighthNV".}
+proc glVertexWeighthvNV*(weight: PGLushort){.dynlib: dllname, 
+    importc: "glVertexWeighthvNV".}
+proc glVertexAttrib1hNV*(index: TGLuint, x: TGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib1hNV".}
+proc glVertexAttrib1hvNV*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib1hvNV".}
+proc glVertexAttrib2hNV*(index: TGLuint, x: TGLushort, y: TGLushort){.
+    dynlib: dllname, importc: "glVertexAttrib2hNV".}
+proc glVertexAttrib2hvNV*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib2hvNV".}
+proc glVertexAttrib3hNV*(index: TGLuint, x: TGLushort, y: TGLushort, 
+                         z: TGLushort){.dynlib: dllname, 
+                                        importc: "glVertexAttrib3hNV".}
+proc glVertexAttrib3hvNV*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib3hvNV".}
+proc glVertexAttrib4hNV*(index: TGLuint, x: TGLushort, y: TGLushort, 
+                         z: TGLushort, w: TGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4hNV".}
+proc glVertexAttrib4hvNV*(index: TGLuint, v: PGLushort){.dynlib: dllname, 
+    importc: "glVertexAttrib4hvNV".}
+proc glVertexAttribs1hvNV*(index: TGLuint, n: TGLsizei, v: PGLushort){.
+    dynlib: dllname, importc: "glVertexAttribs1hvNV".}
+proc glVertexAttribs2hvNV*(index: TGLuint, n: TGLsizei, v: PGLushort){.
+    dynlib: dllname, importc: "glVertexAttribs2hvNV".}
+proc glVertexAttribs3hvNV*(index: TGLuint, n: TGLsizei, v: PGLushort){.
+    dynlib: dllname, importc: "glVertexAttribs3hvNV".}
+proc glVertexAttribs4hvNV*(index: TGLuint, n: TGLsizei, v: PGLushort){.
+    dynlib: dllname, importc: "glVertexAttribs4hvNV".}
+  #***** GL_ATI_map_object_buffer *****//
+proc glMapObjectBufferATI*(buffer: TGLuint): PGLvoid{.dynlib: dllname, 
+    importc: "glMapObjectBufferATI".}
+proc glUnmapObjectBufferATI*(buffer: TGLuint){.dynlib: dllname, 
+    importc: "glUnmapObjectBufferATI".}
+  #***** GL_ATI_separate_stencil *****//
+const 
+  GL_KEEP* = 0x00001E00
+  GL_ZERO* = 0x00000000
+  GL_REPLACE* = 0x00001E01
+  GL_INCR* = 0x00001E02
+  GL_DECR* = 0x00001E03
+  GL_INVERT* = 0x0000150A
+  GL_NEVER* = 0x00000200
+  GL_LESS* = 0x00000201
+  GL_LEQUAL* = 0x00000203
+  GL_GREATER* = 0x00000204
+  GL_GEQUAL* = 0x00000206
+  GL_EQUAL* = 0x00000202
+  GL_NOTEQUAL* = 0x00000205
+  GL_ALWAYS* = 0x00000207
+  GL_FRONT* = 0x00000404
+  GL_BACK* = 0x00000405
+  GL_FRONT_AND_BACK* = 0x00000408
+  GL_STENCIL_BACK_FUNC_ATI* = 0x00008800
+  GL_STENCIL_BACK_FAIL_ATI* = 0x00008801
+  GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI* = 0x00008802
+  GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI* = 0x00008803
+
+proc glStencilOpSeparateATI*(face: TGLenum, sfail: TGLenum, dpfail: TGLenum, 
+                             dppass: TGLenum){.dynlib: dllname, 
+    importc: "glStencilOpSeparateATI".}
+proc glStencilFuncSeparateATI*(frontfunc: TGLenum, backfunc: TGLenum, 
+                               theRef: TGLint, mask: TGLuint){.dynlib: dllname, 
+    importc: "glStencilFuncSeparateATI".}
+  #***** GL_ATI_vertex_attrib_array_object *****//
+proc glVertexAttribArrayObjectATI*(index: TGLuint, size: TGLint, 
+                                   thetype: TGLenum, normalized: TGLboolean, 
+                                   stride: TGLsizei, buffer: TGLuint, 
+                                   offset: TGLuint){.dynlib: dllname, 
+    importc: "glVertexAttribArrayObjectATI".}
+proc glGetVertexAttribArrayObjectfvATI*(index: TGLuint, pname: TGLenum, 
+                                        params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetVertexAttribArrayObjectfvATI".}
+proc glGetVertexAttribArrayObjectivATI*(index: TGLuint, pname: TGLenum, 
+                                        params: PGLint){.dynlib: dllname, 
+    importc: "glGetVertexAttribArrayObjectivATI".}
+  #***** GL_ARB_occlusion_query *****//
+const 
+  GL_SAMPLES_PASSED_ARB* = 0x00008914
+  GL_QUERY_COUNTER_BITS_ARB* = 0x00008864
+  GL_CURRENT_QUERY_ARB* = 0x00008865
+  GL_QUERY_RESULT_ARB* = 0x00008866
+  GL_QUERY_RESULT_AVAILABLE_ARB* = 0x00008867
+
+proc glGenQueriesARB*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glGenQueriesARB".}
+proc glDeleteQueriesARB*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteQueriesARB".}
+proc glIsQueryARB*(id: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsQueryARB".}
+proc glBeginQueryARB*(target: TGLenum, id: TGLuint){.dynlib: dllname, 
+    importc: "glBeginQueryARB".}
+proc glEndQueryARB*(target: TGLenum){.dynlib: dllname, importc: "glEndQueryARB".}
+proc glGetQueryivARB*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetQueryivARB".}
+proc glGetQueryObjectivARB*(id: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetQueryObjectivARB".}
+proc glGetQueryObjectuivARB*(id: TGLuint, pname: TGLenum, params: PGLuint){.
+    dynlib: dllname, importc: "glGetQueryObjectuivARB".}
+  #***** GL_ARB_shader_objects *****//
+const 
+  GL_PROGRAM_OBJECT_ARB* = 0x00008B40
+  GL_OBJECT_TYPE_ARB* = 0x00008B4E
+  GL_OBJECT_SUBTYPE_ARB* = 0x00008B4F
+  GL_OBJECT_DELETE_STATUS_ARB* = 0x00008B80
+  GL_OBJECT_COMPILE_STATUS_ARB* = 0x00008B81
+  GL_OBJECT_LINK_STATUS_ARB* = 0x00008B82
+  GL_OBJECT_VALIDATE_STATUS_ARB* = 0x00008B83
+  GL_OBJECT_INFO_LOG_LENGTH_ARB* = 0x00008B84
+  GL_OBJECT_ATTACHED_OBJECTS_ARB* = 0x00008B85
+  GL_OBJECT_ACTIVE_UNIFORMS_ARB* = 0x00008B86
+  GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB* = 0x00008B87
+  GL_OBJECT_SHADER_SOURCE_LENGTH_ARB* = 0x00008B88
+  GL_SHADER_OBJECT_ARB* = 0x00008B48
+  GL_FLOAT* = 0x00001406
+  GL_FLOAT_VEC2_ARB* = 0x00008B50
+  GL_FLOAT_VEC3_ARB* = 0x00008B51
+  GL_FLOAT_VEC4_ARB* = 0x00008B52
+  GL_INT* = 0x00001404
+  GL_INT_VEC2_ARB* = 0x00008B53
+  GL_INT_VEC3_ARB* = 0x00008B54
+  GL_INT_VEC4_ARB* = 0x00008B55
+  GL_BOOL_ARB* = 0x00008B56
+  GL_BOOL_VEC2_ARB* = 0x00008B57
+  GL_BOOL_VEC3_ARB* = 0x00008B58
+  GL_BOOL_VEC4_ARB* = 0x00008B59
+  GL_FLOAT_MAT2_ARB* = 0x00008B5A
+  GL_FLOAT_MAT3_ARB* = 0x00008B5B
+  GL_FLOAT_MAT4_ARB* = 0x00008B5C
+
+proc glDeleteObjectARB*(obj: GLhandleARB){.dynlib: dllname, 
+    importc: "glDeleteObjectARB".}
+proc glGetHandleARB*(pname: TGLenum): GLhandleARB{.dynlib: dllname, 
+    importc: "glGetHandleARB".}
+proc glDetachObjectARB*(containerObj: GLhandleARB, attachedObj: GLhandleARB){.
+    dynlib: dllname, importc: "glDetachObjectARB".}
+proc glCreateShaderObjectARB*(shaderType: TGLenum): GLhandleARB{.
+    dynlib: dllname, importc: "glCreateShaderObjectARB".}
+proc glShaderSourceARB*(shaderObj: GLhandleARB, count: TGLsizei, str: PGLvoid, 
+                        len: PGLint){.dynlib: dllname, 
+                                      importc: "glShaderSourceARB".}
+proc glCompileShaderARB*(shaderObj: GLhandleARB){.dynlib: dllname, 
+    importc: "glCompileShaderARB".}
+proc glCreateProgramObjectARB*(): GLhandleARB{.dynlib: dllname, 
+    importc: "glCreateProgramObjectARB".}
+proc glAttachObjectARB*(containerObj: GLhandleARB, obj: GLhandleARB){.
+    dynlib: dllname, importc: "glAttachObjectARB".}
+proc glLinkProgramARB*(programObj: GLhandleARB){.dynlib: dllname, 
+    importc: "glLinkProgramARB".}
+proc glUseProgramObjectARB*(programObj: GLhandleARB){.dynlib: dllname, 
+    importc: "glUseProgramObjectARB".}
+proc glValidateProgramARB*(programObj: GLhandleARB){.dynlib: dllname, 
+    importc: "glValidateProgramARB".}
+proc glUniform1fARB*(location: TGLint, v0: TGLfloat){.dynlib: dllname, 
+    importc: "glUniform1fARB".}
+proc glUniform2fARB*(location: TGLint, v0: TGLfloat, v1: TGLfloat){.
+    dynlib: dllname, importc: "glUniform2fARB".}
+proc glUniform3fARB*(location: TGLint, v0: TGLfloat, v1: TGLfloat, v2: TGLfloat){.
+    dynlib: dllname, importc: "glUniform3fARB".}
+proc glUniform4fARB*(location: TGLint, v0: TGLfloat, v1: TGLfloat, v2: TGLfloat, 
+                     v3: TGLfloat){.dynlib: dllname, importc: "glUniform4fARB".}
+proc glUniform1iARB*(location: TGLint, v0: TGLint){.dynlib: dllname, 
+    importc: "glUniform1iARB".}
+proc glUniform2iARB*(location: TGLint, v0: TGLint, v1: TGLint){.dynlib: dllname, 
+    importc: "glUniform2iARB".}
+proc glUniform3iARB*(location: TGLint, v0: TGLint, v1: TGLint, v2: TGLint){.
+    dynlib: dllname, importc: "glUniform3iARB".}
+proc glUniform4iARB*(location: TGLint, v0: TGLint, v1: TGLint, v2: TGLint, 
+                     v3: TGLint){.dynlib: dllname, importc: "glUniform4iARB".}
+proc glUniform1fvARB*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform1fvARB".}
+proc glUniform2fvARB*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform2fvARB".}
+proc glUniform3fvARB*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform3fvARB".}
+proc glUniform4fvARB*(location: TGLint, count: TGLsizei, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniform4fvARB".}
+proc glUniform1ivARB*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform1ivARB".}
+proc glUniform2ivARB*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform2ivARB".}
+proc glUniform3ivARB*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform3ivARB".}
+proc glUniform4ivARB*(location: TGLint, count: TGLsizei, value: PGLint){.
+    dynlib: dllname, importc: "glUniform4ivARB".}
+proc glUniformMatrix2fvARB*(location: TGLint, count: TGLsizei, 
+                            transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix2fvARB".}
+proc glUniformMatrix3fvARB*(location: TGLint, count: TGLsizei, 
+                            transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix3fvARB".}
+proc glUniformMatrix4fvARB*(location: TGLint, count: TGLsizei, 
+                            transpose: TGLboolean, value: PGLfloat){.
+    dynlib: dllname, importc: "glUniformMatrix4fvARB".}
+proc glGetObjectParameterfvARB*(obj: GLhandleARB, pname: TGLenum, 
+                                params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetObjectParameterfvARB".}
+proc glGetObjectParameterivARB*(obj: GLhandleARB, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetObjectParameterivARB".}
+proc glGetInfoLogARB*(obj: GLhandleARB, maxLength: TGLsizei, len: PGLsizei, 
+                      infoLog: PGLcharARB){.dynlib: dllname, 
+    importc: "glGetInfoLogARB".}
+proc glGetAttachedObjectsARB*(containerObj: GLhandleARB, maxCount: TGLsizei, 
+                              count: PGLsizei, obj: PGLhandleARB){.
+    dynlib: dllname, importc: "glGetAttachedObjectsARB".}
+proc glGetUniformLocationARB*(programObj: GLhandleARB, name: PGLcharARB): TGLint{.
+    dynlib: dllname, importc: "glGetUniformLocationARB".}
+proc glGetActiveUniformARB*(programObj: GLhandleARB, index: TGLuint, 
+                            maxLength: TGLsizei, len: PGLsizei, size: PGLint, 
+                            thetype: PGLenum, name: PGLcharARB){.
+    dynlib: dllname, importc: "glGetActiveUniformARB".}
+proc glGetUniformfvARB*(programObj: GLhandleARB, location: TGLint, 
+                        params: PGLfloat){.dynlib: dllname, 
+    importc: "glGetUniformfvARB".}
+proc glGetUniformivARB*(programObj: GLhandleARB, location: TGLint, 
+                        params: PGLint){.dynlib: dllname, 
+    importc: "glGetUniformivARB".}
+proc glGetShaderSourceARB*(obj: GLhandleARB, maxLength: TGLsizei, len: PGLsizei, 
+                           source: PGLcharARB){.dynlib: dllname, 
+    importc: "glGetShaderSourceARB".}
+const 
+  GL_VERTEX_SHADER_ARB* = 0x00008B31
+  GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB* = 0x00008B4A
+  GL_MAX_VARYING_FLOATS_ARB* = 0x00008B4B # GL_MAX_VERTEX_ATTRIBS_ARB  { already defined }
+                                          # GL_MAX_TEXTURE_IMAGE_UNITS_ARB  { already defined }
+  GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB* = 0x00008B4C
+  GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB* = 0x00008B4D # 
+                                                        # 
+                                                        # GL_MAX_TEXTURE_COORDS_ARB  { already defined }
+                                                        # 
+                                                        # 
+                                                        # GL_VERTEX_PROGRAM_POINT_SIZE_ARB  { already defined }
+                                                        # 
+                                                        # 
+                                                        # GL_VERTEX_PROGRAM_TWO_SIDE_ARB  { already defined }
+                                                        # GL_OBJECT_TYPE_ARB  { already defined }
+                                                        # GL_OBJECT_SUBTYPE_ARB  { already defined }
+  GL_OBJECT_ACTIVE_ATTRIBUTES_ARB* = 0x00008B89
+  GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB* = 0x00008B8A # GL_SHADER_OBJECT_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_CURRENT_VERTEX_ATTRIB_ARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB  { already defined }
+                                                          # GL_FLOAT  { already defined }
+                                                          # GL_FLOAT_VEC2_ARB  { already defined }
+                                                          # GL_FLOAT_VEC3_ARB  { already defined }
+                                                          # GL_FLOAT_VEC4_ARB  { already defined }
+                                                          # GL_FLOAT_MAT2_ARB  { already defined }
+                                                          # GL_FLOAT_MAT3_ARB  { already defined }
+                                                          # GL_FLOAT_MAT4_ARB  { already defined }
+                                                          # glVertexAttrib1fARB  { already defined }
+                                                          # glVertexAttrib1sARB  { already defined }
+                                                          # glVertexAttrib1dARB  { already defined }
+                                                          # glVertexAttrib2fARB  { already defined }
+                                                          # glVertexAttrib2sARB  { already defined }
+                                                          # glVertexAttrib2dARB  { already defined }
+                                                          # glVertexAttrib3fARB  { already defined }
+                                                          # glVertexAttrib3sARB  { already defined }
+                                                          # glVertexAttrib3dARB  { already defined }
+                                                          # glVertexAttrib4fARB  { already defined }
+                                                          # glVertexAttrib4sARB  { already defined }
+                                                          # glVertexAttrib4dARB  { already defined }
+                                                          # glVertexAttrib4NubARB  { already defined }
+                                                          # glVertexAttrib1fvARB  { already defined }
+                                                          # glVertexAttrib1svARB  { already defined }
+                                                          # glVertexAttrib1dvARB  { already defined }
+                                                          # glVertexAttrib2fvARB  { already defined }
+                                                          # glVertexAttrib2svARB  { already defined }
+                                                          # glVertexAttrib2dvARB  { already defined }
+                                                          # glVertexAttrib3fvARB  { already defined }
+                                                          # glVertexAttrib3svARB  { already defined }
+                                                          # glVertexAttrib3dvARB  { already defined }
+                                                          # glVertexAttrib4fvARB  { already defined }
+                                                          # glVertexAttrib4svARB  { already defined }
+                                                          # glVertexAttrib4dvARB  { already defined }
+                                                          # glVertexAttrib4ivARB  { already defined }
+                                                          # glVertexAttrib4bvARB  { already defined }
+                                                          # glVertexAttrib4ubvARB  { already defined }
+                                                          # glVertexAttrib4usvARB  { already defined }
+                                                          # glVertexAttrib4uivARB  { already defined }
+                                                          # glVertexAttrib4NbvARB  { already defined }
+                                                          # glVertexAttrib4NsvARB  { already defined }
+                                                          # glVertexAttrib4NivARB  { already defined }
+                                                          # glVertexAttrib4NubvARB  { already defined }
+                                                          # glVertexAttrib4NusvARB  { already defined }
+                                                          # glVertexAttrib4NuivARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # glVertexAttribPointerARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # glEnableVertexAttribArrayARB  { already defined }
+                                                          # 
+                                                          # 
+                                                          # glDisableVertexAttribArrayARB  { already defined }
+
+proc glBindAttribLocationARB*(programObj: GLhandleARB, index: TGLuint, 
+                              name: PGLcharARB){.dynlib: dllname, 
+    importc: "glBindAttribLocationARB".}
+proc glGetActiveAttribARB*(programObj: GLhandleARB, index: TGLuint, 
+                           maxLength: TGLsizei, len: PGLsizei, size: PGLint, 
+                           thetype: PGLenum, name: PGLcharARB){.dynlib: dllname, 
+    importc: "glGetActiveAttribARB".}
+proc glGetAttribLocationARB*(programObj: GLhandleARB, name: PGLcharARB): TGLint{.
+    dynlib: dllname, importc: "glGetAttribLocationARB".}
+  # glGetVertexAttribdvARB  { already defined }
+  # glGetVertexAttribfvARB  { already defined }
+  # glGetVertexAttribivARB  { already defined }
+  # glGetVertexAttribPointervARB  { already defined }
+  #***** GL_ARB_fragment_shader *****//
+const 
+  GL_FRAGMENT_SHADER_ARB* = 0x00008B30
+  GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB* = 0x00008B49 # GL_MAX_TEXTURE_COORDS_ARB  { already defined }
+                                                       # 
+                                                       # 
+                                                       # GL_MAX_TEXTURE_IMAGE_UNITS_ARB  { already defined }
+                                                       # GL_OBJECT_TYPE_ARB  { already defined }
+                                                       # GL_OBJECT_SUBTYPE_ARB  { already defined }
+                                                       # GL_SHADER_OBJECT_ARB  { already defined }
+  #***** GL_ARB_shading_language_100 *****//
+  #***** GL_ARB_texture_non_power_of_two *****//
+  #***** GL_ARB_point_sprite *****//
+
+const 
+  GL_POINT_SPRITE_ARB* = 0x00008861
+  GL_COORD_REPLACE_ARB* = 0x00008862
+  #***** GL_EXT_depth_bounds_test *****//
+
+const 
+  constGL_DEPTH_BOUNDS_TEST_EXT* = 0x00008890
+  constGL_DEPTH_BOUNDS_EXT* = 0x00008891
+
+proc glDepthBoundsEXT*(zmin: TGLclampd, zmax: TGLclampd){.dynlib: dllname, 
+    importc: "glDepthBoundsEXT".}
+  #***** GL_EXT_texture_mirror_clamp *****//
+const 
+  GL_MIRROR_CLAMP_EXT* = 0x00008742
+  GL_MIRROR_CLAMP_TO_EDGE_EXT* = 0x00008743
+  GL_MIRROR_CLAMP_TO_BORDER_EXT* = 0x00008912
+  #***** GL_EXT_blend_equation_separate *****//
+
+const 
+  GL_BLEND_EQUATION_RGB_EXT* = 0x00008009
+  GL_BLEND_EQUATION_ALPHA_EXT* = 0x0000883D
+
+proc glBlendEquationSeparateEXT*(modeRGB: TGLenum, modeAlpha: TGLenum){.
+    dynlib: dllname, importc: "glBlendEquationSeparateEXT".}
+  #***** GL_MESA_pack_invert *****//
+const 
+  GL_PACK_INVERT_MESA* = 0x00008758
+  #***** GL_MESA_ycbcr_texture *****//
+
+const 
+  GL_YCBCR_MESA* = 0x00008757
+  GL_UNSIGNED_SHORT_8_8_MESA* = 0x000085BA
+  GL_UNSIGNED_SHORT_8_8_REV_MESA* = 0x000085BB
+  #***** GL_ARB_fragment_program_shadow *****//
+  #***** GL_NV_fragment_program_option *****//
+  #***** GL_EXT_pixel_buffer_object *****//
+
+const 
+  GL_PIXEL_PACK_BUFFER_EXT* = 0x000088EB
+  GL_PIXEL_UNPACK_BUFFER_EXT* = 0x000088EC
+  GL_PIXEL_PACK_BUFFER_BINDING_EXT* = 0x000088ED
+  GL_PIXEL_UNPACK_BUFFER_BINDING_EXT* = 0x000088EF
+  #***** GL_NV_fragment_program2 *****//
+
+const 
+  GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV* = 0x000088F4
+  GL_MAX_PROGRAM_CALL_DEPTH_NV* = 0x000088F5
+  GL_MAX_PROGRAM_IF_DEPTH_NV* = 0x000088F6
+  GL_MAX_PROGRAM_LOOP_DEPTH_NV* = 0x000088F7
+  GL_MAX_PROGRAM_LOOP_COUNT_NV* = 0x000088F8
+  #***** GL_NV_vertex_program2_option *****//
+  # GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV  { already defined }
+  # GL_MAX_PROGRAM_CALL_DEPTH_NV  { already defined }
+  #***** GL_NV_vertex_program3 *****//
+  # GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB  { already defined }
+  #***** GL_ARB_draw_buffers *****//
+
+const 
+  GL_MAX_DRAW_BUFFERS_ARB* = 0x00008824
+  GL_DRAW_BUFFER0_ARB* = 0x00008825
+  GL_DRAW_BUFFER1_ARB* = 0x00008826
+  GL_DRAW_BUFFER2_ARB* = 0x00008827
+  GL_DRAW_BUFFER3_ARB* = 0x00008828
+  GL_DRAW_BUFFER4_ARB* = 0x00008829
+  GL_DRAW_BUFFER5_ARB* = 0x0000882A
+  GL_DRAW_BUFFER6_ARB* = 0x0000882B
+  GL_DRAW_BUFFER7_ARB* = 0x0000882C
+  GL_DRAW_BUFFER8_ARB* = 0x0000882D
+  GL_DRAW_BUFFER9_ARB* = 0x0000882E
+  GL_DRAW_BUFFER10_ARB* = 0x0000882F
+  GL_DRAW_BUFFER11_ARB* = 0x00008830
+  GL_DRAW_BUFFER12_ARB* = 0x00008831
+  GL_DRAW_BUFFER13_ARB* = 0x00008832
+  GL_DRAW_BUFFER14_ARB* = 0x00008833
+  GL_DRAW_BUFFER15_ARB* = 0x00008834
+
+proc glDrawBuffersARB*(n: TGLsizei, bufs: PGLenum){.dynlib: dllname, 
+    importc: "glDrawBuffersARB".}
+  #***** GL_ARB_texture_rectangle *****//
+const 
+  GL_TEXTURE_RECTANGLE_ARB* = 0x000084F5
+  GL_TEXTURE_BINDING_RECTANGLE_ARB* = 0x000084F6
+  GL_PROXY_TEXTURE_RECTANGLE_ARB* = 0x000084F7
+  GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB* = 0x000084F8
+  #***** GL_ARB_color_buffer_float *****//
+
+const 
+  GL_RGBA_FLOAT_MODE_ARB* = 0x00008820
+  GL_CLAMP_VERTEX_COLOR_ARB* = 0x0000891A
+  GL_CLAMP_FRAGMENT_COLOR_ARB* = 0x0000891B
+  GL_CLAMP_READ_COLOR_ARB* = 0x0000891C
+  GL_FIXED_ONLY_ARB* = 0x0000891D
+  WGL_TYPE_RGBA_FLOAT_ARB* = 0x000021A0
+
+proc glClampColorARB*(target: TGLenum, clamp: TGLenum){.dynlib: dllname, 
+    importc: "glClampColorARB".}
+  #***** GL_ARB_half_float_pixel *****//
+const 
+  GL_HALF_FLOAT_ARB* = 0x0000140B
+  #***** GL_ARB_texture_float *****//
+
+const 
+  GL_TEXTURE_RED_TYPE_ARB* = 0x00008C10
+  GL_TEXTURE_GREEN_TYPE_ARB* = 0x00008C11
+  GL_TEXTURE_BLUE_TYPE_ARB* = 0x00008C12
+  GL_TEXTURE_ALPHA_TYPE_ARB* = 0x00008C13
+  GL_TEXTURE_LUMINANCE_TYPE_ARB* = 0x00008C14
+  GL_TEXTURE_INTENSITY_TYPE_ARB* = 0x00008C15
+  GL_TEXTURE_DEPTH_TYPE_ARB* = 0x00008C16
+  GL_UNSIGNED_NORMALIZED_ARB* = 0x00008C17
+  GL_RGBA32F_ARB* = 0x00008814
+  GL_RGB32F_ARB* = 0x00008815
+  GL_ALPHA32F_ARB* = 0x00008816
+  GL_INTENSITY32F_ARB* = 0x00008817
+  GL_LUMINANCE32F_ARB* = 0x00008818
+  GL_LUMINANCE_ALPHA32F_ARB* = 0x00008819
+  GL_RGBA16F_ARB* = 0x0000881A
+  GL_RGB16F_ARB* = 0x0000881B
+  GL_ALPHA16F_ARB* = 0x0000881C
+  GL_INTENSITY16F_ARB* = 0x0000881D
+  GL_LUMINANCE16F_ARB* = 0x0000881E
+  GL_LUMINANCE_ALPHA16F_ARB* = 0x0000881F
+  #***** GL_EXT_texture_compression_dxt1 *****//
+  # GL_COMPRESSED_RGB_S3TC_DXT1_EXT  { already defined }
+  # GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  { already defined }
+  #***** GL_ARB_pixel_buffer_object *****//
+
+const 
+  GL_PIXEL_PACK_BUFFER_ARB* = 0x000088EB
+  GL_PIXEL_UNPACK_BUFFER_ARB* = 0x000088EC
+  GL_PIXEL_PACK_BUFFER_BINDING_ARB* = 0x000088ED
+  GL_PIXEL_UNPACK_BUFFER_BINDING_ARB* = 0x000088EF
+  #***** GL_EXT_framebuffer_object *****//
+
+const 
+  GL_FRAMEBUFFER_EXT* = 0x00008D40
+  GL_RENDERBUFFER_EXT* = 0x00008D41
+  GL_STENCIL_INDEX_EXT* = 0x00008D45
+  GL_STENCIL_INDEX1_EXT* = 0x00008D46
+  GL_STENCIL_INDEX4_EXT* = 0x00008D47
+  GL_STENCIL_INDEX8_EXT* = 0x00008D48
+  GL_STENCIL_INDEX16_EXT* = 0x00008D49
+  GL_RENDERBUFFER_WIDTH_EXT* = 0x00008D42
+  GL_RENDERBUFFER_HEIGHT_EXT* = 0x00008D43
+  GL_RENDERBUFFER_INTERNAL_FORMAT_EXT* = 0x00008D44
+  GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT* = 0x00008CD0
+  GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT* = 0x00008CD1
+  GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT* = 0x00008CD2
+  GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT* = 0x00008CD3
+  GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT* = 0x00008CD4
+  GL_COLOR_ATTACHMENT0_EXT* = 0x00008CE0
+  GL_COLOR_ATTACHMENT1_EXT* = 0x00008CE1
+  GL_COLOR_ATTACHMENT2_EXT* = 0x00008CE2
+  GL_COLOR_ATTACHMENT3_EXT* = 0x00008CE3
+  GL_COLOR_ATTACHMENT4_EXT* = 0x00008CE4
+  GL_COLOR_ATTACHMENT5_EXT* = 0x00008CE5
+  GL_COLOR_ATTACHMENT6_EXT* = 0x00008CE6
+  GL_COLOR_ATTACHMENT7_EXT* = 0x00008CE7
+  GL_COLOR_ATTACHMENT8_EXT* = 0x00008CE8
+  GL_COLOR_ATTACHMENT9_EXT* = 0x00008CE9
+  GL_COLOR_ATTACHMENT10_EXT* = 0x00008CEA
+  GL_COLOR_ATTACHMENT11_EXT* = 0x00008CEB
+  GL_COLOR_ATTACHMENT12_EXT* = 0x00008CEC
+  GL_COLOR_ATTACHMENT13_EXT* = 0x00008CED
+  GL_COLOR_ATTACHMENT14_EXT* = 0x00008CEE
+  GL_COLOR_ATTACHMENT15_EXT* = 0x00008CEF
+  GL_DEPTH_ATTACHMENT_EXT* = 0x00008D00
+  GL_STENCIL_ATTACHMENT_EXT* = 0x00008D20
+  GL_FRAMEBUFFER_COMPLETE_EXT* = 0x00008CD5
+  GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT* = 0x00008CD6
+  GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT* = 0x00008CD7
+  GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT* = 0x00008CD8
+  GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT* = 0x00008CD9
+  GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT* = 0x00008CDA
+  GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT* = 0x00008CDB
+  GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT* = 0x00008CDC
+  GL_FRAMEBUFFER_UNSUPPORTED_EXT* = 0x00008CDD
+  GL_FRAMEBUFFER_STATUS_ERROR_EXT* = 0x00008CDE
+  GL_FRAMEBUFFER_BINDING_EXT* = 0x00008CA6
+  GL_RENDERBUFFER_BINDING_EXT* = 0x00008CA7
+  GL_MAX_COLOR_ATTACHMENTS_EXT* = 0x00008CDF
+  GL_MAX_RENDERBUFFER_SIZE_EXT* = 0x000084E8
+  GL_INVALID_FRAMEBUFFER_OPERATION_EXT* = 0x00000506
+
+proc glIsRenderbufferEXT*(renderbuffer: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsRenderbufferEXT".}
+proc glBindRenderbufferEXT*(target: TGLenum, renderbuffer: TGLuint){.
+    dynlib: dllname, importc: "glBindRenderbufferEXT".}
+proc glDeleteRenderbuffersEXT*(n: TGLsizei, renderbuffers: PGLuint){.
+    dynlib: dllname, importc: "glDeleteRenderbuffersEXT".}
+proc glGenRenderbuffersEXT*(n: TGLsizei, renderbuffers: PGLuint){.
+    dynlib: dllname, importc: "glGenRenderbuffersEXT".}
+proc glRenderbufferStorageEXT*(target: TGLenum, internalformat: TGLenum, 
+                               width: TGLsizei, height: TGLsizei){.
+    dynlib: dllname, importc: "glRenderbufferStorageEXT".}
+proc glGetRenderbufferParameterivEXT*(target: TGLenum, pname: TGLenum, 
+                                      params: PGLint){.dynlib: dllname, 
+    importc: "glGetRenderbufferParameterivEXT".}
+proc glIsFramebufferEXT*(framebuffer: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsFramebufferEXT".}
+proc glBindFramebufferEXT*(target: TGLenum, framebuffer: TGLuint){.
+    dynlib: dllname, importc: "glBindFramebufferEXT".}
+proc glDeleteFramebuffersEXT*(n: TGLsizei, framebuffers: PGLuint){.
+    dynlib: dllname, importc: "glDeleteFramebuffersEXT".}
+proc glGenFramebuffersEXT*(n: TGLsizei, framebuffers: PGLuint){.dynlib: dllname, 
+    importc: "glGenFramebuffersEXT".}
+proc glCheckFramebufferStatusEXT*(target: TGLenum): TGLenum{.dynlib: dllname, 
+    importc: "glCheckFramebufferStatusEXT".}
+proc glFramebufferTexture1DEXT*(target: TGLenum, attachment: TGLenum, 
+                                textarget: TGLenum, texture: TGLuint, 
+                                level: TGLint){.dynlib: dllname, 
+    importc: "glFramebufferTexture1DEXT".}
+proc glFramebufferTexture2DEXT*(target: TGLenum, attachment: TGLenum, 
+                                textarget: TGLenum, texture: TGLuint, 
+                                level: TGLint){.dynlib: dllname, 
+    importc: "glFramebufferTexture2DEXT".}
+proc glFramebufferTexture3DEXT*(target: TGLenum, attachment: TGLenum, 
+                                textarget: TGLenum, texture: TGLuint, 
+                                level: TGLint, zoffset: TGLint){.
+    dynlib: dllname, importc: "glFramebufferTexture3DEXT".}
+proc glFramebufferRenderbufferEXT*(target: TGLenum, attachment: TGLenum, 
+                                   renderbuffertarget: TGLenum, 
+                                   renderbuffer: TGLuint){.dynlib: dllname, 
+    importc: "glFramebufferRenderbufferEXT".}
+proc glGetFramebufferAttachmentParameterivEXT*(target: TGLenum, 
+    attachment: TGLenum, pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glGetFramebufferAttachmentParameterivEXT".}
+proc glGenerateMipmapEXT*(target: TGLenum){.dynlib: dllname, 
+    importc: "glGenerateMipmapEXT".}
+  #***** GL_version_1_4 *****//
+const 
+  GL_BLEND_DST_RGB* = 0x000080C8
+  GL_BLEND_SRC_RGB* = 0x000080C9
+  GL_BLEND_DST_ALPHA* = 0x000080CA
+  GL_BLEND_SRC_ALPHA* = 0x000080CB
+  GL_POINT_SIZE_MIN* = 0x00008126
+  GL_POINT_SIZE_MAX* = 0x00008127
+  GL_POINT_FADE_THRESHOLD_SIZE* = 0x00008128
+  GL_POINT_DISTANCE_ATTENUATION* = 0x00008129
+  GL_GENERATE_MIPMAP* = 0x00008191
+  GL_GENERATE_MIPMAP_HINT* = 0x00008192
+  GL_DEPTH_COMPONENT16* = 0x000081A5
+  GL_DEPTH_COMPONENT24* = 0x000081A6
+  GL_DEPTH_COMPONENT32* = 0x000081A7
+  GL_MIRRORED_REPEAT* = 0x00008370
+  GL_FOG_COORDINATE_SOURCE* = 0x00008450
+  GL_FOG_COORDINATE* = 0x00008451
+  GL_FRAGMENT_DEPTH* = 0x00008452
+  GL_CURRENT_FOG_COORDINATE* = 0x00008453
+  GL_FOG_COORDINATE_ARRAY_TYPE* = 0x00008454
+  GL_FOG_COORDINATE_ARRAY_STRIDE* = 0x00008455
+  GL_FOG_COORDINATE_ARRAY_POINTER* = 0x00008456
+  GL_FOG_COORDINATE_ARRAY* = 0x00008457
+  GL_COLOR_SUM* = 0x00008458
+  GL_CURRENT_SECONDARY_COLOR* = 0x00008459
+  GL_SECONDARY_COLOR_ARRAY_SIZE* = 0x0000845A
+  GL_SECONDARY_COLOR_ARRAY_TYPE* = 0x0000845B
+  GL_SECONDARY_COLOR_ARRAY_STRIDE* = 0x0000845C
+  GL_SECONDARY_COLOR_ARRAY_POINTER* = 0x0000845D
+  GL_SECONDARY_COLOR_ARRAY* = 0x0000845E
+  GL_MAX_TEXTURE_LOD_BIAS* = 0x000084FD
+  GL_TEXTURE_FILTER_CONTROL* = 0x00008500
+  GL_TEXTURE_LOD_BIAS* = 0x00008501
+  GL_INCR_WRAP* = 0x00008507
+  GL_DECR_WRAP* = 0x00008508
+  GL_TEXTURE_DEPTH_SIZE* = 0x0000884A
+  GL_DEPTH_TEXTURE_MODE* = 0x0000884B
+  GL_TEXTURE_COMPARE_MODE* = 0x0000884C
+  GL_TEXTURE_COMPARE_FUNC* = 0x0000884D
+  GL_COMPARE_R_TO_TEXTURE* = 0x0000884E
+
+proc glBlendFuncSeparate*(sfactorRGB: TGLenum, dfactorRGB: TGLenum, 
+                          sfactorAlpha: TGLenum, dfactorAlpha: TGLenum){.
+    dynlib: dllname, importc: "glBlendFuncSeparate".}
+proc glFogCoordf*(coord: TGLfloat){.dynlib: dllname, importc: "glFogCoordf".}
+proc glFogCoordfv*(coord: PGLfloat){.dynlib: dllname, importc: "glFogCoordfv".}
+proc glFogCoordd*(coord: TGLdouble){.dynlib: dllname, importc: "glFogCoordd".}
+proc glFogCoorddv*(coord: PGLdouble){.dynlib: dllname, importc: "glFogCoorddv".}
+proc glFogCoordPointer*(thetype: TGLenum, stride: TGLsizei, pointer: PGLvoid){.
+    dynlib: dllname, importc: "glFogCoordPointer".}
+proc glMultiDrawArrays*(mode: TGLenum, first: PGLint, count: PGLsizei, 
+                        primcount: TGLsizei){.dynlib: dllname, 
+    importc: "glMultiDrawArrays".}
+proc glMultiDrawElements*(mode: TGLenum, count: PGLsizei, thetype: TGLenum, 
+                          indices: PGLvoid, primcount: TGLsizei){.
+    dynlib: dllname, importc: "glMultiDrawElements".}
+proc glPointParameterf*(pname: TGLenum, param: TGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterf".}
+proc glPointParameterfv*(pname: TGLenum, params: PGLfloat){.dynlib: dllname, 
+    importc: "glPointParameterfv".}
+proc glPointParameteri*(pname: TGLenum, param: TGLint){.dynlib: dllname, 
+    importc: "glPointParameteri".}
+proc glPointParameteriv*(pname: TGLenum, params: PGLint){.dynlib: dllname, 
+    importc: "glPointParameteriv".}
+proc glSecondaryColor3b*(red: TGLByte, green: TGLByte, blue: TGLByte){.
+    dynlib: dllname, importc: "glSecondaryColor3b".}
+proc glSecondaryColor3bv*(v: PGLbyte){.dynlib: dllname, 
+                                       importc: "glSecondaryColor3bv".}
+proc glSecondaryColor3d*(red: TGLdouble, green: TGLdouble, blue: TGLdouble){.
+    dynlib: dllname, importc: "glSecondaryColor3d".}
+proc glSecondaryColor3dv*(v: PGLdouble){.dynlib: dllname, 
+    importc: "glSecondaryColor3dv".}
+proc glSecondaryColor3f*(red: TGLfloat, green: TGLfloat, blue: TGLfloat){.
+    dynlib: dllname, importc: "glSecondaryColor3f".}
+proc glSecondaryColor3fv*(v: PGLfloat){.dynlib: dllname, 
+                                        importc: "glSecondaryColor3fv".}
+proc glSecondaryColor3i*(red: TGLint, green: TGLint, blue: TGLint){.
+    dynlib: dllname, importc: "glSecondaryColor3i".}
+proc glSecondaryColor3iv*(v: PGLint){.dynlib: dllname, 
+                                      importc: "glSecondaryColor3iv".}
+proc glSecondaryColor3s*(red: TGLshort, green: TGLshort, blue: TGLshort){.
+    dynlib: dllname, importc: "glSecondaryColor3s".}
+proc glSecondaryColor3sv*(v: PGLshort){.dynlib: dllname, 
+                                        importc: "glSecondaryColor3sv".}
+proc glSecondaryColor3ub*(red: TGLubyte, green: TGLubyte, blue: TGLubyte){.
+    dynlib: dllname, importc: "glSecondaryColor3ub".}
+proc glSecondaryColor3ubv*(v: PGLubyte){.dynlib: dllname, 
+    importc: "glSecondaryColor3ubv".}
+proc glSecondaryColor3ui*(red: TGLuint, green: TGLuint, blue: TGLuint){.
+    dynlib: dllname, importc: "glSecondaryColor3ui".}
+proc glSecondaryColor3uiv*(v: PGLuint){.dynlib: dllname, 
+                                        importc: "glSecondaryColor3uiv".}
+proc glSecondaryColor3us*(red: TGLushort, green: TGLushort, blue: TGLushort){.
+    dynlib: dllname, importc: "glSecondaryColor3us".}
+proc glSecondaryColor3usv*(v: PGLushort){.dynlib: dllname, 
+    importc: "glSecondaryColor3usv".}
+proc glSecondaryColorPointer*(size: TGLint, thetype: TGLenum, stride: TGLsizei, 
+                              pointer: PGLvoid){.dynlib: dllname, 
+    importc: "glSecondaryColorPointer".}
+proc glWindowPos2d*(x: TGLdouble, y: TGLdouble){.dynlib: dllname, 
+    importc: "glWindowPos2d".}
+proc glWindowPos2dv*(v: PGLdouble){.dynlib: dllname, importc: "glWindowPos2dv".}
+proc glWindowPos2f*(x: TGLfloat, y: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos2f".}
+proc glWindowPos2fv*(v: PGLfloat){.dynlib: dllname, importc: "glWindowPos2fv".}
+proc glWindowPos2i*(x: TGLint, y: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos2i".}
+proc glWindowPos2iv*(v: PGLint){.dynlib: dllname, importc: "glWindowPos2iv".}
+proc glWindowPos2s*(x: TGLshort, y: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos2s".}
+proc glWindowPos2sv*(v: PGLshort){.dynlib: dllname, importc: "glWindowPos2sv".}
+proc glWindowPos3d*(x: TGLdouble, y: TGLdouble, z: TGLdouble){.dynlib: dllname, 
+    importc: "glWindowPos3d".}
+proc glWindowPos3dv*(v: PGLdouble){.dynlib: dllname, importc: "glWindowPos3dv".}
+proc glWindowPos3f*(x: TGLfloat, y: TGLfloat, z: TGLfloat){.dynlib: dllname, 
+    importc: "glWindowPos3f".}
+proc glWindowPos3fv*(v: PGLfloat){.dynlib: dllname, importc: "glWindowPos3fv".}
+proc glWindowPos3i*(x: TGLint, y: TGLint, z: TGLint){.dynlib: dllname, 
+    importc: "glWindowPos3i".}
+proc glWindowPos3iv*(v: PGLint){.dynlib: dllname, importc: "glWindowPos3iv".}
+proc glWindowPos3s*(x: TGLshort, y: TGLshort, z: TGLshort){.dynlib: dllname, 
+    importc: "glWindowPos3s".}
+proc glWindowPos3sv*(v: PGLshort){.dynlib: dllname, importc: "glWindowPos3sv".}
+  #***** GL_version_1_5 *****//
+const 
+  GL_BUFFER_SIZE* = 0x00008764
+  GL_BUFFER_USAGE* = 0x00008765
+  GL_QUERY_COUNTER_BITS* = 0x00008864
+  GL_CURRENT_QUERY* = 0x00008865
+  GL_QUERY_RESULT* = 0x00008866
+  GL_QUERY_RESULT_AVAILABLE* = 0x00008867
+  GL_ARRAY_BUFFER* = 0x00008892
+  GL_ELEMENT_ARRAY_BUFFER* = 0x00008893
+  GL_ARRAY_BUFFER_BINDING* = 0x00008894
+  GL_ELEMENT_ARRAY_BUFFER_BINDING* = 0x00008895
+  GL_VERTEX_ARRAY_BUFFER_BINDING* = 0x00008896
+  GL_NORMAL_ARRAY_BUFFER_BINDING* = 0x00008897
+  GL_COLOR_ARRAY_BUFFER_BINDING* = 0x00008898
+  GL_INDEX_ARRAY_BUFFER_BINDING* = 0x00008899
+  GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING* = 0x0000889A
+  GL_EDGE_FLAG_ARRAY_BUFFER_BINDING* = 0x0000889B
+  GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING* = 0x0000889C
+  GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING* = 0x0000889D
+  GL_WEIGHT_ARRAY_BUFFER_BINDING* = 0x0000889E
+  GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING* = 0x0000889F
+  GL_READ_ONLY* = 0x000088B8
+  GL_WRITE_ONLY* = 0x000088B9
+  GL_READ_WRITE* = 0x000088BA
+  GL_BUFFER_ACCESS* = 0x000088BB
+  GL_BUFFER_MAPPED* = 0x000088BC
+  GL_BUFFER_MAP_POINTER* = 0x000088BD
+  GL_STREAM_DRAW* = 0x000088E0
+  GL_STREAM_READ* = 0x000088E1
+  GL_STREAM_COPY* = 0x000088E2
+  GL_STATIC_DRAW* = 0x000088E4
+  GL_STATIC_READ* = 0x000088E5
+  GL_STATIC_COPY* = 0x000088E6
+  GL_DYNAMIC_DRAW* = 0x000088E8
+  GL_DYNAMIC_READ* = 0x000088E9
+  GL_DYNAMIC_COPY* = 0x000088EA
+  GL_SAMPLES_PASSED* = 0x00008914
+  GL_FOG_COORD_SRC* = 0x00008450
+  GL_FOG_COORD* = 0x00008451
+  GL_CURRENT_FOG_COORD* = 0x00008453
+  GL_FOG_COORD_ARRAY_TYPE* = 0x00008454
+  GL_FOG_COORD_ARRAY_STRIDE* = 0x00008455
+  GL_FOG_COORD_ARRAY_POINTER* = 0x00008456
+  GL_FOG_COORD_ARRAY* = 0x00008457
+  GL_FOG_COORD_ARRAY_BUFFER_BINDING* = 0x0000889D
+  GL_SRC0_RGB* = 0x00008580
+  GL_SRC1_RGB* = 0x00008581
+  GL_SRC2_RGB* = 0x00008582
+  GL_SRC0_ALPHA* = 0x00008588
+  GL_SRC1_ALPHA* = 0x00008589
+  GL_SRC2_ALPHA* = 0x0000858A
+
+proc glGenQueries*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glGenQueries".}
+proc glDeleteQueries*(n: TGLsizei, ids: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteQueries".}
+proc glIsQuery*(id: TGLuint): TGLboolean{.dynlib: dllname, importc: "glIsQuery".}
+proc glBeginQuery*(target: TGLenum, id: TGLuint){.dynlib: dllname, 
+    importc: "glBeginQuery".}
+proc glEndQuery*(target: TGLenum){.dynlib: dllname, importc: "glEndQuery".}
+proc glGetQueryiv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetQueryiv".}
+proc glGetQueryObjectiv*(id: TGLuint, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetQueryObjectiv".}
+proc glGetQueryObjectuiv*(id: TGLuint, pname: TGLenum, params: PGLuint){.
+    dynlib: dllname, importc: "glGetQueryObjectuiv".}
+proc glBindBuffer*(target: TGLenum, buffer: TGLuint){.dynlib: dllname, 
+    importc: "glBindBuffer".}
+proc glDeleteBuffers*(n: TGLsizei, buffers: PGLuint){.dynlib: dllname, 
+    importc: "glDeleteBuffers".}
+proc glGenBuffers*(n: TGLsizei, buffers: PGLuint){.dynlib: dllname, 
+    importc: "glGenBuffers".}
+proc glIsBuffer*(buffer: TGLuint): TGLboolean{.dynlib: dllname, 
+    importc: "glIsBuffer".}
+proc glBufferData*(target: TGLenum, size: GLsizeiptr, data: PGLvoid, 
+                   usage: TGLenum){.dynlib: dllname, importc: "glBufferData".}
+proc glBufferSubData*(target: TGLenum, offset: GLintptr, size: GLsizeiptr, 
+                      data: PGLvoid){.dynlib: dllname, 
+                                      importc: "glBufferSubData".}
+proc glGetBufferSubData*(target: TGLenum, offset: GLintptr, size: GLsizeiptr, 
+                         data: PGLvoid){.dynlib: dllname, 
+    importc: "glGetBufferSubData".}
+proc glMapBuffer*(target: TGLenum, access: TGLenum): PGLvoid{.dynlib: dllname, 
+    importc: "glMapBuffer".}
+proc glUnmapBuffer*(target: TGLenum): TGLboolean{.dynlib: dllname, 
+    importc: "glUnmapBuffer".}
+proc glGetBufferParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
+    dynlib: dllname, importc: "glGetBufferParameteriv".}
+proc glGetBufferPointerv*(target: TGLenum, pname: TGLenum, params: PGLvoid){.
+    dynlib: dllname, importc: "glGetBufferPointerv".}
+  #***** GL_version_2_0 *****//
+const 
+  GL_BLEND_EQUATION_RGB* = 0x00008009
+  GL_VERTEX_ATTRIB_ARRAY_ENABLED* = 0x00008622
+  GL_VERTEX_ATTRIB_ARRAY_SIZE* = 0x00008623
+  GL_VERTEX_ATTRIB_ARRAY_STRIDE* = 0x00008624
+  GL_VERTEX_ATTRIB_ARRAY_TYPE* = 0x00008625
+  GL_CURRENT_VERTEX_ATTRIB* = 0x00008626
+  GL_VERTEX_PROGRAM_POINT_SIZE* = 0x00008642
+  GL_VERTEX_PROGRAM_TWO_SIDE* = 0x00008643
+  GL_VERTEX_ATTRIB_ARRAY_POINTER* = 0x00008645
+  GL_STENCIL_BACK_FUNC* = 0x00008800
+  GL_STENCIL_BACK_FAIL* = 0x00008801
+  GL_STENCIL_BACK_PASS_DEPTH_FAIL* = 0x00008802
+  GL_STENCIL_BACK_PASS_DEPTH_PASS* = 0x00008803
+  GL_MAX_DRAW_BUFFERS* = 0x00008824
+  GL_DRAW_BUFFER0* = 0x00008825
+  GL_DRAW_BUFFER1* = 0x00008826
+  GL_DRAW_BUFFER2* = 0x00008827
+  GL_DRAW_BUFFER3* = 0x00008828
+  GL_DRAW_BUFFER4* = 0x00008829
+  GL_DRAW_BUFFER5* = 0x0000882A
+  GL_DRAW_BUFFER6* = 0x0000882B
+  GL_DRAW_BUFFER7* = 0x0000882C
+  GL_DRAW_BUFFER8* = 0x0000882D
+  GL_DRAW_BUFFER9* = 0x0000882E
+  GL_DRAW_BUFFER10* = 0x0000882F
+  GL_DRAW_BUFFER11* = 0x00008830
+  GL_DRAW_BUFFER12* = 0x00008831
+  GL_DRAW_BUFFER13* = 0x00008832
+  GL_DRAW_BUFFER14* = 0x00008833
+  GL_DRAW_BUFFER15* = 0x00008834
+  GL_BLEND_EQUATION_ALPHA* = 0x0000883D
+  GL_POINT_SPRITE* = 0x00008861
+  GL_COORD_REPLACE* = 0x00008862
+  GL_MAX_VERTEX_ATTRIBS* = 0x00008869
+  GL_VERTEX_ATTRIB_ARRAY_NORMALIZED* = 0x0000886A
+  GL_MAX_TEXTURE_COORDS* = 0x00008871
+  GL_MAX_TEXTURE_IMAGE_UNITS* = 0x00008872
+  GL_FRAGMENT_SHADER* = 0x00008B30
+  GL_VERTEX_SHADER* = 0x00008B31
+  GL_MAX_FRAGMENT_UNIFORM_COMPONENTS* = 0x00008B49
+  GL_MAX_VERTEX_UNIFORM_COMPONENTS* = 0x00008B4A
+  GL_MAX_VARYING_FLOATS* = 0x00008B4B
+  GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS* = 0x00008B4C
+  GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS* = 0x00008B4D
+  GL_SHADER_TYPE* = 0x00008B4F
+  GL_FLOAT_VEC2* = 0x00008B50
+  GL_FLOAT_VEC3* = 0x00008B51
+  GL_FLOAT_VEC4* = 0x00008B52
+  GL_INT_VEC2* = 0x00008B53
+  GL_INT_VEC3* = 0x00008B54
+  GL_INT_VEC4* = 0x00008B55
+  GL_BOOL* = 0x00008B56
+  GL_BOOL_VEC2* = 0x00008B57
+  GL_BOOL_VEC3* = 0x00008B58
+  GL_BOOL_VEC4* = 0x00008B59
+  GL_FLOAT_MAT2* = 0x00008B5A
+  GL_FLOAT_MAT3* = 0x00008B5B
+  GL_FLOAT_MAT4* = 0x00008B5C
+  GL_SAMPLER_1D* = 0x00008B5D
+  GL_SAMPLER_2D* = 0x00008B5E
+  GL_SAMPLER_3D* = 0x00008B5F
+  GL_SAMPLER_CUBE* = 0x00008B60
+  GL_SAMPLER_1D_SHADOW* = 0x00008B61
+  GL_SAMPLER_2D_SHADOW* = 0x00008B62
+  GL_DELETE_STATUS* = 0x00008B80
+  GL_COMPILE_STATUS* = 0x00008B81
+  GL_LINK_STATUS* = 0x00008B82
+  GL_VALIDATE_STATUS* = 0x00008B83
+  GL_INFO_LOG_LENGTH* = 0x00008B84
+  GL_ATTACHED_SHADERS* = 0x00008B85
+  GL_ACTIVE_UNIFORMS* = 0x00008B86
+  GL_ACTIVE_UNIFORM_MAX_LENGTH* = 0x00008B87
+  GL_SHADER_SOURCE_LENGTH* = 0x00008B88
+  GL_ACTIVE_ATTRIBUTES* = 0x00008B89
+  GL_ACTIVE_ATTRIBUTE_MAX_LENGTH* = 0x00008B8A
+  GL_FRAGMENT_SHADER_DERIVATIVE_HINT* = 0x00008B8B
+  GL_SHADING_LANGUAGE_VERSION* = 0x00008B8C
+  GL_CURRENT_PROGRAM* = 0x00008B8D
+  GL_POINT_SPRITE_COORD_ORIGIN* = 0x00008CA0
+  GL_LOWER_LEFT* = 0x00008CA1
+  GL_UPPER_LEFT* = 0x00008CA2
+  GL_STENCIL_BACK_REF* = 0x00008CA3
+  GL_STENCIL_BACK_VALUE_MASK* = 0x00008CA4
+  GL_STENCIL_BACK_WRITEMASK* = 0x00008CA5
+
+{.pop.}
\ No newline at end of file
diff --git a/tests/manyloc/keineschweine/lib/glu.nim b/tests/manyloc/keineschweine/lib/glu.nim
new file mode 100644
index 000000000..e00120d83
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/glu.nim
@@ -0,0 +1,335 @@
+#
+#
+#  Adaption of the delphi3d.net OpenGL units to FreePascal
+#  Sebastian Guenther (sg@freepascal.org) in 2002
+#  These units are free to use
+#******************************************************************************
+# Converted to Delphi by Tom Nuydens (tom@delphi3d.net)                        
+# For the latest updates, visit Delphi3D: http://www.delphi3d.net              
+#******************************************************************************
+
+import 
+  GL
+
+when defined(windows): 
+  {.push, callconv: stdcall.}
+else: 
+  {.push, callconv: cdecl.}
+
+when defined(windows): 
+  const 
+    dllname = "glu32.dll"
+elif defined(macosx): 
+  const 
+    dllname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"
+else: 
+  const 
+    dllname = "libGLU.so.1"
+type 
+  TViewPortArray* = array[0..3, TGLint]
+  T16dArray* = array[0..15, TGLdouble]
+  TCallBack* = proc ()
+  T3dArray* = array[0..2, TGLdouble]
+  T4pArray* = array[0..3, Pointer]
+  T4fArray* = array[0..3, TGLfloat]
+  PPointer* = ptr Pointer
+
+type 
+  GLUnurbs*{.final.} = object 
+  PGLUnurbs* = ptr GLUnurbs
+  GLUquadric*{.final.} = object 
+  PGLUquadric* = ptr GLUquadric
+  GLUtesselator*{.final.} = object 
+  PGLUtesselator* = ptr GLUtesselator # backwards compatibility:
+  GLUnurbsObj* = GLUnurbs
+  PGLUnurbsObj* = PGLUnurbs
+  GLUquadricObj* = GLUquadric
+  PGLUquadricObj* = PGLUquadric
+  GLUtesselatorObj* = GLUtesselator
+  PGLUtesselatorObj* = PGLUtesselator
+  GLUtriangulatorObj* = GLUtesselator
+  PGLUtriangulatorObj* = PGLUtesselator
+  TGLUnurbs* = GLUnurbs
+  TGLUquadric* = GLUquadric
+  TGLUtesselator* = GLUtesselator
+  TGLUnurbsObj* = GLUnurbsObj
+  TGLUquadricObj* = GLUquadricObj
+  TGLUtesselatorObj* = GLUtesselatorObj
+  TGLUtriangulatorObj* = GLUtriangulatorObj
+
+proc gluErrorString*(errCode: TGLenum): cstring{.dynlib: dllname, 
+    importc: "gluErrorString".}
+proc gluErrorUnicodeStringEXT*(errCode: TGLenum): ptr int16{.dynlib: dllname, 
+    importc: "gluErrorUnicodeStringEXT".}
+proc gluGetString*(name: TGLenum): cstring{.dynlib: dllname, 
+    importc: "gluGetString".}
+proc gluOrtho2D*(left, right, bottom, top: TGLdouble){.dynlib: dllname, 
+    importc: "gluOrtho2D".}
+proc gluPerspective*(fovy, aspect, zNear, zFar: TGLdouble){.dynlib: dllname, 
+    importc: "gluPerspective".}
+proc gluPickMatrix*(x, y, width, height: TGLdouble, viewport: var TViewPortArray){.
+    dynlib: dllname, importc: "gluPickMatrix".}
+proc gluLookAt*(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz: TGLdouble){.
+    dynlib: dllname, importc: "gluLookAt".}
+proc gluProject*(objx, objy, objz: TGLdouble, 
+                 modelMatrix, projMatrix: var T16dArray, 
+                 viewport: var TViewPortArray, winx, winy, winz: PGLdouble): int{.
+    dynlib: dllname, importc: "gluProject".}
+proc gluUnProject*(winx, winy, winz: TGLdouble, 
+                   modelMatrix, projMatrix: var T16dArray, 
+                   viewport: var TViewPortArray, objx, objy, objz: PGLdouble): int{.
+    dynlib: dllname, importc: "gluUnProject".}
+proc gluScaleImage*(format: TGLenum, widthin, heightin: TGLint, typein: TGLenum, 
+                    datain: Pointer, widthout, heightout: TGLint, 
+                    typeout: TGLenum, dataout: Pointer): int{.dynlib: dllname, 
+    importc: "gluScaleImage".}
+proc gluBuild1DMipmaps*(target: TGLenum, components, width: TGLint, 
+                        format, atype: TGLenum, data: Pointer): int{.
+    dynlib: dllname, importc: "gluBuild1DMipmaps".}
+proc gluBuild2DMipmaps*(target: TGLenum, components, width, height: TGLint, 
+                        format, atype: TGLenum, data: Pointer): int{.
+    dynlib: dllname, importc: "gluBuild2DMipmaps".}
+proc gluNewQuadric*(): PGLUquadric{.dynlib: dllname, importc: "gluNewQuadric".}
+proc gluDeleteQuadric*(state: PGLUquadric){.dynlib: dllname, 
+    importc: "gluDeleteQuadric".}
+proc gluQuadricNormals*(quadObject: PGLUquadric, normals: TGLenum){.
+    dynlib: dllname, importc: "gluQuadricNormals".}
+proc gluQuadricTexture*(quadObject: PGLUquadric, textureCoords: TGLboolean){.
+    dynlib: dllname, importc: "gluQuadricTexture".}
+proc gluQuadricOrientation*(quadObject: PGLUquadric, orientation: TGLenum){.
+    dynlib: dllname, importc: "gluQuadricOrientation".}
+proc gluQuadricDrawStyle*(quadObject: PGLUquadric, drawStyle: TGLenum){.
+    dynlib: dllname, importc: "gluQuadricDrawStyle".}
+proc gluCylinder*(qobj: PGLUquadric, baseRadius, topRadius, height: TGLdouble, 
+                  slices, stacks: TGLint){.dynlib: dllname, 
+    importc: "gluCylinder".}
+proc gluDisk*(qobj: PGLUquadric, innerRadius, outerRadius: TGLdouble, 
+              slices, loops: TGLint){.dynlib: dllname, importc: "gluDisk".}
+proc gluPartialDisk*(qobj: PGLUquadric, innerRadius, outerRadius: TGLdouble, 
+                     slices, loops: TGLint, startAngle, sweepAngle: TGLdouble){.
+    dynlib: dllname, importc: "gluPartialDisk".}
+proc gluSphere*(qobj: PGLuquadric, radius: TGLdouble, slices, stacks: TGLint){.
+    dynlib: dllname, importc: "gluSphere".}
+proc gluQuadricCallback*(qobj: PGLUquadric, which: TGLenum, fn: TCallBack){.
+    dynlib: dllname, importc: "gluQuadricCallback".}
+proc gluNewTess*(): PGLUtesselator{.dynlib: dllname, importc: "gluNewTess".}
+proc gluDeleteTess*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluDeleteTess".}
+proc gluTessBeginPolygon*(tess: PGLUtesselator, polygon_data: Pointer){.
+    dynlib: dllname, importc: "gluTessBeginPolygon".}
+proc gluTessBeginContour*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluTessBeginContour".}
+proc gluTessVertex*(tess: PGLUtesselator, coords: var T3dArray, data: Pointer){.
+    dynlib: dllname, importc: "gluTessVertex".}
+proc gluTessEndContour*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluTessEndContour".}
+proc gluTessEndPolygon*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluTessEndPolygon".}
+proc gluTessProperty*(tess: PGLUtesselator, which: TGLenum, value: TGLdouble){.
+    dynlib: dllname, importc: "gluTessProperty".}
+proc gluTessNormal*(tess: PGLUtesselator, x, y, z: TGLdouble){.dynlib: dllname, 
+    importc: "gluTessNormal".}
+proc gluTessCallback*(tess: PGLUtesselator, which: TGLenum, fn: TCallBack){.
+    dynlib: dllname, importc: "gluTessCallback".}
+proc gluGetTessProperty*(tess: PGLUtesselator, which: TGLenum, value: PGLdouble){.
+    dynlib: dllname, importc: "gluGetTessProperty".}
+proc gluNewNurbsRenderer*(): PGLUnurbs{.dynlib: dllname, 
+                                        importc: "gluNewNurbsRenderer".}
+proc gluDeleteNurbsRenderer*(nobj: PGLUnurbs){.dynlib: dllname, 
+    importc: "gluDeleteNurbsRenderer".}
+proc gluBeginSurface*(nobj: PGLUnurbs){.dynlib: dllname, 
+                                        importc: "gluBeginSurface".}
+proc gluBeginCurve*(nobj: PGLUnurbs){.dynlib: dllname, importc: "gluBeginCurve".}
+proc gluEndCurve*(nobj: PGLUnurbs){.dynlib: dllname, importc: "gluEndCurve".}
+proc gluEndSurface*(nobj: PGLUnurbs){.dynlib: dllname, importc: "gluEndSurface".}
+proc gluBeginTrim*(nobj: PGLUnurbs){.dynlib: dllname, importc: "gluBeginTrim".}
+proc gluEndTrim*(nobj: PGLUnurbs){.dynlib: dllname, importc: "gluEndTrim".}
+proc gluPwlCurve*(nobj: PGLUnurbs, count: TGLint, aarray: PGLfloat, 
+                  stride: TGLint, atype: TGLenum){.dynlib: dllname, 
+    importc: "gluPwlCurve".}
+proc gluNurbsCurve*(nobj: PGLUnurbs, nknots: TGLint, knot: PGLfloat, 
+                    stride: TGLint, ctlarray: PGLfloat, order: TGLint, 
+                    atype: TGLenum){.dynlib: dllname, importc: "gluNurbsCurve".}
+proc gluNurbsSurface*(nobj: PGLUnurbs, sknot_count: TGLint, sknot: PGLfloat, 
+                      tknot_count: TGLint, tknot: PGLfloat, 
+                      s_stride, t_stride: TGLint, ctlarray: PGLfloat, 
+                      sorder, torder: TGLint, atype: TGLenum){.dynlib: dllname, 
+    importc: "gluNurbsSurface".}
+proc gluLoadSamplingMatrices*(nobj: PGLUnurbs, 
+                              modelMatrix, projMatrix: var T16dArray, 
+                              viewport: var TViewPortArray){.dynlib: dllname, 
+    importc: "gluLoadSamplingMatrices".}
+proc gluNurbsProperty*(nobj: PGLUnurbs, aproperty: TGLenum, value: TGLfloat){.
+    dynlib: dllname, importc: "gluNurbsProperty".}
+proc gluGetNurbsProperty*(nobj: PGLUnurbs, aproperty: TGLenum, value: PGLfloat){.
+    dynlib: dllname, importc: "gluGetNurbsProperty".}
+proc gluNurbsCallback*(nobj: PGLUnurbs, which: TGLenum, fn: TCallBack){.
+    dynlib: dllname, importc: "gluNurbsCallback".}
+  #*** Callback function prototypes ***
+type                          # gluQuadricCallback
+  GLUquadricErrorProc* = proc (p: TGLenum) # gluTessCallback
+  GLUtessBeginProc* = proc (p: TGLenum)
+  GLUtessEdgeFlagProc* = proc (p: TGLboolean)
+  GLUtessVertexProc* = proc (p: Pointer)
+  GLUtessEndProc* = proc ()
+  GLUtessErrorProc* = proc (p: TGLenum)
+  GLUtessCombineProc* = proc (p1: var T3dArray, p2: T4pArray, p3: T4fArray, 
+                              p4: PPointer)
+  GLUtessBeginDataProc* = proc (p1: TGLenum, p2: Pointer)
+  GLUtessEdgeFlagDataProc* = proc (p1: TGLboolean, p2: Pointer)
+  GLUtessVertexDataProc* = proc (p1, p2: Pointer)
+  GLUtessEndDataProc* = proc (p: Pointer)
+  GLUtessErrorDataProc* = proc (p1: TGLenum, p2: Pointer)
+  GLUtessCombineDataProc* = proc (p1: var T3dArray, p2: var T4pArray, 
+                                  p3: var T4fArray, p4: PPointer, p5: Pointer) # 
+                                                                               # 
+                                                                               # gluNurbsCallback
+  GLUnurbsErrorProc* = proc (p: TGLenum) #***           Generic constants               ****/
+
+const                         # Version
+  GLU_VERSION_1_1* = 1
+  GLU_VERSION_1_2* = 1        # Errors: (return value 0 = no error)
+  GLU_INVALID_ENUM* = 100900
+  GLU_INVALID_VALUE* = 100901
+  GLU_OUT_OF_MEMORY* = 100902
+  GLU_INCOMPATIBLE_GL_VERSION* = 100903 # StringName
+  GLU_VERSION* = 100800
+  GLU_EXTENSIONS* = 100801    # Boolean
+  GLU_TRUE* = GL_TRUE
+  GLU_FALSE* = GL_FALSE #***           Quadric constants               ****/
+                        # QuadricNormal
+  GLU_SMOOTH* = 100000
+  GLU_FLAT* = 100001
+  GLU_NONE* = 100002          # QuadricDrawStyle
+  GLU_POINT* = 100010
+  GLU_LINE* = 100011
+  GLU_FILL* = 100012
+  GLU_SILHOUETTE* = 100013    # QuadricOrientation
+  GLU_OUTSIDE* = 100020
+  GLU_INSIDE* = 100021        # Callback types:
+                              #      GLU_ERROR       = 100103;
+                              #***           Tesselation constants           ****/
+  GLU_TESS_MAX_COORD* = 1.00000e+150 # TessProperty
+  GLU_TESS_WINDING_RULE* = 100140
+  GLU_TESS_BOUNDARY_ONLY* = 100141
+  GLU_TESS_TOLERANCE* = 100142 # TessWinding
+  GLU_TESS_WINDING_ODD* = 100130
+  GLU_TESS_WINDING_NONZERO* = 100131
+  GLU_TESS_WINDING_POSITIVE* = 100132
+  GLU_TESS_WINDING_NEGATIVE* = 100133
+  GLU_TESS_WINDING_ABS_GEQ_TWO* = 100134 # TessCallback
+  GLU_TESS_BEGIN* = 100100    # void (CALLBACK*)(TGLenum    type)
+  constGLU_TESS_VERTEX* = 100101 # void (CALLBACK*)(void      *data)
+  GLU_TESS_END* = 100102      # void (CALLBACK*)(void)
+  GLU_TESS_ERROR* = 100103    # void (CALLBACK*)(TGLenum    errno)
+  GLU_TESS_EDGE_FLAG* = 100104 # void (CALLBACK*)(TGLboolean boundaryEdge)
+  GLU_TESS_COMBINE* = 100105 # void (CALLBACK*)(TGLdouble  coords[3],
+                             #                                                            void      *data[4],
+                             #                                                            TGLfloat   weight[4],
+                             #                                                            void      **dataOut) 
+  GLU_TESS_BEGIN_DATA* = 100106 # void (CALLBACK*)(TGLenum    type,
+                                #                                                            void      *polygon_data) 
+  GLU_TESS_VERTEX_DATA* = 100107 # void (CALLBACK*)(void      *data,
+                                 #                                                            void      *polygon_data) 
+  GLU_TESS_END_DATA* = 100108 # void (CALLBACK*)(void      *polygon_data)
+  GLU_TESS_ERROR_DATA* = 100109 # void (CALLBACK*)(TGLenum    errno,
+                                #                                                            void      *polygon_data) 
+  GLU_TESS_EDGE_FLAG_DATA* = 100110 # void (CALLBACK*)(TGLboolean boundaryEdge,
+                                    #                                                            void      *polygon_data) 
+  GLU_TESS_COMBINE_DATA* = 100111 # void (CALLBACK*)(TGLdouble  coords[3],
+                                  #                                                            void      *data[4],
+                                  #                                                            TGLfloat   weight[4],
+                                  #                                                            void      **dataOut,
+                                  #                                                            void      *polygon_data) 
+                                  # TessError
+  GLU_TESS_ERROR1* = 100151
+  GLU_TESS_ERROR2* = 100152
+  GLU_TESS_ERROR3* = 100153
+  GLU_TESS_ERROR4* = 100154
+  GLU_TESS_ERROR5* = 100155
+  GLU_TESS_ERROR6* = 100156
+  GLU_TESS_ERROR7* = 100157
+  GLU_TESS_ERROR8* = 100158
+  GLU_TESS_MISSING_BEGIN_POLYGON* = GLU_TESS_ERROR1
+  GLU_TESS_MISSING_BEGIN_CONTOUR* = GLU_TESS_ERROR2
+  GLU_TESS_MISSING_END_POLYGON* = GLU_TESS_ERROR3
+  GLU_TESS_MISSING_END_CONTOUR* = GLU_TESS_ERROR4
+  GLU_TESS_COORD_TOO_LARGE* = GLU_TESS_ERROR5
+  GLU_TESS_NEED_COMBINE_CALLBACK* = GLU_TESS_ERROR6 #***           NURBS constants                 ****/
+                                                    # NurbsProperty
+  GLU_AUTO_LOAD_MATRIX* = 100200
+  GLU_CULLING* = 100201
+  GLU_SAMPLING_TOLERANCE* = 100203
+  GLU_DISPLAY_MODE* = 100204
+  GLU_PARAMETRIC_TOLERANCE* = 100202
+  GLU_SAMPLING_METHOD* = 100205
+  GLU_U_STEP* = 100206
+  GLU_V_STEP* = 100207        # NurbsSampling
+  GLU_PATH_LENGTH* = 100215
+  GLU_PARAMETRIC_ERROR* = 100216
+  GLU_DOMAIN_DISTANCE* = 100217 # NurbsTrim
+  GLU_MAP1_TRIM_2* = 100210
+  GLU_MAP1_TRIM_3* = 100211   # NurbsDisplay
+                              #      GLU_FILL                = 100012;
+  GLU_OUTLINE_POLYGON* = 100240
+  GLU_OUTLINE_PATCH* = 100241 # NurbsCallback
+                              #      GLU_ERROR               = 100103;
+                              # NurbsErrors
+  GLU_NURBS_ERROR1* = 100251
+  GLU_NURBS_ERROR2* = 100252
+  GLU_NURBS_ERROR3* = 100253
+  GLU_NURBS_ERROR4* = 100254
+  GLU_NURBS_ERROR5* = 100255
+  GLU_NURBS_ERROR6* = 100256
+  GLU_NURBS_ERROR7* = 100257
+  GLU_NURBS_ERROR8* = 100258
+  GLU_NURBS_ERROR9* = 100259
+  GLU_NURBS_ERROR10* = 100260
+  GLU_NURBS_ERROR11* = 100261
+  GLU_NURBS_ERROR12* = 100262
+  GLU_NURBS_ERROR13* = 100263
+  GLU_NURBS_ERROR14* = 100264
+  GLU_NURBS_ERROR15* = 100265
+  GLU_NURBS_ERROR16* = 100266
+  GLU_NURBS_ERROR17* = 100267
+  GLU_NURBS_ERROR18* = 100268
+  GLU_NURBS_ERROR19* = 100269
+  GLU_NURBS_ERROR20* = 100270
+  GLU_NURBS_ERROR21* = 100271
+  GLU_NURBS_ERROR22* = 100272
+  GLU_NURBS_ERROR23* = 100273
+  GLU_NURBS_ERROR24* = 100274
+  GLU_NURBS_ERROR25* = 100275
+  GLU_NURBS_ERROR26* = 100276
+  GLU_NURBS_ERROR27* = 100277
+  GLU_NURBS_ERROR28* = 100278
+  GLU_NURBS_ERROR29* = 100279
+  GLU_NURBS_ERROR30* = 100280
+  GLU_NURBS_ERROR31* = 100281
+  GLU_NURBS_ERROR32* = 100282
+  GLU_NURBS_ERROR33* = 100283
+  GLU_NURBS_ERROR34* = 100284
+  GLU_NURBS_ERROR35* = 100285
+  GLU_NURBS_ERROR36* = 100286
+  GLU_NURBS_ERROR37* = 100287 #***           Backwards compatibility for old tesselator           ****/
+
+proc gluBeginPolygon*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluBeginPolygon".}
+proc gluNextContour*(tess: PGLUtesselator, atype: TGLenum){.dynlib: dllname, 
+    importc: "gluNextContour".}
+proc gluEndPolygon*(tess: PGLUtesselator){.dynlib: dllname, 
+    importc: "gluEndPolygon".}
+const                         # Contours types -- obsolete!
+  GLU_CW* = 100120
+  GLU_CCW* = 100121
+  GLU_INTERIOR* = 100122
+  GLU_EXTERIOR* = 100123
+  GLU_UNKNOWN* = 100124       # Names without "TESS_" prefix
+  GLU_BEGIN* = GLU_TESS_BEGIN
+  GLU_VERTEX* = constGLU_TESS_VERTEX
+  GLU_END* = GLU_TESS_END
+  GLU_ERROR* = GLU_TESS_ERROR
+  GLU_EDGE_FLAG* = GLU_TESS_EDGE_FLAG
+
+{.pop.}
+# implementation
diff --git a/tests/manyloc/keineschweine/lib/glut.nim b/tests/manyloc/keineschweine/lib/glut.nim
new file mode 100644
index 000000000..ff157c327
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/glut.nim
@@ -0,0 +1,438 @@
+#
+#
+#  Adaption of the delphi3d.net OpenGL units to FreePascal
+#  Sebastian Guenther (sg@freepascal.org) in 2002
+#  These units are free to use
+#
+
+# Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
+# This program is freely distributable without licensing fees  and is
+#   provided without guarantee or warrantee expressed or  implied. This
+#   program is -not- in the public domain.
+#******************************************************************************
+# Converted to Delphi by Tom Nuydens (tom@delphi3d.net)
+#   Contributions by Igor Karpov (glygrik@hotbox.ru)
+#   For the latest updates, visit Delphi3D: http://www.delphi3d.net
+#******************************************************************************
+
+import 
+  GL
+
+when defined(windows): 
+  const 
+    dllname = "glut32.dll"
+elif defined(macosx): 
+  const 
+    dllname = "/System/Library/Frameworks/GLUT.framework/GLUT"
+else: 
+  const 
+    dllname = "libglut.so.3"
+type
+  TGlutVoidCallback* = proc (){.cdecl.}
+  TGlut1IntCallback* = proc (value: cint){.cdecl.}
+  TGlut2IntCallback* = proc (v1, v2: cint){.cdecl.}
+  TGlut3IntCallback* = proc (v1, v2, v3: cint){.cdecl.}
+  TGlut4IntCallback* = proc (v1, v2, v3, v4: cint){.cdecl.}
+  TGlut1Char2IntCallback* = proc (c: int8, v1, v2: cint){.cdecl.}
+  TGlut1UInt3IntCallback* = proc (u, v1, v2, v3: cint){.cdecl.}
+
+const 
+  GLUT_API_VERSION* = 3
+  GLUT_XLIB_IMPLEMENTATION* = 12 # Display mode bit masks.
+  GLUT_RGB* = 0
+  GLUT_RGBA* = GLUT_RGB
+  GLUT_INDEX* = 1
+  GLUT_SINGLE* = 0
+  GLUT_DOUBLE* = 2
+  GLUT_ACCUM* = 4
+  GLUT_ALPHA* = 8
+  GLUT_DEPTH* = 16
+  GLUT_STENCIL* = 32
+  GLUT_MULTISAMPLE* = 128
+  GLUT_STEREO* = 256
+  GLUT_LUMINANCE* = 512       # Mouse buttons.
+  GLUT_LEFT_BUTTON* = 0
+  GLUT_MIDDLE_BUTTON* = 1
+  GLUT_RIGHT_BUTTON* = 2      # Mouse button state.
+  GLUT_DOWN* = 0
+  GLUT_UP* = 1                # function keys
+  GLUT_KEY_F1* = 1
+  GLUT_KEY_F2* = 2
+  GLUT_KEY_F3* = 3
+  GLUT_KEY_F4* = 4
+  GLUT_KEY_F5* = 5
+  GLUT_KEY_F6* = 6
+  GLUT_KEY_F7* = 7
+  GLUT_KEY_F8* = 8
+  GLUT_KEY_F9* = 9
+  GLUT_KEY_F10* = 10
+  GLUT_KEY_F11* = 11
+  GLUT_KEY_F12* = 12          # directional keys
+  GLUT_KEY_LEFT* = 100
+  GLUT_KEY_UP* = 101
+  GLUT_KEY_RIGHT* = 102
+  GLUT_KEY_DOWN* = 103
+  GLUT_KEY_PAGE_UP* = 104
+  GLUT_KEY_PAGE_DOWN* = 105
+  GLUT_KEY_HOME* = 106
+  GLUT_KEY_END* = 107
+  GLUT_KEY_INSERT* = 108      # Entry/exit  state.
+  GLUT_LEFT* = 0
+  GLUT_ENTERED* = 1           # Menu usage state.
+  GLUT_MENU_NOT_IN_USE* = 0
+  GLUT_MENU_IN_USE* = 1       # Visibility  state.
+  GLUT_NOT_VISIBLE* = 0
+  GLUT_VISIBLE* = 1           # Window status  state.
+  GLUT_HIDDEN* = 0
+  GLUT_FULLY_RETAINED* = 1
+  GLUT_PARTIALLY_RETAINED* = 2
+  GLUT_FULLY_COVERED* = 3     # Color index component selection values.
+  GLUT_RED* = 0
+  GLUT_GREEN* = 1
+  GLUT_BLUE* = 2              # Layers for use.
+  GLUT_NORMAL* = 0
+  GLUT_OVERLAY* = 1
+
+when defined(Windows): 
+  const                       # Stroke font constants (use these in GLUT program).
+    GLUT_STROKE_ROMAN* = cast[Pointer](0)
+    GLUT_STROKE_MONO_ROMAN* = cast[Pointer](1) # Bitmap font constants (use these in GLUT program).
+    GLUT_BITMAP_9_BY_15* = cast[Pointer](2)
+    GLUT_BITMAP_8_BY_13* = cast[Pointer](3)
+    GLUT_BITMAP_TIMES_ROMAN_10* = cast[Pointer](4)
+    GLUT_BITMAP_TIMES_ROMAN_24* = cast[Pointer](5)
+    GLUT_BITMAP_HELVETICA_10* = cast[Pointer](6)
+    GLUT_BITMAP_HELVETICA_12* = cast[Pointer](7)
+    GLUT_BITMAP_HELVETICA_18* = cast[Pointer](8)
+else: 
+  var                         # Stroke font constants (use these in GLUT program).
+    GLUT_STROKE_ROMAN*: Pointer
+    GLUT_STROKE_MONO_ROMAN*: Pointer # Bitmap font constants (use these in GLUT program).
+    GLUT_BITMAP_9_BY_15*: Pointer
+    GLUT_BITMAP_8_BY_13*: Pointer
+    GLUT_BITMAP_TIMES_ROMAN_10*: Pointer
+    GLUT_BITMAP_TIMES_ROMAN_24*: Pointer
+    GLUT_BITMAP_HELVETICA_10*: Pointer
+    GLUT_BITMAP_HELVETICA_12*: Pointer
+    GLUT_BITMAP_HELVETICA_18*: Pointer
+const                         # glutGet parameters.
+  GLUT_WINDOW_X* = 100
+  GLUT_WINDOW_Y* = 101
+  GLUT_WINDOW_WIDTH* = 102
+  GLUT_WINDOW_HEIGHT* = 103
+  GLUT_WINDOW_BUFFER_SIZE* = 104
+  GLUT_WINDOW_STENCIL_SIZE* = 105
+  GLUT_WINDOW_DEPTH_SIZE* = 106
+  GLUT_WINDOW_RED_SIZE* = 107
+  GLUT_WINDOW_GREEN_SIZE* = 108
+  GLUT_WINDOW_BLUE_SIZE* = 109
+  GLUT_WINDOW_ALPHA_SIZE* = 110
+  GLUT_WINDOW_ACCUM_RED_SIZE* = 111
+  GLUT_WINDOW_ACCUM_GREEN_SIZE* = 112
+  GLUT_WINDOW_ACCUM_BLUE_SIZE* = 113
+  GLUT_WINDOW_ACCUM_ALPHA_SIZE* = 114
+  GLUT_WINDOW_DOUBLEBUFFER* = 115
+  GLUT_WINDOW_RGBA* = 116
+  GLUT_WINDOW_PARENT* = 117
+  GLUT_WINDOW_NUM_CHILDREN* = 118
+  GLUT_WINDOW_COLORMAP_SIZE* = 119
+  GLUT_WINDOW_NUM_SAMPLES* = 120
+  GLUT_WINDOW_STEREO* = 121
+  GLUT_WINDOW_CURSOR* = 122
+  GLUT_SCREEN_WIDTH* = 200
+  GLUT_SCREEN_HEIGHT* = 201
+  GLUT_SCREEN_WIDTH_MM* = 202
+  GLUT_SCREEN_HEIGHT_MM* = 203
+  GLUT_MENU_NUM_ITEMS* = 300
+  GLUT_DISPLAY_MODE_POSSIBLE* = 400
+  GLUT_INIT_WINDOW_X* = 500
+  GLUT_INIT_WINDOW_Y* = 501
+  GLUT_INIT_WINDOW_WIDTH* = 502
+  GLUT_INIT_WINDOW_HEIGHT* = 503
+  constGLUT_INIT_DISPLAY_MODE* = 504
+  GLUT_ELAPSED_TIME* = 700
+  GLUT_WINDOW_FORMAT_ID* = 123 # glutDeviceGet parameters.
+  GLUT_HAS_KEYBOARD* = 600
+  GLUT_HAS_MOUSE* = 601
+  GLUT_HAS_SPACEBALL* = 602
+  GLUT_HAS_DIAL_AND_BUTTON_BOX* = 603
+  GLUT_HAS_TABLET* = 604
+  GLUT_NUM_MOUSE_BUTTONS* = 605
+  GLUT_NUM_SPACEBALL_BUTTONS* = 606
+  GLUT_NUM_BUTTON_BOX_BUTTONS* = 607
+  GLUT_NUM_DIALS* = 608
+  GLUT_NUM_TABLET_BUTTONS* = 609
+  GLUT_DEVICE_IGNORE_KEY_REPEAT* = 610
+  GLUT_DEVICE_KEY_REPEAT* = 611
+  GLUT_HAS_JOYSTICK* = 612
+  GLUT_OWNS_JOYSTICK* = 613
+  GLUT_JOYSTICK_BUTTONS* = 614
+  GLUT_JOYSTICK_AXES* = 615
+  GLUT_JOYSTICK_POLL_RATE* = 616 # glutLayerGet parameters.
+  GLUT_OVERLAY_POSSIBLE* = 800
+  GLUT_LAYER_IN_USE* = 801
+  GLUT_HAS_OVERLAY* = 802
+  GLUT_TRANSPARENT_INDEX* = 803
+  GLUT_NORMAL_DAMAGED* = 804
+  GLUT_OVERLAY_DAMAGED* = 805 # glutVideoResizeGet parameters.
+  GLUT_VIDEO_RESIZE_POSSIBLE* = 900
+  GLUT_VIDEO_RESIZE_IN_USE* = 901
+  GLUT_VIDEO_RESIZE_X_DELTA* = 902
+  GLUT_VIDEO_RESIZE_Y_DELTA* = 903
+  GLUT_VIDEO_RESIZE_WIDTH_DELTA* = 904
+  GLUT_VIDEO_RESIZE_HEIGHT_DELTA* = 905
+  GLUT_VIDEO_RESIZE_X* = 906
+  GLUT_VIDEO_RESIZE_Y* = 907
+  GLUT_VIDEO_RESIZE_WIDTH* = 908
+  GLUT_VIDEO_RESIZE_HEIGHT* = 909 # glutGetModifiers return mask.
+  GLUT_ACTIVE_SHIFT* = 1
+  GLUT_ACTIVE_CTRL* = 2
+  GLUT_ACTIVE_ALT* = 4        # glutSetCursor parameters.
+                              # Basic arrows.
+  GLUT_CURSOR_RIGHT_ARROW* = 0
+  GLUT_CURSOR_LEFT_ARROW* = 1 # Symbolic cursor shapes.
+  GLUT_CURSOR_INFO* = 2
+  GLUT_CURSOR_DESTROY* = 3
+  GLUT_CURSOR_HELP* = 4
+  GLUT_CURSOR_CYCLE* = 5
+  GLUT_CURSOR_SPRAY* = 6
+  GLUT_CURSOR_WAIT* = 7
+  GLUT_CURSOR_TEXT* = 8
+  GLUT_CURSOR_CROSSHAIR* = 9  # Directional cursors.
+  GLUT_CURSOR_UP_DOWN* = 10
+  GLUT_CURSOR_LEFT_RIGHT* = 11 # Sizing cursors.
+  GLUT_CURSOR_TOP_SIDE* = 12
+  GLUT_CURSOR_BOTTOM_SIDE* = 13
+  GLUT_CURSOR_LEFT_SIDE* = 14
+  GLUT_CURSOR_RIGHT_SIDE* = 15
+  GLUT_CURSOR_TOP_LEFT_CORNER* = 16
+  GLUT_CURSOR_TOP_RIGHT_CORNER* = 17
+  GLUT_CURSOR_BOTTOM_RIGHT_CORNER* = 18
+  GLUT_CURSOR_BOTTOM_LEFT_CORNER* = 19 # Inherit from parent window.
+  GLUT_CURSOR_INHERIT* = 100  # Blank cursor.
+  GLUT_CURSOR_NONE* = 101     # Fullscreen crosshair (if available).
+  GLUT_CURSOR_FULL_CROSSHAIR* = 102 # GLUT device control sub-API.
+                                    # glutSetKeyRepeat modes.
+  GLUT_KEY_REPEAT_OFF* = 0
+  GLUT_KEY_REPEAT_ON* = 1
+  GLUT_KEY_REPEAT_DEFAULT* = 2 # Joystick button masks.
+  GLUT_JOYSTICK_BUTTON_A* = 1
+  GLUT_JOYSTICK_BUTTON_B* = 2
+  GLUT_JOYSTICK_BUTTON_C* = 4
+  GLUT_JOYSTICK_BUTTON_D* = 8 # GLUT game mode sub-API.
+                              # glutGameModeGet.
+  GLUT_GAME_MODE_ACTIVE* = 0
+  GLUT_GAME_MODE_POSSIBLE* = 1
+  GLUT_GAME_MODE_WIDTH* = 2
+  GLUT_GAME_MODE_HEIGHT* = 3
+  GLUT_GAME_MODE_PIXEL_DEPTH* = 4
+  GLUT_GAME_MODE_REFRESH_RATE* = 5
+  GLUT_GAME_MODE_DISPLAY_CHANGED* = 6 # GLUT initialization sub-API.
+
+proc glutInit*(argcp: ptr cint, argv: pointer){.dynlib: dllname, 
+    importc: "glutInit".}
+
+proc glutInit*() =
+  ## version that passes `argc` and `argc` implicitely.
+  var
+    cmdLine {.importc: "cmdLine".}: array[0..255, cstring]
+    cmdCount {.importc: "cmdCount".}: cint
+  glutInit(addr(cmdCount), addr(cmdLine))
+
+proc glutInitDisplayMode*(mode: int16){.dynlib: dllname, 
+                                        importc: "glutInitDisplayMode".}
+proc glutInitDisplayString*(str: cstring){.dynlib: dllname, 
+    importc: "glutInitDisplayString".}
+proc glutInitWindowPosition*(x, y: int){.dynlib: dllname, 
+    importc: "glutInitWindowPosition".}
+proc glutInitWindowSize*(width, height: int){.dynlib: dllname, 
+    importc: "glutInitWindowSize".}
+proc glutMainLoop*(){.dynlib: dllname, importc: "glutMainLoop".}
+  # GLUT window sub-API.
+proc glutCreateWindow*(title: cstring): int{.dynlib: dllname, 
+    importc: "glutCreateWindow".}
+proc glutCreateSubWindow*(win, x, y, width, height: int): int{.dynlib: dllname, 
+    importc: "glutCreateSubWindow".}
+proc glutDestroyWindow*(win: int){.dynlib: dllname, importc: "glutDestroyWindow".}
+proc glutPostRedisplay*(){.dynlib: dllname, importc: "glutPostRedisplay".}
+proc glutPostWindowRedisplay*(win: int){.dynlib: dllname, 
+    importc: "glutPostWindowRedisplay".}
+proc glutSwapBuffers*(){.dynlib: dllname, importc: "glutSwapBuffers".}
+proc glutGetWindow*(): int{.dynlib: dllname, importc: "glutGetWindow".}
+proc glutSetWindow*(win: int){.dynlib: dllname, importc: "glutSetWindow".}
+proc glutSetWindowTitle*(title: cstring){.dynlib: dllname, 
+    importc: "glutSetWindowTitle".}
+proc glutSetIconTitle*(title: cstring){.dynlib: dllname, 
+                                        importc: "glutSetIconTitle".}
+proc glutPositionWindow*(x, y: int){.dynlib: dllname, 
+                                     importc: "glutPositionWindow".}
+proc glutReshapeWindow*(width, height: int){.dynlib: dllname, 
+    importc: "glutReshapeWindow".}
+proc glutPopWindow*(){.dynlib: dllname, importc: "glutPopWindow".}
+proc glutPushWindow*(){.dynlib: dllname, importc: "glutPushWindow".}
+proc glutIconifyWindow*(){.dynlib: dllname, importc: "glutIconifyWindow".}
+proc glutShowWindow*(){.dynlib: dllname, importc: "glutShowWindow".}
+proc glutHideWindow*(){.dynlib: dllname, importc: "glutHideWindow".}
+proc glutFullScreen*(){.dynlib: dllname, importc: "glutFullScreen".}
+proc glutSetCursor*(cursor: int){.dynlib: dllname, importc: "glutSetCursor".}
+proc glutWarpPointer*(x, y: int){.dynlib: dllname, importc: "glutWarpPointer".}
+  # GLUT overlay sub-API.
+proc glutEstablishOverlay*(){.dynlib: dllname, importc: "glutEstablishOverlay".}
+proc glutRemoveOverlay*(){.dynlib: dllname, importc: "glutRemoveOverlay".}
+proc glutUseLayer*(layer: TGLenum){.dynlib: dllname, importc: "glutUseLayer".}
+proc glutPostOverlayRedisplay*(){.dynlib: dllname, 
+                                  importc: "glutPostOverlayRedisplay".}
+proc glutPostWindowOverlayRedisplay*(win: int){.dynlib: dllname, 
+    importc: "glutPostWindowOverlayRedisplay".}
+proc glutShowOverlay*(){.dynlib: dllname, importc: "glutShowOverlay".}
+proc glutHideOverlay*(){.dynlib: dllname, importc: "glutHideOverlay".}
+  # GLUT menu sub-API.
+proc glutCreateMenu*(callback: TGlut1IntCallback): int{.dynlib: dllname, 
+    importc: "glutCreateMenu".}
+proc glutDestroyMenu*(menu: int){.dynlib: dllname, importc: "glutDestroyMenu".}
+proc glutGetMenu*(): int{.dynlib: dllname, importc: "glutGetMenu".}
+proc glutSetMenu*(menu: int){.dynlib: dllname, importc: "glutSetMenu".}
+proc glutAddMenuEntry*(caption: cstring, value: int){.dynlib: dllname, 
+    importc: "glutAddMenuEntry".}
+proc glutAddSubMenu*(caption: cstring, submenu: int){.dynlib: dllname, 
+    importc: "glutAddSubMenu".}
+proc glutChangeToMenuEntry*(item: int, caption: cstring, value: int){.
+    dynlib: dllname, importc: "glutChangeToMenuEntry".}
+proc glutChangeToSubMenu*(item: int, caption: cstring, submenu: int){.
+    dynlib: dllname, importc: "glutChangeToSubMenu".}
+proc glutRemoveMenuItem*(item: int){.dynlib: dllname, 
+                                     importc: "glutRemoveMenuItem".}
+proc glutAttachMenu*(button: int){.dynlib: dllname, importc: "glutAttachMenu".}
+proc glutDetachMenu*(button: int){.dynlib: dllname, importc: "glutDetachMenu".}
+  # GLUT window callback sub-API.
+proc glutDisplayFunc*(f: TGlutVoidCallback){.dynlib: dllname, 
+    importc: "glutDisplayFunc".}
+proc glutReshapeFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutReshapeFunc".}
+proc glutKeyboardFunc*(f: TGlut1Char2IntCallback){.dynlib: dllname, 
+    importc: "glutKeyboardFunc".}
+proc glutMouseFunc*(f: TGlut4IntCallback){.dynlib: dllname, 
+    importc: "glutMouseFunc".}
+proc glutMotionFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutMotionFunc".}
+proc glutPassiveMotionFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutPassiveMotionFunc".}
+proc glutEntryFunc*(f: TGlut1IntCallback){.dynlib: dllname, 
+    importc: "glutEntryFunc".}
+proc glutVisibilityFunc*(f: TGlut1IntCallback){.dynlib: dllname, 
+    importc: "glutVisibilityFunc".}
+proc glutIdleFunc*(f: TGlutVoidCallback){.dynlib: dllname, 
+    importc: "glutIdleFunc".}
+proc glutTimerFunc*(millis: int16, f: TGlut1IntCallback, value: int){.
+    dynlib: dllname, importc: "glutTimerFunc".}
+proc glutMenuStateFunc*(f: TGlut1IntCallback){.dynlib: dllname, 
+    importc: "glutMenuStateFunc".}
+proc glutSpecialFunc*(f: TGlut3IntCallback){.dynlib: dllname, 
+    importc: "glutSpecialFunc".}
+proc glutSpaceballMotionFunc*(f: TGlut3IntCallback){.dynlib: dllname, 
+    importc: "glutSpaceballMotionFunc".}
+proc glutSpaceballRotateFunc*(f: TGlut3IntCallback){.dynlib: dllname, 
+    importc: "glutSpaceballRotateFunc".}
+proc glutSpaceballButtonFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutSpaceballButtonFunc".}
+proc glutButtonBoxFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutButtonBoxFunc".}
+proc glutDialsFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutDialsFunc".}
+proc glutTabletMotionFunc*(f: TGlut2IntCallback){.dynlib: dllname, 
+    importc: "glutTabletMotionFunc".}
+proc glutTabletButtonFunc*(f: TGlut4IntCallback){.dynlib: dllname, 
+    importc: "glutTabletButtonFunc".}
+proc glutMenuStatusFunc*(f: TGlut3IntCallback){.dynlib: dllname, 
+    importc: "glutMenuStatusFunc".}
+proc glutOverlayDisplayFunc*(f: TGlutVoidCallback){.dynlib: dllname, 
+    importc: "glutOverlayDisplayFunc".}
+proc glutWindowStatusFunc*(f: TGlut1IntCallback){.dynlib: dllname, 
+    importc: "glutWindowStatusFunc".}
+proc glutKeyboardUpFunc*(f: TGlut1Char2IntCallback){.dynlib: dllname, 
+    importc: "glutKeyboardUpFunc".}
+proc glutSpecialUpFunc*(f: TGlut3IntCallback){.dynlib: dllname, 
+    importc: "glutSpecialUpFunc".}
+proc glutJoystickFunc*(f: TGlut1UInt3IntCallback, pollInterval: int){.
+    dynlib: dllname, importc: "glutJoystickFunc".}
+  # GLUT color index sub-API.
+proc glutSetColor*(cell: int, red, green, blue: TGLfloat){.dynlib: dllname, 
+    importc: "glutSetColor".}
+proc glutGetColor*(ndx, component: int): TGLfloat{.dynlib: dllname, 
+    importc: "glutGetColor".}
+proc glutCopyColormap*(win: int){.dynlib: dllname, importc: "glutCopyColormap".}
+  # GLUT state retrieval sub-API.
+proc glutGet*(t: TGLenum): int{.dynlib: dllname, importc: "glutGet".}
+proc glutDeviceGet*(t: TGLenum): int{.dynlib: dllname, importc: "glutDeviceGet".}
+  # GLUT extension support sub-API
+proc glutExtensionSupported*(name: cstring): int{.dynlib: dllname, 
+    importc: "glutExtensionSupported".}
+proc glutGetModifiers*(): int{.dynlib: dllname, importc: "glutGetModifiers".}
+proc glutLayerGet*(t: TGLenum): int{.dynlib: dllname, importc: "glutLayerGet".}
+  # GLUT font sub-API
+proc glutBitmapCharacter*(font: pointer, character: int){.dynlib: dllname, 
+    importc: "glutBitmapCharacter".}
+proc glutBitmapWidth*(font: pointer, character: int): int{.dynlib: dllname, 
+    importc: "glutBitmapWidth".}
+proc glutStrokeCharacter*(font: pointer, character: int){.dynlib: dllname, 
+    importc: "glutStrokeCharacter".}
+proc glutStrokeWidth*(font: pointer, character: int): int{.dynlib: dllname, 
+    importc: "glutStrokeWidth".}
+proc glutBitmapLength*(font: pointer, str: cstring): int{.dynlib: dllname, 
+    importc: "glutBitmapLength".}
+proc glutStrokeLength*(font: pointer, str: cstring): int{.dynlib: dllname, 
+    importc: "glutStrokeLength".}
+  # GLUT pre-built models sub-API
+proc glutWireSphere*(radius: TGLdouble, slices, stacks: TGLint){.
+    dynlib: dllname, importc: "glutWireSphere".}
+proc glutSolidSphere*(radius: TGLdouble, slices, stacks: TGLint){.
+    dynlib: dllname, importc: "glutSolidSphere".}
+proc glutWireCone*(base, height: TGLdouble, slices, stacks: TGLint){.
+    dynlib: dllname, importc: "glutWireCone".}
+proc glutSolidCone*(base, height: TGLdouble, slices, stacks: TGLint){.
+    dynlib: dllname, importc: "glutSolidCone".}
+proc glutWireCube*(size: TGLdouble){.dynlib: dllname, importc: "glutWireCube".}
+proc glutSolidCube*(size: TGLdouble){.dynlib: dllname, importc: "glutSolidCube".}
+proc glutWireTorus*(innerRadius, outerRadius: TGLdouble, sides, rings: TGLint){.
+    dynlib: dllname, importc: "glutWireTorus".}
+proc glutSolidTorus*(innerRadius, outerRadius: TGLdouble, sides, rings: TGLint){.
+    dynlib: dllname, importc: "glutSolidTorus".}
+proc glutWireDodecahedron*(){.dynlib: dllname, importc: "glutWireDodecahedron".}
+proc glutSolidDodecahedron*(){.dynlib: dllname, importc: "glutSolidDodecahedron".}
+proc glutWireTeapot*(size: TGLdouble){.dynlib: dllname, 
+                                       importc: "glutWireTeapot".}
+proc glutSolidTeapot*(size: TGLdouble){.dynlib: dllname, 
+                                        importc: "glutSolidTeapot".}
+proc glutWireOctahedron*(){.dynlib: dllname, importc: "glutWireOctahedron".}
+proc glutSolidOctahedron*(){.dynlib: dllname, importc: "glutSolidOctahedron".}
+proc glutWireTetrahedron*(){.dynlib: dllname, importc: "glutWireTetrahedron".}
+proc glutSolidTetrahedron*(){.dynlib: dllname, importc: "glutSolidTetrahedron".}
+proc glutWireIcosahedron*(){.dynlib: dllname, importc: "glutWireIcosahedron".}
+proc glutSolidIcosahedron*(){.dynlib: dllname, importc: "glutSolidIcosahedron".}
+  # GLUT video resize sub-API.
+proc glutVideoResizeGet*(param: TGLenum): int{.dynlib: dllname, 
+    importc: "glutVideoResizeGet".}
+proc glutSetupVideoResizing*(){.dynlib: dllname, 
+                                importc: "glutSetupVideoResizing".}
+proc glutStopVideoResizing*(){.dynlib: dllname, importc: "glutStopVideoResizing".}
+proc glutVideoResize*(x, y, width, height: int){.dynlib: dllname, 
+    importc: "glutVideoResize".}
+proc glutVideoPan*(x, y, width, height: int){.dynlib: dllname, 
+    importc: "glutVideoPan".}
+  # GLUT debugging sub-API.
+proc glutReportErrors*(){.dynlib: dllname, importc: "glutReportErrors".}
+  # GLUT device control sub-API.
+proc glutIgnoreKeyRepeat*(ignore: int){.dynlib: dllname, 
+                                        importc: "glutIgnoreKeyRepeat".}
+proc glutSetKeyRepeat*(repeatMode: int){.dynlib: dllname, 
+    importc: "glutSetKeyRepeat".}
+proc glutForceJoystickFunc*(){.dynlib: dllname, importc: "glutForceJoystickFunc".}
+  # GLUT game mode sub-API.
+  #example glutGameModeString('1280x1024:32@75');
+proc glutGameModeString*(AString: cstring){.dynlib: dllname, 
+    importc: "glutGameModeString".}
+proc glutEnterGameMode*(): int{.dynlib: dllname, importc: "glutEnterGameMode".}
+proc glutLeaveGameMode*(){.dynlib: dllname, importc: "glutLeaveGameMode".}
+proc glutGameModeGet*(mode: TGLenum): int{.dynlib: dllname, 
+    importc: "glutGameModeGet".}
+# implementation
diff --git a/tests/manyloc/keineschweine/lib/glx.nim b/tests/manyloc/keineschweine/lib/glx.nim
new file mode 100644
index 000000000..76c052d70
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/glx.nim
@@ -0,0 +1,153 @@
+#
+#
+#  Translation of the Mesa GLX headers for FreePascal
+#  Copyright (C) 1999 Sebastian Guenther
+#
+#
+#  Mesa 3-D graphics library
+#  Version:  3.0
+#  Copyright (C) 1995-1998  Brian Paul
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Library General Public
+#  License as published by the Free Software Foundation; either
+#  version 2 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Library General Public License for more details.
+#
+#  You should have received a copy of the GNU Library General Public
+#  License along with this library; if not, write to the Free
+#  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import 
+  X, XLib, XUtil, gl
+
+when defined(windows): 
+  const 
+    dllname = "GL.dll"
+elif defined(macosx): 
+  const 
+    dllname = "/usr/X11R6/lib/libGL.dylib"
+else: 
+  const 
+    dllname = "libGL.so"
+const 
+  GLX_USE_GL* = 1
+  GLX_BUFFER_SIZE* = 2
+  GLX_LEVEL* = 3
+  GLX_RGBA* = 4
+  GLX_DOUBLEBUFFER* = 5
+  GLX_STEREO* = 6
+  GLX_AUX_BUFFERS* = 7
+  GLX_RED_SIZE* = 8
+  GLX_GREEN_SIZE* = 9
+  GLX_BLUE_SIZE* = 10
+  GLX_ALPHA_SIZE* = 11
+  GLX_DEPTH_SIZE* = 12
+  GLX_STENCIL_SIZE* = 13
+  GLX_ACCUM_RED_SIZE* = 14
+  GLX_ACCUM_GREEN_SIZE* = 15
+  GLX_ACCUM_BLUE_SIZE* = 16
+  GLX_ACCUM_ALPHA_SIZE* = 17  # GLX_EXT_visual_info extension
+  GLX_X_VISUAL_TYPE_EXT* = 0x00000022
+  GLX_TRANSPARENT_TYPE_EXT* = 0x00000023
+  GLX_TRANSPARENT_INDEX_VALUE_EXT* = 0x00000024
+  GLX_TRANSPARENT_RED_VALUE_EXT* = 0x00000025
+  GLX_TRANSPARENT_GREEN_VALUE_EXT* = 0x00000026
+  GLX_TRANSPARENT_BLUE_VALUE_EXT* = 0x00000027
+  GLX_TRANSPARENT_ALPHA_VALUE_EXT* = 0x00000028 # Error codes returned by glXGetConfig:
+  GLX_BAD_SCREEN* = 1
+  GLX_BAD_ATTRIBUTE* = 2
+  GLX_NO_EXTENSION* = 3
+  GLX_BAD_VISUAL* = 4
+  GLX_BAD_CONTEXT* = 5
+  GLX_BAD_VALUE* = 6
+  GLX_BAD_ENUM* = 7           # GLX 1.1 and later:
+  GLX_VENDOR* = 1
+  GLX_VERSION* = 2
+  GLX_EXTENSIONS* = 3         # GLX_visual_info extension
+  GLX_TRUE_COLOR_EXT* = 0x00008002
+  GLX_DIRECT_COLOR_EXT* = 0x00008003
+  GLX_PSEUDO_COLOR_EXT* = 0x00008004
+  GLX_STATIC_COLOR_EXT* = 0x00008005
+  GLX_GRAY_SCALE_EXT* = 0x00008006
+  GLX_STATIC_GRAY_EXT* = 0x00008007
+  GLX_NONE_EXT* = 0x00008000
+  GLX_TRANSPARENT_RGB_EXT* = 0x00008008
+  GLX_TRANSPARENT_INDEX_EXT* = 0x00008009
+
+type                          # From XLib:
+  XPixmap* = TXID
+  XFont* = TXID
+  XColormap* = TXID
+  GLXContext* = Pointer
+  GLXPixmap* = TXID
+  GLXDrawable* = TXID
+  GLXContextID* = TXID
+  TXPixmap* = XPixmap
+  TXFont* = XFont
+  TXColormap* = XColormap
+  TGLXContext* = GLXContext
+  TGLXPixmap* = GLXPixmap
+  TGLXDrawable* = GLXDrawable
+  TGLXContextID* = GLXContextID
+
+proc glXChooseVisual*(dpy: PDisplay, screen: int, attribList: ptr int32): PXVisualInfo{.
+    cdecl, dynlib: dllname, importc: "glXChooseVisual".}
+proc glXCreateContext*(dpy: PDisplay, vis: PXVisualInfo, shareList: GLXContext, 
+                       direct: bool): GLXContext{.cdecl, dynlib: dllname, 
+    importc: "glXCreateContext".}
+proc glXDestroyContext*(dpy: PDisplay, ctx: GLXContext){.cdecl, dynlib: dllname, 
+    importc: "glXDestroyContext".}
+proc glXMakeCurrent*(dpy: PDisplay, drawable: GLXDrawable, ctx: GLXContext): bool{.
+    cdecl, dynlib: dllname, importc: "glXMakeCurrent".}
+proc glXCopyContext*(dpy: PDisplay, src, dst: GLXContext, mask: int32){.cdecl, 
+    dynlib: dllname, importc: "glXCopyContext".}
+proc glXSwapBuffers*(dpy: PDisplay, drawable: GLXDrawable){.cdecl, 
+    dynlib: dllname, importc: "glXSwapBuffers".}
+proc glXCreateGLXPixmap*(dpy: PDisplay, visual: PXVisualInfo, pixmap: XPixmap): GLXPixmap{.
+    cdecl, dynlib: dllname, importc: "glXCreateGLXPixmap".}
+proc glXDestroyGLXPixmap*(dpy: PDisplay, pixmap: GLXPixmap){.cdecl, 
+    dynlib: dllname, importc: "glXDestroyGLXPixmap".}
+proc glXQueryExtension*(dpy: PDisplay, errorb, event: var int): bool{.cdecl, 
+    dynlib: dllname, importc: "glXQueryExtension".}
+proc glXQueryVersion*(dpy: PDisplay, maj, min: var int): bool{.cdecl, 
+    dynlib: dllname, importc: "glXQueryVersion".}
+proc glXIsDirect*(dpy: PDisplay, ctx: GLXContext): bool{.cdecl, dynlib: dllname, 
+    importc: "glXIsDirect".}
+proc glXGetConfig*(dpy: PDisplay, visual: PXVisualInfo, attrib: int, 
+                   value: var int): int{.cdecl, dynlib: dllname, 
+    importc: "glXGetConfig".}
+proc glXGetCurrentContext*(): GLXContext{.cdecl, dynlib: dllname, 
+    importc: "glXGetCurrentContext".}
+proc glXGetCurrentDrawable*(): GLXDrawable{.cdecl, dynlib: dllname, 
+    importc: "glXGetCurrentDrawable".}
+proc glXWaitGL*(){.cdecl, dynlib: dllname, importc: "glXWaitGL".}
+proc glXWaitX*(){.cdecl, dynlib: dllname, importc: "glXWaitX".}
+proc glXUseXFont*(font: XFont, first, count, list: int){.cdecl, dynlib: dllname, 
+    importc: "glXUseXFont".}
+  # GLX 1.1 and later
+proc glXQueryExtensionsString*(dpy: PDisplay, screen: int): cstring{.cdecl, 
+    dynlib: dllname, importc: "glXQueryExtensionsString".}
+proc glXQueryServerString*(dpy: PDisplay, screen, name: int): cstring{.cdecl, 
+    dynlib: dllname, importc: "glXQueryServerString".}
+proc glXGetClientString*(dpy: PDisplay, name: int): cstring{.cdecl, 
+    dynlib: dllname, importc: "glXGetClientString".}
+  # Mesa GLX Extensions
+proc glXCreateGLXPixmapMESA*(dpy: PDisplay, visual: PXVisualInfo, 
+                             pixmap: XPixmap, cmap: XColormap): GLXPixmap{.
+    cdecl, dynlib: dllname, importc: "glXCreateGLXPixmapMESA".}
+proc glXReleaseBufferMESA*(dpy: PDisplay, d: GLXDrawable): bool{.cdecl, 
+    dynlib: dllname, importc: "glXReleaseBufferMESA".}
+proc glXCopySubBufferMESA*(dpy: PDisplay, drawbale: GLXDrawable, 
+                           x, y, width, height: int){.cdecl, dynlib: dllname, 
+    importc: "glXCopySubBufferMESA".}
+proc glXGetVideoSyncSGI*(counter: var int32): int{.cdecl, dynlib: dllname, 
+    importc: "glXGetVideoSyncSGI".}
+proc glXWaitVideoSyncSGI*(divisor, remainder: int, count: var int32): int{.
+    cdecl, dynlib: dllname, importc: "glXWaitVideoSyncSGI".}
+# implementation
diff --git a/tests/manyloc/keineschweine/lib/wingl.nim b/tests/manyloc/keineschweine/lib/wingl.nim
new file mode 100644
index 000000000..7ed78f970
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/wingl.nim
@@ -0,0 +1,368 @@
+import 
+  gl, windows
+
+proc wglGetExtensionsStringARB*(hdc: HDC): cstring{.dynlib: dllname, 
+    importc: "wglGetExtensionsStringARB".}
+const 
+  WGL_FRONT_COLOR_BUFFER_BIT_ARB* = 0x00000001
+  WGL_BACK_COLOR_BUFFER_BIT_ARB* = 0x00000002
+  WGL_DEPTH_BUFFER_BIT_ARB* = 0x00000004
+  WGL_STENCIL_BUFFER_BIT_ARB* = 0x00000008
+
+proc WinChoosePixelFormat*(DC: HDC, p2: PPixelFormatDescriptor): int{.
+    dynlib: "gdi32", importc: "ChoosePixelFormat".}
+proc wglCreateBufferRegionARB*(hDC: HDC, iLayerPlane: TGLint, uType: TGLuint): THandle{.
+    dynlib: dllname, importc: "wglCreateBufferRegionARB".}
+proc wglDeleteBufferRegionARB*(hRegion: THandle){.dynlib: dllname, 
+    importc: "wglDeleteBufferRegionARB".}
+proc wglSaveBufferRegionARB*(hRegion: THandle, x: TGLint, y: TGLint, 
+                             width: TGLint, height: TGLint): BOOL{.
+    dynlib: dllname, importc: "wglSaveBufferRegionARB".}
+proc wglRestoreBufferRegionARB*(hRegion: THandle, x: TGLint, y: TGLint, 
+                                width: TGLint, height: TGLint, xSrc: TGLint, 
+                                ySrc: TGLint): BOOL{.dynlib: dllname, 
+    importc: "wglRestoreBufferRegionARB".}
+proc wglAllocateMemoryNV*(size: TGLsizei, readFrequency: TGLfloat, 
+                          writeFrequency: TGLfloat, priority: TGLfloat): PGLvoid{.
+    dynlib: dllname, importc: "wglAllocateMemoryNV".}
+proc wglFreeMemoryNV*(pointer: PGLvoid){.dynlib: dllname, 
+    importc: "wglFreeMemoryNV".}
+const 
+  WGL_IMAGE_BUFFER_MIN_ACCESS_I3D* = 0x00000001
+  WGL_IMAGE_BUFFER_LOCK_I3D* = 0x00000002
+
+proc wglCreateImageBufferI3D*(hDC: HDC, dwSize: DWORD, uFlags: UINT): PGLvoid{.
+    dynlib: dllname, importc: "wglCreateImageBufferI3D".}
+proc wglDestroyImageBufferI3D*(hDC: HDC, pAddress: PGLvoid): BOOL{.
+    dynlib: dllname, importc: "wglDestroyImageBufferI3D".}
+proc wglAssociateImageBufferEventsI3D*(hdc: HDC, pEvent: PHandle, 
+                                       pAddress: PGLvoid, pSize: PDWORD, 
+                                       count: UINT): BOOL{.dynlib: dllname, 
+    importc: "wglAssociateImageBufferEventsI3D".}
+proc wglReleaseImageBufferEventsI3D*(hdc: HDC, pAddress: PGLvoid, count: UINT): BOOL{.
+    dynlib: dllname, importc: "wglReleaseImageBufferEventsI3D".}
+proc wglEnableFrameLockI3D*(): BOOL{.dynlib: dllname, 
+                                     importc: "wglEnableFrameLockI3D".}
+proc wglDisableFrameLockI3D*(): BOOL{.dynlib: dllname, 
+                                      importc: "wglDisableFrameLockI3D".}
+proc wglIsEnabledFrameLockI3D*(pFlag: PBOOL): BOOL{.dynlib: dllname, 
+    importc: "wglIsEnabledFrameLockI3D".}
+proc wglQueryFrameLockMasterI3D*(pFlag: PBOOL): BOOL{.dynlib: dllname, 
+    importc: "wglQueryFrameLockMasterI3D".}
+proc wglGetFrameUsageI3D*(pUsage: PGLfloat): BOOL{.dynlib: dllname, 
+    importc: "wglGetFrameUsageI3D".}
+proc wglBeginFrameTrackingI3D*(): BOOL{.dynlib: dllname, 
+                                        importc: "wglBeginFrameTrackingI3D".}
+proc wglEndFrameTrackingI3D*(): BOOL{.dynlib: dllname, 
+                                      importc: "wglEndFrameTrackingI3D".}
+proc wglQueryFrameTrackingI3D*(pFrameCount: PDWORD, pMissedFrames: PDWORD, 
+                               pLastMissedUsage: PGLfloat): BOOL{.
+    dynlib: dllname, importc: "wglQueryFrameTrackingI3D".}
+const 
+  WGL_NUMBER_PIXEL_FORMATS_ARB* = 0x00002000
+  WGL_DRAW_TO_WINDOW_ARB* = 0x00002001
+  WGL_DRAW_TO_BITMAP_ARB* = 0x00002002
+  WGL_ACCELERATION_ARB* = 0x00002003
+  WGL_NEED_PALETTE_ARB* = 0x00002004
+  WGL_NEED_SYSTEM_PALETTE_ARB* = 0x00002005
+  WGL_SWAP_LAYER_BUFFERS_ARB* = 0x00002006
+  WGL_SWAP_METHOD_ARB* = 0x00002007
+  WGL_NUMBER_OVERLAYS_ARB* = 0x00002008
+  WGL_NUMBER_UNDERLAYS_ARB* = 0x00002009
+  WGL_TRANSPARENT_ARB* = 0x0000200A
+  WGL_TRANSPARENT_RED_VALUE_ARB* = 0x00002037
+  WGL_TRANSPARENT_GREEN_VALUE_ARB* = 0x00002038
+  WGL_TRANSPARENT_BLUE_VALUE_ARB* = 0x00002039
+  WGL_TRANSPARENT_ALPHA_VALUE_ARB* = 0x0000203A
+  WGL_TRANSPARENT_INDEX_VALUE_ARB* = 0x0000203B
+  WGL_SHARE_DEPTH_ARB* = 0x0000200C
+  WGL_SHARE_STENCIL_ARB* = 0x0000200D
+  WGL_SHARE_ACCUM_ARB* = 0x0000200E
+  WGL_SUPPORT_GDI_ARB* = 0x0000200F
+  WGL_SUPPORT_OPENGL_ARB* = 0x00002010
+  WGL_DOUBLE_BUFFER_ARB* = 0x00002011
+  WGL_STEREO_ARB* = 0x00002012
+  WGL_PIXEL_TYPE_ARB* = 0x00002013
+  WGL_COLOR_BITS_ARB* = 0x00002014
+  WGL_RED_BITS_ARB* = 0x00002015
+  WGL_RED_SHIFT_ARB* = 0x00002016
+  WGL_GREEN_BITS_ARB* = 0x00002017
+  WGL_GREEN_SHIFT_ARB* = 0x00002018
+  WGL_BLUE_BITS_ARB* = 0x00002019
+  WGL_BLUE_SHIFT_ARB* = 0x0000201A
+  WGL_ALPHA_BITS_ARB* = 0x0000201B
+  WGL_ALPHA_SHIFT_ARB* = 0x0000201C
+  WGL_ACCUM_BITS_ARB* = 0x0000201D
+  WGL_ACCUM_RED_BITS_ARB* = 0x0000201E
+  WGL_ACCUM_GREEN_BITS_ARB* = 0x0000201F
+  WGL_ACCUM_BLUE_BITS_ARB* = 0x00002020
+  WGL_ACCUM_ALPHA_BITS_ARB* = 0x00002021
+  WGL_DEPTH_BITS_ARB* = 0x00002022
+  WGL_STENCIL_BITS_ARB* = 0x00002023
+  WGL_AUX_BUFFERS_ARB* = 0x00002024
+  WGL_NO_ACCELERATION_ARB* = 0x00002025
+  WGL_GENERIC_ACCELERATION_ARB* = 0x00002026
+  WGL_FULL_ACCELERATION_ARB* = 0x00002027
+  WGL_SWAP_EXCHANGE_ARB* = 0x00002028
+  WGL_SWAP_COPY_ARB* = 0x00002029
+  WGL_SWAP_UNDEFINED_ARB* = 0x0000202A
+  WGL_TYPE_RGBA_ARB* = 0x0000202B
+  WGL_TYPE_COLORINDEX_ARB* = 0x0000202C
+
+proc wglGetPixelFormatAttribivARB*(hdc: HDC, iPixelFormat: TGLint, 
+                                   iLayerPlane: TGLint, nAttributes: TGLuint, 
+                                   piAttributes: PGLint, piValues: PGLint): BOOL{.
+    dynlib: dllname, importc: "wglGetPixelFormatAttribivARB".}
+proc wglGetPixelFormatAttribfvARB*(hdc: HDC, iPixelFormat: TGLint, 
+                                   iLayerPlane: TGLint, nAttributes: TGLuint, 
+                                   piAttributes: PGLint, pfValues: PGLfloat): BOOL{.
+    dynlib: dllname, importc: "wglGetPixelFormatAttribfvARB".}
+proc wglChoosePixelFormatARB*(hdc: HDC, piAttribIList: PGLint, 
+                              pfAttribFList: PGLfloat, nMaxFormats: TGLuint, 
+                              piFormats: PGLint, nNumFormats: PGLuint): BOOL{.
+    dynlib: dllname, importc: "wglChoosePixelFormatARB".}
+const 
+  WGL_ERROR_INVALID_PIXEL_TYPE_ARB* = 0x00002043
+  WGL_ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB* = 0x00002054
+
+proc wglMakeContextCurrentARB*(hDrawDC: HDC, hReadDC: HDC, hglrc: HGLRC): BOOL{.
+    dynlib: dllname, importc: "wglMakeContextCurrentARB".}
+proc wglGetCurrentReadDCARB*(): HDC{.dynlib: dllname, 
+                                     importc: "wglGetCurrentReadDCARB".}
+const 
+  WGL_DRAW_TO_PBUFFER_ARB* = 0x0000202D # WGL_DRAW_TO_PBUFFER_ARB  { already defined }
+  WGL_MAX_PBUFFER_PIXELS_ARB* = 0x0000202E
+  WGL_MAX_PBUFFER_WIDTH_ARB* = 0x0000202F
+  WGL_MAX_PBUFFER_HEIGHT_ARB* = 0x00002030
+  WGL_PBUFFER_LARGEST_ARB* = 0x00002033
+  WGL_PBUFFER_WIDTH_ARB* = 0x00002034
+  WGL_PBUFFER_HEIGHT_ARB* = 0x00002035
+  WGL_PBUFFER_LOST_ARB* = 0x00002036
+
+proc wglCreatePbufferARB*(hDC: HDC, iPixelFormat: TGLint, iWidth: TGLint, 
+                          iHeight: TGLint, piAttribList: PGLint): THandle{.
+    dynlib: dllname, importc: "wglCreatePbufferARB".}
+proc wglGetPbufferDCARB*(hPbuffer: THandle): HDC{.dynlib: dllname, 
+    importc: "wglGetPbufferDCARB".}
+proc wglReleasePbufferDCARB*(hPbuffer: THandle, hDC: HDC): TGLint{.
+    dynlib: dllname, importc: "wglReleasePbufferDCARB".}
+proc wglDestroyPbufferARB*(hPbuffer: THandle): BOOL{.dynlib: dllname, 
+    importc: "wglDestroyPbufferARB".}
+proc wglQueryPbufferARB*(hPbuffer: THandle, iAttribute: TGLint, piValue: PGLint): BOOL{.
+    dynlib: dllname, importc: "wglQueryPbufferARB".}
+proc wglSwapIntervalEXT*(interval: TGLint): BOOL{.dynlib: dllname, 
+    importc: "wglSwapIntervalEXT".}
+proc wglGetSwapIntervalEXT*(): TGLint{.dynlib: dllname, 
+                                       importc: "wglGetSwapIntervalEXT".}
+const 
+  WGL_BIND_TO_TEXTURE_RGB_ARB* = 0x00002070
+  WGL_BIND_TO_TEXTURE_RGBA_ARB* = 0x00002071
+  WGL_TEXTURE_FORMAT_ARB* = 0x00002072
+  WGL_TEXTURE_TARGET_ARB* = 0x00002073
+  WGL_MIPMAP_TEXTURE_ARB* = 0x00002074
+  WGL_TEXTURE_RGB_ARB* = 0x00002075
+  WGL_TEXTURE_RGBA_ARB* = 0x00002076
+  WGL_NO_TEXTURE_ARB* = 0x00002077
+  WGL_TEXTURE_CUBE_MAP_ARB* = 0x00002078
+  WGL_TEXTURE_1D_ARB* = 0x00002079
+  WGL_TEXTURE_2D_ARB* = 0x0000207A # WGL_NO_TEXTURE_ARB  { already defined }
+  WGL_MIPMAP_LEVEL_ARB* = 0x0000207B
+  WGL_CUBE_MAP_FACE_ARB* = 0x0000207C
+  WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB* = 0x0000207D
+  WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB* = 0x0000207E
+  WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB* = 0x0000207F
+  WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB* = 0x00002080
+  WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB* = 0x00002081
+  WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB* = 0x00002082
+  WGL_FRONT_LEFT_ARB* = 0x00002083
+  WGL_FRONT_RIGHT_ARB* = 0x00002084
+  WGL_BACK_LEFT_ARB* = 0x00002085
+  WGL_BACK_RIGHT_ARB* = 0x00002086
+  WGL_AUX0_ARB* = 0x00002087
+  WGL_AUX1_ARB* = 0x00002088
+  WGL_AUX2_ARB* = 0x00002089
+  WGL_AUX3_ARB* = 0x0000208A
+  WGL_AUX4_ARB* = 0x0000208B
+  WGL_AUX5_ARB* = 0x0000208C
+  WGL_AUX6_ARB* = 0x0000208D
+  WGL_AUX7_ARB* = 0x0000208E
+  WGL_AUX8_ARB* = 0x0000208F
+  WGL_AUX9_ARB* = 0x00002090
+
+proc wglBindTexImageARB*(hPbuffer: THandle, iBuffer: TGLint): BOOL{.
+    dynlib: dllname, importc: "wglBindTexImageARB".}
+proc wglReleaseTexImageARB*(hPbuffer: THandle, iBuffer: TGLint): BOOL{.
+    dynlib: dllname, importc: "wglReleaseTexImageARB".}
+proc wglSetPbufferAttribARB*(hPbuffer: THandle, piAttribList: PGLint): BOOL{.
+    dynlib: dllname, importc: "wglSetPbufferAttribARB".}
+proc wglGetExtensionsStringEXT*(): cstring{.dynlib: dllname, 
+    importc: "wglGetExtensionsStringEXT".}
+proc wglMakeContextCurrentEXT*(hDrawDC: HDC, hReadDC: HDC, hglrc: HGLRC): BOOL{.
+    dynlib: dllname, importc: "wglMakeContextCurrentEXT".}
+proc wglGetCurrentReadDCEXT*(): HDC{.dynlib: dllname, 
+                                     importc: "wglGetCurrentReadDCEXT".}
+const 
+  WGL_DRAW_TO_PBUFFER_EXT* = 0x0000202D
+  WGL_MAX_PBUFFER_PIXELS_EXT* = 0x0000202E
+  WGL_MAX_PBUFFER_WIDTH_EXT* = 0x0000202F
+  WGL_MAX_PBUFFER_HEIGHT_EXT* = 0x00002030
+  WGL_OPTIMAL_PBUFFER_WIDTH_EXT* = 0x00002031
+  WGL_OPTIMAL_PBUFFER_HEIGHT_EXT* = 0x00002032
+  WGL_PBUFFER_LARGEST_EXT* = 0x00002033
+  WGL_PBUFFER_WIDTH_EXT* = 0x00002034
+  WGL_PBUFFER_HEIGHT_EXT* = 0x00002035
+
+proc wglCreatePbufferEXT*(hDC: HDC, iPixelFormat: TGLint, iWidth: TGLint, 
+                          iHeight: TGLint, piAttribList: PGLint): THandle{.
+    dynlib: dllname, importc: "wglCreatePbufferEXT".}
+proc wglGetPbufferDCEXT*(hPbuffer: THandle): HDC{.dynlib: dllname, 
+    importc: "wglGetPbufferDCEXT".}
+proc wglReleasePbufferDCEXT*(hPbuffer: THandle, hDC: HDC): TGLint{.
+    dynlib: dllname, importc: "wglReleasePbufferDCEXT".}
+proc wglDestroyPbufferEXT*(hPbuffer: THandle): BOOL{.dynlib: dllname, 
+    importc: "wglDestroyPbufferEXT".}
+proc wglQueryPbufferEXT*(hPbuffer: THandle, iAttribute: TGLint, piValue: PGLint): BOOL{.
+    dynlib: dllname, importc: "wglQueryPbufferEXT".}
+const 
+  WGL_NUMBER_PIXEL_FORMATS_EXT* = 0x00002000
+  WGL_DRAW_TO_WINDOW_EXT* = 0x00002001
+  WGL_DRAW_TO_BITMAP_EXT* = 0x00002002
+  WGL_ACCELERATION_EXT* = 0x00002003
+  WGL_NEED_PALETTE_EXT* = 0x00002004
+  WGL_NEED_SYSTEM_PALETTE_EXT* = 0x00002005
+  WGL_SWAP_LAYER_BUFFERS_EXT* = 0x00002006
+  WGL_SWAP_METHOD_EXT* = 0x00002007
+  WGL_NUMBER_OVERLAYS_EXT* = 0x00002008
+  WGL_NUMBER_UNDERLAYS_EXT* = 0x00002009
+  WGL_TRANSPARENT_EXT* = 0x0000200A
+  WGL_TRANSPARENT_VALUE_EXT* = 0x0000200B
+  WGL_SHARE_DEPTH_EXT* = 0x0000200C
+  WGL_SHARE_STENCIL_EXT* = 0x0000200D
+  WGL_SHARE_ACCUM_EXT* = 0x0000200E
+  WGL_SUPPORT_GDI_EXT* = 0x0000200F
+  WGL_SUPPORT_OPENGL_EXT* = 0x00002010
+  WGL_DOUBLE_BUFFER_EXT* = 0x00002011
+  WGL_STEREO_EXT* = 0x00002012
+  WGL_PIXEL_TYPE_EXT* = 0x00002013
+  WGL_COLOR_BITS_EXT* = 0x00002014
+  WGL_RED_BITS_EXT* = 0x00002015
+  WGL_RED_SHIFT_EXT* = 0x00002016
+  WGL_GREEN_BITS_EXT* = 0x00002017
+  WGL_GREEN_SHIFT_EXT* = 0x00002018
+  WGL_BLUE_BITS_EXT* = 0x00002019
+  WGL_BLUE_SHIFT_EXT* = 0x0000201A
+  WGL_ALPHA_BITS_EXT* = 0x0000201B
+  WGL_ALPHA_SHIFT_EXT* = 0x0000201C
+  WGL_ACCUM_BITS_EXT* = 0x0000201D
+  WGL_ACCUM_RED_BITS_EXT* = 0x0000201E
+  WGL_ACCUM_GREEN_BITS_EXT* = 0x0000201F
+  WGL_ACCUM_BLUE_BITS_EXT* = 0x00002020
+  WGL_ACCUM_ALPHA_BITS_EXT* = 0x00002021
+  WGL_DEPTH_BITS_EXT* = 0x00002022
+  WGL_STENCIL_BITS_EXT* = 0x00002023
+  WGL_AUX_BUFFERS_EXT* = 0x00002024
+  WGL_NO_ACCELERATION_EXT* = 0x00002025
+  WGL_GENERIC_ACCELERATION_EXT* = 0x00002026
+  WGL_FULL_ACCELERATION_EXT* = 0x00002027
+  WGL_SWAP_EXCHANGE_EXT* = 0x00002028
+  WGL_SWAP_COPY_EXT* = 0x00002029
+  WGL_SWAP_UNDEFINED_EXT* = 0x0000202A
+  WGL_TYPE_RGBA_EXT* = 0x0000202B
+  WGL_TYPE_COLORINDEX_EXT* = 0x0000202C
+
+proc wglGetPixelFormatAttribivEXT*(hdc: HDC, iPixelFormat: TGLint, 
+                                   iLayerPlane: TGLint, nAttributes: TGLuint, 
+                                   piAttributes: PGLint, piValues: PGLint): BOOL{.
+    dynlib: dllname, importc: "wglGetPixelFormatAttribivEXT".}
+proc wglGetPixelFormatAttribfvEXT*(hdc: HDC, iPixelFormat: TGLint, 
+                                   iLayerPlane: TGLint, nAttributes: TGLuint, 
+                                   piAttributes: PGLint, pfValues: PGLfloat): BOOL{.
+    dynlib: dllname, importc: "wglGetPixelFormatAttribfvEXT".}
+proc wglChoosePixelFormatEXT*(hdc: HDC, piAttribIList: PGLint, 
+                              pfAttribFList: PGLfloat, nMaxFormats: TGLuint, 
+                              piFormats: PGLint, nNumFormats: PGLuint): BOOL{.
+    dynlib: dllname, importc: "wglChoosePixelFormatEXT".}
+const 
+  WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D* = 0x00002050
+  WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D* = 0x00002051
+  WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D* = 0x00002052
+  WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D* = 0x00002053
+
+proc wglGetDigitalVideoParametersI3D*(hDC: HDC, iAttribute: TGLint, 
+                                      piValue: PGLint): BOOL{.dynlib: dllname, 
+    importc: "wglGetDigitalVideoParametersI3D".}
+proc wglSetDigitalVideoParametersI3D*(hDC: HDC, iAttribute: TGLint, 
+                                      piValue: PGLint): BOOL{.dynlib: dllname, 
+    importc: "wglSetDigitalVideoParametersI3D".}
+const 
+  WGL_GAMMA_TABLE_SIZE_I3D* = 0x0000204E
+  WGL_GAMMA_EXCLUDE_DESKTOP_I3D* = 0x0000204F
+
+proc wglGetGammaTableParametersI3D*(hDC: HDC, iAttribute: TGLint, 
+                                    piValue: PGLint): BOOL{.dynlib: dllname, 
+    importc: "wglGetGammaTableParametersI3D".}
+proc wglSetGammaTableParametersI3D*(hDC: HDC, iAttribute: TGLint, 
+                                    piValue: PGLint): BOOL{.dynlib: dllname, 
+    importc: "wglSetGammaTableParametersI3D".}
+proc wglGetGammaTableI3D*(hDC: HDC, iEntries: TGLint, puRed: PGLUSHORT, 
+                          puGreen: PGLUSHORT, puBlue: PGLUSHORT): BOOL{.
+    dynlib: dllname, importc: "wglGetGammaTableI3D".}
+proc wglSetGammaTableI3D*(hDC: HDC, iEntries: TGLint, puRed: PGLUSHORT, 
+                          puGreen: PGLUSHORT, puBlue: PGLUSHORT): BOOL{.
+    dynlib: dllname, importc: "wglSetGammaTableI3D".}
+const 
+  WGL_GENLOCK_SOURCE_MULTIVIEW_I3D* = 0x00002044
+  WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D* = 0x00002045
+  WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D* = 0x00002046
+  WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D* = 0x00002047
+  WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D* = 0x00002048
+  WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D* = 0x00002049
+  WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D* = 0x0000204A
+  WGL_GENLOCK_SOURCE_EDGE_RISING_I3D* = 0x0000204B
+  WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D* = 0x0000204C
+  WGL_FLOAT_COMPONENTS_NV* = 0x000020B0
+  WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV* = 0x000020B1
+  WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV* = 0x000020B2
+  WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV* = 0x000020B3
+  WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV* = 0x000020B4
+  WGL_TEXTURE_FLOAT_R_NV* = 0x000020B5
+  WGL_TEXTURE_FLOAT_RG_NV* = 0x000020B6
+  WGL_TEXTURE_FLOAT_RGB_NV* = 0x000020B7
+  WGL_TEXTURE_FLOAT_RGBA_NV* = 0x000020B8
+
+proc wglEnableGenlockI3D*(hDC: HDC): BOOL{.dynlib: dllname, 
+    importc: "wglEnableGenlockI3D".}
+proc wglDisableGenlockI3D*(hDC: HDC): BOOL{.dynlib: dllname, 
+    importc: "wglDisableGenlockI3D".}
+proc wglIsEnabledGenlockI3D*(hDC: HDC, pFlag: PBOOL): BOOL{.dynlib: dllname, 
+    importc: "wglIsEnabledGenlockI3D".}
+proc wglGenlockSourceI3D*(hDC: HDC, uSource: TGLuint): BOOL{.dynlib: dllname, 
+    importc: "wglGenlockSourceI3D".}
+proc wglGetGenlockSourceI3D*(hDC: HDC, uSource: PGLUINT): BOOL{.dynlib: dllname, 
+    importc: "wglGetGenlockSourceI3D".}
+proc wglGenlockSourceEdgeI3D*(hDC: HDC, uEdge: TGLuint): BOOL{.dynlib: dllname, 
+    importc: "wglGenlockSourceEdgeI3D".}
+proc wglGetGenlockSourceEdgeI3D*(hDC: HDC, uEdge: PGLUINT): BOOL{.
+    dynlib: dllname, importc: "wglGetGenlockSourceEdgeI3D".}
+proc wglGenlockSampleRateI3D*(hDC: HDC, uRate: TGLuint): BOOL{.dynlib: dllname, 
+    importc: "wglGenlockSampleRateI3D".}
+proc wglGetGenlockSampleRateI3D*(hDC: HDC, uRate: PGLUINT): BOOL{.
+    dynlib: dllname, importc: "wglGetGenlockSampleRateI3D".}
+proc wglGenlockSourceDelayI3D*(hDC: HDC, uDelay: TGLuint): BOOL{.
+    dynlib: dllname, importc: "wglGenlockSourceDelayI3D".}
+proc wglGetGenlockSourceDelayI3D*(hDC: HDC, uDelay: PGLUINT): BOOL{.
+    dynlib: dllname, importc: "wglGetGenlockSourceDelayI3D".}
+proc wglQueryGenlockMaxSourceDelayI3D*(hDC: HDC, uMaxLineDelay: PGLUINT, 
+                                       uMaxPixelDelay: PGLUINT): BOOL{.
+    dynlib: dllname, importc: "wglQueryGenlockMaxSourceDelayI3D".}
+const 
+  WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV* = 0x000020A0
+  WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV* = 0x000020A1
+  WGL_TEXTURE_RECTANGLE_NV* = 0x000020A2
+
+const 
+  WGL_RGBA_FLOAT_MODE_ATI* = 0x00008820
+  WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI* = 0x00008835
+  WGL_TYPE_RGBA_FLOAT_ATI* = 0x000021A0
+
+# implementation
diff --git a/tests/manyloc/packages/package1/p1.babel b/tests/manyloc/packages/package1/p1.babel
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/manyloc/packages/package1/p1.babel
diff --git a/tests/manyloc/packages/package2/p2.babel b/tests/manyloc/packages/package2/p2.babel
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/manyloc/packages/package2/p2.babel
diff --git a/tests/matrix/tmatrix2.nim b/tests/matrix/tmatrix2.nim
index 442096e93..82990f1a5 100644
--- a/tests/matrix/tmatrix2.nim
+++ b/tests/matrix/tmatrix2.nim
@@ -1,5 +1,5 @@
 discard """
-  output: "5.0000000000000000e+00"
+  output: "5.0"
 """
 
 type
diff --git a/tests/parallel/tdeepcopy.nim b/tests/parallel/tdeepcopy.nim
new file mode 100644
index 000000000..84e2edf3f
--- /dev/null
+++ b/tests/parallel/tdeepcopy.nim
@@ -0,0 +1,18 @@
+discard """
+  output: '''13 abc'''
+"""
+
+type
+  PBinaryTree = ref object
+    le, ri: PBinaryTree
+    value: int
+
+
+proc main =
+  var x: PBinaryTree
+  deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13))))
+  var y: string
+  deepCopy y, "abc"
+  echo x.ri.le.value, " ", y
+
+main()
diff --git a/tests/sets/tsets3.nim b/tests/sets/tsets3.nim
index d2b15d72d..f599f8e7d 100644
--- a/tests/sets/tsets3.nim
+++ b/tests/sets/tsets3.nim
@@ -74,8 +74,27 @@ block symmetricDifference:
   assert((s3 -+- s3) == initSet[int]())
   assert((s3 -+- s1) == s1_s3)
 
+block difference:
+  let
+    s1_s2 = difference(s1, s2)
+    s1_s3 = difference(s1, s3)
+    s2_s3 = s2 - s3
+
+  assert s1_s2.len == 2
+  assert s1_s3.len == 5
+  assert s2_s3.len == 3
+
+  for i in s1:
+    assert i in s1_s2 xor i in s2
+    assert i in s1_s3 xor i in s3
+  for i in s2:
+    assert i in s2_s3 xor i in s3
+
+  assert((s2 - s2) == initSet[int]())
+  assert((s1 - s3 - s1) == s1 -+- s3)
+
 block disjoint:
   assert(not disjoint(s1, s2))
   assert disjoint(s1, s3)
   assert(not disjoint(s2, s3))
-  assert(not disjoint(s2, s2))
\ No newline at end of file
+  assert(not disjoint(s2, s2))
diff --git a/tests/showoff/tdrdobbs_examples.nim b/tests/showoff/tdrdobbs_examples.nim
index 8a39990ba..13a685950 100644
--- a/tests/showoff/tdrdobbs_examples.nim
+++ b/tests/showoff/tdrdobbs_examples.nim
@@ -1,7 +1,7 @@
 discard """
   output: '''108
 11 -1 1936
-4.0000000000000002e-01
+0.4
 true
 truefalse'''
 """
diff --git a/tests/stdlib/testequivalence.nim b/tests/stdlib/testequivalence.nim
index 7c5d9e3e9..7acaad340 100644
--- a/tests/stdlib/testequivalence.nim
+++ b/tests/stdlib/testequivalence.nim
@@ -1,7 +1,6 @@
 discard """
   output: ''''''
 """
-import unittest
 import sets
 
 doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "equivalent or subset")
diff --git a/tests/system/tfloatToString.nim b/tests/system/tfloatToString.nim
new file mode 100644
index 000000000..bb45a91d7
--- /dev/null
+++ b/tests/system/tfloatToString.nim
@@ -0,0 +1,22 @@
+discard """
+  output:'''2.3242
+2.982
+123912.1
+123912.1823
+5.0
+1e+100
+inf
+-inf
+nan
+'''
+"""
+
+echo($(2.3242))
+echo($(2.982))
+echo($(123912.1))
+echo($(123912.1823))
+echo($(5.0))
+echo($(1e100))
+echo($(1e1000000))
+echo($(-1e1000000))
+echo($(0.0/0.0))
diff --git a/tests/table/ptables.nim b/tests/table/ptables.nim
index ec52d08c3..79a9aab17 100644
--- a/tests/table/ptables.nim
+++ b/tests/table/ptables.nim
@@ -104,6 +104,15 @@ block countTableTest1:
 block SyntaxTest:
   var x = newTable[int, string]({:})
 
+block nilTest:
+  var i, j: PTable[int, int] = nil
+  assert i == j
+  j = newTable[int, int]()
+  assert i != j
+  assert j != i
+  i = newTable[int, int]()
+  assert i == j
+
 proc orderedTableSortTest() =
   var t = newOrderedTable[string, int](2)
   for key, val in items(data): t[key] = val
diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim
index 841eb8159..02f7dc1d7 100644
--- a/tests/testament/categories.nim
+++ b/tests/testament/categories.nim
@@ -312,7 +312,7 @@ proc testBabelPackages(r: var TResults, cat: Category, filter: PackageFilter) =
 
 # ----------------------------------------------------------------------------
 
-const AdditionalCategories = ["debugger", "tools", "examples", "stdlib", "babel-core"]
+const AdditionalCategories = ["debugger", "examples", "stdlib", "babel-core"]
 
 proc `&.?`(a, b: string): string =
   # candidate for the stdlib?
@@ -336,9 +336,6 @@ proc processCategory(r: var TResults, cat: Category, options: string) =
     gcTests(r, cat, options)
   of "debugger":
     debuggerTests(r, cat, options)
-  of "tools":
-    testSpec r, makeTest("compiler/c2nim/c2nim.nim", options, cat)
-    testSpec r, makeTest("compiler/pas2nim/pas2nim.nim", options, cat)
   of "manyloc":
     manyLoc r, cat, options
   of "threads":
diff --git a/todo.txt b/todo.txt
index d1387669d..6ae5df509 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,21 +2,27 @@ version 0.9.6
 =============
 
 - scopes are still broken for generic instantiation!
-- integrate the new LL into the devel branch
 - start experimental branch
+- implicit deref for parameter matching
 
 Concurrency
 -----------
 
 - 'gcsafe' inferrence needs to be fixed
+- 'deepCopy' needs to be instantiated for
+  generics *when the type is constructed*
+- test 'deepCopy'
+- overloading of '='; general lift mechanism
+
 - the disjoint checker needs to deal with 'a = spawn f(); g = spawn f()'
-- implement 'deepCopy' builtin
 - implement 'foo[1..4] = spawn(f[4..7])'
-- support for exception propagation
-- Minor: The copying of the 'ref Promise' into the thead local storage only
+- document the new 'spawn' and 'parallel' statements
+
+Low priority:
+- support for exception propagation? (hard to implement)
+- the copying of the 'ref Promise' into the thead local storage only
   happens to work due to the write barrier's implementation
 - implement lock levels --> first without the more complex race avoidance
-- document the new 'spawn' and 'parallel' statements
 
 
 Misc
@@ -27,8 +33,6 @@ Misc
 - fix the tuple unpacking in lambda bug
 - make tuple unpacking work in a non-var/let context
 - special rule for ``[]=``
-- ``=`` should be overloadable; requires specialization for ``=``; general
-  lift mechanism in the compiler is already implemented for 'fields'
 - built-in 'getImpl'
 - type API for macros; make 'spawn' a macro
 - markAndSweepGC should expose an API for fibers
@@ -57,13 +61,9 @@ version 0.9.x
 - implement 'bits' pragmas
 - we need a magic thisModule symbol
 - provide --nilChecks:on|off
-- fix closures/lambdalifting
 - ensure (ref T)(a, b) works as a type conversion and type constructor
 - optimize 'genericReset'; 'newException' leads to code bloat
 - stack-less GC
-- implicit deref for parameter matching
-
-- VM: optimize opcAsgnStr
 
 
 version 0.9.X
diff --git a/tools/nimrepl.nim b/tools/nimrepl.nim
index 8e43b4431..4b6379bd5 100644
--- a/tools/nimrepl.nim
+++ b/tools/nimrepl.nim
@@ -24,7 +24,7 @@ proc execCode(code: string): string =
     f.close()
     result = osproc.execProcess(
       "$# $# --verbosity:0 --hint[Conf]:off temp.nim" % [nimExe, runCmd],
-      {poStdErrToStdOut})
+      options = {poStdErrToStdOut})
   else:
     result = "cannot open file 'temp.nim'"
 
diff --git a/tools/trimcc.nim b/tools/trimcc.nim
index 6271d2b9a..4d9686195 100644
--- a/tools/trimcc.nim
+++ b/tools/trimcc.nim
@@ -18,7 +18,7 @@ proc walker(dir: string) =
       else:

         echo "Required: ", path

         # copy back:

-        moveFile(dest=path, sourc=newName(path))

+        moveFile(dest=path, source=newName(path))

     of pcDir:

       walker(path)

     else: discard

diff --git a/web/babelpkglist.nim b/web/babelpkglist.nim
index 8745c9f99..5da7d60a9 100644
--- a/web/babelpkglist.nim
+++ b/web/babelpkglist.nim
@@ -21,7 +21,7 @@ proc processContent(content: string) =
   var jsonArr = jsonDoc.elems
 
   jsonArr.sort do (x, y: PJsonNode) -> int:
-    system.cmp(x["name"].str, y["name"].str)
+    strutils.cmpIgnoreCase(x["name"].str, y["name"].str)
 
   var
     officialList = ""
@@ -38,8 +38,7 @@ proc processContent(content: string) =
       else: pkg["url"].str
     let
       desc = pkg["description"].str
-      # Review array index access when #1291 is solved.
-      dot = if desc.high > 0 and desc[<desc.high] in endings: "" else: "."
+      dot = if desc.high > 0 and desc[desc.high] in endings: "" else: "."
       listItem = li(a(href=pkgWeb, pkg["name"].str), " ", desc & dot)
     if pkg["url"].str.startsWith("git://github.com/nimrod-code") or
        "official" in pkg["tags"].elems:
@@ -51,19 +50,17 @@ proc processContent(content: string) =
 
   var officialPkgListDiv = document.getElementById("officialPkgList")
 
-  officialPkgListDiv.innerHTML.add(
+  officialPkgListDiv.innerHTML =
     p("There are currently " & $officialCount &
       " official packages in the Babel package repository.") &
     ul(officialList)
-  )
 
   var unofficialPkgListDiv = document.getElementById("unofficialPkgList")
 
-  unofficialPkgListDiv.innerHTML.add(
+  unofficialPkgListDiv.innerHTML =
     p("There are currently " & $unofficialCount &
       " unofficial packages in the Babel package repository.") &
     ul(unofficialList)
-  )
 
 proc gotPackageList(apiReply: TData) {.exportc.} =
   let decoded = decodeContent($apiReply.content)
diff --git a/web/index.txt b/web/index.txt
index c3459d56b..947ebb706 100644
--- a/web/index.txt
+++ b/web/index.txt
@@ -101,5 +101,5 @@ Roadmap to 1.0
 ==============
 
 Please have a look at
-this `wiki page <https://github.com/Araq/Nimrod/wiki/Feature-Matrix>`_ for
+this `wiki page <https://github.com/Araq/Nimrod/wiki/Roadmap>`_ for
 an up-to-date overview.
diff --git a/web/news.txt b/web/news.txt
index a3019df51..20e241221 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -14,7 +14,21 @@ News
     ``threadpool``.
   - The symbol binding rules in generics changed: ``bar`` in ``foo.bar`` is
     now considered for implicit early binding.
-
+  - ``c2nim`` moved into its own repository and is now a Babel package.
+  - ``pas2nim`` moved into its own repository and is now a Babel package.
+  - ``system.$`` for floating point types now produces a human friendly string
+    representation.
+  - ``uri.TUrl`` as well as the ``parseurl`` module are now deprecated in favour
+    of the new ``TUri`` type in the ``uri`` module.
+  - The ``destructor`` pragma has been deprecated. Use the ``override`` pragma
+    instead. The destructor's name has to be ``destroy`` now.
+  - ``lambda`` is not a keyword anymore.
+
+  Language Additions
+  ------------------
+
+  - There is a new ``parallel`` statement for safe fork&join parallel computing.
+  
 
   Library Additions
   -----------------
@@ -22,7 +36,8 @@ News
   - Added module ``cpuinfo``.
   - Added module ``threadpool``.
   - ``sequtils.distnct`` has been renamed to ``sequtils.deduplicate``.
-
+  - Added ``algorithm.reversed``
+  - Added ``uri.combine`` and ``uri.parseUri``.
 
 2014-04-21 Version 0.9.4 released
 =================================
diff --git a/web/nimrod.ini b/web/nimrod.ini
index af9ac0cd9..38a906ac5 100644
--- a/web/nimrod.ini
+++ b/web/nimrod.ini
@@ -37,11 +37,11 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson."""
 
 [Documentation]
 doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters"
-doc: "tools;c2nim;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
-pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc"
+doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
+pdf: "manual;lib;tut1;tut2;nimrodc;niminst;gc"
 srcdoc2: "system.nim;impure/graphics;wrappers/sdl"
 srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned"
-srcdoc2: "impure/re;pure/sockets"
+srcdoc2: "impure/re;pure/sockets;pure/typetraits"
 srcdoc: "system/threads.nim;system/channels.nim;js/dom"
 srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"
 srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"