changeset 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents 5825d48b27d1
children 44a95ac7368a
files bin/llvmdc.conf bin/llvmdc.phobos bin/llvmdc.tango dmd/link.c dmd/mars.c dmd/mars.h gen/arrays.cpp gen/arrays.h gen/classes.cpp gen/classes.h gen/functions.cpp gen/logger.cpp gen/logger.h gen/runtime.cpp gen/statements.cpp gen/structs.cpp gen/toir.cpp gen/tollvm.cpp gen/toobj.cpp gen/typinf.cpp llvmdc.kdevelop llvmdc.kdevelop.filelist tango/LICENSE tango/README.txt tango/README_LLVMDC.txt tango/dsss.conf tango/example/cluster/Add.d tango/example/cluster/alert.d tango/example/cluster/cclient.d tango/example/cluster/cserver.d tango/example/cluster/invalidate.d tango/example/cluster/qclient.d tango/example/cluster/qlisten.d tango/example/cluster/qrequest.d tango/example/cluster/qserver.d tango/example/cluster/reply.d tango/example/cluster/task.d tango/example/cluster/tclient.d tango/example/cluster/tserver.d tango/example/concurrency/fiber_test.d tango/example/conduits/FileBucket.d tango/example/conduits/composite.d tango/example/conduits/filebubbler.d tango/example/conduits/filecat.d tango/example/conduits/filecopy.d tango/example/conduits/fileops.d tango/example/conduits/filepathname.d tango/example/conduits/filescan.d tango/example/conduits/filescanregex.d tango/example/conduits/lineio.d tango/example/conduits/mmap.d tango/example/conduits/paths.d tango/example/conduits/randomio.d tango/example/conduits/unifile.d tango/example/console/buffered.d tango/example/console/hello.d tango/example/console/stdout.d tango/example/dsss.conf tango/example/external/GlueFlectioned.d tango/example/jake-all.bat tango/example/linux.mak tango/example/logging/chainsaw.d tango/example/logging/context.d tango/example/logging/logging.d tango/example/logging/multilog.d tango/example/manual/chapterStorage.d tango/example/networking/homepage.d tango/example/networking/httpget.d tango/example/networking/selector.d tango/example/networking/sockethello.d tango/example/networking/socketserver.d tango/example/synchronization/barrier.d tango/example/synchronization/condition.d tango/example/synchronization/mutex.d tango/example/synchronization/readwritemutex.d tango/example/synchronization/semaphore.d tango/example/system/arguments.d tango/example/system/localtime.d tango/example/system/normpath.d tango/example/system/process.d tango/example/text/formatalign.d tango/example/text/formatindex.d tango/example/text/formatspec.d tango/example/text/localetime.d tango/example/text/properties.d tango/example/text/token.d tango/lib/common/tango/core/BitManip.d tango/lib/common/tango/core/Exception.d tango/lib/common/tango/core/Memory.d tango/lib/common/tango/core/Runtime.d tango/lib/common/tango/core/Thread.d tango/lib/common/tango/core/ThreadASM.S tango/lib/common/tango/llvmdc.mak tango/lib/common/tango/posix.mak tango/lib/common/tango/stdc/posix/pthread_darwin.d tango/lib/common/tango/stdc/wrap.c tango/lib/common/tango/stdc/wrap.ll tango/lib/common/tango/win32.mak tango/lib/compiler/llvmdc/aApply.d tango/lib/compiler/llvmdc/aApplyR.d tango/lib/compiler/llvmdc/aaA.d tango/lib/compiler/llvmdc/adi.d tango/lib/compiler/llvmdc/arrays.d tango/lib/compiler/llvmdc/cast.d tango/lib/compiler/llvmdc/contract.d tango/lib/compiler/llvmdc/genobj.d tango/lib/compiler/llvmdc/lifetime.d tango/lib/compiler/llvmdc/llvm/intrinsic.d tango/lib/compiler/llvmdc/llvmdc.mak tango/lib/compiler/llvmdc/mem.d tango/lib/compiler/llvmdc/memory.d tango/lib/compiler/llvmdc/moduleinfo.ll tango/lib/compiler/llvmdc/qsort2.d tango/lib/compiler/llvmdc/std/intrinsic.d tango/lib/compiler/llvmdc/switch.d tango/lib/compiler/llvmdc/typeinfo/ti_AC.d tango/lib/compiler/llvmdc/typeinfo/ti_Acdouble.d tango/lib/compiler/llvmdc/typeinfo/ti_Acfloat.d tango/lib/compiler/llvmdc/typeinfo/ti_Acreal.d tango/lib/compiler/llvmdc/typeinfo/ti_Adouble.d tango/lib/compiler/llvmdc/typeinfo/ti_Afloat.d tango/lib/compiler/llvmdc/typeinfo/ti_Ag.d tango/lib/compiler/llvmdc/typeinfo/ti_Aint.d tango/lib/compiler/llvmdc/typeinfo/ti_Along.d tango/lib/compiler/llvmdc/typeinfo/ti_Areal.d tango/lib/compiler/llvmdc/typeinfo/ti_Ashort.d tango/lib/compiler/llvmdc/typeinfo/ti_C.d tango/lib/compiler/llvmdc/typeinfo/ti_byte.d tango/lib/compiler/llvmdc/typeinfo/ti_cdouble.d tango/lib/compiler/llvmdc/typeinfo/ti_cfloat.d tango/lib/compiler/llvmdc/typeinfo/ti_char.d tango/lib/compiler/llvmdc/typeinfo/ti_creal.d tango/lib/compiler/llvmdc/typeinfo/ti_dchar.d tango/lib/compiler/llvmdc/typeinfo/ti_delegate.d tango/lib/compiler/llvmdc/typeinfo/ti_double.d tango/lib/compiler/llvmdc/typeinfo/ti_float.d tango/lib/compiler/llvmdc/typeinfo/ti_idouble.d tango/lib/compiler/llvmdc/typeinfo/ti_ifloat.d tango/lib/compiler/llvmdc/typeinfo/ti_int.d tango/lib/compiler/llvmdc/typeinfo/ti_ireal.d tango/lib/compiler/llvmdc/typeinfo/ti_long.d tango/lib/compiler/llvmdc/typeinfo/ti_ptr.d tango/lib/compiler/llvmdc/typeinfo/ti_real.d tango/lib/compiler/llvmdc/typeinfo/ti_short.d tango/lib/compiler/llvmdc/typeinfo/ti_ubyte.d tango/lib/compiler/llvmdc/typeinfo/ti_uint.d tango/lib/compiler/llvmdc/typeinfo/ti_ulong.d tango/lib/compiler/llvmdc/typeinfo/ti_ushort.d tango/lib/compiler/llvmdc/typeinfo/ti_void.d tango/lib/compiler/llvmdc/typeinfo/ti_wchar.d tango/lib/compiler/llvmdc/util/console.d tango/lib/compiler/llvmdc/util/ctype.d tango/lib/compiler/llvmdc/util/string.d tango/lib/compiler/llvmdc/util/utf.d tango/lib/gc/basic/gc.d tango/lib/gc/basic/gcalloc.d tango/lib/gc/basic/gcbits.d tango/lib/gc/basic/gcstats.d tango/lib/gc/basic/gcx.d tango/lib/gc/basic/posix.mak tango/lib/gc/basic/win32.mak tango/lib/gc/stub/gc.d tango/lib/gc/stub/llvmdc.mak tango/lib/gc/stub/posix.mak tango/lib/gc/stub/win32.mak tango/lib/llvmdc-posix.mak tango/lib/llvmdc.conf tango/object.di tango/std/c/stdarg.di tango/std/intrinsic.di tango/std/stdarg.di tango/tango/core/Array.d tango/tango/core/Atomic.d tango/tango/core/BitArray.d tango/tango/core/BitManip.di tango/tango/core/ByteSwap.d tango/tango/core/Exception.di tango/tango/core/Memory.di tango/tango/core/Runtime.di tango/tango/core/Signal.d tango/tango/core/Thread.di tango/tango/core/Traits.d tango/tango/core/Tuple.d tango/tango/core/Vararg.d tango/tango/core/Variant.d tango/tango/core/Version.d tango/tango/core/sync/Barrier.d tango/tango/core/sync/Condition.d tango/tango/core/sync/Config.d tango/tango/core/sync/Mutex.d tango/tango/core/sync/ReadWriteMutex.d tango/tango/core/sync/Semaphore.d tango/tango/group/collection.d tango/tango/group/convert.d tango/tango/group/digest.d tango/tango/group/file.d tango/tango/group/http.d tango/tango/group/log.d tango/tango/group/math.d tango/tango/group/net.d tango/tango/group/stream.d tango/tango/group/text.d tango/tango/group/time.d tango/tango/io/Buffer.d tango/tango/io/Conduit.d tango/tango/io/Console.d tango/tango/io/DeviceConduit.d tango/tango/io/File.d tango/tango/io/FileConduit.d tango/tango/io/FileConst.d tango/tango/io/FilePath.d tango/tango/io/FileRoots.d tango/tango/io/FileScan.d tango/tango/io/FileSystem.d tango/tango/io/GrowBuffer.d tango/tango/io/MappedBuffer.d tango/tango/io/Print.d tango/tango/io/Stdout.d tango/tango/io/TempFile.d tango/tango/io/UnicodeFile.d tango/tango/io/archive/Zip.d tango/tango/io/compress/BzipStream.d tango/tango/io/compress/ZlibStream.d tango/tango/io/compress/c/bzlib.d tango/tango/io/compress/c/zlib.d tango/tango/io/digest/Crc32.d tango/tango/io/digest/Digest.d tango/tango/io/digest/Md2.d tango/tango/io/digest/Md4.d tango/tango/io/digest/Md5.d tango/tango/io/digest/MerkleDamgard.d tango/tango/io/digest/Sha0.d tango/tango/io/digest/Sha01.d tango/tango/io/digest/Sha1.d tango/tango/io/digest/Sha256.d tango/tango/io/digest/Sha512.d tango/tango/io/digest/Tiger.d tango/tango/io/model/IBuffer.d tango/tango/io/model/IConduit.d tango/tango/io/model/IListener.d tango/tango/io/protocol/Allocator.d tango/tango/io/protocol/EndianProtocol.d tango/tango/io/protocol/NativeProtocol.d tango/tango/io/protocol/PickleProtocol.d tango/tango/io/protocol/Reader.d tango/tango/io/protocol/Writer.d tango/tango/io/protocol/model/IProtocol.d tango/tango/io/protocol/model/IReader.d tango/tango/io/protocol/model/IWriter.d tango/tango/io/selector/AbstractSelector.d tango/tango/io/selector/EpollSelector.d tango/tango/io/selector/PollSelector.d tango/tango/io/selector/SelectSelector.d tango/tango/io/selector/Selector.d tango/tango/io/selector/SelectorException.d tango/tango/io/selector/model/ISelector.d tango/tango/io/stream/BufferStream.d tango/tango/io/stream/DataFileStream.d tango/tango/io/stream/DataStream.d tango/tango/io/stream/DigestStream.d tango/tango/io/stream/EndianStream.d tango/tango/io/stream/FileStream.d tango/tango/io/stream/FormatStream.d tango/tango/io/stream/GreedyStream.d tango/tango/io/stream/LineStream.d tango/tango/io/stream/MapStream.d tango/tango/io/stream/SnoopStream.d tango/tango/io/stream/TextFileStream.d tango/tango/io/stream/TypedStream.d tango/tango/io/stream/UtfStream.d tango/tango/io/vfs/FileFolder.d tango/tango/io/vfs/LinkedFolder.d tango/tango/io/vfs/VirtualFolder.d tango/tango/io/vfs/ZipArchive.d tango/tango/io/vfs/model/Vfs.d tango/tango/math/Bessel.d tango/tango/math/Elliptic.d tango/tango/math/ErrorFunction.d tango/tango/math/GammaFunction.d tango/tango/math/IEEE.d tango/tango/math/Math.d tango/tango/math/Probability.d tango/tango/math/Random.d tango/tango/net/DatagramConduit.d tango/tango/net/InternetAddress.d tango/tango/net/MulticastConduit.d tango/tango/net/ServerSocket.d tango/tango/net/Socket.d tango/tango/net/SocketConduit.d tango/tango/net/SocketListener.d tango/tango/net/Uri.d tango/tango/net/cluster/CacheInvalidatee.d tango/tango/net/cluster/CacheInvalidator.d tango/tango/net/cluster/NetworkAlert.d tango/tango/net/cluster/NetworkCache.d tango/tango/net/cluster/NetworkCall.d tango/tango/net/cluster/NetworkClient.d tango/tango/net/cluster/NetworkMessage.d tango/tango/net/cluster/NetworkQueue.d tango/tango/net/cluster/NetworkRegistry.d tango/tango/net/cluster/NetworkTask.d tango/tango/net/cluster/QueuedCache.d tango/tango/net/cluster/model/ICache.d tango/tango/net/cluster/model/IChannel.d tango/tango/net/cluster/model/ICluster.d tango/tango/net/cluster/model/IConsumer.d tango/tango/net/cluster/model/IMessage.d tango/tango/net/cluster/tina/CacheServer.d tango/tango/net/cluster/tina/CacheThread.d tango/tango/net/cluster/tina/Cluster.d tango/tango/net/cluster/tina/ClusterCache.d tango/tango/net/cluster/tina/ClusterQueue.d tango/tango/net/cluster/tina/ClusterServer.d tango/tango/net/cluster/tina/ClusterTask.d tango/tango/net/cluster/tina/ClusterThread.d tango/tango/net/cluster/tina/ClusterTypes.d tango/tango/net/cluster/tina/CmdParser.d tango/tango/net/cluster/tina/ProtocolReader.d tango/tango/net/cluster/tina/ProtocolWriter.d tango/tango/net/cluster/tina/QueueFile.d tango/tango/net/cluster/tina/QueueServer.d tango/tango/net/cluster/tina/QueueThread.d tango/tango/net/cluster/tina/RollCall.d tango/tango/net/cluster/tina/TaskServer.d tango/tango/net/cluster/tina/TaskThread.d tango/tango/net/cluster/tina/util/AbstractServer.d tango/tango/net/cluster/tina/util/ServerThread.d tango/tango/net/cluster/tina/util/model/IServer.d tango/tango/net/ftp/FtpClient.d tango/tango/net/ftp/Telnet.d tango/tango/net/http/ChunkStream.d tango/tango/net/http/HttpClient.d tango/tango/net/http/HttpConst.d tango/tango/net/http/HttpCookies.d tango/tango/net/http/HttpGet.d tango/tango/net/http/HttpHeaders.d tango/tango/net/http/HttpParams.d tango/tango/net/http/HttpPost.d tango/tango/net/http/HttpStack.d tango/tango/net/http/HttpTokens.d tango/tango/net/http/HttpTriplet.d tango/tango/net/http/model/HttpParamsView.d tango/tango/net/model/UriView.d tango/tango/stdc/complex.d tango/tango/stdc/config.d tango/tango/stdc/ctype.d tango/tango/stdc/errno.d tango/tango/stdc/fenv.d tango/tango/stdc/inttypes.d tango/tango/stdc/limits.d tango/tango/stdc/locale.d tango/tango/stdc/math.d tango/tango/stdc/posix/arpa/inet.d tango/tango/stdc/posix/config.d tango/tango/stdc/posix/dirent.d tango/tango/stdc/posix/dlfcn.d tango/tango/stdc/posix/fcntl.d tango/tango/stdc/posix/inttypes.d tango/tango/stdc/posix/net/if_.d tango/tango/stdc/posix/netinet/in_.d tango/tango/stdc/posix/netinet/tcp.d tango/tango/stdc/posix/poll.d tango/tango/stdc/posix/pthread.d tango/tango/stdc/posix/pwd.d tango/tango/stdc/posix/sched.d tango/tango/stdc/posix/semaphore.d tango/tango/stdc/posix/setjmp.d tango/tango/stdc/posix/signal.d tango/tango/stdc/posix/stdio.d tango/tango/stdc/posix/stdlib.d tango/tango/stdc/posix/sys/ipc.d tango/tango/stdc/posix/sys/mman.d tango/tango/stdc/posix/sys/select.d tango/tango/stdc/posix/sys/shm.d tango/tango/stdc/posix/sys/socket.d tango/tango/stdc/posix/sys/stat.d tango/tango/stdc/posix/sys/time.d tango/tango/stdc/posix/sys/types.d tango/tango/stdc/posix/sys/uio.d tango/tango/stdc/posix/sys/wait.d tango/tango/stdc/posix/time.d tango/tango/stdc/posix/ucontext.d tango/tango/stdc/posix/unistd.d tango/tango/stdc/posix/utime.d tango/tango/stdc/signal.d tango/tango/stdc/stdarg.d tango/tango/stdc/stddef.d tango/tango/stdc/stdint.d tango/tango/stdc/stdio.d tango/tango/stdc/stdlib.d tango/tango/stdc/string.d tango/tango/stdc/stringz.d tango/tango/stdc/tgmath.d tango/tango/stdc/time.d tango/tango/stdc/wctype.d tango/tango/sys/Common.d tango/tango/sys/Environment.d tango/tango/sys/Pipe.d tango/tango/sys/Process.d tango/tango/sys/SharedLib.d tango/tango/sys/darwin/darwin.d tango/tango/sys/linux/epoll.d tango/tango/sys/linux/linux.d tango/tango/sys/linux/socket.d tango/tango/sys/win32/CodePage.d tango/tango/sys/win32/Macros.di tango/tango/sys/win32/Process.di tango/tango/sys/win32/Types.di tango/tango/sys/win32/UserGdi.di tango/tango/text/Ascii.d tango/tango/text/Properties.d tango/tango/text/Regex.d tango/tango/text/Text.d tango/tango/text/Unicode.d tango/tango/text/UnicodeData.d tango/tango/text/Util.d tango/tango/text/convert/Float.d tango/tango/text/convert/Format.d tango/tango/text/convert/Integer.d tango/tango/text/convert/Layout.d tango/tango/text/convert/Sprint.d tango/tango/text/convert/TimeStamp.d tango/tango/text/convert/UnicodeBom.d tango/tango/text/convert/Utf.d tango/tango/text/locale/Collation.d tango/tango/text/locale/Convert.d tango/tango/text/locale/Core.d tango/tango/text/locale/Data.d tango/tango/text/locale/Locale.d tango/tango/text/locale/Parse.d tango/tango/text/locale/Posix.d tango/tango/text/locale/Win32.d tango/tango/text/stream/LineIterator.d tango/tango/text/stream/QuoteIterator.d tango/tango/text/stream/RegexIterator.d tango/tango/text/stream/SimpleIterator.d tango/tango/text/stream/StreamIterator.d tango/tango/time/Clock.d tango/tango/time/ISO8601.d tango/tango/time/StopWatch.d tango/tango/time/Time.d tango/tango/time/WallClock.d tango/tango/time/chrono/Calendar.d tango/tango/time/chrono/Gregorian.d tango/tango/time/chrono/GregorianBased.d tango/tango/time/chrono/Hebrew.d tango/tango/time/chrono/Hijri.d tango/tango/time/chrono/Japanese.d tango/tango/time/chrono/Korean.d tango/tango/time/chrono/Taiwan.d tango/tango/time/chrono/ThaiBuddhist.d tango/tango/util/ArgParser.d tango/tango/util/Arguments.d tango/tango/util/Convert.d tango/tango/util/PathUtil.d tango/tango/util/collection/ArrayBag.d tango/tango/util/collection/ArraySeq.d tango/tango/util/collection/CircularSeq.d tango/tango/util/collection/HashMap.d tango/tango/util/collection/HashSet.d tango/tango/util/collection/LinkMap.d tango/tango/util/collection/LinkSeq.d tango/tango/util/collection/TreeBag.d tango/tango/util/collection/TreeMap.d tango/tango/util/collection/impl/AbstractIterator.d tango/tango/util/collection/impl/BagCollection.d tango/tango/util/collection/impl/CLCell.d tango/tango/util/collection/impl/Cell.d tango/tango/util/collection/impl/Collection.d tango/tango/util/collection/impl/DefaultComparator.d tango/tango/util/collection/impl/LLCell.d tango/tango/util/collection/impl/LLPair.d tango/tango/util/collection/impl/MapCollection.d tango/tango/util/collection/impl/RBCell.d tango/tango/util/collection/impl/RBPair.d tango/tango/util/collection/impl/SeqCollection.d tango/tango/util/collection/impl/SetCollection.d tango/tango/util/collection/iterator/ArrayIterator.d tango/tango/util/collection/iterator/FilteringIterator.d tango/tango/util/collection/iterator/InterleavingIterator.d tango/tango/util/collection/model/Bag.d tango/tango/util/collection/model/BagView.d tango/tango/util/collection/model/Comparator.d tango/tango/util/collection/model/Dispenser.d tango/tango/util/collection/model/GuardIterator.d tango/tango/util/collection/model/HashParams.d tango/tango/util/collection/model/Iterator.d tango/tango/util/collection/model/Map.d tango/tango/util/collection/model/MapView.d tango/tango/util/collection/model/Seq.d tango/tango/util/collection/model/SeqView.d tango/tango/util/collection/model/Set.d tango/tango/util/collection/model/SetView.d tango/tango/util/collection/model/Sortable.d tango/tango/util/collection/model/SortedKeys.d tango/tango/util/collection/model/SortedValues.d tango/tango/util/collection/model/View.d tango/tango/util/log/Appender.d tango/tango/util/log/Configurator.d tango/tango/util/log/ConsoleAppender.d tango/tango/util/log/DateLayout.d tango/tango/util/log/Event.d tango/tango/util/log/EventLayout.d tango/tango/util/log/FileAppender.d tango/tango/util/log/Hierarchy.d tango/tango/util/log/Log.d tango/tango/util/log/Log4Layout.d tango/tango/util/log/Logger.d tango/tango/util/log/MailAppender.d tango/tango/util/log/NullAppender.d tango/tango/util/log/PropertyConfigurator.d tango/tango/util/log/RollingFileAppender.d tango/tango/util/log/SocketAppender.d tango/tango/util/log/Trace.d tango/tango/util/log/model/IHierarchy.d tango/tango/util/log/model/ILevel.d tangotests/a.d tangotests/b.d tangotests/c.d tangotests/d.d tangotests/e.d tangotests/f.d tangotests/g.d tester.d
diffstat 524 files changed, 270704 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/bin/llvmdc.conf	Fri Jan 04 01:38:42 2008 +0100
+++ b/bin/llvmdc.conf	Fri Jan 11 17:57:40 2008 +0100
@@ -1,4 +1,4 @@
 
 [Environment]
 
-DFLAGS=-I%@P%/../lphobos -E%@P%/../lib -L-L=%@P%/../lib
+DFLAGS=-I%@P%/../tango -E%@P%/../lib -L-L=%@P%/../lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/llvmdc.phobos	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,4 @@
+
+[Environment]
+
+DFLAGS=-I%@P%/../lphobos -E%@P%/../lib -L-L=%@P%/../lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/llvmdc.tango	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,4 @@
+
+[Environment]
+
+DFLAGS=-I%@P%/../tango -E%@P%/../lib -L-L=%@P%/../lib
--- a/dmd/link.c	Fri Jan 04 01:38:42 2008 +0100
+++ b/dmd/link.c	Fri Jan 11 17:57:40 2008 +0100
@@ -288,7 +288,7 @@
     argv.push((void *)"-lm");
 
     std::string corelibpath = global.params.runtimeImppath;
-    corelibpath.append("/llvmdcore.bc");
+    corelibpath.append("/libtango-base-llvmdc.a");
     argv.append(global.params.objfiles);
     argv.push((void *)corelibpath.c_str());
 
--- a/dmd/mars.c	Fri Jan 04 01:38:42 2008 +0100
+++ b/dmd/mars.c	Fri Jan 11 17:57:40 2008 +0100
@@ -77,7 +77,7 @@
     memset(&params, 0, sizeof(Param));
 }
 
-char *Loc::toChars()
+char *Loc::toChars() const
 {
     OutBuffer buf;
     char *p;
@@ -300,6 +300,8 @@
     // Predefine version identifiers
 #if IN_LLVM
     VersionCondition::addPredefinedGlobalIdent("LLVM");
+    VersionCondition::addPredefinedGlobalIdent("LLVMDC");
+    VersionCondition::addPredefinedGlobalIdent("Posix");
 #endif
 #if _WIN32
     VersionCondition::addPredefinedGlobalIdent("Windows");
--- a/dmd/mars.h	Fri Jan 04 01:38:42 2008 +0100
+++ b/dmd/mars.h	Fri Jan 11 17:57:40 2008 +0100
@@ -242,7 +242,7 @@
 
     Loc(Module *mod, unsigned linnum);
 
-    char *toChars();
+    char *toChars() const;
 };
 
 #ifndef GCC_SAFE_DMD
--- a/gen/arrays.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/arrays.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -598,6 +598,34 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2)
+{
+    Type* t1 = DtoDType(exp1->type);
+    Type* t2 = DtoDType(exp2->type);
+
+    assert(t1->ty == Tarray);
+    assert(t2 == DtoDType(t1->next));
+
+    DValue* e1 = exp1->toElem(gIR);
+    DValue* e2 = exp2->toElem(gIR);
+
+    llvm::Value *len1, *src1, *res;
+    llvm::Value* a = e1->getRVal();
+    len1 = gIR->ir->CreateLoad(DtoGEPi(a,0,0,"tmp"),"tmp");
+    res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
+
+    llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false);
+
+    src1 = gIR->ir->CreateLoad(DtoGEPi(a,0,1,"tmp"),"tmp");
+
+    DtoMemCpy(mem,src1,len1);
+
+    mem = gIR->ir->CreateGEP(mem,len1,"tmp");
+    DVarValue* memval = new DVarValue(e2->getType(), mem, true);
+    DtoAssign(memval, e2);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
 // helper for eq and cmp
 static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
 {
--- a/gen/arrays.h	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/arrays.h	Fri Jan 11 17:57:40 2008 +0100
@@ -25,6 +25,7 @@
 void DtoCatAssignElement(llvm::Value* arr, Expression* exp);
 void DtoCatAssignArray(llvm::Value* arr, Expression* exp);
 void DtoCatArrays(llvm::Value* arr, Expression* e1, Expression* e2);
+void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2);
 
 void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src);
 
--- a/gen/classes.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/classes.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -11,6 +11,7 @@
 #include "gen/arrays.h"
 #include "gen/logger.h"
 #include "gen/classes.h"
+#include "gen/structs.h"
 #include "gen/functions.h"
 #include "gen/runtime.h"
 #include "gen/dvalue.h"
@@ -32,13 +33,19 @@
         Logger::println("Adding base class members of %s", bc->base->toChars());
         LOG_SCOPE;
 
-        for (int k=0; k < bc->base->members->dim; k++) {
+        Array* arr = &bc->base->fields;
+        for (int k=0; k < arr->dim; k++) {
+            VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
+            v->toObjFile();
+        }
+
+        /*for (int k=0; k < bc->base->members->dim; k++) {
             Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
             if (dsym->isVarDeclaration())
             {
                 dsym->toObjFile();
             }
-        }
+        }*/
     }
 }
 
@@ -65,7 +72,7 @@
         }
     }
 
-    Logger::println("DtoResolveClass(%s)", cd->toPrettyChars());
+    Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
     assert(cd->type->ty == Tclass);
@@ -113,10 +120,85 @@
         dsym->toObjFile();
     }
 
+    // resolve class data fields (possibly unions)
+    Logger::println("doing class fields");
+
+    if (irstruct->offsets.empty())
+    {
+        Logger::println("has no fields");
+    }
+    else
+    {
+        Logger::println("has fields");
+        unsigned prevsize = (unsigned)-1;
+        unsigned lastoffset = (unsigned)-1;
+        const llvm::Type* fieldtype = NULL;
+        VarDeclaration* fieldinit = NULL;
+        size_t fieldpad = 0;
+        int idx = 0;
+        for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+            // first iteration
+            if (lastoffset == (unsigned)-1) {
+                lastoffset = i->first;
+                fieldtype = i->second.type;
+                fieldinit = i->second.var;
+                prevsize = gTargetData->getTypeSize(fieldtype);
+                i->second.var->llvmFieldIndex = idx;
+            }
+            // colliding offset?
+            else if (lastoffset == i->first) {
+                size_t s = gTargetData->getTypeSize(i->second.type);
+                if (s > prevsize) {
+                    fieldpad += s - prevsize;
+                    prevsize = s;
+                }
+                cd->llvmHasUnions = true;
+                i->second.var->llvmFieldIndex = idx;
+            }
+            // intersecting offset?
+            else if (i->first < (lastoffset + prevsize)) {
+                size_t s = gTargetData->getTypeSize(i->second.type);
+                assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
+                cd->llvmHasUnions = true;
+                i->second.var->llvmFieldIndex = idx;
+                i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
+            }
+            // fresh offset
+            else {
+                // commit the field
+                fieldtypes.push_back(fieldtype);
+                irstruct->defaultFields.push_back(fieldinit);
+                if (fieldpad) {
+                    fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+                    irstruct->defaultFields.push_back(NULL);
+                    idx++;
+                }
+
+                idx++;
+
+                // start new
+                lastoffset = i->first;
+                fieldtype = i->second.type;
+                fieldinit = i->second.var;
+                prevsize = gTargetData->getTypeSize(fieldtype);
+                i->second.var->llvmFieldIndex = idx;
+                fieldpad = 0;
+            }
+        }
+        fieldtypes.push_back(fieldtype);
+        irstruct->defaultFields.push_back(fieldinit);
+        if (fieldpad) {
+            fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+            irstruct->defaultFields.push_back(NULL);
+        }
+    }
+
+    /*
     // add field types
     for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
         fieldtypes.push_back(i->second.type);
     }
+    */
 
     const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
     // refine abstract types for stuff like: class C {C next;}
@@ -214,7 +296,7 @@
     if (cd->llvmDeclared) return;
     cd->llvmDeclared = true;
 
-    Logger::println("DtoDeclareClass(%s)", cd->toPrettyChars());
+    Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
     assert(cd->type->ty == Tclass);
@@ -262,7 +344,7 @@
         const llvm::StructType* infoTy = llvm::StructType::get(types);
 
         // interface info array
-        if (needs_definition && cd->vtblInterfaces->dim > 0) {
+        if (cd->vtblInterfaces->dim > 0) {
             // symbol name
             std::string nam = "_D";
             nam.append(cd->mangle());
@@ -271,7 +353,7 @@
             const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
             // declare global
             irstruct->interfaceInfosTy = arrTy;
-            irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, llvm::GlobalValue::InternalLinkage, 0, nam, gIR->module);
+            irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
         }
 
         // interface vtables
@@ -329,7 +411,7 @@
     if (cd->isInterfaceDeclaration())
         return; // nothing to do
 
-    Logger::println("DtoConstInitClass(%s)", cd->toPrettyChars());
+    Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
     IRStruct* irstruct = cd->llvmIRStruct;
@@ -355,19 +437,24 @@
     // then comes monitor
     fieldinits.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
 
+    size_t dataoffset = 2;
+
     // next comes interface vtables
     for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
     {
         IRInterface* iri = i->second;
         assert(iri->vtbl);
         fieldinits.push_back(iri->vtbl);
+        ++dataoffset;
     }
 
+    /*
     // rest
     for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
         Logger::println("adding fieldinit for: %s", i->second.var->toChars());
         fieldinits.push_back(i->second.init);
     }
+    */
 
     // get the struct (class) type
     assert(cd->type->ty == Tclass);
@@ -375,6 +462,22 @@
     const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
     const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
 
+    // go through the field inits and build the default initializer
+    size_t nfi = irstruct->defaultFields.size();
+    for (size_t i=0; i<nfi; ++i) {
+        llvm::Constant* c;
+        if (irstruct->defaultFields[i] != NULL) {
+            c = irstruct->defaultFields[i]->llvmConstInit;
+            assert(c);
+        }
+        else {
+            const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+dataoffset));
+            std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
+            c = llvm::ConstantArray::get(arrty, vals);
+        }
+        fieldinits.push_back(c);
+    }
+
     // generate initializer
 #if 0
     Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
@@ -509,7 +612,7 @@
     if (cd->llvmDefined) return;
     cd->llvmDefined = true;
 
-    Logger::println("DtoDefineClass(%s)", cd->toPrettyChars());
+    Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
     // get the struct (class) type
@@ -702,6 +805,119 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx)
+{
+    // start at the bottom of the inheritance chain
+    if (cd->baseClass != 0) {
+        unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx);
+        if (o != (unsigned)-1)
+            return o;
+    }
+
+    // check this class
+    unsigned i;
+    for (i=0; i<cd->fields.dim; ++i) {
+        VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
+        if (os == vd->offset)
+            return i+idx;
+    }
+    idx += i;
+
+    return (unsigned)-1;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result)
+{
+    unsigned idx = 0;
+    unsigned r = LLVM_ClassOffsetToIndex(this, os, idx);
+    assert(r != (unsigned)-1 && "Offset not found in any aggregate field");
+    // vtable is 0, monitor is 1
+    r += 2;
+    // interface offset further
+    r += vtblInterfaces->dim;
+    // the final index was not pushed
+    result.push_back(r); 
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs)
+{
+    Logger::println("checking for offset %u type %s:", os, t->toChars());
+    LOG_SCOPE;
+
+    if (idxs.empty())
+        idxs.push_back(0);
+
+    const llvm::Type* llt = llvm::PointerType::get(DtoType(t));
+    const llvm::Type* st = DtoType(cd->type);
+    if (ptr->getType() != st) {
+        assert(cd->llvmHasUnions);
+        ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
+    }
+
+    unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
+
+    IRStruct* irstruct = cd->llvmIRStruct;
+    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+    //for (unsigned i=0; i<cd->fields.dim; ++i) {
+        //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
+        VarDeclaration* vd = i->second.var;
+        assert(vd);
+        Type* vdtype = DtoDType(vd->type);
+        Logger::println("found %u type %s", vd->offset, vdtype->toChars());
+        assert(vd->llvmFieldIndex >= 0);
+        if (os == vd->offset && vdtype == t) {
+            idxs.push_back(vd->llvmFieldIndex + dataoffset);
+            Logger::cout() << "indexing: " << *ptr << '\n';
+            ptr = DtoGEP(ptr, idxs, "tmp");
+            if (ptr->getType() != llt)
+                ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
+            Logger::cout() << "indexing: " << *ptr << '\n';
+            if (vd->llvmFieldIndexOffset)
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+            Logger::cout() << "indexing: " << *ptr << '\n';
+            return ptr;
+        }
+        else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
+            TypeStruct* ts = (TypeStruct*)vdtype;
+            StructDeclaration* ssd = ts->sym;
+            idxs.push_back(vd->llvmFieldIndex + dataoffset);
+            if (vd->llvmFieldIndexOffset) {
+                Logger::println("has union field offset");
+                ptr = DtoGEP(ptr, idxs, "tmp");
+                if (ptr->getType() != llt)
+                    ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+                std::vector<unsigned> tmp;
+                return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
+            }
+            else {
+                const llvm::Type* sty = llvm::PointerType::get(DtoType(vd->type));
+                if (ptr->getType() != sty) {
+                    ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp");
+                    std::vector<unsigned> tmp;
+                    return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
+                }
+                else {
+                    return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs);
+                }
+            }
+        }
+    }
+
+    assert(0);
+
+    size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0));
+    assert(os % llt_sz == 0);
+    ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
+    return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 void DtoDeclareClassInfo(ClassDeclaration* cd)
 {
     if (cd->llvmClassDeclared) return;
--- a/gen/classes.h	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/classes.h	Fri Jan 11 17:57:40 2008 +0100
@@ -31,4 +31,6 @@
 DValue* DtoDynamicCastObject(DValue* val, Type* to);
 DValue* DtoCastInterfaceToObject(DValue* val, Type* to);
 
+llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs);
+
 #endif
--- a/gen/functions.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/functions.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -189,15 +189,17 @@
 
     const llvm::Type* thisty = NULL;
     if (fdecl->needThis()) {
-        if (AggregateDeclaration* ad = fdecl->isMember()) {
-            Logger::print("isMember = this is: %s\n", ad->type->toChars());
+        if (AggregateDeclaration* ad = fdecl->isMember2()) {
+            Logger::println("isMember = this is: %s", ad->type->toChars());
             thisty = DtoType(ad->type);
             //Logger::cout() << "this llvm type: " << *thisty << '\n';
             if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->recty.get()))
                 thisty = llvm::PointerType::get(thisty);
         }
-        else
-        assert(0);
+        else {
+            Logger::println("chars: %s type: %s kind: %s", fdecl->toChars(), fdecl->type->toChars(), fdecl->kind());
+            assert(0);
+        }
     }
     else if (fdecl->isNested()) {
         thisty = llvm::PointerType::get(llvm::Type::Int8Ty);
@@ -245,7 +247,7 @@
     if (fdecl->llvmResolved) return;
     fdecl->llvmResolved = true;
 
-    Logger::println("DtoResolveFunction(%s)", fdecl->toPrettyChars());
+    Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
     LOG_SCOPE;
 
     if (fdecl->llvmRunTimeHack) {
@@ -289,7 +291,7 @@
     if (fdecl->llvmDeclared) return;
     fdecl->llvmDeclared = true;
 
-    Logger::println("DtoDeclareFunction(%s)", fdecl->toPrettyChars());
+    Logger::println("DtoDeclareFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
     LOG_SCOPE;
 
     assert(!fdecl->isAbstract());
@@ -352,6 +354,17 @@
     if (!vafunc && fdecl->llvmInternal != LLVMintrinsic && fdecl->parent && DtoIsTemplateInstance(fdecl->parent))
         func->setLinkage(llvm::GlobalValue::WeakLinkage);
 
+    // extern(C) functions are always external
+    if (f->linkage == LINKc)
+        func->setLinkage(llvm::GlobalValue::ExternalLinkage);
+
+    // intrinsics are always external C
+    if (fdecl->llvmInternal == LLVMintrinsic)
+    {
+        func->setLinkage(llvm::GlobalValue::ExternalLinkage);
+        func->setCallingConv(llvm::CallingConv::C);
+    }
+
     fdecl->llvmValue = func;
     assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
 
@@ -427,7 +440,7 @@
 
     assert(fd->llvmDeclared);
 
-    Logger::println("DtoDefineFunc(%s)", fd->toPrettyChars());
+    Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars());
     LOG_SCOPE;
 
     // debug info
@@ -495,7 +508,7 @@
                         vd->llvmValue = v;
                     }
                     else {
-                        Logger::attention("some unknown argument: %s", arg ? arg->toChars() : 0);
+                        Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
                     }
                 }
 
--- a/gen/logger.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/logger.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -6,6 +6,8 @@
 #include <fstream>
 #include <string>
 
+#include "mars.h"
+
 #include "gen/logger.h"
 
 namespace Logger
@@ -67,9 +69,9 @@
     {
         return _enabled;
     }
-    void attention(const char* fmt,...)
+    void attention(const Loc& loc, const char* fmt,...)
     {
-        printf("***ATTENTION*** ");
+        printf("***ATTENTION***: %s: ", loc.toChars());
         va_list va;
         va_start(va,fmt);
         vprintf(fmt,va);
--- a/gen/logger.h	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/logger.h	Fri Jan 11 17:57:40 2008 +0100
@@ -3,6 +3,8 @@
 
 #include <iostream>
 
+struct Loc;
+
 namespace Logger
 {
     void indent();
@@ -14,7 +16,7 @@
     void disable();
     bool enabled();
 
-    void attention(const char* fmt, ...);
+    void attention(const Loc& loc, const char* fmt, ...);
 
     struct LoggerScope
     {
--- a/gen/runtime.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/runtime.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -7,20 +7,31 @@
 
 #include "root.h"
 #include "mars.h"
+#include "lexer.h"
+#include "dsymbol.h"
+#include "mtype.h"
+#include "aggregate.h"
 
 #include "gen/runtime.h"
 #include "gen/logger.h"
+#include "gen/tollvm.h"
 
 static llvm::Module* M = NULL;
 static bool runtime_failed = false;
 
+static void LLVM_D_BuildRuntimeModule();
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 bool LLVM_D_InitRuntime()
 {
-    Logger::println("*** Loading D runtime ***");
+    Logger::println("*** Initializing D runtime declarations ***");
     LOG_SCOPE;
 
+    LLVM_D_BuildRuntimeModule();
+    return true;
+
+    /*
     if (!global.params.runtimeImppath) {
         error("You must set the runtime import path with -E");
         fatal();
@@ -47,13 +58,15 @@
 
     delete buffer;
     return retval;
+    */
 }
 
 void LLVM_D_FreeRuntime()
 {
     if (M) {
-        Logger::println("*** Freeing D runtime ***");
+        Logger::println("*** Freeing D runtime declarations ***");
         delete M;
+        M = NULL;
     }
 }
 
@@ -90,9 +103,6 @@
 
 llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name)
 {
-    // TODO maybe check the target module first, to allow overriding the runtime on a pre module basis?
-    // could be done and seems like it could be neat too :)
-
     llvm::GlobalVariable* gv = target->getNamedGlobal(name);
     if (gv) {
         return gv;
@@ -118,3 +128,508 @@
     const llvm::PointerType* t = g->getType();
     return new llvm::GlobalVariable(t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName(),target);
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static const llvm::Type* rt_ptr(const llvm::Type* t)
+{
+    return llvm::PointerType::get(t);
+}
+
+static const llvm::Type* rt_array(const llvm::Type* elemty)
+{
+    std::vector<const llvm::Type*> t;
+    t.push_back(DtoSize_t());
+    t.push_back(rt_ptr(elemty));
+    return rt_ptr(llvm::StructType::get(t));
+}
+
+static const llvm::Type* rt_dg1()
+{
+    std::vector<const llvm::Type*> types;
+    types.push_back(rt_ptr(llvm::Type::Int8Ty));
+    types.push_back(rt_ptr(llvm::Type::Int8Ty));
+    const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
+
+    std::vector<const llvm::Type*> t;
+    t.push_back(rt_ptr(llvm::Type::Int8Ty));
+    t.push_back(rt_ptr(fty));
+    return rt_ptr(llvm::StructType::get(t));
+}
+
+static const llvm::Type* rt_dg2()
+{
+    std::vector<const llvm::Type*> types;
+    types.push_back(rt_ptr(llvm::Type::Int8Ty));
+    types.push_back(rt_ptr(llvm::Type::Int8Ty));
+    types.push_back(rt_ptr(llvm::Type::Int8Ty));
+    const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
+
+    std::vector<const llvm::Type*> t;
+    t.push_back(rt_ptr(llvm::Type::Int8Ty));
+    t.push_back(rt_ptr(fty));
+    return rt_ptr(llvm::StructType::get(t));
+}
+
+static void LLVM_D_BuildRuntimeModule()
+{
+    M = new llvm::Module("llvmdc internal runtime");
+
+    const llvm::Type* voidTy = llvm::Type::VoidTy;
+    const llvm::Type* boolTy = llvm::Type::Int1Ty;
+    const llvm::Type* byteTy = llvm::Type::Int8Ty;
+    const llvm::Type* shortTy = llvm::Type::Int16Ty;
+    const llvm::Type* intTy = llvm::Type::Int32Ty;
+    const llvm::Type* longTy = llvm::Type::Int64Ty;
+    const llvm::Type* floatTy = llvm::Type::FloatTy;
+    const llvm::Type* doubleTy = llvm::Type::DoubleTy;
+    const llvm::Type* sizeTy = DtoSize_t();
+    const llvm::Type* voidPtrTy = rt_ptr(byteTy);
+    const llvm::Type* stringTy = rt_array(byteTy);
+    const llvm::Type* wstringTy = rt_array(shortTy);
+    const llvm::Type* dstringTy = rt_array(intTy);
+    const llvm::Type* objectTy = rt_ptr(ClassDeclaration::object->type->llvmType->get());
+    const llvm::Type* classInfoTy = rt_ptr(ClassDeclaration::classinfo->type->llvmType->get());
+    const llvm::Type* typeInfoTy = rt_ptr(Type::typeinfo->type->llvmType->get());
+    const llvm::Type* aaTy = rt_ptr(llvm::OpaqueType::get());
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // assert
+    // void _d_assert(bool cond, uint line, char[] msg)
+    {
+        std::string fname("_d_assert");
+        std::vector<const llvm::Type*> types;
+        types.push_back(boolTy);
+        types.push_back(intTy);
+        types.push_back(stringTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // realloc
+    // void* _d_realloc(void* ptr, size_t n)
+    {
+        std::string fname("_d_realloc");
+        std::vector<const llvm::Type*> types;
+        types.push_back(voidPtrTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // free
+    // void _d_free(void* ptr)
+    {
+        std::string fname("_d_free");
+        std::vector<const llvm::Type*> types;
+        types.push_back(voidPtrTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    #define ARRAY_INIT(TY,suffix) \
+    { \
+        std::string fname("_d_array_init_"); \
+        fname.append(suffix); \
+        std::vector<const llvm::Type*> types; \
+        types.push_back(rt_ptr(TY)); \
+        types.push_back(sizeTy); \
+        types.push_back(TY); \
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
+    }
+
+    ARRAY_INIT(boolTy,"i1")
+    ARRAY_INIT(byteTy,"i8")
+    ARRAY_INIT(shortTy,"i16")
+    ARRAY_INIT(intTy,"i32")
+    ARRAY_INIT(longTy,"i64")
+    ARRAY_INIT(floatTy,"float")
+    ARRAY_INIT(doubleTy,"double")
+    ARRAY_INIT(voidPtrTy,"pointer")
+
+    #undef ARRAY_INIT
+
+    // array init mem
+    // void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
+    {
+        std::string fname("_d_array_init_mem");
+        std::vector<const llvm::Type*> types;
+        types.push_back(voidPtrTy);
+        types.push_back(sizeTy);
+        types.push_back(voidPtrTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    #define STR_APPLY1(TY,a,b) \
+    { \
+        std::string fname(a); \
+        std::string fname2(b); \
+        std::vector<const llvm::Type*> types; \
+        types.push_back(TY); \
+        types.push_back(rt_dg1()); \
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
+    }
+    STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1")
+    STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1")
+    STR_APPLY1(dstringTy, "_aApplydc1", "_aApplydw1")
+    #undef STR_APPLY
+
+    #define STR_APPLY2(TY,a,b) \
+    { \
+        std::string fname(a); \
+        std::string fname2(b); \
+        std::vector<const llvm::Type*> types; \
+        types.push_back(TY); \
+        types.push_back(rt_dg2()); \
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
+    }
+    STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2")
+    STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2")
+    STR_APPLY2(dstringTy, "_aApplydc2", "_aApplydw2")
+    #undef STR_APPLY2
+
+    #define STR_APPLY_R1(TY,a,b) \
+    { \
+        std::string fname(a); \
+        std::string fname2(b); \
+        std::vector<const llvm::Type*> types; \
+        types.push_back(TY); \
+        types.push_back(rt_dg1()); \
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
+    }
+    STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1")
+    STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1")
+    STR_APPLY_R1(dstringTy, "_aApplyRdc1", "_aApplyRdw1")
+    #undef STR_APPLY
+
+    #define STR_APPLY_R2(TY,a,b) \
+    { \
+        std::string fname(a); \
+        std::string fname2(b); \
+        std::vector<const llvm::Type*> types; \
+        types.push_back(TY); \
+        types.push_back(rt_dg2()); \
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \
+    }
+    STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2")
+    STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2")
+    STR_APPLY_R2(dstringTy, "_aApplyRdc2", "_aApplyRdw2")
+    #undef STR_APPLY2
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // fixes the length for dynamic array casts
+    // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
+    {
+        std::string fname("_d_array_cast_len");
+        std::vector<const llvm::Type*> types;
+        types.push_back(sizeTy);
+        types.push_back(sizeTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // builds the d string[] for the D main args from the C main args
+    // void _d_main_args(uint n, char** args, ref char[][] res)
+    {
+        std::string fname("_d_main_args");
+        std::vector<const llvm::Type*> types;
+        types.push_back(intTy);
+        types.push_back(rt_ptr(rt_ptr(byteTy)));
+        types.push_back(rt_array(stringTy->getContainedType(0)));
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // cast to object
+    // Object _d_toObject(void* p)
+    {
+        std::string fname("_d_toObject");
+        std::vector<const llvm::Type*> types;
+        types.push_back(voidPtrTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // cast interface
+    // Object _d_interface_cast(void* p, ClassInfo c)
+    {
+        std::string fname("_d_interface_cast");
+        std::vector<const llvm::Type*> types;
+        types.push_back(voidPtrTy);
+        types.push_back(classInfoTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // dynamic cast
+    // Object _d_dynamic_cast(Object o, ClassInfo c)
+    {
+        std::string fname("_d_dynamic_cast");
+        std::vector<const llvm::Type*> types;
+        types.push_back(objectTy);
+        types.push_back(classInfoTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // char[] _adReverseChar(char[] a)
+    // char[] _adSortChar(char[] a)
+    {
+        std::string fname("_adReverseChar");
+        std::string fname2("_adSortChar");
+        std::vector<const llvm::Type*> types;
+        types.push_back(stringTy);
+        types.push_back(stringTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
+    }
+
+    // wchar[] _adReverseWchar(wchar[] a)
+    // wchar[] _adSortWchar(wchar[] a)
+    {
+        std::string fname("_adReverseWchar");
+        std::string fname2("_adSortWchar");
+        std::vector<const llvm::Type*> types;
+        types.push_back(wstringTy);
+        types.push_back(wstringTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
+    }
+
+    // Array _adReverse(Array a, size_t szelem)
+    {
+        std::string fname("_adReverse");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(rt_array(byteTy));
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // Array _adDupT(TypeInfo ti, Array a)
+    {
+        std::string fname("_adDupT");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(typeInfoTy);
+        types.push_back(rt_array(byteTy));
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // int _adEq(Array a1, Array a2, TypeInfo ti)
+    // int _adCmp(Array a1, Array a2, TypeInfo ti)
+    {
+        std::string fname("_adEq");
+        std::string fname2("_adCmp");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(rt_array(byteTy));
+        types.push_back(typeInfoTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
+    }
+
+    // int _adCmpChar(Array a1, Array a2)
+    {
+        std::string fname("_adCmpChar");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(rt_array(byteTy));
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // Array _adSort(Array a, TypeInfo ti)
+    {
+        std::string fname("_adSort");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(rt_array(byteTy));
+        types.push_back(typeInfoTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // size_t _aaLen(AA aa)
+    {
+        std::string fname("_aaLen");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // void* _aaGet(AA* aa, TypeInfo keyti, void* pkey, size_t valuesize)
+    {
+        std::string fname("_aaGet");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(typeInfoTy);
+        types.push_back(voidPtrTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void* pkey)
+    {
+        std::string fname("_aaGetRvalue");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(typeInfoTy);
+        types.push_back(sizeTy);
+        types.push_back(voidPtrTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // void* _aaIn(AA aa, TypeInfo keyti, void* pkey)
+    {
+        std::string fname("_aaIn");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(typeInfoTy);
+        types.push_back(voidPtrTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // void _aaDel(AA aa, TypeInfo keyti, void* pkey)
+    {
+        std::string fname("_aaDel");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(typeInfoTy);
+        types.push_back(voidPtrTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // ArrayRet_t _aaValues(AA aa, size_t keysize, size_t valuesize)
+    {
+        std::string fname("_aaValues");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(aaTy);
+        types.push_back(sizeTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // void* _aaRehash(AA* paa, TypeInfo keyti)
+    {
+        std::string fname("_aaRehash");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(typeInfoTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // ArrayRet_t _aaKeys(AA aa, size_t keysize)
+    {
+        std::string fname("_aaKeys");
+        std::vector<const llvm::Type*> types;
+        types.push_back(rt_array(byteTy));
+        types.push_back(aaTy);
+        types.push_back(sizeTy);
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // int _aaApply(AA aa, size_t keysize, dg_t dg)
+    {
+        std::string fname("_aaApply");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(sizeTy);
+        types.push_back(rt_dg1());
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    // int _aaApply2(AA aa, size_t keysize, dg2_t dg)
+    {
+        std::string fname("_aaApply2");
+        std::vector<const llvm::Type*> types;
+        types.push_back(aaTy);
+        types.push_back(sizeTy);
+        types.push_back(rt_dg1());
+        const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    // void _moduleCtor()
+    // void _moduleDtor()
+    {
+        std::string fname("_moduleCtor");
+        std::string fname2("_moduleDtor");
+        std::vector<const llvm::Type*> types;
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+        new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
+    }
+
+}
+
+
+
+
+
+
--- a/gen/statements.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/statements.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -9,6 +9,7 @@
 #include "gen/llvm.h"
 #include "llvm/InlineAsm.h"
 
+#include "mars.h"
 #include "total.h"
 #include "init.h"
 #include "mtype.h"
@@ -27,16 +28,14 @@
 
 void CompoundStatement::toIR(IRState* p)
 {
-    Logger::println("CompoundStatement::toIR()");
+    Logger::println("CompoundStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     for (int i=0; i<statements->dim; i++)
     {
         Statement* s = (Statement*)statements->data[i];
-        if (s)
+        if (s) {
             s->toIR(p);
-        else {
-            Logger::println("??? null statement found in CompoundStatement");
         }
     }
 }
@@ -45,8 +44,7 @@
 
 void ReturnStatement::toIR(IRState* p)
 {
-    static int rsi = 0;
-    Logger::println("ReturnStatement::toIR(%d): %s", rsi++, toChars());
+    Logger::println("ReturnStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     if (exp)
@@ -126,8 +124,7 @@
 
 void ExpStatement::toIR(IRState* p)
 {
-    static int esi = 0;
-    Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars());
+    Logger::println("ExpStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     if (global.params.llvmAnnotate)
@@ -150,7 +147,7 @@
 
 void IfStatement::toIR(IRState* p)
 {
-    Logger::println("IfStatement::toIR()");
+    Logger::println("IfStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     DValue* cond_e = condition->toElem(p);
@@ -195,7 +192,7 @@
 
 void ScopeStatement::toIR(IRState* p)
 {
-    Logger::println("ScopeStatement::toIR()");
+    Logger::println("ScopeStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = p->scopeend();
@@ -226,8 +223,7 @@
 
 void WhileStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("WhileStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("WhileStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     // create while blocks
@@ -271,8 +267,7 @@
 
 void DoStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("DoStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("DoStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     // create while blocks
@@ -308,8 +303,7 @@
 
 void ForStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("ForStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("ForStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     // create for blocks
@@ -370,7 +364,7 @@
 
 void BreakStatement::toIR(IRState* p)
 {
-    Logger::println("BreakStatement::toIR(): %s", toChars());
+    Logger::println("BreakStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     if (ident != 0) {
@@ -386,7 +380,7 @@
 
 void ContinueStatement::toIR(IRState* p)
 {
-    Logger::println("ContinueStatement::toIR(): %s", toChars());
+    Logger::println("ContinueStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     if (ident != 0) {
@@ -402,7 +396,7 @@
 
 void OnScopeStatement::toIR(IRState* p)
 {
-    Logger::println("OnScopeStatement::toIR(): %s", toChars());
+    Logger::println("OnScopeStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     assert(statement);
@@ -413,7 +407,7 @@
 
 void TryFinallyStatement::toIR(IRState* p)
 {
-    Logger::println("TryFinallyStatement::toIR(): %s", toChars());
+    Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     // create basic blocks
@@ -491,11 +485,10 @@
 
 void TryCatchStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("TryCatchStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
-    Logger::attention("try-catch is not yet fully implemented, only the try block will be emitted.");
+    Logger::attention(loc, "try-catch is not yet fully implemented, only the try block will be emitted.");
 
     assert(body);
     body->toIR(p);
@@ -512,11 +505,10 @@
 
 void ThrowStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("ThrowStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
-    Logger::attention("throw is not yet implemented, replacing expression with assert(0);");
+    Logger::attention(loc, "throw is not yet implemented, replacing expression with assert(0);");
 
     DtoAssert(NULL, &loc, NULL);
 
@@ -574,7 +566,7 @@
 
 void SwitchStatement::toIR(IRState* p)
 {
-    Logger::println("SwitchStatement::toIR()");
+    Logger::println("SwitchStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = gIR->scopeend();
@@ -725,7 +717,7 @@
 //////////////////////////////////////////////////////////////////////////////
 void CaseStatement::toIR(IRState* p)
 {
-    Logger::println("CaseStatement::toIR(): %s", toChars());
+    Logger::println("CaseStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     assert(0);
@@ -735,7 +727,7 @@
 
 void UnrolledLoopStatement::toIR(IRState* p)
 {
-    Logger::println("UnrolledLoopStatement::toIR(): %s", toChars());
+    Logger::println("UnrolledLoopStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     llvm::BasicBlock* oldend = gIR->scopeend();
@@ -760,7 +752,7 @@
 
 void ForeachStatement::toIR(IRState* p)
 {
-    Logger::println("ForeachStatement::toIR(): %s", toChars());
+    Logger::println("ForeachStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     //assert(arguments->dim == 1);
@@ -916,7 +908,7 @@
 
 void LabelStatement::toIR(IRState* p)
 {
-    Logger::println("LabelStatement::toIR(): %s", toChars());
+    Logger::println("LabelStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     assert(tf == NULL);
@@ -940,7 +932,7 @@
 
 void GotoStatement::toIR(IRState* p)
 {
-    Logger::println("GotoStatement::toIR(): %s", toChars());
+    Logger::println("GotoStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     assert(tf == NULL);
@@ -959,7 +951,7 @@
 
 void WithStatement::toIR(IRState* p)
 {
-    Logger::println("WithStatement::toIR(): %s", toChars());
+    Logger::println("WithStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
     assert(exp);
@@ -976,10 +968,10 @@
 
 void SynchronizedStatement::toIR(IRState* p)
 {
-    Logger::println("SynchronizedStatement::toIR(): %s", toChars());
+    Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
-    Logger::attention("synchronized is currently ignored. only the body will be emitted");
+    Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted");
 
     body->toIR(p);
 }
@@ -988,7 +980,7 @@
 
 void AsmStatement::toIR(IRState* p)
 {
-    Logger::println("AsmStatement::toIR(): %s", toChars());
+    Logger::println("AsmStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
     error("%s: inline asm is not yet implemented", loc.toChars());
     fatal();
@@ -1020,6 +1012,18 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+void VolatileStatement::toIR(IRState* p)
+{
+    Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
+    LOG_SCOPE;
+
+    Logger::attention(loc, "volatile is currently ignored. only the body will be emitted");
+
+    statement->toIR(p);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
 //////////////////////////////////////////////////////////////////////////////
 
 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
@@ -1044,7 +1048,7 @@
 //STUBST(AsmStatement);
 //STUBST(TryCatchStatement);
 //STUBST(TryFinallyStatement);
-STUBST(VolatileStatement);
+//STUBST(VolatileStatement);
 //STUBST(LabelStatement);
 //STUBST(ThrowStatement);
 STUBST(GotoCaseStatement);
--- a/gen/structs.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/structs.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -171,7 +171,7 @@
     if (sd->llvmResolved) return;
     sd->llvmResolved = true;
 
-    Logger::println("DtoResolveStruct(%s)", sd->toChars());
+    Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
     TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
@@ -180,10 +180,16 @@
     sd->llvmIRStruct = irstruct;
     gIR->structs.push_back(irstruct);
 
-    for (int k=0; k < sd->members->dim; k++) {
+    Array* arr = &sd->fields;
+    for (int k=0; k < arr->dim; k++) {
+        VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
+        v->toObjFile();
+    }
+
+    /*for (int k=0; k < sd->members->dim; k++) {
         Dsymbol* dsym = (Dsymbol*)(sd->members->data[k]);
         dsym->toObjFile();
-    }
+    }*/
 
     Logger::println("doing struct fields");
 
@@ -293,7 +299,7 @@
     if (sd->llvmDeclared) return;
     sd->llvmDeclared = true;
 
-    Logger::println("DtoDeclareStruct(%s)", sd->toChars());
+    Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
     TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
@@ -318,7 +324,7 @@
     if (sd->llvmInitialized) return;
     sd->llvmInitialized = true;
 
-    Logger::println("DtoConstInitStruct(%s)", sd->toChars());
+    Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
     IRStruct* irstruct = sd->llvmIRStruct;
@@ -390,7 +396,7 @@
     if (sd->llvmDefined) return;
     sd->llvmDefined = true;
 
-    Logger::println("DtoDefineStruct(%s)", sd->toChars());
+    Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
     assert(sd->type->ty == Tstruct);
--- a/gen/toir.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/toir.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -14,6 +14,7 @@
 
 #include "gen/llvm.h"
 
+#include "attrib.h"
 #include "total.h"
 #include "init.h"
 #include "mtype.h"
@@ -114,10 +115,19 @@
         Logger::println("TypedefDeclaration");
         tdef->type->getTypeInfo(NULL);
     }
+    // attribute declaration
+    else if (AttribDeclaration* a = declaration->isAttribDeclaration())
+    {
+        Logger::println("AttribDeclaration");
+        for (int i=0; i < a->decl->dim; ++i)
+        {
+            DtoForceDeclareDsymbol((Dsymbol*)a->decl->data[i]);
+        }
+    }
     // unsupported declaration
     else
     {
-        error("Unimplemented DeclarationExp type");
+        error("Unimplemented DeclarationExp type. kind: %s", declaration->kind());
         assert(0);
     }
     return 0;
@@ -261,7 +271,18 @@
         assert(ts->sym->llvmConstInit);
         return ts->sym->llvmConstInit;
     }
-    assert(0 && "Only supported const VarExp is of a SymbolDeclaration");
+    else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
+    {
+        DtoForceDeclareDsymbol(ti);
+        assert(ti->llvmValue);
+        const llvm::Type* vartype = DtoType(type);
+        llvm::Constant* m = isaConstant(ti->llvmValue);
+        assert(m);
+        if (ti->llvmValue->getType() != llvm::PointerType::get(vartype))
+            m = llvm::ConstantExpr::getBitCast(m, vartype);
+        return m;
+    }
+    assert(0 && "Unsupported const VarExp kind");
     return NULL;
 }
 
@@ -836,7 +857,7 @@
         assert(tf);
     }
 
-    // va args
+    // magic stuff
     bool va_magic = false;
     bool va_intrinsic = false;
     DFuncValue* dfv = fn->isFunc();
@@ -867,6 +888,8 @@
             //Argument* fnarg = Argument::getNth(tf->parameters, 0);
             Expression* exp = (Expression*)arguments->data[0];
             DValue* expv = exp->toElem(p);
+            if (expv->getType()->toBasetype()->ty != Tint32)
+                expv = DtoCast(expv, Type::tint32);
             llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
             return new DImValue(type, alloc);
         }
@@ -1315,18 +1338,33 @@
             assert(e1type->next->ty == Tstruct);
             TypeStruct* ts = (TypeStruct*)e1type->next;
             Logger::println("Struct member offset:%d", vd->offset);
+
             llvm::Value* src = l->getRVal();
+
             std::vector<unsigned> vdoffsets;
             arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets);
         }
         else if (e1type->ty == Tclass) {
             TypeClass* tc = (TypeClass*)e1type;
             Logger::println("Class member offset: %d", vd->offset);
-            std::vector<unsigned> vdoffsets(1,0);
+
+            llvm::Value* src = l->getRVal();
+
+            std::vector<unsigned> vdoffsets;
+            arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets);
+
+            /*std::vector<unsigned> vdoffsets(1,0);
             tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets);
+
             llvm::Value* src = l->getRVal();
-            //Logger::cout() << "src: " << *src << '\n';
+
+            Logger::println("indices:");
+            for (size_t i=0; i<vdoffsets.size(); ++i)
+                Logger::println("%d", vdoffsets[i]);
+
+            Logger::cout() << "src: " << *src << '\n';
             arrptr = DtoGEP(src,vdoffsets,"tmp",p->scopebb());
+            Logger::cout() << "dst: " << *arrptr << '\n';*/
         }
         else
             assert(0);
@@ -1609,7 +1647,11 @@
         }
         if (!skip)
         {
-            eval = new llvm::ICmpInst(cmpop, l->getRVal(), r->getRVal(), "tmp", p->scopebb());
+            llvm::Value* a = l->getRVal();
+            llvm::Value* b = r->getRVal();
+            Logger::cout() << "type 1: " << *a << '\n';
+            Logger::cout() << "type 2: " << *b << '\n';
+            eval = new llvm::ICmpInst(cmpop, a, b, "tmp", p->scopebb());
         }
     }
     else if (t->isfloating())
@@ -1810,44 +1852,47 @@
     llvm::Value* emem = 0;
     bool inplace = false;
 
-    if (onstack) {
-        assert(ntype->ty == Tclass);
-        emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint());
-    }
-    else if (ntype->ty == Tclass) {
-        emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
-    }
-    else if (ntype->ty == Tarray) {
-        assert(arguments);
-        if (arguments->dim == 1) {
-            DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
-            llvm::Value* dimval = sz->getRVal();
-            Type* nnt = DtoDType(ntype->next);
-            if (nnt->ty == Tvoid)
-                nnt = Type::tint8;
-            if (!p->topexp() || p->topexp()->e2 != this) {
-                const llvm::Type* restype = DtoType(type);
-                Logger::cout() << "restype = " << *restype << '\n';
-                emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
-                DtoNewDynArray(emem, dimval, nnt);
-                return new DVarValue(newtype, emem, true);
+    {
+        Logger::println("Allocating memory");
+        LOG_SCOPE;
+        if (onstack) {
+            assert(ntype->ty == Tclass);
+            emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint());
+        }
+        else if (ntype->ty == Tclass) {
+            emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
+        }
+        else if (ntype->ty == Tarray) {
+            assert(arguments);
+            if (arguments->dim == 1) {
+                DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
+                llvm::Value* dimval = sz->getRVal();
+                Type* nnt = DtoDType(ntype->next);
+                if (nnt->ty == Tvoid)
+                    nnt = Type::tint8;
+
+                if (p->topexp() && p->topexp()->e2 == this) {
+                    assert(p->topexp()->v);
+                    emem = p->topexp()->v->getLVal();
+                    DtoNewDynArray(emem, dimval, nnt);
+                    inplace = true;
+                }
+                else {
+                    const llvm::Type* restype = DtoType(type);
+                    Logger::cout() << "restype = " << *restype << '\n';
+                    emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
+                    DtoNewDynArray(emem, dimval, nnt);
+                    return new DVarValue(newtype, emem, true);
+                }
             }
-            else if (p->topexp() && p->topexp()->e2 == this) {
-                assert(p->topexp()->v);
-                emem = p->topexp()->v->getLVal();
-                DtoNewDynArray(emem, dimval, nnt);
-                inplace = true;
+            else {
+                assert(0 && "num args to 'new' != 1");
             }
-            else
-            assert(0);
         }
         else {
-            assert(0);
+            emem = new llvm::MallocInst(t,"tmp",p->scopebb());
         }
     }
-    else {
-        emem = new llvm::MallocInst(t,"tmp",p->scopebb());
-    }
 
     if (ntype->ty == Tclass) {
         // first apply the static initializer
@@ -1856,13 +1901,20 @@
 
         // set the this var for nested classes
         if (thisexp) {
+            Logger::println("Resolving 'this' expression");
+            LOG_SCOPE;
             DValue* thisval = thisexp->toElem(p);
             size_t idx = 2;
             idx += tc->sym->llvmIRStruct->interfaces.size();
-            DtoStore(thisval->getRVal(), DtoGEPi(emem,0,idx,"tmp"));
+            llvm::Value* dst = thisval->getRVal();
+            llvm::Value* src = DtoGEPi(emem,0,idx,"tmp");
+            Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
+            DtoStore(dst, src);
         }
         else if (tc->sym->isNested())
         {
+            Logger::println("Resolving nested context");
+            LOG_SCOPE;
             size_t idx = 2;
             idx += tc->sym->llvmIRStruct->interfaces.size();
             llvm::Value* nest = p->func()->decl->llvmNested;
@@ -1876,6 +1928,8 @@
 
         // then call constructor
         if (arguments) {
+            Logger::println("Calling constructor");
+            LOG_SCOPE;
             assert(member);
             assert(member->llvmValue);
             llvm::Function* fn = llvm::cast<llvm::Function>(member->llvmValue);
@@ -2336,17 +2390,25 @@
 
     Type* t = DtoDType(type);
 
+    bool arrNarr = DtoDType(e1->type) == DtoDType(e2->type);
+
     IRExp* ex = p->topexp();
     if (ex && ex->e2 == this) {
         assert(ex->v);
-        DtoCatArrays(ex->v->getLVal(),e1,e2);
+        if (arrNarr)
+            DtoCatArrays(ex->v->getLVal(),e1,e2);
+        else
+            DtoCatArrayElement(ex->v->getLVal(),e1,e2);
         return new DImValue(type, ex->v->getLVal(), true);
     }
     else {
         assert(t->ty == Tarray);
         const llvm::Type* arrty = DtoType(t);
         llvm::Value* dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint());
-        DtoCatArrays(dst,e1,e2);
+        if (arrNarr)
+            DtoCatArrays(dst,e1,e2);
+        else
+            DtoCatArrayElement(dst,e1,e2);
         return new DVarValue(type, dst, true);
     }
 }
--- a/gen/tollvm.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/tollvm.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -134,6 +134,7 @@
                     }
                 }
             }
+            Logger::println("no type found");
         }
 
         TypeClass* tc = (TypeClass*)t;
@@ -349,7 +350,10 @@
     switch(prot)
     {
     case PROTprivate:
-        return llvm::GlobalValue::InternalLinkage;
+        if (stc & STCextern)
+            return llvm::GlobalValue::ExternalLinkage;
+        else
+            return llvm::GlobalValue::InternalLinkage;
 
     case PROTpublic:
     case PROTpackage:
@@ -903,8 +907,12 @@
     else if (t->ty == Tdelegate) {
         if (rhs->isNull())
             DtoNullDelegate(lhs->getLVal());
-        else if (!rhs->inPlace())
-            DtoDelegateCopy(lhs->getLVal(), rhs->getRVal());
+        else if (!rhs->inPlace()) {
+            llvm::Value* l = lhs->getLVal();
+            llvm::Value* r = rhs->getRVal();
+            Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
+            DtoDelegateCopy(l, r);
+        }
     }
     else if (t->ty == Tclass) {
         assert(t2->ty == Tclass);
--- a/gen/toobj.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/toobj.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -351,6 +351,7 @@
     for (size_t i = 0; i < aclasses.dim; i++)
     {
         ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
+        Logger::println("class: %s", cd->toPrettyChars());
         assert(cd->llvmClass);
         classInits.push_back(cd->llvmClass);
     }
@@ -370,9 +371,8 @@
     initVec.push_back(c);
 
     // flags
-    if (needmoduleinfo)
-        c = DtoConstUint(0);        // flags (4 means MIstandalone)
-    else
+    c = DtoConstUint(0);
+    if (!needmoduleinfo)
         c = DtoConstUint(4);        // flags (4 means MIstandalone)
     initVec.push_back(c);
 
@@ -391,6 +391,22 @@
     c = unittest ? unittest : moduleinfo->llvmConstInit->getOperand(8);
     initVec.push_back(c);
 
+    // xgetMembers
+    c = moduleinfo->llvmConstInit->getOperand(9);
+    initVec.push_back(c);
+
+    // ictor
+    c = moduleinfo->llvmConstInit->getOperand(10);
+    initVec.push_back(c);
+
+    /*Logger::println("MODULE INFO INITIALIZERS");
+    for (size_t i=0; i<initVec.size(); ++i)
+    {
+        Logger::cout() << *initVec[i] << '\n';
+        if (initVec[i]->getType() != moduleinfoTy->getElementType(i))
+            assert(0);
+    }*/
+
     // create initializer
     llvm::Constant* constMI = llvm::ConstantStruct::get(moduleinfoTy, initVec);
 
@@ -442,42 +458,6 @@
 
 /* ================================================================== */
 
-static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx)
-{
-    // start at the bottom of the inheritance chain
-    if (cd->baseClass != 0) {
-        unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx);
-        if (o != (unsigned)-1)
-            return o;
-    }
-
-    // check this class
-    unsigned i;
-    for (i=0; i<cd->fields.dim; ++i) {
-        VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
-        if (os == vd->offset)
-            return i+idx;
-    }
-    idx += i;
-
-    return (unsigned)-1;
-}
-
-void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result)
-{
-    unsigned idx = 0;
-    unsigned r = LLVM_ClassOffsetToIndex(this, os, idx);
-    assert(r != (unsigned)-1 && "Offset not found in any aggregate field");
-    // vtable is 0, monitor is 1
-    r += 2;
-    // interface offset further
-    r += vtblInterfaces->dim;
-    // the final index was not pushed
-    result.push_back(r); 
-}
-
-/* ================================================================== */
-
 void ClassDeclaration::toObjFile()
 {
     gIR->resolveList.push_back(this);
@@ -510,6 +490,11 @@
     // global variable or magic
     if (isDataseg())
     {
+        // we don't want to touch private static members at all !!!
+        if ((prot() & PROTprivate) && getModule() != gIR->dmodule)
+            return;
+
+        // don't duplicate work
         if (llvmResolved) return;
         llvmResolved = true;
         llvmDeclared = true;
@@ -548,9 +533,6 @@
             DtoConstInitGlobal(this);
         else
             gIR->constInitList.push_back(this);
-
-        //if (storage_class & STCprivate)
-        //    gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility);
     }
 
     // inside aggregate declaration. declare a field.
--- a/gen/typinf.cpp	Fri Jan 04 01:38:42 2008 +0100
+++ b/gen/typinf.cpp	Fri Jan 11 17:57:40 2008 +0100
@@ -251,7 +251,7 @@
     if (tid->llvmResolved) return;
     tid->llvmResolved = true;
 
-    Logger::println("* DtoResolveTypeInfo(%s)", tid->toChars());
+    Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
     tid->llvmIRGlobal = new IRGlobal(tid);
@@ -264,7 +264,7 @@
     if (tid->llvmDeclared) return;
     tid->llvmDeclared = true;
 
-    Logger::println("* DtoDeclareTypeInfo(%s)", tid->toChars());
+    Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
     std::string mangled(tid->mangle());
@@ -274,13 +274,24 @@
 
     // this is a declaration of a builtin __initZ var
     if (tid->tinfo->builtinTypeInfo()) {
-        tid->llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangled.c_str());
-        assert(tid->llvmValue);
-        mangled.append("__TYPE");
-        gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0));
-        Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str());
-        tid->llvmInitialized = true;
-        tid->llvmDefined = true;
+        llvm::Value* found = gIR->module->getNamedGlobal(mangled);
+        if (!found)
+        {
+            const llvm::Type* t = llvm::OpaqueType::get();
+            llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
+            assert(g);
+            tid->llvmValue = g;
+            mangled.append("__TYPE");
+            gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0));
+            Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str());
+            tid->llvmInitialized = true;
+            tid->llvmDefined = true;
+        }
+        else if (!tid->llvmValue) {
+            tid->llvmValue = found;
+            tid->llvmInitialized = true;
+            tid->llvmDefined = true;
+        }
     }
     // custom typedef
     else {
@@ -294,7 +305,7 @@
     if (tid->llvmInitialized) return;
     tid->llvmInitialized = true;
 
-    Logger::println("* DtoConstInitTypeInfo(%s)", tid->toChars());
+    Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
     gIR->defineList.push_back(tid);
@@ -305,7 +316,7 @@
     if (tid->llvmDefined) return;
     tid->llvmDefined = true;
 
-    Logger::println("* DtoDefineTypeInfo(%s)", tid->toChars());
+    Logger::println("DtoDefineTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
     tid->llvmDefine();
@@ -912,8 +923,9 @@
     {
         fd = fdx->overloadExactMatch(tftohash);
         if (fd) {
+            DtoForceDeclareDsymbol(fd);
             assert(fd->llvmValue != 0);
-            llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+            llvm::Constant* c = isaConstant(fd->llvmValue);
             assert(c);
             c = llvm::ConstantExpr::getBitCast(c, ptty);
             sinits.push_back(c);
@@ -937,8 +949,9 @@
         {
             fd = fdx->overloadExactMatch(tfeqptr);
             if (fd) {
+                DtoForceDeclareDsymbol(fd);
                 assert(fd->llvmValue != 0);
-                llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+                llvm::Constant* c = isaConstant(fd->llvmValue);
                 assert(c);
                 c = llvm::ConstantExpr::getBitCast(c, ptty);
                 sinits.push_back(c);
@@ -964,8 +977,9 @@
     {
         fd = fdx->overloadExactMatch(tftostring);
         if (fd) {
+            DtoForceDeclareDsymbol(fd);
             assert(fd->llvmValue != 0);
-            llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+            llvm::Constant* c = isaConstant(fd->llvmValue);
             assert(c);
             c = llvm::ConstantExpr::getBitCast(c, ptty);
             sinits.push_back(c);
--- a/llvmdc.kdevelop	Fri Jan 04 01:38:42 2008 +0100
+++ b/llvmdc.kdevelop	Fri Jan 11 17:57:40 2008 +0100
@@ -402,6 +402,178 @@
       <path>obj/Debug/utf.d</path>
       <path>obj/Debug/version.d</path>
       <path>obj</path>
+      <path>dmd24</path>
+      <path>dmd24/access.c</path>
+      <path>dmd24/aggregate.h</path>
+      <path>dmd24/array.c</path>
+      <path>dmd24/arraytypes.h</path>
+      <path>dmd24/attrib.c</path>
+      <path>dmd24/attrib.h</path>
+      <path>dmd24/cast.c</path>
+      <path>dmd24/class.c</path>
+      <path>dmd24/complex_t.h</path>
+      <path>dmd24/cond.c</path>
+      <path>dmd24/cond.h</path>
+      <path>dmd24/constfold.c</path>
+      <path>dmd24/dchar.c</path>
+      <path>dmd24/dchar.h</path>
+      <path>dmd24/declaration.c</path>
+      <path>dmd24/declaration.h</path>
+      <path>dmd24/delegatize.c</path>
+      <path>dmd24/doc.c</path>
+      <path>dmd24/doc.h</path>
+      <path>dmd24/dsymbol.c</path>
+      <path>dmd24/dsymbol.h</path>
+      <path>dmd24/dump.c</path>
+      <path>dmd24/entity.c</path>
+      <path>dmd24/enum.c</path>
+      <path>dmd24/enum.h</path>
+      <path>dmd24/expression.c</path>
+      <path>dmd24/expression.h</path>
+      <path>dmd24/func.c</path>
+      <path>dmd24/gnuc.c</path>
+      <path>dmd24/gnuc.h</path>
+      <path>dmd24/hdrgen.c</path>
+      <path>dmd24/hdrgen.h</path>
+      <path>dmd24/html.c</path>
+      <path>dmd24/html.h</path>
+      <path>dmd24/identifier.c</path>
+      <path>dmd24/identifier.h</path>
+      <path>dmd24/idgen.c</path>
+      <path>dmd24/impcnvgen.c</path>
+      <path>dmd24/import.c</path>
+      <path>dmd24/import.h</path>
+      <path>dmd24/inifile.c</path>
+      <path>dmd24/init.c</path>
+      <path>dmd24/init.h</path>
+      <path>dmd24/inline.c</path>
+      <path>dmd24/interpret.c</path>
+      <path>dmd24/lexer.c</path>
+      <path>dmd24/lexer.h</path>
+      <path>dmd24/link.c</path>
+      <path>dmd24/lstring.c</path>
+      <path>dmd24/lstring.h</path>
+      <path>dmd24/macro.c</path>
+      <path>dmd24/macro.h</path>
+      <path>dmd24/mangle.c</path>
+      <path>dmd24/mars.c</path>
+      <path>dmd24/mars.h</path>
+      <path>dmd24/mem.c</path>
+      <path>dmd24/mem.h</path>
+      <path>dmd24/module.c</path>
+      <path>dmd24/module.h</path>
+      <path>dmd24/mtype.c</path>
+      <path>dmd24/mtype.h</path>
+      <path>dmd24/opover.c</path>
+      <path>dmd24/optimize.c</path>
+      <path>dmd24/parse.c</path>
+      <path>dmd24/parse.h</path>
+      <path>dmd24/port.h</path>
+      <path>dmd24/root.c</path>
+      <path>dmd24/root.h</path>
+      <path>dmd24/scope.c</path>
+      <path>dmd24/scope.h</path>
+      <path>dmd24/statement.c</path>
+      <path>dmd24/statement.h</path>
+      <path>dmd24/staticassert.c</path>
+      <path>dmd24/staticassert.h</path>
+      <path>dmd24/stringtable.c</path>
+      <path>dmd24/stringtable.h</path>
+      <path>dmd24/struct.c</path>
+      <path>dmd24/template.c</path>
+      <path>dmd24/template.h</path>
+      <path>dmd24/total.h</path>
+      <path>dmd24/unialpha.c</path>
+      <path>dmd24/utf.c</path>
+      <path>dmd24/utf.h</path>
+      <path>dmd24/version.c</path>
+      <path>dmd24/version.h</path>
+      <path>dmd25</path>
+      <path>dmd25/access.c</path>
+      <path>dmd25/aggregate.h</path>
+      <path>dmd25/array.c</path>
+      <path>dmd25/arraytypes.h</path>
+      <path>dmd25/attrib.c</path>
+      <path>dmd25/attrib.h</path>
+      <path>dmd25/cast.c</path>
+      <path>dmd25/class.c</path>
+      <path>dmd25/complex_t.h</path>
+      <path>dmd25/cond.c</path>
+      <path>dmd25/cond.h</path>
+      <path>dmd25/constfold.c</path>
+      <path>dmd25/dchar.c</path>
+      <path>dmd25/dchar.h</path>
+      <path>dmd25/declaration.c</path>
+      <path>dmd25/declaration.h</path>
+      <path>dmd25/delegatize.c</path>
+      <path>dmd25/doc.c</path>
+      <path>dmd25/doc.h</path>
+      <path>dmd25/dsymbol.c</path>
+      <path>dmd25/dsymbol.h</path>
+      <path>dmd25/dump.c</path>
+      <path>dmd25/entity.c</path>
+      <path>dmd25/enum.c</path>
+      <path>dmd25/enum.h</path>
+      <path>dmd25/expression.c</path>
+      <path>dmd25/expression.h</path>
+      <path>dmd25/func.c</path>
+      <path>dmd25/gnuc.c</path>
+      <path>dmd25/gnuc.h</path>
+      <path>dmd25/hdrgen.c</path>
+      <path>dmd25/hdrgen.h</path>
+      <path>dmd25/html.c</path>
+      <path>dmd25/html.h</path>
+      <path>dmd25/identifier.c</path>
+      <path>dmd25/identifier.h</path>
+      <path>dmd25/idgen.c</path>
+      <path>dmd25/impcnvgen.c</path>
+      <path>dmd25/import.c</path>
+      <path>dmd25/import.h</path>
+      <path>dmd25/inifile.c</path>
+      <path>dmd25/init.c</path>
+      <path>dmd25/init.h</path>
+      <path>dmd25/inline.c</path>
+      <path>dmd25/interpret.c</path>
+      <path>dmd25/lexer.c</path>
+      <path>dmd25/lexer.h</path>
+      <path>dmd25/link.c</path>
+      <path>dmd25/lstring.c</path>
+      <path>dmd25/lstring.h</path>
+      <path>dmd25/macro.c</path>
+      <path>dmd25/macro.h</path>
+      <path>dmd25/mangle.c</path>
+      <path>dmd25/mars.c</path>
+      <path>dmd25/mars.h</path>
+      <path>dmd25/mem.c</path>
+      <path>dmd25/mem.h</path>
+      <path>dmd25/module.c</path>
+      <path>dmd25/module.h</path>
+      <path>dmd25/mtype.c</path>
+      <path>dmd25/mtype.h</path>
+      <path>dmd25/opover.c</path>
+      <path>dmd25/optimize.c</path>
+      <path>dmd25/parse.c</path>
+      <path>dmd25/parse.h</path>
+      <path>dmd25/port.h</path>
+      <path>dmd25/root.c</path>
+      <path>dmd25/root.h</path>
+      <path>dmd25/scope.c</path>
+      <path>dmd25/scope.h</path>
+      <path>dmd25/statement.c</path>
+      <path>dmd25/statement.h</path>
+      <path>dmd25/staticassert.c</path>
+      <path>dmd25/staticassert.h</path>
+      <path>dmd25/stringtable.c</path>
+      <path>dmd25/stringtable.h</path>
+      <path>dmd25/struct.c</path>
+      <path>dmd25/template.c</path>
+      <path>dmd25/template.h</path>
+      <path>dmd25/total.h</path>
+      <path>dmd25/unialpha.c</path>
+      <path>dmd25/utf.c</path>
+      <path>dmd25/utf.h</path>
+      <path>dmd25/version.c</path>
+      <path>dmd25/version.h</path>
     </blacklist>
     <build>
       <buildtool>make</buildtool>
--- a/llvmdc.kdevelop.filelist	Fri Jan 04 01:38:42 2008 +0100
+++ b/llvmdc.kdevelop.filelist	Fri Jan 11 17:57:40 2008 +0100
@@ -142,9 +142,10 @@
 lphobos/build.sh
 lphobos/crc32.d
 lphobos/gc
+lphobos/gc/gc.d
 lphobos/gc/gcbits.d
 lphobos/gc/gclinux.d
-lphobos/gc/gcstub.d
+lphobos/gc/gcx.d
 lphobos/gcstats.d
 lphobos/internal
 lphobos/internal/aApply.d
@@ -239,6 +240,666 @@
 lphobos/typeinfos2.d
 premake.lua
 runalltests.d
+tango
+tango/lib
+tango/lib/common
+tango/lib/common/tango
+tango/lib/common/tango/core
+tango/lib/common/tango/core/BitManip.d
+tango/lib/common/tango/core/Exception.d
+tango/lib/common/tango/core/Memory.d
+tango/lib/common/tango/core/Runtime.d
+tango/lib/common/tango/core/Thread.d
+tango/lib/common/tango/stdc
+tango/lib/common/tango/stdc/posix
+tango/lib/common/tango/stdc/posix/pthread_darwin.d
+tango/lib/common/tango/stdc/wrap.c
+tango/lib/compiler
+tango/lib/compiler/dmd
+tango/lib/compiler/dmd/aApply.d
+tango/lib/compiler/dmd/aApplyR.d
+tango/lib/compiler/dmd/aaA.d
+tango/lib/compiler/dmd/adi.d
+tango/lib/compiler/dmd/alloca.d
+tango/lib/compiler/dmd/arraycast.d
+tango/lib/compiler/dmd/arraycat.d
+tango/lib/compiler/dmd/cast.d
+tango/lib/compiler/dmd/cmath2.d
+tango/lib/compiler/dmd/compiler.d
+tango/lib/compiler/dmd/complex.c
+tango/lib/compiler/dmd/cover.d
+tango/lib/compiler/dmd/critical.c
+tango/lib/compiler/dmd/deh.c
+tango/lib/compiler/dmd/deh2.d
+tango/lib/compiler/dmd/dmain2.d
+tango/lib/compiler/dmd/genobj.d
+tango/lib/compiler/dmd/invariant.d
+tango/lib/compiler/dmd/lifetime.d
+tango/lib/compiler/dmd/llmath.d
+tango/lib/compiler/dmd/mars.h
+tango/lib/compiler/dmd/memory.d
+tango/lib/compiler/dmd/memset.d
+tango/lib/compiler/dmd/monitor.c
+tango/lib/compiler/dmd/obj.d
+tango/lib/compiler/dmd/qsort.d
+tango/lib/compiler/dmd/qsort2.d
+tango/lib/compiler/dmd/switch.d
+tango/lib/compiler/dmd/trace.d
+tango/lib/compiler/dmd/typeinfo
+tango/lib/compiler/dmd/typeinfo/ti_AC.d
+tango/lib/compiler/dmd/typeinfo/ti_Acdouble.d
+tango/lib/compiler/dmd/typeinfo/ti_Acfloat.d
+tango/lib/compiler/dmd/typeinfo/ti_Acreal.d
+tango/lib/compiler/dmd/typeinfo/ti_Adouble.d
+tango/lib/compiler/dmd/typeinfo/ti_Afloat.d
+tango/lib/compiler/dmd/typeinfo/ti_Ag.d
+tango/lib/compiler/dmd/typeinfo/ti_Aint.d
+tango/lib/compiler/dmd/typeinfo/ti_Along.d
+tango/lib/compiler/dmd/typeinfo/ti_Areal.d
+tango/lib/compiler/dmd/typeinfo/ti_Ashort.d
+tango/lib/compiler/dmd/typeinfo/ti_C.d
+tango/lib/compiler/dmd/typeinfo/ti_byte.d
+tango/lib/compiler/dmd/typeinfo/ti_cdouble.d
+tango/lib/compiler/dmd/typeinfo/ti_cfloat.d
+tango/lib/compiler/dmd/typeinfo/ti_char.d
+tango/lib/compiler/dmd/typeinfo/ti_creal.d
+tango/lib/compiler/dmd/typeinfo/ti_dchar.d
+tango/lib/compiler/dmd/typeinfo/ti_delegate.d
+tango/lib/compiler/dmd/typeinfo/ti_double.d
+tango/lib/compiler/dmd/typeinfo/ti_float.d
+tango/lib/compiler/dmd/typeinfo/ti_idouble.d
+tango/lib/compiler/dmd/typeinfo/ti_ifloat.d
+tango/lib/compiler/dmd/typeinfo/ti_int.d
+tango/lib/compiler/dmd/typeinfo/ti_ireal.d
+tango/lib/compiler/dmd/typeinfo/ti_long.d
+tango/lib/compiler/dmd/typeinfo/ti_ptr.d
+tango/lib/compiler/dmd/typeinfo/ti_real.d
+tango/lib/compiler/dmd/typeinfo/ti_short.d
+tango/lib/compiler/dmd/typeinfo/ti_ubyte.d
+tango/lib/compiler/dmd/typeinfo/ti_uint.d
+tango/lib/compiler/dmd/typeinfo/ti_ulong.d
+tango/lib/compiler/dmd/typeinfo/ti_ushort.d
+tango/lib/compiler/dmd/typeinfo/ti_void.d
+tango/lib/compiler/dmd/typeinfo/ti_wchar.d
+tango/lib/compiler/dmd/util
+tango/lib/compiler/dmd/util/console.d
+tango/lib/compiler/dmd/util/ctype.d
+tango/lib/compiler/dmd/util/string.d
+tango/lib/compiler/dmd/util/utf.d
+tango/lib/compiler/gdc
+tango/lib/compiler/gdc/aApply.d
+tango/lib/compiler/gdc/aApplyR.d
+tango/lib/compiler/gdc/aaA.d
+tango/lib/compiler/gdc/actest.d
+tango/lib/compiler/gdc/adi.d
+tango/lib/compiler/gdc/arraycast.d
+tango/lib/compiler/gdc/arraycat.d
+tango/lib/compiler/gdc/cast.d
+tango/lib/compiler/gdc/cmain.d
+tango/lib/compiler/gdc/cmath2.d
+tango/lib/compiler/gdc/compiler.d
+tango/lib/compiler/gdc/config
+tango/lib/compiler/gdc/config.h
+tango/lib/compiler/gdc/config/darwin8
+tango/lib/compiler/gdc/config/gen_config1.c
+tango/lib/compiler/gdc/config/gen_math.c
+tango/lib/compiler/gdc/config/gen_unix.c
+tango/lib/compiler/gdc/config/makestruct.h
+tango/lib/compiler/gdc/config/mingw
+tango/lib/compiler/gdc/config/skyos
+tango/lib/compiler/gdc/critical.c
+tango/lib/compiler/gdc/deh.c
+tango/lib/compiler/gdc/dgccmain2.d
+tango/lib/compiler/gdc/fpmath.d
+tango/lib/compiler/gdc/gcc
+tango/lib/compiler/gdc/gcc/aix_float.h
+tango/lib/compiler/gdc/gcc/builtins.d
+tango/lib/compiler/gdc/gcc/cbridge_fdset.c
+tango/lib/compiler/gdc/gcc/cbridge_math.c
+tango/lib/compiler/gdc/gcc/cbridge_stdio.c
+tango/lib/compiler/gdc/gcc/cbridge_time.c
+tango/lib/compiler/gdc/gcc/configext.d
+tango/lib/compiler/gdc/gcc/configunix.d
+tango/lib/compiler/gdc/gcc/deh.d
+tango/lib/compiler/gdc/gcc/fpmath.d
+tango/lib/compiler/gdc/gcc/support.d
+tango/lib/compiler/gdc/gcc/threadsem.d
+tango/lib/compiler/gdc/gcc/unwind.d
+tango/lib/compiler/gdc/genobj.d
+tango/lib/compiler/gdc/invariant.d
+tango/lib/compiler/gdc/lifetime.d
+tango/lib/compiler/gdc/mars.h
+tango/lib/compiler/gdc/memory.d
+tango/lib/compiler/gdc/memory_dyld.c
+tango/lib/compiler/gdc/memory_freebsd.c
+tango/lib/compiler/gdc/memset.d
+tango/lib/compiler/gdc/minimal.c
+tango/lib/compiler/gdc/monitor.c
+tango/lib/compiler/gdc/obj.d
+tango/lib/compiler/gdc/qsort2.d
+tango/lib/compiler/gdc/qsortg.d
+tango/lib/compiler/gdc/rundmain.d
+tango/lib/compiler/gdc/std
+tango/lib/compiler/gdc/std/intrinsic.d
+tango/lib/compiler/gdc/switch.d
+tango/lib/compiler/gdc/typeinfo
+tango/lib/compiler/gdc/typeinfo/ti_AC.d
+tango/lib/compiler/gdc/typeinfo/ti_Acdouble.d
+tango/lib/compiler/gdc/typeinfo/ti_Acfloat.d
+tango/lib/compiler/gdc/typeinfo/ti_Acreal.d
+tango/lib/compiler/gdc/typeinfo/ti_Adouble.d
+tango/lib/compiler/gdc/typeinfo/ti_Afloat.d
+tango/lib/compiler/gdc/typeinfo/ti_Ag.d
+tango/lib/compiler/gdc/typeinfo/ti_Aint.d
+tango/lib/compiler/gdc/typeinfo/ti_Along.d
+tango/lib/compiler/gdc/typeinfo/ti_Areal.d
+tango/lib/compiler/gdc/typeinfo/ti_Ashort.d
+tango/lib/compiler/gdc/typeinfo/ti_C.d
+tango/lib/compiler/gdc/typeinfo/ti_byte.d
+tango/lib/compiler/gdc/typeinfo/ti_cdouble.d
+tango/lib/compiler/gdc/typeinfo/ti_cfloat.d
+tango/lib/compiler/gdc/typeinfo/ti_char.d
+tango/lib/compiler/gdc/typeinfo/ti_creal.d
+tango/lib/compiler/gdc/typeinfo/ti_dchar.d
+tango/lib/compiler/gdc/typeinfo/ti_delegate.d
+tango/lib/compiler/gdc/typeinfo/ti_double.d
+tango/lib/compiler/gdc/typeinfo/ti_float.d
+tango/lib/compiler/gdc/typeinfo/ti_idouble.d
+tango/lib/compiler/gdc/typeinfo/ti_ifloat.d
+tango/lib/compiler/gdc/typeinfo/ti_int.d
+tango/lib/compiler/gdc/typeinfo/ti_ireal.d
+tango/lib/compiler/gdc/typeinfo/ti_long.d
+tango/lib/compiler/gdc/typeinfo/ti_ptr.d
+tango/lib/compiler/gdc/typeinfo/ti_real.d
+tango/lib/compiler/gdc/typeinfo/ti_short.d
+tango/lib/compiler/gdc/typeinfo/ti_ubyte.d
+tango/lib/compiler/gdc/typeinfo/ti_uint.d
+tango/lib/compiler/gdc/typeinfo/ti_ulong.d
+tango/lib/compiler/gdc/typeinfo/ti_ushort.d
+tango/lib/compiler/gdc/typeinfo/ti_void.d
+tango/lib/compiler/gdc/typeinfo/ti_wchar.d
+tango/lib/compiler/gdc/util
+tango/lib/compiler/gdc/util/console.d
+tango/lib/compiler/gdc/util/ctype.d
+tango/lib/compiler/gdc/util/string.d
+tango/lib/compiler/gdc/util/utf.d
+tango/lib/compiler/llvmdc
+tango/lib/compiler/llvmdc/aApply.d
+tango/lib/compiler/llvmdc/aApplyR.d
+tango/lib/compiler/llvmdc/aaA.d
+tango/lib/compiler/llvmdc/adi.d
+tango/lib/compiler/llvmdc/arrays.d
+tango/lib/compiler/llvmdc/build.sh
+tango/lib/compiler/llvmdc/cast.d
+tango/lib/compiler/llvmdc/contract.d
+tango/lib/compiler/llvmdc/genobj.d
+tango/lib/compiler/llvmdc/llvm
+tango/lib/compiler/llvmdc/llvm/intrinsic.di
+tango/lib/compiler/llvmdc/obj
+tango/lib/compiler/llvmdc/qsort2.d
+tango/lib/compiler/llvmdc/std
+tango/lib/compiler/llvmdc/std/intrinsic.d
+tango/lib/compiler/llvmdc/switch.d
+tango/lib/compiler/llvmdc/typeinfo
+tango/lib/compiler/llvmdc/typeinfo/ti_AC.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Acdouble.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Acfloat.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Acreal.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Adouble.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Afloat.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Ag.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Aint.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Along.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Areal.d
+tango/lib/compiler/llvmdc/typeinfo/ti_Ashort.d
+tango/lib/compiler/llvmdc/typeinfo/ti_C.d
+tango/lib/compiler/llvmdc/typeinfo/ti_byte.d
+tango/lib/compiler/llvmdc/typeinfo/ti_cdouble.d
+tango/lib/compiler/llvmdc/typeinfo/ti_cfloat.d
+tango/lib/compiler/llvmdc/typeinfo/ti_char.d
+tango/lib/compiler/llvmdc/typeinfo/ti_creal.d
+tango/lib/compiler/llvmdc/typeinfo/ti_dchar.d
+tango/lib/compiler/llvmdc/typeinfo/ti_delegate.d
+tango/lib/compiler/llvmdc/typeinfo/ti_double.d
+tango/lib/compiler/llvmdc/typeinfo/ti_float.d
+tango/lib/compiler/llvmdc/typeinfo/ti_idouble.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ifloat.d
+tango/lib/compiler/llvmdc/typeinfo/ti_int.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ireal.d
+tango/lib/compiler/llvmdc/typeinfo/ti_long.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ptr.d
+tango/lib/compiler/llvmdc/typeinfo/ti_real.d
+tango/lib/compiler/llvmdc/typeinfo/ti_short.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ubyte.d
+tango/lib/compiler/llvmdc/typeinfo/ti_uint.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ulong.d
+tango/lib/compiler/llvmdc/typeinfo/ti_ushort.d
+tango/lib/compiler/llvmdc/typeinfo/ti_void.d
+tango/lib/compiler/llvmdc/typeinfo/ti_wchar.d
+tango/lib/compiler/llvmdc/util
+tango/lib/compiler/llvmdc/util/console.d
+tango/lib/compiler/llvmdc/util/ctype.d
+tango/lib/compiler/llvmdc/util/string.d
+tango/lib/compiler/llvmdc/util/utf.d
+tango/lib/gc
+tango/lib/gc/basic
+tango/lib/gc/basic/gc.d
+tango/lib/gc/basic/gcalloc.d
+tango/lib/gc/basic/gcbits.d
+tango/lib/gc/basic/gcstats.d
+tango/lib/gc/basic/gcx.d
+tango/lib/gc/stub
+tango/lib/gc/stub/gc.d
+tango/object.di
+tango/std
+tango/std/c
+tango/std/c/stdarg.di
+tango/std/intrinsic.di
+tango/std/stdarg.di
+tango/tango
+tango/tango/core
+tango/tango/core/Array.d
+tango/tango/core/Atomic.d
+tango/tango/core/BitArray.d
+tango/tango/core/BitManip.di
+tango/tango/core/ByteSwap.d
+tango/tango/core/Exception.di
+tango/tango/core/Memory.di
+tango/tango/core/Runtime.di
+tango/tango/core/Signal.d
+tango/tango/core/Thread.di
+tango/tango/core/Traits.d
+tango/tango/core/Tuple.d
+tango/tango/core/Vararg.d
+tango/tango/core/Variant.d
+tango/tango/core/Version.d
+tango/tango/core/sync
+tango/tango/core/sync/Barrier.d
+tango/tango/core/sync/Condition.d
+tango/tango/core/sync/Config.d
+tango/tango/core/sync/Mutex.d
+tango/tango/core/sync/ReadWriteMutex.d
+tango/tango/core/sync/Semaphore.d
+tango/tango/group
+tango/tango/group/collection.d
+tango/tango/group/convert.d
+tango/tango/group/digest.d
+tango/tango/group/file.d
+tango/tango/group/http.d
+tango/tango/group/log.d
+tango/tango/group/math.d
+tango/tango/group/net.d
+tango/tango/group/stream.d
+tango/tango/group/text.d
+tango/tango/group/time.d
+tango/tango/io
+tango/tango/io/Buffer.d
+tango/tango/io/Conduit.d
+tango/tango/io/Console.d
+tango/tango/io/DeviceConduit.d
+tango/tango/io/File.d
+tango/tango/io/FileConduit.d
+tango/tango/io/FileConst.d
+tango/tango/io/FilePath.d
+tango/tango/io/FileRoots.d
+tango/tango/io/FileScan.d
+tango/tango/io/FileSystem.d
+tango/tango/io/GrowBuffer.d
+tango/tango/io/MappedBuffer.d
+tango/tango/io/Print.d
+tango/tango/io/Stdout.d
+tango/tango/io/TempFile.d
+tango/tango/io/UnicodeFile.d
+tango/tango/io/archive
+tango/tango/io/archive/Zip.d
+tango/tango/io/compress
+tango/tango/io/compress/BzipStream.d
+tango/tango/io/compress/ZlibStream.d
+tango/tango/io/compress/c
+tango/tango/io/compress/c/bzlib.d
+tango/tango/io/compress/c/zlib.d
+tango/tango/io/digest
+tango/tango/io/digest/Crc32.d
+tango/tango/io/digest/Digest.d
+tango/tango/io/digest/Md2.d
+tango/tango/io/digest/Md4.d
+tango/tango/io/digest/Md5.d
+tango/tango/io/digest/MerkleDamgard.d
+tango/tango/io/digest/Sha0.d
+tango/tango/io/digest/Sha01.d
+tango/tango/io/digest/Sha1.d
+tango/tango/io/digest/Sha256.d
+tango/tango/io/digest/Sha512.d
+tango/tango/io/digest/Tiger.d
+tango/tango/io/model
+tango/tango/io/model/IBuffer.d
+tango/tango/io/model/IConduit.d
+tango/tango/io/model/IListener.d
+tango/tango/io/protocol
+tango/tango/io/protocol/Allocator.d
+tango/tango/io/protocol/EndianProtocol.d
+tango/tango/io/protocol/NativeProtocol.d
+tango/tango/io/protocol/PickleProtocol.d
+tango/tango/io/protocol/Reader.d
+tango/tango/io/protocol/Writer.d
+tango/tango/io/protocol/model
+tango/tango/io/protocol/model/IProtocol.d
+tango/tango/io/protocol/model/IReader.d
+tango/tango/io/protocol/model/IWriter.d
+tango/tango/io/selector
+tango/tango/io/selector/AbstractSelector.d
+tango/tango/io/selector/EpollSelector.d
+tango/tango/io/selector/PollSelector.d
+tango/tango/io/selector/SelectSelector.d
+tango/tango/io/selector/Selector.d
+tango/tango/io/selector/SelectorException.d
+tango/tango/io/selector/model
+tango/tango/io/selector/model/ISelector.d
+tango/tango/io/stream
+tango/tango/io/stream/BufferStream.d
+tango/tango/io/stream/DataFileStream.d
+tango/tango/io/stream/DataStream.d
+tango/tango/io/stream/DigestStream.d
+tango/tango/io/stream/EndianStream.d
+tango/tango/io/stream/FileStream.d
+tango/tango/io/stream/FormatStream.d
+tango/tango/io/stream/GreedyStream.d
+tango/tango/io/stream/LineStream.d
+tango/tango/io/stream/MapStream.d
+tango/tango/io/stream/SnoopStream.d
+tango/tango/io/stream/TextFileStream.d
+tango/tango/io/stream/TypedStream.d
+tango/tango/io/stream/UtfStream.d
+tango/tango/io/vfs
+tango/tango/io/vfs/FileFolder.d
+tango/tango/io/vfs/LinkedFolder.d
+tango/tango/io/vfs/VirtualFolder.d
+tango/tango/io/vfs/ZipArchive.d
+tango/tango/io/vfs/model
+tango/tango/io/vfs/model/Vfs.d
+tango/tango/math
+tango/tango/math/Bessel.d
+tango/tango/math/Elliptic.d
+tango/tango/math/ErrorFunction.d
+tango/tango/math/GammaFunction.d
+tango/tango/math/IEEE.d
+tango/tango/math/Math.d
+tango/tango/math/Probability.d
+tango/tango/math/Random.d
+tango/tango/net
+tango/tango/net/DatagramConduit.d
+tango/tango/net/InternetAddress.d
+tango/tango/net/MulticastConduit.d
+tango/tango/net/ServerSocket.d
+tango/tango/net/Socket.d
+tango/tango/net/SocketConduit.d
+tango/tango/net/SocketListener.d
+tango/tango/net/Uri.d
+tango/tango/net/cluster
+tango/tango/net/cluster/CacheInvalidatee.d
+tango/tango/net/cluster/CacheInvalidator.d
+tango/tango/net/cluster/NetworkAlert.d
+tango/tango/net/cluster/NetworkCache.d
+tango/tango/net/cluster/NetworkCall.d
+tango/tango/net/cluster/NetworkClient.d
+tango/tango/net/cluster/NetworkMessage.d
+tango/tango/net/cluster/NetworkQueue.d
+tango/tango/net/cluster/NetworkRegistry.d
+tango/tango/net/cluster/NetworkTask.d
+tango/tango/net/cluster/QueuedCache.d
+tango/tango/net/cluster/model
+tango/tango/net/cluster/model/ICache.d
+tango/tango/net/cluster/model/IChannel.d
+tango/tango/net/cluster/model/ICluster.d
+tango/tango/net/cluster/model/IConsumer.d
+tango/tango/net/cluster/model/IMessage.d
+tango/tango/net/cluster/tina
+tango/tango/net/cluster/tina/CacheServer.d
+tango/tango/net/cluster/tina/CacheThread.d
+tango/tango/net/cluster/tina/Cluster.d
+tango/tango/net/cluster/tina/ClusterCache.d
+tango/tango/net/cluster/tina/ClusterQueue.d
+tango/tango/net/cluster/tina/ClusterServer.d
+tango/tango/net/cluster/tina/ClusterTask.d
+tango/tango/net/cluster/tina/ClusterThread.d
+tango/tango/net/cluster/tina/ClusterTypes.d
+tango/tango/net/cluster/tina/CmdParser.d
+tango/tango/net/cluster/tina/ProtocolReader.d
+tango/tango/net/cluster/tina/ProtocolWriter.d
+tango/tango/net/cluster/tina/QueueFile.d
+tango/tango/net/cluster/tina/QueueServer.d
+tango/tango/net/cluster/tina/QueueThread.d
+tango/tango/net/cluster/tina/RollCall.d
+tango/tango/net/cluster/tina/TaskServer.d
+tango/tango/net/cluster/tina/TaskThread.d
+tango/tango/net/cluster/tina/util
+tango/tango/net/cluster/tina/util/AbstractServer.d
+tango/tango/net/cluster/tina/util/ServerThread.d
+tango/tango/net/cluster/tina/util/model
+tango/tango/net/cluster/tina/util/model/IServer.d
+tango/tango/net/ftp
+tango/tango/net/ftp/FtpClient.d
+tango/tango/net/ftp/Telnet.d
+tango/tango/net/http
+tango/tango/net/http/ChunkStream.d
+tango/tango/net/http/HttpClient.d
+tango/tango/net/http/HttpConst.d
+tango/tango/net/http/HttpCookies.d
+tango/tango/net/http/HttpGet.d
+tango/tango/net/http/HttpHeaders.d
+tango/tango/net/http/HttpParams.d
+tango/tango/net/http/HttpPost.d
+tango/tango/net/http/HttpStack.d
+tango/tango/net/http/HttpTokens.d
+tango/tango/net/http/HttpTriplet.d
+tango/tango/net/http/model
+tango/tango/net/http/model/HttpParamsView.d
+tango/tango/net/model
+tango/tango/net/model/UriView.d
+tango/tango/stdc
+tango/tango/stdc/complex.d
+tango/tango/stdc/config.d
+tango/tango/stdc/ctype.d
+tango/tango/stdc/errno.d
+tango/tango/stdc/fenv.d
+tango/tango/stdc/inttypes.d
+tango/tango/stdc/limits.d
+tango/tango/stdc/locale.d
+tango/tango/stdc/math.d
+tango/tango/stdc/posix
+tango/tango/stdc/posix/arpa
+tango/tango/stdc/posix/arpa/inet.d
+tango/tango/stdc/posix/config.d
+tango/tango/stdc/posix/dirent.d
+tango/tango/stdc/posix/dlfcn.d
+tango/tango/stdc/posix/fcntl.d
+tango/tango/stdc/posix/inttypes.d
+tango/tango/stdc/posix/net
+tango/tango/stdc/posix/net/if_.d
+tango/tango/stdc/posix/netinet
+tango/tango/stdc/posix/netinet/in_.d
+tango/tango/stdc/posix/netinet/tcp.d
+tango/tango/stdc/posix/poll.d
+tango/tango/stdc/posix/pthread.d
+tango/tango/stdc/posix/pwd.d
+tango/tango/stdc/posix/sched.d
+tango/tango/stdc/posix/semaphore.d
+tango/tango/stdc/posix/setjmp.d
+tango/tango/stdc/posix/signal.d
+tango/tango/stdc/posix/stdio.d
+tango/tango/stdc/posix/stdlib.d
+tango/tango/stdc/posix/sys
+tango/tango/stdc/posix/sys/ipc.d
+tango/tango/stdc/posix/sys/mman.d
+tango/tango/stdc/posix/sys/select.d
+tango/tango/stdc/posix/sys/shm.d
+tango/tango/stdc/posix/sys/socket.d
+tango/tango/stdc/posix/sys/stat.d
+tango/tango/stdc/posix/sys/time.d
+tango/tango/stdc/posix/sys/types.d
+tango/tango/stdc/posix/sys/uio.d
+tango/tango/stdc/posix/sys/wait.d
+tango/tango/stdc/posix/time.d
+tango/tango/stdc/posix/ucontext.d
+tango/tango/stdc/posix/unistd.d
+tango/tango/stdc/posix/utime.d
+tango/tango/stdc/signal.d
+tango/tango/stdc/stdarg.d
+tango/tango/stdc/stddef.d
+tango/tango/stdc/stdint.d
+tango/tango/stdc/stdio.d
+tango/tango/stdc/stdlib.d
+tango/tango/stdc/string.d
+tango/tango/stdc/stringz.d
+tango/tango/stdc/tgmath.d
+tango/tango/stdc/time.d
+tango/tango/stdc/wctype.d
+tango/tango/sys
+tango/tango/sys/Common.d
+tango/tango/sys/Environment.d
+tango/tango/sys/Pipe.d
+tango/tango/sys/Process.d
+tango/tango/sys/SharedLib.d
+tango/tango/sys/darwin
+tango/tango/sys/darwin/darwin.d
+tango/tango/sys/linux
+tango/tango/sys/linux/epoll.d
+tango/tango/sys/linux/linux.d
+tango/tango/sys/linux/socket.d
+tango/tango/sys/win32
+tango/tango/sys/win32/CodePage.d
+tango/tango/sys/win32/Macros.di
+tango/tango/sys/win32/Process.di
+tango/tango/sys/win32/Types.di
+tango/tango/sys/win32/UserGdi.di
+tango/tango/text
+tango/tango/text/Ascii.d
+tango/tango/text/Properties.d
+tango/tango/text/Regex.d
+tango/tango/text/Text.d
+tango/tango/text/Unicode.d
+tango/tango/text/UnicodeData.d
+tango/tango/text/Util.d
+tango/tango/text/convert
+tango/tango/text/convert/Float.d
+tango/tango/text/convert/Format.d
+tango/tango/text/convert/Integer.d
+tango/tango/text/convert/Layout.d
+tango/tango/text/convert/Sprint.d
+tango/tango/text/convert/TimeStamp.d
+tango/tango/text/convert/UnicodeBom.d
+tango/tango/text/convert/Utf.d
+tango/tango/text/locale
+tango/tango/text/locale/Collation.d
+tango/tango/text/locale/Convert.d
+tango/tango/text/locale/Core.d
+tango/tango/text/locale/Data.d
+tango/tango/text/locale/Locale.d
+tango/tango/text/locale/Parse.d
+tango/tango/text/locale/Posix.d
+tango/tango/text/locale/Win32.d
+tango/tango/text/stream
+tango/tango/text/stream/LineIterator.d
+tango/tango/text/stream/QuoteIterator.d
+tango/tango/text/stream/RegexIterator.d
+tango/tango/text/stream/SimpleIterator.d
+tango/tango/text/stream/StreamIterator.d
+tango/tango/time
+tango/tango/time/Clock.d
+tango/tango/time/ISO8601.d
+tango/tango/time/StopWatch.d
+tango/tango/time/Time.d
+tango/tango/time/WallClock.d
+tango/tango/time/chrono
+tango/tango/time/chrono/Calendar.d
+tango/tango/time/chrono/Gregorian.d
+tango/tango/time/chrono/GregorianBased.d
+tango/tango/time/chrono/Hebrew.d
+tango/tango/time/chrono/Hijri.d
+tango/tango/time/chrono/Japanese.d
+tango/tango/time/chrono/Korean.d
+tango/tango/time/chrono/Taiwan.d
+tango/tango/time/chrono/ThaiBuddhist.d
+tango/tango/util
+tango/tango/util/ArgParser.d
+tango/tango/util/Arguments.d
+tango/tango/util/Convert.d
+tango/tango/util/PathUtil.d
+tango/tango/util/collection
+tango/tango/util/collection/ArrayBag.d
+tango/tango/util/collection/ArraySeq.d
+tango/tango/util/collection/CircularSeq.d
+tango/tango/util/collection/HashMap.d
+tango/tango/util/collection/HashSet.d
+tango/tango/util/collection/LinkMap.d
+tango/tango/util/collection/LinkSeq.d
+tango/tango/util/collection/TreeBag.d
+tango/tango/util/collection/TreeMap.d
+tango/tango/util/collection/impl
+tango/tango/util/collection/impl/AbstractIterator.d
+tango/tango/util/collection/impl/BagCollection.d
+tango/tango/util/collection/impl/CLCell.d
+tango/tango/util/collection/impl/Cell.d
+tango/tango/util/collection/impl/Collection.d
+tango/tango/util/collection/impl/DefaultComparator.d
+tango/tango/util/collection/impl/LLCell.d
+tango/tango/util/collection/impl/LLPair.d
+tango/tango/util/collection/impl/MapCollection.d
+tango/tango/util/collection/impl/RBCell.d
+tango/tango/util/collection/impl/RBPair.d
+tango/tango/util/collection/impl/SeqCollection.d
+tango/tango/util/collection/impl/SetCollection.d
+tango/tango/util/collection/iterator
+tango/tango/util/collection/iterator/ArrayIterator.d
+tango/tango/util/collection/iterator/FilteringIterator.d
+tango/tango/util/collection/iterator/InterleavingIterator.d
+tango/tango/util/collection/model
+tango/tango/util/collection/model/Bag.d
+tango/tango/util/collection/model/BagView.d
+tango/tango/util/collection/model/Comparator.d
+tango/tango/util/collection/model/Dispenser.d
+tango/tango/util/collection/model/GuardIterator.d
+tango/tango/util/collection/model/HashParams.d
+tango/tango/util/collection/model/Iterator.d
+tango/tango/util/collection/model/Map.d
+tango/tango/util/collection/model/MapView.d
+tango/tango/util/collection/model/Seq.d
+tango/tango/util/collection/model/SeqView.d
+tango/tango/util/collection/model/Set.d
+tango/tango/util/collection/model/SetView.d
+tango/tango/util/collection/model/Sortable.d
+tango/tango/util/collection/model/SortedKeys.d
+tango/tango/util/collection/model/SortedValues.d
+tango/tango/util/collection/model/View.d
+tango/tango/util/log
+tango/tango/util/log/Appender.d
+tango/tango/util/log/Configurator.d
+tango/tango/util/log/ConsoleAppender.d
+tango/tango/util/log/DateLayout.d
+tango/tango/util/log/Event.d
+tango/tango/util/log/EventLayout.d
+tango/tango/util/log/FileAppender.d
+tango/tango/util/log/Hierarchy.d
+tango/tango/util/log/Log.d
+tango/tango/util/log/Log4Layout.d
+tango/tango/util/log/Logger.d
+tango/tango/util/log/MailAppender.d
+tango/tango/util/log/NullAppender.d
+tango/tango/util/log/PropertyConfigurator.d
+tango/tango/util/log/RollingFileAppender.d
+tango/tango/util/log/SocketAppender.d
+tango/tango/util/log/Trace.d
+tango/tango/util/log/model
+tango/tango/util/log/model/IHierarchy.d
+tango/tango/util/log/model/ILevel.d
+tangotests
+tangotests/a.d
+tangotests/b.d
+tangotests/c.d
+tangotests/d.d
+tangotests/e.d
+tangotests/f.d
+tangotests/g.d
 test
 test/a.d
 test/aa1.d
@@ -391,6 +1052,7 @@
 test/funcs.d
 test/funcs2.d
 test/g.d
+test/gc1.d
 test/globals1.d
 test/globals2.d
 test/goto1.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/LICENSE	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,24 @@
+Tango is Open Source software, distributed by a group of developers which has been set up for the purpose of providing a vendor-neutral owner of Tango intellectual property. The goals of all Tango licensing decisions are to:
+
+  * Encourage adoption
+  * Discourage political contention
+  * Encourage collaboration and integration with other projects
+  * Be transparent
+
+Tango is dual-licensed:
+  * Academic Free License v2.1 (http://opensource.org/licenses/afl-2.1.php)
+  * BSD License (http://opensource.org/licenses/bsd-license.php) [1]
+
+The preferred license is the Academic Free License v2.1. All Tango projects release their code under the terms of this license. Both licenses:
+
+  * Allow commercial use without encumbrance
+  * Provide broad rights to make new products and derivative works
+  * Place no requirement on users to contribute back (although we appreciate it if you do)
+
+Users who wish to include Tango with software licensed under the (L)GPL will want to use Tango under the terms of the BSD License. [1] Tango projects may request a variance from the developers to release their projects under additional licenses in conjunction with the AFL.
+
+If you have further questions regarding Tango licensing, please do not hesitate to contact us (http://dsource.org/projects/tango/wiki/Contact).
+
+
+[1] The advertising clause has not been a part of the BSD License since July 22, 1999. (ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/README.txt	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,7 @@
+For a guide to install Tango see the online installation reference:
+
+http://dsource.org/projects/tango/wiki/TopicInstallTango
+
+The license can be found at
+
+http://dsource.org/projects/tango/wiki/LibraryLicense
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/README_LLVMDC.txt	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,10 @@
+This version of Tango is modified to work with LLVMDC
+    by Tomas Lindquist Olsen, 2008
+
+Much has been removed as this is not intended to work with other compilers.
+Hopefully in time, this will go away and the required changes merged into the
+mainline Tango repository.
+
+For more information on LLVMDC, check the site at:
+
+    http://www.dsource.org/projects/llvmdc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/dsss.conf	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,83 @@
+name = tango
+
+[tango/core]
+postinstall=install tango/core/BitManip.di $INCLUDE_PREFIX/tango/core ; \
+    install tango/core/Exception.di $INCLUDE_PREFIX/tango/core ; \
+    install tango/core/Memory.di $INCLUDE_PREFIX/tango/core ; \
+    install tango/core/Runtime.di $INCLUDE_PREFIX/tango/core ; \
+    install tango/core/Thread.di $INCLUDE_PREFIX/tango/core
+version (GNU) {
+    prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -fintfc-file=tango/core/BitManip.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -fintfc-file=tango/core/Exception.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -fintfc-file=tango/core/Memory.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -fintfc-file=tango/core/Runtime.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -fintfc-file=tango/core/Thread.di ; 
+} else version (DigitalMars) {
+    prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -Hftango/core/BitManip.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -Hftango/core/Exception.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -Hftango/core/Memory.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -Hftango/core/Runtime.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -Hftango/core/Thread.di ; 
+}
+else version (LLVMDC) {
+    prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -Hftango/core/BitManip.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -Hftango/core/Exception.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -Hftango/core/Memory.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -Hftango/core/Runtime.di ; \
+    $DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -Hftango/core/Thread.di ; 
+}
+
+version(LLVMDC) {
+    [tango/stdc]
+} else {
+
+[tango/io]
+
+[tango/math]
+
+[tango/net]
+
+[tango/stdc]
+version (Windows) {
+    exclude = tango/stdc/posix
+}
+
+[tango/sys]
+exclude = tango/sys/linux/* tango/sys/darwin/* tango/sys/win32/*
+exclude += tango/sys/TimeConverter.d
+
+version (linux) {
+    [tango/sys/linux]
+}
+
+version (darwin) {
+    [tango/sys/darwin]
+}
+
+version (Windows) {
+    [+tango/sys/win32]
+    preinstall = install tango/sys/win32/Macros.di $INCLUDE_PREFIX/tango/sys/win32 ; \
+        install tango/sys/win32/Process.di $INCLUDE_PREFIX/tango/sys/win32 ; \
+        install tango/sys/win32/Types.di $INCLUDE_PREFIX/tango/sys/win32 ; \
+        install tango/sys/win32/UserGdi.di $INCLUDE_PREFIX/tango/sys/win32
+}
+
+[tango/text]
+
+[tango/text/locale]
+version (!linux) {
+    exclude += tango/text/locale/Linux.d
+}
+version (!Windows) {
+    exclude += tango/text/locale/Win32.d
+}
+
+[tango/util]
+
+[tango/time]
+
+[tango/group]
+
+[+std]
+preinstall = installdir std $INCLUDE_PREFIX/std
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/Add.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,60 @@
+/*******************************************************************************
+
+*******************************************************************************/
+
+public import tango.net.cluster.NetworkCall;
+
+
+/*******************************************************************************
+        
+        a Task function
+
+*******************************************************************************/
+
+real add (real x, real y)
+{
+        return x + y;
+}
+
+
+/*******************************************************************************
+
+        a Task function
+
+*******************************************************************************/
+
+int divide (int x, int y)
+{
+        return x / y;
+}
+
+
+/*******************************************************************************
+
+        a verbose Task message
+
+*******************************************************************************/
+
+class Subtract : NetworkCall
+{
+        double  a,
+                b,
+                result;
+
+        double opCall (double a, double b, IChannel channel = null)
+        {
+                this.a = a;
+                this.b = b;
+                send (channel);
+                return result;
+        }
+
+        override void execute ()
+        {
+                result = a - b;
+        }
+
+        override void read  (IReader input)  {input (a)(b)(result);}
+
+        override void write (IWriter output) {output (a)(b)(result);}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/alert.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,36 @@
+private import  tango.core.Thread;
+
+private import  tango.util.log.Configurator;
+
+private import  tango.net.cluster.NetworkAlert;
+
+private import  tango.net.cluster.tina.Cluster;
+
+/*******************************************************************************
+
+        How to send and recieve Alert messages using tango.net.cluster
+
+*******************************************************************************/
+
+void main()
+{
+        // hook into the cluster
+        auto cluster = (new Cluster).join;
+
+        // hook into the Alert layer
+        auto alert = new NetworkAlert (cluster, "my.kind.of.alert");
+
+        // listen for the broadcast (on this channel)
+        alert.createConsumer (delegate void (IEvent event)
+                             {event.log.info ("Recieved alert on channel " ~ event.channel.name);}
+                             );
+
+        // say what's going on
+        alert.log.info ("broadcasting alert");
+
+        // and send everyone an empty alert (on this channel)
+        alert.broadcast;
+
+        // wait for it to arrive ...
+        Thread.sleep(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/cclient.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,48 @@
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+import tango.io.Stdout;
+
+import tango.time.StopWatch;
+
+import tango.util.log.Configurator;
+
+import tango.net.cluster.NetworkCache;
+
+import tango.net.cluster.tina.Cluster;
+
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        StopWatch w;
+
+        if (args.length > 1)
+           {
+           auto cluster = (new Cluster).join (args[1..$]);
+           auto cache   = new NetworkCache (cluster, "my.cache.channel");
+
+           while (true)
+                 {
+                 w.start;
+                 for (int i=10000; i--;)
+                      cache.put ("key", cache.EmptyMessage);
+
+                 Stdout.formatln ("{} put/s", 10000/w.stop);
+
+                 w.start;
+                 for (int i=10000; i--;)
+                      cache.get ("key");
+        
+                 Stdout.formatln ("{} get/s", 10000/w.stop);
+                 }
+           }
+        else
+           Stdout.formatln ("usage: cache cachehost:port ...");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/cserver.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,30 @@
+/*******************************************************************************
+
+*******************************************************************************/
+
+import tango.io.Console;
+
+import tango.net.InternetAddress;
+
+import tango.net.cluster.tina.CmdParser,
+       tango.net.cluster.tina.CacheServer;
+
+/*******************************************************************************
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        auto arg = new CmdParser ("cache.server");
+
+        // default number of cache entries
+        arg.size = 8192;
+
+        if (args.length > 1)
+            arg.parse (args[1..$]);
+                        
+        if (arg.help)
+            Cout ("usage: cacheserver -port=number -size=cachesize -log[=trace, info, warn, error, fatal, none]").newline;
+        else
+           (new CacheServer(new InternetAddress(arg.port), arg.log, arg.size)).start;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/invalidate.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,38 @@
+private import  tango.core.Thread;
+
+private import  tango.util.log.Configurator;
+
+private import  tango.net.cluster.tina.Cluster;
+
+private import  tango.net.cluster.QueuedCache,
+                tango.net.cluster.CacheInvalidatee,
+                tango.net.cluster.CacheInvalidator;
+
+/*******************************************************************************
+
+        Demonstrates how to invalidate cache entries across a cluster
+        via a channel
+
+*******************************************************************************/
+
+void main()
+{
+        // access the cluster
+        auto cluster = (new Cluster).join;
+
+        // wrap a cache instance with a network listener
+        auto dst = new CacheInvalidatee (cluster, "my.cache.channel", new QueuedCache!(char[], IMessage)(101));
+
+        // connect an invalidator to that cache channel
+        auto src = new CacheInvalidator (cluster, "my.cache.channel");
+
+        // stuff something in the local cache
+        dst.cache.put ("key", dst.EmptyMessage);
+
+        // get it removed via a network broadcast
+        src.log.info ("invalidating 'key' across the cluster");
+        src.invalidate ("key");
+
+        // wait for it to arrive ...
+        Thread.sleep (1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/qclient.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,44 @@
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+import tango.io.Stdout;
+
+import tango.time.StopWatch;
+
+import tango.util.log.Configurator;
+
+import tango.net.cluster.NetworkQueue;
+
+import tango.net.cluster.tina.Cluster;
+
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        StopWatch w;
+
+        auto cluster = (new Cluster).join;
+        auto queue   = new NetworkQueue (cluster, "my.queue.channel");
+
+        while (true)
+              {
+              w.start;
+              for (int i=10000; i--;)
+                   queue.put (queue.EmptyMessage);
+
+              Stdout.formatln ("{} put/s", 10000/w.stop);
+
+              uint count;
+              w.start;
+              while (queue.get !is null)
+                     ++count;
+        
+              Stdout.formatln ("{} get/s", count/w.stop);
+              }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/qlisten.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,41 @@
+private import  tango.core.Thread;
+
+private import  tango.util.log.Configurator;
+
+private import  tango.net.cluster.NetworkQueue;
+
+private import  tango.net.cluster.tina.Cluster;
+
+/*******************************************************************************
+
+        Illustrates how to setup and use a Queue in asynchronous mode
+
+*******************************************************************************/
+
+void main ()
+{
+        void listen (IEvent event)
+        {
+                while (event.get)
+                       event.log.info ("received asynch msg on channel " ~ event.channel.name);
+        }
+                
+
+        // join the cluster 
+        auto cluster = (new Cluster).join;
+
+        // access a queue of the specified name
+        auto queue = new NetworkQueue (cluster, "my.queue.channel");
+
+        // listen for messages placed in my queue, via a delegate
+        queue.createConsumer (&listen);
+
+        // stuff something into the queue
+        queue.log.info ("sending three messages to the queue");
+        queue.put (queue.EmptyMessage);
+        queue.put (queue.EmptyMessage);
+        queue.put (queue.EmptyMessage);
+
+        // wait for asynchronous msgs to arrive ...
+        Thread.sleep (1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/qrequest.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,30 @@
+private import  tango.util.log.Configurator;
+
+private import  tango.net.cluster.NetworkQueue;
+
+private import  tango.net.cluster.tina.Cluster;
+
+/*******************************************************************************
+
+        Illustrates how to setup and use a Queue in synchronous mode
+
+*******************************************************************************/
+
+void main ()
+{
+        // join the cluster 
+        auto cluster = (new Cluster).join;
+
+        // access a queue of the specified name
+        auto queue = new NetworkQueue (cluster, "my.queue.channel");
+
+        // stuff something into the queue
+        queue.log.info ("sending three messages to the queue");
+        queue.put (queue.EmptyMessage);
+        queue.put (queue.EmptyMessage);
+        queue.put (queue.EmptyMessage);
+
+        // retreive synchronously
+        while (queue.get)
+               queue.log.info ("retrieved msg");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/qserver.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,27 @@
+/*******************************************************************************
+
+*******************************************************************************/
+
+import tango.io.Console;
+
+import tango.net.InternetAddress;
+
+import tango.net.cluster.tina.CmdParser,
+       tango.net.cluster.tina.QueueServer;
+
+/*******************************************************************************
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        auto arg = new CmdParser ("queue.server");
+
+        if (args.length > 1)
+            arg.parse (args[1..$]);
+                
+        if (arg.help)
+            Cout ("usage: queueserver -port=number -log[=trace, info, warn, error, fatal, none]").newline;
+        else
+           (new QueueServer(new InternetAddress(arg.port), arg.log)).start;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/reply.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,38 @@
+private import  tango.core.Thread;
+
+private import  tango.util.log.Configurator;
+
+private import  tango.net.cluster.tina.Cluster;
+
+private import  tango.net.cluster.NetworkQueue;
+
+/*******************************************************************************
+
+*******************************************************************************/
+
+void main()
+{
+        // open the cluster and a queue channel. Note that the queue has
+        // been configured with a reply listener ...
+        auto cluster = (new Cluster).join;
+        auto queue = new NetworkQueue (cluster, "message.channel", 
+                                      (IEvent event){event.log.info ("Received reply");}
+                                      );
+
+        void recipient (IEvent event)
+        {
+                auto msg = event.get;
+        
+                event.log.info ("Replying to message on channel "~msg.reply);
+                event.reply (event.replyChannel(msg), queue.EmptyMessage);
+        }
+
+        // setup a listener to recieve and reply
+        queue.createConsumer (&recipient);
+
+        // toss a message out to the cluster
+        queue.put (queue.EmptyMessage);
+
+        // wait for completion ...
+        Thread.sleep (1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/task.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,15 @@
+/*******************************************************************************
+
+        Illustrates usage of cluster tasks
+
+*******************************************************************************/
+
+import Add, tango.io.Stdout, tango.net.cluster.tina.ClusterTask;
+
+void main (char[][] args)
+{
+        scope add = new NetCall!(add);
+
+        Stdout.formatln ("cluster expression of 3.0 + 4.0 = {}", add(3, 4));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/tclient.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,42 @@
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+import Add;
+
+import tango.io.Stdout;
+
+import tango.time.StopWatch;
+
+import tango.util.log.Configurator;
+
+import tango.net.cluster.tina.ClusterTask;
+
+/*******************************************************************************
+
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        // an implicit task instance
+        auto add = new NetCall!(add);
+
+        // an explicit task instance
+        auto sub = new Subtract;
+
+        StopWatch w;
+        while (true)
+              {
+              w.start;
+              for (int i=10000; i--;)
+                  {
+                  // both task types are used in the same manner
+                  add (1, 2);
+                  sub (3, 4);
+                  }
+              Stdout.formatln ("{} calls/s", 20000/w.stop);
+              }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/cluster/tserver.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,34 @@
+/*******************************************************************************
+
+*******************************************************************************/
+
+import tango.io.Console;
+
+import tango.net.InternetAddress;
+
+import tango.net.cluster.tina.CmdParser,
+       tango.net.cluster.tina.TaskServer;
+
+import Add;
+
+/*******************************************************************************
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        auto arg = new CmdParser ("task.server");
+
+        if (args.length > 1)
+            arg.parse (args[1..$]);
+
+        if (arg.help)
+            Cout ("usage: taskserver -port=number -log[=trace, info, warn, error, fatal, none]").newline;
+        else
+           {
+           auto server = new TaskServer (new InternetAddress(arg.port), arg.log);
+           server.enroll (new NetCall!(add));
+           server.enroll (new Subtract);
+           server.start;
+           }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/concurrency/fiber_test.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,806 @@
+import tango.core.Thread;
+
+extern (C) int printf(char * str, ...);
+
+void main()
+{
+	printf("Compile with -unittest");
+}
+
+
+unittest
+{
+    printf("Testing context creation/deletion\n");
+    int s0 = 0;
+    static int s1 = 0;
+    
+    Fiber a = new Fiber(
+    delegate void()
+    {
+        s0++;
+    });
+    
+    static void fb() { s1++; }
+    
+    Fiber b = new Fiber(&fb);
+    
+    Fiber c = new Fiber(
+        delegate void() { assert(false); });
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    
+    assert(s0 == 0);
+    assert(s1 == 0);
+    assert(a.state == Fiber.State.HOLD);
+    assert(b.state == Fiber.State.HOLD);
+    assert(c.state == Fiber.State.HOLD);
+    
+    delete c;
+    
+    assert(s0 == 0);
+    assert(s1 == 0);
+    assert(a.state == Fiber.State.HOLD);
+    assert(b.state == Fiber.State.HOLD);
+    
+    printf("running a\n");
+    a.call();
+    printf("done a\n");
+    
+    assert(a);
+    
+    assert(s0 == 1);
+    assert(s1 == 0);
+    assert(a.state == Fiber.State.TERM);
+    assert(b.state == Fiber.State.HOLD);    
+    
+    assert(b.state == Fiber.State.HOLD);
+    
+    printf("Running b\n");
+    b.call();
+    printf("Done b\n");
+    
+    assert(s0 == 1);
+    assert(s1 == 1);
+    assert(b.state == Fiber.State.TERM);
+    
+    delete a;
+    delete b;
+    
+    printf("Context creation passed\n");
+}
+    
+unittest
+{
+    printf("Testing context switching\n");
+    int s0 = 0;
+    int s1 = 0;
+    int s2 = 0;
+    
+    Fiber a = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            debug printf(" ---A---\n");
+            s0++;
+            Fiber.yield();
+        }
+    });
+    
+    
+    Fiber b = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            debug printf(" ---B---\n");
+            s1++;
+            Fiber.yield();
+        }
+    });
+    
+    
+    Fiber c = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            debug printf(" ---C---\n");
+            s2++;
+            Fiber.yield();
+        }
+    });
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    assert(s0 == 0);
+    assert(s1 == 0);
+    assert(s2 == 0);
+    
+    a.call();
+    b.call();
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    assert(s0 == 1);
+    assert(s1 == 1);
+    assert(s2 == 0);
+    
+    for(int i=0; i<20; i++)
+    {
+        c.call();
+        a.call();
+    }
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    assert(s0 == 21);
+    assert(s1 == 1);
+    assert(s2 == 20);
+    
+    delete a;
+    delete b;
+    delete c;
+    
+    printf("Context switching passed\n");
+}
+    
+unittest
+{
+    printf("Testing nested contexts\n");
+    Fiber a, b, c;
+    
+    int t0 = 0;
+    int t1 = 0;
+    int t2 = 0;
+    
+    a = new Fiber(
+    delegate void()
+    {
+        
+        t0++;
+        b.call();
+        
+    });
+    
+    b = new Fiber(
+    delegate void()
+    {
+        assert(t0 == 1);
+        assert(t1 == 0);
+        assert(t2 == 0);
+        
+        t1++;
+        c.call();
+        
+    });
+    
+    c = new Fiber(
+    delegate void()
+    {
+        assert(t0 == 1);
+        assert(t1 == 1);
+        assert(t2 == 0);
+        
+        t2++;
+    });
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    assert(t0 == 0);
+    assert(t1 == 0);
+    assert(t2 == 0);
+    
+    a.call();
+    
+    assert(t0 == 1);
+    assert(t1 == 1);
+    assert(t2 == 1);
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    
+    delete a;
+    delete b;
+    delete c;
+    
+    printf("Nesting contexts passed\n");
+}
+
+unittest
+{
+	printf("Testing basic exceptions\n");
+
+
+	int t0 = 0;
+	int t1 = 0;
+	int t2 = 0;
+
+	assert(t0 == 0);
+	assert(t1 == 0);
+	assert(t2 == 0);
+
+	try
+	{
+
+		try
+		{
+			throw new Exception("Testing\n");
+			t2++;
+		}
+		catch(Exception fx)
+		{
+			t1++;
+			throw fx;
+		}
+	
+		t2++;
+	}
+	catch(Exception ex)
+	{
+		t0++;
+		printf("%.*s\n", ex.toString);
+	}
+
+	assert(t0 == 1);
+	assert(t1 == 1);
+	assert(t2 == 0);
+
+	printf("Basic exceptions are supported\n");
+}
+
+
+unittest
+{
+    printf("Testing exceptions\n");
+    Fiber a, b, c;
+    
+    int t0 = 0;
+    int t1 = 0;
+    int t2 = 0;
+    
+    printf("t0 = %d\nt1 = %d\nt2 = %d\n", t0, t1, t2);
+    
+    a = new Fiber(
+    delegate void()
+    {
+        t0++;
+        throw new Exception("A exception\n");
+        t0++;
+    });
+    
+    b = new Fiber(
+    delegate void()
+    {
+        t1++;
+        c.call();
+        t1++;
+    });
+    
+    c = new Fiber(
+    delegate void()
+    {
+        t2++;
+        throw new Exception("C exception\n");
+        t2++;
+    });
+    
+    assert(a);
+    assert(b);
+    assert(c);
+    assert(t0 == 0);
+    assert(t1 == 0);
+    assert(t2 == 0);
+    
+    try
+    {
+        a.call();
+        assert(false);
+    }
+    catch(Exception e)
+    {
+        printf("%.*s\n", e.toString);
+    }
+    
+    assert(a);
+    assert(a.state == Fiber.State.TERM);
+    assert(b);
+    assert(c);
+    assert(t0 == 1);
+    assert(t1 == 0);
+    assert(t2 == 0);
+    
+    try
+    {
+        b.call();
+        assert(false);
+    }
+    catch(Exception e)
+    {
+        printf("%.*s\n", e.toString);
+    }
+    
+    printf("blah2\n");
+    
+    assert(a);
+    assert(b);
+    assert(b.state == Fiber.State.TERM);
+    assert(c);
+    assert(c.state == Fiber.State.TERM);
+    assert(t0 == 1);
+    assert(t1 == 1);
+    assert(t2 == 1);
+
+	delete a;
+	delete b;
+	delete c;
+    
+
+	Fiber t;
+	int q0 = 0;
+	int q1 = 0;
+
+	t = new Fiber(
+	delegate void()
+	{
+		try
+		{
+			q0++;
+			throw new Exception("T exception\n");
+			q0++;
+		}
+		catch(Exception ex)
+		{
+			q1++;
+			printf("!!!!!!!!GOT EXCEPTION!!!!!!!!\n");
+			printf("%.*s\n", ex.toString);
+		}
+	});
+
+
+	assert(t);
+	assert(q0 == 0);
+	assert(q1 == 0);
+	t.call();
+	assert(t);
+	assert(t.state == Fiber.State.TERM);
+	assert(q0 == 1);
+	assert(q1 == 1);
+
+	delete t;
+   
+    Fiber d, e;
+    int s0 = 0;
+    int s1 = 0;
+    
+    d = new Fiber(
+    delegate void()
+    {
+        try
+        {
+            s0++;
+            e.call();
+            Fiber.yield();
+            s0++;
+            e.call();
+            s0++;
+        }
+        catch(Exception ex)
+        {
+            printf("%.*s\n", ex.toString);
+        }
+    });
+    
+    e = new Fiber(
+    delegate void()
+    {
+        s1++;
+        Fiber.yield();
+        throw new Exception("E exception\n");
+        s1++;
+    });
+    
+    assert(d);
+    assert(e);
+    assert(s0 == 0);
+    assert(s1 == 0);
+    
+    d.call();
+    
+    assert(d);
+    assert(e);
+    assert(s0 == 1);
+    assert(s1 == 1);
+    
+    d.call();
+    
+    assert(d);
+    assert(e);
+    assert(s0 == 2);
+    assert(s1 == 1);
+    
+    assert(d.state == Fiber.State.TERM);
+    assert(e.state == Fiber.State.TERM);
+    
+    delete d;
+    delete e;
+    
+    printf("Exceptions passed\n");
+}
+
+unittest
+{
+    printf("Testing standard exceptions\n");
+    int t = 0;
+    
+    Fiber a = new Fiber(
+    delegate void()
+    {
+        throw new Exception("BLAHAHA");
+    });
+    
+    assert(a);
+    assert(t == 0);
+    
+    try
+    {
+        a.call();
+        assert(false);
+    }
+    catch(Exception e)
+    {
+        printf("%.*s\n", e.toString);
+    }
+    
+    assert(a);
+    assert(a.state == Fiber.State.TERM);
+    assert(t == 0);
+    
+    delete a;
+    
+    
+    printf("Standard exceptions passed\n");
+}
+
+unittest
+{
+    printf("Memory stress test\n");
+    
+    const uint STRESS_SIZE = 5000;
+    
+    Fiber ctx[];
+    ctx.length = STRESS_SIZE;
+    
+    int cnt0 = 0;
+    int cnt1 = 0;
+    
+    void threadFunc()
+    {
+        cnt0++;
+        Fiber.yield;
+        cnt1++;
+    }
+    
+    foreach(inout Fiber c; ctx)
+    {
+        c = new Fiber(&threadFunc, 1024);
+    }
+    
+    assert(cnt0 == 0);
+    assert(cnt1 == 0);
+    
+    foreach(inout Fiber c; ctx)
+    {
+        c.call;
+    }
+    
+    assert(cnt0 == STRESS_SIZE);
+    assert(cnt1 == 0);
+    
+    foreach(inout Fiber c; ctx)
+    {
+        c.call;
+    }
+    
+    assert(cnt0 == STRESS_SIZE);
+    assert(cnt1 == STRESS_SIZE);
+    
+    foreach(inout Fiber c; ctx)
+    {
+        delete c;
+    }
+    
+    assert(cnt0 == STRESS_SIZE);
+    assert(cnt1 == STRESS_SIZE);
+    
+    printf("Memory stress test passed\n");
+}
+
+unittest
+{
+    printf("Testing floating point\n");
+    
+    float f0 = 1.0;
+    float f1 = 0.0;
+    
+    double d0 = 2.0;
+    double d1 = 0.0;
+    
+    real r0 = 3.0;
+    real r1 = 0.0;
+    
+    assert(f0 == 1.0);
+    assert(f1 == 0.0);
+    assert(d0 == 2.0);
+    assert(d1 == 0.0);
+    assert(r0 == 3.0);
+    assert(r1 == 0.0);
+    
+    Fiber a, b, c;
+    
+    a = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            f0 ++;
+            d0 ++;
+            r0 ++;
+            
+            Fiber.yield();
+        }
+    });
+    
+    b = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            f1 = d0 + r0;
+            d1 = f0 + r0;
+            r1 = f0 + d0;
+            
+            Fiber.yield();
+        }
+    });
+    
+    c = new Fiber(
+    delegate void()
+    {
+        while(true)
+        {
+            f0 *= d1;
+            d0 *= r1;
+            r0 *= f1;
+            
+            Fiber.yield();
+        }
+    });
+    
+    a.call();
+    assert(f0 == 2.0);
+    assert(f1 == 0.0);
+    assert(d0 == 3.0);
+    assert(d1 == 0.0);
+    assert(r0 == 4.0);
+    assert(r1 == 0.0);
+    
+    b.call();
+    assert(f0 == 2.0);
+    assert(f1 == 7.0);
+    assert(d0 == 3.0);
+    assert(d1 == 6.0);
+    assert(r0 == 4.0);
+    assert(r1 == 5.0);
+    
+    c.call();
+    assert(f0 == 12.0);
+    assert(f1 == 7.0);
+    assert(d0 == 15.0);
+    assert(d1 == 6.0);
+    assert(r0 == 28.0);
+    assert(r1 == 5.0);
+    
+    a.call();
+    assert(f0 == 13.0);
+    assert(f1 == 7.0);
+    assert(d0 == 16.0);
+    assert(d1 == 6.0);
+    assert(r0 == 29.0);
+    assert(r1 == 5.0);
+    
+    printf("Floating point passed\n");
+}
+
+
+version(x86) unittest
+{
+    printf("Testing registers\n");
+    
+    struct registers
+    {
+        int eax, ebx, ecx, edx;
+        int esi, edi;
+        int ebp, esp;
+        
+        //TODO: Add fpu stuff
+    }
+    
+    static registers old;
+    static registers next;
+    static registers g_old;
+    static registers g_next;
+    
+    //I believe that D calling convention requires that
+    //EBX, ESI and EDI be saved.  In order to validate
+    //this, we write to those registers and call the
+    //stack thread.
+    static StackThread reg_test = new StackThread(
+    delegate void() 
+    {
+        asm
+        {
+            naked;
+            
+            pushad;
+            
+            mov EBX, 1;
+            mov ESI, 2;
+            mov EDI, 3;
+            
+            mov [old.ebx], EBX;
+            mov [old.esi], ESI;
+            mov [old.edi], EDI;
+            mov [old.ebp], EBP;
+            mov [old.esp], ESP;
+            
+            call StackThread.yield;
+            
+            mov [next.ebx], EBX;
+            mov [next.esi], ESI;
+            mov [next.edi], EDI;
+            mov [next.ebp], EBP;
+            mov [next.esp], ESP;
+            
+            popad;
+        }
+    });
+    
+    //Run the stack context
+    asm
+    {
+        naked;
+        
+        pushad;
+        
+        mov EBX, 10;
+        mov ESI, 11;
+        mov EDI, 12;
+        
+        mov [g_old.ebx], EBX;
+        mov [g_old.esi], ESI;
+        mov [g_old.edi], EDI;
+        mov [g_old.ebp], EBP;
+        mov [g_old.esp], ESP;
+        
+        mov EAX, [reg_test];
+        call StackThread.call;
+        
+        mov [g_next.ebx], EBX;
+        mov [g_next.esi], ESI;
+        mov [g_next.edi], EDI;
+        mov [g_next.ebp], EBP;
+        mov [g_next.esp], ESP;
+        
+        popad;
+    }
+    
+    
+    //Make sure the registers are byte for byte equal.
+    assert(old.ebx = 1);
+    assert(old.esi = 2);
+    assert(old.edi = 3);
+    assert(old == next);
+    
+    assert(g_old.ebx = 10);
+    assert(g_old.esi = 11);
+    assert(g_old.edi = 12);
+    assert(g_old == g_next);
+    
+    printf("Registers passed!\n");
+}
+
+
+unittest
+{
+    printf("Testing throwYield\n");
+    
+    int q0 = 0;
+    
+    Fiber st0 = new Fiber(
+    delegate void()
+    {
+        q0++;
+        Fiber.yieldAndThrow(new Exception("testing throw yield\n"));
+        q0++;
+    });
+    
+    try
+    {
+        st0.call();
+        assert(false);
+    }
+    catch(Exception e)
+    {
+        printf("%.*s\n", e.toString);
+    }
+    
+    assert(q0 == 1);
+    assert(st0.state == Fiber.State.HOLD);
+    
+    st0.call();
+    assert(q0 == 2);
+    assert(st0.state == Fiber.State.TERM);
+    
+    printf("throwYield passed!\n");
+}
+
+unittest
+{
+    printf("Testing thread safety\n");
+    
+    int x = 0, y = 0;
+    
+    Fiber sc0 = new Fiber(
+    {
+        while(true)
+        {
+            x++;
+            Fiber.yield;
+        }
+    });
+    
+    Fiber sc1 = new Fiber(
+    {
+        while(true)
+        {
+            y++;
+            Fiber.yield;
+        }
+    });
+    
+    Thread t0 = new Thread(
+    {
+        for(int i=0; i<10000; i++)
+            sc0.call();
+    });
+    
+    Thread t1 = new Thread(
+    {
+        for(int i=0; i<10000; i++)
+            sc1.call();
+    });
+    
+    assert(sc0);
+    assert(sc1);
+    assert(t0);
+    assert(t1);
+    
+    t0.start;
+    t1.start;
+    t0.join;
+    t1.join;
+    
+    assert(x == 10000);
+    assert(y == 10000);
+    
+    printf("Thread safety passed!\n");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/FileBucket.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,319 @@
+module FileBucket;
+
+private import  tango.io.FilePath,
+                tango.io.FileConduit;
+
+private import  tango.core.Exception;
+
+/******************************************************************************
+
+        FileBucket implements a simple mechanism to store and recover a 
+        large quantity of data for the duration of the hosting process.
+        It is intended to act as a local-cache for a remote data-source, 
+        or as a spillover area for large in-memory cache instances. 
+        
+        Note that any and all stored data is rendered invalid the moment
+        a FileBucket object is garbage-collected.
+
+        The implementation follows a fixed-capacity record scheme, where
+        content can be rewritten in-place until said capacity is reached.
+        At such time, the altered content is moved to a larger capacity
+        record at end-of-file, and a hole remains at the prior location.
+        These holes are not collected, since the lifespan of a FileBucket
+        is limited to that of the host process.
+
+        All index keys must be unique. Writing to the FileBucket with an
+        existing key will overwrite any previous content. What follows
+        is a contrived example:
+        
+        ---
+        char[] text = "this is a test";
+
+        auto bucket = new FileBucket (new FilePath("bucket.bin"), FileBucket.HalfK);
+
+        // insert some data, and retrieve it again
+        bucket.put ("a key", text);
+        char[] b = cast(char[]) bucket.get ("a key");
+
+        assert (b == text);
+        bucket.close;
+        ---
+
+******************************************************************************/
+
+class FileBucket
+{
+        /**********************************************************************
+
+                Define the capacity (block-size) of each record
+
+        **********************************************************************/
+
+        struct BlockSize
+        {
+                int capacity;
+        }
+
+        // basic capacity for each record
+        private FilePath                path;
+
+        // basic capacity for each record
+        private BlockSize               block;
+
+        // where content is stored
+        private FileConduit             file;
+
+        // pointers to file records
+        private Record[char[]]          map;
+
+        // current file size
+        private long                    fileSize;
+
+        // current file usage
+        private long                    waterLine;
+
+        // supported block sizes
+        public static const BlockSize   EighthK  = {128-1},
+                                        HalfK    = {512-1},
+                                        OneK     = {1024*1-1},
+                                        TwoK     = {1024*2-1},
+                                        FourK    = {1024*4-1},
+                                        EightK   = {1024*8-1},
+                                        SixteenK = {1024*16-1},
+                                        ThirtyTwoK = {1024*32-1},
+                                        SixtyFourK = {1024*64-1};
+
+
+        /**********************************************************************
+
+                Construct a FileBucket with the provided path and record-
+                size. Selecting a record size that roughly matches the 
+                serialized content will limit 'thrashing'.
+
+        **********************************************************************/
+
+        this (char[] path, BlockSize block)
+        {
+                this (new FilePath(path), block);
+        }
+
+        /**********************************************************************
+
+                Construct a FileBucket with the provided path, record-size,
+                and inital record count. The latter causes records to be 
+                pre-allocated, saving a certain amount of growth activity.
+                Selecting a record size that roughly matches the serialized 
+                content will limit 'thrashing'. 
+
+        **********************************************************************/
+
+        this (FilePath path, BlockSize block, uint initialRecords = 100)
+        {
+                this.path = path;
+                this.block = block;
+
+                // open a storage file
+                file = new FileConduit (path, FileConduit.ReadWriteCreate);
+
+                // set initial file size (can be zero)
+                fileSize = initialRecords * block.capacity;
+                file.seek (fileSize);
+                file.truncate ();
+        }
+
+        /**********************************************************************
+
+                Return the block-size in use for this FileBucket
+
+        **********************************************************************/
+
+        int getBufferSize ()
+        {
+                return block.capacity+1;
+        }
+
+        /**********************************************************************
+        
+                Return where the FileBucket is located
+
+        **********************************************************************/
+
+        FilePath getFilePath ()
+        {
+                return path;
+        }
+
+        /**********************************************************************
+
+                Return the currently populated size of this FileBucket
+
+        **********************************************************************/
+
+        synchronized long length ()
+        {
+                return waterLine;
+        }
+
+        /**********************************************************************
+
+                Return the serialized data for the provided key. Returns
+                null if the key was not found.
+
+        **********************************************************************/
+
+        synchronized void[] get (char[] key)
+        {
+                Record r = null;
+
+                if (key in map)
+                   {
+                   r = map [key];
+                   return r.read (this);
+                   }
+                return null;
+        }
+
+        /**********************************************************************
+
+                Remove the provided key from this FileBucket.
+
+        **********************************************************************/
+
+        synchronized void remove (char[] key)
+        {
+                map.remove(key);
+        }
+
+        /**********************************************************************
+
+                Write a serialized block of data, and associate it with
+                the provided key. All keys must be unique, and it is the
+                responsibility of the programmer to ensure this. Reusing 
+                an existing key will overwrite previous data. 
+
+                Note that data is allowed to grow within the occupied 
+                bucket until it becomes larger than the allocated space.
+                When this happens, the data is moved to a larger bucket
+                at the file tail.
+
+        **********************************************************************/
+
+        synchronized void put (char[] key, void[] data)
+        {
+                Record* r = key in map;
+
+                if (r is null)
+                   {
+                   auto rr = new Record;
+                   map [key] =  rr;
+                   r = &rr;
+                   }
+                r.write (this, data, block);
+        }
+
+        /**********************************************************************
+
+                Close this FileBucket -- all content is lost.
+
+        **********************************************************************/
+
+        synchronized void close ()
+        {
+                if (file)
+                   {
+                   file.detach;
+                   file = null;
+                   map = null;
+                   }
+        }
+
+        /**********************************************************************
+
+                Each Record takes up a number of 'pages' within the file. 
+                The size of these pages is determined by the BlockSize 
+                provided during FileBucket construction. Additional space
+                at the end of each block is potentially wasted, but enables 
+                content to grow in size without creating a myriad of holes.
+
+        **********************************************************************/
+
+        private static class Record
+        {
+                private long            offset;
+                private int             length,
+                                        capacity = -1;
+
+                /**************************************************************
+
+                **************************************************************/
+
+                private static void eof (FileBucket bucket)
+                {
+                        throw new IOException ("Unexpected EOF in FileBucket '"~bucket.path.toString()~"'");
+                }
+
+                /**************************************************************
+
+                        This should be protected from thread-contention at
+                        a higher level.
+
+                **************************************************************/
+
+                void[] read (FileBucket bucket)
+                {
+                        void[] data = new ubyte [length];
+
+                        bucket.file.seek (offset);
+                        if (bucket.file.read (data) != length)
+                            eof (bucket);
+
+                        return data;
+                }
+
+                /**************************************************************
+
+                        This should be protected from thread-contention at
+                        a higher level.
+
+                **************************************************************/
+
+                void write (FileBucket bucket, void[] data, BlockSize block)
+                {
+                        length = data.length;
+
+                        // create new slot if we exceed capacity
+                        if (length > capacity)
+                            createBucket (bucket, length, block);
+
+                        // locate to start of content 
+                        bucket.file.seek (offset);
+        
+                        // write content
+                        if (bucket.file.write (data) != length)
+                            eof (bucket);
+                }
+
+                /**************************************************************
+
+                **************************************************************/
+
+                void createBucket (FileBucket bucket, int bytes, BlockSize block)
+                {
+                        offset = bucket.waterLine;
+                        capacity = (bytes + block.capacity) & ~block.capacity;
+
+                        bucket.waterLine += capacity;
+                        if (bucket.waterLine > bucket.fileSize)
+                           {
+                           // grow the filesize 
+                           bucket.fileSize = bucket.waterLine * 2;
+
+                           // expand the physical file size
+                           bucket.file.seek (bucket.fileSize);
+                           bucket.file.truncate ();
+                           }
+                }
+        }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/composite.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,85 @@
+
+private import  tango.io.protocol.Reader,
+                tango.io.protocol.Writer,
+                tango.io.FileConduit;
+
+/*******************************************************************************
+
+        Use cascading reads & writes to handle a composite class. There is
+        just one primary call for output, and just one for input, but the
+        classes propogate the request as appropriate. 
+
+        Note that the class instances don't know how their content will be
+        represented; that is dictated by the caller (via the reader/writer
+        implementation).
+
+        Note also that this only serializes the content. To serialize the
+        classes too, take a look at the Pickle.d example.
+
+*******************************************************************************/
+
+void main()
+{
+        // define a serializable class (via interfaces)
+        class Wumpus : IReadable, IWritable
+        {
+                private int     a = 11,
+                                b = 112,
+                                c = 1024;
+
+                void read (IReader input)
+                {
+                        input (a) (b) (c);
+                }
+
+                void write (IWriter output)
+                {
+                        output (a) (b) (c);
+                }
+        }
+
+
+        // define a serializable class (via interfaces)
+        class Wombat : IReadable, IWritable
+        {
+                private Wumpus  wumpus;
+                private char[]  x = "xyz";
+                private bool    y = true;
+                private float   z = 3.14159;
+
+                this (Wumpus wumpus)
+                {
+                        this.wumpus = wumpus;
+                }
+
+                void read (IReader input)
+                {
+                        input (x) (y) (z) (wumpus);
+                }
+
+                void write (IWriter output)
+                {
+                        output (x) (y) (z) (wumpus);
+                }
+        }
+
+        // construct a Wombat
+        auto wombat = new Wombat (new Wumpus);
+
+        // open a file for IO
+        auto file = new FileConduit ("random.bin", FileConduit.ReadWriteCreate);
+
+        // construct reader & writer upon the file, with binary IO
+        auto output = new Writer (file);
+        auto input = new Reader (file);
+
+        // write both Wombat & Wumpus (and flush them)
+        output (wombat) ();
+
+        // rewind to file start
+        file.seek (0);
+
+        // read both back again
+        input (wombat);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filebubbler.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,30 @@
+
+private import  tango.io.Console,
+                tango.io.FileScan,
+                tango.io.FileConst;
+
+/*******************************************************************************
+
+        This example sweeps a named sub-directory tree for html files,
+        and moves them to the current directory. The existing directory 
+        hierarchy is flattened into a naming scheme where a '.' is used
+        to replace the traditional path-separator
+
+        Used by the Tango project to help manage renderings of the source 
+        code.
+
+*******************************************************************************/
+
+void main(char[][] args)
+{
+        // sweep all html files in the specified subdir
+        if (args.length is 2)
+            foreach (proxy; (new FileScan).sweep(args[1], ".html").files)
+                    {
+                    auto other = new FilePath (proxy.toString);
+                    proxy.rename (other.replace (FileConst.PathSeparatorChar, '.'));
+                    }
+        else
+           Cout ("usage is filebubbler subdir").newline;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filecat.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,26 @@
+private import  tango.io.Console,
+                tango.io.FileConduit;
+
+/*******************************************************************************
+
+        Concatenate a number of files onto a single destination
+
+*******************************************************************************/
+
+void main(char[][] args)
+{
+        if (args.length > 2)
+           {
+           // open the file for writing
+           auto dst = new FileConduit (args[1], FileConduit.WriteCreate);
+
+           // copy each file onto dst
+           foreach (char[] arg; args[2..args.length])
+                    dst.copy (new FileConduit(arg));
+
+           // flush output and close
+           dst.close;
+           }
+        else
+           Cout ("usage: filecat target source1 ... sourceN");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filecopy.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,23 @@
+
+private import  tango.io.Console,
+                tango.io.FileConduit;
+
+/*******************************************************************************
+
+        open a file, and stream directly to console
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        if (args.length is 2)
+           {
+           // open a file for reading
+           auto fc = new FileConduit (args[1]);
+
+           // stream directly to console
+           Cout.stream.copy (fc);
+           }
+        else
+           Cout ("usage is: filecopy filename").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/fileops.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,26 @@
+/*****************************************************
+
+  Example that shows some simple file operations
+
+  Put into public domain by Lars Ivar Igesund
+
+*****************************************************/
+
+import tango.io.Stdout;
+
+import tango.io.FilePath;
+
+void main (char[][] args)
+{
+    auto src = args[0] ~ ".d";
+    auto dst = new FilePath (args[0] ~ ".d.copy");
+
+    Stdout.formatln ("copy file {} to {}", src, dst);
+    dst.copy (src);
+    assert (dst.exists);
+
+    Stdout.formatln ("removing file {}",  dst);
+    dst.remove;
+
+    assert (dst.exists is false);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filepathname.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,11 @@
+import tango.io.Console;
+
+import tango.io.FilePath;
+
+void main(){
+    Cout ((new FilePath(r"d:\path\foo.bat")).name).newline;
+    Cout ((new FilePath(r"d:\path.two\bar")).name).newline;
+    Cout ((new FilePath("/home/user.name/bar.")).name).newline;
+    Cout ((new FilePath(r"d:\path.two\bar")).name).newline;
+    Cout ((new FilePath("/home/user/.resource")).name).newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filescan.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,32 @@
+private import  tango.io.Stdout,
+                tango.io.FileScan;
+
+/*******************************************************************************
+
+        List ".d" files and enclosing folders visible via a directory given
+        as a command-line argument. In this example we're also postponing a
+        flush on Stdout until output is complete. Stdout is usually flushed
+        on each invocation of newline or formatln, but here we're using '\n'
+        to illustrate how to avoid flushing many individual lines
+        
+*******************************************************************************/
+
+void main(char[][] args)
+{       
+        char[] root = args.length < 2 ? "." : args[1];
+        Stdout.formatln ("Scanning '{}'", root);
+
+        auto scan = (new FileScan)(root, ".d");
+
+        Stdout.format ("\n{} Folders\n", scan.folders.length);
+        foreach (folder; scan.folders)
+                 Stdout.format ("{}\n", folder);
+
+        Stdout.format ("\n{0} Files\n", scan.files.length);
+        foreach (file; scan.files)
+                 Stdout.format ("{}\n", file);
+
+        Stdout.formatln ("\n{} Errors", scan.errors.length);
+        foreach (error; scan.errors)
+                 Stdout (error).newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/filescanregex.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,40 @@
+/**************************************************************
+
+    Example that use FileScan and Regex as a filter.
+
+    Put into public domain by Lars Ivar Igesund
+
+**************************************************************/
+
+import tango.io.File,
+       tango.io.Stdout,
+       tango.io.FileScan,
+       tango.text.Regex;
+
+void main(char[][] args) {
+    uint total;
+
+    if (args.length < 2) {
+        Stdout("Please pass a directory to search").newline;
+        return;
+    }
+
+    scope scan = new FileScan;
+    scope regex =  Regex(r"\.(d|obj)$");
+
+    scan(args[1], delegate bool (FilePath fp, bool isDir) {
+         ++total;
+         return isDir || regex.test(fp.toString);
+    });
+
+
+    foreach (file; scan.files)
+             Stdout(file).newline;
+
+    Stdout.formatln("Found {} matches in {} entries", scan.files.length, total);
+
+    Stdout.formatln ("\n{} Errors", scan.errors.length);
+    foreach (error; scan.errors)
+             Stdout (error).newline;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/lineio.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,29 @@
+
+private import  tango.io.Console,
+                tango.io.FileConduit;
+
+private import  tango.text.stream.LineIterator;
+
+/*******************************************************************************
+
+        Read a file line-by-line, sending each one to the console. This
+        illustrates how to bind a conduit to a stream iterator (iterators
+        also support the binding of a buffer). Note that stream iterators
+        are templated for char, wchar and dchar types.
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        if (args.length is 2)
+           {
+           // open a file for reading
+           scope file = new FileConduit (args[1]);
+
+           // process file one line at a time
+           foreach (line; new LineIterator!(char)(file))
+                    Cout (line).newline;
+           }
+        else
+           Cout ("usage: lineio filename").newline;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/mmap.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,24 @@
+
+private import  tango.io.Console,
+                tango.io.FileConduit,
+                tango.io.MappedBuffer;
+
+/*******************************************************************************
+
+        open a file, map it into memory, and copy to console
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        if (args.length is 2)
+           {
+           // open a file for reading
+           auto mmap = new MappedBuffer (new FileConduit (args[1]));
+
+           // copy content to console
+           Cout (cast(char[]) mmap.slice) ();
+           }
+        else
+           Cout ("usage is: mmap filename").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/paths.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,13 @@
+/*****************************************************
+
+        How to create a path with all ancestors
+
+*****************************************************/
+
+import tango.io.FilePath;
+
+void main (char[][] args)
+{
+        auto path = new FilePath (r"d/tango/foo/bar/wumpus");
+        assert (path.create.exists && path.isFolder);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/randomio.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,38 @@
+
+private import  tango.io.FileConduit;
+
+private import  tango.io.protocol.Reader,
+                tango.io.protocol.Writer;
+
+/*******************************************************************************
+
+       Create a file for random access. Write some stuff to it, rewind to
+       file start and read back.
+
+*******************************************************************************/
+
+void main()
+{
+        // open a file for reading
+        auto fc = new FileConduit ("random.bin", FileConduit.ReadWriteCreate);
+
+        // construct (binary) reader & writer upon this conduit
+        auto read  = new Reader (fc);
+        auto write = new Writer (fc);
+
+        int x=10, y=20;
+
+        // write some data and flush output since IO is buffered
+        write (x) (y) ();
+
+        // rewind to file start
+        fc.seek (0);
+
+        // read data back again, but swap destinations
+        read (y) (x);
+
+        assert (y is 10);
+        assert (x is 20);
+
+        fc.close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/conduits/unifile.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,25 @@
+
+private import  tango.io.Console,
+                tango.io.UnicodeFile;
+
+/*******************************************************************************
+
+        Open a unicode file of an unknown encoding, and converts to UTF-8 
+        for console display. UnicodeFile is templated for char/wchar/dchar
+        target encodings
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        if (args.length is 2)
+           {
+           // open a file for reading
+           auto file = new UnicodeFile!(char) (args[1], Encoding.Unknown);
+
+           // display on console
+           Cout (file.read).newline;
+           }
+        else
+           Cout ("usage is: unifile filename").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/console/buffered.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,17 @@
+private import tango.stdc.stdio;
+
+private import tango.io.Console;
+
+/*******************************************************************************
+
+        Demonstrates buffered output. Console output (and Stdout etc) is
+        buffered, requiring a flush or newline to render on the console.
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+        Cout ("how now ");
+        printf ("printf\n");
+        Cout ("brown cow").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/console/hello.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,21 @@
+/*******************************************************************************
+
+        Hello World using tango.io
+
+        This illustrates bare console output, with no fancy formatting. 
+
+        Console I/O in Tango is UTF-8 across both linux and Win32. The
+        conversion between various unicode representations is handled
+        by higher level constructs, such as Stdout and Stderr
+
+        Note that Cerr is tied to the console error output, and Cin is
+        tied to the console input. 
+
+*******************************************************************************/
+
+import tango.io.Console;
+
+void main()
+{
+        Cout ("hello, sweetheart \u263a").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/console/stdout.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,14 @@
+/*******************************************************************************
+
+        Illustrates the basic console formatting. This is different than
+        the use of tango.io.Console, in that Stdout supports a variety of
+        printf-style formatting, and has unicode-conversion support
+
+*******************************************************************************/
+
+private import tango.io.Stdout;
+
+void main()
+{
+        Stdout ("hello, sweetheart \u263a").newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/dsss.conf	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,35 @@
+[concurrency/fiber_test.d]
+[conduits/composite.d]
+[conduits/filebubbler.d]
+[conduits/filecat.d]
+[conduits/filecopy.d]
+[conduits/fileops.d]
+[conduits/filepathname.d]
+[conduits/filescan.d]
+[conduits/filescanregex.d]
+[conduits/lineio.d]
+[conduits/mmap.d]
+[conduits/paths.d]
+[conduits/randomio.d]
+[conduits/unifile.d]
+[console/hello.d]
+[console/stdout.d]
+[logging/chainsaw.d]
+[logging/logging.d]
+[logging/multilog.d]
+[manual/chapterStorage.d]
+[networking/homepage.d]
+[networking/httpget.d]
+[networking/selector.d]
+[networking/sockethello.d]
+[networking/socketserver.d]
+[system/arguments.d]
+[system/localtime.d]
+[system/normpath.d]
+[system/process.d]
+[text/formatalign.d]
+[text/formatindex.d]
+[text/formatspec.d]
+[text/localetime.d]
+[text/properties.d]
+[text/token.d]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/external/GlueFlectioned.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,42 @@
+import tango.core.Exception;
+import cn.kuehne.flectioned;
+
+
+TracedExceptionInfo traceHandler( void* ptr = null )
+{
+    class FlectionedTrace :
+        TracedExceptionInfo
+    {
+        this( void* ptr = null )
+        {
+            if( ptr )
+                m_trace = Trace.getTrace( cast(size_t) ptr );
+            else
+                m_trace = Trace.getTrace();
+        }
+
+        int opApply( int delegate( inout char[] ) dg )
+        {
+            int ret = 0;
+            foreach( t; m_trace )
+            {
+                char[] buf = t.toString;
+                ret = dg( buf );
+                if( ret != 0 )
+                    break;
+            }
+            return ret;
+        }
+
+    private:
+        Trace[] m_trace;
+    }
+
+    return new FlectionedTrace( ptr );
+}
+
+
+static this()
+{
+    setTraceHandler( &traceHandler );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/jake-all.bat	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,76 @@
+@rem ###########################################################################
+@rem # CONCURRENCY EXAMPLES
+@rem ###########################################################################
+
+@jake concurrency\fiber_test.d -I.. -op -unittest
+
+@rem ###########################################################################
+@rem # CONDUIT EXAMPLES
+@rem ###########################################################################
+
+@jake conduits\composite.d -I.. -op
+@jake conduits\filebubbler.d -I.. -op
+@jake -c conduits\filebucket.d -I.. -op
+@jake conduits\filecat.d -I.. -op
+@jake conduits\filecopy.d -I.. -op
+@jake conduits\filepathname.d -I.. -op
+@jake conduits\filescan.d -I.. -op
+@jake conduits\filescanregex.d -I.. -op
+@jake conduits\lineio.d -I.. -op
+@jake conduits\mmap.d -I.. -op
+@jake conduits\randomio.d -I.. -op
+@jake conduits\unifile.d -I.. -op
+
+@rem ###########################################################################
+@rem # CONSOLE EXAMPLES
+@rem ###########################################################################
+
+@jake console\hello.d -I.. -op
+@jake console\stdout.d -I.. -op
+
+@rem ###########################################################################
+@rem # LOGGING EXAMPLES
+@rem ###########################################################################
+
+@jake logging\chainsaw.d -I.. -op
+@jake logging\logging.d -I.. -op
+
+@rem ###########################################################################
+@rem # REFERENCE MANUAL EXAMPLES
+@rem ###########################################################################
+
+@jake manual\chapterStorage.d -I.. -op 
+
+@rem ###########################################################################
+@rem # NETWORKING EXAMPLES
+@rem ###########################################################################
+
+@jake networking\homepage.d -I.. -op
+@jake networking\httpget.d -I.. -op
+@jake networking\sockethello.d -I.. -op
+@jake networking\socketserver.d -I.. -op
+@jake networking\selector.d -I.. -op
+
+@rem ###########################################################################
+@rem # SYSTEM EXAMPLES
+@rem ###########################################################################
+
+@jake system\argparser.d -I.. -op
+@jake system\localtime.d -I.. -op
+@jake system\normpath.d -I.. -op
+@jake system\process.d -I.. -op
+
+@rem ###########################################################################
+@rem # TEXT EXAMPLES
+@rem ###########################################################################
+
+@jake text\formatalign.d -I.. -op
+@jake text\formatindex.d -I.. -op
+@jake text\formatspec.d -I.. -op
+@jake text\localetime.d -I.. -op
+@jake text\token.d -I.. -op
+
+@rem FINI
+
+@del *.map
+@dir *.exe
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/linux.mak	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,89 @@
+# Makefile to build the examples of tango for Linux
+# Designed to work with GNU make
+# Targets:
+#	make
+#		Same as make all
+#	make all
+#		Build all examples
+#
+#	make <executable-name>
+#		Build a specified example
+#   	make clean
+#   		remove all build examples
+#   
+# 
+
+# Relative path to the tango include dir
+# This is where the tango tree is located
+TANGO_DIR = ..
+
+# The build tool executable from dsource.org/projects/build
+BUILDTOOL = bud
+BUILDOPTS = -noautoimport -op -clean -full -g -debug -I$(TANGO_DIR)
+
+.PHONY: all clean
+
+# Standard target
+all : 
+
+# 	networking/httpserver	\
+# 	networking/servlets	\
+#	networking/servletserver\
+
+SIMPLE_EXAMPLES =\
+	concurrency/fiber_test	\
+	conduits/FileBucket	\
+	conduits/composite	\
+	conduits/filebubbler	\
+	conduits/filecat	\
+	conduits/filecopy	\
+	conduits/fileops	\
+	conduits/filepathname	\
+	conduits/filescan	\
+	conduits/filescanregex	\
+	conduits/lineio		\
+	conduits/mmap		\
+	conduits/randomio	\
+	conduits/unifile	\
+	console/hello		\
+	console/stdout		\
+	logging/chainsaw	\
+	logging/logging		\
+	networking/homepage	\
+	networking/httpget	\
+	networking/sockethello	\
+	networking/socketserver	\
+	system/argparser	\
+	system/localtime	\
+	system/normpath		\
+	system/process		\
+	networking/selector	\
+	text/formatalign	\
+	text/formatindex	\
+	text/formatspec		\
+	text/localetime		\
+	text/properties		\
+	text/token
+
+REFERENCE_EXAMPLES =		\
+	./reference/chapter4	\
+	./reference/chapter11
+
+$(SIMPLE_EXAMPLES) : % : %.d
+	@echo "Building : " $@
+	$(BUILDTOOL) $< $(BUILDOPTS) -T$@ -unittest
+
+$(REFERENCE_EXAMPLES) : % : %.d
+	@echo "Building : " $@
+	$(BUILDTOOL) $< $(BUILDOPTS) -T$@
+
+all : $(SIMPLE_EXAMPLES)
+
+clean :
+	@echo "Removing all examples"
+	rm -f $(SIMPLE_EXAMPLES) $(REFERENCE_EXAMPLES)
+	rm -f conduits/random.bin
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/logging/chainsaw.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,30 @@
+import  tango.core.Thread;
+
+import  tango.util.log.Log,
+        tango.util.log.Log4Layout,
+        tango.util.log.SocketAppender;
+
+import  tango.net.InternetAddress;
+
+
+/*******************************************************************************
+
+        Hooks up to Chainsaw for remote log capture. Chainsaw should be 
+        configured to listen with an XMLSocketReciever
+
+*******************************************************************************/
+
+void main()
+{
+        // get a logger to represent this module
+        auto logger = Log.getLogger ("example.chainsaw");
+
+        // hook up an appender for XML output
+        logger.addAppender (new SocketAppender (new InternetAddress("127.0.0.1", 4448), new Log4Layout));
+
+        while (true)
+              {
+              logger.info ("Hello Chainsaw!");      
+              Thread.sleep (1.0);
+              }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/logging/context.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,322 @@
+/*******************************************************************************
+
+        copyright:      Copyright (c) 2007 Stonecobra. All rights reserved
+
+        license:        BSD style: $(LICENSE)
+      
+        version:        Initial release: December 2007
+        
+        author:         stonecobra
+
+*******************************************************************************/
+
+module context;
+
+import tango.core.Thread,
+       tango.util.log.Log,
+       tango.util.log.Event,
+       tango.util.log.EventLayout,
+       tango.util.log.ConsoleAppender;
+
+import tango.util.log.model.IHierarchy;
+
+/*******************************************************************************
+
+        Allows the dynamic setting of log levels on a per-thread basis.  
+        Imagine that a user request comes into your production threaded 
+        server.  You can't afford to turn logging up to trace for the sake 
+        of debugging this one users problem, but you also can't afford to 
+        find the problem and fix it.  So now you just set the override log 
+        level to TRACE for the thread the user is on, and you get full trace 
+        output for only that user.
+
+*******************************************************************************/
+
+class ThreadLocalDiagnosticContext : IHierarchy.Context
+{
+        private ThreadLocal!(DCData) dcData;
+        private char[128] tmp;
+		
+    	/***********************************************************************
+    
+    	***********************************************************************/
+
+        public this() 
+        {
+                dcData = new ThreadLocal!(DCData);
+        }
+		
+    	/***********************************************************************
+    
+    	        set the 'diagnostic' Level for logging.  This overrides 
+                the Level in the current Logger.  The default level starts 
+                at NONE, so as not to modify the behavior of existing clients 
+                of tango.util.log
+
+    	***********************************************************************/
+
+        void setLevel (ILevel.Level level) 
+        {
+                auto data = dcData.val;
+                data.level = level;
+                dcData.val = data;
+        }
+		
+        /***********************************************************************
+                
+                All log appends will be checked against this to see if a 
+                log level needs to be temporarily adjusted.
+
+        ***********************************************************************/
+
+        bool isEnabled (ILevel.Level setting, ILevel.Level level = ILevel.Level.Trace) 
+        {
+        	return level >= setting || level >= dcData.val.level;
+        }
+
+        /***********************************************************************
+        
+                Return the label to use for the current log message.  Usually 
+                called by the Layout. This implementation returns "{}".
+
+        ***********************************************************************/
+
+        char[] label () 
+        {
+        	return dcData.val.getLabel;
+        }
+        
+        /***********************************************************************
+        
+                Push another string into the 'stack'.  This strings will be 
+                appened together when getLabel is called.
+
+        ***********************************************************************/
+
+        void push (char[] label) 
+        {
+                auto data = dcData.val;
+                data.push(label);
+        	dcData.val = data;
+        }
+        
+        /***********************************************************************
+        
+                pop the current label off the stack.
+
+        ***********************************************************************/
+
+        void pop ()
+        {
+                auto data = dcData.val;
+                data.pop;
+        	dcData.val = data;
+        }
+        
+        /***********************************************************************
+        
+                Clear the label stack.
+
+        ***********************************************************************/
+
+        void clear()
+        {
+                auto data = dcData.val;
+                data.clear;
+        	dcData.val = data;
+        }
+}
+
+
+/*******************************************************************************
+        
+        The thread locally stored struct to hold the logging level and 
+        the label stack.
+
+*******************************************************************************/
+
+private struct DCData {
+	
+        ILevel.Level    level = ILevel.Level.None;
+        char[][8] 	stack;
+        bool 		shouldUpdate = true;
+        int         	stackIndex = 0;
+        uint   	        labelLength;
+        char[256]       labelContent;
+	
+	
+	char[] getLabel() {
+		if (shouldUpdate) {
+			labelLength = 0;
+			append(" {");
+			for (int i = 0; i < stackIndex; i++) {
+				append(stack[i]);
+				if (i < stackIndex - 1) {
+					append(" ");
+				}
+			}
+			append("}");
+			shouldUpdate = false;
+		}
+		return labelContent[0..labelLength];
+	}
+	
+	void append(char[] x) {
+        uint addition = x.length;
+        uint newLength = labelLength + x.length;
+
+        if (newLength < labelContent.length)
+           {
+           labelContent [labelLength..newLength] = x[0..addition];
+           labelLength = newLength;
+           }
+	}
+	
+	void push(char[] label) {
+		shouldUpdate = true;
+		stack[stackIndex] = label.dup;
+		stackIndex++;
+	}
+	
+	void pop() {
+		shouldUpdate = true;
+		if (stackIndex > 0) {
+			stack[stackIndex] = null;
+			stackIndex--;
+		}
+	}
+		
+	void clear() {
+		shouldUpdate = true;
+		for (int i = 0; i < stack.length; i++) {
+			stack[i] = null;
+		}
+	}
+}
+
+
+/*******************************************************************************
+
+        Simple console appender that counts the number of log lines it 
+        has written.
+
+*******************************************************************************/
+
+class TestingConsoleAppender : ConsoleAppender {
+
+    int events = 0;
+	
+    this (EventLayout layout = null)
+    {
+    	super(layout);
+    }
+
+    override void append (Event event)
+    {
+    	events++;
+    	super.append(event);
+    }
+}
+
+
+/*******************************************************************************
+
+        Testing harness for the DiagnosticContext functionality.
+
+*******************************************************************************/
+
+void main(char[][] args) 
+{	
+    //set up our appender that counts the log output.  This is the configuration 
+    //equivalent of importing tango.util.log.Configurator.
+    auto appender = new TestingConsoleAppender(new SimpleTimerLayout);
+    Log.getRootLogger.addAppender(appender);
+
+    char[128] tmp = 0;
+    auto log = Log.getLogger("context");    
+    log.setLevel(log.Level.Info);
+    
+    //first test, use all defaults, validating it is working.  None of the trace()
+    //calls should count in the test.
+    for (int i=0;i < 10; i++) {
+    	log.info(log.format(tmp, "test1 {}", i));
+    	log.trace(log.format(tmp, "test1 {}", i));
+    }
+    if (appender.events !is 10) {
+    	log.error(log.format(tmp, "events:{}", appender.events));
+    	throw new Exception("Incorrect Number of events in normal mode");	
+    }
+    
+    appender.events = 0;
+    
+    //test the thread local implementation without any threads, as a baseline.
+    //should be same result as test1
+    auto context = new ThreadLocalDiagnosticContext;
+    Log.getHierarchy.context(context);
+    for (int i=0;i < 10; i++) {
+    	log.info(log.format(tmp, "test2 {}", i));
+    	log.trace(log.format(tmp, "test2 {}", i));
+    }
+    if (appender.events !is 10) {
+    	log.error(log.format(tmp, "events:{}", appender.events));
+    	throw new Exception("Incorrect Number of events in TLS single thread mode");	
+    }
+    
+    appender.events = 0;
+    
+    //test the thread local implementation without any threads, as a baseline.
+    //This should count all logging requests, because the DiagnosticContext has
+    //'overridden' the logging level on ALL loggers up to TRACE.
+    context.setLevel(log.Level.Trace);
+    for (int i=0;i < 10; i++) {
+    	log.info(log.format(tmp, "test3 {}", i));
+    	log.trace(log.format(tmp, "test3 {}", i));
+    }
+    if (appender.events !is 20) {
+    	log.error(log.format(tmp, "events:{}", appender.events));
+    	throw new Exception("Incorrect Number of events in TLS single thread mode with level set");	
+    }
+    
+    appender.events = 0;
+    
+    //test the thread local implementation without any threads, as a baseline.
+    context.setLevel(log.Level.None);
+    for (int i=0;i < 10; i++) {
+    	log.info(log.format(tmp, "test4 {}", i));
+    	log.trace(log.format(tmp, "test4 {}", i));
+    }
+    if (appender.events !is 10) {
+    	log.error(log.format(tmp, "events:{}", appender.events));
+    	throw new Exception("Incorrect Number of events in TLS single thread mode after level reset");	
+    }
+    
+    //Now test threading.  set up a trace context in one thread, with a label, while
+    //keeping the second thread at the normal configuration.
+    appender.events = 0;
+    ThreadGroup tg = new ThreadGroup();
+    tg.create({
+        char[128] tmp = 0;
+        context.setLevel(log.Level.Trace);        
+        context.push("specialthread");
+        context.push("2ndlevel");
+        for (int i=0;i < 10; i++) {
+             log.info(log.format(tmp, "test5 {}", i));
+             log.trace(log.format(tmp, "test5 {}", i));
+        }
+    });
+    tg.create({
+        char[128] tmp = 0;      
+        context.setLevel(log.Level.None);
+        for (int i=0;i < 10; i++) {
+             log.info(log.format(tmp, "test6 {}", i));
+             log.trace(log.format(tmp, "test6 {}", i));
+        }
+    });
+    tg.joinAll();
+    
+    if (appender.events !is 30) {
+    	log.error(log.format(tmp, "events:{}", appender.events));
+    	throw new Exception("Incorrect Number of events in TLS multi thread mode");	
+    }   
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/logging/logging.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,102 @@
+/*******************************************************************************
+
+        Shows how the basic functionality of Logger operates.
+
+*******************************************************************************/
+
+private import tango.util.log.Log,
+               tango.util.log.Configurator;
+
+/*******************************************************************************
+
+        Search for a set of prime numbers
+
+*******************************************************************************/
+
+void compute (Logger log, uint max)
+        {
+                byte*   feld;
+                int     teste=1,
+                        mom,
+                        hits=0,
+                        s=0,
+                        e = 1;
+                int     count;
+                char    tmp[128] = void;
+
+                void set (byte* f, uint x)
+                {
+                        *(f+(x)/16) |= 1 << (((x)%16)/2);
+                }
+
+                byte test (byte* f, uint x)
+                {
+                        return cast(byte) (*(f+(x)/16) & (1 << (((x)%16)/2)));
+                }
+
+                // information level
+                log.info (log.format (tmp, "Searching prime numbers up to {}", max));
+
+                feld = (new byte[max / 16 + 1]).ptr;
+
+                // get milliseconds since application began
+                auto begin = log.runtime;
+
+                while ((teste += 2) < max)
+                        if (! test (feld, teste)) 
+                           {
+                           if  ((++hits & 0x0f) == 0) 
+                                // more information level
+                                log.info (log.format (tmp, "found {}", hits)); 
+
+                           for (mom=3*teste; mom < max; mom += teste<<1) 
+                                set (feld, mom);
+                           }
+
+                // get number of milliseconds we took to compute
+                auto period = log.runtime - begin;
+
+                if (hits)
+                    // more information
+                    log.info (log.format (tmp, "{} prime numbers found in {} millsecs", hits, period));
+                else
+                   // a warning level
+                   log.warn ("no prime numbers found");
+        
+                // check to see if we're enabled for 
+                // tracing before we expend a lot of effort
+                if (log.isEnabled (log.Level.Trace))
+                   {        
+                   e = max;
+                   count = 0 - 2; 
+                   if (s % 2 is 0) 
+                       count++;
+           
+                   while ((count+=2) < e) 
+                           // log trace information
+                           if (! test (feld, count)) 
+                                 log.trace (log.format (tmp, "prime found: {}", count));
+                   }
+}
+
+
+/*******************************************************************************
+
+        Compute a bunch of prime numbers
+
+*******************************************************************************/
+
+void main()
+{
+        // get a logger to represent this module. We could just as
+        // easily share a name with some other module(s)
+        auto log = Log.getLogger ("example.logging");
+        try {
+            compute (log, 1000);
+
+            } catch (Exception x)
+                    {
+                    // log the exception as an error
+                    log.error ("Exception: " ~ x.toString);
+                    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/logging/multilog.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,31 @@
+import tango.util.log.Log;
+import tango.util.log.Log4Layout;
+import tango.util.log.FileAppender;
+import tango.util.log.ConsoleAppender;
+import tango.util.log.RollingFileAppender;
+
+/*******************************************************************************
+
+        Shows how to setup multiple appenders on logging tree
+
+*******************************************************************************/
+
+void main ()
+{
+        // set default logging level at the root
+        auto log = Log.getRootLogger;
+        log.setLevel (log.Level.Trace);
+
+        // 10 logs, all with 10 mbs each
+        log.addAppender (new RollingFileAppender("rolling.log", 9, 1024*1024*10));
+
+        // a single file appender, with an XML layout
+        log.addAppender (new FileAppender ("single.log", new Log4Layout));
+
+        // console appender
+        log.addAppender (new ConsoleAppender);
+
+        // log to all
+        log.trace ("three-way logging");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/manual/chapterStorage.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,237 @@
+module example.reference.chapter11;
+
+import tango.util.collection.HashMap;
+import tango.util.collection.ArrayBag;
+import tango.util.collection.LinkSeq;
+import tango.util.collection.CircularSeq;
+import tango.util.collection.ArraySeq;
+import tango.util.collection.TreeBag;
+import tango.util.collection.iterator.FilteringIterator;
+import tango.util.collection.iterator.InterleavingIterator;
+
+import tango.io.Stdout;
+import tango.core.Exception;
+
+import tango.util.collection.model.Comparator;
+import tango.util.collection.impl.BagCollection;
+import tango.util.collection.impl.SeqCollection;
+import Ascii = tango.text.Ascii;
+
+void linkedListExample(){
+    Stdout.format( "linkedListExample" ).newline;
+    alias LinkSeq!(char[]) StrList;
+    StrList lst = new StrList();
+
+    lst.append( "value1" );
+    lst.append( "value2" );
+    lst.append( "value3" );
+
+    auto it = lst.elements();
+    // The call to .more gives true, if there are more elements
+    // and switches the iterator to the next one if available.
+    while( it.more ){
+        char[] item_value = it.get;
+        Stdout.format( "Value:{0}", item_value ).newline;
+    }
+}
+
+void hashMapExample(){
+    Stdout.format( "hashMapExample" ).newline;
+    alias HashMap!(char[], char[]) StrStrMap;
+    StrStrMap map = new StrStrMap();
+    map.add( "key1", "value1" );
+    char[] key = "key1";
+    Stdout.format( "Key: {0}, Value:{1}", key, map.get( key )).newline;
+
+
+    auto it = map.keys();
+    // The call to .more gives true, if there are more elements
+    // and switches the iterator to the next one if available.
+    while( it.more ){
+        char[] item_key = void;
+        char[] item_value = it.get( item_key ); // only for maps, the key is returns via inout
+        Stdout.format( "Key: {0}, Value:{1}", item_key, item_value ).newline;
+    }
+}
+
+void testComparator(){
+    char[][] result;
+
+    // Create and fill the containers
+    auto nameSet = new TreeBag!(char[])( null, new class() Comparator!(char[]){
+        int compare( char[] first, char[] second ){
+            return Ascii.icompare( first, second );
+        }
+    });
+
+    nameSet.addIf( "Alice" );
+    nameSet.addIf( "Bob" );
+    nameSet.addIf( "aliCe" );
+
+    // use foreach to iterate over the container
+    foreach ( char[] i; nameSet )
+        result ~= i;
+ foreach( char[] i; result ) Stdout.format( "{0} ", i );
+ Stdout.newline;
+
+    // test the result
+    assert( result == [ "Alice", "Bob" ], "testIterator" );
+}
+
+void testSreener(){
+    int[] result;
+
+    // Create and fill the containers
+    auto ratioSamples = new ArraySeq!(float)( (float v){
+        return v >= 0.0f && v < 1.0f;
+    });
+
+    ratioSamples.append( 0.0f );
+    ratioSamples.append( 0.5f );
+    ratioSamples.append( 0.99999f );
+    // try to insert a value that is not allowed
+    try{
+        ratioSamples.append( 1.0f );
+        // will never get here
+        assert( false );
+    } catch( IllegalElementException e ){
+    }
+}
+
+
+void testForeach(){
+    int[] result;
+
+    // Create and fill the containers
+    auto l1 = new CircularSeq!(int);
+    for( int i = 0; i < 6; i+=2 ){
+        l1.append( i );
+    }
+
+    // use foreach to iterate over the container
+    foreach ( int i; l1 )
+        result ~= i;
+//     foreach_reverse ( int i; l1 )
+//         result ~= i;
+
+    // test the result
+    assert( result == [ 0, 2, 4 ], "testIterator" );
+}
+
+void testIterator(){
+    int[] result;
+
+    // Create and fill the containers
+    auto l1 = new LinkSeq!(int);
+    for( int i = 0; i < 6; i+=2 ){
+        l1.append( i );
+    }
+
+    // define the Iterator
+    auto it = l1.elements();
+
+    // use the Iterator to iterate over the container
+    while (it.more())
+        result ~= it.get();
+
+    // test the result
+    assert( result == [ 0, 2, 4 ], "testIterator" );
+}
+
+void testFilteringIterator(){
+    int[] result;
+    alias ArrayBag!(int) IntBag;
+
+    // Create and fill the container
+    auto ib = new IntBag;
+    for( int i = 0; i < 20; i++ ){
+        ib.add( i );
+    }
+
+    // define the FilteringIterator with a function literal
+    auto it = new FilteringIterator!(int)( ib.elements(), (int i){
+        return i >= 3 && i < 7;
+    });
+
+    // use the Iterator with the more()/get() pattern
+    while (it.more())
+        result ~= it.get();
+
+    // test the result
+    assert( result == [ 3, 4, 5, 6 ], "testFilteringIterator" );
+
+}
+
+void testFilteringIteratorRemove(){
+    int[] result;
+
+    // Create and fill the container
+    auto container = new LinkSeq!(int);
+    for( int i = 0; i < 10; i++ ){
+        container.append( i );
+    }
+
+    // 1. Build a list of elements to delete
+    auto dellist = new LinkSeq!(int);
+    foreach( int i; container ){
+        if( i < 3 || i >= 7 ){
+            // container.remove( i ); /* NOT POSSIBLE */
+            dellist.append( i );
+        }
+    }
+    // 2. Iterate over this deletion list and
+    // delete the items in the original container.
+    foreach( int i; dellist ){
+        container.remove( i );
+    }
+
+    foreach ( int i; container )
+        result ~= i;
+
+    // test the result
+    assert( result == [ 3, 4, 5, 6 ], "testFilteringIterator" );
+
+}
+
+void testInterleavingIterator(){
+    int[] result;
+
+    // Create and fill the containers
+    auto l1 = new LinkSeq!(int);
+    auto l2 = new ArraySeq!(int);
+    for( int i = 0; i < 6; i+=2 ){
+        l1.append( i );
+        l2.append( i+1 );
+    }
+
+    // define the InterleavingIterator
+    auto it = new InterleavingIterator!(int)( l1.elements(), l2.elements() );
+
+    // use the InterleavingIterator to iterate over the container
+    while (it.more())
+        result ~= it.get();
+
+    // test the result
+    assert( result == [ 0, 1, 2, 3, 4, 5 ], "testInterleavingIterator" );
+}
+
+// foreach( int i; result ) Stdout.format( "{0} ", i );
+// Stdout.newline;
+
+void main(){
+    Stdout.format( "reference - Chapter 11 Example" ).newline;
+    hashMapExample();
+    linkedListExample();
+
+    testSreener();
+    testComparator();
+    testForeach();
+    testIterator();
+    testFilteringIterator();
+    testInterleavingIterator();
+    testFilteringIteratorRemove();
+
+    Stdout.format( "=== End ===" ).newline;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/networking/homepage.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,30 @@
+
+private import  tango.io.Console;
+
+private import  tango.net.http.HttpClient,
+                tango.net.http.HttpHeaders;
+
+/*******************************************************************************
+
+        Shows how to use HttpClient to retrieve content from the D website
+        
+*******************************************************************************/
+
+void main()
+{
+        auto client = new HttpClient (HttpClient.Get, "http://www.digitalmars.com/d/intro.html");
+
+        // open the client and get the input stream
+        auto input = client.open;
+        scope (exit)
+               client.close;
+        
+        // display returned content on console
+        if (client.isResponseOK)
+            Cout.stream.copy (input);
+        else
+           Cout ("failed to return the D home page");  
+
+        // flush the console
+        Cout.newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/networking/httpget.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,27 @@
+private import  tango.io.Console;
+
+private import  tango.net.http.HttpGet;
+
+/*******************************************************************************
+
+        Read a page from a website, gathering the entire page before 
+        returning any content. This illustrates a high-level approach
+        to retrieving web-content, whereas the homepage example shows
+        a somewhat lower-level approach. 
+
+        Note that this expects a fully qualified URL (with scheme), 
+        such as "http://www.digitalmars.com/d/intro.html"
+
+*******************************************************************************/
+
+void main (char[][] args)
+{
+	char[] url = (args.length is 2) ? args[1] : "http://www.digitalmars.com/d/intro.html";
+            
+        // open a web-page for reading (see HttpPost for writing)
+        auto page = new HttpGet (url);
+
+        // retrieve and flush display content
+        Cout (cast(char[]) page.read) ();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/networking/selector.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,399 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+*******************************************************************************/
+
+private
+{
+    version (Posix)
+    {
+        import tango.io.selector.PollSelector;
+    }
+    else version (linux)
+    {
+        import tango.io.selector.EpollSelector;
+        import tango.sys.linux.linux;
+    }
+
+    import tango.io.selector.model.ISelector;
+    import tango.io.selector.Selector;
+    import tango.io.selector.SelectSelector;
+    import tango.io.selector.SelectorException;
+    import tango.io.Conduit;
+    import tango.net.Socket;
+    import tango.net.SocketConduit;
+    import tango.net.ServerSocket;
+    import tango.time.Clock;
+    import tango.util.log.Log;
+    import tango.util.log.ConsoleAppender;
+    import tango.util.log.DateLayout;
+    import tango.text.convert.Sprint;
+    import tango.core.Exception;
+    import tango.core.Thread;
+    import tango.sys.Common;
+    import tango.stdc.errno;
+}
+
+
+const uint      HANDLE_COUNT    = 4;
+const uint      EVENT_COUNT     = 4;
+const uint      LOOP_COUNT      = 50000;
+const char[]    SERVER_ADDR     = "127.0.0.1";
+const ushort    SERVER_PORT     = 4000;
+const uint      MAX_LENGTH      = 16;
+
+int main(char[][] args)
+{
+    Logger          log     = Log.getLogger("selector");
+    Sprint!(char)   sprint  = new Sprint!(char)(256);
+
+    log.addAppender(new ConsoleAppender(new DateLayout()));
+
+    ISelector selector;
+
+    for (int i = 0; i < 1; i++)
+    {
+        // Testing the SelectSelector
+        log.info(sprint("Pass {0}: Testing the select-based selector", i + 1));
+        selector = new SelectSelector();
+        testSelector(selector);
+    }
+
+    // Testing the PollSelector
+    version (Posix)
+    {
+        for (int i = 0; i < 1; i++)
+        {
+            log.info(sprint("Pass {0}: Testing the poll-based selector", i + 1));
+            selector = new PollSelector();
+            testSelector(selector);
+        }
+    }
+
+    // Testing the EpollSelector
+    version (linux)
+    {
+        for (int i = 0; i < 1; i++)
+        {
+            log.info(sprint("Pass {0}: Testing the epoll-based selector", i + 1));
+            selector = new EpollSelector();
+            testSelector(selector);
+        }
+    }
+
+    return 0;
+}
+
+
+/**
+ * Create a server socket and run the Selector on it.
+ */
+void testSelector(ISelector selector)
+{
+    Logger          log     = Log.getLogger("selector.server");
+    Sprint!(char)   sprint  = new Sprint!(char)(512);
+
+    uint        connectCount        = 0;
+    uint        receiveCount        = 0;
+    uint        sendCount           = 0;
+    uint        failedConnectCount  = 0;
+    uint        failedReceiveCount  = 0;
+    uint        failedSendCount     = 0;
+    uint        closeCount          = 0;
+    uint        errorCount          = 0;
+    Time        start               = Clock.now;
+    Thread      clientThread;
+
+    selector.open(HANDLE_COUNT, EVENT_COUNT);
+
+    clientThread = new Thread(&clientThreadFunc);
+    clientThread.start();
+
+    try
+    {
+        TimeSpan            timeout         = TimeSpan.seconds(1);
+        InternetAddress     addr            = new InternetAddress(SERVER_ADDR, SERVER_PORT);
+        ServerSocket        serverSocket    = new ServerSocket(addr, 5);
+        SocketConduit       clientSocket;
+        char[MAX_LENGTH]    buffer;
+        int                 eventCount;
+        uint                count;
+        int                 i = 0;
+
+        debug (selector)
+            log.trace("Registering server socket to Selector");
+
+        selector.register(serverSocket, Event.Read);
+
+        while (true)
+        {
+            debug (selector)
+                log.trace(sprint("[{0}] Waiting for events from Selector", i));
+
+            eventCount = selector.select(timeout);
+
+            debug (selector)
+                log.trace(sprint("[{0}] {1} events received from Selector", i, eventCount));
+
+            if (eventCount > 0)
+            {
+                foreach (SelectionKey selectionKey; selector.selectedSet())
+                {
+                    debug (selector)
+                        log.trace(sprint("[{0}] Event mask for socket {1} is 0x{2:x4}",
+                                        i, cast(int) selectionKey.conduit.fileHandle(),
+                                        cast(uint) selectionKey.events));
+
+                    if (selectionKey.isReadable())
+                    {
+                        if (selectionKey.conduit is serverSocket)
+                        {
+                            debug (selector)
+                                log.trace(sprint("[{0}] New connection from client", i));
+
+                            clientSocket = serverSocket.accept();
+                            if (clientSocket !is null)
+                            {
+                                selector.register(clientSocket, Event.Read);
+                                connectCount++;
+                            }
+                            else
+                            {
+                                debug (selector)
+                                    log.trace(sprint("[{0}] New connection attempt failed", i));
+                                failedConnectCount++;
+                            }
+                        }
+                        else
+                        {
+                            // Reading from a client socket
+                            debug (selector)
+                                log.trace(sprint("[{0}] Receiving message from client", i));
+
+                            count = (cast(SocketConduit) selectionKey.conduit).read(buffer);
+                            if (count != IConduit.Eof)
+                            {
+                                debug (selector)
+                                    log.trace(sprint("[{0}] Received {1} from client ({2} bytes)",
+                                                     i, buffer[0..count], count));
+                                selector.reregister(selectionKey.conduit, Event.Write);
+                                receiveCount++;
+                            }
+                            else
+                            {
+                                debug (selector)
+                                    log.trace(sprint("[{0}] Handle {1} was closed; removing it from Selector",
+                                                     i, cast(int) selectionKey.conduit.fileHandle()));
+                                selector.unregister(selectionKey.conduit);
+                                (cast(SocketConduit) selectionKey.conduit).close();
+                                failedReceiveCount++;
+                                continue;
+                            }
+                        }
+                    }
+
+                    if (selectionKey.isWritable())
+                    {
+                        debug (selector)
+                            log.trace(sprint("[{0}] Sending PONG to client", i));
+
+                        count = (cast(SocketConduit) selectionKey.conduit).write("PONG");
+                        if (count != IConduit.Eof)
+                        {
+                            debug (selector)
+                                log.trace(sprint("[{0}] Sent PONG to client ({1} bytes)", i, count));
+
+                            selector.reregister(selectionKey.conduit, Event.Read);
+                            sendCount++;
+                        }
+                        else
+                        {
+                            debug (selector)
+                                log.trace(sprint("[{0}] Handle {1} was closed; removing it from Selector",
+                                                 i, selectionKey.conduit.fileHandle()));
+                            selector.unregister(selectionKey.conduit);
+                            (cast(SocketConduit) selectionKey.conduit).close();
+                            failedSendCount++;
+                            continue;
+                        }
+                    }
+
+                    if (selectionKey.isError() || selectionKey.isHangup() || selectionKey.isInvalidHandle())
+                    {
+                        char[] status;
+
+                        if (selectionKey.isHangup())
+                        {
+                            closeCount++;
+                            status = "Hangup";
+                        }
+                        else
+                        {
+                            errorCount++;
+                            if (selectionKey.isInvalidHandle())
+                                status = "Invalid request";
+                            else
+                                status = "Error";
+                        }
+
+                        debug (selector)
+                        {
+                            log.trace(sprint("[{0}] {1} in handle {2} from Selector",
+                                             i, status, cast(int) selectionKey.conduit.fileHandle()));
+
+                            log.trace(sprint("[{0}] Unregistering handle {1} from Selector",
+                                             i, cast(int) selectionKey.conduit.fileHandle()));
+                        }
+                        selector.unregister(selectionKey.conduit);
+                        (cast(Conduit) selectionKey.conduit).close();
+
+                        if (selectionKey.conduit !is serverSocket)
+                        {
+                            continue;
+                        }
+                        else
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                debug (selector)
+                    log.trace(sprint("[{0}] No more pending events in Selector; aborting", i));
+                break;
+            }
+            i++;
+
+            // Thread.sleep(1.0);
+            /*
+            if (i % 100 == 0)
+            {
+                fullCollect();
+                getStats(gc)
+            }
+            */
+        }
+
+        serverSocket.socket().detach;
+    }
+    catch (SelectorException e)
+    {
+        log.error(sprint("Selector exception caught:\n{0}", e.toString()));
+    }
+    catch (Exception e)
+    {
+        log.error(sprint("Exception caught:\n{0}", e.toString()));
+    }
+
+    log.info(sprint("Success: connect={0}; recv={1}; send={2}; close={3}", 
+                    connectCount, receiveCount, sendCount, closeCount));
+    log.info(sprint("Failure: connect={0}, recv={1}; send={2}; error={3}", 
+                    failedConnectCount, failedReceiveCount, failedSendCount, errorCount));
+
+    log.info(sprint("Total time: {0} ms", cast(uint) (Clock.now - start).millis));
+
+    clientThread.join();
+
+    selector.close;
+}
+
+
+/**
+ * Thread that creates a client socket and sends messages to the server socket.
+ */
+void clientThreadFunc()
+{
+    Logger          log     = Log.getLogger("selector.client");
+    Sprint!(char)   sprint  = new Sprint!(char)(256);
+    SocketConduit   socket  = new SocketConduit();
+
+    Thread.sleep(0.010);      // 10 milliseconds
+
+    try
+    {
+        InternetAddress     addr = new InternetAddress(SERVER_ADDR, SERVER_PORT);
+        char[MAX_LENGTH]    buffer;
+        uint count;
+        int i;
+
+        debug (selector)
+            log.trace(sprint("[{0}] Connecting to server", i));
+
+        socket.connect(addr);
+
+        for (i = 1; i <= LOOP_COUNT; i++)
+        {
+            debug (selector)
+                log.trace(sprint("[{0}] Sending PING to server", i));
+
+            while (true)
+            {
+                try
+                {
+                    count = socket.write("PING");
+                    break;
+                }
+                catch (SocketException e)
+                {
+                    if (errno != EINTR)
+                        throw e;
+                }
+            }
+            if (count != IConduit.Eof)
+            {
+                debug (selector)
+                {
+                    log.trace(sprint("[{0}] Sent PING to server ({1} bytes)", i, count));
+
+                    log.trace(sprint("[{0}] Receiving message from server", i));
+                }
+                while (true)
+                {
+                    try
+                    {
+                        count = socket.read(buffer);
+                        break;
+                    }
+                    catch (SocketException e)
+                    {
+                        if (errno != EINTR)
+                            throw e;
+                    }
+                }
+                if (count != IConduit.Eof)
+                {
+                    debug (selector)
+                        log.trace(sprint("[{0}] Received {1} from server ({2} bytes)",
+                                         i, buffer[0..count], count));
+                }
+                else
+                {
+                    debug (selector)
+                        log.trace(sprint("[{0}] Handle was closed; aborting",
+                                         i, socket.fileHandle()));
+                    break;
+                }
+            }
+            else
+            {
+                debug (selector)
+                    log.trace(sprint("[{0}] Handle {1} was closed; aborting",
+                                     i, socket.fileHandle()));
+                break;
+            }
+        }
+        socket.shutdown();
+        socket.close();
+    }
+    catch (Exception e)
+    {
+        log.error(sprint("Exception caught:\n{0}", e.toString()));
+    }
+    debug (selector)
+        log.trace("Leaving thread");
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/networking/sockethello.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,29 @@
+/*******************************************************************************
+
+        Shows how to create a basic socket client, and how to converse with
+        a remote server. The server must be running for this to succeed
+
+*******************************************************************************/
+
+private import  tango.io.Console;
+
+private import  tango.net.SocketConduit, 
+                tango.net.InternetAddress;
+
+void main()
+{
+        // make a connection request to the server
+        auto request = new SocketConduit;
+        request.connect (new InternetAddress ("localhost", 8080));
+        request.output.write ("hello\n");
+
+        // wait for response (there is an optional timeout supported)
+        char[64] response;
+        auto size = request.input.read (response);
+
+        // close socket
+        request.close;
+
+        // display server response
+        Cout (response[0..size]).newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/networking/socketserver.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,53 @@
+/*******************************************************************************
+
+        Shows how to create a basic socket server, and how to talk to
+        it from a socket client. Note that both the server and client
+        are entirely simplistic, and therefore this is for illustration
+        purposes only. See HttpServer for something more robust.
+
+*******************************************************************************/
+
+private import  tango.core.Thread;
+
+private import  tango.io.Console;
+
+private import  tango.net.ServerSocket,
+                tango.net.SocketConduit;
+
+/*******************************************************************************
+
+        Create a socket server, and have it respond to a request
+
+*******************************************************************************/
+
+void main()
+{
+        const int port = 8080;
+ 
+        // thread body for socket-listener
+        void run()
+        {       
+                auto server = new ServerSocket (new InternetAddress(port));
+                
+                // wait for requests
+                auto request = server.accept;
+
+                // write a response 
+                request.output.write ("server replies 'hello'");
+        }
+
+        // start server in a separate thread, and wait for it to start
+        (new Thread (&run)).start;
+        Thread.sleep (0.250);
+
+        // make a connection request to the server
+        auto request = new SocketConduit;
+        request.connect (new InternetAddress("localhost", port));
+
+        // wait for and display response (there is an optional timeout)
+        char[64] response;
+        auto len = request.input.read (response);
+        Cout (response[0..len]).newline;
+
+        request.close;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/synchronization/barrier.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,138 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+               Converted to use core.sync by Sean Kelly <sean@f4.ca>
+*******************************************************************************/
+
+private import tango.core.sync.Barrier;
+private import tango.core.sync.Mutex;
+private import tango.core.Exception;
+private import tango.core.Thread;
+private import tango.io.Stdout;
+private import tango.text.convert.Integer;
+debug (barrier)
+{
+    private import tango.util.log.Log;
+    private import tango.util.log.ConsoleAppender;
+    private import tango.util.log.DateLayout;
+}
+
+
+/**
+ * Example program for the tango.core.sync.Barrier module.
+ */
+void main(char[][] args)
+{
+    const uint MaxThreadCount   = 100;
+    const uint LoopsPerThread   = 10000;
+
+    debug (barrier)
+    {
+        Logger log = Log.getLogger("barrier");
+
+        log.addAppender(new ConsoleAppender(new DateLayout()));
+
+        log.info("Barrier test");
+    }
+
+    Barrier barrier = new Barrier(MaxThreadCount);
+    Mutex   mutex = new Mutex();
+    uint    count = 0;
+    uint    correctCount = 0;
+
+    void barrierTestThread()
+    {
+        debug (barrier)
+        {
+            Logger log = Log.getLogger("barrier." ~ Thread.getThis().name());
+
+            log.trace("Starting thread");
+        }
+
+        try
+        {
+            for (uint i; i < LoopsPerThread; ++i)
+            {
+                // 'count' is a resource shared by multiple threads, so we must
+                // acquire the mutex before modifying it.
+                synchronized (mutex)
+                {
+                    // debug (barrier)
+                    //     log.trace("Acquired mutex");
+                    count++;
+                    // debug (barrier)
+                    //     log.trace("Releasing mutex");
+                }
+            }
+
+            // We wait for all the threads to finish counting.
+            debug (barrier)
+                log.trace("Waiting on barrier");
+            barrier.wait();
+            debug (barrier)
+                log.trace("Barrier was opened");
+
+            // We make sure that all the threads exited the barrier after
+            // *all* of them had finished counting.
+            synchronized (mutex)
+            {
+                // debug (barrier)
+                //     log.trace("Acquired mutex");
+                if (count == MaxThreadCount * LoopsPerThread)
+                {
+                    ++correctCount;
+                }
+                // debug (barrier)
+                //     log.trace("Releasing mutex");
+            }
+        }
+        catch (SyncException e)
+        {
+            Stderr.formatln("Sync exception caught in Barrier test thread {0}:\n{1}\n",
+                            Thread.getThis().name, e.toString());
+        }
+        catch (Exception e)
+        {
+            Stderr.formatln("Unexpected exception caught in Barrier test thread {0}:\n{1}\n",
+                            Thread.getThis().name, e.toString());
+        }
+    }
+
+    ThreadGroup group = new ThreadGroup();
+    Thread      thread;
+    char[10]    tmp;
+
+    for (uint i = 0; i < MaxThreadCount; ++i)
+    {
+        thread = new Thread(&barrierTestThread);
+        thread.name = "thread-" ~ format(tmp, i);
+
+        group.add(thread);
+        debug (barrier)
+            log.trace("Created thread " ~ thread.name);
+        thread.start();
+    }
+
+    debug (barrier)
+        log.trace("Waiting for threads to finish");
+    group.joinAll();
+
+    if (count == MaxThreadCount * LoopsPerThread)
+    {
+        debug (barrier)
+            log.info("The Barrier test was successful");
+    }
+    else
+    {
+        debug (barrier)
+        {
+            log.error("The Barrier is not working properly: the counter has an incorrect value");
+            assert(false);
+        }
+        else
+        {
+            assert(false, "The Barrier is not working properly: the counter has an incorrect value");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/synchronization/condition.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,307 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+               Converted to use core.sync by Sean Kelly <sean@f4.ca>
+*******************************************************************************/
+
+private import tango.core.sync.Condition;
+private import tango.core.Exception;
+private import tango.core.Thread;
+private import tango.text.convert.Integer;
+private import tango.io.Stdout;
+debug (condition)
+{
+    private import tango.util.log.Log;
+    private import tango.util.log.ConsoleAppender;
+    private import tango.util.log.DateLayout;
+}
+
+
+void main(char[][] args)
+{
+    debug (condition)
+    {
+        Logger log = Log.getLogger("condition");
+
+        log.addAppender(new ConsoleAppender(new DateLayout()));
+
+        log.info("Condition test");
+    }
+
+    testNotifyOne();
+    testNotifyAll();
+}
+
+
+/**
+ * Test for Condition.notify().
+ */
+void testNotifyOne()
+{
+    debug (condition)
+    {
+        Logger log = Log.getLogger("condition.notify-one");
+    }
+
+    scope Mutex     mutex   = new Mutex();
+    scope Condition cond    = new Condition(mutex);
+    int             waiting = 0;
+    Thread          thread;
+
+    void notifyOneTestThread()
+    {
+        debug (condition)
+        {
+            Logger log = Log.getLogger("condition.notify-one." ~ Thread.getThis().name());
+
+            log.trace("Starting thread");
+        }
+
+        try
+        {
+            synchronized (mutex)
+            {
+                debug (condition)
+                    log.trace("Acquired mutex");
+
+                scope(exit)
+                {
+                    debug (condition)
+                        log.trace("Releasing mutex");
+                }
+
+                waiting++;
+
+                while (waiting != 2)
+                {
+                    debug (condition)
+                        log.trace("Waiting on condition variable");
+                    cond.wait();
+                }
+
+                debug (condition)
+                    log.trace("Condition variable was signaled");
+            }
+        }
+        catch (SyncException e)
+        {
+            Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}",
+                            Thread.getThis().name(), e.toString());
+        }
+        catch (Exception e)
+        {
+            Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}",
+                            Thread.getThis().name(), e.toString());
+        }
+        debug (condition)
+            log.trace("Exiting thread");
+    }
+
+    thread = new Thread(&notifyOneTestThread);
+    thread.name = "thread-1";
+
+    debug (condition)
+        log.trace("Created thread " ~ thread.name);
+    thread.start();
+
+    try
+    {
+        // Poor man's barrier: wait until the other thread is waiting.
+        while (true)
+        {
+            synchronized (mutex)
+            {
+                if (waiting != 1)
+                {
+                    Thread.yield();
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        synchronized (mutex)
+        {
+            debug (condition)
+                log.trace("Acquired mutex");
+
+            waiting++;
+
+            debug (condition)
+                log.trace("Notifying test thread");
+            cond.notify();
+
+            debug (condition)
+                log.trace("Releasing mutex");
+        }
+
+        thread.join();
+
+        if (waiting == 2)
+        {
+            debug (condition)
+                log.info("The Condition notification test to one thread was successful");
+        }
+        else
+        {
+            debug (condition)
+            {
+                log.error("The condition variable notification to one thread is not working");
+                assert(false);
+            }
+            else
+            {
+                assert(false, "The condition variable notification to one thread is not working");
+            }
+        }
+    }
+    catch (SyncException e)
+    {
+        Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString());
+    }
+}
+
+
+/**
+ * Test for Condition.notifyAll().
+ */
+void testNotifyAll()
+{
+    const uint MaxThreadCount = 10;
+
+    debug (condition)
+    {
+        Logger log = Log.getLogger("condition.notify-all");
+    }
+
+    scope Mutex     mutex   = new Mutex();
+    scope Condition cond    = new Condition(mutex);
+    int             waiting = 0;
+
+    /**
+     * This thread waits for a notification from the main thread.
+     */
+    void notifyAllTestThread()
+    {
+        debug (condition)
+        {
+            Logger log = Log.getLogger("condition.notify-all." ~ Thread.getThis().name());
+
+            log.trace("Starting thread");
+        }
+
+        try
+        {
+            synchronized (mutex)
+            {
+                debug (condition)
+                    log.trace("Acquired mutex");
+
+                waiting++;
+
+                while (waiting != MaxThreadCount + 1)
+                {
+                    debug (condition)
+                        log.trace("Waiting on condition variable");
+                    cond.wait();
+                }
+
+                debug (condition)
+                    log.trace("Condition variable was signaled");
+
+                debug (condition)
+                    log.trace("Releasing mutex");
+            }
+        }
+        catch (SyncException e)
+        {
+            Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}",
+                            Thread.getThis().name(), e.toString());
+        }
+        catch (Exception e)
+        {
+            Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}",
+                            Thread.getThis().name(), e.toString());
+        }
+        debug (condition)
+            log.trace("Exiting thread");
+    }
+
+    ThreadGroup group = new ThreadGroup();
+    Thread      thread;
+    char[10]    tmp;
+
+    for (uint i = 0; i < MaxThreadCount; ++i)
+    {
+        thread = new Thread(&notifyAllTestThread);
+        thread.name = "thread-" ~ format(tmp, i);
+
+        group.add(thread);
+        debug (condition)
+            log.trace("Created thread " ~ thread.name);
+        thread.start();
+    }
+
+    try
+    {
+        // Poor man's barrier: wait until all the threads are waiting.
+        while (true)
+        {
+            synchronized (mutex)
+            {
+                if (waiting != MaxThreadCount)
+                {
+                    Thread.yield();
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        synchronized (mutex)
+        {
+            debug (condition)
+                log.trace("Acquired mutex");
+
+            waiting++;
+
+            debug (condition)
+                log.trace("Notifying all threads");
+            cond.notifyAll();
+
+            debug (condition)
+                log.trace("Releasing mutex");
+        }
+
+        debug (condition)
+            log.trace("Waiting for threads to finish");
+        group.joinAll();
+
+        if (waiting == MaxThreadCount + 1)
+        {
+            debug (condition)
+                log.info("The Condition notification test to many threads was successful");
+        }
+        else
+        {
+            debug (condition)
+            {
+                log.error("The condition variable notification to many threads is not working");
+                assert(false);
+            }
+            else
+            {
+                assert(false, "The condition variable notification to many threads is not working");
+            }
+        }
+    }
+    catch (SyncException e)
+    {
+        Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/synchronization/mutex.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,248 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+               Converted to use core.sync by Sean Kelly <sean@f4.ca>
+*******************************************************************************/
+
+private import tango.core.sync.Mutex;
+private import tango.core.Exception;
+private import tango.core.Thread;
+private import tango.io.Stdout;
+private import tango.text.convert.Integer;
+debug (mutex)
+{
+    private import tango.util.log.Log;
+    private import tango.util.log.ConsoleAppender;
+    private import tango.util.log.DateLayout;
+}
+
+
+/**
+ * Example program for the tango.core.sync.Mutex module.
+ */
+void main(char[][] args)
+{
+    debug (mutex)
+    {
+        Logger log = Log.getLogger("mutex");
+
+        log.addAppender(new ConsoleAppender(new DateLayout()));
+
+        log.info("Mutex test");
+    }
+
+    testNonRecursive();
+    testLocking();
+    testRecursive();
+}
+
+/**
+ * Test that non-recursive mutexes actually do what they're supposed to do.
+ *
+ * Remarks:
+ * Windows only supports recursive mutexes.
+ */
+void testNonRecursive()
+{
+    version (Posix)
+    {
+        debug (mutex)
+        {
+            Logger log = Log.getLogger("mutex.non-recursive");
+        }
+
+        Mutex   mutex = new Mutex(Mutex.Type.NonRecursive);
+        bool    couldLock;
+
+        try
+        {
+            mutex.lock();
+            debug (mutex)
+                log.trace("Acquired mutex");
+            couldLock = mutex.tryLock();
+            if (couldLock)
+            {
+                debug (mutex)
+                {
+                    log.trace("Re-acquired mutex");
+                    log.trace("Releasing mutex");
+                }
+                mutex.unlock();
+            }
+            else
+            {
+                debug (mutex)
+                    log.trace("Re-acquiring the mutex failed");
+            }
+            debug (mutex)
+                log.trace("Releasing mutex");
+            mutex.unlock();
+        }
+        catch (SyncException e)
+        {
+            Stderr.formatln("Sync exception caught when testing non-recursive mutexes:\n{0}\n", e.toString());
+        }
+        catch (Exception e)
+        {
+            Stderr.formatln("Unexpected exception caught when testing non-recursive mutexes:\n{0}\n", e.toString());
+        }
+
+        if (!couldLock)
+        {
+            debug (mutex)
+                log.info("The non-recursive Mutex test was successful");
+        }
+        else
+        {
+            debug (mutex)
+            {
+                log.error("Non-recursive mutexes are not working: "
+                          "Mutex.tryAcquire() did not fail on an already acquired mutex");
+                assert(false);
+            }
+            else
+            {
+                assert(false, "Non-recursive mutexes are not working: "
+                              "Mutex.tryAcquire() did not fail on an already acquired mutex");
+            }
+        }
+    }
+}
+
+/**
+ * Create several threads that acquire and release a mutex several times.
+ */
+void testLocking()
+{
+    const uint MaxThreadCount   = 10;
+    const uint LoopsPerThread   = 1000;
+
+    debug (mutex)
+    {
+        Logger log = Log.getLogger("mutex.locking");
+    }
+
+    Mutex   mutex = new Mutex();
+    uint    lockCount = 0;
+
+    void mutexLockingThread()
+    {
+        try
+        {
+            for (uint i; i < LoopsPerThread; i++)
+            {
+                synchronized (mutex)
+                {
+                    lockCount++;
+                }
+            }
+        }
+        catch (SyncException e)
+        {
+            Stderr.formatln("Sync exception caught inside mutex testing thread:\n{0}\n", e.toString());
+        }
+        catch (Exception e)
+        {
+            Stderr.formatln("Unexpected exception caught inside mutex testing thread:\n{0}\n", e.toString());
+        }
+    }
+
+    ThreadGroup group = new ThreadGroup();
+    Thread      thread;
+    char[10]    tmp;
+
+    for (uint i = 0; i < MaxThreadCount; i++)
+    {
+        thread = new Thread(&mutexLockingThread);
+        thread.name = "thread-" ~ format(tmp, i);
+
+        debug (mutex)
+            log.trace("Created thread " ~ thread.name);
+        thread.start();
+
+        group.add(thread);
+    }
+
+    debug (mutex)
+        log.trace("Waiting for threads to finish");
+    group.joinAll();
+
+    if (lockCount == MaxThreadCount * LoopsPerThread)
+    {
+        debug (mutex)
+            log.info("The Mutex locking test was successful");
+    }
+    else
+    {
+        debug (mutex)
+        {
+            log.error("Mutex locking is not working properly: "
+                      "the number of times the mutex was acquired is incorrect");
+            assert(false);
+        }
+        else
+        {
+            assert(false,"Mutex locking is not working properly: "
+                         "the number of times the mutex was acquired is incorrect");
+        }
+    }
+}
+
+/**
+ * Test that recursive mutexes actually do what they're supposed to do.
+ */
+void testRecursive()
+{
+    const uint LoopsPerThread   = 1000;
+
+    debug (mutex)
+    {
+        Logger log = Log.getLogger("mutex.recursive");
+    }
+
+    Mutex   mutex = new Mutex;
+    uint    lockCount = 0;
+
+    try
+    {
+        for (uint i = 0; i < LoopsPerThread; i++)
+        {
+            mutex.lock();
+            lockCount++;
+        }
+    }
+    catch (SyncException e)
+    {
+        Stderr.formatln("Sync exception caught in recursive mutex test:\n{0}\n", e.toString());
+    }
+    catch (Exception e)
+    {
+        Stderr.formatln("Unexpected exception caught in recursive mutex test:\n{0}\n", e.toString());
+    }
+
+    for (uint i = 0; i < lockCount; i++)
+    {
+        mutex.unlock();
+    }
+
+    if (lockCount == LoopsPerThread)
+    {
+        debug (mutex)
+            log.info("The recursive Mutex test was successful");
+    }
+    else
+    {
+        debug (mutex)
+        {
+            log.error("Recursive mutexes are not working: "
+                      "the number of times the mutex was acquired is incorrect");
+            assert(false);
+        }
+        else
+        {
+            assert(false, "Recursive mutexes are not working: "
+                          "the number of times the mutex was acquired is incorrect");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/synchronization/readwritemutex.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,145 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+               Converted to use core.sync by Sean Kelly <sean@f4.ca>
+*******************************************************************************/
+
+private import tango.core.sync.ReadWriteMutex;
+private import tango.core.sync.Mutex;
+private import tango.core.Thread;
+private import tango.text.convert.Integer;
+debug (readwritemutex)
+{
+    private import tango.util.log.Log;
+    private import tango.util.log.ConsoleAppender;
+    private import tango.util.log.DateLayout;
+}
+
+
+/**
+ * Example program for the tango.core.sync.ReadWriteMutex module.
+ */
+void main(char[][] args)
+{
+    const uint ReaderThreads    = 100;
+    const uint WriterThreads    = 20;
+    const uint LoopsPerReader   = 10000;
+    const uint LoopsPerWriter   = 1000;
+    const uint CounterIncrement = 3;
+
+    debug (readwritemutex)
+    {
+        Logger log = Log.getLogger("readwritemutex");
+
+        log.addAppender(new ConsoleAppender(new DateLayout()));
+
+        log.info("ReadWriteMutex test");
+    }
+
+    ReadWriteMutex  rwlock = new ReadWriteMutex();
+    Mutex           mutex = new Mutex();
+    uint            readCount = 0;
+    uint            passed = 0;
+    uint            failed = 0;
+
+    void mutexReaderThread()
+    {
+        debug (readwritemutex)
+        {
+            Logger log = Log.getLogger("readwritemutex." ~ Thread.getThis().name());
+
+            log.trace("Starting reader thread");
+        }
+
+        for (uint i = 0; i < LoopsPerReader; ++i)
+        {
+            // All the reader threads acquire the mutex for reading and when they are
+            // all done
+            synchronized (rwlock.reader)
+            {
+                for (uint j = 0; j < CounterIncrement; ++j)
+                {
+                    synchronized (mutex)
+                    {
+                        ++readCount;
+                    }
+                }
+            }
+        }
+    }
+
+    void mutexWriterThread()
+    {
+        debug (readwritemutex)
+        {
+            Logger log = Log.getLogger("readwritemutex." ~ Thread.getThis().name());
+
+            log.trace("Starting writer thread");
+        }
+
+        for (uint i = 0; i < LoopsPerWriter; ++i)
+        {
+            synchronized (rwlock.writer)
+            {
+                synchronized (mutex)
+                {
+                    if (readCount % 3 == 0)
+                    {
+                        ++passed;
+                    }
+                }
+            }
+        }
+    }
+
+    ThreadGroup group = new ThreadGroup();
+    Thread      thread;
+    char[10]    tmp;
+
+    for (uint i = 0; i < ReaderThreads; ++i)
+    {
+        thread = new Thread(&mutexReaderThread);
+        thread.name = "reader-" ~ format(tmp, i);
+
+        debug (readwritemutex)
+            log.trace("Created reader thread " ~ thread.name);
+        thread.start();
+
+        group.add(thread);
+    }
+
+    for (uint i = 0; i < WriterThreads; ++i)
+    {
+        thread = new Thread(&mutexWriterThread);
+        thread.name = "writer-" ~ format(tmp, i);
+
+        debug (readwritemutex)
+            log.trace("Created writer thread " ~ thread.name);
+        thread.start();
+
+        group.add(thread);
+    }
+
+    debug (readwritemutex)
+        log.trace("Waiting for threads to finish");
+    group.joinAll();
+
+    if (passed == WriterThreads * LoopsPerWriter)
+    {
+        debug (readwritemutex)
+            log.info("The ReadWriteMutex test was successful");
+    }
+    else
+    {
+        debug (readwritemutex)
+        {
+            log.error("The ReadWriteMutex is not working properly: the counter has an incorrect value");
+            assert(false);
+        }
+        else
+        {
+            assert(false, "The ReadWriteMutex is not working properly: the counter has an incorrect value");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/synchronization/semaphore.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,340 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2007 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+               Converted to use core.sync by Sean Kelly <sean@f4.ca>
+*******************************************************************************/
+
+module semaphore;
+
+private import tango.core.sync.Semaphore;
+private import tango.core.sync.Mutex;
+private import tango.core.Exception;
+private import tango.core.Exception;
+private import tango.core.Thread;
+private import tango.io.Console;
+private import tango.text.stream.LineIterator;
+private import tango.text.convert.Integer;
+private import tango.sys.Process;
+
+debug (semaphore)
+{
+    private import tango.util.log.Log;
+    private import tango.util.log.ConsoleAppender;
+    private import tango.util.log.DateLayout;
+}
+
+const char[] SemaphoreName = "TestProcessSemaphore";
+
+
+/**
+ * Example program for the tango.core.sync.Barrier module.
+ */
+int main(char[][] args)
+{
+    if (args.length == 1)
+    {
+        debug (semaphore)
+        {
+            Logger log = Log.getLogger("semaphore");
+
+            log.addAppender(new ConsoleAppender(new DateLayout()));
+
+            log.info("Semaphore test");
+        }
+
+        testSemaphore();
+        testProcessSemaphore(args[0]);
+
+        return 0;
+    }
+    else
+    {
+        return testSecondProcessSemaphore();
+    }
+}
+
+/**
+ * Test for single-process (multi-threaded) semaphores.
+ */
+void testSemaphore()
+{
+    const uint MaxThreadCount   = 10;
+
+    // Semaphore used in the tests.  Start it "locked" (i.e., its initial
+    // count is 0).
+    Semaphore   sem = new Semaphore(MaxThreadCount - 1);
+    Mutex       mutex = new Mutex();
+    uint        count = 0;
+    bool        passed = false;
+
+    void semaphoreTestThread()
+    {
+        debug (semaphore)
+        {
+            Logger log = Log.getLogger("semaphore.single." ~ Thread.getThis().name());
+
+            log.trace("Starting thread");
+        }
+
+        try
+        {
+            uint threadNumber;
+
+            // 'count' is a resource shared by multiple threads, so we must
+            // acquire the mutex before modifying it.
+            synchronized (mutex)
+            {
+                // debug (semaphore)
+                //     log.trace("Acquired mutex");
+                threadNumber = ++count;
+                // debug (semaphore)
+                //     log.trace("Releasing mutex");
+            }
+
+            // We wait for all the threads to finish counting.
+            if (threadNumber < MaxThreadCount)
+            {
+                sem.wait();
+                debug (semaphore)
+                    log.trace("Acquired semaphore");
+
+                while (true)
+                {
+                    synchronized (mutex)
+                    {
+                        if (count >= MaxThreadCount + 1)
+                            break;
+                    }
+                    Thread.yield();
+                }
+
+                debug (semaphore)
+                    log.trace("Releasing semaphore");
+                sem.notify();
+            }
+            else
+            {
+                passed = !sem.tryWait();
+                if (passed)
+                {
+                    debug (semaphore)
+                        log.trace("Tried to acquire the semaphore too many times and failed: OK");
+                }
+                else
+                {
+                    debug (semaphore)
+                        log.error("Tried to acquire the semaphore too may times and succeeded: FAILED");
+
+                    debug (semaphore)
+                        log.trace("Releasing semaphore");
+                    sem.notify();
+                }
+                synchronized (mutex)
+                {
+                    count++;
+                }
+            }
+        }
+        catch (SyncException e)
+        {
+            Cerr("Sync exception caught in Semaphore test thread " ~ Thread.getThis().name ~
+                 ":\n" ~ e.toString()).newline;
+        }
+        catch (Exception e)
+        {
+            Cerr("Unexpected exception caught in Semaphore test thread " ~ Thread.getThis().name ~
+                 ":\n" ~ e.toString()).newline;
+        }
+    }
+
+    debug (semaphore)
+    {
+        Logger log = Log.getLogger("semaphore.single");
+    }
+
+    ThreadGroup group = new ThreadGroup();
+    Thread      thread;
+    char[10]    tmp;
+
+    for (uint i = 0; i < MaxThreadCount; ++i)
+    {
+        thread = new Thread(&semaphoreTestThread);
+        thread.name = "thread-" ~ tango.text.convert.Integer.format(tmp, i);
+
+        group.add(thread);
+        debug (semaphore)
+            log.trace("Created thread " ~ thread.name);
+        thread.start();
+    }
+
+    debug (semaphore)
+        log.trace("Waiting for threads to finish");
+    group.joinAll();
+
+    if (passed)
+    {
+        debug (semaphore)
+            log.info("The Semaphore test was successful");
+    }
+    else
+    {
+        debug (semaphore)
+        {
+            log.error("The Semaphore is not working properly: it allowed "
+                      "to be acquired more than it should have done");
+            assert(false);
+        }
+        else
+        {
+            assert(false, "The Semaphore is not working properly: it allowed "
+                          "to be acquired more than it should have done");
+        }
+    }
+}
+
+/**
+ * Test for multi-process semaphores: this test works by creating a copy of
+ * this process that tries to acquire the ProcessSemaphore that was created
+ * in this function. If everything works as expected, the attempt should fail,
+ * as the count of the semaphore is set to 1.
+ */
+void testProcessSemaphore(char[] programName)
+{
+    /+
+    bool success = false;
+
+    debug (semaphore)
+    {
+        Logger log = Log.getLogger("semaphore.multi");
+        Logger childLog = Log.getLogger("semaphore.multi.child");
+
+        log.info("ProcessSemaphore test");
+    }
+
+    try
+    {
+        scope ProcessSemaphore sem = new ProcessSemaphore(SemaphoreName, 1);
+        Process proc = new Process(programName, "2");
+
+        debug (semaphore)
+            log.trace("Created ProcessSemaphore('" ~ SemaphoreName ~ "')'");
+
+        sem.wait();
+        debug (semaphore)
+            log.trace("Acquired semaphore in main process");
+
+        debug (semaphore)
+            log.trace("Executing child test process: " ~ proc.toString());
+        proc.execute();
+
+        debug (semaphore)
+        {
+            foreach (line; new LineIterator!(char)(proc.stdout))
+            {
+                childLog.trace(line);
+            }
+        }
+        foreach (line; new LineIterator!(char)(proc.stderr))
+        {
+            Cerr(line).newline;
+        }
+
+        debug (semaphore)
+            log.trace("Waiting for child process to finish");
+        auto result = proc.wait();
+
+        success = (result.reason == Process.Result.Exit && result.status == 2);
+
+        debug (semaphore)
+            log.trace("Releasing semaphore in main process");
+        sem.notify();
+    }
+    catch (SyncException e)
+    {
+        Cerr("Sync exception caught in ProcessSemaphore main test process:\n" ~ e.toString()).newline;
+    }
+    catch (ProcessException e)
+    {
+        Cerr("Process exception caught in ProcessSemaphore main test process:\n" ~ e.toString()).newline;
+    }
+    catch (Exception e)
+    {
+        Cerr("Unexpected exception caught in ProcessSemaphore main test process:\n" ~ e.toString()).newline;
+    }
+
+    if (success)
+    {
+        debug (semaphore)
+            log.info("The ProcessSemaphore test was successful");
+    }
+    else
+    {
+        debug (semaphore)
+        {
+            log.error("The multi-process semaphore is not working");
+            assert(false);
+        }
+        else
+        {
+            assert(false, "The multi-process semaphore is not working");
+        }
+    }
+    +/
+}
+
+/**
+ * Test for multi-process semaphores (second process).
+ */
+int testSecondProcessSemaphore()
+{
+    int rc = 0;
+
+    /+
+    debug (semaphore)
+    {
+        Cout("Starting child process\n");
+    }
+
+    try
+    {
+        scope ProcessSemaphore sem = new ProcessSemaphore(SemaphoreName);
+        bool success;
+
+        success = !sem.tryAcquire();
+        if (success)
+        {
+            debug (semaphore)
+                Cout("Tried to acquire semaphore in child process and failed: OK\n");
+            rc = 2;
+        }
+        else
+        {
+            debug (semaphore)
+            {
+                Cout("Acquired semaphore in child process: this should not have happened\n");
+                Cout("Releasing semaphore in child process\n");
+            }
+            sem.notify();
+            rc = 1;
+        }
+    }
+    catch (SyncException e)
+    {
+        Cerr("Sync exception caught in ProcessSemaphore child test process:\n" ~ e.toString()).newline;
+    }
+    catch (ProcessException e)
+    {
+        Cerr("Process exception caught in ProcessSemaphore child test process:\n" ~ e.toString()).newline;
+    }
+    catch (Exception e)
+    {
+        Cerr("Unexpected exception caught in ProcessSemaphore child test process:\n" ~ e.toString()).newline;
+    }
+
+    debug (semaphore)
+        Cout("Leaving child process\n");
+
+    +/
+    return rc;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/system/arguments.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,97 @@
+/*******************************************************************************
+        Illustrates use of the Arguments class.
+*******************************************************************************/
+
+import tango.util.Arguments;
+import tango.io.Stdout;
+import tango.io.FileConduit;
+import tango.text.stream.LineIterator;
+
+void usage()
+{
+	Stdout("Usage: [OPTIONS]... FILES...").newline;
+	Stdout("This is a program that does something.").newline;
+	Stdout.newline;
+	Stdout("OPTIONS: ").newline;
+	Stdout("Output this help message:          -?,      --help").newline;
+	Stdout("Do cool things to your files:      -c, -C,  --cool").newline;
+	Stdout("Use filename as response file:     -r, -R,  --response").newline;
+}
+
+void main(char[][] cmdlArgs)
+{
+	char[][] implicitArguments = ["files"];
+	
+	char[][][] argumentAliases;
+	argumentAliases ~= ["help",          "?"];
+	argumentAliases ~= ["cool",     "C", "c"];
+	argumentAliases ~= ["response", "R", "r"];
+	
+	auto args = new Arguments(cmdlArgs, implicitArguments, argumentAliases);
+
+	bool fileExistsValidation(char[] arg)
+	{
+		bool rtn;
+		FilePath argFile = new FilePath(arg);
+		rtn = argFile.exists;
+		if (!rtn)
+			Stdout.format("Specified path does not exist: {}", arg).newline;
+		return rtn;
+	}
+
+	bool singleFileValidation(char[][] args, inout char[] invalidArg)
+	{
+		if (args.length > 1)
+		{
+			Stdout("Cannot specify multiple paths for argument.").newline;
+			invalidArg = args[1];
+		}
+		else
+			return true;
+		return false;
+	}
+
+	args.addValidation("response", &fileExistsValidation);
+	args.addValidation("response", &singleFileValidation);
+	args.addValidation("files", true, true);
+
+	bool argsValidated = true;
+	try
+		args.validate;
+	catch (ArgumentException ex)
+	{
+		if (ex.reason == ArgumentException.ExceptionReason.MISSING_ARGUMENT)
+			Stdout.format("Missing Argument: {} ({})", ex.name, ex.msg).newline;
+		else if (ex.reason == ArgumentException.ExceptionReason.MISSING_PARAMETER)
+			Stdout.format("Missing Parameter to Argument: {} ({})", ex.name, ex.msg).newline;
+		else if (ex.reason == ArgumentException.ExceptionReason.INVALID_PARAMETER)
+			Stdout.format("Invalid Parameter: {} ({})", ex.name, ex.msg).newline;
+		Stdout.newline;
+		argsValidated = false;
+	}
+
+	if ((!argsValidated) || ("help" in args))
+		usage();
+	else
+	{// ready to run
+		if ("response" in args)
+		{
+            Stdout(args["response"][0]).newline;
+            auto file = new FileConduit(args["response"][0]);
+            auto lines = new LineIterator!(char)(file);
+            char[][] arguments;
+            foreach (line; lines)
+                arguments ~= line.dup;
+            args.parse(arguments, implicitArguments, argumentAliases);
+		}
+		if ("cool" in args)
+		{
+            Stdout ("Listing the files to be actioned in a cool way.").newline;
+            foreach (char[] file; args["files"])
+                Stdout.format("{}", file).newline;
+            Stdout ("Cool and secret action performed.").newline;
+		}
+		if ("x" in args)
+			Stdout.format("User set the X factor to '{}'", args["x"]).newline;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/system/localtime.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,54 @@
+/*******************************************************************************
+
+        localtime.d
+        
+*******************************************************************************/
+
+private import  tango.io.Stdout;
+
+private import  tango.time.WallClock;
+
+/******************************************************************************
+
+        Example code to format a local time in the following format:
+        "Wed Dec 31 16:00:00 GMT-0800 1969". The day and month names
+        would typically be extracted from a locale instance, but we
+        convert them locally here for the sake of simplicity
+
+******************************************************************************/
+
+void main ()
+{
+        /// list of day names
+        static char[][] days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+
+        /// list of month names
+        static char[][] months =
+        [
+            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+        ];
+
+        // retreive local time
+        auto dt = WallClock.toDate;
+
+        // get GMT difference in minutes
+        auto tz = cast(int) WallClock.zone.minutes;
+        char sign = '+';
+        if (tz < 0)
+            tz = -tz, sign = '-';
+
+        // format date
+        Stdout.formatln ("{}, {} {:d2} {:d2}:{:d2}:{:d2} GMT{}{:d2}:{:d2} {}",
+                          days[dt.date.dow],
+                          months[dt.date.month-1],
+                          dt.date.day,
+                          dt.time.hours, 
+                          dt.time.minutes,
+                          dt.time.seconds,
+                          sign,
+                          tz / 60,
+                          tz % 60,
+                          dt.date.year
+                         );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/system/normpath.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,51 @@
+/*****************************************************************
+
+  Simple example that shows possible inputs to normalize and the
+  corresponding outputs.
+
+  Put into public domain by Lars Ivar Igesund.
+
+*****************************************************************/
+
+import tango.io.Stdout;
+
+import tango.util.PathUtil;
+
+int main()
+{
+version (Posix) {
+    Stdout(normalize ( "/foo/../john")).newline;
+    Stdout(normalize ( "foo/../john")).newline;    
+    Stdout(normalize ( "foo/bar/..")).newline;    
+    Stdout(normalize ( "foo/bar/../john")).newline;
+    Stdout(normalize ( "foo/bar/doe/../../john")).newline;
+    Stdout(normalize ( "foo/bar/doe/../../john/../bar")).newline;
+    Stdout(normalize ( "./foo/bar/doe")).newline;
+    Stdout(normalize ( "./foo/bar/doe/../../john/../bar")).newline;
+    Stdout(normalize ( "./foo/bar/../../john/../bar")).newline;
+    Stdout(normalize ( "foo/bar/./doe/../../john")).newline;
+    Stdout(normalize ( "../../foo/bar/./doe/../../john")).newline;
+    Stdout(normalize ( "../../../foo/bar")).newline;
+    Stdout("** Should now throw exception as the following path is invalid for normalization.").newline;
+    Stdout(normalize ( "/../../../foo/bar")).newline;
+}
+version (Windows) {
+    Stdout(normalize ( "C:\\foo\\..\\john")).newline;
+    Stdout(normalize ( "foo\\..\\john")).newline;    
+    Stdout(normalize ( "foo\\bar\\..")).newline;    
+    Stdout(normalize ( "foo\\bar\\..\\john")).newline;
+    Stdout(normalize ( "foo\\bar\\doe\\..\\..\\john")).newline;
+    Stdout(normalize ( "foo\\bar\\doe\\..\\..\\john\\..\\bar")).newline;
+    Stdout(normalize ( ".\\foo\\bar\\doe")).newline;
+    Stdout(normalize ( ".\\foo\\bar\\doe\\..\\..\\john\\..\\bar")).newline;
+    Stdout(normalize ( ".\\foo\\bar\\..\\..\\john\\..\\bar")).newline;
+    Stdout(normalize ( "foo\\bar\\.\\doe\\..\\..\\john")).newline;
+    Stdout(normalize ( "..\\..\\foo\\bar\\.\\doe\\..\\..\\john")).newline;
+    Stdout(normalize ( "..\\..\\..\\foo\\bar")).newline;
+    Stdout("** Should now throw exception as the following path is invalid for normalization.").newline;
+    Stdout(normalize ( "C:\\..\\..\\..\\foo\\bar")).newline;
+}
+
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/system/process.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,60 @@
+/*******************************************************************************
+  copyright:   Copyright (c) 2006 Juan Jose Comellas. All rights reserved
+  license:     BSD style: $(LICENSE)
+  author:      Juan Jose Comellas <juanjo@comellas.com.ar>
+*******************************************************************************/
+
+private import tango.io.Stdout;
+private import tango.sys.Process;
+private import tango.core.Exception;
+
+private import tango.text.stream.LineIterator;
+
+
+/**
+ * Example program for the tango.sys.Process class.
+ */
+void main()
+{
+    version (Windows)
+        char[] command = "ping -n 4 localhost";
+    else version (Posix)
+        char[] command = "ping -c 4 localhost";
+    else
+        assert(false, "Unsupported platform");
+
+    try
+    {
+        auto p = new Process(command, null);
+
+        Stdout.formatln("Executing {0}", p.toString());
+        p.execute();
+
+        Stdout.formatln("Output from process: {0} (pid {1})\n---",
+                        p.programName, p.pid);
+
+        foreach (line; new LineIterator!(char)(p.stdout))
+        {
+            Stdout.formatln("{0}", line);
+        }
+
+        Stdout.print("---\n");
+
+        auto result = p.wait();
+
+        Stdout.formatln("Process '{0}' ({1}) finished: {2}",
+                        p.programName, p.pid, result.toString());
+    }
+    catch (ProcessException e)
+    {
+        Stdout.formatln("Process execution failed: {0}", e.toString());
+    }
+    catch (IOException e)
+    {
+        Stdout.formatln("Input/output exception caught: {0}", e.toString());
+    }
+    catch (Exception e)
+    {
+        Stdout.formatln("Unexpected exception caught: {0}", e.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/text/formatalign.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,20 @@
+/**
+
+  Example showing how the alignment component in a format string argument works.
+
+  Put into public domain by Lars Ivar Igesund
+
+*/
+
+import tango.io.Stdout;
+
+void main(){
+    char[] myFName = "Johnny";
+    Stdout.formatln("First Name = |{0,15}|", myFName);
+    Stdout.formatln("Last Name = |{0,15}|", "Foo de Bar");
+
+    Stdout.formatln("First Name = |{0,-15}|", myFName);
+    Stdout.formatln("Last Name = |{0,-15}|", "Foo de Bar");
+
+    Stdout.formatln("First name = |{0,5}|", myFName);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/text/formatindex.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,15 @@
+/**
+
+    Example that shows how the format specifiers can be used to index into
+    the argument list.
+
+    Put into public domain by Lars Ivar Igesund.
+
+*/
+
+import tango.io.Stdout;
+
+void main(){
+    Stdout.formatln("Many {1} can now be {0} around to make {2} easier,\n and {1} can also be repeated.", 
+                    "switched", "arguments", "localization");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/text/formatspec.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,17 @@
+/**
+
+  Example showing how to use format specifier components in a format string's 
+  argument.
+
+  Put into public domain by Lars Ivar Igesund
+
+*/
+
+import tango.io.Stdout;
+
+void main(){
+    double avogadros = 6.0221415e23;
+    Stdout.formatln("I have {0:C} in cash.", 100);
+    Stdout.formatln("Avogadro's number is {0:E}.", avogadros);
+    Stdout.formatln("Avogadro's number (with alignment) is {0,4:E}.", avogadros);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/text/localetime.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,21 @@
+/******************************************************************************
+
+        Example to format a locale-based time. For a default locale of 
+        en-gb, this examples formats in the following manner:
+
+        "Thu, 27 April 2006 18:20:47 +1"
+
+******************************************************************************/
+
+private import tango.io.Console;
+
+private import tango.time.Clock;
+
+private import tango.text.locale.Locale;
+
+void main ()
+{
+        auto layout = new Locale;
+
+        Cout (layout ("{:ddd, dd MMMM yyyy HH:mm:ss z}", Clock.now)).newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/example/text/properties.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,32 @@
+private import  tango.io.Buffer,
+                tango.io.Console;
+
+private import  tango.text.Properties;
+
+/*******************************************************************************
+
+        Illustrates simple usage of tango.text.Properties
+
+*******************************************************************************/
+
+void main() 
+{