Linkloader improvement: mclinker.

Change-Id: I8805e39ccbc2ee204234fb3e71c70c906f3990bb
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d970594
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+*.o
+*.swp
+Makefile.in
+VERSION
+aclocal.m4
+autom4te.cache
+config.guess
+config.sub
+configure
+depcomp
+install-sh
+ltmain.sh
+missing
+libtool.m4
+ltoptions.m
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
+ltoptions.m4
+test/*
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..6210620
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,33 @@
+LOCAL_PATH := $(call my-dir)
+MCLD_ROOT_PATH := $(LOCAL_PATH)
+# For mcld.mk
+LLVM_ROOT_PATH := external/llvm
+MCLD_ENABLE_ASSERTION := true
+
+include $(CLEAR_VARS)
+
+# MCLinker Libraries
+subdirs := \
+  lib/CodeGen \
+  lib/LD \
+  lib/MC \
+  lib/Support \
+  lib/Target
+
+# ARM Code Generation Libraries
+subdirs += \
+  lib/Target/ARM \
+  lib/Target/ARM/TargetInfo
+
+# MIPS Code Generation Libraries
+subdirs += \
+  lib/Target/Mips \
+  lib/Target/Mips/TargetInfo
+
+# X86 Code Generation Libraries
+subdirs += \
+  lib/Target/X86 \
+  lib/Target/X86/TargetInfo
+
+include $(MCLD_ROOT_PATH)/mcld.mk
+include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, $(subdirs)))
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..3dcd781
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,9 @@
+
+================================================
+Copyrights and Licenses for Third Party Software
+Distributed with MCLinker Project
+================================================
+Program             Directory
+-------             ---------
+Google Test         ${MCLinker}/utils/gtest
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..d2ddba3
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,112 @@
+2012-03-14 Luba Tang <lubatang@gmail.com>
+	* Migrate on LLVM@r152063
+	* Migrate on clang@r152062
+
+	* LD/LDSection, LD/ELFFileFormat, LD/ELFDynObjFileFormat,
+	  LD/ELFExecFileFormat:
+	Support setting alignment constraint in section header.
+	* LD/Layout:
+	Update sections' alignment constraints during section merging. 
+
+	* Support/MemoryArea, Support/MemoryRegion:
+	Enhance memory utilities. 
+
+	* Target/ARMLDBackend:
+	1. work around ARM.exidx and ARM.extab.
+	2. add relocation supports - R_ARM_TARGET1, R_ARM_TARGET2, R_ARM_ABS32, 
+	R_ARM_BASE_PREL, and R_ARM_GOT_PREL
+
+	* Target/MipsLDBackend:
+	1. Android bitmap, native Plasma and Quake1 is examined successfully.
+
+	* Target/GNULDBackend, LD/ELFSegmentFactory:
+	Move segment-related implemenation out of GNULDBackend.
+
+	* Support/ScopedWriter:
+	Obsolete, removed.
+
+	* MC/SymbolCategory:
+	add random accessing functions
+
+2012-03-01 Luba Tang <lubatang@gmail.com>
+	* add test/ARM/Relocation:
+	* add test/ARM/GOTPLT:
+	Simple regression testcases. Each case is used for testing a single
+	relocation or GOTPLT entry.
+
+	* add test/Android/Plasma/ARM, X86, MIPS:
+	* add test/Android/Quake/ARM, X86:
+	* add test/Android/Quake2/ARM, X86:
+	Basic regression testcases for Android platform. The system libraries
+	for each platform are under test/libs/ARM, X86, MIPS.
+
+	* Target/TargetLDBackend:
+	separate readSections() into readRegularSection() and
+	readTargetSection().
+
+	* Target/GNULDBackend:
+	Move hash_bucket_count() and isDynamicSymbol() on successors.
+
+	* Target/MipsLDBackend: Eable to link trivial cases and Android Plasma.
+	* Target/X86LDBackend: Eable to link all Android JNI cases with CRT.
+
+	* CodeGen/SectLinkerOption, llvm-mcld.cpp:
+	get rid of -dB option. MCLinker does not need to ask users for -dB
+	option.
+
+	* MC/MCLinker, LD/ELFObjectReader, LD/ELFObjectWriter:
+	Support symbol visibility.
+
+	* LD/LDSection: Separate LinkInfo into Link and Info. 
+
+	* LD/Relocation:
+	In order to enhance memory footprints:
+	1. Remove Relocation::m_Parent.
+	2. Let target data be a copy, not a pointer.
+
+	* LD/ELFReader, LD/ObjectReader, LD/ELFObjectReader, LD/Layout:
+	Support GROUPT section.
+
+	* LD/LDFileFormat:
+	Support all special sections listed in Linux Standard Base
+	(ISO/IEC 23360).
+
+	* Support/GCFactoryListTraits:
+	Provides GCFactory's trait for llvm::iplist.
+
+	* Support/LEB128: Add LEB128 utilities.
+
+	* Support/HashTable:
+	Identify ambiguous constructors by adding an anonyous parameter.
+
+	* Suppot/MemoryRegion, Support/MemoryArea:
+	1. remove pIsWrite parameter in MemoryArea::request(). MemoryArea knows
+	the file is readable or writable when map() the file.
+	2. MemoryArea allows to request a zero size MemoryRegion.
+
+	* patch/LLVM.patch: complement llvm/Support/ELF.h.
+	Add SHT_GNU_ATTRIBUTES, SHT_GNU_HASH, SHT_GNU_verdef, SHT_GNU_verneed,
+	and SHT_GNU_versym.
+
+	* LD/Layout:
+	1. Work around LDFileFormat::Exception and LDFileFormat::Version.
+	2. appendFragment(): Support merging sections with different alignment
+	constraints.
+
+2012-02-03 Luba Tang <lubatang@gmail.com>
+	* allocate common symbols in BSS section
+	* add ThreadLocal type in ResolveInfo::Type
+	* Quake2 can be linked on ARM Android.
+
+2012-02-02 Luba Tang <lubatang@gmail.com>
+	* Quake can be linked on x86 Android.
+
+2012-01-17 Luba Tang <lubatang@gmail.com>
+	* Quake can be linked on ARM Android.
+	* All APIs for backends is ready.
+
+2012-01-12 Jush Lu <Jush.Lu@mediatek.com>
+	* Trivial cases have worked on ARM.
+
+2011-05-23 Luba Tang <lubatang@gmail.com>
+	* create all basic files and directories.
diff --git a/ChangeLog.txt b/ChangeLog.txt
new file mode 100644
index 0000000..719a25e
--- /dev/null
+++ b/ChangeLog.txt
@@ -0,0 +1,11615 @@
+Linkloader improvement: mclinker.
+
+commit c58eed892e965064c66841b99a7492b155bee456
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Mar 15 09:07:33 2012 +0800
+
+    Add Android makefiles for MCLinker.
+
+commit 2fafd87a75fb85f77453cbec31403a2df47a284f
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Mar 14 14:43:00 2012 +0800
+
+    Remove things under mclinker/test directory.
+
+    It is not required for MCLinker build.
+
+commit 64b43e630548f6ff5e29f67fd50fdfa1627cdd03
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Mar 14 18:54:32 2012 +0800
+
+    Increase version number to 2.10.1-18peaks.
+
+commit 2670f6eb7355fac11eeb1e9b4b7cbad2cdcc8b96
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Mar 14 18:53:27 2012 +0800
+
+    Update golden model of ARM Quake
+
+commit bbe26afd1ea952e3d35ef4b7cb62ba4a88fa31c7
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Mar 14 18:43:58 2012 +0800
+
+    Fixes issue 21 comment 1.
+
+    crtbegin.o should precede all input files and crtend.o should be the
+    last. Golden model files for ARM are also updated to reflect such
+    changes.
+
+commit 99a16a23c03e34e50537efe5337fc2b00444edce
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Mar 14 17:44:15 2012 +0800
+
+    Update golden model files for X86.
+
+commit 9bd9575c2676f7b409e18c021c73264a9cfbb705
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Mar 14 15:46:50 2012 +0800
+
+    Add error message when scan relcoation R_ARM_BASE_PREL
+
+    Currently we handle R_ARM_BASE_PREL only if its target
+    symbol is _GLOBAL_OFFSET_TABEL_
+
+    R_ARM_BASE_PREL only against symbol defined by linker,
+    for example, section or segment symbols. Now we support
+    only got section symbol _GLOBAL_OFFSET_TABLE_
+
+commit fb2c70a1b22c594b256c1726cc7eff03a98065a5
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Mar 14 15:39:43 2012 +0800
+
+    Fix a bug - region should not released before creating symbol.
+
+    Because we use llvm::StringRef to pass symbol name, and llvm::StringRef
+    has no copy of the string. So, we must remain the region until we
+    finish creating symbol.
+
+commit ac12e4f59fe222245f1cb924b760b932644c096e
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Mar 14 14:26:46 2012 +0800
+
+    Refine code. let entry size use type size_t, not uint64_t.
+
+commit d904b5a237f7d49450d6569bfbce2d20d63866f3
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Mar 14 14:19:39 2012 +0800
+
+    Refine a bit - to supress the warning messages.
+
+commit 6cd13d38e0fdb37e35fc6e2211d1d566b7609d28
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Mar 14 13:54:06 2012 +0800
+
+    Refine code.
+
+    The size of got entry and fragment is hard to out of the range of size_t.
+    So, I use size_t instead of uint64_t.
+
+commit 7de970aba179e30db7f69486eeac7b3e9f052fb7
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Mar 14 13:46:19 2012 +0800
+
+    Suppress the build warnings in GNUArchiveReader.
+
+    Patch by Ping-Jung Lu <pingjunglu at gmail.com>.
+
+commit f53bf100944d0b15d1d8509e8450ea9cb5863e0c
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Mar 14 11:12:02 2012 +0800
+
+    Rename the function.
+
+commit 363f704321b4a533bd5cc624790749a28509a169
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Mar 13 21:54:25 2012 +0800
+
+    Refactor pread() out of request() in MemoryArea.
+
+commit 2aac5daab09f381d49a5106b0ec07d6e96680b15
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Tue Mar 13 21:34:56 2012 +0800
+
+    Use MemoryArea::release(MemoryRegion*) to reduce the memory footprint.
+
+commit 7f8198e609778300fcd853f388f40b3c9caac6c1
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:49:29 2012 +0800
+
+    For enhance performance, remove MemoryRegion::sync()
+
+commit cccd59a73e6995654815b1c827c80d9867519536
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:45:14 2012 +0800
+
+    Add new functio - RegionFactory::destruct(MemoryRegion*)
+
+commit a9f2046bb3a98105c3ac466823764dd8b0b836bd
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:44:05 2012 +0800
+
+    Add drift and increase/decrease MemoryArea::Space::region_num
+
+commit 203df1dce6f0499288e6da60043243f6c63643da
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:38:45 2012 +0800
+
+    Avoid from allocating big memory space at very first time.
+
+commit 7719d5b9a39baa77c4edfd98d3107013cbac5333
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:37:57 2012 +0800
+
+    remove obsolete ScopedWriter.
+
+commit 46252dc19cccb09dbcff0b28c42075bdbf602d77
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:36:25 2012 +0800
+
+    add a new field of MemoryArea::Space - region_num.
+
+    Let MemoryArea::Space be countable.
+
+commit 7deb4cc8fbd34b96761c5654bd2d59223060799d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:32:57 2012 +0800
+
+    Refine code. Change the type of parameter of PLT::reserveEntry from int to size_t.
+
+commit a32b0633a1cb899563aceced1901801587d56b52
+Author: luba <lubatang@gmail.com>
+Date:   Tue Mar 13 20:31:01 2012 +0800
+
+    Remove obsolete ScopedWriter.
+
+commit 3f1657871789c2e10597fb814a8976a287e8b1a9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Mar 13 20:20:54 2012 +0800
+
+    Set real relocation type to R_ARM_TARGET1 and R_ARM_TARGET2
+
+commit 7ee57163fb4274e29fc2004524847d0f7d1cc2c4
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Mar 13 19:59:11 2012 +0800
+
+    Update golden model files for ARM.
+
+commit 5460ca01dbf89e72f47ef936f923e28a32b925cb
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Mar 13 14:06:44 2012 +0800
+
+    Add ARM relcoation function for R_ARM_TARGET1
+
+    Refer to GNU gold, treat R_ARM_TARGET1 as R_ARM_ABS32
+
+commit 222cbd1efa892d48aa47d6de195778b51293dc2a
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Mar 13 12:00:35 2012 +0800
+
+    Set section .ARM.exidx and .ARM.extab to 'Exception.'
+
+    Currently we emit these two sections directly from inputs.
+
+commit 84bec2b1a2d6a6d3612b1b691d1130395d1ebbfa
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Mar 12 21:47:19 2012 +0800
+
+    Add ARM relocation support
+
+    R_ARM_BASE_PREL, R_ARM_TARGET2 and R_ARM_GOT_PREL
+    Refer to GNU gold, we treat R_ARM_TARGET2 as R_ARM_GOT_PREL here
+
+commit 7209c752ab4e6e0e26d51261260fbee51fb8752e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Mar 12 21:23:02 2012 +0800
+
+    Suppress more warning messages.
+
+commit 726dd63cd894c08336f8bd96dd9fe5d80d9d77ee
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Mar 12 20:33:27 2012 +0800
+
+    Suppress the warning message about enumeral and non-enumeral type in conditional expression
+
+commit 0814259a29b34222959eb8e49fb2e2ff5aa3c7e6
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Mar 12 20:16:54 2012 +0800
+
+    Remove some unused code and variables.
+
+commit e20dc4fd1122ebdd5e0b33f7b7c04b59067762f3
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Mar 12 19:12:12 2012 +0800
+
+    Suppress the warning messages about order of initialization.
+
+    No functionality was expected to change.
+
+    Initialze the member variables in the order they are declared.
+
+commit 3ef7531e9e700666a9fdb5ff9a5ac7abab422a92
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Mar 12 19:07:33 2012 +0800
+
+    Rename m_ELFSegmentFactory as m_ELFSegmentTable in GNULDBackend.
+
+commit afba4bc78d33a361e32f926e7a272898800dab01
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Mon Mar 12 18:39:13 2012 +0800
+
+    Fix a bug - SymbolCategory::arrange upward does not change the category.begin/end correctly.
+
+commit 843d7c0e8c4831362439d349dd71c9412e44067f
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Mon Mar 12 18:33:46 2012 +0800
+
+    Add access functions of SymbolCategory.
+
+commit 05bdee9db90fbffa6088be80e99b9d0acf553907
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Mar 12 16:48:16 2012 +0800
+
+    add ELFSegmentFactory class.
+
+commit dad3cbf8460739d2a709224c7f101e66336837b0
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Mon Mar 12 15:56:10 2012 +0800
+
+    eliminate clang++ warnings
+
+commit 9bf8e7d52e08420b0ef4d35f7cf90207731cb628
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Mar 12 15:21:56 2012 +0800
+
+    Migrate to LLVM upstream r152063.
+
+commit 32f23312756038f853d959613721f6df83e0a16f
+Author: luba <lubatang@gmail.com>
+Date:   Mon Mar 12 15:08:39 2012 +0800
+
+    remove sed -i option for all platforms.
+
+commit 74bbca62e25f04adfdbb3f7d6ad29c4b00635c3b
+Author: Luba Tang <lubatang@Scarecrow.local>
+Date:   Mon Mar 12 14:59:25 2012 +0800
+
+    Conforming to Mac iOS 10.7.
+
+    Using sed -i "" -e instead of sed -i
+
+commit 30c4c4a9abf655fb30817846c0fa71ad3cf49aa3
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Mar 12 14:57:03 2012 +0800
+
+    Update golden model files for ARM.
+
+commit 8be0c24c9cbeea14fdefb06bee5f3172a2b2466f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Mar 12 14:12:32 2012 +0800
+
+    Fix a bug - If not building a PIC object, no relocation type is invalid
+
+commit bab512b3b7c1f15a578666bf0cf3c8e807588381
+Author: luba <lubatang@gmail.com>
+Date:   Mon Mar 12 09:47:41 2012 +0800
+
+    Revert "Fix a bug - No matter the old symbol exists or not, StrSymPool should"
+
+    This reverts commit ae5f00574654c98426f95bc0e062ce0e5727ad25.
+
+    The bug is in SymbolCategory, not StrSymPool.
+
+commit 517d91be79c2e5bf8e3e9d0c34adbd6d09c70a75
+Author: luba <lubatang@gmail.com>
+Date:   Mon Mar 12 09:47:14 2012 +0800
+
+    Revert "Conforming to FreeBSD's sed."
+
+    This reverts commit d5decba261d3ad72d0bb978a805e3269a79bd014.
+
+commit ae5f00574654c98426f95bc0e062ce0e5727ad25
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Sun Mar 11 16:16:08 2012 +0800
+
+    Fix a bug - No matter the old symbol exists or not, StrSymPool should
+    set pOldInfo if it isn't NULL.
+
+commit d5decba261d3ad72d0bb978a805e3269a79bd014
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Sun Mar 11 16:00:05 2012 +0800
+
+    Conforming to FreeBSD's sed.
+
+commit 092c60351451c2e34ab22970ed78a4adefa05ec8
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Sun Mar 11 15:58:16 2012 +0800
+
+    Add Mips backend.
+
+commit e09e8f332dab61b7f74ea684fb44928b16344415
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Sun Mar 11 02:52:46 2012 +0800
+
+    Refine format.
+
+commit 1f5e424dc99c7d103044e1623fe47b819b0137bb
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Sat Mar 10 03:50:00 2012 +0800
+
+    Fix a bug - when a entry does not exist in a hash table, the parameter
+    bool & pExist should set false.
+
+commit b6a144426f7c819ef60b05f1717a5e7bfd4bf6fa
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Mar 9 11:48:48 2012 +0800
+
+    Fix a bug - When applying ABS32 relocation in X86 and ARM, check if
+    symbol is not local (external) instead of checking if it's global
+
+commit 7362d1e643756893d4b8e9eec0f0f22f89082a2d
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Fri Mar 9 09:28:56 2012 +0800
+
+    Fix arithmetic error in MIPS helper_CalcAHL.
+
+    Fix helper_CalcAHL section offset added to avoid arithmetic error by
+    the comment http://code.google.com/p/mclinker/issues/detail?id=20#c24
+
+commit feaf13d60030aaf1ec4a719b53c5a7670f8fa436
+Author: luba <lubatang@gmail.com>
+Date:   Thu Mar 8 17:36:49 2012 +0800
+
+    clean up code.
+
+commit 29ba42e4513ee8e9ff9317cdca359d96c449f12c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Mar 8 17:28:37 2012 +0800
+
+    Fix a bug - In OutputRelocSection, not to use iterator as a boolean
+
+commit c3a62be7ffce3f652bab64785b5462c05276d135
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Mar 8 11:09:24 2012 +0800
+
+    Fix a bug - Modify X86RelocationFactory
+
+    The dynamic relocations which relocating GOT entry,
+    their type may be R_386_RELATIVE or R_386_GLOB_DAT
+
+commit ea5c2032f569376f8d927cfe10ad0eb9119831f7
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Thu Mar 8 00:44:41 2012 +0800
+
+    Fix AHL HI-part value in MIPS AHL calculation.
+
+commit efd979162595780f5f1d15bd071ae8b715c5c68a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Mar 7 22:10:21 2012 +0800
+
+    Fix a bug where applying wrong value to PLT entries.
+
+commit 9d38ed3a0b946a3d100edf4206c71db5528fc92e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Mar 7 20:33:56 2012 +0800
+
+    Fix a bug - The dynamic relocations which relocating GOT entry,
+    their type may be R_ARM_RELATIVE or R_ARM_GLOB_DAT
+
+commit af4263eff50dc4fc0185f9bd3cbea7ededc72425
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Mar 7 07:42:17 2012 +0400
+
+    Cleanup the code. Remove obsoleted FIXME notes.
+
+commit a15ce7547bf10d2d36efbac0d7b1f732531b0532
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Mar 5 14:18:33 2012 +0400
+
+    Remove redundant code. MIPS local GOT entries cannot be dynamic. MIPS
+    global GOT entries are always dynamic.
+
+commit 2d66da2594d9c0d7a9039199855a89f6df7b2594
+Merge: 7945be9 bd8e77f
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sun Mar 4 17:52:00 2012 +0400
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 7945be9fa81db1bc83e36cfd9a48a2a743b4ef4b
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sun Mar 4 17:26:15 2012 +0400
+
+    Fix a bug in the R_MIPS_GPREL32 relocation handling.
+
+commit bd8e77f50d2366289d72531453bb4b3d82eff7ac
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Mar 2 13:50:07 2012 +0800
+
+    Refine code. Pass more specific GNULDBackend to ELFFileFormat instead.
+
+commit 21d1e845be3d83f22c9b0795bcbe76a7e7b9b08b
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Mar 2 11:17:17 2012 +0800
+
+    Return the number of bytes being written in leb128::encode().
+
+commit 46a42e8f46a4153294ddc19afa45e212599e5193
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Mar 1 15:39:11 2012 +0400
+
+    Emit MIPS .rel.dyn entries for local symbols.
+
+commit 692a9dbea99d575a61d9f8dc96813de91702eed5
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Mar 1 14:52:47 2012 +0400
+
+    Use target() and addend() uniformly in all MIPS relocation handles.
+
+commit 01cb37e11941d5cad49843872d2fdae51cf11075
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Fri Mar 2 01:34:37 2012 +0800
+
+    Fix a typo in README
+
+commit 6a5e7296d267366f0a738aab2d3bd39919ef68fd
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Mar 1 21:14:36 2012 +0800
+
+    Set the align field in output LDSection.
+
+    For output LDSection,
+    1. the alignment is initialized in the initialization function of
+       "FilfFormat" or Target Section
+    2. the alignment is also updated when merging sections if needed
+    Then we can use its alignment constraint in Layout::layout() directly.
+
+commit d2f094c84b419254f163c63d53346245d47ccc6a
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Mar 1 21:26:10 2012 +0800
+
+    Fix a bug - use the value from -mtriple when possible.
+
+commit 9413eacd135be46d5d43cb7a42fff3b1bab33ef6
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Mar 1 17:35:51 2012 +0800
+
+    Update optimized/Makefile.am
+
+commit f75e059b3bf05a2bc5f3832a83e54f261d06d17e
+Author: luba <lubatang@gmail.com>
+Date:   Thu Mar 1 16:17:27 2012 +0800
+
+    Refine README - add the steps to download and compile clang.
+
+commit 6c0fcd2e7aadddeaa856994897a9e5a5ffc36345
+Author: luba <lubatang@gmail.com>
+Date:   Thu Mar 1 11:59:13 2012 +0800
+
+    Increase version number. Sorry for the long and large release.
+    In this version, both ARM and X86 Android cases (with CRT) are examinated.
+
+commit 2ffae8a472b1f6f526a5cb8e8245e51a5d618558
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 29 23:57:41 2012 +0400
+
+    Add missed files for MIPS target testing.
+
+commit 79f618678fcc25884359cef66ce5e6b41df60636
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Mar 1 10:37:46 2012 +0800
+
+    Fix a bug - update addend of the relocation against a section symbol
+
+    Add updateAddend into ARM/X86/MipsLDBackend.
+
+    For the relocation which againsts a section symbol, its addend
+    is supposed to be the offset in the section. This offset should
+    be updated after section merged.
+
+commit ee10db85d63962f08152a5c89a94a54a74a302ed
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Mar 1 10:37:17 2012 +0800
+
+    Update golden model files for ARM and X86.
+
+commit 9a3e5b180107e7a8ca3eb2c21da6d766dd50b851
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 29 06:55:41 2012 +0400
+
+    Add Plasma test case for MIPS target platform.
+
+commit db2dc667e6e07e3f41be496f1653e249f75dba47
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 29 18:17:49 2012 +0800
+
+    Refine format.
+
+commit 5b8ca2e10aeb5f1bf609ebdedc372db09a97a3ee
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Feb 29 13:50:08 2012 +0800
+
+    Handle the alignment of common symbols in X86GNULDBackend
+
+commit 47a6a79752d9cf061757f5e05dc2da3de97f294f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Feb 29 11:36:23 2012 +0800
+
+    Fix the value applied to PLT1 entries.
+
+    According to the order of .got and .plt,
+    we should use different ways to calculate the values of PLT1 entries.
+
+commit b49129b899bcf88c8d76f35aaeb3805a44b6c7eb
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sun Feb 26 17:22:09 2012 +0400
+
+    Fix R_MIPS_HI16 / R_MIPS_LO16 relocation calculation bug.
+
+commit 2551281f30c53db037b628b128bc887ea053bc36
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Feb 24 19:49:41 2012 +0800
+
+    Update golden model files for ARM.
+
+commit ba2dff7c335ac23eaaf0f70fe999f14275c0de94
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 19:13:00 2012 +0800
+
+    Fix a bug - use virtual fillment fragment to represent zero sections.
+
+commit 7f0459ab6c403775fafb11f95c17e6b42eb08147
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 19:11:52 2012 +0800
+
+    Refactoring - remove pIsWrite parameter in MemoryArea::request.
+
+commit d22cfbc0a372a748990aee94b432d8ca3a6a5e72
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 19:09:33 2012 +0800
+
+    Refine code.
+
+commit 309a3094cf4098cd0ce59f431f8a5752c8a9ddf0
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 19:08:39 2012 +0800
+
+    Refine code.
+
+commit dfea6c724986980f0b47878eb73c6deee0654c1e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 19:07:19 2012 +0800
+
+    Allow MemoryRegion is a virtual, zero memory address space.
+
+commit e90c7108897d441912a0ba648511c199f3da51ec
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 24 12:10:45 2012 +0800
+
+    Read exception and version sections.
+
+commit b36d04682eee8e4f5891d8141b2b8963efe52fc4
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Feb 23 16:09:22 2012 +0400
+
+    Configure .rel.dyn entries.
+
+commit 67f1ffd187742c6ca7827a1bb62866d0570abc3d
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Feb 20 16:05:10 2012 +0400
+
+    Process R_MIPS_GOT16 for local symbols.
+
+commit 775875f83689bdf45f18cb0836e1fa25fb7cf315
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Feb 20 15:56:13 2012 +0400
+
+    Allow to call helper_CalcAHL() for R_MIPS_GOT16 relocation.
+
+commit 97da85f1fcb643f97e14c1bc0ddfe00bf4b5c227
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Feb 16 10:41:12 2012 +0400
+
+    Emit local GOT entries before global ones.
+
+commit cfc393a694d9107d1c3a9fe18a856521115ac13f
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 21:07:12 2012 +0800
+
+    Fix a bug. Fix the typo for DT_INIT_ARRAYSZ and DT_FINI_ARRAYSZ in ELFDynamic.
+
+commit 95d864a8e4d928dde6d2490827694558c6249358
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 21:05:14 2012 +0800
+
+    Fix a bug. Correct the section kind and output section order of .eh_frame
+
+commit d0d46c5618a397154ae87bfc4f6b572e194b0133
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 23 18:18:12 2012 +0800
+
+    Fix a bug - ELFObjectReader should read Exception and Version sections.
+
+commit 6f0cfd0ee056b8ffdb39f98630e072a44530de38
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 17:44:23 2012 +0800
+
+    Initiate MCAlignFragment emmision support in ELFWriter::emitSectionData()
+
+commit 4bcb041764e509af45b0fab47c5e0d0fc931f1f7
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 16:34:54 2012 +0800
+
+    Handle alignment issue as finding FragmentRef and deciding section offset.
+
+commit 310c12126e9ac5e3ff9bb642729e1fe041ec4cd2
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 16:12:23 2012 +0800
+
+    Use Layout::appendFragment() for mergeable sections.
+
+    Currently we changed to use new API as
+    1. reading Regular sections and BSS sections from input objects.
+    2. allocating common symbols in BSS sections
+
+commit 3739e4217e45fbb6781c184e1b90d240c7b8133f
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 16:06:01 2012 +0800
+
+    Add API Layout::appendFragment().
+
+    To handle alignment in section merging correctly, we need to preserve input
+    alignment constraint. For mergeable sections (e.g., .text, .data, and .bss, ...)
+    from input objects, we should use this new API to append the fragment to the
+    associated MCSectionData.
+
+    As for the backend part, there is no need to change the used API.
+
+commit ade62d0450729561944699f599b22e64f6756626
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 16:03:17 2012 +0800
+
+    Set up the alignment constraint of input section in ELFReader.
+
+commit d797fa0a4a09cc5ae4689e2c592ccc5758235b6e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 16:02:45 2012 +0800
+
+    Add a field in LDSection for alignment constraint
+
+commit cd346eff71145785b1fb96363756452b6edf79c5
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Feb 23 17:27:18 2012 +0800
+
+    Remove the const-ness from ELFReaderIF::readTargetSection.
+
+    Target-specific section is usually associated with a specialized
+    object which is managed by the target backend. And during the
+    read, it processes the bits from the input and may changes the
+    state of the associated object in the target backend.
+
+commit d423039e0a1bdf05425a1d236ed96d24414cbbd8
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 23 16:49:05 2012 +0800
+
+    Fix a bug - exception section should be able to be relocated.
+
+commit e565d30787176f67a1cfaeb35a85000c982a65bc
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 23 13:44:43 2012 +0800
+
+    Enhance warning messages.
+
+commit 8b9fbaf526e2edcbd59da1a483181979ac6ae5da
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 10:13:37 2012 +0800
+
+    Code refinement.
+
+commit dd3c5ab939a607c5fc538a6875f3a7f2d52a9e1b
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 09:51:31 2012 +0800
+
+    Fix a bug. Correct the way to calculate the file size of a ELF segment.
+
+commit 71d1bf7ae0dad888885bd46113e3c61f4d186436
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 09:42:52 2012 +0800
+
+    Fix a bug. Correct the offset of a section which is right after BSS section.
+
+commit 776eba0e3317ff4b29b91d04c19dd21b2a89db4d
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 09:39:12 2012 +0800
+
+    Remove sect_iterator in mcld::Layout
+
+commit 65371459a7251f00361cb31aa655d43511432b5b
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 23 09:35:34 2012 +0800
+
+    Refine code and comment.
+
+    It should be more clear to set output section indices after sorting section order.
+
+commit 90ceb06ca53afda34504e048f10b9be50ff0ace3
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Feb 22 18:42:36 2012 +0800
+
+    Thumb relocation note.
+
+commit 4681126a39cdfe435b6f2767a8fad98fbee57d35
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 22 15:06:49 2012 +0800
+
+    Remove handling 64bit backend in MipsGNULDBackend::emitDynNamePools
+
+commit 4ca129cb8ac7fdbfe71a72d3cfe2e19fc524273f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 22 14:30:59 2012 +0800
+
+    Add a HashMap into GNULDBackend to map symbols to their ouput symtab index
+
+    1. Add a HashMap m_pSymIndexMap, maintain the map when emitDynNamePools
+       and emitRegNamePools
+    2. Add an API GNULDBackend::getSymbolIdx to get symbol's index. This
+       API is used when emitRelocation. This API takes the place of
+       original LDContext::getSymbolIdx.
+
+    Now only the input symbols will push into LDContex's symTab, the
+    output symbols and the index maintained in m_pSymIndexMap of GNULDBackend.
+
+    When emitRelocation, we get the symbol's index in ouput symbol table
+    by asking the HashTable, this can reduce time on searching from the
+    vector and avoid string comparison.
+
+commit fca4108f643edeb74d163d9b7ddb2871b3a3dc1f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 22 14:21:17 2012 +0800
+
+    Add API - LDContext::addSymbol
+
+    Add input symbols into SymTab in LDContext by this API instead of
+    pushing into the SymTab directly.
+
+commit 1ff48e8f60c04334c284bd76dff99ce02bb1de20
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Feb 22 12:16:38 2012 +0800
+
+    Separate the implementation of LEB128 from header.
+
+    No functionality or API changed.
+
+    Fully specialized template functions are just like the normal
+    functions. It doesn't depend on the template parameters any more.
+    Therefore, you should declare them as inline functions in header
+    or define them in a .cpp in order to not violating the ODR. And
+    we choose the later.
+
+commit 12732aea6e1844c07bc066681bfde8792bf4f56f
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 22 12:02:05 2012 +0800
+
+    Refine warning information.
+
+commit ab8b32751554b817d3920375557c06106b505fc2
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Feb 22 09:30:47 2012 +0800
+
+    Allow signed char stream to be passed to LEB128 APIs.
+
+commit b03e65f660416f0d34ec3770b34fcf057a294e27
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 23:01:36 2012 +0800
+
+    Add special section support in ELFFileFormat
+
+    @ref "Additional Special Sections," ch. 10.3.1.2, ISO/IEC 23360 Part 1:2010(E)
+
+commit 6f429e27a868513bab6164d85f3e2af181c1857d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 23:00:26 2012 +0800
+
+    Fix a bug - MCLinker should not set the index of output LDSection.
+    Instead, Layout should set up the index of output LDSection.
+
+commit 18cb084376bbe4589e0457265913821aa140400f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 22:59:39 2012 +0800
+
+    Handle Exception and Version section kind.
+
+commit 455bc970e42ff12b3ed9dc0aed05d8489bbd0d1f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 22:58:51 2012 +0800
+
+    Fix a bug - initialize LDSection::m_Index.
+
+commit 0c51de0dedac8f0f37f6e406255284a375b3e2a8
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 22:57:34 2012 +0800
+
+    Add new LDFileFormat::Kinds - Exception and Version.
+
+    Exception is used to identify a section for exception handling.
+    Version is used to identify a section for symbolic versioning.
+
+commit 8f0ae100a435e4b53943dbe2636a43e9e7fd80b6
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 22:55:54 2012 +0800
+
+    Complement lost ELF definitions in LLVM/include/llvm/Support/ELF.h
+
+commit c2754ddbdea85ad0460dd6e67e5d8d6ff549a1de
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Feb 21 19:58:24 2012 +0800
+
+    Fix typo.
+
+commit e1454f9d24b40e0784ef603bf844d87bad465054
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Feb 21 19:54:48 2012 +0800
+
+    Rearrange files for regression test.
+
+commit e4f8b8bf06c56d012146c363bed24f7125c3d032
+Author: luba <lubatang@gmail.com>
+Date:   Tue Feb 21 17:01:56 2012 +0800
+
+    Add ISO/IEC 23360, LSB support.
+
+commit 4b58952253ff5b980c61837fe4f97217ae5b09ca
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Feb 21 15:06:10 2012 +0800
+
+    Change the decoding function APIs of LEB128.
+
+    Original: IntType decode(ByteType *pBuf, size_t *pSize);
+
+    Revised: IntType decode(const ByteType *pBuf, size_t &pSize);
+             IntType decode(const ByteType *&pBuf);
+
+    Also fix bugs in encode<uint32_t> (wrong mask.)
+
+commit f00151375dd50bcbe34ab6971933e8a932e76914
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Feb 21 13:49:31 2012 +0800
+
+    Load the input file content into memory after open.
+
+    Almost every byte in the input file (e.g., input object file) will
+    be examined during processing. Enforcing kernel to load the entire
+    file into memory right after open could generally reduce the
+    number of page fault generated.
+
+commit 7835521c2893df4650c46263f8ad8aa047d0a396
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Feb 21 12:11:19 2012 +0800
+
+    Fix HashTable - Identify ambiguous methods by adding an anonymous parameter
+
+commit a1b98456c9978f4b47842ac91912a9131db4fa0c
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Feb 21 11:56:03 2012 +0800
+
+    Use more correct type in template class SizeTraits.
+
+commit 706e8c41dfeab68417fb7f90e7815ea7e053e935
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Feb 21 11:44:51 2012 +0800
+
+    Add utility functions to support LEB128 encoding.
+
+commit 94b6e95182389993c807cb473b9ca2de7556cb7d
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 18:14:04 2012 +0800
+
+    Add unit test for GCFactoryListTraits.
+
+commit 2a19a2a89b60d18cc63e31cfe98ed41079105b92
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 17:31:37 2012 +0800
+
+    Format tabs with some typos fixed in Makefiles.
+
+    No functionality changed.
+
+commit 1b7be3e5098d852dc726f6d41a887c13ed9b9593
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 10:18:54 2012 +0800
+
+    Use LinearAllocator for input Relocation.
+
+commit 8eb7dc5a8f50b6826de4cd3172bc4973ccbfd672
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 10:13:37 2012 +0800
+
+    Add GCFactoryListTraits.
+
+    GCFactoryListTraits provides trait class for llvm::iplist when
+    the nodes in the list is produced by GCFactory.
+
+commit ec8c9322c12cb68aeb5c84bd7b77214c1544e7e4
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 13:47:13 2012 +0800
+
+    TargetLDBacked should have longer lifetime.
+
+    TargetLDBacked contains target RelocationFactory which holds the
+    allocation of the Relocation entries a target uses during linking
+    (i.e., MCLinker::m_RelocationList.) If the TargetLDBacked object
+    was destroy first, it will cause the relocation list in a valid
+    object however its allocation has been corrupted.
+
+commit cba8168c37579a45322bd1b99c3e574d77763118
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 17 10:06:39 2012 +0800
+
+    Let RelocationFactory inherit GCFactory again.
+
+    This reverts commit 6ffb8df05e1c0859fd2e74217b645ec3466e457f
+    "Change Relocation member variable m_pTargetData type from DWord* to DWord"
+
+    and commit f2e77a332a448cb1ac0ac2f30c599c7f4987814b.
+    "Let RelocationFactory not to inherit to GCFactory"
+
+commit 84634224e89ab32ec1c482de943359ce0f31cd5e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Feb 16 13:56:35 2012 +0800
+
+    Use llvm::ELF to specify the namespace of ELF
+
+    for building MCLinker on FreeBSD machine.
+
+commit f5543c18085dcafc8740473bf2bce9bc107f3ed0
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 17:26:41 2012 +0400
+
+    Do not reserve GOT entry twice.
+
+commit 7d5e0e96d6687522fd57c06584d119c3d2948f62
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 17:09:52 2012 +0400
+
+    Save calculated AHL value between R_MIPS_HI16/R_MIPS_LO16 relocations.
+
+commit 4602029c2f9b0992f7ed5391ab7f43f289f13fca
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 17:04:48 2012 +0400
+
+    Replace duplicated code in the MipsGNULDBackend::emitDynNamePools() routine
+    by getOutputFormat() call.
+
+commit 1263f542c4afa34986c5c44e88800856309719a7
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 16:59:51 2012 +0400
+
+    Emit dynamic symbols referenced by GOT at the end of .dynsym section.
+
+commit 312d21fe5664cae5d7abd2a677683d547f0ab791
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 16:54:01 2012 +0400
+
+    Save local/global symbols referenced by GOT in the m_LocalGOTSyms/m_GlobalGOTSyms arrays.
+
+commit ebc1e5c938c5e3f6497c70f9f165063c3f2d0981
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 15 16:45:41 2012 +0400
+
+    Make hash_bucket_count() and isDynamicSymbol() the GNULDBackend class memebers
+    to reuse in the GNULDBackend successors.
+
+commit 7933aef3fc78c35a1cbf9dd98d55605bf874a8d7
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Feb 15 18:02:19 2012 +0800
+
+    Fix bugs in group section handling.
+
+    1. set up the link section of group sections as symtab section
+    2. correct the code to check if discarding a relocation section
+
+commit 05deb106a3b706c74e3f11cc64e815f7f40beb06
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 15 14:06:46 2012 +0800
+
+    Refine optimized compilation options.
+
+commit 2b75acf4db917ed853cee8457d2c8618c6719daa
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 15 14:05:59 2012 +0800
+
+    Enhance performance. Eliminate the number of MemoryArea::request.
+
+commit 227e94232b776ce9b5e5d550900fce46b140a6b3
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 15 14:03:59 2012 +0800
+
+    Refine group section code.
+
+commit e0e0dee53da2c3bbd4cf1fe80e10012b565ddffa
+Author: luba <lubatang@gmail.com>
+Date:   Mon Feb 13 14:08:26 2012 +0800
+
+    Refined optimized compilation options.
+
+commit 127607018a29c29cd4ae7649015852d53382f777
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Feb 15 14:03:14 2012 +0800
+
+    We can use diff only.(Return value.)
+
+commit 5a2927a9a63d088ebde7b13a01d0f83a319d06a2
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Feb 15 13:41:54 2012 +0800
+
+    Copy bitcode to individual folder.
+
+    Copy to same file will cause error when multithread.
+    E.g. When A thread is running plasma_arm and reading the bc, another
+    thread is running plasma_x86 and copying the bc, plasma_arm will fail.
+
+commit f702adaffc4649915e7c3bc3684d1ac1780ebc33
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Feb 15 13:37:53 2012 +0800
+
+    Fix typo. Remove unused file.
+
+commit e066a3c508d2ef6ab408a7845f403d97d4754cda
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Feb 14 16:45:55 2012 +0800
+
+    Fix a bug - When scanRelocation, Weak and Common symbol should do
+    scanGlobalReloc. While scanGlobalReloc handles all the external
+    symbols but not only for symbols with Global binding.
+
+commit ad6732f718a0b21f53d338e24f0fcacf467f9898
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Feb 13 21:06:13 2012 +0800
+
+    Add group section support.
+
+    The shared objects of Quake Android w/ ELF group section are verified on both
+    x86 and arm target.
+
+commit 8a4d59bc9c591d8eaf8a6b6b96a47c2e73a79dcf
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Feb 13 20:50:06 2012 +0800
+
+    Remove Relocation member variable m_Parent
+
+commit 6ffb8df05e1c0859fd2e74217b645ec3466e457f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Feb 13 20:20:31 2012 +0800
+
+    Change Relocation member variable m_pTargetData type from DWord* to DWord
+
+    To reduce memory footprint, let Relocation entry holds the TargetData
+    itself instead of using GCFactory to allocate a memory space for TargetData.
+
+commit f2e77a332a448cb1ac0ac2f30c599c7f4987814b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Feb 13 20:14:03 2012 +0800
+
+    Let RelocationFactory not to inherit to GCFactory
+
+commit 758c2c1c49fcf0678c0720ecd58119d2b236106e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Feb 13 19:08:31 2012 +0800
+
+    Separate Link and Info from LinkInfo in LDSection
+
+commit 2e34545e28918e18383061f2d5352b57d526f3b0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 13 14:30:00 2012 +0800
+
+    Add regression tests for the Android examples on X86.
+
+    Running the regression tests for X86 by binary file comparison.
+    Remove them when MCLinker has more test cases for X86.
+
+commit a80b5d3532770202298b2eadec4d417a5586310d
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Feb 11 07:57:40 2012 +0400
+
+    Move the const GOT offset to the helper functions.
+
+commit 13addedc0afe67f89ec677219098705ec4390bfa
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Fri Feb 10 03:31:13 2012 +0400
+
+    Adjust G value using _gp_disp offset.
+
+commit aa41a8c624b9f5ce936555b15940e37d524bef19
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 10 17:47:05 2012 +0800
+
+    Add support for target-dependent section.
+
+commit 76e0a0c7cbd6edc5c2e399e4320b3372f3a1debf
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 10 10:47:39 2012 +0800
+
+    No need to specify -dB for linking native files.
+
+commit 74deea14a47458276f5e8d6ca465170f480e7575
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 10 09:08:34 2012 +0800
+
+    Drop the dependency of llvm::Module in SectLinker.
+
+    Change the API of the constructor of SectLinkerOption. We now read
+    the library dependency from command line. Also modify the test such
+    that `make check' still works after this commit.
+
+    MCLinker requires both native input and its associated bitcode (
+    via -dB option) for linking. MCLinker treats the input bitcode as
+    linker script.
+
+    More specifically, given a bitcode module, MCLinker only need the
+    dependent library information within the module which can be
+    assigned via command line option "-l." Moreover, MCLinker spends
+    90%+ time on decoding the bitcode when performs linking.
+
+    This and subsequent commits relax this requirement.
+
+commit 5df66059bdfc6124454269148a755e953380b833
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 10 10:54:01 2012 +0800
+
+    Fix logic bug.
+
+commit 1a835f684ea2e8cd3a6093452c2e4df83098c6c8
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 10 03:29:03 2012 +0800
+
+    Fix build on Mac.
+
+commit ec6e41d254b2075e4c77e9ddae0887ad18a2ee36
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Feb 9 20:24:10 2012 +0800
+
+    Use the proper variable.
+
+commit 7973e64e61ee5726585b47317b965f2e705d2cdb
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 17:43:02 2012 +0800
+
+    Fix a bug - user, OS, and processor specific section types should be LDFileFormat::Target sections.
+
+commit 6b6cc27f922bb29d97067050af67a81949eb832e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Feb 9 13:55:15 2012 +0800
+
+    Refactoring - Add getOutputFormat to ARM and X86LDBackend
+
+commit 6d22b22a75a27d042598c0fd20e19744e0c0ce86
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Feb 9 13:38:24 2012 +0800
+
+    Refine the code.
+
+    Reduce the calls to map insertion in MemoryAreaFactory when an
+    entry already exists in the map.
+
+commit e9c111d26aa52658c1631aaff527657310b0c9ea
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Feb 9 11:27:23 2012 +0800
+
+    Refine error message in ARMRelocationFactory
+
+commit 3700ecf0983d2b33d7ea215df3c7e52ae7b0e155
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Feb 9 10:01:08 2012 +0800
+
+    Add a regression test for Quake2 on ARM.
+
+    Currently running the regression test for Quake2 by binary file comparison.
+    Remove it when MCLinker has more test cases to ensure that Quake2 will work.
+
+commit d745e9af87248e14734e8e7755c9002d7dd045af
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Feb 8 11:41:59 2012 -0800
+
+    Allow R_386_PC32 in scanGlobalReloc if not preemptible
+
+    We allow R_386_PC32 only if it isn't preemptible.  Otherwise we will
+    generate writable text section in output.
+
+commit 8a165afd2271b9ccd362bfa6895265d38ba6a121
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 02:37:45 2012 +0800
+
+    Fix a bug - we should check visibility and change symbol's binding during writing.
+
+commit a154003e4e366ec86f0d316fc0b7094983bcfb5f
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 02:31:23 2012 +0800
+
+    Refine code.
+
+commit d3a172595bd3bea111ca8e41e7bbbee872a73035
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 02:30:43 2012 +0800
+
+    Fix a bug - We should not change the binding at reading.
+
+commit 3011c9bb0b22ab09bba0d436daba715c3f2232de
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 02:29:33 2012 +0800
+
+    Fix a bug - When the symbol is old, and its category is changed, MCLinker should
+    arrange the symbol.
+
+commit 9b6e3c2eda00db383efb2dc80230d3e23d77d50a
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 9 02:13:29 2012 +0800
+
+    Fix a bug - when a symbol is forcefully added into local category, all other categories' begin and end should be increased.
+
+commit f0ef47e8d43bdcf3547288e7352121f9a5a90deb
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:08:12 2012 +0400
+
+    Check _gp_disp symbol existence before access it.
+
+commit daca6babfab7111e5fd8b764ae4ced79d5f8205c
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Fix MIPS_GOTSYM value.
+
+commit 9f220590f3de9cab18805e074c7f541c1face81d
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Fix bug in the NipsGOT iterator.
+
+commit ee7ce7727d57b5cd5d884b8e487be66a88a027ad
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Fix a bug in the MipsGOT::reserveEntry() code.
+
+commit 1414dcde776932e2def6422a316d1d22b7043afb
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Refine MipsGNULDBackend::scanGlobalReloc() code.
+
+commit 4ff71f8439e66c25230c6828381be3945b5f1249
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Reserve GOT entry for non-local R_MIPS_GOT16 and R_MIPS_GOT16 relocations.
+
+commit a06fdce36088665988f233b238e593f0b4db3783
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Reserve GOT entry for R_MIPS_GOT16 and R_MIPS_GOT16 relocations.
+
+commit df254304c75b183565e3ac7adc7feb452241d46f
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Implement R_MIPS_GOT16 relocation for non-local symbols.
+
+commit 52f1720b66f8fb743ad3a1101f382044f14aea99
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Implement R_MIPS_CALL16 relocation.
+
+commit 7a2378c847fbccc17ec7818113de36232e4ead9f
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Fix a typo in the function return type name.
+
+commit a1a47fd7486ee6f19c724c3757d139f8a142d415
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Implement R_MIPS_GPREL32 relocation.
+
+commit 883ea5441cc05e1787fbae17a9e6d78f59d347f1
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Implement R_MIPS_HI16/R_MIPS_LO16 relocations for the _gp_disp.
+
+commit 28a23a68d5a6c386d754e0bffab966fb27567bca
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Implement R_MIPS_HI16/R_MIPS_LO16 relocations (except _gp_disp).
+
+commit 0e1c6bcb8469bae9ee88fe2d77b61096080fe9cf
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Fix typo in _gp_disp offset.
+
+commit 62ab473c9f6365ffd9378b3d6d4c6c627a07fbb7
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Refine reservation type constant values.
+
+commit c2ee7d13534683ce18d236172e88d3b0de9a6b4a
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Add helper function to setup .rel.dyn section entry.
+
+commit 84fff7fbc2f453075a769375548c95e49bdc8dc6
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Remove handler for R_MIPS_REL32 relocation.
+
+commit faad90e5fd5ef52bdee5e886ee1e85989e23e3af
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Add flags to mark requests for GOT and .rel.dyn sections entries reservations.
+
+commit 602c0136c61e54723b5fe9ecc3e96eb66fdbe359
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Add methods to access .rel.dyn section representation.
+
+commit 41488b02c69fcbdbb54d6c02afa39c83a8dff87f
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Define _gp_disp symbol.
+
+commit 20b353a6fbaf111c50bdf6719c93204d9d285ad4
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Move calculation of the MIPS specific dynamic section entries to the
+    separate functions.
+
+commit 5d0881a53692a009c4cbcf4e1484a08ebaea632b
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Reserve one entry in the GOT. Do not support gnu extension.
+
+commit 9516ec8e00a1795de88ab5216be83f1a5148d1bd
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Write correct value to the MIPS_SYMTABNO entry.
+
+commit 0d4f4594eba1b4f8d4581366ae8799260e9c75b2
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Pass non-const reference to the MipsRelocationFactory to relocation
+    processing functions.
+
+commit d187eb62e4a279ade7e5c0f35ca250018d2aabfa
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Create reserved entries in the GOT head.
+
+commit 471b08d6347342c7bbce57a896cc260e13ad12c2
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Synchronize code with ARM implementation.
+
+commit 40ef97d600f82d95726a2b75855bfdfbef1a4e33
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Do not use std::auto_ptr to simplify the code.
+
+commit 2385d784c99a87250beb69a003ae061aa9b6e578
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Rearrange MipsLDBackend class member functions.
+
+commit 9dfd8cc0712d502b90557c1f3a9d30e7a73e2319
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Reserver and apply MIPS specific dynamic section entries.
+
+commit 1a918712e467830dcdc433656964e32305ef5b8d
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Refine local variables names.
+
+commit 1214910f8a141ddac21b9c7a596bc8f47849f56b
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Feb 8 14:00:00 2012 +0400
+
+    Pass reference to the MCLDInfo to the MIPS relocation processing
+    functions.
+
+commit 679c2440ddecb8072276ea2c44a8262d462f6c3a
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 8 17:46:41 2012 +0800
+
+    If a symbol is absolute, it should be a global symbol.
+
+commit 56cd3d6ceefb072cddbed6bf6543ac37a871fb23
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 8 17:46:12 2012 +0800
+
+    Enahnce error message.
+
+commit 8ff5d1cdeed63bb3261c9b83f1535e4ff0577cfb
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Feb 8 17:35:08 2012 +0800
+
+    Add a regression test for Plasma on ARM.
+
+    Currently running the regression test for Plasma by binary file comparison.
+    Remove it when MCLinker has more test cases to ensure that Plasma will work.
+
+commit 31c88c45e05e8a1f8ea1fccd5693e8d573127656
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 8 17:16:19 2012 +0800
+
+    Fix a bug - MCLinker should not forbid defining a section symbol.
+
+commit 771a838be86aeed4534d61ca629cb5b08d33824b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Feb 8 17:01:30 2012 +0800
+
+    Reset errno to zero where the value of errno may has changed.
+
+commit bd72555be4517d60efe2af63d4cae0760cff279e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 8 15:43:17 2012 +0800
+
+    Fix a bug - we should finalize target symbol first.
+
+commit 68ab790946559f18f70ea508a9833832284d6312
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Tue Feb 7 09:21:00 2012 -0800
+
+    Handle R_386_PC32 in scanLocalReloc
+
+    We don't allow R_386_PC32 in scanGlobalReloc since it results in
+    writable text section in shared library and we don't support executable
+    yet.
+
+commit 834a16a16ba848e40ff68c19de6e7fd85f6ef5aa
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Feb 7 11:07:25 2012 +0800
+
+    No functionality changes.
+
+commit e6cadd10c455ad3e84c76a4bd847dcd6d586d0bc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Feb 7 09:44:26 2012 +0800
+
+    Change the destination of cp for separate targets to use the same bitcode file.
+
+commit fcbdbad05f6efb2316baaf323468c0fce6d75afd
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Feb 7 09:34:00 2012 +0800
+
+    Fix a bug - In Relocation::symValue, check if symbol has fragmentRef if it's a section symbol.
+
+commit b619f47e3748a7bb374c08ea1797a1195e2d308e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 21:12:10 2012 +0800
+
+    Get rid of the use of GNU objdump and strip in regression tests.
+
+commit a780fa6b61a5ee722f5c339736dc15b59a2a6cf1
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 16:47:29 2012 +0800
+
+    Strip the source file path from the object file for Quake regression test.
+
+    By default, Object files contain the path of the source file,
+    This will make the comparision of binary files fail.
+
+commit 6a467f73017bc1bb37a7820b14e6b1e182b25459
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 16:46:15 2012 +0800
+
+    Add missing files for the regression test of Quake.
+
+commit 011856411f364126dcd06ac0a38d27cdb0a75244
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Feb 6 15:25:44 2012 +0800
+
+    Fix a bug occurring in merge operation of InputTree.
+
+commit 5678e8e436192dcfbdb9225366d46afb56254f14
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Feb 6 15:21:30 2012 +0800
+
+    Fix a trival bug of GNUArchiveReader.
+
+    We use the file name instead the symbol name when opening an external file.
+
+commit 0c1303641bf9a65cc13923fe259a476716626d24
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jan 31 15:54:33 2012 +0800
+
+    Enable the functionality of reading thin archive.
+
+    Additionally, make the coding style consistent and refine the comment.
+
+commit 4b31b16b29ee16a79057412209e4770b7cb75a8c
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jan 31 11:26:26 2012 +0800
+
+    Correct the constructor of GNUArchiveReader.
+
+commit 240babefe0ad85f71f0d3a388c72e079438cbc2a
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jan 31 10:29:25 2012 +0800
+
+    Refine the commit of GNUArchiveReader.
+
+commit a01335007c3aa7298761cfeb3868a8e6047cde84
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 14:28:02 2012 +0800
+
+    Add a regression test for Quake on ARM.
+
+    Currently running the regression test for Quake by binary file comparison.
+    Remove it when MCLinker has more separate regression tests.
+
+commit 3b374c6bd177df731a32281a465484c0a33ffaff
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 14:17:36 2012 +0800
+
+    Move the regression tests of Relocation to test/ARM/Relocation.
+
+commit 001e7b3d1bf806b36e21ad3a7f4a04e5d703852e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 14:12:54 2012 +0800
+
+    Add a regression test for ARM got0.
+
+commit 6d71742e9d57608d247914e74d1304887155e19c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Feb 6 14:08:17 2012 +0800
+
+    Add a regression test sample to demo how to use variables with FileCheck.
+
+commit 0c134b8d22b6b0bdf187ca42eba4ea7886c5c8cb
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 3 22:44:08 2012 +0800
+
+    Fix a bug in PathCache.
+
+    Missing the assignment of the parent path for the first entry when
+    read it in open_dir().
+
+commit 5345f6c466b7b08c9ebd2ee468cbec82a55d9cc8
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 18:07:10 2012 +0800
+
+    Fix a bug - MCLinker should only add new symbols in the output symbol table.
+
+commit e5e842f5ef4120d735682d036b384a6a9fdd7b02
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 11:19:23 2012 +0800
+
+    Increase version number - Quake2 Android is linkable on ARM Android.
+
+commit 69f99cb08cd9ab9c711191919f0141390638d913
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Fri Feb 3 12:13:45 2012 +0800
+
+    Refine the comments.
+
+commit 82d5f80792a60746734e81d4190c7ecad9cb4e0f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 02:52:18 2012 +0800
+
+    Enable TargetLDBackend::allocateCommonSymbols()
+
+commit 19bf25970b446b110373a62eb0ee15c85557e274
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 02:48:27 2012 +0800
+
+    Add allocateCommonSymbols to TargetLDBackend.
+
+    Although different formats allocate common symbols in different section, but
+    all formats have steps to allocate common symbols. So, we add a new API
+    TargetLDBackend::allocateCommonSymbols() and implement it in different targets.
+
+    Some targets, such as Mips and X86_64, have different need to allocate
+    common symbols. Their LDSection, the definition of common symbols, etc. are
+    very different. So, we leave the implementation of allocateCommonSymbols() to
+    the lowerest target backends.
+
+    In ARM and X86, a basic allocation is implemented. But Mips needs small symbol
+    support.
+
+commit 13b6580af224ec8d33880812e957fb98c8c0094c
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 02:47:19 2012 +0800
+
+    Fix a bug - because there are may different BSS section, we should not fix the name as .bss.
+
+commit 81c4562ece94ef540cc67832bdd9300e7cf50f02
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 02:44:47 2012 +0800
+
+    After allocation of common symbols, all common symbols must move to Global category.
+    So, we add SymbolCategory::moveCommonsToGlobal() function.
+
+commit 2931aa2f26d38f7c4d9c4673ed614a16db431e77
+Author: luba <lubatang@gmail.com>
+Date:   Fri Feb 3 02:44:05 2012 +0800
+
+    Add TLS symbol type
+
+commit 8c337e71d8b6aa7d2791f481296ff6af4fca24a1
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Feb 2 19:37:24 2012 +0800
+
+    Add Group section kind.
+
+    Let ELFReader can recognize group section first.
+    TODO: implement group section support.
+
+commit 5f448bce6fb5c6035d0b3832db9a4c08c2edc3ec
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 2 18:55:15 2012 +0800
+
+    Refactoring - by Simon's suggestion, change the reserve/applyPLTGOT to general reserve/applyTargetEntries
+
+commit cd3459a3959f0a6f22745248436c1b0d16f170bd
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 2 13:59:36 2012 +0800
+
+    Increase the version number - Quake is ready to run on x86 Android.
+
+commit b980efbdd0ce5d45cb64638129f57f829a4d1e2c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Feb 2 10:16:27 2012 +0800
+
+    Refine error message in ARMLDBackend
+
+commit 83d05ff948cfa7ceed5b5fb5f846787bd51dc684
+Author: luba <lubatang@gmail.com>
+Date:   Thu Feb 2 01:00:09 2012 +0800
+
+    Fix a bug - if the symbol is in the output symbol table, arrange it. Otherwise, add it.
+
+commit cd028c67baa8d30ca9c9bbbb32c84d240f0c8d13
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 22:44:45 2012 +0800
+
+    Fix a bug - ResolveInfo in the pool does not mean it is already in the output. We should still add it into the output.
+
+commit 11e74bd8ba338ba7a9c8a2511c8acc330e4f704c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 1 20:41:20 2012 +0800
+
+    Refactoring - using comparison of pointer instead of string compare.
+
+commit 9d266c741ff9ea5f5d4e731facaac739ad0bbb24
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 1 20:33:17 2012 +0800
+
+    Reorder pass 7.a - add standard/target symbols before read and
+    scan relocations.
+
+commit 2642f21bbe8578fc1f72f54578fe17e6aa810045
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 19:57:45 2012 +0800
+
+    Add SymbolCategory's unittest.
+
+commit b5dfaa011bddfacc9ebb95e4923a278ec6267e24
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 19:20:36 2012 +0800
+
+    All reasons of force local should be the same.
+
+commit 99c9f72b76b566b6acef86e4aeae63da10068116
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 19:00:05 2012 +0800
+
+    Fix a bug - If a symbol is existent, we should not add it into output again.
+
+commit cc6ffef4605b544581305cacff7bb2771886f05b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 18:59:17 2012 +0800
+
+    Fix a bug - In Darwin, GCC 4.2 forbit inconsistent template reference.
+
+commit af22c32a6676cd7eb3512a78a6f5cd01dbcc4218
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 17:16:36 2012 +0800
+
+    Change API - MCLinker::defineSymbol<POLICY, RESOLVE>(), add the 2nd template
+    argument.
+
+    Backends request a new defineSymbol() function - the new one can define a
+    symbol, but do not resolve the symbol immediately, just override the existent
+    symbol.
+
+    Therefore, MCLinker add a new template argument - RESOVLE.
+    If RESOLVE is MCLinker::Unresolve, then defineSymbol() defines a symbol and
+    overrides it.
+    Else if RESOLVE is MCLinker::Resolve, then defineSymbol() defines a symbol
+    and resolve it immediately. Just like the old behavior.
+
+commit 572e320a34bdd4603933ae54314b2c121c1d92ab
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 17:14:40 2012 +0800
+
+    Fix a bug - Creating a new symbol should be treated as overriding an old symbol.
+
+commit 1782eb764ac34b8dfb501905a949ddfff6cbedbb
+Author: luba <lubatang@gmail.com>
+Date:   Wed Feb 1 17:13:47 2012 +0800
+
+    Refine comments.
+
+commit 5281d5dbb2081c18ffab6aad14b5413c67237824
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 1 16:19:03 2012 +0800
+
+    Modify API - TargetLDBackend::scanRelocation
+
+    Add a parameter pInputSym which is the input LDSymbol of
+    relocation target symbol.
+
+    We need to update value in relocation place (A value) if it's a
+    ABS type relocation and point to a section symbol. This value
+    should be the offset to the output section. We needs the
+    input section symbol to get the correct output offset if several
+    sections are merged to single one.
+
+commit 421b256fa93912dcdadc3cb28ee15a3719e3257e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Feb 1 15:49:46 2012 +0800
+
+    clean up the code in Layout::layout()
+
+commit e8d6546fd6a39f3f7fbaf9d7a209bddf911508ea
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Feb 1 15:43:12 2012 +0800
+
+    Refine the code - add assert to check if segment pointer is NULL
+
+commit f7095c27f9af7545c5e6301a5ca896d952220694
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 1 10:54:02 2012 +0800
+
+    Fix a bug - For R_ARM_ABS32 type relocation, no need to check if
+    it is function or not in helper_use_relative_reloc
+
+commit 82c5d35e1e3ab0c5eb5cf149ecc20a3c6bef41fb
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Feb 1 10:14:30 2012 +0800
+
+    Refine code.
+
+commit d753d4811dd53af51c6b7e39ef4a596fd0af67f8
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 31 16:16:36 2012 +0800
+
+    Fix a bug - MCLinker should not crash when it's a shared library.
+
+    if we build MCLinker as a dynamic shared library, it will crash when we load MCLinker twice.
+    This is because we use a static local variable in a function.
+
+commit cb593166652d96f05f90804b4039e181a711076b
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Jan 31 15:58:32 2012 +0800
+
+    Fix the types.
+
+commit 71242fae4bb7cb25f304ef77e1316ec3b8c842c7
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Jan 31 15:30:50 2012 +0800
+
+    Clean the code.
+
+    Remove unused variables.
+
+commit 94d18868919ffac706abaac2c7c96149154993fa
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 31 15:02:27 2012 +0800
+
+    refine comments.
+
+commit 822525dc3f1c1d9be6f99aed79996f56a969e5a4
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Jan 31 14:26:48 2012 +0800
+
+    Add basic ARM/ABS32 relocation test.
+
+    For verify relocation, we may need some tool to get the instruction of a
+    given address.
+
+commit 594b934cbedce9c16e885658557f83eb8aa2b5e6
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Jan 18 15:33:39 2012 +0800
+
+    Fix TestSample.o.
+
+commit bbcf2855efffd3932e3516bc630af2b77f907c5e
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 31 14:47:31 2012 +0800
+
+    clean up code.
+
+    For clarity, use incremental addition.
+
+commit 2162ef32bdea1484841b14a0455ab0fa5d4e1eb8
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 31 11:41:06 2012 +0800
+
+    Use isPIC to check ouput type during scanRelocation.
+
+commit 59fd2f8b6db678b4200417fe4a714d5a76cf12f2
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jan 31 10:35:45 2012 +0800
+
+    Avoid summing up sizes of .ARM.attributes sections of input files for output.
+
+    MCLinker uses the .ARM.attributes section of the first input file for output.
+    The size of .ARM.attributes in output is same as the one in first input file.
+    there is no need to sum up size for ARM.attributes section.
+
+    MCLinker will emit .ARM.attributes section in correct way in the future.
+
+commit e834ac1392db08ad7b36b26632ea690d2f5ff73f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 31 10:49:33 2012 +0800
+
+    Recover change - using comparison of pointer instead of string compare.
+
+    Because the GOT symbol will be created after creating the GOT section.
+    We won't gete the pointer of GOT symbol until creating GOT section.
+
+commit bd7730cb5f687d15c6c2db14556ef039183fa9e5
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 31 10:05:05 2012 +0800
+
+    Refactoring - using comparison of pointer instead of string compare.
+
+commit 8d797f5fe21047f8bdfbccf517d60d32d9c7058a
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 31 09:51:53 2012 +0800
+
+    Clean up code - move out create GOT from createX86PLTandRelPLT
+
+commit 787c86546655e3683642f8e159490fe3f35ebeb3
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 31 09:26:32 2012 +0800
+
+    Refactoring - For clarity, replace zero magic value by NULL.
+
+commit 27ace9924d4c527b152778651cf6dcdac9a4c6e2
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:56:11 2012 +0800
+
+    Refactoring - using comparison of pointer instead of string compare.
+
+commit 9f19f0c3af66bc925e3fda66cf918ee412ed4cd6
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:50:15 2012 +0800
+
+    refine comments.
+
+commit 15b9c8ca41cf13230f53353c5ae19bcf138c755c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:46:03 2012 +0800
+
+    clean up the code.
+
+commit 4c7611f090f3baca46568573ed614bfb49b73133
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:43:54 2012 +0800
+
+    Refactoring - For clarity, replace zero magic value by NULL.
+
+commit 801d4ec509e24dd819bfb2bcd3bb6647224ca9dc
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:27:55 2012 +0800
+
+    Refactoring - Move some trivial functions from ARMLDBackend implementation file to header
+
+commit 37e04b69d3c976175dce2a049158dd6bb6159928
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:21:07 2012 +0800
+
+    Refactoring - change the structure of emitSectionData from if/else to ripple if/return.
+
+commit edc03b8cf64f9fb6db777fcf7b5b21fd09f49ddf
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 16:04:56 2012 +0800
+
+    Refactoring - move the details of emission of ARMGOT from ARMLDBackend to ARMGOT itself.
+
+commit fc57a81e73498745db6e9bb1dbfc9a79bb4f89ec
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 15:58:01 2012 +0800
+
+    Refactoring - move the details of emission of ARMPLT from ARMLDBackend to ARMPLT itself.
+
+commit 65b49f4d6e4da078f1e6237dd3e50ce6f0962a28
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 15:44:25 2012 +0800
+
+    Refactoring - auto-variables' names should be lower-case words.
+
+commit cde5fec451a408232244039ead6513d41683ae19
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 15:26:09 2012 +0800
+
+    Refactoring - apply GOT and PLT should be done during doPostLayout(), not during emitSectionData().
+
+commit 6c5b7068bfaf560ef64a255cc0236109e0afc872
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 15:06:35 2012 +0800
+
+    Refactoring - select file format first. This can remove many duplicated code.
+
+commit 33eab96e81b3598c026076cdbf0d300fb7fd2eff
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 30 14:57:44 2012 +0800
+
+    Refactoring - in order to keep encapsulation, we should use Output rather output's type as input arguments.
+
+commit 39e6850693a2960a3dec84f9ce674c21ac429ba9
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 30 14:10:04 2012 +0800
+
+    Avoid const cast in emitProgramHdrs
+
+commit 88e8f4035870f5807a1c62d368274b53e67d5544
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Jan 24 09:16:41 2012 +0400
+
+    Small cleanup of OutputRelocSection class.
+
+commit a1dca7451e684791374fd9dd2dcae196993d75b5
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jan 21 22:38:22 2012 +0800
+
+    Refactoring - remove some stupid interfaces.
+
+commit e088bd0415d86efd20d01ca5c43f3e964c4325e8
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Jan 20 09:13:43 2012 -0800
+
+    Properly handle R_386_PLT32 without PLT entry
+
+commit 004516520594d691b776fa7eb1f94efb864fdddd
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 20:44:46 2012 +0800
+
+    Remove unneeded header.
+
+commit a4e931b52d501eb2152723bd79ce5573c88b16d7
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 20:34:00 2012 +0800
+
+    Add class X86GOTPLT.
+
+    X86GOTPLT is simliar to ARMGOT.
+    It is used to emit .got.plt section on X86.
+
+commit bc0fa7d5596471b57e0939fb18de95a7d130c216
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 19:45:11 2012 +0800
+
+    Revise comments, no functionality changes.
+
+commit 6ea1c6822197c98fa968e8dd53504742156c36da
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 18:08:49 2012 +0800
+
+    Reorder function declarations and add comments.
+
+    No functionality changes.
+
+commit d8f0ed69ed5cafc94bac8ba360994d960f99abb2
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 17:24:52 2012 +0800
+
+    Remove friend functions in ARMGOT.
+
+commit d68176ad2fed547ad7f80a9addde572a6fd20d4a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 16:30:51 2012 +0800
+
+    Refactor some code in applyPLT1() out into applyAllGOTPLT().
+
+commit 4103e6bec356a08aa45b8c8872ba35f0ccbd0576
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 16:19:08 2012 +0800
+
+    Use iterator to process all GOTPLT entries.
+
+commit 0a0f270f89393870a2e9fc2835f920752ba886f7
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 15:16:00 2012 +0800
+
+    Start refactoring ARMGOT and ARMPLT for reusability.
+
+    1. Rename general got entry to normal got entry.
+    2. Refactor some code out into reserveGOTPLTEntry().
+
+commit e5160ae90cb87de069f4f8f9de820133c9168276
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 20 18:06:09 2012 +0800
+
+    Avoid string comparison in getSectionOrder functions
+
+    we can get the LDSection from ELFFileFormat and compare it with the given
+    LDSection directly.
+
+    TODO: Review the ELFFileFormat for executable and object files.
+
+commit 76e3041eed22558131dc0f1235168e3338f0bd7f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 20 15:10:31 2012 +0800
+
+    Refactoring - ARM/X86/MipsDynRelSection to general OutputRelocSection
+
+    Because the output relocation is format- and target-independent,
+    we move origin DynRelSection from ARM/X86/Mips to Target.
+    The original ARM/X86/MipsDynRelSection have totally the same
+    functionality. Now they share the same structure.
+
+commit e82a5cbc98a2194ba91d2bc74654dc727259072b
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 20 13:20:34 2012 +0800
+
+    Adjust the section order of .got and .got.plt in X86GNULDBackend
+
+commit a609d1ec135d702ab9369ab94c0a305021af433a
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 20 13:19:37 2012 +0800
+
+    Refine ARMGNULDBackend::getTargetSectionOrder() since ARM has no .got.plt
+
+commit a4379af62da91cc3c948acea49d26beb652648e4
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 20 13:18:07 2012 +0800
+
+    Minor code refinement in GNULDBackend::getSectionOrder()
+
+commit f766140caeed2478e7d99ffbdbae5676b8253d14
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 20 11:33:01 2012 +0800
+
+    Remove obsolete code.
+
+commit 1def14764c99de206929bc599fb949e023588d84
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 20 10:56:33 2012 +0800
+
+    Remove obsolete code.
+
+commit d59be6e9457e93a552b44c9c36e46cd0d129d765
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 20 10:02:17 2012 +0800
+
+    Increment position counters for local symbol and common symbol after insertion.
+
+commit f73f6db8bc672707990a1a735117cd9e5add9d99
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 13:14:31 2012 -0800
+
+    Check if the symbol is preemptible on x86
+
+    It is x86 part of commit 8ba9c4b54a360cb3d3253b1b56a8afe0317f53bf
+    for arm.
+
+commit 4a213c598051fc0a53f26edf30b85ffab5883cff
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:58:09 2012 -0800
+
+    Replace isSymbolPreemtible with isSymbolPreemptible
+
+commit f190b4771a51918d1768c73256cd3f6c30d1e7f2
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:44:05 2012 -0800
+
+    Implement X86RelocationFactory
+
+    Known limitations:
+
+    1. Only shared library support is tested.
+    2. There is no TLS support.
+
+commit 1769226d41b7190b37e2f4193d3757860fb7ef25
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:35:52 2012 -0800
+
+    Implement shared library support in X86LDBackend
+
+    It shares many codes with ARMLDBackend.
+
+    Known limitations:
+
+    1. Only shared library is supported.
+    2. Only PIC input is supported.
+    3. There is no TLS support.
+    4. It doesn't use .got.plt section.
+
+commit ed1c3740140cd1f0312becc1104450affb80854b
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:31:54 2012 -0800
+
+    Add X86DynRelSection
+
+    It is copied from ARMDynRelSection.
+
+commit 13479a0d785747e0f84f18cbeb9416505711b65c
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:20:15 2012 -0800
+
+    Add x86 GOT and PLT support
+
+    X86 GOT and PLT support is based on arm GOT and PLT support.
+    X86 and arm share many common codes in this area.
+
+commit aa4f6ce3277acfaf24d6a015a4474799556eafc7
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Jan 19 12:04:05 2012 -0800
+
+    Add m_HasGOTPLT to indicate .got.plt support
+
+    We can avoid GOT0 entries with .got.plt section so that we don't create
+    them if PLT isn't used.  To support .got.plt section, we must combine
+    .got section and .got.plt section into a single GOT.
+
+    For now, x86 doesn't use .got.plt section.  We always have GOT0 entries
+    in at the beginning of .got section even if PLT isn't used.
+
+commit e2f5694303e3c21c44f45f8074521fe7b702e033
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 20 00:55:29 2012 +0800
+
+    Fix a bug - The order of the symbols should be "File" -> "Local" -> "Common" -> "Weak" -> "the rest"
+
+commit 7207ac264dddf47c282062e5c39ef641f3e1d220
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 20 00:53:52 2012 +0800
+
+    ResolveInfo adds a new friend class MCLinker
+
+commit daeb39431219944cd79303c8fa514ead5949efd1
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 20 00:53:19 2012 +0800
+
+    Refine comments.
+
+commit a5e65e7843af4303e8b29aac2926c539661fe003
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 19 22:13:21 2012 +0800
+
+    Use co-variant return type to return target-specific dynamic section.
+
+commit cb86c80b01c35c83dd1da47aa4557acf98a5d7aa
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 19 20:13:27 2012 +0800
+
+    Implement DT_PLTGOT for ARM and X86.
+
+    DT_PLTGOT for Mips is still unsupported.
+    MipsELFDynamic::reservePLTGOT() and
+    MipsELFDynamic::applyPLTGOT() need implementation.
+
+commit 6f4e4a327d278e46ba3d2904ae7a611e2c293906
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 19 16:31:01 2012 +0800
+
+    Add virtual functions for DT_PLTGOT entry on various target.
+
+commit 24164f8c8810fea57e087c4cc939a2f9a060b5ef
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 19 16:14:35 2012 +0800
+
+    Refactoring - let different target backends can implement its own dynamic section.
+
+    If a target backend need its own dynamic section, it can override dynamic() and
+    use co-variant return type to generate its own dynamic section.
+
+commit 8ba9c4b54a360cb3d3253b1b56a8afe0317f53bf
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 19 11:49:27 2012 +0800
+
+    Fix a bug - check the symbol is preemptible
+    when attmpt to generate ouput relocation of R_ARM_RELATIVE type.
+
+commit 53a5a14283d3ea03d5c74607bd2eda7c44105b76
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 19 10:33:49 2012 +0800
+
+    Modify API - Relocation::apply and RelocationFactory::applyRelocation
+
+    Add parameter MCLDInfo for applying relocation.
+
+commit 1a52a94dd9e5858b551d643d5f7ead8fe83b12c9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 19 09:22:42 2012 +0800
+
+    Fix 80-column violations.
+
+commit b85a3dbe8fb1b20f442b8b40de8c87b748902559
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Jan 18 10:39:15 2012 -0800
+
+    Update comments in ELFWriter.cpp
+
+commit d5341a19812027751915a1750c5f25494d1cee9d
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Jan 18 10:36:19 2012 -0800
+
+    Handle SHT_DYNAMIC section in getELF64SectEntrySize
+
+commit 671b356aa5152c00f992e89fd2861818b533716e
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Jan 18 09:44:07 2012 -0800
+
+    Handle SHT_DYNAMIC section in getELF32SectEntrySize
+
+commit 013edf93ccefdba1d9743fd08fc5370d6497f561
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Jan 18 09:39:18 2012 -0800
+
+    Fix another typo in comment
+
+commit c22ce3fd9839b6b809e9728d910fb07dac67eca9
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Jan 18 09:37:24 2012 -0800
+
+    Fix a typo in comment
+
+commit 36f89e2c2659807ae273f6993b85792f678ccced
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Jan 18 14:50:28 2012 +0800
+
+    Fix bug: PLT is not in thumb mode.
+
+commit 8fda3164400240239cbb0f85e0c1fa839db4a5a9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 18 14:23:03 2012 +0800
+
+    Implement ELFWriter::emitRela
+
+commit 2b23a398b1aa2e97142aba856cc34ef1090f0cb3
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Jan 18 12:09:27 2012 +0800
+
+    Fix typos.
+
+commit b26c74a9a119f38b116c4712cbb2d8509dd11f77
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 18 10:58:08 2012 +0800
+
+    Check if output relocation type is valid during scanRelocation
+
+commit b0e75c73eb2f069f1a4e2ac565996cbe2bbaba8d
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Jan 18 10:46:46 2012 +0800
+
+    Fix typo.
+
+commit 9aea15094a1e69258066fdbf6dbd592178b5c526
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Jan 18 10:37:56 2012 +0800
+
+    Add a sample object file for relocation testing.
+
+commit 748f5c777796f3a49ff20383d5e6cdc95dec2b60
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jan 18 09:50:36 2012 +0800
+
+    Replace delete by free() for the memory space allocated by malloc().
+
+commit 65d345de14f0a19c91c97dbdd45744010f6b7f4f
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Tue Jan 17 10:02:35 2012 -0800
+
+    Emit program headers for x86
+
+commit e741f76fa3177a74c888851c9b494e95b1db50dd
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 22:41:01 2012 +0800
+
+    Increase version - 1.6.0-open
+
+    In current version, Quake can be linked on ARM Android.
+
+commit 07040cd7a7fb37ac0e800d83d6f7c77f04c7b89f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 21:21:18 2012 +0800
+
+    Fix a bug - Write back relocation target data to correct place
+
+commit 3fd03f0f18d093a241d9b883e7cbe6838e515f6e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jan 17 20:42:00 2012 +0800
+
+    Fix a bug where modifying the last GOT0 entry unexpectedly.
+
+commit 36b0ad0454ca0b0d3a035e7fd5d2d6ce008b190d
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jan 17 20:15:06 2012 +0800
+
+    Fix a bug where the iterator of got.plt will walk through general got entries.
+
+commit 047549ec677b3728ce819fe447d286b9005e934b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 20:01:16 2012 +0800
+
+    Refine code, no functionality changed
+
+commit 97d07ac833ad2cdd4956ddc57900462f024bcd37
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Jan 17 19:00:28 2012 +0800
+
+    Add an sample test.
+
+    This test will generate an ARM ELF object file and a dynamic share
+    object, and check the symbols and sections which are basically required
+    are exist.
+
+commit 3f6e8610dea08566466defdab5c695b1544df44d
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Jan 17 18:46:48 2012 +0800
+
+    .ll treat as test files.
+
+commit 5705123368ea0c47580d6379a5ab22b2865e078a
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 17:49:41 2012 +0800
+
+    Fix a bug - if the backend does not recongize the symbol during finalizeSymbols(),
+    MCLinker should take over the symbol.
+
+commit 5b2d726dcf7d7727025381260a110d27727c6c2d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 17:46:12 2012 +0800
+
+    Modify API - TargetLDBackend::finalizeSymbol
+
+    Add return value:
+    return ture - if backend set the symbol value sucessfully
+    return false - if backend do not recognize the symbol
+
+commit ae935e3cf795e1608a0113ce8cec3873bc854d7e
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 17:00:43 2012 +0800
+
+    Fix a bug - the scale of relocations is huge, so, we should not sync relocation-by-relocation.
+
+commit f6d22bbc41fe828d0673c1b90ad470895a394379
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 17:00:20 2012 +0800
+
+    Add a new function - MemoryArea::sync()
+
+commit 8ba345695fb31a6023e47edeed3f3a3af4ab1b9f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 16:21:39 2012 +0800
+
+    Set output relocation symbol index to 0 if it's R_ARM_RELATIVE
+
+commit 400abcaa602b9ee8e49d685d8fb432c8b71e4f54
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 16:18:24 2012 +0800
+
+    Modify Relocation::symValue
+
+    If relocation meets a section symbol, set S value to
+    the output section's virtual address
+
+commit 4fd17381cec853596d0824771cdf12eed2b2ddab
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 15:51:46 2012 +0800
+
+    Turn off CodeGenPasses if we're performing linking.
+
+commit da9abb62f25779d122c0539e4358e3ffd7ab33d9
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 13:44:45 2012 +0800
+
+    refine code - add an assertion to check if a Relocation object has a valid symInfo.
+
+commit e236324e5505674565717ac2e5cc8a4bc9516b08
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jan 17 12:15:57 2012 +0800
+
+    Fix a bug and conform to clang++ - we should not refer to a template argument.
+
+commit afeb4519d3429d5359b0f4057c42364350300f1d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 12:11:19 2012 +0800
+
+    Fix a bug - Scan ABS type relocations
+
+commit a83ddc8167383f761cf6b3f66db8bb526bb23fd2
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 17 12:06:01 2012 +0800
+
+    Fix a bug - do not report error unsupport relocation type when
+    applying relocation.
+
+    Because a symbol's reserved won't be 0 if it has relocations with
+    ABS32 and REL32 type point to it. In this case, we should generate
+    dynamic relocation for ABS32 type relocation and perform static
+    relocation on REL32 instead of reporting error.
+
+    TODO: Report this error when scanRelocation
+
+commit 5046913407dbd8d15a11e308e1f1e939ae3fa3e0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Jan 17 11:03:28 2012 +0800
+
+    Let Output be in build dir.
+
+commit 6addb106e6a7b00ddd877cfe20278776d6f98da9
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 23:30:57 2012 +0800
+
+    Increase version - in current version, ARM Android plasma is ready.
+
+commit 8951b13bed44207b4dd6b61afa15bf7ff03edb74
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 16 23:14:16 2012 +0800
+
+    Clean comment in ARMLDBackend::scanRelocation
+
+commit 07189308b1956502ec1ae375218c7aa2cc27f158
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 16 23:07:15 2012 +0800
+
+    Add parameter MCLDInfo to TargetLDBackend::scanRelocation
+
+    In ARM scanRelocation, we need input options to judge the
+    symbol is preemtible or not.
+
+commit f1de3601284cffa67cffc89e24de439b8d2c0874
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 16 22:15:49 2012 +0800
+
+    Don't modify variable within assert() statement.
+
+commit 4c4cdbd3fdc8c08ac86a6ced57b15e5a08d045df
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 22:13:13 2012 +0800
+
+    Fix a bug - whether a relocation entry needs a symbol in .dynsym, is not
+    determined by ResolveInfo::reserved(). Relocation entry pushes the symbols
+    into force local by itself.
+
+commit 29c432726133bff7c8f1319690bb98bc551f268c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 20:27:21 2012 +0800
+
+    Refactoring MCLDFile and MCLDOutput - setSOName should be in MCLDFile.
+
+commit 3a975dd5e0fa9b32899f63e5926c8ef337d27318
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 16 20:12:22 2012 +0800
+
+    Fix a bug - do not report error when applying relocation with
+    branch type if its target symbol's reserved() is not 0 or PLT
+
+    Because there might be a symbol with GOT and there is another
+    relocation with branch related relocation type
+    (CALL, PLT32, ...) point to this symbol, and we no need to
+    generate PLT entry for it. In this situation, the symbol's
+    reserved() won't be 0 or PLT, but it's still correct and we
+    should perform static relocation on it.
+
+commit f275631743978a7483a165f49cf1cbf01e6486c2
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 18:28:34 2012 +0800
+
+    Fix a bug - Undefined and dynamic symbols should have zero size.
+
+commit 39a3709f54c41b3131c94440e7b1aecad7e658c3
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 16 18:17:03 2012 +0800
+
+    Fix bugs - ARM relocation applying functions
+
+    We may generate a got and a plt entry to the same symbol,
+    so we should take all these situations into consideration
+    when applying relocation.
+
+commit 65e1c0e732509a2ed2603f5cf7196e480b79f120
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 17:41:26 2012 +0800
+
+    Fix a bug - if a symbol or a section can not be found, use zero index.
+
+commit d1575fc2169271f9e1a62d14b10a746ae8af0da5
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 16 17:31:21 2012 +0800
+
+    Refine the code to set SONAME
+
+commit 0b354cbf50d949f0871bf03b7e7738da307f3f75
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 16:42:37 2012 +0800
+
+    Fix a bug - a undefined symbol meets a dynamic defined symbol, should use the
+    undefined symbol's binding.
+
+commit a472f2a1710a7359c1b761d877ca2caa739ed9bb
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 16 14:45:06 2012 +0800
+
+    Change data to Nop if applying relocation meets a weak undefined symbol
+    and we didn't generate a plt entry for it.
+
+commit fe6bec3c29d0696ffd3cc00029a232bcde78eff9
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 16 14:12:58 2012 +0800
+
+    Fix a bug - section symbol should stay at Input's LDContext, but do not
+    get into Output's LDContext.
+
+commit bea7b1b44f68085b8061e17f5dde244b64190312
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Jan 16 12:11:26 2012 +0800
+
+    Fix a bug for DT_JMPREL and DT_PLTRELSZ.
+
+    Values of DT_JMPREL and DT_PLTRELSZ should be decided by .rel.plt section.
+
+commit f035c318c05d9bffba3f7faadd1da27f652fef59
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 22:27:13 2012 +0800
+
+    Fix a bug - MCLinker should write down the symbol's value no matter if the
+    symbol is absolute or not.
+
+commit 50af09e996bc24b3d747c1abaf1fe71a677e99d4
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 22:10:01 2012 +0800
+
+    Fix a bug - Finalize symbol value should use SymbolCategory, not output's symtab().
+
+commit d162a1222c9b1a7906844a8d63cee07ed155cef5
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 20:38:15 2012 +0800
+
+    Fix a bug - Output's LDContext::symtab should be maintained before emitRelocation
+
+    move emit NamePools before emitRelocation.
+
+commit 164c0a4b5ddde790f2a6c4b4902964fd04b84ec2
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 20:37:27 2012 +0800
+
+    Fix a bug - LDContext::getSymbol by name should skip the first symbol.
+
+commit a6deea7cb4c5c8b4a5cd1de2a855c2697d2de5d7
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 20:37:02 2012 +0800
+
+    Remove redundant creation of first ResloveInfo.
+
+commit a61badd2124703d0dd50f61f1bd096b54a7c45f6
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 19:52:23 2012 +0800
+
+    Fix a bug - the symbol index of the output dynamic relocation should correct.
+
+commit 04b9a93c70987f5156b1c4da3a9e4bfb15698725
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 19:50:39 2012 +0800
+
+    Add iterator for SymbolCategory.
+
+commit 9a6175b5d9c3f34aabae14704fb3181126c2c25d
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 19:49:48 2012 +0800
+
+    Add new ConstIteratorTraits and NonConstIteratorTraits for getting the right iterator.
+
+commit 5fca0980f01296b628eb52d3ef1a86648ef01799
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 19:48:51 2012 +0800
+
+    Summon old SymbolCategory.
+
+commit 5b7a347544a3d96d2a9427f528953f3adece2fc3
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 13 17:10:03 2012 +0800
+
+    Refine MCLinker::syncRelocationResult
+
+commit 4440c9ae6b3ebf94e7a38581d945262e801c9d3e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 13 16:41:47 2012 +0800
+
+    Add function MCLinker::syncRelocationResult
+
+    Move write back relocation target data from applyRelocations
+    to this function. Relocation target data shold write to
+    output region and should write after all section data has
+    been written, so that it will replace the input data to the
+    relocation applying result.
+
+commit 995b415ce3097b8ab6361a12acaf0e60266568d9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 13 16:39:14 2012 +0800
+
+    Add API - MCLDDriver::postProcessing
+
+    Let MCLinker do any needed modification after all
+    processes.
+
+commit 4b6ef391f36547de5255eb1a00fc8388e701cafb
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 13 14:14:57 2012 +0800
+
+    Refactor ELFWriter::emitRel().
+
+    No functionality changes.
+
+commit c59b007bae34fbd219014bdd16fe64a34b186b53
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 13 11:21:58 2012 +0800
+
+    Split out emitRelocation() into emitRel() and emitRela().
+
+    No functionality changes.
+
+commit 31da795373a3cb7ce2dfa8fcd66b1522545d7ac3
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 13 09:48:50 2012 +0800
+
+    Refine formant
+
+commit b829cf34ecaceeb32384efc9ac2bde7c7c5f369c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 13 09:45:58 2012 +0800
+
+    Fix a bug in function ARMPLT::applyPLT1.
+
+    Apply right value now.
+
+commit ea018e93504c468c58b200b0cc47c27fb5e87460
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 13 09:01:01 2012 +0800
+
+    Use virtual address to apply PLT[0] and PLT[N]
+
+commit 80e6ec1088f5ebeb21c454e75cd71863f3724692
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 03:16:15 2012 +0800
+
+    Fix a bug - dynamic symbols should have 0x0 value.
+
+commit 4cc20c0afcb8c9ec43aded25a60d7d5cfaf19c6c
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 03:05:11 2012 +0800
+
+    Fix bugs - MCLinker should maintains the output LDContext's symbol table.
+
+commit 839d95a416b3a71fcbe5dfe914a39251b70c28ff
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 03:04:39 2012 +0800
+
+    Add a new function - LDContext::getSymbol by name.
+
+commit 9aa004ae51eb8cfe89b79a4b872a87994575999f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 01:37:41 2012 +0800
+
+    Fix a bug - dynamic symbol's output section should be undefine.
+
+commit 95e23aeb035a5dacefc3f2e83f534b47b02f280f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 01:20:09 2012 +0800
+
+    Fix a bug - local symbols should be read but do not resolve them.
+
+commit a3483669541e8def1e7880ac64b161f928a095a4
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 01:19:46 2012 +0800
+
+    Fix a bug - the first symbol need to be inserted.
+
+commit fd906f7b5aa90d156e1279bc9522643b19372ac2
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 13 01:03:36 2012 +0800
+
+    Revert ab3d09e014f6
+
+    revert "reading symbols from the symbol table's first not local symbol."
+    Because relocation entries need local symbols, we read them but do not
+    resolve them.
+
+commit ab3d09e014f651d8b5618ad79d145886ff30d8d4
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 20:31:44 2012 +0800
+
+    Fix a bug - the first entry of the symbol table should not be put in LDContext::symtab().
+
+    LDContext::symtab() is used to group symbols into different file. It's not use to maintain
+    the index of input symbols.
+
+commit 1e1e8825efd95b2a9828838d114871ef481e0ace
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 20:29:10 2012 +0800
+
+    Fix a bug - the first fragment's offset and order is not set.
+
+commit 8c5bc4a3994cab28939969ade167b145bd9bddf9
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Jan 12 18:29:00 2012 +0800
+
+    Set up input shared objects' SONAME for DT_NEEDED
+
+commit 0aa76f98a3eb0d5f7be17f19869dc2f1ae681b00
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 12 17:49:50 2012 +0800
+
+    Modify ELFWriter::emitRelocation
+
+    Set output relocation r_offset to virtual address
+    when buiding .so or executable, otherwise set to
+    section offset.
+
+commit 528d7f35853befc4a1646081bf339500dd21c37c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 12 17:27:47 2012 +0800
+
+    Set GOT reserved entry value when emit .got section.
+
+commit 9737942ead9c2fb6177cd33e09bc98b64a6ee29c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 16:45:20 2012 +0800
+
+    Refactoring - let TargetLDBackend::initStandardSymbol() become a pure virtual function.
+
+    Because different format-dependent target backend should implement its own initStandardSymbol,
+    I leave it as a pure virtual function.
+
+commit 1ba759878f57b6084e49112bf02b8579ac72cbfe
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 12 16:24:07 2012 +0800
+
+    Prevent relocations from double free.
+
+    Relocations are double free by both iplist and GCFactory.
+    To temporarily solve this problem, we new relocations
+    directly instead of allocating their memory space by
+    GCFactory.
+
+commit 9fe80774372f17b878447e0fa8155290cf7a3f22
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 12 16:13:31 2012 +0800
+
+    Write back Relocation target data to MCFragment
+
+commit 3e42c0eae9264e93fecdebbdece54d67f716f4e5
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Jan 12 15:58:35 2012 +0800
+
+    Fix hash section size calculation.
+
+    The number of symbol table entries should equal to nchain.
+    Therefore the previous fix is wrong, now revert it.
+
+commit 1480a43ccec6ab5f445ac8832c50b177c2b0bf50
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 14:11:52 2012 +0800
+
+    For performance, remove redundant malloc().
+
+commit 3b8725ed4dd1e69239cadef98070656b119a31e5
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 13:48:58 2012 +0800
+
+    Set up DT_SONAME.
+
+commit d53a0f7f722707476a7b4857dd57968e21565441
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Jan 12 12:59:12 2012 +0800
+
+    Revert "Fix GNULDBackend::emitDynNamePools() to handle hash conflict correctly.", to
+    maintain the same chain order as gold.
+    This reverts commit 605f04d198ed521d9697707aa0d88cfded04da5b.
+
+commit 605f04d198ed521d9697707aa0d88cfded04da5b
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Jan 12 11:56:37 2012 +0800
+
+    Fix GNULDBackend::emitDynNamePools() to handle hash conflict correctly.
+
+commit f65b48e0c7707b8d1f5db89f89713d63171a3e9b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 12 11:55:03 2012 +0800
+
+    Fix a bug - should not override existing bucket.
+
+commit d9bd4b564e0da97dbb4d3da41c34b73fd88718f7
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Jan 12 11:17:48 2012 +0800
+
+    Fix .hash, .symtab and .strtab size calculation.
+
+    Symbol table already contains NULL entry, no need to write it again.
+    Hash table size calculation should get rid of NULL entry.
+
+commit ceb5a8994c5d8e2a6874eb26b70b4035ac1fc3bc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 12 10:33:56 2012 +0800
+
+    Update ChangeLog and VERSION.
+
+    Trivial cases generated by llvm-mcld have worked on ARM. For example,
+    the shared library, whose source code only has "int g = 3;", works now.
+
+commit 4d45efa22f97db79decf47b3c2a33a268955d5d5
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Thu Jan 12 09:01:30 2012 +0800
+
+    Include missing header <set> and fix naming.
+
+commit 5347b51798e938af883b52ce591977f2046fc405
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 11 17:57:07 2012 +0800
+
+    Fix a bug - First symbol in both .dynsym and .symtab should be NULL symbol.
+
+commit 2fc92c746ab376a44895b503061d1acd3143d41d
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Jan 11 17:51:30 2012 +0800
+
+    Fix another typo for DT_SYMTAB and DT_STRTAB
+
+commit 5245cca946c4258c5b0eeff923115264b6b35e47
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Jan 11 17:32:37 2012 +0800
+
+    Fix typo for DT_SYMTAB and DT_STRTAB
+
+commit fa6ebb87afcf5bf8b06f7fb05056025e7c26f794
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 11 17:15:04 2012 +0800
+
+    Change the defintion of MCLinker::defineSymbol.
+
+    Because some symbols need to set as a local symbol forcefully, so we
+    should separate MCLinker::defineSymbol() into two functions:
+
+      MCLinker::defineSymbol<AsNeed>() and
+      MCLinker::defineSymbol<Force>()
+
+    There two functions are both inserting symbol into the symbol table and
+    resolve the symbol immediately.
+
+    MCLinker::defineSymbol<AsNeed> is just like Google gold linker's only_if_ref.
+    If there is existing an old symbol, the symbol is not defined until the
+    old symbol is a undefined reference.
+
+    MCLinker::defineSymbol<Force>() defines the symbol and resolves it, no matter
+    if the existing symbol is a undefined reference.
+
+commit cff88c952e1b0806f4f8449cca46b6ff05046b64
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Jan 11 14:43:43 2012 +0800
+
+    Update the output section index as final section ordering is known
+
+commit 5f56778a19faa529a4ee4cb2e939b89a15843a70
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 11 10:39:25 2012 +0800
+
+    Move define symbol _GLOBAL_OFFSET_TABLE_ from
+    ARMLDBackend::initTargetSymbol to ARMLDBackend::createARMGOT
+
+    In scanRelocation, if we meet a relocation with the
+    symbol _GLOBAL_OFFSET_TABLE_, we should define this
+    symbol immediately to let the relocation get the
+    resolved symbol which we defined. And that the correct
+    judgement will be processed for this relocation.
+
+commit 722990656bb7aec860669391a92f9644920962be
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 10 14:36:31 2012 +0800
+
+    Fix a bug - ARMDynRelSection::reserveEntry
+    should reserve number of pNum entries
+
+commit 5093c3bff9b26e199aaa33cf17a6786060b8d18f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 10 14:31:45 2012 +0800
+
+    Modify RelocationFactory::produce
+
+    Check target and host endian to make sure if byte swapping is needed
+    when generate target data for relocation.
+
+commit 40aed57bc0eba6834e13bfd2462c563c4c0f8363
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 10 14:30:00 2012 +0800
+
+    Move byte swapping functions from ELFReader.h to SizeTraits.h
+
+commit 52fa03aa90430d45a6861e32e9164a8451d9ea34
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 10 11:22:37 2012 +0800
+
+    Refine formats
+
+commit ecba32742706bf7369d472a933b0491e27762b6c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 10 10:37:16 2012 +0800
+
+    Fix a bug - RelocationFactory::produce
+
+    No need to shift the target_data after copying because
+    we only copy the needed byte from fragment content.
+
+commit 9d2fc5986573e36949fe6a0694a92068156fd073
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Jan 10 10:21:17 2012 +0800
+
+    Fix ARM PLT32 relocation bug.
+
+    The REL addend of B, BL, BLX should do 2-bit left shift
+    after extracting from instruction.
+
+commit d22942580c47d168c6b44c0d12331c8e110629e3
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 10 09:30:35 2012 +0800
+
+    Emit program headers if output is so or exec
+
+commit e1b21c08eb57828b2f8c4d48d04310790c4c9711
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 19:59:01 2012 +0800
+
+    Minor code refinement. No functionality changed.
+
+commit deacd848bdc8fbfad6331e32fdf34336275f6898
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Jan 9 19:34:10 2012 +0800
+
+    Replace strcmp by address comparison.
+
+commit 70b3e196b104ec518fc6056f7d39eebe69a256db
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 17:42:46 2012 +0800
+
+    Refine the code to calculate mem size of ELF segments
+
+commit f8a85823f66cdc3f76b0fd6816b584cd11041df9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Jan 9 17:25:24 2012 +0800
+
+    Emit the section .ARM.attributes directly from the input file.
+
+commit b070fc27aad35afa8551b665af79a174359303b7
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 17:14:49 2012 +0800
+
+    Refine the code for PT_LOAD segments in GNULDBackend::createProgramHdrs()
+
+commit 934175c2a96571854a0c9df3c79c8c0b67e39f88
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 16:09:40 2012 +0800
+
+    Refine the SectLinker's constructor interface.
+
+    Values passed to the constructor of SectLinker (and its derivatives) are now
+    all in SectLinkOption.
+
+commit b4f7b155285b5183a3d7f5627cfa5a4a7c9482f2
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 15:33:30 2012 +0800
+
+    Let SectLinkerOption start playing its role -- in that way, we're able to seprate the user input (from command line) processing from SectLinker.
+
+commit 377e533ecc5dde6ab10f714ed19abf2d02059b21
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 14:56:54 2012 +0800
+
+    Interface change: SectLinker::addInputsBeforeCMD() and SectLinker::addInputsAfterCMD()
+
+    are suppressed to
+
+      SectLinker::addTargetOptions().
+
+commit 0015c8922cf82d31a279157004167adc1c65ee44
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 14:35:50 2012 +0800
+
+    Interface change: pass SectLinkerOption to the constructor of SectLinker instead of MCLDInfo (SectLinkerOption has already contained this.) This invloves the interface change from LLVMTargetMachine to all derived target- specific SectLinker.
+
+commit 1111a1723034142fab1645281e4679ca2b3b0dfb
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 14:34:48 2012 +0800
+
+    Introduce class SectLinkerOption. This will be used later to seprate the "data" (i.e., user input from command) from the library (SectLinker itself).
+
+commit 478a5f7e2b90fc5b46819e61e174dcb3e3cf7238
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Mon Jan 9 14:33:23 2012 +0800
+
+    Refactor class PositionDependentOption out from class SectLinker and introduce "derived PositionDependentOption" to handle different kind of options.
+
+commit 1a1f4e448b5f87d9e8f846f8cb56755225cdc6c8
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 16:38:49 2012 +0800
+
+    Not include .bss in output if its size is zero.
+
+commit d960a402d99f6534eca4c5ff72a067b9e2ddae5c
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 16:35:00 2012 +0800
+
+    1st ELF PT_LOAD segment should include ELF file header and program headers
+
+commit eec23b196dfc13b543c35c9198d2e69434331c91
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 16:16:52 2012 +0800
+
+    Add functions to get the first/last section in ELF segment
+
+commit 3f35b2331065e27df2b4bc6337f7845fc68942b9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 9 15:49:13 2012 +0800
+
+    Fix a bug - GOTEntry::getSize return correct entry size
+
+commit 69975829d19e4df1b0cf749edd02e2e8a4d10a87
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 9 14:48:18 2012 +0800
+
+    Use virtual address of .got and .plt section when applying relocation
+
+commit 4abd0ac66e9fa9c5a155ffcc7b8a45ec8aee8ee6
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 9 14:38:43 2012 +0800
+
+    Define _GLOBAL_OFFSET_TABLE_ simultaneously when .got created
+    in ARMLDBackend::doPreLayxout
+
+commit 13912532aac8d7ec25fa1b5d791eb7683c512595
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 9 14:20:10 2012 +0800
+
+    Use virtual address as S and P value for applying relocation
+
+    1. Modify Relocation::place - use LDSection.addr() as base address
+    2. Modify Relocation::symValue -
+       Symbol's value is set to virtual address before applying
+       relcoation, so we can take this value directly as S value to
+       apply relocation.
+
+commit 3111407b46b766028e3d0665ece0b8ea0b9dedcf
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 14:02:56 2012 +0800
+
+    Correct the alignment to byte alignment
+
+commit b80e0a538cc8a0e4402dd4ccb372a0c9f61f0678
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 9 13:55:57 2012 +0800
+
+    Change the bug reportee from Luba to mclinker@googlegroups.com.
+
+commit 2ced0a42910e2ea516d6249a211fe41f922b997e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 13:30:03 2012 +0800
+
+    Refine the function to get section order
+
+    .dynamic is changed to NamePool
+
+commit 4baefc969db0d7f0c8dd0411359ab0a5fe0673d4
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Mon Jan 9 09:55:35 2012 +0800
+
+    Remove '#include <iostream>' and 'using namespace std'.
+
+commit 9842d170066e6ec6482b3e3e0c99ffaa570d3c9e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 9 09:46:16 2012 +0800
+
+    Correct the segment flag for .dynamic
+
+commit 40924a00ae4f3b984659f4917cfec5f7c86503fe
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 23:03:09 2012 +0800
+
+    The symbol's value should be virtual address. If the symbol is
+    reserved by target backend, call back target backend to finalize
+    the symbol's value.
+
+commit 757b7f29e436b394d746c266727dc43ce399b85d
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 22:26:47 2012 +0800
+
+    Open the getSymbolShndx() - now the symbol's shndx should be right.
+
+commit 52a7cbeea0a7ce37e614d812eca8387905b7e45b
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 22:24:37 2012 +0800
+
+    Fix a bug - because we merge section when reading them, we don't
+    need input's STT_SECTION symbols for relocation. Skip section symbols
+    when reading them.
+
+commit 93094ab3afa4851ce71abb7302fdc4d5a05426e8
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 22:23:24 2012 +0800
+
+    Remove obsolete comments.
+
+commit c766a6b40c849da0d1dc2ff3e0d40f27db13b3cb
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 18:35:16 2012 +0800
+
+    Add a new function - LDSymbol::hasFragRef().
+
+    This function return true if the symbol's fragment is set.
+
+commit 60a6a7679134bbb70db1d2cf40bcdca213cf3b1e
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 18:19:22 2012 +0800
+
+    Fix a bug - Local and absolute symbols' binding should still local.
+
+commit e85a4f3117722767e5048b9ec3b9b1c4e438a5a2
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 17:58:56 2012 +0800
+
+    Refactoring ELFDynamic and GNULDBackend
+
+    1. Move .dynamic section's initialization from GNULDBackend::prelayout to sizeNamePools
+    2. Move MCLDDriver::measureNamePool() into MCLDDriver::preLayout()
+
+commit 59fe697fade87471541b1cafe5ef53afdfdbc096
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 17:57:37 2012 +0800
+
+    Refine ELFDynamic Section
+
+    move applyOne and reserveOne to .cpp, and add some parameters for debugging.
+
+commit 47fcaef2d6bd77f21042ba36a6d5fa9dbfbd2733
+Author: luba <lubatang@gmail.com>
+Date:   Sun Jan 8 16:31:25 2012 +0800
+
+    Refine rules - if a symbol is reserved or external, add it into dynamic symbol table.
+
+commit f46efc738d24306d50dca76ce7723365e31f4fee
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Sun Jan 8 12:17:43 2012 +0800
+
+    Clean debugging insertion
+
+commit a2e6d1ef62a5ec9dbebdf13e1ea8f99e22986942
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Sun Jan 8 12:14:13 2012 +0800
+
+    Modify Reocation::symValue
+
+    For symbol with no FragmentRef, return its symbol value directly.
+
+commit eb4971267340e343a302970458bd1041fd853eab
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jan 7 23:06:29 2012 +0800
+
+    Fix a bug - Any symbol with hidden or internal visibility should be treated as a local symbol
+
+commit 924a15117daeefd4b61ec208299272783e0cb90c
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jan 7 22:55:44 2012 +0800
+
+    Fix a bug - A protected symbol coming from a shared object must be treated
+    as a normal symbol
+
+commit ea958dd27e39060da2bb1de1cb4e57996140385f
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jan 7 22:43:23 2012 +0800
+
+    Fix a bug - ignore symbols from the shared objects:
+                     1. local binding STB_LOCAL
+                     2. STV_INTERNAL
+                     3. STV_HIDDEN
+
+commit e1e6b960018afbe7e311acffe949f5e2c04fecc2
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jan 7 22:21:38 2012 +0800
+
+    Fix a bug - a symbol defined in a section which iwe are not including must be
+    treated as an undefined symbol.
+
+commit 5463c4953fbcb13ecab5c305d60cc9593c7b7cd8
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 23:34:33 2012 +0800
+
+    Apply new ELF .dynamic section on all backends.
+
+commit 258d871b28a35422a28d0a2ab3aced610cfce9c6
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 23:34:11 2012 +0800
+
+    Implement common .dynamic section for all ELF backends.
+
+commit 32c86db8a4edbac688eb834f9329a1ee60d8139e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 23:33:41 2012 +0800
+
+    Let .dynamic section become a kind of NamePool
+
+commit 91c7317bd0e5f650357e1b41e48c423af7d2ab07
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 23:32:41 2012 +0800
+
+    Implement many hasXXX section checking functions.
+
+commit 8c9e44d5bed5229b9c6ec8c35ae6b995880a56c0
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 6 23:20:54 2012 +0800
+
+    Emit program headers in ARMGNULDBackend::postLayout()
+
+commit 4990a37724326287b637a1421c184e26d807e322
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 6 23:20:24 2012 +0800
+
+    Implement GNULDBackend::emitProgramHdrs()
+
+commit 2ccc45ab9b0a65d8110a17b87021c7ded49221d5
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 6 23:18:14 2012 +0800
+
+    Add pagesize() to define page size of the target machine
+
+commit 7ebcaecff7ed237e7a677083fd14e1c242660adf
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Jan 6 22:45:25 2012 +0800
+
+    Add ELFSegment class.
+
+commit 354fb454a82328e702143402a6e75d35af4d5c7a
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 6 20:02:52 2012 +0800
+
+    Modify symValue() and place() in Relocation
+
+    Use file offset of the symbol and the place being relocated
+    as S and P value for applying relocation.
+
+commit e6595f2dbad20beadd335d9734016fdb5f31e27b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 6 19:28:35 2012 +0800
+
+    Modify createARMGOT/ARMPLTandRelPLT/ARMRelDyn in ARMLDBackend
+
+    In ARMLDBackend, directly get LDSection from LDFileFormat instead
+    of getting from MCLinker
+
+commit b0f74c4d889d438922a03367e753890ce873a4c3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 6 15:50:06 2012 +0800
+
+    Do check before generating dynamic section entries.
+
+commit 629b78c40069fedf0c2270170aca853ef35d1e60
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 15:05:01 2012 +0800
+
+    Implement finalize symbol value.
+
+commit 8ce6932dad00ed0a4ab9df56fc321a7d6dfd1474
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 6 14:11:19 2012 +0800
+
+    Fix a bug - fix typo of Rela to Rel
+
+commit cdc28be2dfd86e4c5901d34a4061cfdc91091251
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 13:47:10 2012 +0800
+
+    Fix a typo. MCLinker::finalizeSymbols() should have no parameters.
+
+commit a13bb7e0e666219d668aebddb67aaa721db9a61b
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 13:44:47 2012 +0800
+
+    Refine format.
+
+commit 7fdbf6aa4762ce24cee534ac9bb0753e61fab254
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 13:44:22 2012 +0800
+
+    Enable MCLDDriver::finalizeSymbolValue
+
+commit 903de0b94bdddf262a662c377f7fa0ed246aa237
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 13:36:03 2012 +0800
+
+    Enable TargetLDBackend's preLayout() and postLayout()
+
+commit dc4ceddb70bb11381910cfe4a8f780ae58b6f02b
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jan 6 13:19:57 2012 +0800
+
+    Fix a bug - symbol resolution should not override the ResolveInfo's pointer to output's LDSymbol
+
+commit e9124e2f59c421515f43875d089203ee455a9d1a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 6 12:23:37 2012 +0800
+
+    Enable ARMLDBackend APIs to call the implementation of .dynamic section.
+
+commit 9623085a64401cfecc93fa51796e830fcdb518c9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Jan 6 11:40:58 2012 +0800
+
+    Fix bugs - Add missing ++it in while loop
+
+commit a197b269f33054978400a996b6565b556ec91a9f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jan 6 11:02:30 2012 +0800
+
+    Move the implementation of .dynamic section to ARMLDBackend.
+
+commit 00434aeac60ef334e4c2ea84216eae646bb6f673
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 21:14:22 2012 +0800
+
+    Fix a bug where re-pushing MCFragments into MCSectionData.
+
+commit 17a10d49c18bed780d5a6248f4aa2b895b62bbf6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 21:09:04 2012 +0800
+
+    Fix a bug - MCFragment pushes itself into MCSectionData at constructor.
+    Therefore, any one should not push MCFragment into MCSectionData again.
+
+commit 3993c7dfa8b58d79177af00a5bf60345bb989b4f
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 20:36:28 2012 +0800
+
+    Fix a bug - reader should set up output's LDSection size
+
+commit 8c5946523705c90bbc892b99d7f1ce6659a8e878
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 20:16:42 2012 +0800
+
+    Enable target backend's initTargetSymbol().
+
+commit 207711864c208b4ed977828a35a6d8b16d411126
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 20:14:43 2012 +0800
+
+    Implement GNULDBackend::emitDynNamePool
+
+commit 5e9b12711f9330cc8569b9850038b44eded9ba6e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 5 19:38:33 2012 +0800
+
+    Add APIs - TargetLDBackend::preLayout and postLayout
+
+    create .got section in ARMLDBackend::preLayout while
+    building shared object.
+
+    TODO:
+    1. create .dynamic section
+    2. create _GLOBAL_OFFSET_TABLE_ symbol when creating
+       .got section
+
+commit 7e5b753e38ddb50f70ec638a2362156fc7577632
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Jan 5 18:54:32 2012 +0800
+
+    [ARM] Correct the Section flags for .ARM.attributes
+
+commit b21adcf07e8241228c30339cc97a8fb4d09b931e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Jan 5 18:50:35 2012 +0800
+
+    Remove the code to set section size and refine some code in Layout
+
+commit c17a7cb792d53775e84aabe007644d04c0d9a1ad
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 18:02:30 2012 +0800
+
+    Calculate the size of .plt section for LDSection in ARMPLT.
+
+commit 40c92724cb55cdb6bafa311c1e71840e8f7b423b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 17:43:36 2012 +0800
+
+    Calculate the size of .got section for LDSection in ARMGOT.
+
+commit c5ca8210193a6f56529f276fb7926ad35ca79d4a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 17:15:27 2012 +0800
+
+    Add empty emitting functions for DT_SONAME and DT_NEEDED.
+
+    it has no need to deal with DT_SONAME and DT_NEEDED in emitDynamic(),
+    Using empty emitting functions here are for skipping assert check.
+
+commit d5bf56a171160bb91876e68633127213c364af0b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 17:06:51 2012 +0800
+
+    Change the type of .dynamic section to LDFileFormat::Target.
+
+commit 57fe477031c194b2c0475064821fb6d040f8b8ed
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 17:00:00 2012 +0800
+
+    remove obsolete code.
+
+commit b00a118399e1a2c6756af082c22ed8aa896cabde
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 16:57:44 2012 +0800
+
+    Remove obsolete code.
+
+commit a5ec28fff10512dc3c6f4c2342d404176ef8378e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 16:16:44 2012 +0800
+
+    Fix wrong assert statement.
+
+commit f59f4adda2206a57c15004da974e430d5790a802
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 5 14:02:21 2012 +0800
+
+    Add API - TargetLDBackend::initRelocFactory
+
+    1. initRelocFactory - create and initialize RelocationFactory
+    2. Modify getRelocFactory() to only get RelocationFactory but not
+       get or create RelocationFactory
+
+commit 114b828359228ffd7d55ee76835833f1c25cda81
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 12:18:32 2012 +0800
+
+    Fix a bug - Dynamic symbols which do not in the relocatable objects, should not be pushed into dynammic symbol table.
+
+commit a1f691c2db4cde4e31ab9cbb4c1bc164d03b03a0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 11:49:01 2012 +0800
+
+    Update unittests for the changes of MemoryArea.
+
+commit b24215aae5f56abfa57d80900f46e2d24418ab20
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 11:34:13 2012 +0800
+
+    Fix a bug - ELFObjectReader::readRelocations should check if the
+    LDSection::kind() is LDFileFormat::Relocation.
+
+commit 9e013dce25d8f6ca908bd92ba1474461324b7640
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jan 5 11:23:08 2012 +0800
+
+    Remove Layout from emitDynamic() function prototype.
+
+commit cbc854ffa91959d5e44021a266059b3f68ac4709
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 5 09:59:08 2012 +0800
+
+    Remove debugging insertion
+
+commit a2c2fc755b5499ae1dcea1c9b5adccad1f36317c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Jan 5 09:54:51 2012 +0800
+
+    Fix bugs - create symbol _GLOBAL_OFFSET_TABLE_
+
+    1. Ask layout to create FragmentRef for this symbol.
+    2. The size of _GLOBAL_OFFSET_TABLE_ is 0.
+
+commit c04430036f58b5c199377203bb6380348b17e4d6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 04:19:22 2012 +0800
+
+    Fix a bug - when layout, the fragment list of MCSectionData should not be empty.
+
+commit ed1a19489f3dc1986eb57d6f9159fbae35601e1c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 04:11:27 2012 +0800
+
+    Fix a bug - In current verion, MCLinker merges sections when reading
+    them. So, the offset of the read fragment should be set.
+
+commit 4a0c98a5e2b572ca57b27599ccc85ab254661641
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 04:09:48 2012 +0800
+
+    Refine the error message.
+
+commit f0a5228dcec061ef8855cdc4acab276c1d0b811c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 03:22:53 2012 +0800
+
+    Fix a bug - Layout::isEmptyRange() causes segmentation fault when
+    the range is the first element in the range list.
+
+commit 1e5a9a2fb1453045c5e1621c58d973f0b3afdd1b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 03:03:18 2012 +0800
+
+    Fix a bug - Even dynamic symbols ask Layout to get their FragmentRef.
+    Since dynamic shared objects have no MCSectionData, Layout should
+    return NULL when the symbols's st_shndx points to no MCSectionData,
+    should not report fatal error.
+
+commit c682c31a5fae0760e07cfe291a336e86df8026a4
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 02:49:44 2012 +0800
+
+    refactor the relationship between MCLinker and Relocation
+
+    relocation's fragment reference should be set by format-dependent readers,
+    not MCLinker. Transfer the responsibility from MCLinker to ELFReader
+
+commit 99f069f0b8f37a936bdaedcfc818bec4272aef70
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jan 5 01:55:01 2012 +0800
+
+    Set up sh_info and sh_link in input's LDSections.
+
+commit ef9e73ed4cfe3e2701ccc978282dfe2bb35cd3ae
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 23:15:03 2012 +0800
+
+    Fix bugs - There are some relocation entries point to the
+    undefined symbol, and undefined symbol has no fragment reference.
+    These undefined fragment references cause segmentation fault when
+    applying relocations.
+
+    The bug source is: in ELF, the relocations' fragment references
+    come from relocation section's sh_info, not from the dynamic
+    symbols' st_shndx. So, ELFReader is responsible for set the
+    LDSection::setInfoLink() when reading relocation sections.
+
+    The same problem is easy in MachO, because MachO's relocation table
+    is within the section. There is no extra effort to get the relocations'
+    fragment references.
+
+commit 9ee8d31b4f39f4dda6d6472b18e50ffb64d52d6b
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Wed Jan 4 19:59:47 2012 +0800
+
+    This patch suppressed the number of warnings when builds the MCLinker under Android compilation flags.
+
+    It includes:
+    1. Trim spaces.
+    2. Initialization order.
+    3. Comparison between signed and unsigned number
+    4. Uninitialized loop iterator in include/mcld/LD/ELFReader.tcc
+    5. Move mcld::fs::exists(FileStatus f) and
+            mcld::fs::is_directory(FileStatus f) from Path.cpp to FileSystem.h
+
+commit 079c579fe2f79451c763a4b022a7ff1e193d2664
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jan 4 20:30:26 2012 +0800
+
+    Add the Implementation of emitting .dynamic section.
+
+commit 9ce9285a4a997b33c3ea53e19ed0e43b4cd694b5
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 4 18:02:50 2012 +0800
+
+    Modify ARMLDBackend::isSymbolNeedsDynRel
+
+    Add parameter isAbsReloc to check if symbol needs dynamic
+    relocation when building shared object.
+
+commit a3dbe9ca13b0461731155d9fe97cd61dd6eab3c3
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 4 17:58:14 2012 +0800
+
+    Fix a bug - we can't emit dynamic relocation with type
+    R_ARM_MOVW_PREL_NC and R_ARM_MOVW_ABS_NC
+
+commit b28327cf3385aaeb15556471547f2fe391f2678f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Jan 4 16:34:07 2012 +0800
+
+    Fix comment and refine error message
+
+commit 54f5511857354e612782cfe8df3f44a96062b2d0
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Jan 4 01:31:55 2012 +0400
+
+    Add one reserved entry on Mips GOT initialization.
+
+commit 7a2ee69ef80f5d9a473bedd4daa1998f93cc6f1a
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Jan 4 01:08:13 2012 +0400
+
+    Add a bit more MIPS flags to the ElfXX_Ehdr::e_flags.
+
+commit e347611835616bd346e5609226c054033db80f86
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Jan 4 01:03:33 2012 +0400
+
+    Add namespace qualification to the R_MIPS_HI16 constant name.
+
+commit 3011400c7be9ac02e75c4cf6070b2d1a6a120786
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Jan 3 15:53:53 2012 +0400
+
+    Implement MipsGOT::reserveEntry() and MipsGOT::gotEntry() routines.
+
+commit f4b82d455e287d7797c3deebf9e07ce59423a1e8
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Jan 2 15:21:44 2012 +0400
+
+    Extend the list of Mips relocations processed by the MipsGNULDBackend::scanRelocation() routine.
+
+commit ad6e2eda57c9fe9db930dce4daac725b88161219
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Jan 2 14:24:18 2012 +0400
+
+    Move _GLOBAL_OFFSET_TABLE_ processing to the MipsGNULDBackend::initTargetSymbols() method.
+
+commit 6ceb028677045e69d4c2aa6df50314451dd26163
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Jan 2 14:21:49 2012 +0400
+
+    Add begin()/end() methods to MipsGOT class.
+
+commit a11f8bcd3be88f45629d9ce4b83849de7f086446
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Jan 2 14:02:34 2012 +0400
+
+    Refine MipsGOT code.
+
+commit 93d6e506d075066b83ca2bb8f4030ff5f611f414
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Jan 2 13:23:42 2012 +0400
+
+    Refine MipsGNULDBackend code.
+
+commit 53a8d13f75241e7e94a2b8810a9c762dadafa272
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Dec 31 00:34:41 2011 +0400
+
+    Refine MipsRelocationFactory code.
+
+commit 8d9ae90a8bc8f515aa5c14b21f5e5f986c169518
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Dec 31 00:14:29 2011 +0400
+
+    Add new entries to the DECL_MIPS_APPLY_RELOC_FUNC_PTRS macro.
+
+commit 15f2df15f4c378509423ccc5f208ba4f45a475d2
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 00:30:46 2012 +0800
+
+    Remove rslinker, and use our own readers.
+
+    Sorry for the big patch, but I think this is the last big patch.
+
+commit d42ee92511c1f85308d568d5538d98cec852ef65
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 00:29:49 2012 +0800
+
+    Fix a bug - should determine if the fragment is NULL before using it.
+
+commit 8b5c813f53b9dccbf3d86ec80a59013338e0fc49
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 00:28:34 2012 +0800
+
+    Fix a bug - the default semantic of Memory::request() should be read-only.
+
+commit a6ca15f9831efb58aac4804d795db27558b8446e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 00:27:13 2012 +0800
+
+    Fix a bug - Layout should return a MCFragmentRef<NULL, 0> when it can not find any fragment.
+
+commit 1b7dffa62857466b6f54d1a6f8b083c49ce9c1fe
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jan 4 00:26:30 2012 +0800
+
+    Fix a bug - Add missing llvm::ELF namespace
+
+commit 8a1293d064e9b6c0bc4a92f0e758fca730f5e164
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 20:45:44 2012 +0800
+
+    Fix a bug. Refine loop boundary condition in Layout::orderRange()
+
+commit 3c3b5ca1ad50204a20c74a6890c717cdc9346111
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 19:58:54 2012 +0800
+
+    Fix typo in ELFDynObjReader::isMyFormat()
+
+commit dc441ccc8ec5acba47820a3edb0c5d38a6338af4
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 17:55:07 2012 +0800
+
+    Remove the code to set LDSection address.
+
+    We should base on "Segment" to set section address, and this part will be done
+    in post layout.
+
+commit 8564c3f2e0726d608ef4242f8ee484c0d424d7c4
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Tue Jan 3 19:47:54 2012 +0800
+
+    Use MemoryArea::page_boundary() to find the page-boundary that larger than file-offset.
+
+commit 11661c9b489b7a21c2b0ae3c2ba5517a0bd58109
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 3 19:09:29 2012 +0800
+
+    Fix a bug - ARMDynRelSection::getEntry
+
+commit c721fa8050ab969a7be7f4cd529fd65fb560c01b
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 15:26:59 2012 +0800
+
+    Refine comment.
+
+commit 988a531b6b32125128132207f85fbdcc4cb87004
+Author: Zonr Chang <zonr.net@gmail.com>
+Date:   Tue Jan 3 16:05:14 2012 +0800
+
+    Fix build when --with-unittest was not given.
+
+commit a4c9f6555118c2cc51f6f51b6bfcf5b41616d3bd
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 14:57:47 2012 +0800
+
+    Add mapping rules for .ctors.* and .dtors.* in SectionMap
+
+commit 5f485803471db9be08229da3d6cc1ef105fafd63
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Jan 3 13:49:18 2012 +0800
+
+    Add .init and .fini in ELFFileFormat
+
+commit 39f4cc4245c6fe2b502c49a119f2be507bc3cb45
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 3 11:59:04 2012 +0800
+
+    Refine format
+
+commit b92287ed88cdad5c43946a70cc750b0a3a3b8e3c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Jan 3 08:52:03 2012 +0800
+
+    Fix build failed
+
+commit 47207c00b9f2c41548e836c2006b8974c49a7dfd
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 22:08:43 2012 +0800
+
+    Refine format.
+
+commit b869a4e0b42d2d1cbfa70939262c106a064515ee
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 22:07:43 2012 +0800
+
+    Refactoring - move TargetLDBackend::machine() to GNULDBackend
+
+commit 5e84179fb316af641a675e718c2b809db89f81cb
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 22:05:59 2012 +0800
+
+    Implement byte swaps.
+
+commit 55a981e5a252604981efa07b1c6bda6d2e9ee9be
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 2 20:05:12 2012 +0800
+
+    Add ARMGNULDBackend::getTargetSectionOrder()
+
+commit 470e0593cb2def7e7967d0fe50c7b9b5445485da
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 2 19:59:34 2012 +0800
+
+    Implement GNULDBackend::getSectionOrder()
+
+commit 80aaa308441ff3f89061dca90f48b316161a1ff5
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 2 19:58:34 2012 +0800
+
+    Define the basic section orders for ELF format
+
+commit 34b348d1909089dcb2dd8f134d67c82f5bebdf78
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Jan 2 17:19:30 2012 +0800
+
+    Modify ARM relocation functions
+
+commit 80d202a5358c2ee2636eddf6500de71d5033ed95
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Jan 2 15:58:56 2012 +0800
+
+    Enable testing make.(When "make check")
+
+commit 630cc7219c262687e41d32ac6777fd286eb53b75
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Jan 2 15:57:25 2012 +0800
+
+    Fix testing config bug.
+
+commit 54b997780caa11cb2b43a018b46a42951b76d784
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Jan 2 15:56:48 2012 +0800
+
+    Remove testing temporary files.
+
+commit b7f0f9721ccf21ad13e29c64525000633f635307
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 15:55:22 2012 +0800
+
+    Refactoring - collect all MemoryArea::request in ELFObjectReader and ELFDynObjReader.
+
+commit ae0c1babf8bf969f8058178ce24929da976412d2
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 15:37:14 2012 +0800
+
+    Refactor ELFReader: eliminate the number of using MemoryArea::request.
+
+commit 5c9b26645d64822d729b867d9a41c6035e930a77
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Jan 2 14:56:06 2012 +0800
+
+    Uncomment emitSectionData() and do little modification.
+
+commit 46b1162de3d85ddd4270e0c809b0fbf951beceef
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 2 14:17:22 2012 +0800
+
+    Refine comments.
+
+commit f7637d41b45dbb63264493b00047a7884f9e78cc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Jan 2 12:14:11 2012 +0800
+
+    Complete the member function emitRelocation().
+
+commit 80eff6b9386ab4a403f81d23948b5897ba75abe8
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 12:07:13 2012 +0800
+
+    enable backend's scanRelocations().
+
+commit 9b2a4151960babbbe0469c480122a61cd6f56e69
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jan 2 11:31:39 2012 +0800
+
+    open MCLinker::prelayout() and postlayout() for Backend
+
+commit 559c32fd7c500e5e37821f09f96e24858c35203e
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Jan 2 11:22:41 2012 +0800
+
+    Move m_fileOffset from MCLDFile to MCLDInput.
+
+commit 972d3974e99d12105bf23e69fddcd780d4e4528d
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Jan 2 11:13:58 2012 +0800
+
+    Refine comments.
+
+commit ac57f5127d1c83087b53239882993ab31e886284
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Jan 2 02:04:22 2012 +0800
+
+    Add a varable "fileOffset" for class MCLDFile.
+
+    For a member object file of an archive, we need the start address
+    in the archive. Add an variable for class MCLDFile and set the value
+    in GNUArchiveReader using the member function of MCLDFile ,setFileOffset.
+
+commit 7133194501e161b8dc81da0aa67b1c187f5bf8c1
+Author: Duo <pinronglu@gmail.com>
+Date:   Sun Jan 1 09:41:44 2012 +0800
+
+    Complete isolated GNUArchiveReader without thin archive.
+
+    MCLinker can't still work with GNUArchiveReader.
+    We need some unittest to confirm the correctness of MCArchiveReader.
+
+commit 0c722d32b54ef5c2c7e44733f94ce6d4f744e8a2
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 30 17:57:36 2011 +0800
+
+    Add LDContext::getSymbolIdx() for writing out relocation table.
+
+commit 3ea85fd32cc03757cf0e9f9df52ff181d1e31ac5
+Merge: a2c2655 6b5b4fd
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 17:47:55 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 6b5b4fde7be7c121b7f59551f30aed104c973c1f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 17:46:16 2011 +0800
+
+    Fix a bug - produced relocations need to set up input's ResolveInfo.
+
+commit 19e1aa9e96eb921563a7d46044518c847799f515
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 30 17:45:28 2011 +0800
+
+    Implement Layout::getFragmentRef from the big offset
+
+commit a2c265577bc39af4d4fa8857dd0d9f2d1047cf7d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 17:45:59 2011 +0800
+
+    Modify ARM relocation applying functions
+
+    R_ARM_MOVW_PREL_NC and R_ARM_MOVW_ABS_NC
+
+commit e47dbf5641357d4507bb4786e89f9d5a52323e2a
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 17:45:11 2011 +0800
+
+    Add assertion if ResolveInfo of relocation not set while scanRelocation
+
+commit 2d38016e4cd23bd518c5dc6dc4e331d50c82ee06
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 30 17:39:58 2011 +0800
+
+    Fix wrong virtual address calculation.
+
+commit 208b75256dc7a75b1829f99d9801147bddc09114
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 30 17:28:10 2011 +0800
+
+    Implement ELFWriter::emitRelocation().
+
+    It is unfinished.
+
+commit 1a0da05a617f89191149b66a826a9a570c67bc01
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 17:23:01 2011 +0800
+
+    Enable `MCLDDriver::relocation()'
+
+    Implement MCLinker::applyRelocations() and related functions.
+
+commit f442311b9f19067fc57d842cecc72a7d406446a2
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 30 17:08:19 2011 +0800
+
+    Modify the return type of Layout::getFragmentRef from the big offset
+
+commit 35bcb06c79acdfb4fae7ccfaed0bb807fa33921e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 16:57:02 2011 +0800
+
+    Implement MCLinker::addRelocation.
+
+commit 142fd33c403f38e15899c062ecb0427c86a7a1d9
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 16:55:36 2011 +0800
+
+    Open Layout::getFragmentRef from the big offset.
+
+commit 09e22e7c3d506a4f18861570f702551d19322104
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 16:43:00 2011 +0800
+
+    Modify ARMRelocationFactory
+
+    1. Implement relocation function prel31,
+
+    2. Refine some judgements if got entry is needed
+
+commit 2a13eda6730cb64eccbdc2a67ec80a6a70e1b409
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:49:17 2011 +0800
+
+    Implement format reader's readRelocation().
+
+commit 9fd370ba93f84bfc4435dcc249c4c4326b952cdc
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:48:04 2011 +0800
+
+    add LDContext::getSymbol()
+
+    Because we may change the definition of LDContext::SymbolTable, LDContext
+    better provides this API.
+
+commit 6b545fe85b908aa333ec5078592d9da6799b57b4
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 30 15:19:11 2011 +0800
+
+    Refine format
+
+commit 0fc01b92e9c82eda9f0d01f983c1cb47283bf605
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:11:52 2011 +0800
+
+    Fix a bug - if the section name contains any "debug" sub-string,
+    the section should be a LDFileFormat::Debug section.
+
+commit 9b4233273a69f35e32ecb20c5ff592f23e98293a
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:02:49 2011 +0800
+
+    Enable `reading relocation entries'.
+
+commit 98cb9c290428a715bd13bdd38ce2aff65991aef2
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:01:19 2011 +0800
+
+    Refine format.
+
+commit dfbabd99b3db7afd45871b6c42bfc3c392dabbc7
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 15:00:15 2011 +0800
+
+    Make a note - we should make a map from section name to section
+    index to speed up the querying.
+
+commit 031a2951ba8879f797be707c3ac98ecdf82ba6a6
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 13:50:26 2011 +0800
+
+    refine comments.
+
+commit ee080734e874ce1898c8545f84a718eb8aad2eda
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 14:17:31 2011 +0800
+
+    Modify ARMLDBackend::scanRelocation
+
+    check if relocation target symbol is _GLOBAL_OFFSET_TABLE_
+
+commit 0fcbde36689d60916c76979269c813354b546273
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 30 13:54:00 2011 +0800
+
+    Implement get Input/Output LDSection in Layout
+
+commit e5e02f694f04c4c935945b0d9ea5ac80570bd20b
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 13:45:02 2011 +0800
+
+    Refactoring the architecture - transfer TargetLDBackends from pure-abstract reader interface to format-dependent reader interface.
+
+commit 3c4bc285ac00a9da71b2bbb196f4bbaccc994246
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 13:41:34 2011 +0800
+
+    Implement ARM relocation functions: abs32, rel32, gotoff32
+
+commit 45f9be9be83195f01489b96f3ce756cafdfd2ecf
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 30 13:39:16 2011 +0800
+
+    Fix bug - ARMRelocationFactory::ScanRelocation
+
+    A place may still needs a dynamic relocation to relocate itself
+    although it jumps to plt.
+
+commit b193909cd559cc3525400b83c0a0b13c578f0573
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 05:47:00 2011 +0800
+
+    Fix a bug - now can see the symbol name.
+
+commit 81dc1faee5c769f4d6f2511da32f5886ca2e89f8
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 05:01:55 2011 +0800
+
+    Implement emitRegSymTab()
+
+    Some bugs are still remaining.
+
+commit 239c2dca20ab3ecdcf1f3199fee82c8bc237f415
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 05:01:01 2011 +0800
+
+    Fix a bug - when read unsupported symbol, should ignore them.
+
+commit b1ce25b502c8f6fa8cfeff1eb05a3d1e2d2c6a0b
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 04:58:01 2011 +0800
+
+    Fix a bug - when read unsupported symbols, should ignore them.
+
+commit 3bffaf99bea88fe3b737879e5c1723baaa116558
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 04:53:03 2011 +0800
+
+    Add the default NULL symbol when MCLinker is initialized.
+
+commit da75f8ddc0e233134c9368ff8d61a9f1b594340f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 04:51:30 2011 +0800
+
+    refine typo of comment.
+
+commit 885c6853421646bc2e1144e3b5affc7c7d3f4244
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 04:49:53 2011 +0800
+
+    Add Layout::getOutputLDSection()
+
+    The behavior of this function is similar to getInputLDSection().
+
+commit fb9a3422a6bc8c67e6734cbd2d023c36afcb433e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 30 04:48:33 2011 +0800
+
+    Add LDSection::setIndex() and index() to remember the input and output
+    section index.
+
+commit 29af7ca5679947e78664aa7427ce15a44901004e
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Fri Dec 30 02:06:39 2011 +0800
+
+    Add missing `static' qualifier.
+
+commit 74104917ecb1dd19f75156203cec87075a761a29
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 23:57:44 2011 +0800
+
+    Implement emitSectionData.
+
+commit 25e2167c9071e3e8a37b789bb6b264ccb6c8b44e
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 23:56:56 2011 +0800
+
+    Fix a bug - the return type of MemoryRegion::getBuffer() should be wrapped by traits.
+
+commit a5a20ca578dad98d4fd00f9ba52da39f01224c2b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 23:02:18 2011 +0800
+
+    Fix bugs - the start address and size of shstrtab are wrong.
+
+commit 6682993c962600895765db65bf3cf8942b1b77b5
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 22:59:34 2011 +0800
+
+    add template partial specific Align() functions.
+
+commit 04d2cbf6e78844451c581f9017038ff8b54d8c64
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 21:13:09 2011 +0800
+
+    Fix a bug. Correct the type of a variable.
+
+    The variable is used to check if out-of-bound and should be signed in this case
+
+commit 5d9d515c96b654b6b975123bae9236f39f4cc4ba
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Thu Dec 29 20:23:35 2011 +0800
+
+    We need to check if PLT of the symbol is exist to determine how to apply while applying relocations.
+
+commit 3da54699c0df014ff7262a6b5f19602386e44fe6
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 29 20:12:00 2011 +0800
+
+    Define target dependent symbol _GLOBAL_OFFSET_TABLE_
+
+commit 6b4dd3d8ba6191f3dbf5cfab8f961217f6fbbe74
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 20:04:58 2011 +0800
+
+    Pass MCSectionData to the constructors of GOT entries and PLT entries.
+
+commit 33d9fafcda5d80777c2a7f9e059d75f5f373904c
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 19:04:30 2011 +0800
+
+    Add function Layout::getInputLDSection()
+
+    This may be useful in some scenarios.
+
+commit 9893c832962113d2c16299bfaa86c98b7d1196e9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 19:07:25 2011 +0800
+
+    Rename m_GOTPLT to m_GOT. No functionality changes.
+
+commit 83abffda34e3e677838763b6cab6a6d60e4db667
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 18:57:53 2011 +0800
+
+    Refine the function used to align an address
+
+commit 6e9ab5d4b28ce9e3476ec2c2d129d16bc587a194
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 18:02:31 2011 +0800
+
+    Remove redundent ARMGOT::applyGOTPLT() function.
+
+commit 6681d77383bedc6e19f70d0b8d3d9cc9235dfe21
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 16:19:09 2011 +0800
+
+    Handle target-dependent fragment in computeFragmentSize()
+
+    As applying relocations, we need to know the fragment offset in GOT/PLT from
+    Layout. Thus we still need to handle target fragments.
+
+commit a7aa9cf925172716c9af35f2ae4db03cee33ef76
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 17:42:14 2011 +0800
+
+    Fix a bug - ResovleInfo.outSymbol() should point to output symbol.
+
+commit b6a45fcfeeb6422bb0faa36d5ff6bbdc33ae2bb4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 17:36:33 2011 +0800
+
+    Fix some commented code in emitSectionData().
+
+commit c0e795131aa133de61d1b9b73c0b601274977fa4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 17:19:57 2011 +0800
+
+    Add begin() and end() functions in class ARMGOT.
+
+commit ba4cde9ab4af6e306a5ef1325c2e903519e76574
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 29 17:08:04 2011 +0800
+
+    Sorry to mis-merge the wrong file, ARMRelocationFactory.cpp
+
+commit b3a9172c724cc20263ee8810cc48df4c436dc5e8
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 17:03:32 2011 +0800
+
+    Add the implementation of getGOTPLTEntry.
+
+commit 65e695efbc913f2e3e03c5fd9c354fbb25a8d798
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 29 16:55:31 2011 +0800
+
+    Remove offset() in GOTEntry and PLTEntry
+
+    Now we let Layout to fill up the offset of TargetFragment,
+    so we should ask Layout for the offset to make sure the
+    offset is valid.
+
+commit 8c6e3c68519a51dd66a5a02ce7993bcdb0a633e5
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 29 16:55:16 2011 +0800
+
+    Fix typo.
+
+commit 09d4a89406b5cbaed26c6aa760881cf5a7f9c476
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 16:28:33 2011 +0800
+
+    Implement MCLinker::defineSymbol()
+
+    Because targets and driver may define standard symbols, MCLinker should provide API to do this.
+
+commit 0656aef58bdb634150e17a2e4440af6c7c41c6ab
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 16:09:31 2011 +0800
+
+    Enable layout in MCLDDriver
+
+commit fd9e6f7cd04b7250a722f33fca9f9db839bd31eb
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 15:59:11 2011 +0800
+
+    Implement Layout::layout()
+
+commit 71fc72a4902204f5f8ba494434a97df772ca5696
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 29 14:37:31 2011 +0800
+
+    Add a helper function to align an address in SizeTraits.h
+
+commit efb966bd7a23c71787ef6e40d0cd902512a801e9
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Thu Dec 29 14:50:40 2011 +0800
+
+    Fix bugs for ARM relocation functions.
+
+    Several minor changes:
+     - Fix some typo
+     - Add overflow checking
+     - Add missing addend if relocation type is RELA
+     - Refine R_ARM_THM_CALL (but still not work)
+
+commit 7e9e873f3ca8d40af3d108b8f2e2a5628d7b41f8
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 14:21:54 2011 +0800
+
+    Add new class MCTargetFragment.
+
+    MCTargetFragment will be inherited by Target-dependent MCFragment.
+
+commit 03fb34aa0cd42a4e438c4b0963302704bb8bd5f8
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 29 13:20:31 2011 +0800
+
+    Remove the class ARMGOTEntries.
+
+    Now using the class GOTEntry to represent all kinds of GOT entries.
+    This is for simplifying the design of GOT.
+
+commit 2f901ad97abfc3473d7da889e6ab2ce55644d5ea
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Dec 29 13:13:06 2011 +0800
+
+    Implement helper_get_PLT_and_init().
+
+commit 339f672b65bbab8a8d39d2eaae44f20dc2a12b55
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 10:29:45 2011 +0800
+
+    Reorder the linking process - move MCLDDriver::readRelocations() before
+    MCLDDriver::add STD/Target Symbols().
+
+    Previously on MCLinker:
+    1. readRelocations() calls TargetLDBackend::scanRelocations(), and the
+       TargetLDBackend computes the size of target-dependent tables during
+       readRelocations().
+
+    2. MCLDDriver::addTargetSymbols() calls TargetLDBackend::initTargetSymbols(MCLinker& pLinker)
+
+    3. TargetLDBackend::initTargetSymbols() calls MCLinker::addGlobalSymbol()
+
+    4. If user give a non-NULL MCFragmenetRef in MCLinker::addGlobalSymbol(),
+       MCLinker will computes the value of the symbol automatically during
+       MCLDDriver::finalizeSymbolValue().
+
+    Conclusion:
+    It's better to create all fragments before creation of target symbols.
+
+    Because we can not know if the target-dependent tables are existent until
+    MCLDDriver::readRelocations(), so we should move the function before
+    MCLDDriver::add STD/Target Symbols().
+
+commit 8ec35b29b669eaf5c1a3f846fb7d27fbc91d4957
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 29 08:51:23 2011 +0800
+
+    Add API - ARMPLT::getGOTPLTEntry()
+
+    Get an GOT entry in .got.plt
+
+commit fb0b6b11e3eb746ab0fa25794ddb6ac1fab4e530
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 04:13:21 2011 +0800
+
+    Fix a bug - ELF hash entry size should be 4 bytes
+
+commit 45f0bb3b784c206c5bbb6bd5c28320c6579ddd94
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 04:02:16 2011 +0800
+
+    Implement MCLDDriver::measureNamePools.
+
+    Now, the sizes of .symtab, .strtab, .dynsym, .dynstr and .hash should
+    be correct.
+
+commit 92877f4b0e66d3730b0732fe3232986b1afa4c15
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 03:59:26 2011 +0800
+
+    Let the input file remember if she's needed.
+
+    Option --as-needed ask linker to make DT_NEEDED tag only when the
+    shared libraries are needed. We let the input file has a flag to
+    remember if itself is needed.
+
+commit 0a93330e9c1e8a2943d07cdd6faa5adbe331bbb8
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 03:57:44 2011 +0800
+
+    Move all access functions in ELFDynObjFileFormat to ELFFileFormat.
+
+commit 184d13e6d3a63ca70ad0a94d142408ffa29007f6
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Dec 28 11:53:08 2011 -0800
+
+    Issue error in X86RelocationFactory::applyRelocation
+
+    Issue error for now.
+
+commit aae6fac46a042df992db4e19ab5cc185b0922c8e
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Wed Dec 28 11:51:47 2011 -0800
+
+    Issue error in X86GNULDBackend::scanRelocation
+
+    Issue error for now.
+
+commit fac17ed1f3f935ba2e51904e4b40103e8b8b2a95
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 29 00:19:57 2011 +0800
+
+    Add access functions in all kinds of LDFileFormats
+
+commit 6ce4a39443493366eaf45c7cf024efce97278927
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 23:17:18 2011 +0800
+
+    replace \#include<stdint.h> by \#include<llvm/Support/DataTypes.h>
+
+commit 7b443200f6e90b976d55de9ef4fd63080a37eaa7
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 22:16:22 2011 +0800
+
+    Initialize standard section map in MCLDDriver directly
+
+commit fb7d9b0151880c358815ac85297c597f2b0fc490
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 21:30:53 2011 +0800
+
+    Refine R_ARM_THM_CALL relocation function.
+
+    Add some helper functions to handle bitwise operations.
+      - helper_thumb32_branch_upper
+      - helper_thumb32_branch_lower
+      - helper_check_signed_overflow
+
+commit 0ab8fd07fd0c6da2fb65fa44542470bbf8081144
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 21:27:35 2011 +0800
+
+    ARMTargetBackend should initialize section by MCLinker::getOrCreateOutputSectHdr() directly.
+
+commit 478ba9a43a99a3cb49d5d2cca6c7960631785200
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 21:16:34 2011 +0800
+
+    Change scanRelocation from trivial virtual function to pure virtual function.
+
+    Because all target backends need to override this function, so it should be
+    a pure virtual function.
+
+commit 2dc7ee8d8dec91347d4aec062947f54563205835
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 20:55:51 2011 +0800
+
+    change the API of TargetLDBackend::computeSectionOrder() and TargetLDBackend::computeTargetSectionOrder().
+
+    Because targets rarely change the default order, so we use trivial virtual function instead of pure virtual function.
+
+    And we also shorten the function name. Use get instead of compute
+    TargetLDBackend::getSectionOrder() and TargetLDBackend::getTargetSectionOrder().
+
+commit 25836ea267fc4c730cab810a6d90022c68d88559
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 20:49:46 2011 +0800
+
+    Refine the input parameter, size, for ARMDynRelSection
+
+commit a9322558e204e54913ca6ad5fdbf12b518668d2f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 20:46:26 2011 +0800
+
+    Set section info of .rel.plt to .plt
+
+commit dfc55f3a445c4d62c48ae9da3292609102626a28
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 20:37:07 2011 +0800
+
+    Give TargetLDBackend::emitSectionData() more parameters.
+
+commit 4c19f36cf2d9585c7333d8d02819bb6558d7d695
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 20:20:58 2011 +0800
+
+    change the name MCLDDriver::computeDynSymTab() to MCLDDriver::measureNamePools().
+
+    This function computes the size of the sections - .hash, .symtab, .strtab, and so on.
+
+commit ac61247f5a65e509f22199d16bc1fe157fb3c8a9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 19:36:10 2011 +0800
+
+    Get PLT/GOT offset by calling offset()
+
+    For target dependent section, Target is responsible to
+    maintain the MCFragment (Entry) offset. Layout consider
+    only the section size and has no idea about fragment
+    offset.
+
+    So, when applying relocation, instead of asking Layout
+    for the offset of PLT/GOT entry, we extract from the
+    entry directly.
+
+commit ded73047105b31e8bc1d8b9973407b19a574958e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 18:03:14 2011 +0800
+
+    Revert ARMRelocationFunctions.h and ARMRelocationFactory.cpp
+
+commit b2ca6a16105575802642b3da6fc0afc5b0e156f2
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 17:56:50 2011 +0800
+
+    Implement ELFWriter::getSectInfo()
+
+    transfer the responsibility of "set sh_info" from writers to LDSection creators.
+
+commit a0be4a4883e2b03d817b87a48587708ffa7721ee
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 17:36:55 2011 +0800
+
+    Reorder if-else statements, no functionality changes. MCLinker should emit PLT SectionData before emitting GOT.
+
+commit bfd99640d46a281fed6e611c539715f295325887
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 17:36:59 2011 +0800
+
+    Implement ELFWriter::setSectLink()
+
+commit d274d7fb9c73a06c0b46f76902e07106af92184a
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 17:28:03 2011 +0800
+
+    Refine ARMRelocationFunctions.h.
+
+    From now on, we need only one modification in ARMRelocationFunctions.h
+    when implementating a new relocation function.
+
+commit 310eefcec21d54ac779dd0fcf873a6f2ae72545a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 17:17:56 2011 +0800
+
+    Perform applyPLT0 and applyPLT1 in emitSectionData.
+
+commit 9c4aa89aa53c1d348229c761fe2ac533fb188a9e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 17:11:31 2011 +0800
+
+    Add member m_EntryBytes into ARM/MipsDynRelSection
+
+    1. Add entry size as an parameter in constructor of
+       ARM/MipsDynRelSection
+    2. While reserveEntry, update the section size in LDSection
+
+commit 11fbe3f506158cb8a71d73bd5b0d395c7d686cf3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 17:06:47 2011 +0800
+
+    ARMPLT::applyPLT0 applies a value to PLT0 Entry without parameters.
+
+commit 12b04f8ccc3383f2b2325eaeae583e60dd186b96
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 16:57:54 2011 +0800
+
+    Fix bug: Use bitwise AND, not logical AND.
+
+commit 00a411d4015fa2dc9488c5ebd6f8bea498b14731
+Merge: a9ca660 3da5c7b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 16:20:15 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 3da5c7bdf32a1cdd99ce5e011ad3dfeb420c1ab5
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 16:16:14 2011 +0800
+
+    Implement emitSectionData for ARM GOT and PLT.
+
+    Currently I comment some code.
+    I will uncomment them once the size of MemoryRegion is not zero.
+
+commit a9ca660a50cb6bc688b5f08a3bcf2a86a861c134
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 16:15:34 2011 +0800
+
+    Remove API - TargerLDBackend::getRelocEntrySize
+
+    Relocation entry size is both target and format dependent.
+    Let target handles the size itself.
+
+commit 1da35041319730e81faef6ac2a9a060bf9a5ed64
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 15:53:19 2011 +0800
+
+    Add LDSection::setInfoLink() for conforming to GCC.
+
+commit 7b473df9c46e9d998418f906361b9ea6791b0818
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 15:22:49 2011 +0800
+
+    Compute layout order of section in Backend.
+
+    Section order in layout is format-dependent and target-dependent.
+
+commit dc6ca94e472933344c278f97b270e9f19cc0cb0f
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 15:16:47 2011 +0800
+
+    Add API - getRelocEntrySize() in TargetLDBackend
+
+    A format dependent API to get the size of
+    relocation entry.
+
+commit d8f43156bbebc508e1805d3fa5ef1dabd014e83a
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 14:21:15 2011 +0800
+
+    Fix Bug - set pExist in getEntry()
+
+commit cad284cb9ee0267fda05ebe7880bb6f94255d4c5
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 14:10:52 2011 +0800
+
+    Implement ELFWriter::getEntrySize().
+
+commit b9ec46b43454ab7c9693113f723a0071b72e41fa
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 13:59:52 2011 +0800
+
+    Refine the function name.
+
+    Because we have too many getEntry() functions, so I change the
+    ELFWriter::getEntry() to ELFWrite::getnEntryPoint().
+
+commit dc6b852ba058d21b7fe0d62559da8a250d078fca
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 13:49:27 2011 +0800
+
+    Add LDSection pointer into GOT, PLT and ARM/MipsDynRelSection
+
+    For target dependent ouput sections and relocation ouput
+    sections, target should maintain the size of the section
+    by itself.
+
+    While reserveEntry() is called, the size in LDSection has
+    to be updated, so that Layout will get the correct size
+    to decide the section offset.
+
+    Besides, target should maintain the offset of MCFragment
+    (GOT, PLT,...entries) by itself if the offset is needed to
+    apply relocation.
+
+commit 1fe266a3b6f6344e94a3d36d459c3eef838dc45f
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 13:42:24 2011 +0800
+
+    Refine the code in Layout::getFragmentRef().
+
+commit f329318e92f6519718f22e0672a54dad6c82835f
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 13:18:30 2011 +0800
+
+    Also make sure that fragment is ordered and valid in Layout::getFragmentRefOffset()
+
+commit 102e3e1abe8cee149d23bcea2c02a1980fa5029e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 13:17:25 2011 +0800
+
+    Short cut for debuging sections.
+
+    On-device linking should not support debug sections. But, in order to
+    speed up the development process, I handle debug sections as regular sections.
+
+commit e167e013b8afa7d91361134f30a5d9af7c93b6a6
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 13:10:17 2011 +0800
+
+    Refine the code to set layout order.
+
+commit 7896922ad4d92c18ddfaee1c4ea83ba6a15e32bd
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 11:45:08 2011 +0800
+
+    Fix a bug in Layout::getFragmentRef().
+
+    As computing the size of a range (section), need to add the size of last fragment.
+
+commit 7708c0fc24bf143fe68319b8c7fd4ff7ba4e3a24
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 28 11:41:38 2011 +0800
+
+    Add code to order a range of fragments (set their LayoutOrder correctly.)
+
+    The patch for LLVM in commit, 040f5ca0cb95bf2329e1251e9bb28031d335dce7,
+    to initialize LayoutFragment in MCFragment is required.
+
+commit 58e517a42a9d9b6a56c9f6064e9bbb8ad9300e8d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 10:58:03 2011 +0800
+
+    Unify API - getSectionData() in GOT and PLT
+
+    Both return reference of MCSectionData
+
+commit 70c8782ef9d85aabdce5bca11b7e2eebb03d0022
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 28 10:50:41 2011 +0800
+
+    Modify API - getEntry() in ARMDynRelSection
+
+    Add input parameter "isForGOT" to identify if the relocation
+    entry is used to relocate GOT or normal sections.
+
+commit 040f5ca0cb95bf2329e1251e9bb28031d335dce7
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 10:21:45 2011 +0800
+
+    Update patch/LLVM.patch. Initialize LayoutOrder in MCFragment.
+
+commit 477d9de2b9f562ea9178e867d80268c302b28706
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 10:19:16 2011 +0800
+
+    Scaffolding of R_ARM_THM_CALL relocation function.
+
+commit d315bc21208d5621d4d8efca2d708e521eb7c4ca
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 09:30:47 2011 +0800
+
+    Fix bugs of ARM thm_movw, thm_movt relocations.
+
+commit 7fc904d41c54b98470d0dcaeaa7751d706a15fbf
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 10:14:31 2011 +0800
+
+    Add MCFillFragment when meeting a BSS.
+
+commit 21f92079397642341b072ff8f90345332f48f8a7
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 09:59:58 2011 +0800
+
+    Move private member data in MCFragment to protected for inheritance.
+
+commit 64e35a9817d664329a5deaaf715d9ab37352fd79
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 28 09:41:53 2011 +0800
+
+    Add new MCFragment type FT_Target for target-dependent MCFragments.
+    Remove FT_GOT and FT_PLT.
+
+commit 744ed8b01a28643ff1da44aa14149ed42ab104ad
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Wed Dec 28 09:19:26 2011 +0800
+
+    pread() returns ssize_t (signed size type),
+
+commit 4b0487ce96bfe0a73421bca2057ca4cee2aab00d
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 05:03:26 2011 +0800
+
+    Refine R_ARM_THM_MOV* relocation functions.
+
+commit 2bb6c4f20e7b9bc6d4c21f3d183cbee9b2398f98
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 04:35:13 2011 +0800
+
+    Extract common helper function for ARM movw, movt relocation.
+
+commit 383363bb1d288bd6b862e09058128d35427d99b2
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 04:22:43 2011 +0800
+
+    Refine R_ARM_MOVW_ABS_NC and R_ARM_MOVW_PREL_NC relocation functions.
+
+commit 3f51c2d057d3d5d7c14dd46ca864d5105d2ebecf
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 03:42:38 2011 +0800
+
+    Fix bugs - ELFObjectReader should put all LDSections into the input's LDContext.
+
+commit 603b0387a42db848b7ebb6e3220fd18fea9c8421
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 03:41:40 2011 +0800
+
+    Fix a bug - ELFReader::getLDSectionKind() should follow this table:
+
+    Regular	 AW	 SHT_PREINIT_ARRAY	 .preinit_array,
+    Regular	 AW	 SHT_INIT_ARRAY	 .init_array,
+    Regular	 AW	 SHT_FINI_ARRAY	 .fini_array,
+    Regular	 AW	 PROGBITS	 .ctors,.dtors, .data,
+    Regular	 AX	 PROGBITS	 .text
+    Regular	 A	 PROGBITS	 .rodata
+    Null	 0	 NULL	 ""
+    BSS	 AW	 NOBITS	 .bss
+    Note	 A	 PROGBITS	.interp
+    Note	 AW	 DYNAMIC	 .dynamic
+    MetaData	 0	 PROGBITS	 .comment
+    NamePool	 A	 DYNSYM	 .dynsym,
+    NamePool	 A	 STRTAB	 .dynstr,
+    NamePool	 A	 HASH	 .hash
+    NamePool	 0	 SYMTAB	.symtab,
+    NamePool	 0	 STRTAB	.strtab
+    Relocation	 A	 REL/RELA	 .rela.dyn, .rela.plt, .rel.dyn, .rel.plt
+
+commit ad55c14f39a890182e5702b508e59817dd1fcb0e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 03:38:50 2011 +0800
+
+    add MCLinker::getOrCreateOutputSectHdr()
+
+    In some cases, it becomes convenient if MCLinker can get or create the output
+    section and return it directly.
+
+commit 3e9875d283ab7366a0e5273338e60fd6d6205ee0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Dec 28 03:23:58 2011 +0800
+
+    Code cleanup.
+
+commit 194eff80a5bd3f109548f1092904fba335dc39ea
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 02:27:55 2011 +0800
+
+    Implement R_ARM_MOVT* and R_ARM_THM_MOVT* relocation functions.
+
+commit 680035f66033ab667c66102207250e89f7ce64df
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 01:56:47 2011 +0800
+
+    Let writers can emit correct section header and tables.
+
+commit 54541820a23ecebb3be2d73f00ddd62c9e03dbc2
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 01:55:26 2011 +0800
+
+    Add LDSection::setKind(). Writers want to esure LDSection::kind() is also correct.
+
+commit 45433c157107cc762516c6045ae7afe1f96bc8da
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 01:54:37 2011 +0800
+
+    increase the default number of the program header entries.
+
+commit 21817979918904927121a4e86ce3080207bf60d0
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 01:49:44 2011 +0800
+
+    Decrease the warning level. When a weak symbol is marked by a dynamic defined symbol, it won't issue warning.
+
+commit 91331253ad64c0adc2eb2a5712b82fa72facb017
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 28 01:48:58 2011 +0800
+
+    Add a new function LDContext::getSectionIdx - get the section's index by name
+
+commit e3735a39ad183bff6cbcaee31bc0f0f587d27cf8
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 01:50:08 2011 +0800
+
+    Add ARM TLS relocation function which LLVM may generate.
+
+    Though, we don't support it,
+    we still have to show error, rather than keep silent.
+
+commit 095825be0c84e71a142668ec8d802a8ebd01018f
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 01:34:21 2011 +0800
+
+    Coding style: 80-columns.
+
+commit 9445f38aa166c6bfbf88b878ec635d69318a1472
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 01:07:54 2011 +0800
+
+    Implement R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVW_PREL_NC relocation type.
+
+    Besides, merge MOVW unchecked (_NC) relocations into one
+    function, since their behaviors are almost same.
+
+commit 406eda48bf763dccdfe91bdac62af78083b810f2
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 00:55:43 2011 +0800
+
+    Implement R_ARM_MOVW_PREL_NC relocation type.
+
+commit fa8c9091bd937bd8e66721d076981d9994cae743
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 28 00:34:47 2011 +0800
+
+    Implement R_ARM_MOVW_ABS_NC relocation type.
+
+commit 59768ad2fc0980bc532e65e5b034a67620df12fd
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Dec 27 23:19:02 2011 +0800
+
+    Remove unnecessary functions of GNUArchiveReader.
+
+    Refine the code & Remove unnecessary functions.
+
+commit 5b6640ea2a376f99b26c876b8d30d2bfb8714505
+Merge: cde246a 868694a
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Dec 27 23:15:59 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 868694a9bda6f56c15ae0e8791117d86fc1fec78
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 27 23:11:53 2011 +0800
+
+    Revert "Implement R_ARM_PC24 relocation type."
+
+    This reverts commit c87a5f2e7f04d0a055be56c32f8e492913197a06.
+    Sorry that I misunderstood the spec.
+
+commit 5bdec948675c82e62d12c03ae7d48767c1e1ae39
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 22:19:33 2011 +0800
+
+    Not compute the size of Reloc, GOT, and PLT fragment.
+
+    Let Backend handle this. Layout and Writer only need to know llvm Fragments,
+    RegionFragment, and total size of Reloc, GOT, and PLT from LDSection.
+
+commit c87a5f2e7f04d0a055be56c32f8e492913197a06
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 27 21:30:09 2011 +0800
+
+    Implement R_ARM_PC24 relocation type.
+
+commit cde246a667964c47ee943d8adcd5be5f43720c0e
+Merge: cc0fbc5 bd84a4d
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Tue Dec 27 18:49:11 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 14d7bf7c90c6aeb2d86fbcae7a6982fdb501fb21
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 20:55:54 2011 +0800
+
+    Add R_ARM_CALL and some PLT helper functions.
+
+commit 73295df697a0ef738c828c99fb07edd40198aa7a
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 20:54:39 2011 +0800
+
+    Add sign extend helper function.
+
+commit b112fdac7aeddfd1d845ca3949fe685b4b880d93
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 19:42:27 2011 +0800
+
+    Implement Layout::getFragmentRef() and Layout::getFragmentRefOffset()
+
+commit a027e466cbe5faf59721b306b0dc0379058466eb
+Merge: cc0fbc5 bd84a4d
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Tue Dec 27 18:49:11 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit cc0fbc5a0eb54e1d3c6ed579054a7a099ad0c92f
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Tue Dec 27 18:46:57 2011 +0800
+
+    std::stringstream needs <sstream>
+
+commit bd84a4dadf172e81ce7da79c0a8651d6d4416a49
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 18:46:27 2011 +0800
+
+    Compute the size of MCRegionFragment.
+
+commit aeee708ab045c5c578d94a571c3b62278e1ec3a0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 17:53:59 2011 +0800
+
+    Merge fix for relocation API issue.
+
+commit 386243f21a3e2ac83ad28c07c3e1080bfc59afdf
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 17:05:15 2011 +0800
+
+    Rewrite R_ARM_GOT_BREL.
+
+    Apply relocation must focus on apply the "pReloc" relocation. Initialize
+    GOT, PLT, and dynamic relocation can done by helper functions. Because
+    those operation basically is Relocation type independent.
+
+commit 79c8ca3952615702a038b9bc7cc8224cdbd1a755
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 15:55:40 2011 +0800
+
+    Fix helper_GOT(section offset+fragment offsest).
+
+commit 94cb09aa2bc372660e2c238e36fc9824ed2c9bb6
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 15:44:36 2011 +0800
+
+    Remove rel apply function's pParent constent.
+
+commit d18676dbdb3a398001fba2ed5bf7fd65d93e1e66
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Dec 27 15:34:35 2011 +0800
+
+    Fix typo.
+
+commit 86846f7389eec716042f7caf827e263c06bfd193
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Dec 26 22:42:30 2011 +0800
+
+    Implement ARM relocation: R_ARM_GOT_BREL.
+
+commit 8fd4a499866676b85f801205fa5f8a9957e07460
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Dec 26 22:34:48 2011 +0800
+
+    Add ARM relocation helper functions.
+
+commit c0f3c5a687adcec37cff147f28b7cd7832a16f20
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon Dec 26 03:44:18 2011 +0800
+
+    First priority arm relocations.
+
+commit be5a709c5918ee07a76ad847f028b84a9cb8ce05
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 17:43:52 2011 +0800
+
+    Fix a bug - Writer should use LDSection::kind(), not LDSection::type(), to determine if the section needs special handling.
+
+commit 9ee0f2379307072fb2dcdfa9d42a297d9ddb64a8
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 17:34:57 2011 +0800
+
+    Implement readers -
+    1. ELFDynObjReader::isMyFormat() and endian()
+    2. ELFObjectReader::isMyFormat() and endian().
+
+commit d9834d67410416b522cbaacc226978e99bb84751
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 17:33:50 2011 +0800
+
+    Fix a bug - ELFReader::fileType() reads the opposite endian.
+
+commit 0864b0c13f96891c2b4dbc0333c77a4d8adbf18c
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 16:58:19 2011 +0800
+
+    Implement some functions in ELFReader.
+
+commit e3c302fe3c0e0e82af035641fad3f8ad6a87c74e
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 12:47:53 2011 +0400
+
+    Turn on MIPS LDInfo attributes and constraints.
+
+commit ce007f50cb4bdd4bfb91494cecd96b9c1eac1b82
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 27 15:49:07 2011 +0800
+
+    Enhance applyPLT1().
+    applyPLT1() now is able to apply correct values without parameters.
+
+commit eeb44651bedcd420c455c5d889d2de9c1225d76f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 15:33:16 2011 +0800
+
+    Separate ELFReader::createELFObject() into createELF32Object() and createELF64Object().
+
+commit 26160f290eb376486323368c149a18a85b572222
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Dec 27 15:07:16 2011 +0800
+
+    Unify API getEntry()
+
+    Let GOT has the same input parameter type with
+    PLT and ARMDynRelSection.
+
+commit 50dc0f97dd8298d06bbeab193f3accee63cf2f6a
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 14:29:13 2011 +0800
+
+    Fix a bug - getLDSectionKind() can not return LDFileFormat::Debug.
+
+    In ELF, debug section is ruled by prefix 'debug', not type.
+
+commit 788fe3a6b7a58f267a055f5dde09c90e1c27e6bf
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Dec 27 13:09:02 2011 +0800
+
+    Fix bug : assert when m_pTargetData is NULL
+
+commit 1ed052e43da5b90a10c9e85a56c759c726f7206d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Dec 27 13:05:00 2011 +0800
+
+    Add setSymInfo() in Relocation
+
+commit c438c453c3d370a5d847ce30f5a08af7c8f759d0
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 27 11:50:39 2011 +0800
+
+    Fix a bug - MCFragmentRef should have forward declaration of class Layout.
+
+commit d0b1762356e1e1ef3d91b2172a1b0d360be75b71
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 10:24:02 2011 +0800
+
+    Add implementation of layout functions to lay out a fragment.
+
+commit dd59a29fcb34ce87d072f1c93dec6fa65de83fe8
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 09:54:01 2011 +0800
+
+    Follow llvm::MCAsmLayout to add some layout functions in Layout.
+
+commit edda9ee39c4344fb5c3754434119ad45a9fe3f43
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 27 09:44:08 2011 +0800
+
+    Add mcld::computeFragmentSize for Layout or Writer to compute fragment size.
+
+commit d8bb922d9bfd2cd49210cac36da979b6e6b5f7e6
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 02:35:26 2011 +0400
+
+    Replace EF_MIPS_ARCH_32 by EF_MIPS_ARCH_32R2.
+
+commit 2291b81f31b63b8b348bf4a72b98e241d87cd3c6
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 02:04:40 2011 +0400
+
+    Add placeholders to .MIPS.stubs and .plt entries reservations.
+
+commit 4997cca774f01db26f8409e3f97a310186f24946
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 01:52:37 2011 +0400
+
+    Implement aux functions to create MIPS specific sections.
+
+commit 478439a1992166ddc1874ceaf23dbbe02e27b99e
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 01:25:53 2011 +0400
+
+    Implement entry reservation for MIPS .rel.dyn section.
+
+commit 0b960b4748adc67a2571af69ed6bffbc11ebd369
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 27 00:01:28 2011 +0400
+
+    Move GOT section creation to the separate MipsGNULDBackend::createGOTSec() method.
+
+commit 8fd36ac29d938580302a5332ef40bfce3f19d10c
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Dec 26 23:38:42 2011 +0400
+
+    Initial implementation of MipsGNULDBackend::scanRelocation().
+
+commit bc294aa93d072bba5eccbb1ec9c9c42b8f194bbc
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Dec 26 23:27:29 2011 +0400
+
+    Use std::auto_ptr to ensure that an object will be deleted.
+
+commit e2a263e42a309ed7022826406b93ff4f2c067f32
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:27:18 2011 +0800
+
+    implement MCLinker::emitOutput()
+
+commit edc84403dec6d5f906ed502dc1fce16414c8e054
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:25:08 2011 +0800
+
+    Redefine LDFileFormat, and implement the basic shared object writer.
+
+commit 8e4a41c38c083f242aa6e3b3c7fd7dbe860bdfe5
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:23:51 2011 +0800
+
+    Implement -e options.
+
+commit 4f2d8cbc447bef3e2c1bf95e6b6bb29476a593ba
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:22:51 2011 +0800
+
+    Fix a bug - previous commits forget to add GNULDBackend
+
+commit 23ede9002a41baa4f1c1b56d64540deb5f2b1ff2
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:21:15 2011 +0800
+
+    Add some fields for emission of the ELF header.
+
+commit 2518990a1bad651c9c9c59bbfb55782301e89225
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:19:22 2011 +0800
+
+    MCLinker redirects StrSymPool to MCLDInfo
+
+commit b5e2d70aab39eb148b85cb3e366cf988ab5bf7f5
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:18:29 2011 +0800
+
+    Enable -e options in MCLinker.
+
+commit 29c1c4232a0dd9a4273c4f584f861806f1cc61f1
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:17:30 2011 +0800
+
+    Add LDSection::hasSectionData().
+
+commit 2de4610459a3d0ce2c6b374cdc8412faa6044f9d
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:14:39 2011 +0800
+
+    Use only one LDContext::symtab()
+
+    dynsym() is redundant.
+
+commit a3aa37557681f1efec7a96022a972813bf6e09f5
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:10:46 2011 +0800
+
+    Add StrSymPool::addSymbol and addInfo functions.
+
+commit b5947fd364f2cdb9fda2e6b3a5df60b2efebba50
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:09:46 2011 +0800
+
+    Let StrSymPool can get from MCLDInfo.
+
+commit f089c45eb8ec68a317b8bd8552309b9167af6c08
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 26 22:08:36 2011 +0800
+
+    Add some basic functions in Layout.
+
+commit da248b3c9b7a278defce8c6a92d89e8ebaec8988
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 21:10:00 2011 +0800
+
+    Enhance GOTIterator.
+
+commit c34cac884e406a7946242519d1b95f072c504320
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 20:08:33 2011 +0800
+
+    Add a member function getPLT0().
+
+commit 260391b4f21d4ae11787b55321dcff064dbd2d44
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 19:55:09 2011 +0800
+
+    Implement GOTIterator.
+    GOTIterator is used to traverse all kinds of got entries.
+
+commit f50ea946c3740b18be4fd2d0451eaa2164361cb3
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 26 17:54:17 2011 +0800
+
+    Let Relocation be a kind of MCFragment with type FT_Reloc
+
+commit 314174d230658fdd6dfb62436712f5aba4711963
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 26 17:10:57 2011 +0800
+
+    Change the type of Offset in MCFragmentRef to uint64_t.
+
+commit 9d346b4d9295b9e369a7530fad86fa972459307e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 26 17:04:41 2011 +0800
+
+    Implement addInputRange in Layout.
+
+commit 354a447881b4edf663b859518f15c4ed56c0ee58
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 26 15:52:46 2011 +0800
+
+    Refine the structure for input range in Layout.
+
+commit b270dd5d0b06e141ee43fda04c6b4341bbd38690
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 16:27:45 2011 +0800
+
+    Add new MCFragment type FT_Reloc for relocation.
+
+commit 70b7183942d92b6fb93caa6bb4675fe922c07704
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Mon Dec 26 15:52:30 2011 +0800
+
+    Clean up logs
+
+commit aef214663d6584db5b08d6e9bbe9409c34668132
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Mon Dec 26 15:18:39 2011 +0800
+
+    Add program header write out function.
+
+    Program header table sometimes has target-dependent seqment entries
+    for different architectures, currently we use swithes to generate
+    these special segments for now.
+
+commit a9c0210bcdc2ba66b3715261e6f71f15ad100137
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 15:34:08 2011 +0800
+
+    Fix coding style, no functionality change.
+
+commit 056e1aa7f9a303155d3a762e72f3d9a9821ffeb6
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 26 15:32:05 2011 +0800
+
+    Add const version of getSectionData in LDSection.
+
+commit 670f6d30cb243a18b5ac5202df94e692fc4340d9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 15:30:22 2011 +0800
+
+    Update patch/LLVM.patch.
+    Add missing namespace mcld to class Layout.
+
+commit a6cc3d29bf567a42b911ce3759678ab410cd1da2
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 14:45:29 2011 +0800
+
+    Update patch/LLVM.patch.
+    Make Layout be friend class of MCFragment and MCSectionData.
+
+commit 2c6c30e32504e6fc5d98cd134db51d44aac760ee
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 26 13:44:30 2011 +0800
+
+    Add the Implementation of ARMGOT::getEntry, applyGOT0, applyGOTPLT.
+
+commit 4286be84bfadb83c974d71b87327eca6dcfa127b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 26 13:04:28 2011 +0800
+
+    Implement getPLT(), getRelDyn() and getRelPLT() in ARMLDBackend
+
+commit 295873c9fa6d81adfb438a501f3cd9711dda705d
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 26 11:32:02 2011 +0800
+
+    Add error message in ScanRelocation
+
+commit b4a76b03b70389c37c98f6bc168fdeaee1f89088
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 25 00:43:07 2011 +0800
+
+    Because MCLinker::createSectHdr() and getOrCreateSectionData() always return a valid result, I change their type from pointer to reference.
+
+commit e9be486a629c21e6e3861b21cea901ecf5cbabf4
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:23:49 2011 +0800
+
+    Fix a bug - every section header should be added in its LDContext::SectionTable.
+
+commit fa72975274447ca83c1553d078de9d5fc2aee0b2
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:23:07 2011 +0800
+
+    ELFReader::getSectionType should return LDFileFormat::Debug type.
+
+commit 889108d49275551a377e3d531fc1fddc587e3517
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:21:43 2011 +0800
+
+    remove obsolete getOrCreateSection() in LDContext
+
+commit c64785986f3feffd1aa0995d8292040e67bdf054
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:21:00 2011 +0800
+
+    Fix a bug - every pointer should be initialized as zero.
+
+commit 7fb5bd6ccfc84a4088156286d5575bdf020b065e
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:05:37 2011 +0800
+
+    Add a new kind - LDFileFormat::Debug
+
+commit fadc31f96b1421789f834cb5a2ce88b0fba3e4f0
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 23:00:18 2011 +0800
+
+    Refine the warning message when read a symbol with unsupported type.
+
+commit b495dc73016cb3648e81ea9f8d37dd8c99fe47f7
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:48:25 2011 +0800
+
+    Fix a bug - add dynamic symbols should enable the `pIsDyn' paramter.
+
+commit 44313e81484300ed0c0a84aa928180a04d196870
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:47:53 2011 +0800
+
+    Fix a bug - dynamic ABS symbol should be handled as dynamic defined symbol.
+
+commit 4a140c1a885ecc12007cfc5acdcf3e9b6a8bd9b4
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:31:46 2011 +0800
+
+    Fig a bug - should let LDSymbol::FragmentRef in ELF shared object empty.
+
+    sh_shndx of symbols in dynamic shared objects will eventually be set to SHN_UNDEF.
+    Therefore, readers do not need to read it.
+
+commit a882ff25989cd64be364b29cfdf70d38c139c556
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:28:38 2011 +0800
+
+    Let the error message of invalid section clearier.
+
+commit 4db79fc61732f32e673818b78bad346699b64657
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:20:02 2011 +0800
+
+    Because we have no RTTI and exception, we should handle the out_of_range by ourselves.
+
+commit 602829648da18410c98e59448b35df863c9af819
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:18:51 2011 +0800
+
+    Refine the symbol-adding functions.
+
+    1. Add ABS symbol
+    2. set symbol's fragment reference
+    3. resolve some conflicting definition between rslinkers and llvm/Support/ELF.h
+
+commit 9f3ccf91ad92cfd5ac04cb18e3076248f183da3b
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:17:34 2011 +0800
+
+    Add LDSymbol::setFragmentRef(const FragmentRef& pRef) for conventient.
+
+commit f9f1d91a209686c994aab1aefff009b9339ae56f
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:16:01 2011 +0800
+
+    fix bug - MCLinker and StrSymPool should provide ResolveInfo::Type as one of the parameters in the adding-symbol functions
+
+commit 841248330380b9c2b1a392e082ef0784a1b83fc9
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:14:37 2011 +0800
+
+    open Layout::getFragmentRef API.
+
+commit 6360a725302d5ec2a496bfbe7855597eec130d74
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:11:57 2011 +0800
+
+    Because in current LLVM, some variables, such as STB_LOOS, etc., are defined,
+    I remove them from rslinker/ELF.h.
+
+    In order to avoid `expected unqualified-id before numeric constant', I define
+    these variables by enum, rather than \#define.
+
+commit eb56740fc14caa95f3ee17a4f7b9d9a19922de5a
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:03:08 2011 +0800
+
+    Fix a but - ResolveInfo::overrideAttribute() should override low_16 bits of bitfield.
+
+commit b9a3414dbf1a33fff097f615245347475486c16c
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 24 22:01:25 2011 +0800
+
+    add MCFragmenrRef::assign(const MCFragmentRef& pCopy) for convenient.
+
+commit a96ea168307fb1551bb0cda8319d668ff325b72b
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 23 21:49:15 2011 +0800
+
+    Create .plt, .got, .rel.plt, .rel.dyn Section and SectionData
+
+commit 1f870f1a4516370021ca1aafe4d8cafc3bffac07
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 23 21:22:47 2011 +0800
+
+    Implement ScanRelocation in ARMLDBackend
+
+commit bfadd67b5dd4adf7c627c5c4ffc7cbda8b8f835c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 23 21:20:14 2011 +0800
+
+    Create ARMDynRelSection
+
+    The dynamic relocation table for .rel.plt and .rel.dyn sectoin
+
+commit 334cd9bbf3580d5496aeafeff633093991c32f02
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 23 21:00:55 2011 +0800
+
+    Add addMapping() in SectionMerger.
+
+    When we need to create a section header for output LDContext, we should add a
+    mapping in the mapping table of SectionMerger.
+
+commit 704c3720fc2d25da8a1fa70eaa82ffa898e25dbf
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 20:16:40 2011 +0800
+
+    Remove TODO and fix a bug in ARM::getEntry().
+
+commit db8508c939ea1bf4073fcf7d1c665200d7594701
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 23 20:08:37 2011 +0800
+
+    Add find() in SectionMerger.
+
+commit e7f12246d4b47749b7a2157b8929c8166e367747
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Fri Dec 23 19:55:28 2011 +0800
+
+    malloc() should in stdlib.h, and many BSD systems don't have <malloc.h> now,
+
+commit b6d299d0eab71ab6e44fe820ae8b21409bc5d283
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 17:59:22 2011 +0800
+
+    Enhance ARMPLT::reserveEntry().
+
+commit a0df9590e866888238f16f96368992c78f35ef6e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 17:34:08 2011 +0800
+
+    Implement several ARMPLT methods.
+    They are applyPLT0, applyPLT1,and getEntry.
+
+commit 67c632f5ef29f7265eef50a6a80c067af7c241c7
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 16:27:25 2011 +0800
+
+    Fix a bug -
+    Typo, I should use CommonBlock rather Common for the Type.
+
+commit 8598343dee8f6bcba51cf1fbf105082123620edc
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 16:12:22 2011 +0800
+
+    Add ResolveInfo::Common for common block.
+
+commit c8ec48b211ae5411c7a56116a279caff3dbd883d
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Fri Dec 23 10:34:17 2011 +0800
+
+    Write out section data by iterate the section header.
+
+    Assume layout is done correctly, now we can start to write section data.
+    Use LDContext::const_sect_iterator to iterate all LDSection and get
+    its MCSectionData. Currently, we have not really write section data
+    to the output file.
+
+commit 3be6b667c849092fa342a6f297a10d9864db81f2
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 15:52:08 2011 +0800
+
+    Open MCLinker API to add relocations.
+
+commit 075fbe5c4cf1dcb0d00cfd1bce647590de751521
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Fri Dec 23 15:02:28 2011 +0800
+
+    Add alignment information in section header table.
+
+commit 8f6382e415272fa13277f1051056545bfd7cadcf
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Fri Dec 23 14:02:13 2011 +0800
+
+    Support read sections from ELF-Object.
+
+commit b6f208cfc7d7bfb74e7e020f25edca4704fd1e89
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Thu Dec 22 20:12:59 2011 +0800
+
+    Support ELF-Relocation in ELF-Object.
+
+commit e813f3423d33f4659352a970a67e2fbb466e3ba8
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Fri Dec 23 14:36:44 2011 +0800
+
+    Refine ELF header write out function.
+
+commit 4ed0c1dd2ae53fde8ea0739bd2edef08a71fcac9
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 14:21:35 2011 +0800
+
+    Fix bug -
+    StaticResolver will jump out of the table.
+
+commit 47c946561772f56a91f6b2d0f2462cec26e18054
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 14:12:34 2011 +0800
+
+    Add Resolver::Result to member the result of symbol resolution.
+
+commit dff7a00f6c4d9f7bf175ea708f9e8718bc29083f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 13:36:25 2011 +0800
+
+    Make PLT own an MCSectionData pointer as GOT rather than inheriting it.
+
+commit 41d11b46b66ccd21c5aa16e728cb92b43ebd664f
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 23 11:44:03 2011 +0800
+
+    report an internal error when StaticResolver fails.
+
+commit 1d7b2f4aece1ab876f9b9addda822b52f771cd4d
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Fri Dec 23 11:05:36 2011 +0800
+
+    Fix typo.
+
+commit 81eefc392b18ac213d9b6e13c2de095025012bda
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 10:47:32 2011 +0800
+
+    Make GOT own an MCSectionData pointer rather than inheriting it.
+
+commit b75c07654bfa79acb34d9e8d74ad56a8ca2b9d02
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Fri Dec 23 09:28:57 2011 +0800
+
+    [Style] Remove 'using namespace std' and #include <iostream>
+
+commit 94b0a18372c1f4f32bcad850959929a4b5e2fe26
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 23 09:39:01 2011 +0800
+
+    Move initPLTEntry to private.
+
+commit 7948f2fbcd77d6ad49903c4ae25d857b377904a5
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Fri Dec 23 09:16:38 2011 +0800
+
+    Refine the code.
+
+commit ff21d7cce6ca4401298dba08e141b8ddd12362f3
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 21:43:06 2011 +0800
+
+    Initialize the pointer to MCSectionData in LDSection as NULL.
+
+commit 563614a22083cb5590a195bb9e1942af773be972
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 21:24:21 2011 +0800
+
+    Implement getOrCreateSectData in MCLinker.
+
+    Any who request a MCSectionData from MCLinker should base on a LDSection first.
+    And SectionMerger in MCLinker will try to find a suitable MCSectionData in return.
+    (see commit, 162fb771a9d9e351a45aeeba2a7c7433863694b5)
+
+    And the pointer to MCSectionData in input LDsection and/or in output LDSection
+    will be set properly also.
+
+commit dcf956efa48e2c4581bf4f3c9ef848f36259eba0
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 21:20:22 2011 +0800
+
+    Add SectionMerger in MCLinker.
+
+commit 162fb771a9d9e351a45aeeba2a7c7433863694b5
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 20:49:54 2011 +0800
+
+    Refine SectionMerger to fit current design.
+
+    SectionMerger would use
+    1. SectionMap, a "Name-to-Name" map from input substring to output section
+    2. LDContext of output, who has the output LDSection list
+    to build up another map from input substring to output LDSection.
+
+    And then from the output LDSection itself, an associated output MCSectionData
+    can be gotten. Furthermore, section mergeing is done in this way.
+
+    For example, reader requests one MCSectionData for .text.foo, and another one
+    for .text.bar, and SectionMerger returns the MCSectionData of .text in output
+    directly.
+
+commit bdb417e301a5f7376b09b8502dc648aa3c3e1b9a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 22 21:28:50 2011 +0800
+
+    A quick patch.
+    Avoid passing instances of derived classes of MCSectionData
+    to MCFragment constructor, this results in segmentation fault.
+
+commit 80dd5b73b833cbca0118d3d2bca79268590133ff
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 22 21:14:57 2011 +0800
+
+    Modify API - TargetLDBackend::scanRelocation
+
+    Add parameters pLinker and pType
+    pLinker - we need MCLinker to create LDSection and MCSectionData
+    pType - the output format type
+
+commit bba7f054c9e0d065796fba853ae04a8459f5b93a
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 22 20:37:55 2011 +0800
+
+    Update .dynsym and .dynstr section header.
+
+    Write the correct sh_offset and sh_addr.
+
+commit 3605d5accef1ed0067d351fe97283478da0d76e5
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 22 20:39:48 2011 +0800
+
+    Add API - produceEmptyEntry() in RelocationFactory
+
+    When ScanRelocation, we need to create empty entry for
+    dynamic relocatoin (ouput relocation).
+    These empty entris occupied memory space but all their
+    contents are set to zero.
+
+commit af4db020d4e4e54b445052c293b2b43b45f197a4
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Dec 22 18:10:16 2011 +0800
+
+    Fix some typo and comments.
+
+commit a94967b9a9989f8dc44c64844d7719c214525192
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Dec 22 17:31:49 2011 +0800
+
+    Fix section header table sh_name index assignment issue.
+
+commit c82184bbb81bb03caf5ade27d508ae2509edd1e6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 14:52:40 2011 +0800
+
+    Let bitcode is a kind of position-dependent option
+    The embedded libraries also be treated as a kind of namespec.
+
+commit 466b0cdc4a3b225e25c47c6ed3664cadea4fccf7
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 22 14:41:07 2011 +0800
+
+    Implement ARM GOT.
+
+    There are three kinds of got entries in .got section,
+    they are reserved got entries, got.plt entries, general got entries.
+
+    The top of .got  section is reserved got entries,
+    and got.plt entries immediately follow behind reserved got entries,
+    the last are general got entries.
+
+    We store got entries in three separate ARMGOTEnties instances, which inherits MCFragment,
+    to avoid sort or rearrangement when writing out by the order.
+
+commit 59b6ca8c30e79e4ab266fc9d24e66b37cd6a6f08
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 22 14:35:27 2011 +0800
+
+    Add sectionStartOffset() to get section's start offset in the output file.
+
+commit 3fb6408e6459c4350f177a6af4a450ff2198a694
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 13:17:34 2011 +0800
+
+    Change the type of first parameter `pInputFilename' from const std::string& to const llvm::cl::opt<std::string>&
+
+    Because the input bitcode should be position-dependent, we let the input bitcode keep its position.
+
+commit a2f95fdceef97f926d2ba0800895dfb15df8ceaf
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 13:14:30 2011 +0800
+
+    Add ARM dependent section mappings in ARM backend.
+
+commit f80e8451062a6d5abc181c06f39ac015247fd87e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 11:48:38 2011 +0800
+
+    Initialize standard section map in MCLinker.
+
+commit f9563793a42417edccdbfbfb98e1483d07159a92
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 11:45:54 2011 +0800
+
+    Refine SectionMap.
+
+commit ea7fa03a1ee865ea96e5a8055a8f1da196d7c34e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 11:25:34 2011 +0800
+
+    Add initializing section map support in MCLDDriver.
+
+    1. MCLinker will add standard section mapping, e.g., elf
+    2. Target can also add target dependent mapping
+
+commit b83f5af023bba393b8d32521c353bae3f048ee42
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 10:55:21 2011 +0800
+
+    Refine the warning message in SectionLinker
+
+commit 72d9fe76ade287a3050525b066cb6556c99c1987
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Thu Dec 22 10:39:24 2011 +0800
+
+    Refine mapping rule in SectionMap.
+
+    Add support for
+    1. wildcard (*) to a user defined output section
+    2. if still no matching, just let a output section has the same input name
+
+commit 1afc0eed3dfdc2d83accf429675bba1889ff1043
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 10:43:02 2011 +0800
+
+    Refine the warning message of AndroidSectLinker
+
+commit 2d485e6bd0d7e7d4e3fec3a820a3bd1fd765e025
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 10:40:15 2011 +0800
+
+    Decrease the level of warning -
+    If a directory can not open, should not report fatal error immediately.
+    We should open a !isGood() directory.
+
+commit d5f4d60ae3ae23872b2dbb763e5db4f1c4f3918a
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Dec 22 09:30:12 2011 +0800
+
+    Remove function which generates testing information.
+
+commit 75a0870fab5038e8fc48c7791c246de692c14a68
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 02:17:40 2011 +0800
+
+    MemoryArea should open before calling isMyFormat().
+
+commit 023ec211429af0691f35a12cb8d7ead5efa5d73c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 02:15:41 2011 +0800
+
+    Let AndroidSectLinker to go the normal path.
+
+    Previous AndroidSectLinker use its own doInitialize for rapid prototyping.
+    This patch changes it to the original normalization path.
+
+commit 5487eb6731c23814b23dac000d3ac6945d1e60af
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 02:14:01 2011 +0800
+
+    Fix bugs -
+    MCLDDirectory::iterator should always begin from the cache.
+
+commit 4a1065cec7608c3c5beff5e0b9b46b153920e6e6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 22 02:10:15 2011 +0800
+
+    Fix a bug -
+    When HashIterator is end(), it should return immediately.
+
+commit 7fefe1136c75dbb0ccc6c10aff3934f819c5a7a4
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 21 19:15:09 2011 +0400
+
+    Check for _gp_disp symbol name in the R_MIPS_LO16 relocation processing function.
+
+commit a17c1f7d1a52f064978c189decc4f2ceb10628de
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Wed Dec 21 22:18:17 2011 +0800
+
+    Add section header table write out functions
+
+commit ec1ee45956d01c70c2bc7d9a185ece6a72f38362
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 22:08:35 2011 +0800
+
+    The function, getOrCreateSectData, should depend on LDSection.
+
+commit ebfe31b80d1342d33f1e9d1362d1a445eef0e7db
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 22:06:41 2011 +0800
+
+    Implement getSection in LDContext.
+
+commit 9d809e93e8d24ff1577aebe90c648dcc9b90e4da
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 21:56:10 2011 +0800
+
+    Changes due to the change of corresponding api name.
+
+    This is based on previous commit, 37c5f6f9e8cf38375b60d2c587b56987d0952dd9
+
+commit 37c5f6f9e8cf38375b60d2c587b56987d0952dd9
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 21:50:20 2011 +0800
+
+    Change getOrCreateSectHdr to createSectHdr in MCLinker.
+
+    Now reader also needs LDSection and all users of LDSection should get it from
+    corresponding LDContext. Thus Change the api name to prevent confusion.
+
+commit 6776482e59b8a845fe607a5362905209a06150ac
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 21:36:34 2011 +0800
+
+    Add SectionMap in MCLDDriver.
+
+commit d7409c8f8fbcc84c4ad1b85c9731e0760d0d045e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 21:28:13 2011 +0800
+
+    Add getOutputSectName api in SectionMap.
+
+    This is for user to find out the associated output section name from the
+    given input section name.
+
+commit c205ff091f4f44ca48762e9ede1b32acea5a031e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 21:24:15 2011 +0800
+
+    Create GOT, PLT, .rel.dyn and .rel.plt in ARMLDBackend.
+
+commit 49ffca6e955889e3da28895962fe64acaf2d4f55
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 21:09:03 2011 +0800
+
+    Modify Relocation to inherit MCFragment
+
+    The Relocation becomes a kind of MCFragment.
+    and the relocation table will be a MCSectionData.
+
+    Modify applying function lol6 in MipsRelocationFactory
+    to resolve the pReloc.getPrevNode() return type.
+
+commit a10467493cce08fc3c4f32f2784e6e061cfcacf3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 21 20:34:53 2011 +0800
+
+    Add a missing header file.
+
+commit 4d39006bf5bcb671598f60cc8dff084aff0b6156
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 19:12:55 2011 +0800
+
+    Add pointer back to MCSectionData in LDSection.
+
+commit 0d520ec83c443eb282b57c8df93e499a0603e42b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 21 19:06:46 2011 +0800
+
+    Add a missing header file.
+
+commit 9d76dae305e578f5a5e70bcfe0149ce1e11792db
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 17:40:09 2011 +0800
+
+    Trigger read sections.
+
+commit c0422e9a5498d7d205eedc5a3bbe243bf8cb2ba4
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 17:19:54 2011 +0800
+
+    Change ResolveInfo::value() setValue()
+
+    Because Relocation should use finalized symbol value, so we
+    move the finalized address pointed by the symbol from ResolveInfo::value
+    to LDSymbol::outSymbol().
+
+commit 3b02f5cee5027922e5230b142ac04e9094da17b3
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 16:44:12 2011 +0800
+
+    Add value in LDSymbol.
+
+commit 29ed64610896512023a5a74039d70a1cf84242c3
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 15:05:33 2011 +0800
+
+    open finalizeSymbolValue API.
+
+commit d88adc28c78f94bf49ba4c4d55e5f63b4a3223b8
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 14:09:10 2011 +0800
+
+    Add API - TargetLDBackend::scanRelocation(Relocation&)
+
+    Determine the entries such as GOT and PLT are needed or
+    not for the input relocation. If needed, create the
+    empty entries.
+
+    After symbol resolution has been done, MCLinker traveses
+    relocations to generate empty entries. These empty entries
+    are genrtated for Layout to determine the ouput offset.
+
+    For ARM and X86, GOT, PLT and dynamic relocation entries
+    are created if needed.
+
+    For Mips, GOT, dynamic relocation, GP, or other target
+    dependent entrires are created here if needed.
+
+commit 471f65e19434dab1adca03fcde8a9e8bb821db57
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 12:55:14 2011 +0800
+
+    Fix a bug -
+    ResolveInfo.info() is out of the range.
+
+commit 8d236455633bf70a05ef8ca307bf5f2ea481f002
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 11:45:38 2011 +0800
+
+    Add virtual function reserveEntry() and getEntry() to GOT.
+
+    void reserveEntry(int pNum) -
+    Before layout, we scan all relocations to determine if GOT entries are
+    needed. If an entry is needed, an empty entry is reserved by calling
+    reserveEntry(), so that Layout has ability to adjust the GOT fragment offset.
+
+    GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist) -
+    After layout is determined, we fill up the GOT entries when applying relocations.
+    getEntry() return the entry we need:
+    - An empty entry or
+    - the filled entry with pSymbol if we've filled a entry for pSymbol before.
+
+commit d01d57067f588de5483f8d24d2a0ae6c1c78a99b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 11:32:36 2011 +0800
+
+    Create API - MCLDDriver::createDynSymTable().
+
+    Because the hash table and dynamic symbol table are format-dependent,
+    I want to move related functions to TargetLDBackend.
+    Just like GOT, PLT, dynamic symbol table and hash table should be
+    backend special data structures.
+
+commit eb276864b2cbce9bed1c235b7ffa84099f640e8f
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Wed Dec 21 11:15:55 2011 +0800
+
+    Change field filesize from MCLDFile to MemoryArea.
+
+commit 97371c456b285af22905e1e7bae331d2458bea25
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Wed Dec 21 10:36:43 2011 +0800
+
+    Rewrite SectionMap.
+
+    Now SectionMap contains the mapping from input substr to output str and offset
+    for future LD Script support.
+
+commit 47a13edccd75c4930e09555307c12244e142d234
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 10:15:02 2011 +0800
+
+    Modify PLT interface
+
+    1. add reserveEntry() and getEntry()
+    2. remove virtual funtion getOrCreateGOTPLT()
+    3. remove parameter GOT section in constructor
+    4. Refine ARMPLT
+
+commit 5c01b73d614a2a8d70194374a4654f37beac63f8
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 09:57:01 2011 +0800
+
+    remove the 2nd parameter `TargetLDBackend' from RelocationFactory constructor.
+
+    All target backends have their own special data structures. For example,
+    ARM has .got, .plt, X86 has .got.plt, .got and .plt, Mips has .gp, .got.
+    Those special data structures should not dependent on the abstract TargetLDBackend
+    interface. We want that target backends themselves handle the special data
+    structure.
+
+    We want:
+
+    ARMGNUTargetBackend has functions getGOT(), getPLT()
+    X86GNUTargetBackend has functions getGOT, getPLT(), getGOTPLT()
+    MipsGNUTargetBackend has function getGOT(), getGP(), and so on.
+
+    TargetLDBackend or any abstract backend interface should not provide abovementioned
+    functions, instead, the concrete backend should provide.
+
+    In previous architecture, Luba made a mistake to put the abstract TargetLDBackend
+    as one of parameters in the RelocationFactory constructor. This wrong design forcely
+    put all target special data structure in the abstract TargetLDBackend.
+
+    So, we add getTarget() virtual function in the abstract RelocationFactory,
+    and ask all target backends should implement this virtual function by co-variant
+    return type. For example, ARMRelocationFactory::getTarget() should return
+    ARMGNULDBackend& if the relocation factory is created by the ARMGNULDBackend.
+
+    By the new design, all concrete targets can implement their own target special data
+    structure.
+
+commit d0df17e88eae111b9675126d78589f7d83ae5eb5
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 21 08:52:54 2011 +0800
+
+    Fix build fail
+
+    Remove calling hasPLT() in StaticResolverTest
+
+commit 4eafdad8dab88aa02788d40ee0aabe28bdaee522
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 21 02:23:57 2011 +0800
+
+    Remove hasPLT field and add Reserved field in ResolveInfo.
+
+commit f19050d69265cdc726fadddf6ac66c3deada7c22
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Tue Dec 20 22:31:36 2011 +0800
+
+    Convert value between ResolveInfo::Binding and ELF::Binding.
+
+commit c25457c8b8dc6fe9f2d304c722b92c25d245dc73
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Tue Dec 20 22:01:02 2011 +0800
+
+    Revert the change on LDSection.
+
+commit d658c94c07c615db760ebc0c5f3ee458b9af6269
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Tue Dec 20 16:52:02 2011 +0800
+
+    Support Reading Symbols from ELF-Object.
+
+commit e00f8d3a724850132be9bda9ac6da48cd0c8a964
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Tue Dec 20 20:59:49 2011 +0800
+
+    Add sh_link and sh_info member into LDSection.
+
+commit 2b5edd6068532c9f8588d565a54fd0289101b508
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Tue Dec 20 19:26:28 2011 +0800
+
+    Set correct file size in MemoryArea.
+
+commit c0bb3a7cc615b28c71bd9aef0096736b22d936cf
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 17:38:14 2011 +0800
+
+    Add a switch case for mcld::CGFT_OBJFile.
+
+commit a5faec9fb63a81b077c53211f1965b3f810c84f0
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Tue Dec 20 15:37:04 2011 +0800
+
+    Write out .dynsym and .dynstr section data.
+
+commit 4b3b8ee4e42a7cf5be9a2d190ac48f45c20c0b06
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 17:08:32 2011 +0800
+
+    Fix typo.
+
+commit cfce8a2a50a1c1fd589d7385fd15a9d1d5076ce3
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 16:35:16 2011 +0800
+
+    Add ARM target-dependent sections in ARMLDBackend.
+
+    add .ARM.exidx, .ARM.extab, and .ARM.attributes sections
+
+commit 8928ce5f6d36641cbde4bcd234a2c650e6878791
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 20 16:38:49 2011 +0800
+
+    Fix bug in StrSymPool and MCLinker -
+    If the symbol is existent, MCLinker should not push the symbol into LDContext.
+
+commit e840ac925a7873df198577514982cb28254cb5aa
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 16:18:23 2011 +0800
+
+    Silence warning.
+
+commit c674a30bae7f58a00d2eca02c1d47200aa5c2c7c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 16:00:58 2011 +0800
+
+    Modify building system.
+    Now MCLinker can be built without "source ./scripts/envsetup.sh".
+
+commit bfbc8dd667b0db11e16fe8e03ca2c9510d8dab98
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 15:50:02 2011 +0800
+
+    Add a missing header file.
+
+commit 31109fbf57bdb79e5c8c03b523cf564103556f89
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Tue Dec 20 15:21:15 2011 +0800
+
+    Fix MemoryArea write issue.
+
+    if file_offset+length > current file-size, we need to expand the file-size to fit it.
+    Otherwise, it will cause bus error.
+
+commit 44c8d4ed74ca74b937ef50f40b6f96fb929a1508
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 15:03:29 2011 +0800
+
+    Add getOrCreateSectData api in MCLinker for reader to map and perform section merging.
+
+    To prevent confusion, rename getOrCreateSection as getOrCreateSectHdr.
+
+commit 36d36b889b30c4bbbabc30cb70147c4f47e73486
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 14:50:06 2011 +0800
+
+    Rename SectionFactory as LDSectionFactory, and implement getOrCreateSection.
+
+commit a41acb52f445312bd151a6d022000618760e8e63
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 20 14:20:16 2011 +0800
+
+    Add new testcases for our common cases in AndroidSectLinker
+
+commit e7c6ef256623a6d67ad4a599ee0926b91526a1de
+Author: luba <lubatang@gmail.com>
+Date:   Tue Dec 20 13:41:14 2011 +0800
+
+    The function of ResolveInfo::setSource return the opposite value.
+
+commit 93ffd84ed3f19a31a9c2d5bf04034c103f49817e
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 10:36:35 2011 +0800
+
+    Use unified getOrCreateSection api instead of knowing SectionFactory.
+
+commit 9d195a1e34d4688c581d4803f4278e8ad9b573d8
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 10:17:27 2011 +0800
+
+    Clean up the code in MCLDDriver and LDBackend related files.
+
+    Remove LDContext since SectionFactor is moved to MCLinker instead.
+
+commit e142d0e6f51618527fa3c0ce80ee47990e130dc0
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 10:16:00 2011 +0800
+
+    Clean up the code in FileFormat related files.
+
+    Remove LDContext since SectionFactory is moved to MCLinker.
+
+commit c0608413669ea3d8bd812b0e04b9abb543e348b2
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Tue Dec 20 10:06:06 2011 +0800
+
+    Move SectionFactory from LDContext to MCLinker.
+
+    We decided to do so due to centralized design in 1st prototype of MCLinker.
+
+commit c77d5161023a74c16e30cd3431cce9965dfd703a
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Tue Dec 20 10:38:02 2011 +0800
+
+    Support Reading Symbols from ELF-DSO.
+
+commit fa6d740cb8d484b2fc94f16e05b95f4ab0a82722
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 10:26:49 2011 +0800
+
+    Add missing DSO and EXE switch case.
+
+commit f9ae5ad6ae862ef5caf155f976f82bce1b0d808f
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 20 03:02:13 2011 +0800
+
+    Fix README.
+
+    Use LLVM 3.1svn r146714.
+
+commit 996126a67872ec293371ebb6ff0afcb265fd3a2a
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 20 10:04:07 2011 +0800
+
+    Add a new getOrCreateGOTPLT method.
+
+commit 49f97b746b703313bd466ac84de2e91c51b38c80
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Mon Dec 19 21:33:51 2011 +0800
+
+    Support ELF Reading feature (Simplify from linkloader).
+
+commit b070963fc72b21e725f1ad43f1561a41bbfe32e4
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Mon Dec 19 22:13:54 2011 +0800
+
+    Fix build fail when no --enable-unittest option configured.
+
+commit 2bd5a857d7ca2028af8094da681d388e33922d1e
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 19 21:42:13 2011 +0800
+
+    Implement place() in Relocation
+
+    Add Layout.h and Layout.cpp into Makefile.am
+
+commit 1f0ff309b4d4b1d6f1cb57f2827c392c350c5368
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Mon Dec 19 15:57:40 2011 +0400
+
+    Fix a comment.
+
+commit d898c017e3b588d6f80e7d78d08f4965f5210a97
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 19:05:09 2011 +0800
+
+    Make git ignore ltoptions.m4.
+
+commit f3e15d2ae0cb682268de2f15c4f6edc484a96660
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 19:00:29 2011 +0800
+
+    Fix patch/LLVM.patch.
+    Silence warning.
+
+commit faee70930939d2c8d0322839af0da5f347f55c42
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 18:55:29 2011 +0800
+
+    Add MCLinker::addGlobalSymbol() and addLocalSymbol()
+
+    Standard symbol, target-depdent symbol and readers can use these functions to insert
+    and resolve symbols.
+
+commit cf36dcd5dd202c934678818811793198ee62efc0
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 18:54:30 2011 +0800
+
+    Resolver should also return the resolved ResolveInfo.
+
+commit a3bbc16ac5147c3108bf282bdba95e7a45c0207e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 18:35:52 2011 +0800
+
+    Remove redundent functions in PLT.
+    Use member functions in MCSctionData.
+
+commit 63e692db6a3ac134c265b6a6e0ffb187d31ab7a5
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 17:57:37 2011 +0800
+
+    Remove redundent headers.
+
+commit f2ed2b5917116a3d82c7221818a47767fb215550
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 17:47:28 2011 +0800
+
+    Add missing options used in LLVM trunk@146714.
+
+commit 4bcd5f4b6c936e1ea3eeae1ac966612fac562ee4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 17:03:47 2011 +0800
+
+    Migrate to LLVM trunk@146714.
+    Build MCLinker with LLVM trunk@146714.
+    Update the web page "Getting Started" as well.
+
+commit f16e41abd14acd1fa324ab497293e174b39a81af
+Merge: d95e32a 2b71280
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Mon Dec 19 16:22:10 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit d95e32a1df3a30c9fa90cec5585386f3d1258880
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Mon Dec 19 16:16:09 2011 +0800
+
+    don't track generated .m4 files
+
+commit 2b7128027392f16909afbc4f5600778d5a6c3878
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 19 16:14:38 2011 +0800
+
+    Modify PLT amd add class ARMPLT
+
+    1. Let PLT inherit to MCSectionData
+    2  Initialize PLT by incoming parameter LDSection
+       (Instead of create LDSection itself)
+    3. Add class ARMPLT which inherits to PLT
+    4. Add ARMPLT.h and ARMPLT.cpp into Makefile.am
+
+commit 964f9199fa6d287eb9a452894457cc322fa62629
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Mon Dec 19 16:14:04 2011 +0800
+
+    add generated .m4 files
+
+commit ed95bb627f3f519ec3a6c71f41279fb4f0944c50
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Mon Dec 19 16:04:25 2011 +0800
+
+    test
+
+commit b79bd46262d88553ab48f3ea80c7a2a77d0eeafc
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 19 15:15:37 2011 +0800
+
+    Add a series of init/fini sections in ELFDynObjFileFormat.
+
+commit b3be2785a7b892e9b8c3fc42adcc4c856f44dd77
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 14:31:22 2011 +0800
+
+    Move the call of `adding the target-dependent section' from GNULDbackend to MCLDDriver.
+
+commit cce2a8aca3b3dd6ebd4e419b556b7445b5eb938a
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 14:05:37 2011 +0800
+
+    For conforming to gcc on Linux -
+    Add the return type of the template proxy
+
+commit 79a63702d6f79255d3ad5c5702adfb2518417ea0
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 13:52:07 2011 +0800
+
+    Revert "For conforming to clang on BSD -"
+
+    This reverts commit 5829fb9074efcc5a693e788f0c5822082f0d0844.
+
+commit 5829fb9074efcc5a693e788f0c5822082f0d0844
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 13:41:38 2011 +0800
+
+    For conforming to clang on BSD -
+    Remove the return type of the template proxy.
+
+commit f33989cf39002f9f680706b870696f45261dc63f
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Mon Dec 19 11:36:38 2011 +0800
+
+    Fix page-align logic of MemoryArea.
+
+commit f2d10e4796b895a3ba87e9f97ebba7f26b75c25d
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Mon Dec 19 10:20:42 2011 +0800
+
+    Refine the script used by "add_class" to create .h and .cpp files from template
+
+commit 26725499f6104c7ddf1cd78e426c8396809ffddf
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Mon Dec 19 10:25:53 2011 +0800
+
+    Fix build fail.
+
+commit 1d6aeaa24ffb2dc82a8b516efb13dbdbe646b6d9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Dec 19 09:31:44 2011 +0800
+
+    A quick patch for fixing build failure.
+
+commit e3c72cbc2643120ec4b3395fc4530f88547e8fae
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 05:43:52 2011 +0800
+
+    Finish the basic method to create standard sections.
+
+    The approach is very similar to llvm::MCAssembler.
+    - We replace MCObjectFileInfo by LDFileFormat.
+    - We put all LDSections among all inputs and output files.
+    - We use LDFileFormat to create standard sections.
+    - Target uses LDContext.getSectFactory() to create target-dependent section headers.
+    - Target uses MCLinker.createSectionData() to create the section data.
+
+    ------
+    Because we have to create different type of output files.(DSO, EXE, OBJ)
+    So, we need more kinds of LDFileFormat -
+     - ELFObjectFileFormat
+     - ELFDynObjFileFormat
+     - ELFExecFileFormat
+
+    ELFFileFormat is the basic template for all ELFXXXFileFormat.
+
+    ------
+    I put LDSections into LDContext, and put llvm::MCSectionData
+    int MCLinker. Every input file has its own LDSection list. But all
+    (llvm::MCSectionData::Section* Section)s point to the output's LDSections.
+
+    ------
+    GOT should be a kind of MCSectionData and GOT::Entry is a kind of llvm::MCFragment
+
+commit 04f0003bf35756802c4db3f98bbfb97d9872eb3c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 19 05:33:37 2011 +0800
+
+    change the definition of GOT.
+
+    Let GOT is a kind of MCSectionData, and GOT::Entry is a kind of MCFragment.
+
+commit 0fa8746d3b81aa7581beac7346088595cdb31963
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Sun Dec 18 16:31:01 2011 +0800
+
+    Remove the SectionList reference in SectionMerger.
+
+    Using the section_list_iterator provided by MCLinker is enough.
+
+commit b7d7c1a757de72a7691effe57a3b80f4c85bca28
+Author: Chinyen Chou <petechou@gmail.com>
+Date:   Sun Dec 18 16:25:34 2011 +0800
+
+    Add empty class for DynObjFormat and ELFDynObjFormat.
+
+commit 5ef0cba0ffd2c15f15d2db1d9733c7c34aebb46e
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 18 16:07:03 2011 +0800
+
+    add memcpy() in MCFragmentRef.
+
+commit 013eae897c65d387e997ce9cad5a8d89c0985e5f
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 18 16:05:33 2011 +0800
+
+    ABS symbol should be handled as Global, Define symbol.
+
+commit d6a46b0cc622b1dd537cd879a76b5cf06daa73cc
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Sun Dec 18 11:14:32 2011 +0800
+
+    Change type Address from char* to unsigned char*.
+
+commit 6d64dcd4c26c8426d69b61d153e97d3a160d3ffb
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sun Dec 18 01:22:36 2011 +0400
+
+    Fix a comment.
+
+commit 75d643ff0987a675a78ce5fb93ca019fb9915cc9
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Dec 17 23:16:40 2011 +0400
+
+    Improve R_MIPS_LO16/R_MIPS_HI16 relocation processing methods.
+
+commit a1a90389549cb7caf517b2343ad4a25529c985f7
+Author: Jush Lu <jush@Jushteki-MacBook-Air.local>
+Date:   Sat Dec 17 23:57:40 2011 +0800
+
+    The section name of GOT should be from parameters.
+    The section name may be ".got" or ".got.plt".
+
+commit 3cc417bd06d2155a941ad58cfb15741a1f85ded1
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 17 21:56:55 2011 +0800
+
+    Add ABS in ResolveInfo. The symbol has an absolute value that will not change
+    because of relocation.
+
+commit 32fecd13ecb24eb9938bbf738da211ef32d4aac9
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Dec 16 16:08:59 2011 -0800
+
+    PATCH: include <sys/stat.h> before using stat
+
+    Hi,
+
+    On Fedora 15, I need to include  <sys/stat.h> before using stat system
+    call. This patch fixes it.
+
+    --
+    H.J.
+
+commit bc6734b7b32c2b9e34147c27aba9f6f548cd87fb
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Dec 16 16:06:25 2011 -0800
+
+    PATCH: Add -Wformat for -Werror=format-security
+
+    Hi,
+
+    GCC on Fedora 15 needs -Wformat for -Werror=format-security.  Otherwise,
+    it will give an error. Here is a patch to fix it.
+
+    --
+    H.J.
+
+commit b751ba2c4be668067a4070e6c3cadec9d52c2ee6
+Merge: d0976f3 71cbee1
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Sat Dec 17 17:52:39 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 71cbee1acd81241ee1908b96eb82376719b8e083
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Dec 17 11:37:13 2011 +0400
+
+    Add five new placeholders for Mips relocation handlers.
+
+commit 7b2b6957f8021aa7c9a3bf6be8370117109d663c
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Sat Dec 17 11:03:58 2011 +0400
+
+    Single equal sign is a more portable way to compare strings in a shell script.
+
+commit d0976f3fb6c701c4925b7787aa56d75e6e796a88
+Author: Jush Lu <jush@Jushteki-MacBook-Air.local>
+Date:   Sat Dec 17 12:39:36 2011 +0800
+
+    Make PLT have a LDSection.
+
+commit 6a04339e16bf68a6af0f4ff6f82d83053218aafa
+Author: Jush Lu <jush@Jushteki-MacBook-Air.local>
+Date:   Sat Dec 17 12:11:31 2011 +0800
+
+    Declare LDSection as member data of GOT.
+    Because GOT always has a LDSection,
+    declaring it as member data to avoid new, delete, and possible exception.
+
+commit cb8b34e4e3069323a97fdbcc9fc952baddccf829
+Author: Koan-Sin Tan <koansin.tan@gmail.com>
+Date:   Sat Dec 17 10:25:31 2011 +0800
+
+    README: add source ./scripts/envsetup.sh
+    autogen.sh: libtoolize is named glibtoolize on OS X
+
+commit de13226ca6f60248a20458b4347afa040e0cab77
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 16 22:37:32 2011 +0800
+
+    Add SectionMerger class.
+
+commit 3c7adc64543265f66e132997c3da23f682e5dba4
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 16 21:45:41 2011 +0800
+
+    Give SectionMap a default mappings for ELF format based on gold linker.
+
+    As reading object files that are compiled with -ffunction-sections and
+    -fdata-sections options, this will give better performance.
+
+commit ef81a97de44e75f630999d62d2ad5489b440b88a
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Fri Dec 16 16:30:37 2011 +0400
+
+    Add a couple of trivial Mips relocations.
+
+commit a58abd469d9efdb8135e8a49dcda7cf1c41a5f65
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 16 20:00:32 2011 +0800
+
+    Add SectionMap class.
+
+    SectionMap describes the mappings from input section's name (or prefix) to it
+    associated output section's name.
+
+commit 32e7c33fe84f6a2f1d7e9ecd589b121165483ee9
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Fri Dec 16 15:49:59 2011 +0400
+
+    Small set of corrections in the Mips related  files: headers,
+    comments etc.
+
+commit 921c4243aebd8a2de573935641589f345060c218
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 16 19:03:23 2011 +0800
+
+    Add SectionFactory class.
+
+commit 40d79dfaf7a917ea07189318885299f1bc702cfa
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 16 19:02:51 2011 +0800
+
+    Add rule to ignore *.o in .gitignore
+
+commit 2b5181f9a8ce07e780a721cd7f47a4c0dcc58437
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Fri Dec 16 17:41:45 2011 +0800
+
+    Add 64bit object file output support
+
+commit 060d3cc2818202c4b9af18ae304fc7921b767263
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 16 17:21:23 2011 +0800
+
+    Move ARMGOT and ARMPLT to separate header files.
+    No funtionality or interface change.
+
+commit 9388bb27659329e44c76e5dba9a77bcd203ebd26
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 16 16:59:18 2011 +0800
+
+    Remove the duplicate member functions in GOTEntry and PLTEntry.
+    Use the member functions inherited from MCFragment instead.
+
+commit 8711bed79380c375975ef467d36f9ce30fe89768
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:30:33 2011 +0800
+
+    Add GOT, RelocationFactorys in the compilation list.
+
+commit f9c9383df1f1abc14e1bd908bc906c06eb76ab88
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:26:55 2011 +0800
+
+    Sorry for the big change. But I think the new architecture is easier
+    to understand. All that targets need to do becomes list all relocation
+    function prototypes in ARMRelocationFunctions.h (C functions) and
+    implement each C function in RelocationFactory.cpp.
+
+commit 575d3feda1e5f308234432bb18617fb6ef037bac
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:24:04 2011 +0800
+
+    Add new GOT class.
+
+commit 0a9435c5a34fa5e74abeb73c60cbbec3ef645086
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:23:20 2011 +0800
+
+    Refine typo and style.
+
+commit 4bdffe67869f16f6372036c8ae54535811157f04
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:20:09 2011 +0800
+
+    1. The relationship between relocation and relocation factory is fixed. (rarely chang in the future)
+      i. Relocation ask RelocationFactory to apply the relocation.
+     ii. Client only need to know Relocation::apply()
+    iii. Targets need to implement RelocationFactory::applyRelocation()
+
+commit a5391acadf5786272e6d5885529bf65a2db8b889
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:18:43 2011 +0800
+
+    add empty Layout::getFragmentOffset()
+
+commit 12e5edbd37939e9d918b10cc731025f238a5699d
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:17:00 2011 +0800
+
+    make LDSection more loosely-couple with MCSection.
+
+    Do not reuse llvm::SectionKind. Use LDFileFormat::Kind instead.
+
+commit 11f4c1e05468ba91fd7bcc8c61a895e88dc2d5d6
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 16:15:27 2011 +0800
+
+    add GOT kind in LDFileFormat
+
+commit 0fdcb434d63cfc402976e16ec238e0a74503d439
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Fri Dec 16 15:58:24 2011 +0800
+
+    Add ELF header write out function
+
+commit daa6fcf1a064d5fdaf3ee8c6c8115637caa57792
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 16 15:24:50 2011 +0800
+
+    Use angle brackets to include LLVM header files.
+
+commit e26a9a839e9d1fe68d799359494e3c13cd359074
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Fri Dec 16 15:01:15 2011 +0800
+
+    Refine error message. Replace tab by 2 spaces.
+
+commit 3c6be9b1a481fe3b281be441bc58996a54a21cf2
+Merge: 35634c1 3233a0d
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Fri Dec 16 14:54:34 2011 +0800
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 35634c1eb8228ae186d8df4a4fa2fc4edcdcba12
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Fri Dec 16 14:48:23 2011 +0800
+
+    Enhance MCLDFile and MemoryArea handling.
+
+    1. Add property filesize for MCLDFile.
+    2. Change MemoryArea.request for read-only and read-write.
+
+commit 3233a0deffb18a4db5a3945dc317d9fc60e77c61
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 16 14:50:11 2011 +0800
+
+    Fix the warning from getcwd.
+
+    Fix the warning:
+    ignoring return value of 'char* getcwd(char*, size_t)'.
+
+commit 669748343ec4ff2286c92b8f96a51de7918a03d7
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 16 09:08:38 2011 +0800
+
+    Use ResolveInfo type definition of symbols
+
+    1. Use ResolveInfo type definition of symbols instead of llvm::ELF
+    2. Clean spaces and tabs
+
+commit 07a1c8c177b86e719b0ca5478ecc818558d7b101
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 16 08:59:25 2011 +0800
+
+    Fix build failure.
+    Remove #include MCLDCommand.h.
+
+commit 1e1f1c85c1e4067eb838c6ea7a43eebd2c41f270
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 16 03:55:12 2011 +0800
+
+    Refine ResolveInfo.
+
+    1. fix many bugs of access the description and type of the symbol
+    2. change the function name from the original type() to desc()
+    3. add new function type() as ELF_ST_TYPE
+    4. add unit-test cases
+
+commit f3941aad56c54aead525cb0a71f546df3e42b85c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 15 20:06:55 2011 +0800
+
+    remove obsolete code.
+
+commit 83c71bd31e8de366f55b6f1a00e7d946bbb1307c
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Thu Dec 15 23:15:57 2011 +0800
+
+    Move ARM GOT and PLT entries to ARMLDBackend.h.
+
+commit 9ef46fc7152eacdd251fde570b5c336158ce9273
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Dec 15 18:16:55 2011 +0400
+
+    Define virtual function MipsGNULDBackend::machine().
+
+commit f313fbf40bb6bf0eed62cfc15c763d0631e25343
+Author: Jason Lin <sh.lin@mediatek.com>
+Date:   Thu Dec 15 21:14:27 2011 +0800
+
+    Force implementation of TargetLDBackend provides machine information.
+
+commit 4e2fb98fa6878095a3fe6f64901a645872b5fd78
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 15 21:03:01 2011 +0800
+
+    Implement GOT and PLT entries for ARM.
+
+commit f99e9e47389a8134cf5aa553be645ff140c8c2e4
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 15 19:37:52 2011 +0800
+
+    Add some common testcases for static symbol resolutions.
+    Also add these testcases in the compilation list.
+
+commit 47373998b2fb96d571782d85dc38c5b7648d02d7
+Merge: 47dcf73 4f50b2b
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Dec 15 14:16:24 2011 +0400
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 4f50b2bf6d025896efed3e90e9a5746f58c89376
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 15 17:58:35 2011 +0800
+
+    Fix bugs
+
+    The StaticResolver uses a table to drive resolution process.
+    The row and the column do not match to ResolveInfo::m_BitField.
+
+commit cda66ba64e9a763bab015ce23d0843e9459b3354
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 15 16:27:11 2011 +0800
+
+    Fix a bug
+
+    ResolveInfoFactory produces the ResolveInfo with wrong types and bindings.
+
+commit 929e39ebb0b8492d298f8e0e5d60ef9cd11520e0
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 15 15:39:32 2011 +0800
+
+    For performance concern, WriteSameuint(8/16/32)_t takes uint32_t.
+
+commit 8c765870568f812c0e3d4ccc9fd6641230a1305b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 15 14:45:35 2011 +0800
+
+    Fix the bugs in script builders
+
+    Because we change our building system from BOLD (the old project name) to
+    MCLinker (the new project name), so these scripts have to be changed consistently.
+
+commit de74f82f4f04db1af3ed9343dcdd9656a9356b18
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 19:47:46 2011 +0400
+
+    Declare ObjectReader::readSections() as an abstract virtual function.
+
+commit caabf5794e85613a1e5938bcc8be4fffdbed94f4
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 15 10:05:41 2011 +0800
+
+    Fix ScopedWriter boundary issue.
+
+    1. m_Cursor+sizeof(TYPE) <= m_Region->size()
+    2. Write16 should use uint16_t as argument
+
+commit bdfa73736e01bd02fad99ea54d9fe3112920af94
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 15 10:06:46 2011 +0800
+
+    Add ELFDynObjWriter initial code.
+
+commit 47dcf7300d14a29a7f8270b0cf6e5c76888ea303
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Thu Dec 15 00:15:10 2011 +0400
+
+    Add stub classes to support mipsel target. The classes do nothing yet.
+
+commit 0a257babe6fa86cf8b459a79558bb0367969b41e
+Merge: 4a9b922 07ef497
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 19:49:40 2011 +0400
+
+    Merge branch 'master' of https://code.google.com/p/mclinker
+
+commit 4a9b922f1de76dc5ffd1542438d65fc99fec26fa
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 19:47:46 2011 +0400
+
+    Declare ObjectReader::readSections() as an abstract virtual function.
+
+commit 07ef4971433ed8a3af54b6b8fc5a20b79ae07552
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 23:27:08 2011 +0800
+
+    add symbol tables in LDContext.
+
+    MCLinker is still responsible for creating LDSymbols. LDContext is just a bookkeeper.
+
+commit 80ad6432f53cfa9d7626eb5504a92718484ad190
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 23:25:35 2011 +0800
+
+    Fix a bug in ResolveInfo
+
+    Bug: Previous patch did not change all TOUCH_OFFSET to PLT_OFFSET
+
+commit 2eb467e858ae0647db14c0bcbb560a9bb5452266
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 22:10:21 2011 +0800
+
+    Add ResolveInfo::hasPLT() and setHasPLT()
+
+    Which comes first? Applying relocations or creating GOT/PLT? This is
+    like checkens and eggs. Without applying relocation, we don't know
+    the number of entries of GOT and PLT. But without GOT and PLT's offset,
+    we can not fix symbol values and applying relocation.
+
+    In order to solve this problem, MCLinker separate the creating GOT/PLT process
+    into two different phases. The first phase is determining if the relocation
+    entry will produce a GOT and a PLT entry, then *create empty* GOT and
+    PLT whose sizes are precisely the same with the final sizes. The second phase
+    is applying the relocation entries, and simultaneously *fill* the GOT and PLT.
+
+    ResolveInfo::hasPLT() and setHasPLT() are functions for the relocation entry which
+    refer to the symbol. If a relocation entry needs to create an empty entry, than
+    the symbol is setHasPLT(true). And when applying the relocation, MCLinker looks
+    up the hasPLT(). If it's true, MCLinker will fill the value of the PLT entry and
+    GOT entry.
+
+    By this two-phase solution, we have no performance lost, and still keep
+    applying relocation and file layout simply.
+
+    Google gold scans relocation entries in file many times to deal with this problem.
+    But we know the scale of the number of relocation entries are huge, and it is
+    performance critical for on-device linking.
+
+commit e843b45c684995afce6ea830d6b4d1228ff64774
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Wed Dec 14 22:09:45 2011 +0800
+
+    Make two typedef(s) public.
+
+commit 6953fab92fef7c55bfb6e0ed83bef3ae16ecc231
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 14:42:47 2011 +0400
+
+    Move MCAssembler::setWriter() function definition to the cpp file.
+
+commit eca5451b5d9c6be05977d0924d51a9c980a97bf5
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 14:39:06 2011 +0400
+
+    Revert 1fce3a1a1361. The applied patch is obsoleted.
+
+commit 6f829659759631799aa7d5e86257a3c31920c2e0
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Wed Dec 14 20:16:06 2011 +0800
+
+    Initialize GNUArchiveReader in GNULDBackend.
+
+    We need to complete the right ArchiveReader/GNUArchiveReader ctors latter.
+
+commit 7f43c8e73fa01809f5ed56b1184d2aa9ae041300
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 18:08:13 2011 +0800
+
+    Fix a bug - MCLDDriver cat readers and writers before they are intialized.
+
+commit 1fce3a1a1361f690d7e7829267f635649417f7be
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 13 16:31:58 2011 +0400
+
+    The invocation of delete operator for an incomplete type has an undefined behaviour and g++ shows warning on this. To switch off this warning move MCAssembler::setWriter() function definition to the cpp file.
+
+commit 89cbcb97cbfbf280005aea53b94d829e1bbe6c41
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 13 16:09:15 2011 +0400
+
+    Put llvm libraries before the system's ones in the linker commad line. This fix linkage problem when g++ 4.6 is used to build MCLinker.
+
+commit 20403141692eb1174f0521c20c10e5791dbe94b7
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Tue Dec 13 16:08:46 2011 +0400
+
+    Finally fix wrong usage of typedef in MCFragmentRef::deref().
+
+commit 8eb2e5c8105f225941132c9fd51f1a9481cc2c7a
+Author: Simon Atanasyan <simon@atanasyan.com>
+Date:   Wed Dec 14 12:16:49 2011 +0400
+
+    The autogen.sh do not use external env variable to get path to "m4" folder. It expects to see "m4" folder in the same directory where the autogen.sh is.
+
+commit 2b982d3654d208b912e834b33d1e7335905cf988
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 17:07:31 2011 +0800
+
+    MCLinker should pass MCLDInfo for readers.
+
+commit 101af4f0b07b9060cc84b7c79fa27a9760aa63cd
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 15:42:56 2011 +0800
+
+    Fix bugs in add_class
+
+    Because we change the building system and some environment parameters are
+    changed, we have to revise add_class script, too.
+
+commit cd088060939c4e1ac75146e21998f26c7e20f6ef
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Dec 14 15:38:26 2011 +0800
+
+    Delete redundant file lib/MC/TargetLDBackend.cpp
+
+commit 955c9893c9e9ff065684c7ae7508d92f40881acc
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 15:30:10 2011 +0800
+
+    class adapter ELFDynObjectReader connects DynObjectReader and ELFReader
+
+commit 986e95ae9f86b95f89b6728ccaca5932b6d957c2
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 15:11:47 2011 +0800
+
+    MCLDDriver checks the result of reading.
+
+commit ad575be2e90ba0bfed99e964c3fc4b460b9fee85
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 15:06:56 2011 +0800
+
+    Let MCLDDriver and MCLinker meet Readers.
+
+    Finish the basic algorithms in MCLDDriver::readSymbols() and mergeSymbolTable().
+
+commit c707ef3a9c538dfcf8263f46e9751cb35f0dce2f
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 14:51:30 2011 +0800
+
+    add DynObjReader::addSymbols interfaces.
+
+commit 92e38888082758b15784da09df2a2399abf1abfb
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 14:49:52 2011 +0800
+
+    Initialize ELFDynObjectReader, ELFDynObjWriter in GNULDBackend.
+
+commit 3742ac2e68cefaeb2c3e637943b34dc0f88d42cb
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 14:01:37 2011 +0800
+
+    Fix a bug in StaticResolver
+
+    Bug: Do not change the row in action_table when get in REFC.
+
+commit ce1f5f24f36cc7a2f9d1f274830dbbceff361e05
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 14 13:57:07 2011 +0800
+
+    Add the missing relocation function.
+
+commit ecc3f20182439be3b496abefb8e62acb64ec5b29
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 14 12:58:38 2011 +0800
+
+    Move relocation function declaration from .h/.cpp to ARMRelocationFunction.def.
+
+    We separate the code flow and the spec to simplify our code.
+    Once we want to implement a relocation function,
+    we need to
+      1. Modify ARMRelocationFunction.def to add new function name
+      2. Implement the function in ARMRelocationFactory.cpp
+
+commit 3491cccd6e2e67bd41e880cf7cb9ad1524cdfe62
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 13:53:40 2011 +0800
+
+    Remove author declaration in the header template.
+
+commit 47de2a6346aec8749344ba015f9418f838e1b562
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 13:50:33 2011 +0800
+
+    Add StaticResolver in the compilation list.
+
+commit 4b1a6ad75d0d903b1d8f928b6ac4d35d61e089d1
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 13:49:55 2011 +0800
+
+    MCLinker should have StrSymPool for symbol resolution.
+
+commit 06ef7dc8abfa28cb0efc9e8e818e4a50797ac95e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 13:46:30 2011 +0800
+
+    1. Fix bugs in StaticResolver.
+
+    2. Let Resolver as a clone factory.
+
+    3.In old ResolveInfo, set functions use ResolveInfo defined enum types as the
+      parameters. For higher performance, change those parameters to uint32_t.
+
+commit 8be180a7c49ff0219886034b32489c3deb2368cc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 14 13:30:00 2011 +0800
+
+    Use the University of Illinois Open Source License for new files.
+
+commit 8b7e10a93a8accabc74838f64eb2b15dd87bd66e
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Wed Dec 14 13:25:20 2011 +0800
+
+    Fix typo for ScopedWriter.
+
+    Use pRegion to initialize m_Buffer instead of m_Region.
+
+commit 3c51db281e5d65fa31f87279175b0844a15cfd6b
+Author: Anders Cheng <anders.cheng@mediatek.com>
+Date:   Wed Dec 14 10:49:26 2011 +0800
+
+    Support Android SectLinker.
+
+commit aa2fe236bc089cb6cd6f02537f8f91f2f56f8e9d
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 11:39:13 2011 +0800
+
+    ResolveInfo::setVisibility should always choose the most strict visibility.
+
+commit b8592f5a219be3cdd9601171091b64a7fabc3765
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 14 11:31:14 2011 +0800
+
+    Use the University of Illinois Open Source License.
+
+commit 221faed40cd9054ebd522f52f3b77e07a8bbb459
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 03:03:37 2011 +0800
+
+    Add ScopedWriter.
+
+    ScopedWriter writes the region and synchronize the region with file at
+    its destructor.
+
+commit 8eb8bcbd158b129d17ad540b0c93327cb184c595
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 02:59:39 2011 +0800
+
+    Finish the static resolver.
+
+    The kernel of symbol resolution - StaticResolver.
+    It can resolve not only the regular symbols, but also indirect symbols.
+    MachO's indirect symbol can directly use the same StaticResolver.
+
+commit 48284527c99bfed258c14ade91402cf178ddd413
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 02:58:43 2011 +0800
+
+    Remove the code in readSymbols(). They can not pass compilation.
+
+commit b460c21691d237d9313028c0f99a3215e6e19a6e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 02:57:32 2011 +0800
+
+    Symbol resolution changes the original symbol, so Resolver::resolve()
+    must use reference to ResolveInfo instead of constant reference.
+
+commit 3b2c5349998bb780a00ff31e901738c938474a12
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 02:54:45 2011 +0800
+
+    1. move size and value fields from LDSymbol to ResolveInfo
+    2. Because indirect symbol use value field as the link to the other
+       ResolveInfo, change the interface of ResolveInfo.
+
+commit 938968f24c9397f1742726527adad32886604c77
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 02:53:28 2011 +0800
+
+    Fix some missing headers in Layout
+
+commit 65f5588158b5d2b5c26e33b5977d1806c440d10f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 14 10:59:02 2011 +0800
+
+    Fix building system.
+
+    Fix the build failure when building MCLinker in separate building directory.
+
+commit b661426ec46d6bd6f17a5b83520a225bb370efae
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 10:18:34 2011 +0800
+
+    We are currently the external project of LLVM.
+    So, use include `<' `>' instead of `"' `"'
+
+commit 798f14f04306c2d16d015436a9d338f4ea792f0e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Dec 14 10:17:42 2011 +0800
+
+    Add files generated by autogen.sh to .gitignore.
+    Based on a patch by Simon Atanasyan.
+
+commit 0b5b26087708fa0934def8ecff234c581f1510b0
+Author: luba <lubatang@gmail.com>
+Date:   Wed Dec 14 10:13:20 2011 +0800
+
+    Change the building system.
+
+    Move the placehold of object files from tools/llvm-mcld to debug and optimized.
+    Change script/envsetup.sh to export environment ${MCLINKERTOP}
+
+commit fe83d4c55fbbfdef3525fca64fc83ae81b78b946
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Wed Dec 14 09:22:38 2011 +0800
+
+    [Patch] llvm::StringRef cannot operator+.
+
+    Use std::string instead.
+
+commit fde52a66fcc382e23bd81a467d192e87b6ddb336
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 13 22:24:07 2011 +0800
+
+    Oops! Method overriding becomes hiding.
+
+    Fix the signature of BSDArchiveReader::isMyFormat().
+
+commit 22a773fb7237dba0200acae47700aca94612269c
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 13 22:20:11 2011 +0800
+
+    Add remaining relocation applying functions.
+
+    In order to meet our 1st milestone, I write the
+    scaffolding of applying functions which can seen
+    in LLVM lib/MC/ELFObjectWriter.cpp.
+
+    There are still some functions not mentioned, and
+    they will be invoked with ARMRelocationFactory::none().
+
+commit f819b7bb2afbede7caa8cda9b7d958f29b6d7c58
+Author: pete <petechou@gmail.com>
+Date:   Tue Dec 13 21:15:44 2011 +0800
+
+    Revise the file headers.
+
+commit 1d1e70b22424aba665f58ae9b9b0fb42dd1e5a1d
+Author: Nowar Gu <wenhan.gu@gmail.com>
+Date:   Tue Dec 13 20:46:05 2011 +0800
+
+    Add return enum of ARM relocation status;
+
+    Every private relocation function to be applied
+    should return the value of enum ARM_Reloc_Status.
+
+commit 7e33978829dbee73c47af915c3be34b85653abf9
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Dec 13 20:35:30 2011 +0800
+
+    Include llvm/Support/ELF.h as symbol type definition
+
+    Clean space
+
+commit 753dc5889cc09e10fe641c8746edbb6e5664d233
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Tue Dec 13 16:55:18 2011 +0800
+
+    Relocation and RelocationFactory
+
+    1. Remove destroy() in ARM and X86 RelcoatoinFactory
+    2. Add APIs to RelocatioFactory
+    3. Add a few applying functions to ARMRelocatoinFactory
+
+commit 2f3f17784da3c591d7b8a642597539197ffd5878
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 13 16:54:50 2011 +0800
+
+    The development of MCLinker migrates to code.google.com .
+
+commit 5ca1aba0f951f00bcd957c859e0fe55ad2b36c56
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 13 16:25:56 2011 +0800
+
+    Use the University of Illinois Open Source License.
+
+commit c38947f7a889eaeef517a07e057fe2ecfdbab643
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 13 16:19:45 2011 +0800
+
+    Remove redundant "#include <iostream>".
+
+commit 2c3b6bdd90ba5202fcd65c1f90bc24fac340b16b
+Author: pete <petechou@gmail.com>
+Date:   Tue Dec 13 14:12:54 2011 +0800
+
+    Fix build break.
+
+commit cd145bcdf7178b4a91a30ebc90579b26787156ff
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 12 21:35:28 2011 +0800
+
+    Layout laid out the sections and fragments
+
+commit 4652987bb676a4e04db7716515a8c414ee3933ef
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 12 21:33:47 2011 +0800
+
+    LDFileFormat describes the common object files.
+
+commit d32477944af36fa03689d0d3762d3c55b361ee84
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 12 14:57:40 2011 +0800
+
+    Fix a bug - set the wrong type of mcld::Input
+
+commit 95586130a0ae4afee1a8b9c2aa41ded57489df75
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Dec 13 15:44:00 2011 +0800
+
+    Merging mainline.
+
+commit 2bf6851902b2f2df82a6abe6eb26b434af43014d
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 11 01:08:51 2011 +0800
+
+    Fix wrong usage of typedef in MCFragmentRef::deref
+
+    Thanks Simon. By his suggestion, I correct the wrong declaration of deref().
+
+commit 70234d9a318e40bc63d60e59d4ee33f63739bbb5
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 11 00:56:14 2011 +0800
+
+    Set new TODO - implement SectionMap and SegmentMap
+
+commit 11b3bd488bad5ea822d5bef55a76ed38c6204a8b
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 11 00:52:10 2011 +0800
+
+    Add LDSection in compilation list.
+
+commit 6c4c3e5c73e752f651a230f0ace48e702081f8a5
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 11 00:40:43 2011 +0800
+
+    LDSection should be a kind of MCSection.
+
+    LDSection has name, type, flags and offset of a section.
+
+    MCLinker reuses llvm::MCSectionData. llvm::MCSectionData only contains
+    partial information of a section, such as real data size and alignment
+    constraint. We complement the rest information by put them in LDSection.
+
+    LDSection is designed for both ELF and MachO. We do not consider about
+    WinPE when we designed it. So, WinPE may not use it.
+
+commit eeb2e9754dc7e301bf66cb1c4a752155eeb3c589
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sun Dec 11 00:34:54 2011 +0800
+
+    Update patch/LLVM.patch and patch/README.
+    We use LLVM RELEASE_30@145348 now.
+
+    Checkout it by
+    "svn co -r 145348 http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_30/final llvm_30"
+
+commit 3f8342044be5e63e45922943bfb93dc949ec5486
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 10 22:11:36 2011 +0800
+
+    Every debt has it debtor :p
+
+commit 5778cd114cd07e3e1433dac5bdc1afab4d9d3e76
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 10 21:59:07 2011 +0800
+
+    Add 'prepare LLVM' sections in the README
+
+commit 0078964a9df503c358ef5fa2eb23f71cdd50631a
+Author: luba <lubatang@gmail.com>
+Date:   Sat Dec 10 21:44:18 2011 +0800
+
+    Add MCSection::SectionVariant a new variety - LD_Context
+
+    Since MCLinker uses LDSection as a common representation of section headers,
+    we need a new variety of section.
+
+commit 3098c5a0851e99fde77f5f2376165ffe42ccf5c9
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 9 14:18:28 2011 +0800
+
+    Add missing MCLinker header in MCLDDriver.
+
+commit eda322c15b5dfd36430be4f7eea70e687aebd71d
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 9 13:47:09 2011 +0800
+
+    Initialize MCLinker
+
+    In MCLDDriver::initMCLinker, MCLinker and all readers and writers are
+    initialized.
+
+    TODO:
+    In the same function MCLDDriver::initMCLinker(), MCLinker should initalize
+    all internal data structures, such as segments, sections, and symbol tables.
+
+commit 22f0fad5630050abf970850bf4ec66d50250daa7
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 22:56:35 2011 +0800
+
+    Fix bug - hasContext return opposite value.
+
+    By Simon patch/LLVM.patch
+
+commit 5e56d91d52fceb8cdc7f9ea813cd272c1b710abd
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 22:02:06 2011 +0800
+
+    Fix a bug - hasMemArea return opposite value.
+
+    By Simon Atanasyan's patch.
+
+commit 45d47f655e8ffd71e6a7cf42c1ba913f51ce8b87
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 8 21:41:39 2011 +0800
+
+    Add general apply function interface into RelocationFactory
+
+    Remove function pointer in Relocation.
+
+commit b7c194ca85a7f7b8af18173c68bae40e72ffce14
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 8 20:58:09 2011 +0800
+
+    Change type of apply function pointer to pmf
+
+    Apply functions in RelocationFactory should be non-static.
+    Use pmf on Relocation to hold the pointer.
+
+commit 7dc044b48c2ca4a67a76d3d82fef554963225935
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Thu Dec 8 16:39:09 2011 +0800
+
+    Add Relocation and RelocationFactory prototypes
+
+    Remove ARMRelocation and X86Relocation.
+    Define RelocationFactory and apply function prototypes.
+
+commit a2de45a96b5f661b273fc4db2540c22ebd6373e4
+Author: pete <petechou@gmail.com>
+Date:   Thu Dec 8 15:00:17 2011 +0800
+
+    Remove mcld::StringMap, its testcase, and related code.
+
+commit ffdc2452a71e8389f2f3d267f54ada53d5029839
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 8 13:34:45 2011 +0800
+
+    Add new MCFragment types FT_GOT and FT_PLT to LLVM 3.0.
+
+commit 633842441e9bc64d69e682070f85ead306ce6749
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 10:34:01 2011 +0800
+
+    Add some basic functions in MCLDDriver.
+
+    Because in these early version, algorithms are simple. So I directly write the functions in SectLinker.
+
+commit 9f7c4e27d314bd58bb363335272deaf885732b9a
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 03:15:07 2011 +0800
+
+    Add some ARM target backend scaffoldings
+
+    - Relocation Factory
+    - Relocation
+    - Backend
+
+commit 814dd5ead01058162c85017e0fbefdf323b44671
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 01:33:32 2011 +0800
+
+    Add some target callback functions for overriding.
+
+commit ec519d96ead369d48c6329c82c8d1b9d4f2f57b9
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 01:29:38 2011 +0800
+
+    Add GOT scaffolding
+
+commit dcd1bab5fa09334ad21a8f8e68fb258b483728a4
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 8 01:15:54 2011 +0800
+
+    Add scaffolding of PLT
+
+commit 26b0df4f58214c5769a3b947c93d3ba3f5e87381
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 5 21:23:36 2011 +0800
+
+    Add RelocationFactory interface
+    Add RelocationFactory into Makefile.am
+
+commit 58ad32a8084e64769da2ad871f7ed59cc0061105
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 5 21:21:04 2011 +0800
+
+    Change relocations type to std::vector
+
+commit b68dcea42a93b93f2de690a36352040ae095f7de
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Mon Dec 5 21:19:19 2011 +0800
+
+    Add resolveInfo() into LDSymbol
+
+commit 8ed0f131cbdc717057ebe3fab16bb8c73987148c
+Author: pete <petechou@gmail.com>
+Date:   Mon Dec 5 16:25:48 2011 +0800
+
+    Rewrite PathCache of Directory to use mcld::HashTable instead.
+
+commit c222b70e1e6eb7789368002cc5cd850a5db0ac09
+Author: luba <lubatang@gmail.com>
+Date:   Mon Dec 5 00:57:49 2011 +0800
+
+    Finish StrSymPool, and define Resolver's API.
+
+    Let resolver has more control for symbol resolution.
+
+    Resolver now can be inherited by static resolver for static linker or by
+    dynamic resolver for dynamic linker.
+
+commit 35dd88a5fdb9b69b65c7d008047cccf36b990593
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 4 14:17:31 2011 +0800
+
+    Change include file - stdint.h to llvm/Support/DataTypes.h
+
+commit 5731c3e1afdb7ec4ee66493ae0b0d5a673c349e2
+Author: luba <lubatang@gmail.com>
+Date:   Sun Dec 4 14:17:00 2011 +0800
+
+    Add BranchIsland and Stub
+
+    Not implement yet.
+
+commit 7f3fae69146dc3c05c43a791eead40e70e8eab37
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 2 18:13:31 2011 +0800
+
+    Relocation inherit to ilist_node
+
+commit 87b30c7ec68593f8688426d402303dd8c3c2413d
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 17:44:10 2011 +0800
+
+    Add TargetLDBackend::applyRelocation interface
+
+commit a472c0a9362ec080a26bd8ae04299ccea88f21c5
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 16:39:20 2011 +0800
+
+    Add empty class of Group and Layout
+
+    Group and Layout are two classes used to finalize the layout of regions.
+
+commit 5a546a1459f16d061bc17bd589e7644d88dd5fed
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 16:31:56 2011 +0800
+
+    Add Howto and Relocation into make list
+
+commit c2ebf70bccf6cc890f060e0445029d18b0e01260
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 16:31:12 2011 +0800
+
+    Add Howto
+
+    add Howto as the common information of relocation entries
+
+commit 70dfc86d8dbdf25d7e03b2b05cd7173e6dad1670
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 16:27:39 2011 +0800
+
+    Add MCBitcodeInterceptor
+
+    MCBitcodeInterceptor intercepts data in MCAssembler.
+
+commit f9d450da825e76b8dd2f780a0c334ad3159158b4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 2 16:18:05 2011 +0800
+
+    Build MCLinker with options which are used in Android.
+
+commit 1c1577cfc9e38edd1964344c39feae7e95575c0e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 16:08:04 2011 +0800
+
+    Change MCAsmObjectReader to MCBitcodeInterceptor
+
+commit ef7de030bd3381a770ac493e1feb1265d15874d0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Dec 2 15:46:27 2011 +0800
+
+    Fix build failure when building MCLinker without "--enable-unittest".
+
+commit 19e2d77416d84552f9316b43c7b9cbac7ccdf31e
+Author: pete <petechou@gmail.com>
+Date:   Fri Dec 2 15:08:29 2011 +0800
+
+    HashTable
+
+    1. refine the interface of const interator
+    2. refine begin iterator (advance if needed)
+    3. refine the interface of string hash and compare functions
+    4. enable the unittest of hash table
+
+commit 7ce917c0ec2426096a4bdbe24c8e4e58a696994c
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 14:55:49 2011 +0800
+
+    Remove obsolete code
+
+commit 4bc81fb85bca2b06f4db472532079e0e903a84b4
+Author: luba <lubatang@gmail.com>
+Date:   Fri Dec 2 14:46:39 2011 +0800
+
+    remove obsolete codes
+
+commit 63cb8f09d0b36b03eded8a4b097a9109e16f1128
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 2 09:03:51 2011 +0800
+
+    Change type LDRelocation to  Relocation
+
+commit 0cebccd14965f785536742b9b7b6a1fce5b17c5c
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Fri Dec 2 08:46:47 2011 +0800
+
+    Remove including file LDRelocation.h from lib/MC/MCAsmObjectReader.cpp
+
+commit 4cac453872b143007c18bea5d55b688866fc2d5b
+Author: ras46 <Robert.Lai@mediatek.com>
+Date:   Thu Dec 1 16:36:14 2011 +0800
+
+    STLport needs std::less const version.
+
+commit 814c017983096d3e67df561c18657804fc0371bf
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Dec 1 14:36:59 2011 +0800
+
+    Use ${TOPLEVEL} instead of ".." in Makefile.am.
+
+commit 49814ae1bb6bd86ced88a5edd76ef0def5b8b592
+Author: luba <lubatang@gmail.com>
+Date:   Thu Dec 1 14:11:53 2011 +0800
+
+    1. rename LDRelocation as Relocation
+    2. change the interface of RelocationFactory
+    3. refine the API of Relocation.
+
+commit 36dd5efc9e85f180d0636269724099044407f7a4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Nov 30 21:22:06 2011 +0800
+
+    Fix bug where MCLinker generates empty object files.
+
+commit 12825372ce875ccc72d30bfd4e2f17f3c49d5c31
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Nov 30 18:02:24 2011 +0800
+
+    Add MCDataFragment and MCInstFragment
+
+commit 1b9339ebb1a1baff100c1a82e7af7b05ade4b718
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Nov 30 11:08:21 2011 +0800
+
+    Remove symbols related definition in LDContext
+
+commit 9421ba3955ee189ae9b3b437d10f11b2f2e5a978
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Nov 30 10:29:05 2011 +0800
+
+    Add LDRelocation, LDHowto and LDRelocationFactory
+
+    1. Remove Relocation.h
+    2. Change relocation type from Relocation to LDRelocation
+    3. Remove relocations in LDContext and MCAsmObjectReader
+
+commit 9d385e3683813e24a95731a1dbf0675b15a92dfb
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Nov 30 01:07:02 2011 +0800
+
+    Add an option of golden model linker.
+
+commit aeae012cc95521b03abf812122174564612195d9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 29 16:23:28 2011 +0800
+
+    Move MC/MCLDContext to LD/LDContext.
+
+commit 98975a1aacdd77893a1702cc982ebacbb2e660d4
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 29 15:52:07 2011 +0800
+
+    Revert some changes for building MCLinker with LLVM r142614
+
+commit b0956e0091993c6de228683041e24254c9d21891
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 15:27:11 2011 +0800
+
+    Add StrSymPool
+
+    Use HashTable and ResolveInfo to remember the shared attributes of all symbols.
+
+commit 75c7eefe67b8069c18b5f18db06219a690e9dd7f
+Author: pete <petechou@gmail.com>
+Date:   Tue Nov 29 13:52:35 2011 +0800
+
+    LDSymbol: add one missing open brace.
+
+commit 213d67b1693804bc216bef43b7b772cd5f754b94
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 11:51:38 2011 +0800
+
+    Add assert()s in LDSymbol and LDSymbol::setValue()
+
+commit 82732c2a798c034290ea297cbec9e7268ce546da
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 11:43:10 2011 +0800
+
+    Revise ResolveInfo for adapting HashEntry
+
+    add bool compare(llvm::StringRef) and typedef llvm::StringRef key_type
+
+commit d34cdfd3a63cf0afe42d99aa6e0c7dc278bb8b5f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 10:40:05 2011 +0800
+
+    Remove LDSymbolFactory
+
+commit 419a180a9b65280f0840bd2b56dc9366902c2a6c
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 10:33:21 2011 +0800
+
+    Accommodate new options - -Werror=format-security -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
+
+commit 75ba993bf689a6c4037539c6a8e0669174bab800
+Author: pete <petechou@gmail.com>
+Date:   Tue Nov 29 10:15:04 2011 +0800
+
+    Fix build break.
+
+    1. add key() api in ResolveInfo
+    2. modify the makefile
+
+commit 9b8ee64fff298d1d2b05840ce07e0f7c77967161
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 10:11:02 2011 +0800
+
+    Implement MCFragmentRef::assign
+
+commit 3f89a717f38267887cc8ddc10ae1eaf9806ac43d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Nov 29 09:49:09 2011 +0800
+
+    Fix typo-error and add some missing header files in LDSymbol
+
+commit af12e0bade43dba059253bdd0977302e9b553669
+Author: pete <petechou@gmail.com>
+Date:   Mon Nov 28 21:11:23 2011 +0800
+
+    ResolveInfo implementation and some refinements.
+
+commit 2c585300f58b247a7b4a96ec45196a32f69d4723
+Author: luba <lubatang@gmail.com>
+Date:   Mon Nov 28 18:28:40 2011 +0800
+
+    Separate ResolveInfo from LDSymbol
+
+commit bae8cdff60052729d2e7d2d3516cc9776e20bde1
+Author: luba <lubatang@gmail.com>
+Date:   Mon Nov 28 17:39:05 2011 +0800
+
+    Follow ResolveInfo, change the RESOLVE_OFFSET to NAME_LENGTH_OFFSET
+
+commit a75d0db412a3ecbf087633e10bcf5bc2b2023d2c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Nov 28 17:33:30 2011 +0800
+
+    Add ResolveInfoFactory
+
+    ResolveInfo is a dynamic class whose size is various at run-time.
+    ResolveInfoFactory creates ResolveInfo and make sure such kind of dynamic
+    class is only created in dynamic storage.
+
+commit 518bcd6fa243481d19fd94315cddfaa5833f4d69
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Nov 28 16:46:15 2011 +0800
+
+    Add new MCFragment type FT_Region.
+
+commit 2386bc39771d8d5a3c252f7b5d3fae9e52e96984
+Author: luba <lubatang@gmail.com>
+Date:   Mon Nov 28 16:15:17 2011 +0800
+
+    Add ResolveInfo
+
+    ResolveInfo is a common storage for all resolved symbols. It records all
+    information that used during symbol resolution, such as binding, type,
+    isDyn and so on.
+
+commit b49abdefd70309d2c311758dbc916256fc2fd8ec
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Nov 28 14:37:05 2011 +0800
+
+    Remove non-existent files from debug/Makefile.am
+
+commit c37d8a4e32a6177ce38e8af7bff7614d651cc3bd
+Author: luba <lubatang@gmail.com>
+Date:   Mon Nov 28 14:18:48 2011 +0800
+
+    Add SizeTraits
+
+    SizeTraits is responsible for defining the numeral system.
+
+commit f88646c19970e5d1839b8d41cd2aabab387cda8b
+Author: luba <lubatang@gmail.com>
+Date:   Sun Nov 27 21:53:59 2011 +0800
+
+    Add MCFragmentRef
+
+    MCFragmentRef is a reference to *MCFragments.
+    BTW, in order to compatible to MCInstFragment and MCDataFragment, change FileSystem::Address from unsigned char* to char*.
+
+commit ef4b44d4caa503d5722f253fe92a99ec3b9eafc3
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 24 22:57:48 2011 +0800
+
+    Remove PZString and finish LDSymbols
+
+    Because PZString is impossible to be other classes' member variable, and
+    it is error-prone, remove it.
+
+    Instead, direct add the strings into LDSymbol.
+
+    LDSymbol make sure string and symbol is high-possibly in the same cache line.
+
+commit 40f67efb61335d70e18780303b8a24e2612d09ce
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Nov 24 19:32:25 2011 +0800
+
+    Add a -soname=name option to store soname in class Output
+
+commit 293c6a2da51ffc7d630fa6af5d642ca0a76eaac6
+Author: pete <petechou@gmail.com>
+Date:   Thu Nov 24 18:45:02 2011 +0800
+
+    Refine the erase code.
+
+commit 5847a955218fdf4fcb6d1a30770d8d71ce78de4b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 24 13:44:46 2011 +0800
+
+    add PZString::at() prototypes.
+
+commit 802b1e082c84c9b355be5aa18a3653b86865b4a8
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 24 13:41:07 2011 +0800
+
+    Add PZStringFactory::create functions
+
+    PZStringFactory is responsible for creating and destroy PZString.
+    Since PZString only can exist in heap, it should not be created by normal
+    user code.
+
+commit c3b40a09c7ad181d9dd9af19c50a0c70a8f743da
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 24 11:40:05 2011 +0800
+
+    Add the scaffolding of PZString and PZStringFactory.
+
+    PZString is a Pascal string with zero terminal.
+    Because PZString is a kind of class whose size is various, it's only
+    can be put in dynamic storage. Therefore, it can not use normal allocator.
+
+commit 8c514c26e73af68e96b989b3cf7e23261753003c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Nov 24 11:12:59 2011 +0800
+
+    Set file mode bits to most common value "755" and "544".
+
+commit cb0eb5d71785a2cd78a022118ffb7f24aa001e62
+Author: pete <petechou@gmail.com>
+Date:   Wed Nov 23 20:33:52 2011 +0800
+
+    1. fine tune the probing performance
+    2. fix the bug as erasing
+    3. write testcases for "erase", "clear", and "tombstone"
+
+commit 30abb8e1bc78819ee34b6ecf222059693456d4e7
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Nov 15 16:59:43 2011 +0800
+
+    Remove testing example.
+
+commit 5cf25e3524bcde04874b3782b266125d0ba7030d
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Nov 15 16:54:20 2011 +0800
+
+    Check llvm 3.0.
+
+commit 9819f43d7ca925f581cdcdffcd22e9a37bb6ec0c
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Nov 15 16:53:30 2011 +0800
+
+    Remove lit, we use llvm's lit
+
+commit a251244f111fcf4c80d0682557edc5c36c6e7616
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Nov 15 15:37:02 2011 +0800
+
+    Use Makefile.am. Use llvm build dir for test tool.
+
+    Now can use some llvm tool such as FileCheck.
+
+commit 9a761813eaacc6354d09be74498c992950aa7b19
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 15 14:35:57 2011 +0800
+
+    Changes to fit LLVM Release 3.0
+
+    1. generate the diff for llvm 3.0 based on r142614
+
+    2. made the corresponding changes about TargetRegistry and TargetSelect
+
+    commit 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
+    Author: Evan Cheng <evan.cheng@apple.com>
+    Date:   Wed Aug 24 18:08:43 2011 +0000
+
+        Move TargetRegistry and TargetSelect from Target to Support where they belong.
+        These are strictly utilities for registering targets and components.
+
+        git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138450 91177308-0d34-0410-b5e6-96231b3b80d8
+
+    3. remove the code for llvm 2.9
+
+commit 61cdc16ec58247719ec881816dc001cd559c31a4
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 10 23:21:37 2011 +0800
+
+    write comments in HashTable::rehash()s
+
+commit e530bb829207fcf285aa37ec703c19c61e8f4d32
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 10 22:57:39 2011 +0800
+
+    Add MCRegionFragment
+
+    MCRegionFragment is a kind of MCFragment which is used to represent the
+    section data when reading a object/DSO file.
+
+commit 70ef2cf40a845ac10617405d57df3db7e0eba70f
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 10 14:30:56 2011 +0800
+
+    Add a some testcases for hash table.
+
+    1. a pressure test to insert 4000000 elements
+    2. test case for traversing chains of the hash table
+
+commit 8dae4b66bbb8ba019a8c24f5a8ef08c3cac03e6a
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 10 14:24:06 2011 +0800
+
+    1. Change the HashTable from quadratic probing to linear probing.
+    2. Fix bugs in ChainIteratorBase
+
+    At first, we follow llvm, use quadratic probing. However, in llvm, the quadratic function is not real quadratic, it's a triangle function - K(K+1)/2. Some number of buckets, even when the load factor is under the threshold, can not be probed by given triangle function. This will cause a infinite loop in HashBase::lookUpBucketFor. In order to avoid the problem, I change the hash table to linear probing.
+
+    ChainIteratorBase::advance behave wrong. It returned when meeting a empty bucket. It should ignore empty bucket.
+
+commit 2e0a251e8e87a30125c27e45ce3b39dd1ae17e2a
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 14:56:03 2011 +0800
+
+    Fix bugs in HashTable
+
+    Thanks for TDY, we resolve the bug - use the bucket reference that is deleted after rehash
+
+commit 28569f6e455c2d0a9fe077e912842d2d4c81227e
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Nov 9 14:30:34 2011 +0800
+
+    Cleanup tests which cannot pass.
+
+commit bfda46018175dfe691451382e2d0be17d396edfa
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Nov 9 11:15:46 2011 +0800
+
+    Let tests can use llvm-tools.
+
+commit f77630965e5ae8db82fa83db1080cd122166f702
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 06:34:04 2011 +0800
+
+    fix a bug in HashTable::load_factor()
+
+    HashTable::load_factor() has typo error. Since it's a template class, typo-error is not easy to be found.
+
+commit 7da98b64d1d0781870abda659a295be3abfa40bc
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 06:09:56 2011 +0800
+
+    Add a new testcase - alloc100 - for HashTable
+
+    alloc100 sequentically inserts 100 elements into the HashTable
+
+commit 4f461a3a2147e20a363609ffa73738f567a11fb1
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 05:56:13 2011 +0800
+
+    Refactoring HashTable
+
+    1. make HashTable is no longer limited to llvm::StringRef key type.
+
+    HashTable get the type of key and value from HashEntry.
+    HashEntry::key_type and HashEntry::value_type. HashTable does not assume the key type is based on string. Moreover, the hash function is also not limited to the string hash.
+
+    2. move the construction of HashEntry outside from the HashTable.
+
+    Clients must pass the factory of HashEntry as a template argument into the HashTable. That is,
+
+      HashTable<..., EntryFactory>
+
+    The memory can control by the factory. HashTable no longer takes care of it.
+
+commit 5a5694a55753d0a6e68bae33072c578a4b4697ec
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Nov 8 16:27:33 2011 +0800
+
+    Move regtests into test/ subdir.
+
+    Since MCLinker is not done yet.
+    `make check' will get 4 errors. That is okay.
+
+commit ad0e76dcaa623db67ff9eb58667b7249a8a10d13
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 3 02:54:41 2011 +0800
+
+    Unit test of mcld::HashTable
+
+    Only few cases are tested. Please contribute more cases.
+
+commit 3f09d3c77917baebee346283caf64665f6f74f68
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 3 02:51:38 2011 +0800
+
+    A HashTable whose hash function is changable
+
+    Since the hash function in linkers can be changed in GNU ld, MCLinker should
+    provide such feature to change the hash table. mcld::HashTable is the implementation.
+
+    Features:
+      - Can change hash table
+      - User defined hash entry - Symbol table uses this feature to keep string and symbol in the same cache line.
+      - Quadratic probing, open addressing hash table.
+
+commit 975c757ce17eb83f2e7357e78554b59f94963b85
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Nov 2 19:07:08 2011 +0800
+
+    Add llvm-lit for testing.
+
+    We use lit(LLVM Integrated Tester) for MCLinker testing.
+    Add basic config and some simple tests.
+
+commit 1f9a62dfdc1907be35278f767bfa466f67153887
+Author: luba <lubatang@gmail.com>
+Date:   Mon Oct 31 08:19:39 2011 +0800
+
+    Add MallocAllocator
+
+    LLVM has provided a llvm::MallocAllocator, but it is a 'plain' allocator.
+    That is, llvm::MallocAllocator returns a raw byte string and users need to
+    cast the raw byte string on a new type by itself. Additionally,
+    llvm::MallocAllocator does not follow the API defined in C++ standard.
+    So, I decide to give them a new MallocaAllocator.
+
+commit 83c8f2bd7b417cee2f095ef28d2bf08bbbda82c3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 20:56:04 2011 +0800
+
+    Force RegionWriter to be used only through auto variables
+
+commit 7ecaef28263a26caf73f49d6c624aefbeaeff3a5
+Author: pete <petechou@gmail.com>
+Date:   Mon Nov 28 09:51:08 2011 +0800
+
+    HashTable
+    1. fine tune the probing performance
+    2. refine the erasing code
+    3. write testcases for "erase", "clear", and "tombstone"
+
+commit 5cbc4f2546d046ec50e5930f7e6da4ae99201d32
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Nov 16 11:06:21 2011 +0800
+
+    Add comments
+
+commit f783a732c31e44744863d60b0bf86c196320ebe1
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 15 11:37:01 2011 +0800
+
+    Add missing '<'
+
+commit 49c8beabfacfdef9171a24e038a1bb0e243c628f
+Author: luba <lubatang@gmail.com>
+Date:   Thu Nov 10 23:21:37 2011 +0800
+
+    write comments in HashTable::rehash()s
+
+commit 1b3c38cd68808aa6ab9a4ac96d4e698105e6dc86
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 13:16:50 2011 +0800
+
+    Add testcase to make sure two MCRegionFragment::classof()s are correct.
+
+commit f95de000888b22fb7af57d2053b53dd239f9ec16
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 13:11:36 2011 +0800
+
+    Add MCRegionFragment
+
+    MCRegionFragment is a kind of MCFragment which is used to represent the
+    section data when reading a object/DSO file.
+
+commit b87c95aa31d90e7bec8834f715462a2a9cc5d0ca
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 13:00:16 2011 +0800
+
+    Add a some testcases for hash table.
+
+    1. a pressure test to insert 4000000 elements
+    2. test case for traversing chains of the hash table
+
+commit 14cc34ee4583e807b0dd606c0ef0c68571bece14
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 12:59:20 2011 +0800
+
+    1. Change the HashTable from quadratic probing to linear probing.
+    2. Fix bugs in ChainIteratorBase
+
+    At first, we follow llvm, use quadratic probing. However, in llvm, the quadratic function is not real quadratic, it's a triangle function - K(K+1)/
+
+    ChainIteratorBase::advance behave wrong. It returned when meeting a empty bucket. It should ignore empty bucket.
+
+commit 6307571e18535b25ee1b63987705762e056ade89
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 12:58:44 2011 +0800
+
+    Fix bugs in HashTable
+
+    Thanks for TDY, we resolve the bug - use the bucket reference that is deleted after rehash
+
+commit 64c155a8bf7256bf8b35cb1c7a420e06c937995c
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 06:34:04 2011 +0800
+
+    fix a bug in HashTable::load_factor()
+
+    HashTable::load_factor() has typo error. Since it's a template class, typo-error is not easy to be found.
+
+commit ede118612a71753ae4a1f990d0f7727534bb7067
+Author: luba <lubatang@gmail.com>
+Date:   Wed Nov 9 06:09:56 2011 +0800
+
+    Add a new testcase - alloc100 - for HashTable
+
+    alloc100 sequentically inserts 100 elements into the HashTable
+
+commit b6014605f72bdc76bdbd961cdc3ae67b62606a19
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 11:29:45 2011 +0800
+
+    Refactoring HashTable
+
+    1. make HashTable is no longer limited to llvm::StringRef key type.
+
+    HashTable get the type of key and value from HashEntry.
+    HashEntry::key_type and HashEntry::value_type. HashTable does not assume the key type is based on string. Moreover, the hash function is also not l
+
+    2. move the construction of HashEntry outside from the HashTable.
+
+    Clients must pass the factory of HashEntry as a template argument into the HashTable. That is,
+
+      HashTable<..., EntryFactory>
+
+    The memory can control by the factory. HashTable no longer takes care of it.
+
+commit 12ef316a47a7d068a2593cb9510c829662149a73
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 10:59:53 2011 +0800
+
+    Unit test of mcld::HashTable
+
+    Only few cases are tested. Please contribute more cases.
+
+commit 564228ab83535e7f60d043e6923bdb5f5c3ad6f5
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 10:55:34 2011 +0800
+
+    A HashTable whose hash function is changable
+
+    Since the hash function in linkers can be changed in GNU ld, MCLinker should
+    provide such feature to change the hash table. mcld::HashTable is the implementation.
+
+    Features:
+      - Can change hash table
+      - User defined hash entry - Symbol table uses this feature to keep string and symbol in the same cache line.
+      - Quadratic probing, open addressing hash table.
+
+commit 84586bd7ed6e0023f3f661323f8f93140d72439d
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 10:48:44 2011 +0800
+
+    Add MallocAllocator
+
+    LLVM has provided a llvm::MallocAllocator, but it is a 'plain' allocator.
+    That is, llvm::MallocAllocator returns a raw byte string and users need to
+    cast the raw byte string on a new type by itself. Additionally,
+    llvm::MallocAllocator does not follow the API defined in C++ standard.
+    So, I decide to give them a new MallocaAllocator.
+
+commit acc2c370db8c9c1d437bdbb87277f49152c31c53
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Nov 11 10:43:49 2011 +0800
+
+    add all string hash functions
+
+    string hash functions are partial specifized with the prototype:
+
+      template<size_t HASH_TYPE>
+      class StringHash : public std::unary_function<llvm::StringRef, size_t>
+      { };
+
+    MCLinker provides the following hash functions:
+
+      enum StringHashType
+      {
+        RS,
+        JS,
+        PJW,
+        ELF,
+        BKDR,
+        SDBM,
+        DJB,
+        DEK,
+        BP,
+        FNV,
+        AP
+      };
+
+commit 24a8d22a905e0995cfde8b196e3b8cc2f2ab10bd
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 14:48:14 2011 +0800
+
+    Re-add MCLDDriver scaffolding.
+
+    Use MCLDDriver as GNU collect2 to prepare
+    all implicit parameters for MCLinker.
+
+commit c9812dd48671c83261c3ecc182d0d22e64376228
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:37:34 2011 +0800
+
+    Remove legacy code from MCELFObjectReader
+
+commit 1df9138c88d3e76b3882e3ead7dced589ff29508
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:36:51 2011 +0800
+
+    Remove verbose printout from unittest.
+
+commit 9e689583cea552c684483b61d8be1779ccc8c8ce
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:35:29 2011 +0800
+
+    Correct the copyright and license.
+
+commit c143ee81e5d6e36321baabcfd57a96e05445bcdc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:33:20 2011 +0800
+
+    Change the description of MCLinker.
+
+    The main contribution of MCLinker is not BSD-like license.
+    Instead, is using LLVM machine code layer and perform well under limited memory budget.
+
+commit 396917e17da3a9dcd64f01b9e91e622cdf0c750f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:30:51 2011 +0800
+
+    Fix Luba's email and the Copyright
+
+commit a23025ae217cb5353826cbad6d9bbf3bc56616bf
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:30:00 2011 +0800
+
+    Remove directory check from the unit test "PathTest".
+
+commit 1f9e256769b3b1c3a3ee6cdb083798a78fc40d0b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:28:51 2011 +0800
+
+    Change the old project name to MCLinker.
+
+commit 405382710ebe8b2f88e0415cd5d8d4275068c902
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Nov 1 10:27:10 2011 +0800
+
+    Add LLVM release license file.
+
+commit 0f5fb0b15f353e777c9d5734b79cf92db632fb27
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Oct 27 13:46:59 2011 +0800
+
+    Replace get_current_dir_name() with getcwd()
+
+    get_current_dir_name() is not portable in Unix-like systems
+
+commit f07dc273f036e1fd1f7616275ff52d065a02378b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Oct 27 13:40:34 2011 +0800
+
+    Refine MemoryAreaTest
+
+    Remove redundant tests, and change file names of sample files
+
+commit 8e67d2da40c2bb2daaea12bf20161415a44c26d5
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Oct 26 17:00:11 2011 +0800
+
+    ./patch/LLVM.patch is for LLVM 3.0 branch, not trunk.
+
+commit b634a59912a1d40ccf99bed32869dc715f0c997e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Oct 26 12:47:26 2011 +0800
+
+    Add ELFEXEWriter header and footer
+
+commit 4ea0616604456788c2e1a7b940f6e584606df707
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Oct 26 12:46:17 2011 +0800
+
+    Move LDScriptReader directory to lib/LD
+
+commit 6cff6d7e074a781a957464d28f3a7c3fc7d7a8a9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Oct 26 11:04:49 2011 +0800
+
+    Remove temporary code of Readers
+
+commit 43a592f296c6af10e6b4af34b18332d1618408fd
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Oct 25 17:35:38 2011 +0800
+
+    Write comments for a number of files
+
+commit 31abc0988cbfd69fca49d8c863004d90de9c9365
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Oct 25 14:23:17 2011 +0800
+
+    Remove ObjectWriter and ObjectTargetWriter
+    Use LDDSOWriter and LDEXEWriter instead
+
+commit a0befa4577e50f6b225a534a1fa885d7d7834612
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Oct 25 10:55:33 2011 +0800
+
+    Rename MCLDDriver to MCLinker, remove old MCLinker
+
+commit bb8c5250771fe50d33ec6cfc6145f361d510cd8d
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Oct 24 19:53:35 2011 +0800
+
+    Tidy up ./patch directory
+
+commit 465bd9fd412465e87c792a0873fe8ee463930f51
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Oct 24 19:34:32 2011 +0800
+
+    Add missing header files
+
+commit 7e9713b1928848551bae4dbea336bcd17f9a6555
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Oct 24 12:59:18 2011 +0800
+
+    Remove include<cerrno>
+
+commit 52418fcb55b764caa163d82ce8f7974a8b9091d5
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Oct 24 12:53:11 2011 +0800
+
+    Remove redundant include<iostream>
+
+commit d935db745b93ae175ae10ce8b75e55c366ca5ad9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Oct 24 11:48:25 2011 +0800
+
+    Fix warning about "NULL used in arithmetic"
+
+commit eea7f316e094e5236f396e974c0c3a52250bb1c1
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 21:01:29 2011 +0800
+
+    Force RegionWriter to be used only through auto variables
+
+commit bbb2780e8a078b5cea8391b27be48007dffadcc6
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 17:01:15 2011 +0800
+
+    Move MC/MCLDContext to LD/LDContext
+
+commit eab6d7efb73f44d1776001e56634e2d53205685e
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 16:30:40 2011 +0800
+
+    Rearrange some code
+
+commit 4c20d4b12dd120ebc820ab385db2571102bfdc2c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 15:47:46 2011 +0800
+
+    Add namespace missing "std::" prefix
+
+commit 576147414854bf04a6c1cea8861ecc56029409e1
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 15:45:12 2011 +0800
+
+    Remove unnecessary forward declaration
+
+commit df74078521e645b6fbf97c0e22ab9174e4967980
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Sun Oct 23 15:32:40 2011 +0800
+
+    Avoid building MCLinker in source directory for the case without specifying "--unittest"
+
+commit f7aa1d3a2ede9b40451277ed077098a36c419d71
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Oct 21 22:14:09 2011 +0800
+
+    Remove "#include <iostream>" and rearrange include order
+
+commit 766081a84d93013bb1c5ca28c3370706cbaa9da7
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 20:03:51 2011 +0800
+
+    Changes to fit LLVM Release 3.0
+
+    1. generate the diff for llvm 3.0 based on r142614
+
+    2. made the corresponding changes about TargetRegistry and TargetSelect
+
+    commit 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
+    Author: Evan Cheng <evan.cheng@apple.com>
+    Date:   Wed Aug 24 18:08:43 2011 +0000
+
+        Move TargetRegistry and TargetSelect from Target to Support where they belong.
+        These are strictly utilities for registering targets and components.
+
+        git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138450 91177308-0d34-0410-b5e6-96231b3b80d8
+
+    3. remove the code for llvm 2.9
+
+commit e3502d9411bab32ddf06accd4ccaff231e2b38e0
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 17:51:07 2011 +0800
+
+    Style: Avoid std::endl
+
+commit 059dc0551fa92e068dd145189b377c502784d9f6
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 17:36:08 2011 +0800
+
+    Style: Do not use 'using namespace std'
+
+commit e40a57cc29ea1ca3ff835920c30c5279bd85f471
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 17:24:38 2011 +0800
+
+    Style: more license fixes
+
+commit e645c3e0e22f92e8a924536b1aa98f2386832aae
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 17:20:32 2011 +0800
+
+    extend the AUTHORS list
+
+commit 73d9e668f734c43fa44ec3e214b1321c1781e56f
+Author: pete <petechou@gmail.com>
+Date:   Fri Oct 21 16:35:59 2011 +0800
+
+    Style: Modify the license and include style to fit llvm style
+
+commit ddece1991a5d370d80ca2de31f8fcb64197b695c
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Oct 21 11:32:08 2011 +0800
+
+    Rename the standalone tool
+
+commit 83e08ed9788ee0f2a0c896ff3a5f77888dc33946
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Oct 21 10:57:56 2011 +0800
+
+    Modify build script, avoid building in source directory
+
+commit f8dfc828bb7d75714a7a07335b7a1da184c5b248
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Oct 20 19:27:43 2011 +0800
+
+    Remove two folder "./src" and "./debug"
+    Move MCLinker main to tools/llvm-mcld
+
+commit 3e78adc440d54a544a040ba2e83e76d8f117f6e5
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Oct 12 08:14:17 2011 +0800
+
+    Code clean up.
+
+commit ebee2cfab18ce62a6f20e0a09a9acc89af6dad33
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 11 21:08:16 2011 +0800
+
+    Implement shouldOverride.
+
+commit 8c3cf01465d6fb013dd933825a60cf03ea2952a3
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 11 16:14:24 2011 +0800
+
+    Overwrite -> Override.
+
+commit 11a4e5d15095bfb35150aa02685f78d1c92fb118
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Oct 6 10:07:34 2011 +0800
+
+    Add checks before RegionWriter writes buffer
+
+commit 8e70d908ba564cee4d3373ed2d167a01b364c888
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Oct 5 20:09:43 2011 +0800
+
+    Add LDWriter scaffolding
+
+commit 3d16c37f6a0078a9e48e839529d55740865dfd4e
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 19:43:37 2011 +0800
+
+    Change some fatal failure to nonfatal.
+
+commit 474175b9230dee039a1128d19417055cfcbb5ab6
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 17:14:17 2011 +0800
+
+    Add more StrSymPool tests.
+
+commit 60858969b65dbeaac3b6eae2a85522eda133ba0b
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Oct 4 14:00:04 2011 +0800
+
+    Add unittest for StringTable.
+
+commit 4b904a594ca281419ae15d3250d8151815c7c243
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 13:55:57 2011 +0800
+
+    Resolver pass by value.
+
+commit 32f6b6c9dace7546281c7d814a740dad6657f67f
+Merge: 041c1c2 da5dd9e
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 12:24:32 2011 +0800
+
+    Merge remote-tracking branch 'origin/master' into symbol-table
+
+commit 041c1c2f45e24cfdb453c743c7e14abed230f7cc
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 12:23:49 2011 +0800
+
+    Add StrSymPool unittest.
+
+commit da5dd9ee45bfabd425c68e73722997e58e4d1132
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Oct 4 11:39:57 2011 +0800
+
+    Fix StringTable.
+
+    Move StringTableIF to StringTable.
+    Cleanup useless unittest.
+
+commit bfd56054fb52fe4a54a03f506dac4759fb82c691
+Merge: dc62dd8 ce06c6b
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 10:19:07 2011 +0800
+
+    Merge branch 'origin/master' into symbol-table
+
+    Remove SymbolStorage.
+    SymbolTableFactory finished.
+
+commit dc62dd8e6339a08a1d838d753e287fc8a763234f
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Oct 4 09:19:25 2011 +0800
+
+    Fix SymbolTableFactory.
+
+commit ce06c6bfc0d300ee120b9ebd9df05eb5b7ed67cd
+Author: luba <lubatang@gmail.com>
+Date:   Mon Oct 3 11:52:14 2011 +0800
+
+    Add SymbolStorage under ${MCLinker}/LD
+
+    This is an early prototype of SymbolStrage. Some trivial bugs may occur.
+
+commit 77cd06378472bdd63752a52578085f077804892f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Sep 30 17:31:32 2011 +0800
+
+    Add the definition of LDSection
+
+    LDSection represents a section header entry
+    It is a unified abstraction for various file format
+
+commit b756bffdf5061043605a1390818d9a59c089fff8
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 29 23:56:15 2011 +0800
+
+    Fix SymbolTableFactory.
+
+commit c364b0b6530c4de753d74f18af0ec3d5b51ef77d
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 20:01:42 2011 +0800
+
+    Add default value for "Value", "Size", and "Other"
+
+commit 28dbc8c229439eea98564ab31d0238d914dd9e83
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 19:48:24 2011 +0800
+
+    Sorry for such a large commit again.
+
+    Fix typo: Catagory to Category.
+
+    Implement SymbolCategory::interpose.
+
+    Move out CategorySet from StrSymPool.
+
+    Fix compilation of StringTableIF.
+
+    Add "Value", "Size", and "Other" argument to insertSymbol.
+
+    Add LDSymbol's private copy constructor and operator assign.
+
+commit 3bb98f27f042923a5fbe80e605a630e817fdbd49
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Sep 28 19:51:15 2011 +0800
+
+    Add the testing file for MemoryArea unittest
+
+commit 7b26b4902ad6c91eb62453398865f86df02e4ebc
+Author: Diana Chen <diana.chen@mediatek.com>
+Date:   Wed Sep 28 14:28:08 2011 +0800
+
+    Add testcases for MemoryArea
+
+commit 22adaeac58590b2230b0c8a606ef64a9a14bac15
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 13:29:06 2011 +0800
+
+    Implement that move symbol to other catagory.
+
+commit 83c50ded317a100f12ac3c543ad60d38e852f75b
+Merge: 9de22cd 74e9046
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 11:50:57 2011 +0800
+
+    Merge remote-tracking branch 'origin/master' into symbol-table
+
+    Merge StrSymPool and Resolver.
+
+commit 9de22cdadb8f5ec9fa83f82b144398be0c788e26
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 11:48:04 2011 +0800
+
+    Sorry for such a large commit again.
+
+    We use StrSymPool instead of SymbolStorage and StringStorage.
+
+commit d6e65d9b7cc20b22465245a61dd25c771cdbdc26
+Merge: a2a4cd7 7c3b4df
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 28 10:44:18 2011 +0800
+
+    Merge branch 'origin/master' into symbol-table
+
+commit 74e904670ef790ba4425acb9f206effb0ca4c6e0
+Author: luba <lubatang@gmail.com>
+Date:   Wed Sep 28 11:41:53 2011 +0800
+
+    1. add forward declaration of LDSymbol in Resolver's header file.
+    2. add the including of LDSymbol's header in Resolver's implemenation file.
+
+commit 1128fcfc51ef86d0ad8a9b02681fd773fbe59f9b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Sep 28 11:31:21 2011 +0800
+
+    Add mcld::Resolver to bind symbols.
+
+    mcld::Resolver is the object who processes symbol resolution.
+
+commit 7c3b4dfc4f862fe68e2b9c6f9d6ab3fff75eee40
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Sep 27 17:52:46 2011 +0800
+
+    Implement the function of StringTable.
+
+commit 3155131f8487f311818e82248f2270238463dfbe
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Sep 27 16:25:08 2011 +0800
+
+    Fix the architecture of StringTable.
+
+commit 8cbc92b8b84f843ee1c49219cea6e351a1ad1440
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Sep 27 10:18:11 2011 +0800
+
+    Fix twice increment.
+
+commit 51a8cfccfa09a9775060c2b4e1608629259267ce
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Sep 27 09:57:19 2011 +0800
+
+    Move StringTableStorage to StringStorage.
+
+    Change StringStorage API, without changing usage.
+
+commit 2713fd1c933554a508f29f7e1556d3f3d0191db3
+Author: luba <lubatang@gmail.com>
+Date:   Mon Sep 26 03:51:51 2011 +0800
+
+    1. MemoryArea can write back to the mapped file
+    2. Finish memory mapped I/O parts of MemoryArea
+
+commit a2a4cd7cfa145a7a58773b01e087f835b94e3a5b
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Sep 20 20:27:40 2011 +0800
+
+    Sorry for such a large commit.
+
+    Add all symbol table relative source code to Makefile.
+    Compile success, we need some unittests.
+
+    Add three symbol list: Entire, Dynamic, Common.
+    We cache the specify type symbols, then we can traverse more easy.
+
+    Remove SymbolTableFactory's template.
+    We only use singleton on any cases.
+
+    Move some small function from cpp file to header file.
+    For "inline".
+
+    Move SymbolList to SymbolStorage.
+    Let class dependency become a DAG.
+
+    Use reference instead of pointer when it can't be null.
+
+    Add "rebind" to LinearAllocator.
+    Obey the C++ Standard. For StringUnorderedMap using.
+
+commit 8dd4676cb9dafb7f706be42145ee96260e99eecf
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Sep 20 14:30:25 2011 +0800
+
+    Move SymbolList decl to SymbolTableIF.
+
+commit ab9bc330ea702b4fd01e8fbf8b6b00b9efc7466e
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Sep 20 13:08:50 2011 +0800
+
+    Implement SymbolStorage.
+
+    Change LDSymbol's friend from SymbolTableEntry to SymbolStorage.
+    Add SymbolStorage and SymbolTableEntry to Makefile.
+
+commit c258dfe219d00f9aa29406af6e72922489c3b9a5
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Tue Sep 20 11:20:05 2011 +0800
+
+    Modify StringUnorderedMap functor and allocator.
+
+    For empty base class optimization.
+
+commit f4010b6d6b0a5eb15c766799daa78a170348f913
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Fri Sep 16 22:13:22 2011 +0800
+
+    Fix StringTable unittest bug.
+
+commit 4fb28d22ee9b8678a04a91a945ea6c151ee71548
+Author: luba <lubatang@gmail.com>
+Date:   Fri Sep 16 18:12:30 2011 +0800
+
+    1. add readSymbolTables() and mergeSymbolTables() in MCLDDriver.
+    2. remove obsolete class SymbolTable
+
+commit f8b323d1e834b8beac3c21634e3545f3610d4ce8
+Author: luba <lubatang@gmail.com>
+Date:   Fri Sep 16 18:08:14 2011 +0800
+
+    Review SymbolTableIF
+
+    1. Fix a but - the last embrace of class SymbolTableIF is not followed with ';'
+    2. Add comments
+    3. change the name merge_impl() and insertSymbol_impl() to doMerge() and doInsertSymbol()
+    4. let getSymbol as a observer - return const LDSymbol*
+    5. add a new modifier getSymbol() - returns non-constant LDSymbol*
+
+commit 641d648470b231c49fb6e8a2bb1bd3895b70ddcc
+Merge: 61a2476 106f9c3
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Fri Sep 16 16:28:50 2011 +0800
+
+    Merge remote branch 'origin/master' into HEAD
+
+    Conflicts:
+    	debug/Makefile.am
+
+commit 106f9c304e96625fa8b762a24fdd8b2e8a0abefe
+Author: luba <lubatang@gmail.com>
+Date:   Fri Sep 16 15:51:47 2011 +0800
+
+    add --add-needed/--no-add-needed attributes
+
+    MCLinker needs to double confirm if it is allowed not to copy the DT_NEED of input files when
+    checking the dependencies of dynamic libraries.
+
+commit 61a247653b9d748dd9f29eb40acef06695a178af
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 15 23:33:19 2011 +0800
+
+    Add SymbolTableEntry usage to SymbolStorage.
+
+commit cef15fdcc1178658abafda99b14b9ea8773f637b
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 15 23:31:28 2011 +0800
+
+    Add SymbolTableEntry.
+
+commit 637f5ed17d6e51ca63bd11ce9c6fb2920a36167b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Sep 15 20:53:25 2011 +0800
+
+    Add a unittest for MemoryArea
+
+commit 8828be501730baf80cbf675323cfa8742b879dd6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 20:27:30 2011 +0800
+
+    Finish LDSymbol and move SymbolTableTest out of unittest
+
+    Because SymbolTable has not finished yet, and it conflicts with current LDSymbol,
+    I move it out of the compilation list.
+
+commit ec89c687a517e8b24c38b3b3f29fe8b5eb1f214c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 19:55:02 2011 +0800
+
+    Fix a bug - MemoryArea::isGood() returns the opposite value.
+
+commit 7b40a5172acb2ce2f307699b61082ab37d0cdf3f
+Merge: bce4c35 43e7101
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 15 18:08:22 2011 +0800
+
+    Merge remote branch 'origin/symbol-table' into nowar
+
+commit 596d478524ec9afc462aa323b4c23e7cb6209e6d
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 16:18:32 2011 +0800
+
+    Finish the implementation of MemoryArea.
+
+    I have not implemented memory mapped I/O parts of MemoryArea.
+    Because when we link in Android platform, linkers load few sections of input files.
+    And memory performance is not a critical issue under such scenario.
+
+commit 67f7ab10981ef3721800d47b3ac8152ea42ab2a5
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 16:17:26 2011 +0800
+
+    Fix a typo error - Allocator::isAvailable()
+
+commit 70b53f382c158a50c8931eb772e92535e45a8ee6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 14:51:11 2011 +0800
+
+    MemoryArea::request add a new case: if we find an existing space.
+
+commit 001cd1479c9d0b2ff4c0965e7412ab9bcf40b379
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 14:05:57 2011 +0800
+
+    Let MemoryAreaFactory create MemoryRegion by RegionFactory.
+
+commit 94d8c0040a9d6238197a6b0a6f263d46d8df48f8
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 14:05:35 2011 +0800
+
+    add RegionFactory to manage all MemoryRegion.
+
+commit f007e2bb769933593d4d2aea78e78e41f0037a18
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 14:00:49 2011 +0800
+
+    add an empty testcase of MemoryAreaTest
+
+commit cdd634ba7dc67514b63aae56127f11e14ac20ce5
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 11:10:46 2011 +0800
+
+    Finish the scaffolding of MemoryArea and implementation of MemoryArea::request
+
+commit c2c5540083f281eaff49e1d0980dc5186f7dfbee
+Author: luba <lubatang@gmail.com>
+Date:   Thu Sep 15 11:09:23 2011 +0800
+
+    Let the implementation source of unittest searches in the local directory first.
+
+commit bce4c358e6a402585fbdf619d777f75efc047f7a
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 15 10:23:13 2011 +0800
+
+    Fix memory leak on string table.
+
+commit 3618c931ceb0d633ec2d842682c5fd77c1ba6d99
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 15 09:57:10 2011 +0800
+
+    Fix null-terminated string size bug.
+
+commit 43e7101747b1f9c193a44fbd7fe07cb112125fb1
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 18:23:27 2011 +0800
+
+    Fix StringUnorderedMap StringType.
+
+commit f2f18f7eef077ed67618d8b1414e0eb4c8eb44fb
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 17:28:00 2011 +0800
+
+    Fix SymbolTableFactory singleton.
+
+commit 81845fad57b14465791c392333c6c4adc8e7f367
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 17:00:48 2011 +0800
+
+    StringUnorderedMap: clear() & destructor.
+
+commit 3f91c8eefdf3d0e9007f32b2dd0031b76fbd6eb2
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 16:42:29 2011 +0800
+
+    Add StringUnorderedMapTest.
+
+commit 67505dc6fc7a281adbba5089293270ca87d196f2
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 14:16:00 2011 +0800
+
+    StringUnorderedMap is close to finish.
+
+commit 4ca681b2db8bf4a0b881924fe57fab357b65e3ca
+Merge: 0d78df2 239064e
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 10:53:22 2011 +0800
+
+    Merge 'origin/a127-tmp' into symbol-table.
+
+    Merge our StringUnorderedMap.
+
+    Conflicts:
+    	include/mcld/LD/StringTable.h
+
+commit 0d78df23fb8f6308fea9d43b81668ee687d6c76c
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 14 10:48:23 2011 +0800
+
+    Use StringTableIF rather then StringTable.
+
+commit 7a378374448df0265c57cb3253d79d09e48a089f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Sep 13 15:25:59 2011 +0800
+
+    All mcld::MCLDFile gets its MemoryArea.
+
+commit 45c920eab8f6adfa1e14242eafde9ec5c6dfb752
+Author: luba <lubatang@gmail.com>
+Date:   Tue Sep 13 15:16:53 2011 +0800
+
+    add MemoryAreaFactory in MCLDInfo.
+
+    The architect decides let MCLDInfo carries MemoryAreaFactory to everywhere.
+    It may be a stupid decision. If it's stupid, please tell Luba gentely.
+
+commit cfd9de20f114265e371a2f65fdb759c72a4a1ff5
+Author: luba <lubatang@gmail.com>
+Date:   Tue Sep 13 14:54:49 2011 +0800
+
+    add new class MemoryAreaFactory
+
+    MCLinker should let two different inputs with identical file path share
+    the same MemoryArea. So, like ContextFactory does, we provides a new
+    factory to do that.
+
+commit 2a43699955b158a36126736fd4a0591e8c49f466
+Author: luba <lubatang@gmail.com>
+Date:   Tue Sep 13 12:03:49 2011 +0800
+
+    Add UniqueGCFactoryBase.
+
+    Because we have more and more request for an associative factories which
+    has unique key and value pair, for example ContextFactory and
+    MemoryAreaFactory, therefore, I create a class UniqueGCFactoryBase for
+    the common parts of these factories.
+
+commit ea30a3a7b79db9cb8940a0a8c239141bd13367c9
+Author: luba <lubatang@gmail.com>
+Date:   Tue Sep 13 12:01:45 2011 +0800
+
+    envsetup.sh determines if the user is on SWRD server stg01 and add git commands in the searching path.
+
+commit ce0ea9786d7e03e7efc091a43d356c4f99b8e06e
+Merge: 2e3d040 4ae7094
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 8 18:56:48 2011 +0800
+
+    Merge remote-tracking branch 'origin/symbol-table' into nowar
+
+commit 4ae7094eba1c2296b3e0b057a6eedff4d6a46e8b
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 18:53:49 2011 +0800
+
+    Add SymbolStorage's some code.
+
+commit 2e3d040969f804665d4f3c6177457827445e82cd
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 8 18:49:46 2011 +0800
+
+    Add StringTable, DynStrTable, and unittest.
+
+commit f35dbb5fea04d1166a5b193873f686cf3dbe661c
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 17:58:00 2011 +0800
+
+    Reserve SymbolList size when construct.
+
+commit 808a7b1e5c91916e8c81a86faf9d6597b565e279
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 17:30:28 2011 +0800
+
+    Remove LD prefix.
+
+commit 878e229732e29e65bb3527b7152039b9d8aec905
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 17:26:39 2011 +0800
+
+    Remove LD prefix.
+
+commit d58566b0bd8f7f77491cd983c4fdb34a84d75816
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 8 17:14:15 2011 +0800
+
+    Code cleanup. Remove LD prefix and old StringTable.
+
+commit d23795114d9a4f215f14316e013a9f039a9ad128
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 8 16:54:46 2011 +0800
+
+    Add scaffolding of StringTableFactory.
+
+commit 58db1a9e2fbe7fc7f826e6c04f741d0bffb90851
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 16:52:24 2011 +0800
+
+    Add LDSymbolTableStorage draft.
+
+commit 8b1ba35c2f4b9ebf0bfa09dc9fb8d7abf1259f1c
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Sep 8 16:51:39 2011 +0800
+
+    Add scaffolding of StringTableStorage and StringTableInterface.
+
+commit 337f6adeba144944e49ef83489f560506f099ad6
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 13:43:36 2011 +0800
+
+    Fix LDSymbolTable initialization.
+
+commit 75a7945082edf34aee1f26af01c7673f8c75f7ea
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 13:31:46 2011 +0800
+
+    Implement constructor and distructor.
+
+commit 0c981e9f50f727da824015d3a5d8856dd59df8c0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 12:28:57 2011 +0800
+
+    Remove LDDirectSymbolTable and LDIOSymbolTableIF.
+
+    Now:
+                  LDSymbolTable
+                        /\
+                       /__\
+                        |
+            --------------------------
+            |                        |
+    LDInputSymbolTable      LDOutputSymbolTable
+
+commit b47ffc09d2b70c3c8c5f8156ecc2da6ffe26c955
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 10:25:08 2011 +0800
+
+    Remove unwanted typename.
+
+commit 3e545b352c7b63b950125000800bdfa9f47384c0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 10:04:21 2011 +0800
+
+    Move virtual member to private.
+
+    Use NVI pattern let the iterator operation can be hidden by derived class.
+    Then the iterator operation can be fast when know the type.
+
+commit f2b687ba31b5662427b85cc4aa35a0044edb4c45
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 08:15:15 2011 +0800
+
+    Impl Input and Output SymbolTable::insertSymbol.
+
+commit 215ed62dd6d0ac5b729d30050749557d9f90d1ee
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 08:04:50 2011 +0800
+
+    Add MCLDOutput.h include.
+
+commit 841774e4cc04573cd845c426842bb5aaa95cf24c
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 8 07:54:36 2011 +0800
+
+    Interface changes. Implement DirectSymbolTable.
+
+    Move iterator relative interface to lower level interface.
+    Implement DirectSymbolTable.
+
+commit 8ee8cf8b610cbeb07bef36685e5f48be0008ebae
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 23:09:55 2011 +0800
+
+    Add LDSymbolTableFactory<true> draft.
+
+commit d176b5138db7f5096b0bab3ce2b2d1031521d1e2
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 22:38:02 2011 +0800
+
+    LDSymbolTableFactory is LDSymbolTables' friend.
+
+commit a769c14a1cb7f313bfb2420305a06e5c0729520e
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 22:20:31 2011 +0800
+
+    Add draft note.
+
+commit 47eab80a93cddba2ae838d28ba13f24b6d6f59a2
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 22:15:48 2011 +0800
+
+    Add symbol table factory draft.
+
+commit e7e916941a99b27eca092493792eac757ff68ee0
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 21:59:48 2011 +0800
+
+    Fix typo: talbe -> table...
+
+commit a8300f3914b371e62a350fb2b8aec82d1b5bafaa
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 21:43:24 2011 +0800
+
+    Add direct symbol table draft.
+
+commit a932f98a838a65fe7ccec131859e170384d6cf4c
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 21:40:19 2011 +0800
+
+    Add LDOutputSymbolTable.h include.
+
+commit 99543babb6db39bcaa4259344ba9056e6bf7f1ae
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 21:21:19 2011 +0800
+
+    Add Output symbol table draft.
+
+commit 1bbecf1d27db4cf2e2afd4333a19d53bffa9bfce
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 20:39:43 2011 +0800
+
+    Add input symbol table draft.
+
+commit 871ca4c0b31a20126a839d08a5bc45f2a984cbf1
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 20:31:28 2011 +0800
+
+    Add IO symbol table interface draft.
+
+commit 8cab6036f0afaddc22e49c169ecf68116c5cf344
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Wed Sep 7 20:23:28 2011 +0800
+
+    Add Symbol table interface draft.
+
+commit d7895e40690b87418f14cb84fa13b9756e120308
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Sep 7 10:15:48 2011 +0800
+
+    Add FIXME to unittests for "DirIteratorTest"
+
+    Some bugs modifies the global value "errno" to non-zero.
+    This makes readir() failed when daily build system runs unittest
+    Remove the FIXME after fixing those bugs
+
+    This unittest fails only when running unittests by daily build system
+
+commit 239064e6d8f23558ad5ecc1cf59e6088c14062e5
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Sep 1 19:14:01 2011 +0800
+
+    Add StringUnorderedMap draft(not complete).
+
+commit 3d65138fdfdab0b994888aee195a9135f73e7429
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 31 08:04:46 2011 +0800
+
+    Add some missing unittest of StringMap.
+
+commit fe7ff2a94c9fd787f9fa0f7b3c6f399eb7e324af
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 31 07:47:19 2011 +0800
+
+    Add SymbolTable, LDSymbol and corresponding unittest.
+
+commit 3e67358487dd0ff11ae97571eca2ee1bb719e27f
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 30 13:43:26 2011 +0800
+
+    Add StringTable and corresponding unittest.
+
+commit 4bbe75fe3202a731b303ef0dd38d8dd77b9a0308
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 30 11:17:09 2011 +0800
+
+    Improve StringMap unittest. Replace tab by 2 space.
+
+commit a893afcb5bf673e5703614796101949ce248bce2
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 30 16:10:06 2011 +0800
+
+    Let MCLDFile get MemoryArea.
+
+    MemoryArea is the manager of memory map I/O and allocated memory array for files.
+    MCLDFile uses MemoryArea to get memory regions.
+
+commit 66a232e3cdf4a22ed4094b126f9c579c7bcae354
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 30 16:09:09 2011 +0800
+
+    add the scaffolding of MemoryArea and MemoryRegion.
+
+commit af909522fe4369afda1f3aa111b3c297537f2442
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 30 14:05:36 2011 +0800
+
+    The result of unittest BFS_BasicTraversal was wrong, fixed it.
+
+           Root
+           /
+         111
+         /  \
+        9   10
+       / \
+      7   8
+
+    ROL, the result should be 111, 10, 9, 8, 7
+
+commit a8e920dcb2bc8e6f7361b967e3f696aaa343257d
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 30 09:54:16 2011 +0800
+
+    Add features into scripts.
+
+commit e11caa50c0486246788a0f43b05c1a326d7e8675
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Aug 29 20:35:15 2011 +0800
+
+    Adding a header file for std::cerr
+
+commit 24e84578d7aa5f30c6f13693778d9d75d3c3296e
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 29 20:21:56 2011 +0800
+
+    Add a Config.h.in
+
+    autoconf reads Config.h.in and generage Config.h
+    Some target-independent information about MCLinker are in.
+
+commit c2224729a2907edf6753c7fcc77294926d25a5cd
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 29 20:21:13 2011 +0800
+
+    add unittest for StringMap
+
+commit 1d11a78bc8608da1dd46b6a1553bdc98533e113a
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 29 20:19:16 2011 +0800
+
+    add X86 target in compilation.
+
+commit c15f0c015fe65831f63e307a399fdeefaadee0fb
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 29 20:18:53 2011 +0800
+
+    add X86 target
+
+commit dd067673e230d69f1bd2b4c98c6d9bfd236273cf
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 29 19:53:46 2011 +0800
+
+    Fix bugs
+
+    1. StringMap's constructor set value to parameter, not member variable
+    2. cur_node in SectLinker initializeInputTree does not move forward correctly.
+    3. refine BFSIterator algorithm
+
+commit 4accb839a02ea302b9dcdd72cc77f56e89421fa2
+Author: luba <lubatang@gmail.com>
+Date:   Sat Aug 27 16:59:05 2011 +0800
+
+    VERSION - The document of software versioning.
+
+commit b66e4d97bbd3d4c9d72f7eafb2ae70fb16457a09
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 26 18:13:09 2011 +0800
+
+    add option -V and -verbose for demo.
+
+commit 9051b6f3de4fff555dc1860bded747b601e80e5e
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 26 17:46:12 2011 +0800
+
+    LLVM 3.0svn removes IsSymbolRefDifferenceFullyResolvedImpl from target writers.
+
+    Since LLVM 3.0svn let MCObjectWriter finish the jobs of IsSymbolRefDifferenceFullyResolvedImpl,
+    we do not need to expose this function in MCAsmObjectReader any more.
+
+    This patch also fixes the bug - an unexpected assert in ARMObjectReader::getRelocInner().
+
+commit 89bc3b6d8513a8f7da6ddb0b5e2305fb69dc0335
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 26 11:26:51 2011 +0800
+
+    This patch is by Wen-Han Gu - Add the Relocation class.
+
+    BTW, PLEASE make sure EVERY COMMIT can be COMPILED!!
+
+commit 1f9c0c5c10fd6de0154712b365126d901800eeb9
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 26 10:57:11 2011 +0800
+
+    LinearAllocator doesn't mean to release memory at destruction.
+
+    By the C++ standard, allocator is just an abstruction of underlying memory.
+    It should not refer to the area of garbage collection, even memory stack.
+
+    Please ask the author written in the header before you starting modifing code.
+
+commit 786c71c9255a2d55de3b2b47406583e712c7f80d
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 25 18:59:07 2011 +0800
+
+    Improve MCAsmObjectReader::RecordRelocation().
+
+commit 8fa8a35f3b7a44aded948651d8c793768798f7bd
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 25 17:12:09 2011 +0800
+
+    Move RelocationInfo from MC to LD.
+
+commit a3cbae418e766aca4c0c495ca59e8a683ed06746
+Author: luba <lubatang@gmail.com>
+Date:   Thu Aug 25 11:43:29 2011 +0800
+
+    enhance -t output
+
+    Display the name of a object file when -t enabled.
+
+commit b2d9280de1d8632dc50f4ed666adb708b3f98ccd
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Thu Aug 25 13:21:37 2011 +0800
+
+    Add LD/StringTable draft.
+
+commit 59bb714dc3561b6aa6b058cf6df14eadd0891fdd
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 25 10:24:16 2011 +0800
+
+    Let objects in StringMap live consistently.
+
+commit 09371704bdc653fbe14141828aa87d42a8349746
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 24 21:17:50 2011 +0800
+
+    Keep valgrind leak-check silent.
+
+    Call clear() in destructor of LinearAllocator.
+
+commit c2e92a3b1b06400b04ef0ab1feba2ea882317171
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 24 20:31:35 2011 +0800
+
+    Fix memory leak in unittest.
+
+commit 5c0d0906951cf4bf20394fe08269426d2102c75b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 24 17:57:27 2011 +0800
+
+    fix a bug in AttributeProxy.
+
+    Bug: AttributeProxy::isStatic() check the wrong condition of AttributeConstraint.
+
+commit fe21a3652b594834475eecc22ea0eea7c8943327
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 24 15:26:58 2011 +0800
+
+    Implement our mcld::StringMap.
+
+    An object adaptor of llvm::StringMap to make it
+    - While insert, only find once, and we can get the iterator to the Value
+    - Stable iterator
+
+    Thanks for TDYa127!
+
+commit 8ffed91cbd22b31dc9264da31bff829550e6b9a8
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Aug 24 13:38:29 2011 +0800
+
+    Adding type identification for -dy & -static
+
+commit f92a911524478c09bc2108f590bcc378cce5addc
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Aug 24 09:34:30 2011 +0800
+
+    Adding missing header files
+
+commit c11ee37e58a36af6531d10670c3787221c8f097b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 24 02:33:51 2011 +0800
+
+    Fisrt stable version of normalization.
+
+    Bugs List:
+     1. ArchiveReader can not read members correctly
+
+commit a22efb5ebe91b7bd8e3e887991f4e4bf24c9ca17
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 24 00:21:41 2011 +0800
+
+    MCLDDirectory should not be opened if in sysroot.
+
+commit 2ecc851588c4a7c350b16e9bea113618152a93cf
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 23 22:53:51 2011 +0800
+
+    Fix the bugs in Path library
+
+    canoncal_form is wrong in some cases.
+    For example - '//' should not be entirely removed. There should be existing a '/'.
+    Another case is '/.kde.local/../', the result of old conocal_form is 'kde.local/../'
+    the correct result should be '/'
+
+commit edc85d4ad21f741ca033ebb39afbffd99f4c890c
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 23 14:06:32 2011 +0800
+
+    Never use the space having been freed.
+
+    RehashTable() of llvm::StringMap *MIGHT* delete the table.
+    That cause us has SIGSEGV sometimes.
+    Now this is bug-free, but less efficient.
+    When inserting, lookup happens twice.
+
+    I'm thinking maybe I should re-design a mcld::StringMap.
+
+commit 928641b775aca69db87fa157dc8e68a0f40e9a2c
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 23 11:42:19 2011 +0800
+
+    Add function - RealPath& RealPath::assign(const Path& pPath)
+
+    Since RealPath has default constructor and copy constructor, it should have an assign function.
+
+commit b50a378d67448f76972456d9551a7b6111b259e3
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 23 11:26:55 2011 +0800
+
+    move SearchDirs under MC
+
+    Since SearchDirs is customized for linking, not a normal case for all searchable directories,
+    we move it from ADT to MC.
+
+commit 376368af3711f813cc0ba54415c0692ae3148af4
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 22 19:39:52 2011 +0800
+
+    add regression test - trace
+
+commit b5b9033a2acadb2c635c100f65994b6cdcf9a06e
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Mon Aug 22 19:19:53 2011 +0800
+
+    Follow the default template parameter.
+
+commit c26fcc7b036e977ef6008090d6c3d951ef3de49d
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 22 19:02:24 2011 +0800
+
+    Fix the bug - IteratorBase should have a default constructor
+
+    DFSIterator's constructor needs the access its left child and right child.
+    However, in the default constructor of IteratorBase, both left and right children are NULL.
+
+    For avoid dereference NULL pointers, I create a new default constructor of DFSIterator that does not pre-read the left and right children.
+
+commit 0c6bed4492fca5ac3d89c1786ee4f29f6ba15e9b
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Mon Aug 22 18:06:14 2011 +0800
+
+    Make a partial-specialization of llvm::StringMap.
+
+    We need a more-suitable-interface one when template parameter
+    is our mcld::Path.
+
+commit 53933ce899edbed2ecbf2af8e310e9839d32a25c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 22 17:11:07 2011 +0800
+
+    Fix the bugs in BFS iterators.
+
+    Pin-Roung is so stupid.
+
+commit c645a0c678857a4f36340a33d9e183627325eda3
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 22 16:58:48 2011 +0800
+
+    Fix the bug of DFS Iterator
+
+    Pin-Roung is stupid.
+
+commit 9cb394d2be904f26f00f75f7d430151d687615d9
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 22 14:44:23 2011 +0800
+
+    Bug free but bad performance Directory
+
+    This version of Directory needs two StringMap::find
+
+commit 93d8305872a5eaf08bf30b9648f4f19a8007e215
+Author: luba <lubatang@gmail.com>
+Date:   Sun Aug 21 22:25:33 2011 +0800
+
+    Fix a bug - read an entry in the directory immediately after opening a directory.
+
+commit 87a1bfeb89dd3675fdba264c8452d237c0e5d0a9
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 19 14:33:36 2011 +0800
+
+    add some diagnostic code in MCELFObjectReader::isMyFormat
+
+commit 8cede7eeda6bf4798f11339f1c82db4f7bb0bb63
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 19 14:08:41 2011 +0800
+
+    Change the PositonDependentOptions
+
+    Since LLVM removes the data of cl::list<Data> when it leaves scope.
+    We let PositionDependentOption stores the data.
+
+commit 5d2db3f9fb2355556cd8eb9523621c3bb8401ad0
+Author: luba <lubatang@gmail.com>
+Date:   Fri Aug 19 13:50:40 2011 +0800
+
+    Release AsmStreamer in the wrong time.
+
+commit 5a6100474a49ac801c9ebc5abc8caca928c4e88f
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Fri Aug 19 13:25:01 2011 +0800
+
+    First compile-able release for 8/11's scope.
+
+    !!WARNING!! This version is not debugged.
+
+commit f991492dfba6de66c720270fccdbb9c7e0692f19
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 8 20:37:20 2011 +0800
+
+    Cancel the target-dependent archive reader.
+
+    Since the difference of the formats of archive files are only on
+    the OS type, not on target, we remove all target-dependent archive readers.
+
+commit 48fe63f04e8fe6d158d9290b4dd4a1c6203dd94b
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 10:40:07 2011 +0800
+
+    add iterator for each data in the Allocator.
+
+commit c0223e1943542c1fd1ad4ca34ad55e1870ffc703
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 29 02:05:11 2011 +0800
+
+    A syntax-correct BinaryTree
+
+commit 4368ec551ebb65fd127f5d93caafdf8304c93753
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Aug 18 18:18:47 2011 +0800
+
+    add scaffording of algorithm about MCArchiveReader.
+
+commit 25fb7e66a8d5eeee84e333f39d32b3d673aa0a4a
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 18 17:40:12 2011 +0800
+
+    Change design: Need no MCObjectTargetReader.
+
+commit ab133b6d81efc4cdb03b233289b7d341fd6691b4
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 18 16:40:55 2011 +0800
+
+    Implement mcld::MCAsmObjectReader::RecordRelocation() done.
+
+commit a5b299ed5fc0614867cff23949d0c679b60a999a
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Aug 18 16:36:00 2011 +0800
+
+    fix a bug: archive map is big-endian, and turn on the binaryTree test case.
+
+commit 3ae4df53b920d33e5ff4daa9be8532eecf386441
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Aug 18 10:40:31 2011 +0800
+
+    Refine BinaryTree::merge(): change template argument order.
+
+commit 89c9f31107b7cd98732176bf1201d08270d886b6
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Aug 18 10:06:49 2011 +0800
+
+    Fixing MCObjectReader
+    it reads hello-jni.o & libhellojni in NDK samples
+
+commit 1d65d9314fee829ef96cf032cf0c4f131e9410bc
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 18 09:09:47 2011 +0800
+
+    Implement mcld::MCAsmObjectReader::RecordRelocation().
+
+commit a9d1e8f2ff5db35977ce46d8a6f0b7ea16d2fbb2
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Aug 17 22:15:41 2011 +0800
+
+    Refine the DFSIterator inheritance system. Add scaffording of MCArchiveReader. Modify MCLDDriver::normalize(), and let it can traverse to an archive. Use "using BinaryTree<Input>::merge" expression in InputTree, so we can use it from object of InputTree. Shut donw The test case of BinaryTree. I will fix it later.
+
+commit 17b939b0d4b942c10da0c27d96a5baa98da31965
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Wed Aug 17 20:29:40 2011 +0800
+
+    add a new class - PathSet
+
+    PathSet is a specifized set of Path for fast searching.
+
+commit 0e2b86f9f80b2fd92b321492df1dcb1db4b7d750
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Aug 17 19:58:54 2011 +0800
+
+    Fixing isMyFormat() for MCELFObjectReader
+
+commit a9e63c955ab1765e349056c3b52bbe9414143f7d
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 18:03:42 2011 +0800
+
+    Offer reloc_iterator for MCLDContext.
+
+commit 38d447e04716c45e09a13a76968c31116ff7b0a0
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 17:52:22 2011 +0800
+
+    Add `has_addend' field into RelocationEntry.
+
+commit 881b7fb08a0c63a2fb077130709f3f9f2bc343df
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 17:34:35 2011 +0800
+
+    Make comment more clear for r_info.
+
+commit ffb5d1c298dfe2679fb07d05b6af6a31b9341220
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 17:25:45 2011 +0800
+
+    Determine the common relocation entry.
+
+commit 09ab13aee039f0f0cc2acef622f8d54aaa1ed5df
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Aug 17 17:09:20 2011 +0800
+
+    Let it no compilation error.
+
+commit a787aecfd812b6094a08cd42b9e618d6597c9e8b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 17 13:36:47 2011 +0800
+
+    Remove a redundant function - Inputfactory::produce(StringRef pName);
+
+commit 93862ae3fc92ae806cdc40bd36999591e08bc744
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 12:03:28 2011 +0800
+
+    Move Relocation to ELFRelocation.
+
+    There is a design defect in MCLDContext which should have a
+    RelocationInfo reference or pointer, not an ELFRelocationInfo.
+    This version of MCLDContext will break scalability from ELF
+    to other format.
+
+    This code is not done yet.
+
+commit ee5b46e5350cb889d9e077daaf8cba888b8529d7
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 11:17:19 2011 +0800
+
+    Code cleanup for end-of-line space.
+
+commit e9b7421319e2b1dfe82dfc5dc534223f56417716
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 17 09:58:07 2011 +0800
+
+    We don't need `-relocation-model=pic' anymore.
+
+commit 18d8ec16c4a20a0ed58e7fc7e5667bceac9556e1
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 17 09:56:56 2011 +0800
+
+    enable MCLDDriver::normalize() in SectLinker::doFinialization()
+
+commit 240c7ba85ce5b6c4da79f81254a1f588a0fe210b
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 17 09:55:43 2011 +0800
+
+    bool trace() has been moved in GeneralOptions.
+
+    User can get trace() by calling MCLDInfo.options().trace()
+
+commit 365e42996b540e6780aadfdf3d2215b728ef7994
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 17 09:51:03 2011 +0800
+
+    In normalization, ContextFactory should produce Context by the path of mcld::Input. Not a empty path.
+
+commit d0c193c27afb258ac60e9a22b2f0df312ea230db
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 16 21:01:24 2011 +0800
+
+    Add scaffolding of RelocationEntry.
+
+commit 2fcae7190c95cd1773d7b1ff809575242f2021f7
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 16 20:32:23 2011 +0800
+
+    Move RelocationTable from MCLinker to MCLDContext.
+
+commit f4ddd568fc9716bd875556e5c4723a608fc9cfdd
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Tue Aug 16 20:23:38 2011 +0800
+
+    Take out -mcpu option from MCELFObjectReader.
+
+commit 4a881cdebf2200f61daa39a74b4981b6b485812f
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Aug 16 19:54:26 2011 +0800
+
+    Adding scaffolding of normalize()
+
+commit abdae55a774537da7d2275e2ca6b6768776e3739
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Aug 16 19:53:42 2011 +0800
+
+    Adding missing header files
+
+commit 248fffdc3060fde55c905718694c5cb3b3097ad6
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 19:18:12 2011 +0800
+
+    call InitializeAllTargetMCs() in main()
+
+commit ef001ac6fa6c57d193f33b14e47e5ba26777814a
+Merge: 9dd3ca2 d94fde2
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 18:10:16 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 9dd3ca28740de2e117d0cac00961b2d3ce36d829
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 18:05:50 2011 +0800
+
+    mcld::InputTree::bfs/dfs iterators advance more one step when it meets a Group.
+
+commit d94fde270f14e94c80ffebd6504c4044ce8c76e9
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 18:05:50 2011 +0800
+
+    mcld::InputTree::bfs/dfs iterators advance more one step when it meets a Group.
+
+commit ea3a2cdfc8a50dfa796718f9d79d2df27566514e
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 16:21:09 2011 +0800
+
+    Default bitcode is add in MCLDInfo.
+
+    MCLDInfo::bitcode can get the default bitcode that comes from LLVM.
+
+    default bitcode is inserted into MCLDInputTree with mcld::Input::Object
+    type and namespec - "default bitcode"
+
+    Of course, it's the first element of the input tree, and its attribute
+    is predefined.
+
+commit fcc4c583c5fbfe2137af9de68637851780700c4d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 15:16:55 2011 +0800
+
+    Finish MCLDDriver::linkable()
+
+commit 5571053cbd3b56bcfd3ee567f3b8190be52e2f05
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 14:41:08 2011 +0800
+
+    AttrConstraint - The constraint of attributes.
+
+    Create a dedicated class for the constraint of attributes.
+
+commit 2a06832f716272d94c6a7823ec3c7998d62cb16b
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 11:40:53 2011 +0800
+
+    add the scaffolding of MCLDDriver::linkable.
+
+commit 489c64c9fb1004130de3341ffe40b4547a443eb7
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 16 11:04:52 2011 +0800
+
+    Fix a bug - all MCLDInput get the same attribute.
+
+    For easilier readable, I rename
+      MCLDAttribute -> AttributeProxy
+      AttributeBase -> Attribute
+
+    Since many mcld::Input shares common attribute, but AttributeFactory
+    can not assign the very identical pointer of attribute to different
+    mcld::Input when the pointed attribute will be modified in the future.
+
+    So, we let AttributeProxy hold the pointer of the attriubte. When we
+    change the attributes by proxy, mcld::Input will be affected and stick
+    to the same Attribute.
+
+commit 6b0fb384d0b103289d7c1f4f8cd53656c6879be3
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 15 23:11:41 2011 +0800
+
+    Luba changes the big design of MC Linker
+
+    1. all factories are composed in MCLDInfo.
+    2. ARMELFSectLinker is responsed for initialize Attribute and Factories
+    3. MCLDContext is created by ContextFactory
+    4. Allocator<DataType, ChunkSize> and Allocator<DataType, 0> means two different allocation timing.
+    5. AttributeFactory is a Makov-chain of produced attribute
+    6. AttributeFactory is hidden in InputTree and MCLDInfo.
+
+commit 54d196cecedb2b3557f3a486d177bd33f4ffe344
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 15 15:58:57 2011 +0800
+
+    Create the scaffolding of RealPath.
+
+commit 008073c80b760f43856e78cdae94a9ab71c0427a
+Author: luba <lubatang@gmail.com>
+Date:   Sun Aug 14 03:19:39 2011 +0800
+
+    partial specification template of Allcoator<DataType, 0> is the run-time allocator.
+
+    Benefit from template partial specification on Allocator<DataType, ChunkSize>,
+    we use Allocator<DataType, 0> as the run-time allocator. The size of chunk of run-time
+    allocators is no longer a compile-time constant, instead, a run-time integer passed in
+    by constructor.
+
+commit 8723b5b5a8a5de9bd35e7d57edfaae5daa546425
+Author: luba <lubatang@gmail.com>
+Date:   Sun Aug 14 01:33:36 2011 +0800
+
+    Change the roles of SectLinker, MCLDInfo, and LLVMTargetMachine.
+
+    MCLDInfo comprises of
+     - attribute factory
+     - input factory
+     - context factory
+     - the default output
+     - script options
+     - general options
+     - input tree.
+
+    The construction of MCLDInfo is target-independent.
+    Although MCLDInfo contains some target-dependent information, such as the
+    default attribute and the default script, the construction of these data
+    should be target-independent. Therefore, we move the construction of MCLDInfo
+    to LLVMTargetMachine.
+
+    SectLinker now is in charge of the construction of target-indepedent data.
+    Such as the default input file and the default output file. The target-
+    dependent data are contructed by the inheritor of SectLinker. Take
+    ARMELFSectLinker for example, target depedent data, like default link script
+    and the defaut attribute are configured in the constructor of ARMELFSectLinker.
+
+commit 95d1833f8c0b05fd5e309cf48f68cbd1c3ff6cd0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Aug 15 21:30:37 2011 +0800
+
+    Removing verbose debugging information
+
+commit a6afc50cd2bad2b558b0c6272088fbec73849a5d
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Mon Aug 15 20:36:19 2011 +0800
+
+    Fixing MCObjectReader for new commits
+
+    The tool "MCObjectReader"
+    in "tools/MCObjectReader" works again
+
+commit 4e471a376dfd693a75820d724926476b638551a4
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 11 16:54:59 2011 +0800
+
+    Fix typo of RTGCFactory.
+
+commit eef6a26070c136d5d4e61a65a0bae725b8d9f9fb
+Author: luba <lubatang@gmail.com>
+Date:   Thu Aug 11 16:48:36 2011 +0800
+
+    finish the implementation of RTGCFactory
+
+commit 2c535a11f7ed4a5bb25b6c4e369db7a5b5177598
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 11 16:41:39 2011 +0800
+
+    fix some typo error
+
+commit f8669a7161bf32007d69c80136509cbe297e2cbf
+Author: luba <lubatang@gmail.com>
+Date:   Thu Aug 11 16:04:35 2011 +0800
+
+    Implementation of RTLinearAllocator
+
+commit 880b2a188c2a50b3b35f02b94db29a349dd322d6
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 11 15:32:15 2011 +0800
+
+    Add unittest of RTLinearAllocator.
+
+commit b35d1e81872946af73b58d61b71bcfeced2bf07d
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 11 15:24:56 2011 +0800
+
+    Take out the third parameter of RTLinearAllocator constructor.
+
+    Since `llvm::BumpPtrAllocator::DefaultSlabAllocator’ is private,
+    I think we don't need this default parameter.
+
+commit 63d05ca9bc638aae051c3b01e892a294c14bcb4b
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Thu Aug 11 14:42:47 2011 +0800
+
+    Add missing namespace llvm.
+
+commit 5d1c0c59490647636c558fc4690003c5fc6413f7
+Author: luba <lubatang@gmail.com>
+Date:   Thu Aug 11 14:33:34 2011 +0800
+
+    Add a new Linear Allocator for run-time
+
+commit 89af031c2a52fda3ec7ede2e8343576334c2fee5
+Author: luba <lubatang@gmail.com>
+Date:   Thu Aug 11 10:03:50 2011 +0800
+
+    allow MCLDInputTree insert a mcld::Input from outside.
+
+    In original design, MCLDInputTree should handle the construction of
+    mcld::Input. Now, we loose this constraint and let MCLDInputTree can
+    insert a mcld::Input from the outside world.
+
+commit 82e499de419fb359b23cd99a1aebd21b728ef318
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Aug 10 22:49:45 2011 +0800
+
+    Add some implementation of RelocData and MCLinker.
+
+    Sorry I cannot write a unittest, since MCLDInfo and TargetLDBackend
+    is not done yet, and MCLinker needs both of these.
+
+    This is a placeholder commit that tell others I have started doing
+    the relocation part. The function is not done yet.
+
+    BTW, the LLVM patch has a bug.
+    We use `delete' in MCAssembler.h, so we should use `include' instead
+    of forward declaration.
+
+    Be care of compilation warning!!
+
+commit 4c52ab1a94d11c1a427893a35c79f473e4c198c8
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 10 18:02:18 2011 +0800
+
+    attribute is attached on MCLDFile.
+
+    SectLinker can create attribute by the command line.
+    InputTree::Input can attach attributes
+    default attributes is set up by ARMELFSectLinker
+
+commit d44c009bdafa554d34cc6b4d8c521334f1589e72
+Author: luba <lubatang@gmail.com>
+Date:   Wed Aug 10 11:20:01 2011 +0800
+
+    add a new class MCLDInput to replace original MCLDFile.
+
+    Since the information of input and of output are different, we separate
+    the API of MCLDFile into MCLDInput and MCLDOutput.
+
+    This also help MCLDInput to have a clear Type information.
+
+commit cf36b90a49f9b9ce0869b7886f6d80c2339ccf81
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 20:55:21 2011 +0800
+
+    attach attributes on MCLDFile
+
+commit dd6f24dc258ebab40990ca47c826f8d16732b65a
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 20:37:43 2011 +0800
+
+    create MCLDAttribute and AttributeFactory
+
+commit 28ede4c5b059684bd1781c7e0012470118c42d6e
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 19:10:36 2011 +0800
+
+    Luba is so stupid
+
+commit 302c02d95568158ea42b990e6e187cf6a3e68b2f
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 19:07:54 2011 +0800
+
+    Sorry, Luba is stupid.
+
+commit fe6427aa910cbe43ee40e7709e676ff1c2678d3e
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 19:00:41 2011 +0800
+
+    Sorry, Luba forgot to add GNULDBackend
+
+commit 578716cb391c50b1c30c8f2ece5d1fc63906545a
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 15:57:35 2011 +0800
+
+    add partial specific less<mcld::sys::fs::MCLDFile>
+
+    add this template functor to help map insert MCLDFile.
+
+commit 0fda962322d03f59b6c9541c702fc391b5724706
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 9 15:02:48 2011 +0800
+
+    create a new garbage collection factory - GCFactory
+
+commit 919ba478b7ac30c837d30868a11b4efbe0989669
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Tue Aug 9 14:46:19 2011 +0800
+
+    finish is_directory and exists
+
+commit 7ec21a0559f49e6bee6556e77a4475e761a7c431
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 8 20:37:20 2011 +0800
+
+    Cancel the target-dependent archive reader.
+
+    Since the difference of the formats of archive files are only on
+    the OS type, not on target, we remove all target-dependent archive readers.
+
+commit 8d7f351964693b4e4ab5cd56d0d604b438eb7ddf
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Aug 8 20:06:55 2011 +0800
+
+    Add a test case for class InputTree at file MCLDInputTree.
+
+commit 7ff101919738cac6ac7b865b8205a9a8156d4c6a
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Mon Aug 8 17:59:09 2011 +0800
+
+    Fix scaffolding of class MCLinker.
+
+    There are still some functions not implemented yet.
+    But this won't bother the regression test.
+
+commit 8791439a87a605a510e818e88e07c3110d63539c
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Aug 4 19:21:45 2011 +0800
+
+    Add DFSIterator and BFSIterator of InputTree.
+
+    Fix a bug : BinaryTree::join() runs the opposite direction when join a new node.
+
+commit 07efe81e55fed84e85aa7d625579d2d1ba8b71ff
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 21:44:41 2011 +0800
+
+    Fix a bug :
+    	Leftward => Downward => Inclusive
+    	Rightward => Afterward => Positional
+
+           ROOT (right == self == end)
+          /
+        begin
+       /    \
+      A      B
+
+commit 139b56db6f0a1e66a02406607ab4e74a73cd2cff
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 20:40:15 2011 +0800
+
+    Fix the bug - self assignment of BinaryTree and TreeImpl
+
+commit 29cfb44b90dd8a1a0bfbda1e2ab12b7fff47d2fb
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 20:28:50 2011 +0800
+
+    add testcase LinearAllocator and FactoriesTest.
+
+commit 27096837de3748c003e968c1e1d5582b37dab15c
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 20:27:04 2011 +0800
+
+    fix a bug coming from LLVM. LLVM StringRef::size does not contain '\0' character.
+    Therefore, if we use strcpy, we always copy lack of the last charactor.
+
+commit ec71a6ec68b282b3dc442f7ddc0ca60cc5542f6b
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 19:42:06 2011 +0800
+
+    Fix a bug - NodeFactory object can not delegate itself.
+    If the object detect this situation, do nothing.
+
+commit fb0c7a4c0e7aa078647d57a5e67e0b3d2ac9d558
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 18:59:21 2011 +0800
+
+    Fix a bug in LinearAllocator.
+    If there are no chunks being initialized, end() will segmentation fault by access m_pCurrent->bound.
+
+commit 4c207da72add8936f5ba396473560e00170a8a7c
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 17:59:49 2011 +0800
+
+    Fix bugs in BinaryTree
+    1. TreeImpl::summon calls the wrong function
+    2. Move NodeFactory::iterator function to public
+
+commit 7577359a7b01b50f673a43522502a5b1f2f49fdd
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 17:34:06 2011 +0800
+
+    Fix a bug - compiler can not specify template function TreeBase::move()
+
+    - incorrect template argument type - template<size_t DIR> move()
+
+commit 1d3de703a7df46b3d49526e20fe81935f8cd8eec
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 17:22:48 2011 +0800
+
+    remove redundant message in TreeAllocator
+
+commit 1133f8acdae1cad09c3a0756b94c49ffa9aa68ca
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 17:19:31 2011 +0800
+
+    Fix a bug in the LinearAllocator
+
+    Bug - Iterator never goes to the end()
+
+commit ab35d771eda74e000ddb88bfe5736dc64fb3d88d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 13:53:42 2011 +0800
+
+    Fix bugs in LinearAllocatr
+
+    1. the conditions of equivalent comparison is insufficient. We should
+       also compare the positon of iterators
+
+commit c25906995a913dba516a560f9a5b5d9852a7cec3
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 10:56:54 2011 +0800
+
+    add directory, and fix some basic syntax bugs in MCLDDirectory.
+
+commit a247cb32d8c4ffe3489d8acda41c9b0eaf602ac8
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 10:45:11 2011 +0800
+
+    Add host-specific Path libraries
+
+commit 8d7d3c5f720db801e3bac0c02b821b0b23da56bb
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 10:45:11 2011 +0800
+
+    Add host-specific Path libraries
+
+commit 105397d60a3313e59f71951462133bfd0ea378f6
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 10:39:34 2011 +0800
+
+    add new class - Directory
+
+commit 2b694ac4ee4f8dbe89869fae53f4a0bdbd10e424
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Aug 2 10:20:24 2011 +0800
+
+    initialize MCAsmInfo for LLVM 3.0svn's demand
+
+commit 27fd0e6462f1382880ba0dcd7e143f962a52d914
+Author: luba <lubatang@gmail.com>
+Date:   Tue Aug 2 10:18:10 2011 +0800
+
+    fix a bug - m_pRoot is forgetten to be initialized.
+
+commit 02f62cf3e15dcd21ab3ba544d5cd6ac70978fdc7
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 20:57:37 2011 +0800
+
+    Check host. If host is unix, set LLVM_ON_UNIX=1. On the other heand, if host is win-32, set LLVM_ON_WIN32=1.
+
+commit 2bf6cc71e2b7cd1617f89a0330cc2d96c5404db1
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 18:58:03 2011 +0800
+
+    move create function of MCLDInfo out of SectLiner, and let it work like MCAsmInfo.
+
+commit 577ae17fa105f9e01d93df344d30d0936c4f2a02
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 13:32:32 2011 +0800
+
+    add `-t' argument on the command line.
+
+commit af25232ed7848ff7e4ad7029311dc693eccf0fa7
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 12:30:10 2011 +0800
+
+    move out traits from TreeBase.h
+    extract common code of LinearAllocator::iterator and const_iterator to DataIteratorBase
+
+commit bfe60efa3a076ced231e61eff65b80728966f90f
+Author: luba <lubatang@gmail.com>
+Date:   Mon Aug 1 10:40:07 2011 +0800
+
+    add iterator for each data in the Allocator.
+
+commit 6ccff786637f1f0367c765bf9e9019c337a7b761
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 29 12:01:54 2011 +0800
+
+    make binary tree and allocators are uncopyable.
+
+commit 2554fcf2b1791d4664718f273892686c4c8b7f7a
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 29 11:50:46 2011 +0800
+
+    remove the DataType construction in Binary Tree.
+
+    Data construction should be handled by the user of binary tree, not
+    tree itself.
+
+commit 557270c556ddbdf3719ff32c552378ec85ef5bf6
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 29 02:05:11 2011 +0800
+
+    A syntax-correct BinaryTree
+
+commit d9b60663c5dccde749adddb058086d51202b5a15
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 29 01:15:19 2011 +0800
+
+     - Finish LinearAllocator
+     - Finish STL Compatible Binary Tree
+     - Remove useless MCLDBackend file
+
+commit 43835d5a177724b3c16173fad79164824f25225b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 28 14:31:08 2011 +0800
+
+    finish the implementation of linear allocator.
+
+    linear allocator is a two-phase memory allocator.
+
+commit 0a8f0553b1edcf8bd11d20a2a29318d11fa3efaa
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 28 10:59:04 2011 +0800
+
+    Add a new directory - ADT to store abstract data types.
+
+commit 715d7ed9b72c168a7841ba31994022c6ed708677
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 27 22:18:25 2011 +0800
+
+    finish the scaffolding of binary tree
+
+commit 40df3d49c5facf0bf8f1002ba3c597244cc33f28
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 27 20:36:45 2011 +0800
+
+    finish the scaffolding of InputTree, which be used in SectLinker.
+
+commit bfdb6d770ca14e070131a9ead11088086d28f341
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 27 15:14:24 2011 +0800
+
+    change MCLDInfo's member from pointers to reference.
+
+commit 7d0f04541d188135cca533a043a4a0bb37d51a01
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Jul 28 13:17:20 2011 +0800
+
+    a test for BinTr[Cee
+
+commit cb971398cf663efc4e07f96f1e1aee70ad561ecf
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Wed Aug 3 22:20:50 2011 +0800
+
+    Adding a new tool "MCELFObjectReader"
+    Seeing tools/MCObjectReader/README for the details
+
+commit cc3be0820ab0296171757db207612373de627a91
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Wed Aug 3 22:18:36 2011 +0800
+
+    Adding parts of implementation of MCELFObjectReader
+    It includes readObject() & dump()
+
+    MCELFObjectReader reads entries in Symbol Table
+    It stores entries with MC data structures
+    such as MCSectionData & MCSymbolData
+
+commit 6ef3ae35c0c7939ec7be65ded4392bfbd1105556
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Wed Aug 3 22:17:17 2011 +0800
+
+    Updating LLVM.diff.patch for MCObjectReader
+    LLVM.diff is obsolete here, it should be updated by someone
+
+commit b0aa341084d4dbf0520169c3697dbe6c9ae16921
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 27 14:23:13 2011 +0800
+
+    add Tree of inputs in the MCLDInfo
+
+commit ca878a61afbf3564d616d5419649cda5a740231f
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 27 10:06:45 2011 +0800
+
+    change the name of method merge to join
+
+commit 9340a5219aeda55e2dee4ca3d060f6b264e8e58b
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 26 21:48:07 2011 +0800
+
+    new an abstract BinaryTree
+
+commit 3c34067b2c229797d9f8ec8ac8d529e427ae532d
+Merge: 9e54bab c1466b6
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 25 16:57:18 2011 +0800
+
+    Merge branch 'master' of upstream
+
+    Conflicts:
+    	include/mcld/MC/MCLDInputFileList.h
+    	lib/MC/MCLDInputTree.cpp
+
+commit 9e54bab294d03e22510e0b6c8ffc20f6b5fbcb5f
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 25 16:46:09 2011 +0800
+
+    add a new sub-class - SectLinker::PositionDependentOptions to handle the position of options on the command line.
+    SectLinker can traverse the list of PositionDependentOptions and push each option into the tree of input files.
+
+commit 3b33658b41bf31157199aa55ab679e68686a966b
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 22 00:04:20 2011 +0800
+
+    describes the classes of Command line options.
+
+commit c1466b6987aae2ee090b9c4b01de6d2719290320
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Fri Jul 22 14:37:16 2011 +0800
+
+    Creating patches for "patch" command & "git apply"
+    All patches are for LLVM r135569
+
+    For building MCLinker project,
+    Choosing one of them is enough.
+
+    Applying patches from $(LLVM_ROOT)
+
+commit a64e424c39585edc7baf4641b56001a4348814c8
+Author: Nowar Gu <nowar100@gmail.com>
+Date:   Wed Jul 20 14:01:55 2011 +0800
+
+    Update patches.
+
+commit add2cb3dc1c70ae32f5fd9055f3bd6bcc149bcd8
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 20 13:57:40 2011 +0800
+
+    fix error : lack of destructor of MCLDInputFile::Node
+
+commit d7386c24bf457606647b8aa2546d329f047fb65d
+Merge: 70c2f5f 9d9c56b
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 20 09:17:24 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 70c2f5f549d6a8a3d3aae0dde20028d53a87a3c3
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 20 09:15:22 2011 +0800
+
+    change the algorithm of MCLDInputFileList creation.
+
+commit 9d9c56be8967adabde6fc2b0bd2a865aadb19d0a
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 21:48:21 2011 +0800
+
+    write the basic idea about how to get position of input options from command list.
+
+commit 0acf73aecc22ee6b670443f205367ea04b5b71c2
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 21:08:08 2011 +0800
+
+    add four testcases for exists and is_directory
+
+commit 7d499957063a2fb5ec5aa21ae3823a6afa7de533
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 21:07:43 2011 +0800
+
+    let -dB not be necessary
+
+commit 7fd5edc2908ea0e0a7f247e0040ea405b4488f6d
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 20:54:14 2011 +0800
+
+    complete parser<mcld::MCLDDirectory>
+
+commit a99fcd8701a961735f73c5e4282705e3482d8046
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 19:44:24 2011 +0800
+
+    Add destructor of Path
+
+commit bc93dd7c35e4bd37e8aeb9202a09e2005a7440d4
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 19:43:46 2011 +0800
+
+    add a new testcase for mcld::sys::fs::Path
+
+commit d49d5d75f05beae037af960b146f4310de3df9b0
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 19 19:14:21 2011 +0800
+
+    1. add Path library for MC Linker
+    2. let CommandLine library can parse Path, Directory and MCLDDirectory
+    3. refine SectLinker
+
+commit b37451de4e030adb22a06d6e462ec94fd9602aca
+Author: Duo <duo@duo-laptop.(none)>
+Date:   Tue Jul 19 16:15:06 2011 +0800
+
+    delete unnecessary file.
+
+commit c76959008f9ca054fe42ade590b42d452812f702
+Author: Duo <duo@duo-laptop.(none)>
+Date:   Tue Jul 19 16:02:43 2011 +0800
+
+    refine the code of MCLDInputFileList
+
+commit c5724a63c306b1261201cd0f7d12885f8ad134a8
+Author: Duo <duo@duo-laptop.(none)>
+Date:   Tue Jul 19 14:15:15 2011 +0800
+
+    Change the data structure of MCLDInputFileList from graph to binary tree.
+
+commit d46e90b0d55de5cd04801f691b69053a94e702d6
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jul 19 13:42:29 2011 +0800
+
+    patch for LLVM. ${llvm_src}$patch -p0 < ${mclinker}/patch/LLVM.diff
+
+commit 2e7bb382da1c4c0f5a2ee69814655f786e8f6802
+Author: Duo <pinronglu@gmail.com>
+Date:   Mon Jul 18 22:18:41 2011 +0800
+
+    Change the interface of MCLDInputFileList::iterator.
+    Remove member function insert and delelte ,and add to MCLDInputFileList.
+
+commit 2af10e40c60f811dcfdf92fcb74230b50149c5dc
+Author: Duo <pinronglu@gmail.com>
+Date:   Sat Jul 16 20:13:15 2011 +0800
+
+    build scaffolding of class MCLDInputFileList
+
+commit 2b562e2c563066246ad140c83635ac38551260e0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Fri Jul 15 10:27:47 2011 +0800
+
+    Removing readers from Target directories
+    Using MCTargetObjectReader as target-dependent reader
+
+commit 127ac107c998d8fc39d61fc7ad681999d2dd2425
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 17:44:25 2011 +0800
+
+    remove attribute from MCLDFile
+
+commit 9acc1afca6cc15e60e65430b5e3eb2b30b58f011
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 17:28:16 2011 +0800
+
+    add sysroot functions in MCLDInfo
+
+commit 27e7620fdfd50dd95adfd5992d00fe8fe89181b2
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 16:48:25 2011 +0800
+
+    refine the indent of MCLDFile to fit LLVM style.
+
+commit d032e2fff236158f58dcbd5f5432aed656b25c79
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 16:20:33 2011 +0800
+
+    add SearchDirs class.
+
+commit c10c150e630f18c3baf84d349895926cf4cd410f
+Merge: 4f21432 4975671
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 16:13:20 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 4f21432c245e0a7fba6b484db5395308ac002482
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 16:09:46 2011 +0800
+
+    1. add Support directory to deployment
+    2. add a new flag `-dB' to indicate default bitcode.
+
+commit 49756716c3587b7867c03fa3180f6d0f9d7ab2d1
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 14 16:09:46 2011 +0800
+
+    1. add Support directory to deployment
+    2. add a new flag `-dB' to indicate default bitcode.
+
+commit 88c40df44a703822110da88f03a1291add5f92a9
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 13 18:41:10 2011 +0800
+
+    add a new class MCLDFileTree using to decide the linking order.
+    Delete unnecessary component of MCLDFile.
+
+commit 82c826db4de17b7ead4d116baeed0489320fd1e5
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 18:09:03 2011 +0800
+
+    add a "should be failed" case into search_patch case
+
+commit 7d5ecb8a2e9947e74cd82eb7758da540f4b5663f
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 15:52:43 2011 +0800
+
+    fixes a bug of undefined StringRef. We forget to expose llvm namespace scope to him.
+
+commit 76c6111032f0a1efc644002c7e40d0ce0eff4308
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 15:19:46 2011 +0800
+
+    add the basic interface of MCLDDriver for input files being listed in command line
+
+commit 21ab372cf2373743e6653ccff05daeb12035531e
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 15:06:12 2011 +0800
+
+    add a new regression test for search path of MCLinker
+
+commit e9052e14e5dfba835a6c0643be6a7b48bfad5185
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 15:05:32 2011 +0800
+
+    make the output format of regression test pretty.
+
+commit 6eacfa06a1301bd54f7f290726d11c047a53a520
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jul 13 12:34:39 2011 +0800
+
+    connect SectLinkers and MCAsmObjectReader by default bitcode.
+
+commit 70b24badc0d4ecf72b4a8ca61256bdabff98cd50
+Merge: 08a7dc6 1f35ba1
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 13 12:01:49 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 08a7dc684e98d91aeffda8468dfd116e7c291dd8
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 13 11:50:32 2011 +0800
+
+    build scaffolding from SectLinker to MCLDDriver.
+    Associative ARM target SectLinker is also built.
+
+commit 1f35ba1650b309d8a07f599b978d329814bf6ef5
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 13 11:50:32 2011 +0800
+
+    build scaffolding from SectLinker to MCLDDriver.
+    Associative ARM target SectLinker is also built.
+
+commit 0fb90820592c45c91458fd5d8285b7dd1314b41e
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Tue Jul 12 17:40:41 2011 +0800
+
+    add empty class of MCLDInfo.
+
+commit 7f85da66537af515455074306f98a778656896f3
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jul 12 14:20:04 2011 +0800
+
+    Remove files that can not be compiled well
+    MCFragment
+
+commit 15fcc51a77f33d12ac6a464041fbf15b016b4ae4
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 12 14:07:17 2011 +0800
+
+    add patch to llvm::MCAssembler
+
+commit b89166ef732ac3e08e831f81b00459b68b234310
+Author: Duo <pinronglu@gmail.com>
+Date:   Tue Jul 12 13:55:45 2011 +0800
+
+    Merge Makefile.am
+
+commit dfe026a989117000fde23bc768d2bf397cff62f3
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 12 12:13:19 2011 +0800
+
+    remove AsmPrinter from SectLinker.
+
+    Every MachineFunctionPass must be added into PassManager before calling MachineFunctionPass::runOnMachineFunction().
+    However, in our original design, AsmPrinter is called by SectLinker. AsmPrinter is not added into PassManager and can not be initialized correctly.
+    Therefore, we move AsmPrinter out from SectLinker, and add AsmPrinter back to PassManager.
+    SectLinker gets the result of AsmPrinter by the references of common data - MCLDContext.
+
+commit 246dc88093431e928c882e516f0b16f365d00359
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 12 11:29:20 2011 +0800
+
+    redirect assembler to MCAsmObjectReader
+
+commit 34a7c5f905f1f289664699ff5aba649fc205b6d3
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 12 11:28:46 2011 +0800
+
+    remove invalid testcases
+
+commit 423d4a4291568f0e0e8b2008b2e494eea564747b
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 12 09:52:56 2011 +0800
+
+    add the scaffolding of class MCAsmObjectReader.
+
+commit 8416f02ae41a056052a0daa2edfcb29b9d2e017c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 11 17:36:19 2011 +0800
+
+    Follows the most new LLVM svn3.0. refine the patch
+
+commit 8de15e5bb9e6f993443c47ded878a829fbc8de36
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 11 14:23:25 2011 +0800
+
+    add a new regression test - file.
+
+    `file' make sure the output can be examined by `file' command.
+
+commit 7cabe6765817c51cb4ef44b9f597b772ccb5be51
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 11 14:09:19 2011 +0800
+
+    clean all temporary files while tearing down.
+
+commit 7c8fb9792c6212b1324be83b24df33149637b457
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 11 13:45:10 2011 +0800
+
+    add -typefile=asm, obj to MCLinker.
+
+    Now, MCLinker has full ability of llc.
+
+commit 7e292189aa7df0f3a129d769b5040b15084a252c
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 11 13:43:41 2011 +0800
+
+    add setup()/teardown() functions in regression test. Rename the majar test function as testcase().
+
+commit 1530b82d3118b56ee0833bfd9ae809d39bf9edfe
+Author: Duo <pinronglu@gmail.com>
+Date:   Sun Jul 10 22:31:06 2011 +0800
+
+    scaffolding of MCObjectFile : MCSectionData Proxy
+
+commit 29a64bcce7ab848c1aa0fa33904b22a147531233
+Merge: 1318d11 87bf885
+Author: Duo <pinronglu@gmail.com>
+Date:   Sun Jul 10 22:23:11 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 1318d111fa3c782fd1c9ef36e787f24bcc169a1e
+Author: Duo <pinronglu@gmail.com>
+Date:   Sun Jul 10 22:19:51 2011 +0800
+
+    scaffolding of MCObjectFile : MCSectionData Proxy
+
+commit 87bf88552b388c202aeeab97f1b0e19458a45444
+Author: Luba Tang <luba@LubaSite.site>
+Date:   Sun Jul 10 02:59:57 2011 +0800
+
+    remove some files that should not be pushed into git repositry
+
+commit d718be5216f28b5e3219a614779fb1981558f3a6
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jul 9 21:43:21 2011 +0800
+
+    create SectLinker in LLVMTargetMachine
+
+commit d79eeec475ee7c58b33b06de2e9ae0408ee68a17
+Merge: 578c1a2 fdd7db8
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jul 9 20:59:15 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 578c1a299aefbbc1b0b0e670e8ee95ecfce1e373
+Author: luba <lubatang@gmail.com>
+Date:   Sat Jul 9 20:47:21 2011 +0800
+
+    register target-dependent SectLinker into mcld::TargetRegistry
+
+commit fdd7db8b56b8011b8fdcbef589f30169fe30cfc8
+Author: Duo <pinronglu@gmail.com>
+Date:   Sat Jul 9 00:17:56 2011 +0800
+
+    Modify MCObjetfile.cpp and MCObjectFile.h
+
+commit b4bea44a7996f7c7c066a20855c56bb536f178bc
+Author: luba <lubatang@gmail.com>
+Date:   Fri Jul 8 20:13:26 2011 +0800
+
+    add regression test
+
+commit 5e0041bd6002e192cd4cc50dfe2e50b733735a22
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Jul 7 21:10:20 2011 +0800
+
+    Modify mclinker/debug/Makefile.am : add MCObjetFile.h MCObjectFile.cpp
+
+commit e14640dcb45f5803b5cd88be53b6af011c5f206e
+Merge: 272e6f4 f4674cb
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Jul 7 20:47:41 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 272e6f4773d661464eb2cbac2a0dee6741931d18
+Author: Duo <pinronglu@gmail.com>
+Date:   Thu Jul 7 20:39:42 2011 +0800
+
+    Scaffolding of MCObjectFile : Finish Iterator
+
+commit f4674cb222ae9f42b4979311133bc05bf602355b
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 7 18:22:36 2011 +0800
+
+    Finish scaffolding of all readers and writers.
+
+commit f04d1ce24a52f26ed32792bb4252c2de86ef8571
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jul 7 11:50:20 2011 +0800
+
+    add_class can add target-dependent files into source directory.
+
+commit 0abe2a2f36291f1240b139e73fdf03592e180675
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 6 23:50:47 2011 +0800
+
+    Test case for MCArchiveReader/MCObjectReader.
+
+commit 237df5f6c266e18198b76f880fd5b265e4c5e7a9
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 6 20:42:31 2011 +0800
+
+    Build the interface of ELF Archive/Object readers.
+
+commit 81182a67a348361bd882c66bf55ccfe0d3a2b112
+Author: Duo <pinronglu@gmail.com>
+Date:   Wed Jul 6 20:38:18 2011 +0800
+
+    build the abstract interface of ArchiveReader and ObjectReader
+    Let TargetLDBackend owns the function pointer of the constructor of readers
+
+commit c2679593c1cb7849df679fc920633f514c93802c
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 22:18:41 2011 +0800
+
+    make the scaffolding for createTargetLDBackend.
+
+    ARM's createTargetLDBackend has not implemented yet.
+    The result is assert in
+    MCLinker: ../lib/Target/ARM/ARMLDBackend.cpp:25: mcld::TargetLDBackend* mcld::createARMLDBackend(const llvm::Target&, const std::string&): Assertion `0 && "MC Linker for ELF system has not been supported yet"' failed.
+
+commit 8c80a4949dbed040cdc2df8258487860491d60e9
+Author: CIT
+Date:   Tue Jul 5 15:12:23 2011 +0800
+
+    LLVM version 3.0svn changes the API about llvm::TargetMachine.
+    downstream with the macro LLVM_VERSION
+
+commit d7d4560bf7eadb9e23bedb9248d84aa73911e21f
+Author: CIT
+Date:   Tue Jul 5 15:08:53 2011 +0800
+
+    pass LLVM_VERSION into source code.
+
+    add -DLLVM_VERSION=${LLVM_VERSION} in the compilation command line
+
+commit 5bb8e229139994709c200c1b9d753d58fbadbb95
+Merge: 16c4c90 128b419
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 14:57:21 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 16c4c901b88b6475483360312359f84cf23b9291
+Merge: de71d4e bccffcd
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 14:53:13 2011 +0800
+
+    Merge branch 'master' of upstream
+    add ARMTargetInfo
+
+commit 128b419b7688ddef6c2ae9bcee7201932112307c
+Merge: de71d4e bccffcd
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 14:53:13 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit de71d4e3110f16b739cc7581050baa0d3d1770d5
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 12:29:09 2011 +0800
+
+    Initialize mcld::TargetMachine
+
+    mcld::TargetMachine has right mcld::Target
+    mcld::TargetRegistry can find corresponding mcld::Target
+    mcld::Target::createTargetMachine can create mcld::TargetMachine
+
+commit bccffcdcc2c1dd854bbcca2a64051fb1e6dda3e4
+Author: luba <lubatang@gmail.com>
+Date:   Tue Jul 5 12:29:09 2011 +0800
+
+    Initialize mcld::TargetMachine
+
+    mcld::TargetMachine has right mcld::Target
+    mcld::TargetRegistry can find corresponding mcld::Target
+    mcld::Target::createTargetMachine can create mcld::TargetMachine
+
+commit 4d1d9b34b89b942918a410ca186b2f85fd3e1122
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 4 21:42:30 2011 +0800
+
+    Finish adapters of mcld::TargetMachine, mcld::Target, and mcld::TargetRegistry
+
+    Now, mcld::Target::createLDBackend works.
+
+commit fbb629cace23e37adba86623ab44380103f822be
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 4 17:53:10 2011 +0800
+
+    Add a new alias mk.
+
+    command `mk' can make MCLinker in any level of directory.
+
+commit f3b5cec6bc19a8d19a83767a9ccdfcfd0def7d00
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jul 4 12:26:43 2011 +0800
+
+    add Initialize##TargetName##Linkers() and corresponding InitializeARMSectLinker() functions.
+
+commit b514f27c60b1d5cc0b65a3a981511fe73b43a1db
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 30 21:05:56 2011 +0800
+
+    add m4 macro to specify targets when executing `./configure' script.
+
+     * Enumlate all targets in include/mcld/Config/Targets.def
+     * Enumlate all linkers in include/mcld/Config/Linkers.def
+
+commit 7e3056811244ca3429dc73ff038f3e906cccf5c2
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 30 14:26:21 2011 +0800
+
+    Add implementation of Target
+
+commit 41d758f2ee25665de835c54b44a9ae3cb2c9a8d0
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sun Jun 26 21:08:07 2011 +0800
+
+    Add a core function "getMCInstruction"
+    to MCELFObjectReader
+
+    Which is based on MC Disassembler
+
+commit 95c6fc7a8dd0ecffa27b507f183dbac2c25e2769
+Merge: 7cdd6dd 514c75a
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 17:35:22 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 7cdd6dd3dea91c22fbcf36617bdf6386b7d8650e
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 17:34:43 2011 +0800
+
+    finish a basic scaffolding of mcld::TargetMachine
+
+commit 41303498bcf209f8596dd49bce5fa6d3caddc920
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 17:13:27 2011 +0800
+
+    a new patch for LLVM. Move function LLVMTargetMachine::setCodeModelForStatic() to public field.
+
+commit 514c75a4c4db94348a9e684c1c0930ab0412c172
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jun 23 14:28:36 2011 +0800
+
+    Add MCLDCommand header and footer
+
+commit 48e02772557403c2323a588fc28eb28c0e6bc19c
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 13:29:41 2011 +0800
+
+    adds new UML object diagram of MCLinker
+
+commit 8c33cc12e4e98024487c90e5e8377932eeb3e7d9
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 12:05:44 2011 +0800
+
+    fix a typo error in header template.
+
+commit 6d6349e91c6c38b2f10383ef3ea040a52dcb43b1
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 12:01:08 2011 +0800
+
+    Add header and footer in MCLDDriver
+
+commit 20e91885a70cb4114393ae0267d15899b47914dd
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Thu Jun 23 11:44:17 2011 +0800
+
+    Add MCLDDriver header file
+
+commit f1f330d1d9da0bf6550f888442ddc85d513609a1
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 11:23:58 2011 +0800
+
+    Add mcld::LLVMTargetMachien to do object adapter of llvm::TargetMachine
+
+commit 37b5687318121493422c07adff2b448798ef21f6
+Author: luba <lubatang@gmail.com>
+Date:   Thu Jun 23 09:30:27 2011 +0800
+
+    change debug macro from -DDEBUG to -DMCLD_DEBUG.
+
+    Google test also has a macro -DDEBUG. In order to avoid from conflict, we rename our own macro.
+
+commit 828928ec7d8fa497003411b617e189bc10dd078b
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 17:53:41 2011 +0800
+
+    Update Makefile.am for LLVMTargetMachine
+
+commit bfc89176b49a6634fd29cf636bfd34972b1a45b3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 17:47:53 2011 +0800
+
+    Rename lib/CodeGen/TargetMachine.cpp
+    to lib/CodeGen/LLVMTargetMachine.cpp
+
+    Avoid confusion with lib/Target/TargetMachine.cpp
+
+commit fa383b819cfce9fe343e6087cd41e27e0e6ae8c0
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Jun 22 16:51:02 2011 +0800
+
+    LLVM 2.9 (stablest) and LLVM 3.1 (newest) have different API.
+    In order to run on these versions, I add new macro - LLVM_VERSION
+
+    In LLVM 2.9, LLVM_VERSION is 2, and in LLVM 3.1, LLVM_VERSION is 3.
+    Developers can separate code into different versions like that:
+     {{{
+     #!cpp
+     #if LLVM_VERSION > 2
+     	... code in LLVM 3.1 API...
+     #end
+     }}}
+
+commit edb0c63e826178304b75809440b517bf6022d560
+Merge: dc2bc00 1345fe4
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Jun 22 16:39:26 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 1345fe46fc9ff6daf7aaabb413a01e15b8204d29
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 15:40:16 2011 +0800
+
+    Add LDBackend creation and registry
+
+commit dc2bc00d94472ddb8af699c5d81381c876cba689
+Merge: 3527e74 3a57e65
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed Jun 22 15:07:05 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 3a57e65fe1d7728f317bd14bd4f05bb9fa6995a3
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 11:54:55 2011 +0800
+
+    Add createLDDriver
+
+commit 71c5abea9295a59b8f1045ba5ce31bf4355358f9
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 11:48:43 2011 +0800
+
+    Comment createStreamer
+    Add LDDriver
+
+commit 30401a99499413bdfbf0ea081678c54b44322cdd
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Wed Jun 22 11:44:48 2011 +0800
+
+    Adding MCLDDriver stub
+
+commit eb1bb9813e95c98dbcc449c019ecff824a353ca1
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jun 21 21:50:17 2011 +0800
+
+    Adding implementation of TargetLDBackend
+    Which is similar to TargetAsmBackend
+
+commit 3527e74f6760a8f41c1c08412197d5532791d063
+Merge: 937032d e3039fb
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Tue Jun 21 21:40:54 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit e3039fb8e51d11664895570362e2bc99724770ea
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jun 21 21:34:04 2011 +0800
+
+    Create TargetLDBackend.cpp
+    Move TargetLDBackend.h
+
+commit 82fc3f57dcc678ed026a5da516b3095e333b53b0
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jun 21 19:25:40 2011 +0800
+
+    Adding LDBackend header files
+
+commit ed5708821020fc1a5dcf627e9860174f2bce4dd6
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jun 21 19:20:23 2011 +0800
+
+    Adding implementation of addPassesToEmitFile
+
+commit 9638fe989a26ecf4418044174234cc376e666013
+Author: Jush Lu <Jush.Lu@mediatek.com>
+Date:   Tue Jun 21 16:59:05 2011 +0800
+
+    Removing merge legacy
+
+commit 937032de3e1724326c61f0d3102a531eebda0af3
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Tue Jun 21 00:26:49 2011 +0800
+
+    fix a typo error
+
+commit 2cdd7e52e24f3d60cdb4655f04e4840f8502ad7b
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 17:37:38 2011 +0800
+
+    Change the name of project - from bold to MCLinker
+
+commit 194ff3bb3abdaac1a8751046e986b91435bef5e2
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 17:30:50 2011 +0800
+
+    Move addPassToEmitFile from extern "C" to namespace mcld
+
+commit 31d2211b9c6fdcc9c6bec2e3357bc2da1f18585e
+Merge: 402686b 9668907
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 17:08:47 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 402686b6034c87add9d85d935880bcbfe02910e8
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 17:07:19 2011 +0800
+
+    Change the deployment
+
+     * from lib to lib/MC, lib/CodeGen, lib/Target
+     * from include to include/mcld/MC, include/mcld/CodeGen, include/mcld/Target
+
+commit 96689072ec13ef8d24a1bf2cb64698edabcaa2bd
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 16:40:39 2011 +0800
+
+    Copying ELFObjectWriter into ELFLDWriter
+    Replacing "ObjectWriet" by "LDWriter"
+
+commit 3a0c8ef7e635f7a01464e408071298c6a843cd85
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 16:24:34 2011 +0800
+
+    change the template files:
+
+     *. project name - MCLinker
+     *. namespace - mcld and mcldtest
+
+commit ba07f54285b901e7307cd5e943a6858f73fe4d4c
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 16:19:10 2011 +0800
+
+    Adding MCELFLDTargetWriter
+
+commit ce739351767ee26d46f840c165a9c3e1ac3983c3
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 16:18:55 2011 +0800
+
+    add virtual function addCommonPasses() to class TargetMachine.
+    Original, it's a private member function of LLVMTargetMachine.
+
+commit 4ebe8ec401b05c7532db36aa309d23c5b4612e34
+Merge: 2055a07 6dd7074
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 15:59:37 2011 +0800
+
+    Fix a stupid typo error
+    Conflicts:
+    	src/main.cpp
+
+commit 2055a07192fca451b24da12e092bba2c477da7ea
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 15:52:55 2011 +0800
+
+    FileType in GetOutputStream() should be compared with mcld::CGFT_XXXFile, not old TargetMachine::CGFT_XXXFile
+
+commit 6dd7074906b6965d56cd891db270aed480a6fa55
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 15:52:55 2011 +0800
+
+    FileType in GetOutputStream() should be compared with mcld::CGFT_XXXFile, not old TargetMachine::CGFT_XXXFile
+
+commit e12362af59a508ca61c7e8f88356483db954528a
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 14:35:16 2011 +0800
+
+    Add a README of `patch' directory.
+
+commit a079b86e5d316641416d43127774de21d5e028e0
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 14:28:43 2011 +0800
+
+    Add a patch of LLVM. In LLVM, the function addCommonCodeGenPasses() is hidden.
+    Let addCommonCodeGenPasses() be public.
+
+commit 6c27377a22e5b420809a7fb20b1451e2122ef50e
+Author: luba <lubatang@gmail.com>
+Date:   Mon Jun 20 14:02:14 2011 +0800
+
+    CodeGen has a sub-directory CodeGen. It dis-follows the rule of LLVM directory structure.
+
+    remove CodeGen/CodeGen, and move all files to the up CodeGen directory.
+
+commit aee528f7cd55ff97e44eb8a36fbb00543251e2d4
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:37:45 2011 +0800
+
+    Adding MCLD header files
+
+commit 4613cdedb8d987ad7a4301cd70379c755561d0ce
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:27:20 2011 +0800
+
+    Adding CodeGen stubs
+
+commit 81b188f30a851e5045e1d223ec4f8b7cf3f79ebf
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:24:16 2011 +0800
+
+    Add mcld headers
+
+commit 0d5669cc5654c15d99f7cde0099a57e21d79bc4b
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:09:07 2011 +0800
+
+    Update build scripts
+
+commit c1f4f9ebcd06f093beeef03e8e444ebd9f521a63
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:04:54 2011 +0800
+
+    Adding unittest for TargetMachine
+
+commit ae4faa7f5654ce0caa0d0b0f206c22445d816ef8
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:03:32 2011 +0800
+
+    Adding MCLDScriptReader stub
+
+commit 6ca29571adb961e8b15174eac02163df890720c6
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Mon Jun 20 00:02:17 2011 +0800
+
+    Adding MCLinker stub
+
+commit 17f4f2df233f266334f0fb8d2ba024053eed5c52
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sun Jun 19 19:11:25 2011 +0800
+
+    Rename MCLDWriter to ELFLDWriter
+
+commit 22e8328de9407e585731c34dd46930f547abb279
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sun Jun 19 14:53:54 2011 +0800
+
+    Adding stubs for ARMLDBackend.
+
+commit 26dca80bfeed3852582dd053fd1b634f62365e6b
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sun Jun 19 13:21:41 2011 +0800
+
+    Adding README
+
+commit a83e4f52cd5267013b5ae32e3e357f428a7ed0b8
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Sat Jun 18 00:51:10 2011 +0800
+
+    Adding Java side implementation of NDK-MCLinker
+    NDK-MCLinker invokes MCLinker via NDK
+
+commit 8848eebd46440d2b4fdc76f24707b840914171a8
+Author: Jush Lu <jush.msn@gmail.com>
+Date:   Fri Jun 17 23:46:53 2011 +0800
+
+    Creating directories and files for MCLinker architecture
+
+commit 97bf250afe8e3d1cecc67782786c2497bd942e03
+Author: luba <lubatang@gmail.com>
+Date:   Wed Jun 1 10:22:47 2011 +0800
+
+    fix a bug
+
+    if either llvm-config --version is A.Bsvn, or minor version is less than required minor version,
+    configure return error.
+
+commit b64d8cbda3946b9b9000e38c05ce27b63761e6d1
+Author: luba <lubatang@gmail.com>
+Date:   Thu May 26 15:58:56 2011 +0800
+
+    `./configure' script for checking LLVM is done.
+    see [ticket:36]
+
+commit 8798e5d890a6abb6a2c3ee594269a8eebe586b4d
+Author: luba <lubatang@gmail.com>
+Date:   Wed May 25 20:25:05 2011 +0800
+
+    Move TEST_F from the header to the implementation.
+    This is more fit using scenario.
+
+commit 4152b15f8bf84e960d9f0c27510b6a9075e60239
+Merge: 3a6af50 b4fd4b4
+Author: luba <lubatang@gmail.com>
+Date:   Wed May 25 17:49:36 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 3a6af5027bc1a8ba114613383242041d1140111a
+Author: luba <lubatang@gmail.com>
+Date:   Wed May 25 17:46:43 2011 +0800
+
+    Add empty but necessary directories.
+
+commit b4fd4b471548b438f8a2e1e211a3de9d6f15dd84
+Author: luba <lubatang@gmail.com>
+Date:   Wed May 25 17:46:43 2011 +0800
+
+    Add empty but necessary directories.
+
+commit 8ffdbc6323d3da1bac857b5eb8339254cf9eb432
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:38:35 2011 +0800
+
+    put created headers in the ${BOLDTOP}/include/
+
+commit ee26ff715b457e3e81bbfacdfaa128ba18f2e5a7
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:37:56 2011 +0800
+
+    main function doesn't invoke gtest correctly. fixes these bugs.
+
+commit 31d5729e35caec19a891bb6dee0cc9863462a409
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:24:28 2011 +0800
+
+    The same bug like [ticket:46] in the `add_class' program.
+
+commit 1c5bc38d4e355334ba35e3b8c9da50bb12163340
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:20:48 2011 +0800
+
+    Fix a bug in envsetup.sh
+    see [ticket:46]
+
+commit 666d5974763bc6505166af60d9ee40a3bfc78fba
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:19:22 2011 +0800
+
+    include unit-test header
+
+commit 7f4383c62d978776f693cdbc37b1140676c5d95c
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:08:29 2011 +0800
+
+    add friend class for the unit-test
+
+commit 35e67c3dc80fa8419ee444e625cf7e19b2032897
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 17:06:52 2011 +0800
+
+    Modify the template of testcases.
+    see [ticket:44]
+
+commit 55097d1ed67274906fa67f146d2d71ff8566d244
+Author: Luba Tang <lubatang@gmail.com>
+Date:   Wed May 25 15:34:33 2011 +0800
+
+    Change some configurations of the testing framework.
+     * put compiled object files into obj/
+     * use libtool to create `libgtest.la' library
+     * modify configure.ac to add above functionalities.
+     * change the #include path `gtest.h'
+
+commit 1fa3e17175b520915cf59ac3f02f8b64b110db06
+Author: luba <lubatang@gmail.com>
+Date:   Wed May 25 14:31:30 2011 +0800
+
+    create the basic infrastructure of unit-test.
+    using google C++ test
+    see [ticket:37]
+
+commit b059d14f37660ae196148a03a89ed8166e67197d
+Author: luba <lubatang@gmail.com>
+Date:   Tue May 24 18:39:49 2011 +0800
+
+    Implementation of the add_class tool is completed.
+    See [ticket:39]
+
+commit bc6f1008bb26ea90e18c531613563911120e903c
+Merge: 68cd61e 4b4b6e0
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 23 20:31:26 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 68cd61ef8bc135b04295196786679e6e7bab56ff
+Merge: 2b52163 40b3a4c
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 23 17:55:19 2011 +0800
+
+    create the building system - using auto-tools, and basic directories.
+
+commit 4b4b6e0b340e87996a6573edee48f02cd26cbe5d
+Merge: 2b52163 40b3a4c
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 23 17:55:19 2011 +0800
+
+    Merge branch 'master' of upstream
+
+commit 2b52163847724611b3f788eac22193e6b18abb03
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 23 17:44:59 2011 +0800
+
+    creates the building system - using auto-tools, and basic directories
+
+commit 40b3a4c09e1437356c9cb56ddb6c17c02fa9c117
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 23 17:44:59 2011 +0800
+
+    creates the building system - using auto-tools, and basic directories
+
+commit 32562fc969851b1cda32729dc475265e59e6c3ec
+Author: TDYa127 <a127a127@gmail.com>
+Date:   Mon May 23 14:19:31 2011 +0800
+
+    Test proxy.
+
+commit b85e50a9971913a9ff6ba9786cea38198f8d540f
+Author: luba <lubatang@gmail.com>
+Date:   Tue May 17 10:31:26 2011 +0800
+
+     On branch master
+     Changes to be committed:
+    	new file:   bold/Makefile.am
+    	new file:   bold/README
+    	new file:   bold/configure.ac
+    	new file:   bold/debug/Makefile.am
+    	new file:   bold/optimized/Makefile.am
+
+     Build the basic directory structure of BOLD project.
+     I choose auto-tools as our build system for following reasons:
+      1. auto-tools are standard build system for cross platform compilation
+      2. CMake is another building system for cross platform. although it's
+         also used in LLVM, it support less libraries than auto-tools.
+
+commit 13a0eafbe004a0364e16cc2980d8cac0b83710bb
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 16 17:59:08 2011 +0800
+
+    Test for big file
+
+commit dbca9ba423827d80d8449582838f2e2d7bd62766
+Author: luba <lubatang@gmail.com>
+Date:   Mon May 16 17:49:25 2011 +0800
+
+    try to commit files
+
+commit 93b33cc586bc288ff62fcd0b252ee26b1fe0ed8b
+Author: duo <duo@duo-desktop.(none)>
+Date:   Wed May 11 22:54:36 2011 +0800
+
+    add a new file hello
+
+commit ab80f8a8c0816105777a2156fcaec0dcce928bb2
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Wed May 11 19:18:13 2011 +0800
+
+    push to new brach csmon
+
+commit fd5b000f8eaf2bdd306de7ce8489f251c172ccf5
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Wed May 11 19:15:37 2011 +0800
+
+    add a folder source
+
+commit 73b347ed1941bef06dd946365d72a9cbbb21ba43
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Wed May 11 17:22:42 2011 +0800
+
+    First revision
+
+commit 4af68d56600382997a90cf7541d95b734d71bb37
+Author: csmon7507 <csmon7507@gmail.com>
+Date:   Tue May 10 12:12:29 2011 +0800
+
+    First revision
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..5894b8d
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,237 @@
+                    The MCLinker project
+
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+
+==================
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+=====================
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+====================================
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+==================
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+=================
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+==========================
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+================
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+==================
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+======================
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..17ba080
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,66 @@
+==============================================================================
+MCLinker Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2011-2012 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+    Authors in ChangeLog.txt.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Google Test         utils/gtest/
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..ceb628d
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,5 @@
+ACLOCAL_AMFLAGS=-I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = utils debug test
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..de3437d
--- /dev/null
+++ b/README
@@ -0,0 +1,64 @@
+------------------------------------------------------------------------------
+                            MCLinker Project
+------------------------------------------------------------------------------
+============
+Introduction
+============
+  MCLinker is a linkage editor.
+
+========================
+Compilation Instructions
+========================
+  The simplest way to compile this package is:
+
+----------------------
+Prepare LLVM and Clang
+----------------------
+  0.a Download LLVM 3.1@r152063
+      `svn co -r 152063 http://llvm.org/svn/llvm-project/llvm/trunk llvm-src'
+
+  0.b Type `cd llvm-src' to enter the directory containing LLVM source code
+
+  0.c Apply patches from MCLinker
+      `patch -p0 < ${MCLinker}/patch/LLVM.patch'
+
+  0.d Download Clang @r146744
+      `cd tools'
+      `svn co -r 146744 http://llvm.org/svn/llvm-project/cfe/trunk clang'
+
+  0.e Build and install LLVM
+      `cd ../../'
+      `mkdir llvm-build && cd ./llvm-build'
+      `../llvm/configure --prefix=${LLVM_INSTALL}'
+      `make all install'
+
+--------------
+Build MCLinker
+--------------
+
+  1.  Type `cd ${MCLinker}' to the directory containing the source code.
+
+  2.  source ./scripts/envsetup.sh
+
+  3.  If there are no `configure' shell script in the directory, type
+      `./autogen.sh' to generate `configure' script.
+
+  4.  Type `./configure` to configure the package for your system. See INSTALL
+      for more details.
+
+  5.  Type `make` to compile the package
+
+  6.  Type `make install` to install the package into your system.
+
+===================
+Directory Structure
+===================
+README               - this document
+Makefile.am          - input of automake
+configure.ac         - input of autoconf
+src/                 - source code of verification tool
+include/             - include file, exported interface
+lib/                 - source code of exported interface
+debug/               - placeholder of object files which are compiled for debugging
+optimized/           - placeholder of object files which are compiled for optimization
+test/                - placeholder of testcases
diff --git a/VERSION.in b/VERSION.in
new file mode 100644
index 0000000..3e2a7af
--- /dev/null
+++ b/VERSION.in
@@ -0,0 +1,21 @@
+@MCLD_VERSION@
+==================
+Versioning Format:
+  [MAJOR].[MINOR].[MICRO].[AGE]-[PKG BUILD]
+
+[MAJOR]
+  It is changed for marketing purposes.
+
+[MINOR]
+  ALPHA - 0 for alpha
+  BETA  - 1 for beta
+  RC    - 2 for release candidate
+  FR    - 3 for final release
+  MA    - 4 for market acceptance
+  GM    - 5 for golden model
+
+Making a release:
+  If any inputs/outputs have been changed, set AGE to 0.
+  If all inputs/outputs/ are not changed, but make a significant change, increase MICRO.
+  If backward compatiblity has been broken, then set both MICRO and AGE to 0, and increase MINOR.
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..8ce8cf4
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+LIBTOOLIZE=libtoolize
+my_uname=`uname`
+
+if [ ${my_uname} = "Darwin" ]; then
+  LIBTOOLIZE=glibtoolize
+fi
+root=`dirname $0`
+cd $root
+
+aclocal -I ./m4
+${LIBTOOLIZE} --force
+automake --add-missing
+autoconf
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..2fc25ea
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,97 @@
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+##############################################################################
+### WARNING: this file contains embedded tabs.  Do not run untabify on this file.
+
+####################
+#  m4 includes
+m4_include(m4/acx_pthread.m4)
+####################
+#  Autoconf/Automake Initialization
+
+dnl AC_INIT(PKG_NAME, CONFIG_VERSION, BUG_REPORTER)
+AC_INIT([MCLinker],[1.1],[mclinker@googlegroups.com])
+AC_PREREQ(2.59)
+
+AC_CONFIG_SRCDIR([./COPYING])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([1.9 dist-bzip2 foreign])
+
+####################
+#  Versioning, see VERSION
+MAJOR=0
+MINOR=2
+MICRO=10
+AGE=1
+BUILD=18peaks
+
+DEV_VERSION=$MAJOR.$MINOR.$MICRO.$AGE-$BUILD
+PKG_VERSION=$MAJOR.$MINOR.$MICRO-$BUILD
+MCLD_VERSION=$DEV_VERSION
+AC_SUBST(MCLD_VERSION)
+
+####################
+#  Languages
+AC_PROG_CC
+AC_PROG_CXX
+AC_LANG([C++])
+LT_INIT
+
+####################
+#  Check for libraries
+
+#  Configure pthreads.
+AC_ARG_WITH([pthreads],
+            [AS_HELP_STRING([--with-pthreads],
+               [use pthreads (default is yes)])],
+            [with_pthreads=$withval],
+            [with_pthreads=check])
+
+have_pthreads=no
+AS_IF([test "x$with_pthreads" != "xno"],
+      [ACX_PTHREAD(
+        [],
+        [AS_IF([test "x$with_pthreads" != "xcheck"],
+               [AC_MSG_FAILURE(
+                 [--with-pthreads was specified, but unable to be used])])])
+       have_pthreads="$acx_pthread_ok"])
+AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"])
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_LIBS)
+
+# Configure Unit-test
+AC_ARG_ENABLE(unittest,
+            [AS_HELP_STRING([--enable-unittest],
+                [turn on unit-tests (default is no)])],
+            [case "${enableval}" in
+              yes) unittest=true ;;
+              no)  unittest=false ;;
+              *) AC_MSG_ERROR(bad value ${enableval} for --enable-unittest) ;;
+             esac],
+             [unittest=false])
+AM_CONDITIONAL([ENABLE_UNITTEST],[test "x${unittest}" == "xtrue" ])
+
+####################
+# Configure LLVM
+CHECK_LLVM([3.0])
+ENUM_LLVM_TARGETS
+
+####################
+# OUTPUT
+AC_CONFIG_FILES([VERSION])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([debug/Makefile])
+AC_CONFIG_FILES([optimized/Makefile])
+AC_CONFIG_FILES([utils/Makefile])
+AC_CONFIG_FILES([utils/gtest/Makefile])
+AC_CONFIG_FILES([utils/gtest/obj/Makefile])
+AC_CONFIG_FILES([include/mcld/Config/Targets.def])
+AC_CONFIG_FILES([include/mcld/Config/Linkers.def])
+AC_CONFIG_FILES([include/mcld/Config/Config.h])
+AC_CONFIG_FILES([test/Makefile])
+
+AC_OUTPUT
diff --git a/debug/Makefile.am b/debug/Makefile.am
new file mode 100644
index 0000000..4f9d24d
--- /dev/null
+++ b/debug/Makefile.am
@@ -0,0 +1,280 @@
+BUILDTOP=..
+TOPLEVEL=${srcdir}/..
+TOOLDIR=${TOPLEVEL}/tools/llvm-mcld
+LIBDIR=${TOPLEVEL}/lib
+INCDIR=${TOPLEVEL}/include/mcld
+UNITTEST=${TOPLEVEL}/unittests
+
+ANDROID_CPPFLAGS=-Wformat -Werror=format-security -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
+
+bin_PROGRAMS = llvm-mcld
+
+if ENABLE_UNITTEST
+llvm_mcld_CPPFLAGS = -g -O1 -DTOPDIR=\"${abs_top_srcdir}\" -DLLVM_VERSION=${LLVM_VERSION} -DENABLE_UNITTEST -DMCLD_DEBUG -I$(TOPLEVEL)/utils/gtest/include -I$(TOPLEVEL)/include -I$(TOPLEVEL)/unittests -I$(BUILDTOP)/include ${LLVM_CPPFLAGS} -DGTEST_HAS_RTTI=0 ${ANDROID_CPPFLAGS}
+llvm_mcld_LDADD = -L$(BUILDTOP)/utils/gtest/lib/ ${LLVM_LDFLAGS} -lgtest
+else
+llvm_mcld_CPPFLAGS = -g -O1 -DLLVM_VERSION=${LLVM_VERSION} -I$(TOPLEVEL)/utils/gtest/include -I$(TOPLEVEL)/include -I$(TOPLEVEL)/include -I$(BUILDTOP)/include ${LLVM_CPPFLAGS} ${ANDROID_CPPFLAGS}
+llvm_mcld_LDADD = ${LLVM_LDFLAGS}
+endif
+
+NORMAL_SOURCE = ${TOOLDIR}/llvm-mcld.cpp \
+	${INCDIR}/ADT/Uncopyable.h \
+	${INCDIR}/ADT/TypeTraits.h \
+	${INCDIR}/ADT/TreeBase.h \
+	${INCDIR}/ADT/Allocators.h \
+	${INCDIR}/ADT/TreeAllocator.h \
+	${INCDIR}/ADT/BinTree.h \
+	${INCDIR}/Support/Path.h \
+	${LIBDIR}/Support/Path.cpp \
+	${INCDIR}/Support/RealPath.h \
+	${LIBDIR}/Support/RealPath.cpp \
+	${INCDIR}/Support/Directory.h \
+	${LIBDIR}/Support/Directory.cpp \
+	${INCDIR}/Support/FileSytem.h \
+	${LIBDIR}/Support/FileSystem.cpp \
+	${INCDIR}/Support/LEB128.h \
+	${LIBDIR}/Support/LEB128.cpp \
+	${INCDIR}/Support/MemoryArea.h \
+	${LIBDIR}/Support/MemoryArea.cpp \
+	${INCDIR}/Support/MemoryRegion.h \
+	${LIBDIR}/Support/MemoryRegion.cpp \
+	${INCDIR}/Support/RegionFactory.h \
+	${LIBDIR}/Support/RegionFactory.cpp \
+	${INCDIR}/Support/MemoryAreaFactory.h \
+	${LIBDIR}/Support/MemoryAreaFactory.cpp \
+	${INCDIR}/Support/CommandLine.h \
+	${LIBDIR}/Support/CommandLine.cpp \
+	${INCDIR}/Support/GCFactory.h \
+	${INCDIR}/Support/UniqueGCFactory.h \
+	${INCDIR}/Support/PositionDependentOption.h \
+	${INCDIR}/Support/DerivedPositionDependentOptions.h \
+	${LIBDIR}/CodeGen/LLVMTargetMachine.cpp \
+	${INCDIR}/CodeGen/SectLinker.h \
+	${LIBDIR}/CodeGen/SectLinker.cpp \
+	${INCDIR}/CodeGen/SectLinkerOption.h \
+	${LIBDIR}/CodeGen/SectLinkerOption.cpp \
+	${INCDIR}/Target/PLT.h\
+	${LIBDIR}/Target/PLT.cpp\
+	${INCDIR}/Target/GOT.h \
+	${LIBDIR}/Target/GOT.cpp \
+	${INCDIR}/Target/TargetMachine.h \
+	${INCDIR}/Target/TargetRegistry.h \
+	${LIBDIR}/Support/TargetRegistry.cpp \
+	${LIBDIR}/Target/Target.cpp \
+	${INCDIR}/Target/TargetSelect.h \
+	${INCDIR}/Target/TargetLDBackend.h \
+	${LIBDIR}/Target/TargetLDBackend.cpp \
+	${INCDIR}/Target/GNULDBackend.h \
+	${LIBDIR}/Target/GNULDBackend.cpp \
+	${INCDIR}/Target/AndroidSectLinker.h \
+	${LIBDIR}/Target/AndroidSectLinker.cpp \
+	${INCDIR}/Target/ELFDynamic.h \
+	${LIBDIR}/Target/ELFDynamic.cpp \
+	${INCDIR}/Target/OutputRelocSection.h \
+	${LIBDIR}/Target/OutputRelocSection.cpp \
+	${LIBDIR}/Target/ARM/ARMELFDynamic.h \
+	${LIBDIR}/Target/ARM/ARMELFDynamic.cpp \
+	${LIBDIR}/Target/ARM/ARMLDBackend.h \
+	${LIBDIR}/Target/ARM/ARMLDBackend.cpp \
+	${LIBDIR}/Target/ARM/ARMGOT.h \
+	${LIBDIR}/Target/ARM/ARMGOT.cpp \
+	${LIBDIR}/Target/ARM/ARMPLT.h \
+	${LIBDIR}/Target/ARM/ARMPLT.cpp \
+	${LIBDIR}/Target/ARM/ARMTargetMachine.h \
+	${LIBDIR}/Target/ARM/ARMTargetMachine.cpp \
+	${LIBDIR}/Target/ARM/ARMRelocationFactory.h \
+	${LIBDIR}/Target/ARM/ARMRelocationFactory.cpp \
+	${LIBDIR}/Target/ARM/ARMSectLinker.cpp \
+	${LIBDIR}/Target/ARM/ARMELFSectLinker.h \
+	${LIBDIR}/Target/ARM/ARMELFSectLinker.cpp \
+	${LIBDIR}/Target/ARM/ARMAndroidSectLinker.h \
+	${LIBDIR}/Target/ARM/ARMAndroidSectLinker.cpp \
+	${LIBDIR}/Target/ARM/TargetInfo/ARMTargetInfo.cpp \
+	${LIBDIR}/Target/Mips/MipsELFDynamic.h \
+	${LIBDIR}/Target/Mips/MipsELFDynamic.cpp \
+	${LIBDIR}/Target/Mips/MipsLDBackend.h \
+	${LIBDIR}/Target/Mips/MipsLDBackend.cpp \
+	${LIBDIR}/Target/Mips/MipsGOT.h \
+	${LIBDIR}/Target/Mips/MipsGOT.cpp \
+	${LIBDIR}/Target/Mips/MipsTargetMachine.h \
+	${LIBDIR}/Target/Mips/MipsTargetMachine.cpp \
+	${LIBDIR}/Target/Mips/MipsRelocationFactory.h \
+	${LIBDIR}/Target/Mips/MipsRelocationFactory.cpp \
+	${LIBDIR}/Target/Mips/MipsSectLinker.cpp \
+	${LIBDIR}/Target/Mips/MipsELFSectLinker.h \
+	${LIBDIR}/Target/Mips/MipsELFSectLinker.cpp \
+	${LIBDIR}/Target/Mips/MipsAndroidSectLinker.h \
+	${LIBDIR}/Target/Mips/MipsAndroidSectLinker.cpp \
+	${LIBDIR}/Target/Mips/TargetInfo/MipsTargetInfo.cpp \
+	${LIBDIR}/Target/X86/X86ELFDynamic.h \
+	${LIBDIR}/Target/X86/X86ELFDynamic.cpp \
+	${LIBDIR}/Target/X86/X86LDBackend.h \
+	${LIBDIR}/Target/X86/X86LDBackend.cpp \
+	${LIBDIR}/Target/X86/X86GOT.h \
+	${LIBDIR}/Target/X86/X86GOT.cpp \
+	${LIBDIR}/Target/X86/X86GOTPLT.h \
+	${LIBDIR}/Target/X86/X86GOTPLT.cpp \
+	${LIBDIR}/Target/X86/X86PLT.h \
+	${LIBDIR}/Target/X86/X86PLT.cpp \
+	${LIBDIR}/Target/X86/X86TargetMachine.h \
+	${LIBDIR}/Target/X86/X86TargetMachine.cpp \
+	${LIBDIR}/Target/X86/X86RelocationFactory.h \
+	${LIBDIR}/Target/X86/X86RelocationFactory.cpp \
+	${LIBDIR}/Target/X86/X86SectLinker.cpp \
+	${LIBDIR}/Target/X86/X86ELFSectLinker.h \
+	${LIBDIR}/Target/X86/X86ELFSectLinker.cpp \
+	${LIBDIR}/Target/X86/X86AndroidSectLinker.h \
+	${LIBDIR}/Target/X86/X86AndroidSectLinker.cpp \
+	${LIBDIR}/Target/X86/TargetInfo/X86TargetInfo.cpp \
+	${INCDIR}/MC/MCLDDriver.h \
+	${LIBDIR}/MC/MCLDDriver.cpp \
+	${INCDIR}/MC/SymbolCategory.h \
+	${LIBDIR}/MC/SymbolCategory.cpp \
+	${INCDIR}/MC/MCLinker.h \
+	${LIBDIR}/MC/MCLinker.cpp \
+	${INCDIR}/MC/MCBitcodeInterceptor.h \
+	${LIBDIR}/MC/MCBitcodeInterceptor.cpp \
+	${INCDIR}/MC/MCLDFile.h \
+	${LIBDIR}/MC/MCLDFile.cpp \
+	${INCDIR}/MC/MCLDInput.h \
+	${LIBDIR}/MC/MCLDInput.cpp \
+	${INCDIR}/MC/MCLDOutput.h \
+	${LIBDIR}/MC/MCLDOutput.cpp \
+	${INCDIR}/MC/InputFactory.h \
+	${LIBDIR}/MC/InputFactory.cpp \
+	${INCDIR}/MC/MCLDOptions.h \
+	${LIBDIR}/MC/MCLDOptions.cpp \
+	${INCDIR}/MC/MCLDInfo.h \
+	${LIBDIR}/MC/MCLDInfo.cpp \
+	${INCDIR}/MC/ContextFactory.h \
+	${LIBDIR}/MC/ContextFactory.cpp \
+	${INCDIR}/MC/SearchDirs.h \
+	${LIBDIR}/MC/SearchDirs.cpp \
+	${INCDIR}/MC/MCLDDirectory.h \
+	${LIBDIR}/MC/MCLDDirectory.cpp \
+	${INCDIR}/MC/MCLDAttribute.h \
+	${LIBDIR}/MC/MCLDAttribute.cpp \
+	${INCDIR}/MC/AttributeFactory.h \
+	${LIBDIR}/MC/AttributeFactory.cpp \
+	${INCDIR}/MC/MCLDInputTree.h \
+	${LIBDIR}/MC/MCLDInputTree.cpp \
+	${INCDIR}/MC/MCRegionFragment.h \
+	${LIBDIR}/MC/MCRegionFragment.cpp \
+	${INCDIR}/MC/MCTargetFragment.h \
+	${INCDIR}/MC/MCFragmentRef.h \
+	${LIBDIR}/MC/MCFragmentRef.cpp \
+	${INCDIR}/LD/LDContext.h \
+	${LIBDIR}/LD/LDContext.cpp \
+	${INCDIR}/LD/LDSection.h \
+	${LIBDIR}/LD/LDSection.cpp \
+	${INCDIR}/LD/ResolveInfo.h \
+	${LIBDIR}/LD/ResolveInfo.cpp \
+	${INCDIR}/LD/ResolveInfoFactory.h \
+	${LIBDIR}/LD/ResolveInfoFactory.cpp \
+	${INCDIR}/LD/Resolver.h \
+	${LIBDIR}/LD/Resolver.cpp \
+	${INCDIR}/LD/LDSymbol.h \
+	${LIBDIR}/LD/LDSymbol.cpp \
+	${INCDIR}/LD/Layout.h \
+	${LIBDIR}/LD/Layout.cpp\
+	${INCDIR}/LD/Relocation.h \
+	${LIBDIR}/LD/Relocation.cpp \
+	${INCDIR}/LD/RelocationFactory.h \
+	${LIBDIR}/LD/RelocationFactory.cpp \
+	${INCDIR}/LD/StaticResolver.h \
+	${LIBDIR}/LD/StaticResolver.cpp \
+	${INCDIR}/LD/StrSymPool.h \
+	${LIBDIR}/LD/StrSymPool.cpp \
+	${INCDIR}/LD/LDReader.h \
+	${LIBDIR}/LD/LDReader.cpp \
+	${INCDIR}/LD/LDWriter.h \
+	${LIBDIR}/LD/LDWriter.cpp \
+	${INCDIR}/LD/ArchiveReader.h \
+	${LIBDIR}/LD/ArchiveReader.cpp \
+	${INCDIR}/LD/ObjectReader.h \
+	${INCDIR}/LD/DynObjReader.h \
+	${LIBDIR}/LD/DynObjReader.cpp \
+	${INCDIR}/LD/ObjectWriter.h \
+	${LIBDIR}/LD/ObjectWriter.cpp \
+	${INCDIR}/LD/DynObjWriter.h \
+	${LIBDIR}/LD/DynObjWriter.cpp \
+	${INCDIR}/LD/ELFReader.h \
+	${LIBDIR}/LD/ELFReader.cpp \
+	${INCDIR}/LD/ELFWriter.h \
+	${LIBDIR}/LD/ELFWriter.cpp \
+	${INCDIR}/LD/GNUArchiveReader.h \
+	${LIBDIR}/LD/GNUArchiveReader.cpp \
+	${INCDIR}/LD/BSDArchiveReader.h \
+	${LIBDIR}/LD/BSDArchiveReader.cpp \
+	${INCDIR}/LD/ELFObjectReader.h \
+	${LIBDIR}/LD/ELFObjectReader.cpp \
+	${INCDIR}/LD/ELFDynObjReader.h \
+	${LIBDIR}/LD/ELFDynObjReader.cpp \
+	${INCDIR}/LD/ELFObjectWriter.h \
+	${LIBDIR}/LD/ELFObjectWriter.cpp \
+	${INCDIR}/LD/ELFDynObjWriter.h \
+	${LIBDIR}/LD/ELFDynObjWriter.cpp \
+	${INCDIR}/LD/LDFileFormat.h \
+	${LIBDIR}/LD/LDFileFormat.cpp \
+	${INCDIR}/LD/ELFFileFormat.h \
+	${LIBDIR}/LD/ELFFileFormat.cpp \
+	${INCDIR}/LD/ELFDynObjFileFormat.h \
+	${LIBDIR}/LD/ELFDynObjFileFormat.cpp \
+	${INCDIR}/LD/ELFExecFileFormat.h \
+	${LIBDIR}/LD/ELFExecFileFormat.cpp \
+	${INCDIR}/LD/LDSectionFactory.h \
+	${LIBDIR}/LD/LDSectionFactory.cpp \
+	${INCDIR}/LD/SectionMap.h \
+	${LIBDIR}/LD/SectionMap.cpp \
+	${INCDIR}/LD/SectionMerger.h \
+	${LIBDIR}/LD/SectionMerger.cpp \
+	${INCDIR}/LD/ELFSegment.h \
+	${LIBDIR}/LD/ELFSegment.cpp \
+	${INCDIR}/LD/ELFSegmentFactory.h \
+	${LIBDIR}/LD/ELFSegmentFactory.cpp
+#	${LIBDIR}/CodeGen/LDPrinter.cpp \
+#	${INCDIR}/CodeGen/LDPrinter.h
+#	${INCDIR}/Support/ScopedRegion.h \
+#	${LIBDIR}/Support/ScopedRegion.cpp
+
+if ENABLE_UNITTEST
+SOURCE = ${NORMAL_SOURCE} \
+	${UNITTEST}/PathTest.h \
+	${UNITTEST}/PathTest.cpp \
+	${UNITTEST}/BinTreeTest.h \
+	${UNITTEST}/BinTreeTest.cpp \
+	${UNITTEST}/LinearAllocatorTest.h \
+	${UNITTEST}/LinearAllocatorTest.cpp \
+	${UNITTEST}/InputTreeTest.h \
+	${UNITTEST}/InputTreeTest.cpp \
+	${UNITTEST}/RTLinearAllocatorTest.h \
+	${UNITTEST}/RTLinearAllocatorTest.cpp \
+	${UNITTEST}/DirIteratorTest.h \
+	${UNITTEST}/DirIteratorTest.cpp \
+	${UNITTEST}/UniqueGCFactoryBaseTest.h \
+	${UNITTEST}/UniqueGCFactoryBaseTest.cpp \
+	${UNITTEST}/MemoryAreaTest.h \
+	${UNITTEST}/MemoryAreaTest.cpp \
+	${UNITTEST}/HashTableTest.h \
+	${UNITTEST}/HashTableTest.cpp \
+	${UNITTEST}/LDSymbolTest.h \
+	${UNITTEST}/LDSymbolTest.cpp \
+	${UNITTEST}/MCFragmentRefTest.h \
+	${UNITTEST}/MCFragmentRefTest.cpp \
+	${UNITTEST}/StaticResolverTest.h \
+	${UNITTEST}/StaticResolverTest.cpp \
+	${UNITTEST}/GCFactoryListTraitsTest.h \
+	${UNITTEST}/GCFactoryListTraitsTest.cpp \
+	${UNITTEST}/LEB128Test.h \
+	${UNITTEST}/LEB128Test.cpp \
+	${UNITTEST}/SymbolCategoryTest.h \
+	${UNITTEST}/SymbolCategoryTest.cpp
+#	${UNITTEST}/SymbolTableTest.h \
+#	${UNITTEST}/SymbolTableTest.cpp \
+#        ${UNITTEST}/TargetRegistryTest.h \
+#        ${UNITTEST}/TargetRegistryTest.cpp
+else
+SOURCE = ${NORMAL_SOURCE}
+endif
+
+llvm_mcld_SOURCES = ${SOURCE}
diff --git a/docs/DesignNote b/docs/DesignNote
new file mode 100644
index 0000000..d0eee5e
--- /dev/null
+++ b/docs/DesignNote
@@ -0,0 +1,11 @@
+Design Note
+===================
+1st Milestone:
+
+Architecture     | ARM v7
+Operating System | Android
+Runtime Support  | without C-runtime library
+Inputs           | bitcode, shared object
+Output           | shared object
+Numeral system   | imprecise 64-bit (sufficiently large number)
+
diff --git a/docs/LLVM-architecture.dia b/docs/LLVM-architecture.dia
new file mode 100755
index 0000000..2db8cf9
--- /dev/null
+++ b/docs/LLVM-architecture.dia
Binary files differ
diff --git a/docs/MCLinker.dia b/docs/MCLinker.dia
new file mode 100755
index 0000000..c447bcc
--- /dev/null
+++ b/docs/MCLinker.dia
Binary files differ
diff --git a/include/mcld/ADT/BinTree.h b/include/mcld/ADT/BinTree.h
new file mode 100644
index 0000000..0a7fe28
--- /dev/null
+++ b/include/mcld/ADT/BinTree.h
@@ -0,0 +1,481 @@
+//===- BinTree.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BINARY_TREE_H
+#define MCLD_BINARY_TREE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TreeAllocator.h"
+
+#include <iterator>
+#include <memory>
+#include <queue>
+#include <stack>
+
+namespace mcld
+{
+
+template<class DataType>
+class BinaryTree;
+
+class DFSIterator : public TreeIteratorBase
+{
+public:
+  DFSIterator()
+  : TreeIteratorBase()
+  { }
+
+  DFSIterator(NodeBase *X)
+    : TreeIteratorBase(X) {
+    if (hasRightChild())
+      m_Stack.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Stack.push(m_pNode->left);
+  }
+
+  virtual ~DFSIterator()
+  { }
+
+  void advance() {
+    if (m_Stack.empty()) { // reach the end
+      m_pNode = m_pNode->right; // should be root
+      return;
+    }
+    m_pNode = m_Stack.top();
+    m_Stack.pop();
+    if (hasRightChild())
+      m_Stack.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Stack.push(m_pNode->left);
+  }
+
+private:
+    std::stack<NodeBase *> m_Stack;
+};
+
+class BFSIterator : public TreeIteratorBase
+{
+public:
+  BFSIterator()
+  : TreeIteratorBase()
+  { }
+
+  BFSIterator(NodeBase *X)
+    : TreeIteratorBase(X) {
+    if (hasRightChild())
+      m_Queue.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Queue.push(m_pNode->left);
+  }
+
+  virtual ~BFSIterator()
+  { }
+
+  void advance() { 
+    if (m_Queue.empty()) { // reach the end
+      m_pNode = m_pNode->right; // should be root
+      return;
+    }
+    m_pNode = m_Queue.front();
+    m_Queue.pop();
+    if (hasRightChild())
+      m_Queue.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Queue.push(m_pNode->left);
+  }
+
+private:
+    std::queue<NodeBase *> m_Queue;
+};
+
+template<class DataType, class Traits, class IteratorType>
+class PolicyIteratorBase : public IteratorType
+{
+public:
+  typedef DataType                       value_type;
+  typedef Traits                         traits;
+  typedef typename traits::pointer       pointer;
+  typedef typename traits::reference     reference;
+  
+  typedef PolicyIteratorBase<value_type, Traits, IteratorType>          Self;
+  typedef Node<value_type>                                              node_type;
+  typedef typename traits::nonconst_traits                              nonconst_traits;
+  typedef PolicyIteratorBase<value_type, nonconst_traits, IteratorType> iterator;
+  typedef typename traits::const_traits                                 const_traits;
+  typedef PolicyIteratorBase<value_type, const_traits, IteratorType>    const_iterator;
+  typedef std::forward_iterator_tag                                     iterator_category;
+  typedef size_t                                                        size_type;
+  typedef ptrdiff_t                                                     difference_type;
+
+public:
+  PolicyIteratorBase()
+    : IteratorType() {}
+
+  PolicyIteratorBase(const iterator &X)
+    : IteratorType(X.m_pNode) {}
+
+  explicit PolicyIteratorBase(NodeBase* X)
+    : IteratorType(X) {}
+
+  virtual ~PolicyIteratorBase() {}
+
+  // -----  operators  ----- //
+  pointer operator*() const 
+  { return static_cast<node_type*>(IteratorType::m_pNode)->data; }
+
+  reference operator->() const
+  { return *static_cast<node_type*>(IteratorType::m_pNode)->data; }
+
+  bool isRoot() const
+  { return (IteratorType::m_pNode->right == IteratorType::m_pNode); }
+
+  bool hasData() const 
+  { return (!isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }
+
+};
+
+template<class DataType, class Traits, class IteratorType>
+class PolicyIterator : public PolicyIteratorBase<DataType, Traits, IteratorType>
+{
+public:
+  typedef PolicyIterator<DataType, Traits, IteratorType> Self;
+  typedef PolicyIteratorBase<DataType, Traits, IteratorType> Base;
+  typedef PolicyIterator<DataType, typename Traits::nonconst_traits, IteratorType> iterator;
+  typedef PolicyIterator<DataType, typename Traits::const_traits, IteratorType>    const_iterator;
+
+public:
+  PolicyIterator()
+    : Base() {}
+
+  PolicyIterator(const iterator &X)
+    : Base(X.m_pNode) {}
+
+  explicit PolicyIterator(NodeBase* X)
+    : Base(X) {}
+
+  virtual ~PolicyIterator() {}
+
+  Self& operator++() {
+    IteratorType::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    IteratorType::advance();
+    return tmp;
+  }
+};
+
+template<class DataType>
+class BinaryTree;
+
+/** \class TreeIterator
+ *  \brief TreeIterator provides full functions of binary tree's iterator.
+ *
+ *  TreeIterator is designed to compatible with STL iterators.
+ *  TreeIterator is bi-directional. Incremental direction means to move
+ *  rightward, and decremental direction is leftward.
+ *
+ *  @see TreeIteratorBase
+ */
+template<class DataType, class Traits>
+struct TreeIterator : public TreeIteratorBase
+{
+public:
+  typedef DataType                       value_type;
+  typedef Traits                         traits;
+  typedef typename traits::pointer       pointer;
+  typedef typename traits::reference     reference;
+
+  typedef TreeIterator<value_type, Traits>          Self;
+  typedef Node<value_type>                          node_type;
+
+  typedef typename traits::nonconst_traits          nonconst_traits;
+  typedef TreeIterator<value_type, nonconst_traits> iterator;
+  typedef typename traits::const_traits             const_traits;
+  typedef TreeIterator<value_type, const_traits>    const_iterator;
+  typedef std::bidirectional_iterator_tag           iterator_category;
+  typedef size_t                                    size_type;
+  typedef ptrdiff_t                                 difference_type;
+
+public:
+  TreeIterator()
+  : TreeIteratorBase() {}
+
+  TreeIterator(const iterator &X)
+    : TreeIteratorBase(X.m_pNode) {}
+
+  ~TreeIterator() {}
+
+  // -----  operators  ----- //
+  pointer operator*() const 
+  { return static_cast<node_type*>(m_pNode)->data; }
+
+  reference operator->() const
+  { return *static_cast<node_type*>(m_pNode)->data; }
+
+  bool isRoot() const
+  { return (m_pNode->right == m_pNode); }
+
+  bool hasData() const 
+  { return (!isRoot() && (0 != static_cast<node_type*>(m_pNode)->data)); }
+
+  Self& operator++() {
+    this->move<TreeIteratorBase::Rightward>();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->move<TreeIteratorBase::Rightward>();
+    return tmp;
+  }
+
+  Self& operator--() {
+    this->move<TreeIteratorBase::Leftward>();
+    return *this;
+  }
+
+  Self operator--(int) {
+    Self tmp = *this;
+    this->move<TreeIteratorBase::Leftward>();
+    return tmp;
+  }
+
+  explicit TreeIterator(NodeBase* X)
+    : TreeIteratorBase(X) {}
+};
+
+/** \class BinaryTreeBase
+ *  \brief BinaryTreeBase gives root node and memory management.
+ *
+ *  The memory management of nodes in is hidden by BinaryTreeBase.
+ *  BinaryTreeBase also provides the basic functions for merging a tree and 
+ *  inserton of a node.
+ * 
+ *  @see BinaryTree
+ */
+template<class DataType>
+class BinaryTreeBase : private Uncopyable
+{
+public:
+  typedef Node<DataType> NodeType;
+protected:
+  /// TreeImpl - TreeImpl records the root node and the number of nodes
+  //
+  //    +---> Root(end) <---+
+  //    |        |left      |
+  //    |      begin        |
+  //    |     /     \       |
+  //    |  Left     Right   |
+  //    +---/         \-----+
+  //     
+  class TreeImpl : public NodeFactory<DataType>
+  {
+    typedef typename NodeFactory<DataType>::iterator       iterator;
+    typedef typename NodeFactory<DataType>::const_iterator const_iterator;
+
+  public:
+    NodeBase node;
+
+  public:
+    TreeImpl()
+      : NodeFactory<DataType>() {
+      node.left = node.right = &node;
+    }
+
+    ~TreeImpl()
+    { }
+
+    /// summon - change the final edges of pClient to our root
+    void summon(TreeImpl& pClient) {
+      if (this == &pClient)
+        return;
+
+      iterator data;
+      iterator dEnd = pClient.end();
+      for (data = pClient.begin(); data!=dEnd; ++data ) {
+        if ((*data).left == &pClient.node)
+          (*data).left = &node;
+        if ((*data).right == &pClient.node)
+          (*data).right = &node;
+      }
+    }
+  }; // TreeImpl
+
+protected:
+  /// m_Root is a special object who responses:
+  //  - the pointer of root
+  //  - the simple factory of nodes.
+  TreeImpl m_Root;
+
+protected:
+  NodeType *createNode() {
+    NodeType *result = m_Root.produce();
+    result->left = result->right = &m_Root.node;
+    return result;
+  }
+
+  void destroyNode(NodeType *pNode) {
+    pNode->left = pNode->right = 0;
+    pNode->data = 0;
+    m_Root.deallocate(pNode);
+  }
+
+public:
+  BinaryTreeBase()
+  : m_Root()
+  { }
+
+  virtual ~BinaryTreeBase()
+  { }
+
+  size_t size() const {
+    return m_Root.size();
+  }
+
+  bool empty() const {
+    return m_Root.empty();
+  }
+
+protected:
+  void clear() {
+    m_Root.clear();
+  }
+};
+
+/** \class BinaryTree
+ *  \brief An abstract data type of binary tree.
+ *
+ *  @see mcld::InputTree
+ */
+template<class DataType>
+class BinaryTree : public BinaryTreeBase<DataType>
+{
+public:
+  typedef size_t             size_type;
+  typedef ptrdiff_t          difference_type;
+  typedef DataType           value_type;
+  typedef value_type*        pointer;
+  typedef value_type&        reference;
+  typedef const value_type*  const_pointer;
+  typedef const value_type&  const_reference;
+
+  typedef BinaryTree<DataType>  Self;
+  typedef TreeIterator<value_type, NonConstTraits<value_type> > iterator;
+  typedef TreeIterator<value_type, ConstTraits<value_type> >    const_iterator;
+
+  typedef PolicyIterator<value_type, NonConstTraits<value_type>, DFSIterator> dfs_iterator;
+  typedef PolicyIterator<value_type, ConstTraits<value_type>, DFSIterator>    const_dfs_iterator;
+  typedef PolicyIterator<value_type, NonConstTraits<value_type>, BFSIterator> bfs_iterator;
+  typedef PolicyIterator<value_type, ConstTraits<value_type>, BFSIterator>    const_bfs_iterator;
+
+protected:
+  typedef Node<value_type> node_type;
+
+public:
+  // -----  constructors and destructor  ----- //
+  BinaryTree()
+  : BinaryTreeBase<DataType>()
+  { }
+
+  ~BinaryTree() {
+  }
+
+  // -----  iterators  ----- //
+  bfs_iterator bfs_begin()
+  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  bfs_iterator bfs_end()
+  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_bfs_iterator bfs_begin() const
+  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_bfs_iterator bfs_end() const
+  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  dfs_iterator dfs_begin()
+  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  dfs_iterator dfs_end()
+  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_dfs_iterator dfs_begin() const
+  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_dfs_iterator dfs_end() const
+  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  iterator root()
+  { return iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
+
+  const_iterator root() const
+  { return const_iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
+
+  iterator begin()
+  { return iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  iterator end()
+  { return iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_iterator begin() const
+  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_iterator end() const
+  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  // ----- modifiers  ----- //
+  /// join - create a leaf node and merge it in the tree.
+  //  This version of join determines the direction on compilation time.
+  //  @param DIRECT the direction of the connecting edge of the parent node.
+  //  @param position the parent node
+  //  @param value the value being pushed.
+  template<size_t DIRECT, class Pos>
+  BinaryTree& join(Pos position, const DataType& value) {
+    node_type *node = BinaryTreeBase<DataType>::createNode();
+    node->data = const_cast<DataType*>(&value);
+    if (position.isRoot())
+      proxy::hook<TreeIteratorBase::Leftward>(position.m_pNode,
+                          const_cast<const node_type*>(node));
+    else
+      proxy::hook<DIRECT>(position.m_pNode,
+                          const_cast<const node_type*>(node));
+    return *this;
+  }
+
+  /// merge - merge the tree
+  //  @param DIRECT the direction of the connecting edge of the parent node.
+  //  @param position the parent node
+  //  @param the tree being joined.
+  //  @return the joined tree
+  template<size_t DIRECT, class Pos>
+  BinaryTree& merge(Pos position, BinaryTree& pTree) {
+    if (this == &pTree)
+      return *this;
+
+    if (!pTree.empty()) {
+      proxy::hook<DIRECT>(position.m_pNode,
+                        const_cast<const NodeBase*>(pTree.m_Root.node.left));
+      BinaryTreeBase<DataType>::m_Root.summon(
+                                   pTree.BinaryTreeBase<DataType>::m_Root);
+      BinaryTreeBase<DataType>::m_Root.delegate(pTree.m_Root);
+      pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
+    }
+    return *this;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashBase.h b/include/mcld/ADT/HashBase.h
new file mode 100644
index 0000000..76410ab
--- /dev/null
+++ b/include/mcld/ADT/HashBase.h
@@ -0,0 +1,139 @@
+//===- HashBase.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_HASH_BASE_H
+#define MCLD_HASH_BASE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <cstdlib>
+
+namespace mcld {
+
+/** forward declaration **/
+template<typename HashTableImplTy>
+class ChainIteratorBase;
+
+template<typename HashTableImplTy>
+class EntryIteratorBase;
+
+/** \class HashBucket
+ *  \brief HashBucket is an entry in the hash table.
+ */
+template<typename HashEntryTy>
+class HashBucket
+{
+public:
+  typedef HashEntryTy entry_type;
+
+public:
+  unsigned int FullHashValue;
+  entry_type *Entry;
+
+public:
+  static entry_type* getEmptyBucket();
+  static entry_type* getTombstone();
+
+};
+
+/** \class HashTableImpl
+ *  \brief HashTableImpl is the base class of HashTable.
+ *
+ *  HashTableImpl uses open-addressing, linear probing hash table.
+ *  linear probing hash table obviously has high performance when the
+ *  load factor is less than 0.7.
+ *  The drawback is that the number of the stored items can notbe more
+ *  than the size of the hash table.
+ *
+ *  MCLinker tries to merge every things in the same HashEntry. It can
+ *  keep every thing in the same cache line and improve the locality
+ *  efficiently. HashTableImpl provides a template argument to change the
+ *  definition of HashEntries.
+ *
+ *  HashEntryTy must provide getKey() and getKenLength() functions.
+ *
+ *  Different environments have different demands of HashFunctions. For
+ *  example, on-device linkers needs a more light-weight hash function
+ *  than static linkers. HashTableImpl also provides a template argument to
+ *  change the hash functions.
+ */
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+class HashTableImpl
+{
+private:
+  static const unsigned int NumOfInitBuckets = 16;
+
+public:
+  typedef size_t size_type;
+  typedef HashFunctionTy hasher;
+  typedef HashEntryTy entry_type;
+  typedef typename HashEntryTy::key_type key_type;
+  typedef HashBucket<HashEntryTy> bucket_type;
+  typedef HashTableImpl<HashEntryTy, HashFunctionTy> Self;
+
+
+public:
+  HashTableImpl();
+  explicit HashTableImpl(unsigned int pInitSize);
+  virtual ~HashTableImpl();
+
+  // -----  observers  ----- //
+  bool empty() const;
+
+  size_t numOfBuckets() const
+  { return m_NumOfBuckets; }
+
+  size_t numOfEntries() const
+  { return m_NumOfEntries; }
+
+  hasher& hash()
+  { return m_Hasher; }
+
+  const hasher& hash() const
+  { return m_Hasher; }
+
+protected:
+  /// initialize the hash table.
+  void init(unsigned int pInitSize);
+
+  /// lookUpBucketFor - search the index of bucket whose key is p>ey
+  //  @return the index of the found bucket
+  unsigned int lookUpBucketFor(const key_type& pKey);
+
+  /// findKey - finds an element with key pKey
+  //  return the index of the element, or -1 when the element does not exist.
+  int findKey(const key_type& pKey) const;
+
+  /// mayRehash - check the load_factor, compute the new size, and then doRehash
+  void mayRehash();
+
+  /// doRehash - re-new the hash table, and rehash all elements into the new buckets
+  void doRehash(unsigned int pNewSize);
+
+friend class ChainIteratorBase<Self>;
+friend class ChainIteratorBase<const Self>;
+friend class EntryIteratorBase<Self>;
+friend class EntryIteratorBase<const Self>;
+protected:
+  // Array of Buckets
+  bucket_type* m_Buckets;
+  unsigned int m_NumOfBuckets;
+  unsigned int m_NumOfEntries;
+  unsigned int m_NumOfTombstones;
+  hasher m_Hasher;
+
+};
+
+#include "HashBase.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashBase.tcc b/include/mcld/ADT/HashBase.tcc
new file mode 100644
index 0000000..62d92b1
--- /dev/null
+++ b/include/mcld/ADT/HashBase.tcc
@@ -0,0 +1,250 @@
+//===- HashBase.tcc -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// internal non-member functions
+inline static unsigned int compute_bucket_count(unsigned int pNumOfBuckets)
+{
+  static const unsigned int bucket_size[] =
+  {
+    1, 3, 17, 37, 67, 97, 197, 419, 977, 2593, 4099, 8209, 12289,
+    16411, 20483, 32771, 49157, 65537, 98317, 131101, 196613
+  };
+
+  const unsigned int buckets_count =
+      sizeof(bucket_size) / sizeof(bucket_size[0]);
+  unsigned int idx = 0;
+  do {
+    if (pNumOfBuckets < bucket_size[idx]) {
+      return bucket_size[idx];
+    }
+    ++idx;
+  } while(idx < buckets_count);
+
+  return (pNumOfBuckets+131101); // rare case. increase constantly
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashBucket
+template<typename DataType>
+typename HashBucket<DataType>::entry_type*
+HashBucket<DataType>::getEmptyBucket()
+{
+  static entry_type* empty_bucket = reinterpret_cast<entry_type*>(0x0);
+  return empty_bucket;
+}
+
+template<typename DataType>
+typename HashBucket<DataType>::entry_type*
+HashBucket<DataType>::getTombstone()
+{
+  static entry_type* tombstone = reinterpret_cast<entry_type*>(0x1);
+  return tombstone;
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashTableImpl
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl()
+  : m_Buckets(0),
+    m_NumOfBuckets(0),
+    m_NumOfEntries(0),
+    m_NumOfTombstones(0),
+    m_Hasher() {
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl(
+  unsigned int pInitSize)
+  : m_Hasher() {
+  if (pInitSize) {
+    init(pInitSize);
+    return;
+  }
+
+  m_Buckets = 0;
+  m_NumOfBuckets = 0;
+  m_NumOfEntries = 0;
+  m_NumOfTombstones = 0;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::~HashTableImpl()
+{
+  free(m_Buckets);
+}
+
+/// empty - check if the hash table is empty
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+bool HashTableImpl<HashEntryTy, HashFunctionTy>::empty() const
+{
+  return (0 == m_NumOfEntries);
+}
+
+/// init - initialize the hash table.
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::init(unsigned int pInitSize)
+{
+  m_NumOfBuckets = pInitSize? compute_bucket_count(pInitSize): NumOfInitBuckets;
+
+  m_NumOfEntries = 0;
+  m_NumOfTombstones = 0;
+
+  /** calloc also set bucket.Item = bucket_type::getEmptyStone() **/
+  m_Buckets = (bucket_type*)calloc(m_NumOfBuckets, sizeof(bucket_type));
+}
+
+/// lookUpBucketFor - look up the bucket whose key is pKey
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+unsigned int
+HashTableImpl<HashEntryTy, HashFunctionTy>::lookUpBucketFor(
+  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey)
+{
+  if (0 == m_NumOfBuckets) {
+    // NumOfBuckets is changed after init(pInitSize)
+    init(NumOfInitBuckets);
+  }
+
+  unsigned int full_hash = m_Hasher(pKey);
+  unsigned int index = full_hash % m_NumOfBuckets;
+
+  const unsigned int probe = 1;
+  int firstTombstone = -1;
+
+  // linear probing
+  while(true) {
+    bucket_type& bucket = m_Buckets[index];
+    // If we found an empty bucket, this key isn't in the table yet, return it.
+    if (bucket_type::getEmptyBucket() == bucket.Entry) {
+      if (-1 != firstTombstone) {
+        m_Buckets[firstTombstone].FullHashValue = full_hash;
+        return firstTombstone;
+      }
+
+      bucket.FullHashValue = full_hash;
+      return index;
+    }
+
+    if (bucket_type::getTombstone() == bucket.Entry) {
+      if (-1 == firstTombstone) {
+        firstTombstone = index;
+      }
+    }
+    else if (bucket.FullHashValue == full_hash) {
+      if (bucket.Entry->compare(pKey)) {
+        return index;
+      }
+    }
+
+    index += probe;
+    if (index == m_NumOfBuckets)
+      index = 0;
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+int
+HashTableImpl<HashEntryTy, HashFunctionTy>::findKey(
+  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey) const
+{
+  if (0 == m_NumOfBuckets)
+    return -1;
+
+  unsigned int full_hash = m_Hasher(pKey);
+  unsigned int index = full_hash % m_NumOfBuckets;
+
+  const unsigned int probe = 1;
+  // linear probing
+  while (true) {
+    bucket_type &bucket = m_Buckets[index];
+
+    if (bucket_type::getEmptyBucket() == bucket.Entry)
+      return -1;
+
+    if (bucket_type::getTombstone() == bucket.Entry) {
+      // Ignore tombstones.
+    }
+    else if (full_hash == bucket.FullHashValue) {
+      // get string, compare, if match, return index
+      if (bucket.Entry->compare(pKey))
+        return index;
+    }
+    index += probe;
+    if (index == m_NumOfBuckets)
+      index = 0;
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::mayRehash()
+{
+
+  unsigned int new_size;
+  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+  // the buckets are empty (meaning that many are filled with tombstones),
+  // grow/rehash the table.
+  if ((m_NumOfEntries<<2) > m_NumOfBuckets*3)
+    new_size = compute_bucket_count(m_NumOfBuckets);
+  else if (((m_NumOfBuckets-(m_NumOfEntries+m_NumOfTombstones))<<3) < m_NumOfBuckets)
+    new_size = m_NumOfBuckets;
+  else
+    return;
+
+  doRehash(new_size);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::doRehash(unsigned int pNewSize)
+{
+  bucket_type* new_table = (bucket_type*)calloc(pNewSize, sizeof(bucket_type));
+
+  // Rehash all the items into their new buckets.  Luckily :) we already have
+  // the hash values available, so we don't have to recall hash function again.
+  for (bucket_type *IB = m_Buckets, *E = m_Buckets+m_NumOfBuckets; IB != E; ++IB) {
+    if (IB->Entry != bucket_type::getEmptyBucket() &&
+        IB->Entry != bucket_type::getTombstone()) {
+      // Fast case, bucket available.
+      unsigned full_hash = IB->FullHashValue;
+      unsigned new_bucket = full_hash % pNewSize;
+      if (bucket_type::getEmptyBucket() == new_table[new_bucket].Entry) {
+        new_table[new_bucket].Entry = IB->Entry;
+        new_table[new_bucket].FullHashValue = full_hash;
+        continue;
+      }
+
+      // Otherwise probe for a spot.
+      const unsigned int probe = 1;
+      do {
+        new_bucket += probe;
+        if (new_bucket == pNewSize)
+          new_bucket = 0;
+      } while (new_table[new_bucket].Entry != bucket_type::getEmptyBucket());
+
+      // Finally found a slot.  Fill it in.
+      new_table[new_bucket].Entry = IB->Entry;
+      new_table[new_bucket].FullHashValue = full_hash;
+    }
+  }
+
+  free(m_Buckets);
+
+  m_Buckets = new_table;
+  m_NumOfBuckets = pNewSize;
+  m_NumOfTombstones = 0;
+}
+
diff --git a/include/mcld/ADT/HashEntry.h b/include/mcld/ADT/HashEntry.h
new file mode 100644
index 0000000..c034783
--- /dev/null
+++ b/include/mcld/ADT/HashEntry.h
@@ -0,0 +1,95 @@
+//===- HashEntry.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_ENTRY_H
+#define MCLD_HASH_ENTRY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld {
+
+/** forward declaration **/
+template<typename HashEntryTy>
+class EntryFactory;
+
+/** \class HashEntry
+ *  \brief HashEntry is the item in the bucket of hash table.
+ *
+ *  mcld::HashEntry illustrates the demand from mcld::HashTable.
+ *  Since HashTable can change the definition of the HashEntry by changing
+ *  the template argument. class mcld::HashEntry here is used to show the
+ *  basic interfaces that HashTable requests. You can define your own entry
+ *  of the hash table which has no relation to mcld::HashEntry
+ *
+ *  Since mcld::HashEntry here is a special class whose size is changing,
+ *  derive a new class from it is risky. Make sure you understand what you
+ *  are doing when you let a new class inherit from mcld::HashEntry.
+ */
+template <typename KeyType, typename ValueType, typename KeyCompare>
+class HashEntry
+{
+public:
+  typedef KeyType key_type;
+  typedef ValueType value_type;
+  typedef KeyCompare key_compare;
+
+private:
+  typedef HashEntry<KeyType, ValueType, KeyCompare> Self;
+  friend class EntryFactory<Self>;
+
+private:
+  HashEntry(const KeyType& pKey);
+  ~HashEntry();
+
+public:
+  KeyType& key()
+  { return m_Key; }
+
+  const KeyType& key() const
+  { return m_Key; }
+
+  ValueType& value()
+  { return m_Value; }
+
+  const ValueType& value() const
+  { return m_Value; }
+
+  void setValue(const ValueType& pValue)
+  { m_Value = pValue; }
+
+  bool compare(const key_type& pKey);
+
+public:
+  KeyType m_Key;
+  ValueType m_Value;
+};
+
+template <typename HashEntryTy>
+class EntryFactory
+{
+public:
+  typedef HashEntryTy                      entry_type;
+  typedef typename HashEntryTy::key_type   key_type;
+  typedef typename HashEntryTy::value_type value_type;
+
+public:
+  EntryFactory();
+  ~EntryFactory();
+
+  HashEntryTy* produce(const key_type& pKey);
+  void destroy(HashEntryTy* pEntry);
+};
+
+#include "HashEntry.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashEntry.tcc b/include/mcld/ADT/HashEntry.tcc
new file mode 100644
index 0000000..fdd886b
--- /dev/null
+++ b/include/mcld/ADT/HashEntry.tcc
@@ -0,0 +1,53 @@
+//===- HashEntry.tcc ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashEntry
+template <typename KeyType, typename ValueType, typename KeyCompare>
+HashEntry<KeyType, ValueType, KeyCompare>::HashEntry(const KeyType& pKey)
+  : m_Key(pKey) {
+}
+
+template <typename KeyType, typename ValueType, typename KeyCompare>
+HashEntry<KeyType, ValueType, KeyCompare>::~HashEntry()
+{
+}
+
+template <typename KeyType, typename ValueType, typename KeyCompare>
+bool HashEntry<KeyType, ValueType, KeyCompare>::compare(const KeyType& pKey)
+{
+  static KeyCompare comparator;
+  return comparator(m_Key, pKey);
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of EntryFactory
+template <typename HashEntryTy>
+EntryFactory<HashEntryTy>::EntryFactory()
+{
+}
+
+template <typename HashEntryTy>
+EntryFactory<HashEntryTy>::~EntryFactory()
+{
+}
+
+template <typename HashEntryTy>
+void EntryFactory<HashEntryTy>::destroy(HashEntryTy* pEntry)
+{
+  delete pEntry;
+}
+
+template <typename HashEntryTy>
+HashEntryTy*
+EntryFactory<HashEntryTy>::produce(const typename EntryFactory<HashEntryTy>::key_type& pKey)
+{
+  return new HashEntryTy(pKey);
+}
+
diff --git a/include/mcld/ADT/HashIterator.h b/include/mcld/ADT/HashIterator.h
new file mode 100644
index 0000000..92ccdc5
--- /dev/null
+++ b/include/mcld/ADT/HashIterator.h
@@ -0,0 +1,323 @@
+//===- HashIterator.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_HASH_ITERATOR_H
+#define MCLD_HASH_ITERATOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld {
+
+/** \class ChainIteratorBase
+ *  \brief ChaintIteratorBase follows the HashEntryTy with the same hash value.
+ */
+template<typename HashTableImplTy>
+class ChainIteratorBase
+{
+public:
+  typedef HashTableImplTy hash_table;
+  typedef typename HashTableImplTy::key_type key_type;
+  typedef typename HashTableImplTy::entry_type entry_type;
+  typedef typename HashTableImplTy::bucket_type bucket_type;
+
+public:
+  ChainIteratorBase()
+  : m_pHashTable(0), m_HashValue(0), m_Index(0), m_EndIndex(0)
+  { }
+
+  ChainIteratorBase(HashTableImplTy* pTable, const key_type& pKey)
+  : m_pHashTable(pTable)
+  {
+    m_HashValue = pTable->hash()(pKey);
+    m_EndIndex = m_Index = m_HashValue % m_pHashTable->m_NumOfBuckets;
+    const unsigned int probe = 1;
+    while(true) {
+      bucket_type &bucket = m_pHashTable->m_Buckets[m_Index];
+      if (bucket_type::getTombstone() == bucket.Entry) {
+        // Ignore tombstones.
+      }
+      else if (m_HashValue == bucket.FullHashValue) {
+        if (bucket.Entry->compare(pKey)) {
+          m_EndIndex = m_Index;
+          break;
+        }
+      }
+      m_Index += probe;
+      if (m_Index == m_pHashTable->m_NumOfBuckets)
+        m_Index = 0;
+      // doesn't exist
+      if (m_EndIndex == m_Index) {
+        reset();
+        break;
+      }
+    }
+  }
+
+  ChainIteratorBase(const ChainIteratorBase& pCopy)
+  : m_pHashTable(pCopy.m_pHashTable),
+    m_Index(pCopy.m_Index),
+    m_EndIndex(pCopy.m_EndIndex),
+    m_HashValue(pCopy.m_HashValue)
+  { }
+
+  ChainIteratorBase& assign(const ChainIteratorBase& pCopy) {
+    m_pHashTable = pCopy.m_pHashTable;
+    m_Index = pCopy.m_Index;
+    m_EndIndex = pCopy.m_EndIndex;
+    m_HashValue = pCopy.m_HashValue;
+    return *this;
+  }
+
+  inline bucket_type* getBucket() {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline const bucket_type* getBucket() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline entry_type* getEntry() {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline const entry_type* getEntry() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline void reset() {
+    m_pHashTable = 0;
+    m_Index = 0;
+    m_EndIndex = 0;
+    m_HashValue = 0;
+  }
+
+  inline void advance() {
+    if (0 == m_pHashTable)
+      return;
+    const unsigned int probe = 1;
+    while(true) {
+      m_Index += probe;
+      if (m_Index == m_pHashTable->m_NumOfBuckets)
+        m_Index = 0;
+      // reach end()
+      if (m_Index == m_EndIndex) {
+        reset();
+        return;
+      }
+
+      bucket_type &bucket = m_pHashTable->m_Buckets[m_Index];
+
+      if (bucket_type::getTombstone() == bucket.Entry ||
+          bucket_type::getEmptyBucket() == bucket.Entry) {
+        // Ignore tombstones.
+      }
+      else if (m_HashValue == bucket.FullHashValue) {
+        return;
+      }
+    }
+  }
+
+  bool operator==(const ChainIteratorBase& pCopy) const {
+    if (m_pHashTable == pCopy.m_pHashTable) {
+      if (0 == m_pHashTable)
+        return true;
+      return ((m_HashValue == pCopy.m_HashValue) &&
+              (m_EndIndex == pCopy.m_EndIndex) &&
+              (m_Index == pCopy.m_Index));
+    }
+    return false;
+  }
+
+  bool operator!=(const ChainIteratorBase& pCopy) const
+  { return !(*this == pCopy); }
+
+private:
+  HashTableImplTy* m_pHashTable;
+  unsigned int m_Index;
+  unsigned int m_HashValue;
+  unsigned int m_EndIndex;
+};
+ 
+/** \class EntryIteratorBase
+ *  \brief EntryIteratorBase walks over hash table by the natural layout of the
+ *  buckets
+ */
+template<typename HashTableImplTy>
+class EntryIteratorBase
+{
+public:
+  typedef HashTableImplTy hash_table;
+  typedef typename HashTableImplTy::key_type key_type;
+  typedef typename HashTableImplTy::entry_type entry_type;
+  typedef typename HashTableImplTy::bucket_type bucket_type;
+
+public:
+  EntryIteratorBase()
+  : m_pHashTable(0), m_Index(0)
+  { }
+
+  EntryIteratorBase(HashTableImplTy* pTable,
+                   unsigned int pIndex)
+  : m_pHashTable(pTable), m_Index(pIndex)
+  { }
+
+  EntryIteratorBase(const EntryIteratorBase& pCopy)
+  : m_pHashTable(pCopy.m_pHashTable), m_Index(pCopy.m_Index)
+  { }
+
+  EntryIteratorBase& assign(const EntryIteratorBase& pCopy) {
+    m_pHashTable = pCopy.m_pHashTable;
+    m_Index = pCopy.m_Index;
+    return *this;
+  }
+
+  inline bucket_type* getBucket() {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline const bucket_type* getBucket() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline entry_type* getEntry() {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline const entry_type* getEntry() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline void reset() {
+    m_pHashTable = 0;
+    m_Index = 0;
+  }
+
+  inline void advance() {
+    if (0 == m_pHashTable)
+      return;
+    do {
+      ++m_Index;
+      if (m_pHashTable->m_NumOfBuckets == m_Index) { // to the end
+        reset();
+        return;
+      }
+    } while(bucket_type::getEmptyBucket() == m_pHashTable->m_Buckets[m_Index].Entry || 
+            bucket_type::getTombstone() == m_pHashTable->m_Buckets[m_Index].Entry);
+  }
+
+  bool operator==(const EntryIteratorBase& pCopy) const
+  { return ((m_pHashTable == pCopy.m_pHashTable) &&
+            (m_Index == pCopy.m_Index)); }
+
+  bool operator!=(const EntryIteratorBase& pCopy) const
+  { return !(*this == pCopy); }
+
+private:
+  HashTableImplTy* m_pHashTable;
+  unsigned int m_Index;
+
+};
+
+/** \class HashIterator
+ *  \brief HashIterator provides a policy-based iterator.
+ *
+ *  HashTable has two kinds of iterators. One is used to traverse buckets
+ *  with the same hash value; the other is used to traverse all entries of the
+ *  hash table.
+ *
+ *  HashIterator is a template policy-based iterator, which can change its
+ *  behavior by change the template argument IteratorBase. HashTable defines
+ *  above two iterators by defining HashIterators with different IteratorBase.
+ */
+template<typename IteratorBase,
+         typename Traits>
+class HashIterator : public IteratorBase
+{
+public:
+  typedef Traits                     traits;
+  typedef typename traits::pointer   pointer;
+  typedef typename traits::reference reference;
+  typedef size_t                     size_type;
+  typedef ptrdiff_t                  difference_type;
+  typedef IteratorBase               Base;
+
+  typedef HashIterator<IteratorBase,
+                       Traits>             Self;
+
+  typedef typename traits::nonconst_traits nonconst_traits;
+  typedef HashIterator<IteratorBase,
+                       nonconst_traits>    iterator;
+
+  typedef typename traits::const_traits    const_traits;
+  typedef HashIterator<IteratorBase,
+                       const_traits>       const_iterator;
+  typedef std::forward_iterator_tag        iterator_category;
+
+public:
+  HashIterator()
+  : IteratorBase()
+  { }
+
+  /// HashIterator - constructor for EntryIterator
+  HashIterator(typename IteratorBase::hash_table* pTable, unsigned int pIndex)
+  : IteratorBase(pTable, pIndex)
+  { }
+
+  /// HashIterator - constructor for ChainIterator
+  explicit HashIterator(typename IteratorBase::hash_table* pTable,
+                        const typename IteratorBase::key_type& pKey,
+                        int)
+  : IteratorBase(pTable, pKey)
+  { }
+
+  HashIterator(const HashIterator& pCopy)
+  : IteratorBase(pCopy)
+  { }
+
+  ~HashIterator()
+  { }
+
+  HashIterator& operator=(const HashIterator& pCopy) {
+    IteratorBase::assign(pCopy);
+    return *this;
+  }
+
+  // -----  operators  ----- //
+  Self& operator++() {
+    this->Base::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->Base::advance();
+    return tmp;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashTable.h b/include/mcld/ADT/HashTable.h
new file mode 100644
index 0000000..dfc2f5a
--- /dev/null
+++ b/include/mcld/ADT/HashTable.h
@@ -0,0 +1,126 @@
+//===- HashTable.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_TABLE_H
+#define MCLD_HASH_TABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/HashBase.h"
+#include "mcld/ADT/HashIterator.h"
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/Allocators.h"
+#include <utility>
+
+namespace mcld
+{
+
+/** \class HashTable
+ *  \brief HashTable is a hash table which follows boost::unordered_map, but it
+ *  is open addressing and can linear probing.
+ *
+ *  mcld::HashTable is a linear probing hash table. It does not allocate
+ *  the memory space of the entries by itself. Instead, entries are allocated
+ *  outside and then emplaced into the hash table.
+ */
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+class HashTable : public HashTableImpl<HashEntryTy, HashFunctionTy>,
+                  private Uncopyable
+{
+private:
+  typedef HashTableImpl<HashEntryTy, HashFunctionTy> BaseTy;
+
+public:
+  typedef size_t size_type;
+  typedef HashFunctionTy hasher;
+  typedef HashEntryTy entry_type;
+  typedef typename BaseTy::bucket_type bucket_type;
+  typedef typename HashEntryTy::key_type key_type;
+
+  typedef HashIterator<ChainIteratorBase<BaseTy>,
+                       NonConstTraits<HashEntryTy> > chain_iterator;
+  typedef HashIterator<ChainIteratorBase<const BaseTy>,
+                       ConstTraits<HashEntryTy> >    const_chain_iterator;
+
+  typedef HashIterator<EntryIteratorBase<BaseTy>,
+                       NonConstTraits<HashEntryTy> > entry_iterator;
+  typedef HashIterator<EntryIteratorBase<const BaseTy>,
+                       ConstTraits<HashEntryTy> >    const_entry_iterator;
+
+  typedef entry_iterator                             iterator;
+  typedef const_entry_iterator                       const_iterator;
+
+public:
+  // -----  constructor  ----- //
+  explicit HashTable(size_type pSize=3);
+  ~HashTable();
+  
+  EntryFactoryTy& getEntryFactory()
+  { return m_EntryFactory; }
+
+  // -----  modifiers  ----- //
+  void clear();
+
+  /// insert - insert a new element to the container. The element is
+  //  constructed in-place, i.e. no copy or move operations are performed.
+  //  If the element already exists, return the element, and set pExist true.
+  entry_type* insert(const key_type& pKey, bool& pExist);
+
+  /// erase - remove the element with the same key
+  size_type erase(const key_type& pKey);
+
+  // -----  lookups  ----- //
+  /// find - finds an element with key pKey
+  //  If the element does not exist, return end()
+  iterator find(const key_type& pKey);
+
+  /// find - finds an element with key pKey, constant version
+  //  If the element does not exist, return end()
+  const_iterator find(const key_type& pKey) const;
+
+  size_type count(const key_type& pKey) const;
+  
+  // -----  hash policy  ----- //
+  float load_factor() const;
+
+  /// rehash - if the load factor is larger than 75%, or the empty buckets is
+  //  less than 12.5%, the rehash the hash table
+  void rehash();
+
+  /// rehash - immediately re-new the hash table to the size pCount, and
+  //  rehash all elements.
+  void rehash(size_type pCount);
+
+  // -----  iterators  ----- //
+  iterator begin();
+  iterator end();
+
+  const_entry_iterator begin() const;
+  const_entry_iterator end() const;
+
+  chain_iterator begin(const key_type& pKey);
+  chain_iterator end(const key_type& pKey);
+  const_chain_iterator begin(const key_type& pKey) const;
+  const_chain_iterator end(const key_type& pKey) const;
+
+private:
+  EntryFactoryTy m_EntryFactory;
+
+};
+
+#include "HashTable.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashTable.tcc b/include/mcld/ADT/HashTable.tcc
new file mode 100644
index 0000000..6fb05a3
--- /dev/null
+++ b/include/mcld/ADT/HashTable.tcc
@@ -0,0 +1,268 @@
+//===- HashTable.tcc ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashTable
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::HashTable(size_type pSize)
+  : HashTableImpl<HashEntryTy, HashFunctionTy>(pSize), m_EntryFactory()
+{
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::~HashTable()
+{
+  if (BaseTy::empty())
+    return;
+
+  /** clean up **/
+  for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
+    if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry &&
+        bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
+      m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
+    }
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::clear()
+{
+  if (BaseTy::empty())
+    return;
+
+  /** clean up **/
+  for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
+    if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry ) {
+      if (bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
+        m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
+      }
+      BaseTy::m_Buckets[i].Entry = bucket_type::getEmptyBucket();
+    }
+  }
+  BaseTy::m_NumOfEntries = 0;
+  BaseTy::m_NumOfTombstones = 0;
+}
+
+/// insert - insert a new element to the container. If the element already
+//  exist, return the element.
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::entry_type*
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::insert(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey,
+  bool& pExist)
+{
+  unsigned int index = BaseTy::lookUpBucketFor(pKey);
+  bucket_type& bucket = BaseTy::m_Buckets[index];
+  entry_type* entry = bucket.Entry;
+  if (bucket_type::getEmptyBucket() != entry &&
+      bucket_type::getTombstone() != entry) {
+    // Already exist in the table
+    pExist = true;
+    return entry;
+  }
+
+  // find a tombstone
+  if (bucket_type::getTombstone() == entry)
+    --BaseTy::m_NumOfTombstones;
+
+  entry = bucket.Entry = m_EntryFactory.produce(pKey);
+  ++BaseTy::m_NumOfEntries;
+  BaseTy::mayRehash();
+  pExist = false;
+  return entry;
+}
+
+/// erase - remove the elements with the pKey
+//  @return the number of removed elements.
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::erase(
+        const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return 0;
+
+  bucket_type& bucket = BaseTy::m_Buckets[index];
+  m_EntryFactory.destroy(bucket.Entry);
+  bucket.Entry = bucket_type::getTombstone();
+
+  --BaseTy::m_NumOfEntries;
+  ++BaseTy::m_NumOfTombstones;
+  BaseTy::mayRehash();
+  return 1;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return end();
+  return iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return end();
+  return const_iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::count(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  const_chain_iterator bucket, bEnd = end(pKey);
+  size_type count = 0;
+  for (bucket = begin(pKey); bucket != bEnd; ++bucket)
+    ++count;
+  return count;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+float HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::load_factor() const
+{
+  return ((float)BaseTy::m_NumOfEntries/(float)BaseTy::m_NumOfBuckets);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash()
+{
+  BaseTy::mayRehash();
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash(
+       typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type pCount)
+{
+  BaseTy::doRehash(pCount);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin()
+{
+  if (BaseTy::empty())
+    return iterator(this, 0);
+  unsigned int index = 0;
+  while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
+         bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
+    ++index;
+  }
+  return iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end()
+{
+  return iterator(NULL, 0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin() const
+{
+  if (BaseTy::empty())
+    return const_iterator(this, 0);
+  unsigned int index = 0;
+  while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
+         bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
+    ++index;
+  }
+  return const_iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end() const
+{
+  return const_iterator(NULL, 0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
+    const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  return chain_iterator(this, pKey, 0x0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
+    const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  return chain_iterator();
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  return const_chain_iterator(this, pKey, 0x0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  return const_chain_iterator();
+}
+
diff --git a/include/mcld/ADT/SizeTraits.h b/include/mcld/ADT/SizeTraits.h
new file mode 100644
index 0000000..8d307bd
--- /dev/null
+++ b/include/mcld/ADT/SizeTraits.h
@@ -0,0 +1,102 @@
+//===- SizeTraits.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SIZE_TRAITS_H
+#define MCLD_SIZE_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+
+namespace mcld
+{
+
+template<size_t SIZE>
+struct SizeTraits;
+
+template<>
+class SizeTraits<32>
+{
+  typedef uint32_t Address;
+  typedef uint32_t Offset;
+  typedef uint32_t Word;
+  typedef int32_t  SWord;
+};
+
+template<>
+class SizeTraits<64>
+{
+  typedef uint64_t Address;
+  typedef uint64_t Offset;
+  typedef uint64_t Word;
+  typedef int64_t  SWord;
+};
+
+/// alignAddress - helper function to align an address with given alignment
+/// constraint
+///
+/// @param pAddr - the address to be aligned
+/// @param pAlignConstraint - the alignment used to align the given address
+inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint)
+{
+  if (pAlignConstraint != 0)
+    pAddr = (pAddr + pAlignConstraint - 1) &~ (pAlignConstraint - 1);
+}
+
+template<size_t Constraint>
+uint64_t Align(uint64_t pAddress);
+
+template<>
+inline uint64_t Align<32>(uint64_t pAddress)
+{
+  return (pAddress + 0x1F) & (~0x1F);
+}
+
+template<>
+inline uint64_t Align<64>(uint64_t pAddress)
+{
+  return (pAddress + 0x3F) & (~0x3F);
+}
+
+/// bswap16 - byte swap 16-bit version
+/// @ref binary utilities - elfcpp_swap
+inline uint16_t bswap16(uint16_t pData)
+{
+   return ((pData >> 8) & 0xFF) | ((pData & 0xFF) << 8);
+}
+
+/// bswap32 - byte swap 32-bit version
+/// @ref elfcpp_swap
+inline uint32_t bswap32(uint32_t pData)
+{
+   return (((pData & 0xFF000000) >> 24) |
+           ((pData & 0x00FF0000) >>  8) |
+           ((pData & 0x0000FF00) <<  8) |
+           ((pData & 0x000000FF) << 24));
+
+}
+
+/// bswap64 - byte swap 64-bit version
+/// @ref binary utilities - elfcpp_swap
+inline uint64_t bswap64(uint64_t pData)
+{
+   return (((pData & 0xFF00000000000000ULL) >> 56) |
+           ((pData & 0x00FF000000000000ULL) >> 40) |
+           ((pData & 0x0000FF0000000000ULL) >> 24) |
+           ((pData & 0x000000FF00000000ULL) >>  8) |
+           ((pData & 0x00000000FF000000ULL) <<  8) |
+           ((pData & 0x0000000000FF0000ULL) << 24) |
+           ((pData & 0x000000000000FF00ULL) << 40) |
+           ((pData & 0x00000000000000FFULL) << 56));
+}
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/StringHash.h b/include/mcld/ADT/StringHash.h
new file mode 100644
index 0000000..f100a49
--- /dev/null
+++ b/include/mcld/ADT/StringHash.h
@@ -0,0 +1,289 @@
+//===- StringHash.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_STRING_HASH_FUNCTION_H
+#define MCLD_STRING_HASH_FUNCTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <functional>
+
+namespace mcld
+{
+
+enum StringHashType
+{
+  RS,
+  JS,
+  PJW,
+  ELF,
+  BKDR,
+  SDBM,
+  DJB,
+  DEK,
+  BP,
+  FNV,
+  AP
+};
+
+/** \class template<size_t TYPE> StringHash
+ *  \brief the template StringHash class, for specification
+ */
+template<size_t TYPE>
+struct StringHash : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    llvm::report_fatal_error("Undefined StringHash function.\n");
+  }
+};
+
+/** \class StringHash<RSHash>
+ *  \brief RS StringHash funciton
+ */
+template<>
+struct StringHash<RS> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const unsigned int b = 378551;
+    size_t a = 63689;
+    size_t hash_val = 0;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = hash_val * a + pKey[i];
+      a = a * b;
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<JSHash>
+ *  \brief JS hash funciton
+ */
+template<>
+struct StringHash<JS> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 1315423911;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+       hash_val ^= ((hash_val << 5) + pKey[i] + (hash_val >> 2));
+    } 
+    return hash_val;
+  }
+};
+
+/** \class StringHash<PJW>
+ *  \brief P.J. Weinberger hash function
+ */
+template<>
+struct StringHash<PJW> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
+    const unsigned int ThreeQuarters     = (unsigned int)((BitsInUnsignedInt  * 3) / 4);
+    const unsigned int OneEighth         = (unsigned int)(BitsInUnsignedInt / 8);
+    const unsigned int HighBits          = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
+    size_t hash_val = 0;
+    size_t test = 0;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = (hash_val << OneEighth) + pKey[i];
+
+      if((test = hash_val & HighBits) != 0) {
+        hash_val = (( hash_val ^ (test >> ThreeQuarters)) & (~HighBits));
+      }
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<ELF>
+ *  \brief ELF hash function.
+ */
+template<>
+struct StringHash<ELF> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+    size_t x = 0;
+
+    for (unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = (hash_val << 4) + pKey[i];
+      if((x = hash_val & 0xF0000000L) != 0)
+        hash_val ^= (x >> 24); 
+      hash_val &= ~x;
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<BKDR>
+ *  \brief BKDR hash function
+ */
+template<>
+struct StringHash<BKDR> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const size_t seed = 131;
+    size_t hash_val = 0;
+      
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = (hash_val * seed) + pKey[i];
+    return hash_val;
+  }
+};
+
+
+/** \class StringHash<SDBM>
+ *  \brief SDBM hash function
+ *  0.049s in 100000 test
+ */
+template<>
+struct StringHash<SDBM> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = pKey[i] + (hash_val << 6) + (hash_val << 16) - hash_val;
+    return hash_val;
+  }
+};
+
+/** \class StringHash<DJB>
+ *  \brief DJB hash function
+ *  0.057s in 100000 test
+ */
+template<>
+struct StringHash<DJB> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 5381;
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = ((hash_val << 5) + hash_val) + pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<DEK>
+ *  \brief DEK hash function
+ *  0.60s
+ */
+template<>
+struct StringHash<DEK> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = pKey.size();
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = ((hash_val << 5) ^ (hash_val >> 27)) ^ pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<BP>
+ *  \brief BP hash function
+ *  0.057s
+ */
+template<>
+struct StringHash<BP> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = hash_val << 7 ^ pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<FNV>
+ *  \brief FNV hash function
+ *  0.058s
+ */
+template<>
+struct StringHash<FNV> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const size_t fnv_prime = 0x811C9DC5;
+    size_t hash_val = 0;
+    for(size_t i = 0; i < pKey.size(); ++i) {
+      hash_val *= fnv_prime;
+      hash_val ^= pKey[i];
+    }
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<AP>
+ *  \brief AP hash function
+ *  0.060s
+ */
+template<>
+struct StringHash<AP> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    unsigned int hash_val = 0xAAAAAAAA;
+   
+    for(size_t i = 0; i < pKey.size(); ++i) {  
+      hash_val ^= ((i & 1) == 0)?
+                          ((hash_val <<  7) ^ pKey[i] * (hash_val >> 3)):
+                          (~((hash_val << 11) + (pKey[i] ^ (hash_val >> 5))));
+    }
+   
+    return hash_val;
+  }
+};
+
+/** \class template<size_t TYPE> StringCompare
+ *  \brief the template StringCompare class, for specification
+ */
+template<typename STRING_TYPE>
+struct StringCompare : public std::binary_function<const STRING_TYPE&, const STRING_TYPE&, bool>
+{
+  bool operator()(const STRING_TYPE& X, const STRING_TYPE& Y) const
+  { return X == Y; }
+};
+
+template<>
+struct StringCompare<const char*> : public std::binary_function<const char*, const char*, bool>
+{
+  bool operator()(const char* X, const char* Y) const
+  { return (0 == std::strcmp(X, Y)); }
+};
+
+template<>
+struct StringCompare<char*> : public std::binary_function<const char*, const char*, bool>
+{
+  bool operator()(const char* X, const char* Y) const
+  { return (0 == std::strcmp(X, Y)); }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TreeAllocator.h b/include/mcld/ADT/TreeAllocator.h
new file mode 100644
index 0000000..899896c
--- /dev/null
+++ b/include/mcld/ADT/TreeAllocator.h
@@ -0,0 +1,98 @@
+//===- TreeAllocator.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TREE_ALLOCATOR_H
+#define MCLD_TREE_ALLOCATOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <set>
+#include "mcld/Support/GCFactory.h"
+#include "mcld/ADT/TreeBase.h"
+
+namespace mcld
+{
+
+/** \class NodeFactory
+ *  \brief NodeFactory manages the creation and destruction of mcld::Node.
+ *
+ *  NodeFactory guarantees all allocated memory are released finally. When
+ *  the destructor of NodeFactory is called, all allocated memory are freed.
+ *
+ *  NodeFactory provides delegation of memory. Sometimes, we have to merge two
+ *  NodeFactories, and NodeFactory::delegate() can move the memory from one
+ *  NodeFactories to another.
+ *  
+ *  @see LinearAllocator
+ */
+template<typename DataType>
+class NodeFactory : public GCFactory<Node<DataType>, 64>
+{
+private:
+  typedef GCFactory<Node<DataType>, 64> Alloc;
+
+public:
+  typedef Node<DataType>                 NodeType;
+  typedef typename Alloc::iterator       iterator;
+  typedef typename Alloc::const_iterator const_iterator;
+
+public:
+  /// produce - produce a node, add it under control
+  NodeType* produce() {
+    NodeType* result = Alloc::allocate();
+    Alloc::construct(result);
+    return result;
+  }
+
+  /// delegate - get the control of chunks owned by the client
+  //  after calling delegate(), client will renouce its control
+  //  of memory space.
+  void delegate(NodeFactory& pClient) {
+    if (this == &pClient)
+      return;
+
+    if (pClient.empty())
+      return;
+
+    if (Alloc::empty()) {
+      replace(pClient);
+      pClient.renounce();
+      return;
+    }
+
+    // neither me nor client is empty
+    concatenate(pClient);
+    pClient.renounce();
+  }
+
+private:
+  /// renounce - give up the control of all chunks
+  void renounce()
+  { Alloc::reset(); }
+
+  /// replace - be the agent of client.
+  void replace(NodeFactory& pClient) {
+    Alloc::m_pRoot = pClient.Alloc::m_pRoot;
+    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
+    Alloc::m_AllocatedNum = pClient.Alloc::m_AllocatedNum;
+    Alloc::m_NumAllocData = pClient.Alloc::m_NumAllocData;
+  }
+
+  /// concatenate - conncet two factories
+  void concatenate(NodeFactory& pClient) {
+    Alloc::m_pCurrent->next = pClient.Alloc::m_pRoot;
+    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
+    Alloc::m_AllocatedNum += pClient.Alloc::m_AllocatedNum;
+    Alloc::m_NumAllocData += pClient.Alloc::m_NumAllocData;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TreeBase.h b/include/mcld/ADT/TreeBase.h
new file mode 100644
index 0000000..c518975
--- /dev/null
+++ b/include/mcld/ADT/TreeBase.h
@@ -0,0 +1,127 @@
+//===- TreeBase.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TREE_BASE_H
+#define MCLD_TREE_BASE_H
+#include "mcld/ADT/TypeTraits.h"
+
+namespace mcld
+{
+
+class NodeBase
+{
+public:
+  NodeBase *left;
+  NodeBase *right;
+
+public:
+  NodeBase()
+  : left(0), right(0)
+  { }
+};
+
+namespace proxy
+{
+  template<size_t DIRECT>
+  inline void move(NodeBase *&X)
+  { assert(0 && "not allowed"); }
+
+  template<size_t DIRECT>
+  inline void hook(NodeBase *X, const NodeBase *Y)
+  { assert(0 && "not allowed"); }
+
+} // namespace of template proxy
+
+struct TreeIteratorBase
+{
+public:
+  enum Direct {
+    Leftward,
+    Rightward
+  };
+
+  typedef size_t                          size_type;
+  typedef ptrdiff_t                       difference_type;
+  typedef std::bidirectional_iterator_tag iterator_category;
+
+public:
+  NodeBase* m_pNode;
+
+public:
+  TreeIteratorBase()
+  : m_pNode(0)
+  { }
+
+  TreeIteratorBase(NodeBase *X)
+  : m_pNode(X)
+  { }
+
+  virtual ~TreeIteratorBase(){};
+
+  template<size_t DIRECT>
+  inline void move() {
+    proxy::move<DIRECT>(m_pNode);
+  }
+
+  bool hasRightChild() const
+  { return ((m_pNode->right) != (m_pNode->right->right)); }
+
+  bool hasLeftChild() const
+  { return ((m_pNode->left) != (m_pNode->left->right)); }
+
+  bool operator==(const TreeIteratorBase& y) const
+  { return this->m_pNode == y.m_pNode; }
+
+  bool operator!=(const TreeIteratorBase& y) const
+  { return this->m_pNode != y.m_pNode; }
+};
+
+namespace proxy
+{
+  template<>
+  inline void move<TreeIteratorBase::Leftward>(NodeBase *&X) 
+  { X = X->left; }
+
+  template<>
+  inline void move<TreeIteratorBase::Rightward>(NodeBase *&X)
+  { X = X->right; }
+
+  template<>
+  inline void hook<TreeIteratorBase::Leftward>(NodeBase *X, const NodeBase *Y)
+  { X->left = const_cast<NodeBase*>(Y); }
+
+  template<>
+  inline void hook<TreeIteratorBase::Rightward>(NodeBase* X, const NodeBase* Y)
+  { X->right = const_cast<NodeBase*>(Y); }
+
+} //namespace of template proxy
+
+template<typename DataType>
+class Node : public NodeBase
+{
+public:
+  typedef DataType        value_type;
+
+public:
+  value_type* data;
+
+public:
+  Node()
+  : NodeBase(), data(0)
+  { }
+
+  Node(const value_type& pValue)
+  : NodeBase(), data(&pValue)
+  { }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TypeTraits.h b/include/mcld/ADT/TypeTraits.h
new file mode 100644
index 0000000..90b2224
--- /dev/null
+++ b/include/mcld/ADT/TypeTraits.h
@@ -0,0 +1,71 @@
+//===- TypeTraits.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TYPE_TRAITS_H
+#define MCLD_TYPE_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <cstdlib>
+
+namespace mcld
+{
+template<typename DataType>
+struct NonConstTraits;
+
+template<typename DataType>
+struct ConstTraits
+{
+  typedef DataType                 value_type;
+  typedef const DataType*          pointer;
+  typedef const DataType&          reference;
+  typedef size_t                   size_type;
+  typedef ConstTraits<DataType>    const_traits;
+  typedef NonConstTraits<DataType> nonconst_traits;
+};
+
+template<typename DataType>
+struct NonConstTraits
+{
+  typedef DataType                 value_type;
+  typedef DataType*                pointer;
+  typedef DataType&                reference;
+  typedef size_t                   size_type;
+  typedef ConstTraits<DataType>    const_traits;
+  typedef NonConstTraits<DataType> nonconst_traits;
+};
+
+template<typename DataType>
+struct ConstIteratorTraits
+{
+  typedef DataType                          value_type;
+  typedef const DataType*                   pointer;
+  typedef const DataType&                   reference;
+  typedef size_t                            size_type;
+  typedef ConstTraits<DataType>             const_traits;
+  typedef NonConstTraits<DataType>          nonconst_traits;
+  typedef typename DataType::const_iterator iterator;
+};
+
+template<typename DataType>
+struct NonConstIteratorTraits
+{
+  typedef DataType                    value_type;
+  typedef DataType*                   pointer;
+  typedef DataType&                   reference;
+  typedef size_t                      size_type;
+  typedef ConstTraits<DataType>       const_traits;
+  typedef NonConstTraits<DataType>    nonconst_traits;
+  typedef typename DataType::iterator iterator;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/Uncopyable.h b/include/mcld/ADT/Uncopyable.h
new file mode 100644
index 0000000..7ddfbe3
--- /dev/null
+++ b/include/mcld/ADT/Uncopyable.h
@@ -0,0 +1,36 @@
+//===- Uncopyable.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNCOPYABLE_H
+#define MCLD_UNCOPYABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class Uncopyable
+ *  \brief Uncopyable provides the base class to forbit copy operations.
+ *
+ */
+class Uncopyable
+{
+protected:
+  Uncopyable() { }
+  ~Uncopyable() { }
+
+private:
+  Uncopyable(const Uncopyable&); /// NOT TO IMPLEMENT
+  Uncopyable& operator=(const Uncopyable&); /// NOT TO IMPLEMENT
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/CodeGen/SectLinker.h b/include/mcld/CodeGen/SectLinker.h
new file mode 100644
index 0000000..31fae4a
--- /dev/null
+++ b/include/mcld/CodeGen/SectLinker.h
@@ -0,0 +1,107 @@
+//===- SectLinker.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//SectLinker is a base class inherited by target specific linker.
+//This class primarily handles common functionality used by all linkers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SECTION_LINKER_H
+#define SECTION_LINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/CodeGen/MachineFunctionPass.h>
+#include <mcld/Support/PositionDependentOption.h>
+#include <vector>
+
+namespace llvm
+{
+  class Module;
+  class MachineFunction;
+} // namespace of llvm
+
+namespace mcld
+{
+  class MCLDFile;
+  class MCLDDriver;
+  class TargetLDBackend;
+  class AttributeFactory;
+  class SectLinkerOption;
+
+  /** \class SectLinker
+   *  \brief SectLinker provides a linking pass for standard compilation flow
+   *
+   *  SectLinker is responded for
+   *  - provide an interface for target-specific SectLinekr
+   *  - set up environment for MCLDDriver
+   *  - control AsmPrinter, make sure AsmPrinter has already prepared
+   *    all MCSectionDatas for linking
+   *
+   *  SectLinker resolves the absolue paths of input arguments.
+   *
+   *  @see MachineFunctionPass MCLDDriver
+   */
+  class SectLinker : public llvm::MachineFunctionPass
+  {
+  protected:
+    // Constructor. Although SectLinker has only two arguments,
+    // TargetSectLinker should handle
+    // - enabled attributes
+    // - the default attribute
+    // - the default link script
+    // - the standard symbols
+    SectLinker(SectLinkerOption &pOption,
+               TargetLDBackend &pLDBackend);
+
+  public:
+    virtual ~SectLinker();
+
+    /// addTargetOptions - target SectLinker can hook this function to add
+    /// target-specific inputs
+    virtual void addTargetOptions(llvm::Module &pM,
+                                  SectLinkerOption &pOption)
+    { }
+
+    /// doInitialization - Read all parameters and set up the AsmPrinter.
+    /// If your pass overrides this, it must make sure to explicitly call
+    /// this implementation.
+    virtual bool doInitialization(llvm::Module &pM);
+
+    /// doFinalization - Shut down the AsmPrinter, and do really linking.
+    /// If you override this in your pass, you must make sure to call it
+    /// explicitly.
+    virtual bool doFinalization(llvm::Module &pM);
+
+    /// runOnMachineFunction
+    /// redirect to AsmPrinter
+    virtual bool runOnMachineFunction(llvm::MachineFunction& pMFn);
+
+  protected:
+    void initializeInputTree(const PositionDependentOptions &pOptions) const;
+
+    AttributeFactory* attrFactory()
+    { return m_pAttrFactory; }
+
+  private:
+    SectLinkerOption *m_pOption;
+
+  protected:
+    TargetLDBackend *m_pLDBackend;
+    MCLDDriver *m_pLDDriver;
+    AttributeFactory *m_pAttrFactory;
+
+  private:
+    static char m_ID;
+  };
+
+} // namespace of MC Linker
+
+#endif
+
diff --git a/include/mcld/CodeGen/SectLinkerOption.h b/include/mcld/CodeGen/SectLinkerOption.h
new file mode 100644
index 0000000..b3e3327
--- /dev/null
+++ b/include/mcld/CodeGen/SectLinkerOption.h
@@ -0,0 +1,57 @@
+//===- SectLinkerOption.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTLINKERDATA_H
+#define MCLD_SECTLINKERDATA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/MC/MCLDInfo.h"
+#include "mcld/Support/PositionDependentOption.h"
+
+#include <string>
+
+namespace mcld
+{
+  class PositionDependentOption;
+
+  /** \class SectLinkerOption
+   *  \brief This file collects inputs to linker.
+   */
+  class SectLinkerOption
+  {
+  public:
+    // Constructor.
+    SectLinkerOption(MCLDInfo &pLDInfo);
+
+    // -----  Position-dependent Options  ----- //
+    inline void appendOption(PositionDependentOption *pOption)
+    { m_PosDepOptions.push_back(pOption); }
+
+    inline void prependOption(PositionDependentOption *pOption)
+    { m_PosDepOptions.insert(m_PosDepOptions.begin(), pOption); }
+
+    inline const PositionDependentOptions &pos_dep_options() const
+    { return m_PosDepOptions; }
+    inline PositionDependentOptions &pos_dep_options()
+    { return m_PosDepOptions; }
+
+    inline const MCLDInfo &info() const { return *m_pLDInfo; }
+    inline MCLDInfo &info() { return *m_pLDInfo; }
+
+    ~SectLinkerOption();
+
+  private:
+    MCLDInfo *m_pLDInfo;
+    PositionDependentOptions m_PosDepOptions;
+  };
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Config/Config.h b/include/mcld/Config/Config.h
new file mode 100644
index 0000000..362b076
--- /dev/null
+++ b/include/mcld/Config/Config.h
@@ -0,0 +1,26 @@
+//===- Config.h.in --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_CONFIG_H
+#define MCLD_CONFIG_H
+
+namespace mcld {
+namespace internal {
+
+static const char* version="0.2.10.1-18peaks";
+
+} // namespace of internal
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Config/Config.h.in b/include/mcld/Config/Config.h.in
new file mode 100644
index 0000000..6d428c0
--- /dev/null
+++ b/include/mcld/Config/Config.h.in
@@ -0,0 +1,21 @@
+//===- Config.h.in --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_CONFIG_H
+#define MCLD_CONFIG_H
+
+namespace mcld {
+namespace internal {
+
+static const char* version="@MCLD_VERSION@";
+
+} // namespace of internal
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Config/Linkers.def b/include/mcld/Config/Linkers.def
new file mode 100644
index 0000000..2781461
--- /dev/null
+++ b/include/mcld/Config/Linkers.def
@@ -0,0 +1,33 @@
+//===- llvm/Config/Linkers.def - LLVM Linkers -------------------*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the linkers supported by this build of LLVM.
+// Clients of this file should define the LLVM_LINKER macro to be a function-like
+// macro with a single parameter (the name of the target whose exe/dso can be
+// generated); including this file will then enumerate all of the targets with
+// linkers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER
+#  error Please define the macro LLVM_LINKER(TargetName)
+#endif
+
+#define LLVM_TARGET LLVM_LINKER
+#include <llvm/Config/Targets.def>
+
+#undef LLVM_LINKER
diff --git a/include/mcld/Config/Linkers.def.in b/include/mcld/Config/Linkers.def.in
new file mode 100644
index 0000000..0e09040
--- /dev/null
+++ b/include/mcld/Config/Linkers.def.in
@@ -0,0 +1,28 @@
+//===- llvm/Config/Linkers.def - LLVM Linkers -------------------*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the linkers supported by this build of LLVM. 
+// Clients of this file should define the LLVM_LINKER macro to be a function-like 
+// macro with a single parameter (the name of the target whose exe/dso can be
+// generated); including this file will then enumerate all of the targets with
+// linkers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER
+#  error Please define the macro LLVM_LINKER(TargetName)
+#endif
+
+@LLVM_ENUM_LINKERS@
+
+#undef LLVM_LINKER
diff --git a/include/mcld/Config/Targets.def b/include/mcld/Config/Targets.def
new file mode 100644
index 0000000..a0981d6
--- /dev/null
+++ b/include/mcld/Config/Targets.def
@@ -0,0 +1,32 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The MCLinker Project                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the target architectures supported by          *|
+|* this build of LLVM. Clients of this file should define the                 *|
+|* LLVM_TARGET macro to be a function-like macro with a single                *|
+|* parameter (the name of the target); including this file will then          *|
+|* enumerate all of the targets.                                              *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET
+#  error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+#include <llvm/Config/Targets.def>
+
+#undef LLVM_TARGET
diff --git a/include/mcld/Config/Targets.def.in b/include/mcld/Config/Targets.def.in
new file mode 100644
index 0000000..a73b9b7
--- /dev/null
+++ b/include/mcld/Config/Targets.def.in
@@ -0,0 +1,28 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The MCLinker Project                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the target architectures supported by          *|
+|* this build of LLVM. Clients of this file should define the                 *|
+|* LLVM_TARGET macro to be a function-like macro with a single                *|
+|* parameter (the name of the target); including this file will then          *|
+|* enumerate all of the targets.                                              *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_TARGET
+#  error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+@LLVM_ENUM_TARGETS@
+
+#undef LLVM_TARGET
diff --git a/include/mcld/LD/ArchiveReader.h b/include/mcld/LD/ArchiveReader.h
new file mode 100644
index 0000000..99db0db
--- /dev/null
+++ b/include/mcld/LD/ArchiveReader.h
@@ -0,0 +1,39 @@
+//===- ArchiveReader.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARCHIVE_READER_INTERFACE_H
+#define MCLD_ARCHIVE_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+
+namespace mcld
+{
+
+class Input;
+class InputTree;
+
+/** \class ArchiveReader
+ *  \brief ArchiveReader provides an common interface for all archive readers.
+ *
+ *  ArchiveReader also reads the target-independent parts of an archive file.
+ */
+class ArchiveReader : public LDReader
+{
+public:
+  ArchiveReader();
+  virtual ~ArchiveReader();
+
+  virtual InputTree *readArchive(Input &input) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/BSDArchiveReader.h b/include/mcld/LD/BSDArchiveReader.h
new file mode 100644
index 0000000..a275621
--- /dev/null
+++ b/include/mcld/LD/BSDArchiveReader.h
@@ -0,0 +1,39 @@
+//===- BSDArchiveReader.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BSD_ARCHIVE_READER_H
+#define MCLD_BSD_ARCHIVE_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/ArchiveReader.h"
+
+namespace mcld
+{
+
+class Input;
+class InputTree;
+
+/** \class BSDArchiveReader
+ *  \brief BSDArchiveReader reads BSD-variant archive files.
+ *
+ */
+class BSDArchiveReader : public ArchiveReader
+{
+public:
+  BSDArchiveReader();
+  ~BSDArchiveReader();
+
+  InputTree *readArchive(Input &input);
+  bool isMyFormat(Input& pInput) const;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/BranchIsland.h b/include/mcld/LD/BranchIsland.h
new file mode 100644
index 0000000..8e5cf9c
--- /dev/null
+++ b/include/mcld/LD/BranchIsland.h
@@ -0,0 +1,30 @@
+//===- BranchIsland.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef BRANCHISLAND_H
+#define BRANCHISLAND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class BranchIsland
+ *  \brief BranchIsland is a collection of stubs
+ *
+ */
+class BranchIsland
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjFileFormat.h b/include/mcld/LD/DynObjFileFormat.h
new file mode 100644
index 0000000..7b1626d
--- /dev/null
+++ b/include/mcld/LD/DynObjFileFormat.h
@@ -0,0 +1,29 @@
+//===- header.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DYNOBJFORMAT_H
+#define DYNOBJFORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class DynObjFormat
+ *  \brief DynObjFormat describes the file format for dynamic objects.
+ */
+class DynObjFormat : public LDFileFormat
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjReader.h b/include/mcld/LD/DynObjReader.h
new file mode 100644
index 0000000..0900109
--- /dev/null
+++ b/include/mcld/LD/DynObjReader.h
@@ -0,0 +1,45 @@
+//===- DynObjReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DYNAMIC_SHARED_OBJECT_READER_H
+#define MCLD_DYNAMIC_SHARED_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class TargetLDBackend;
+class Input;
+
+/** \class DynObjReader
+ *  \brief DynObjReader provides an common interface for different object
+ *  formats.
+ */
+class DynObjReader : public LDReader
+{
+protected:
+  DynObjReader()
+  { }
+
+public:
+  virtual ~DynObjReader() { }
+
+  virtual bool readDSO(Input& pFile) = 0;
+
+  virtual bool readSymbols(Input& pFile) = 0;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjWriter.h b/include/mcld/LD/DynObjWriter.h
new file mode 100644
index 0000000..1c77bd4
--- /dev/null
+++ b/include/mcld/LD/DynObjWriter.h
@@ -0,0 +1,41 @@
+//===- DynObjWriter.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DYNAMIC_SHARED_OBJECT_WRITER_H
+#define MCLD_DYNAMIC_SHARED_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/LD/LDWriter.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+/** \class DynObjWriter
+ *  \brief DynObjWriter provides an common interface for different object
+ *  formats.
+ */
+class DynObjWriter : public LDWriter
+{
+protected:
+  // force to have a TargetLDBackend
+  DynObjWriter(TargetLDBackend& pLDBackend)
+  { }
+
+public:
+  virtual ~DynObjWriter() { }
+
+  virtual llvm::error_code writeDynObj(Output& pOutput) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjFileFormat.h b/include/mcld/LD/ELFDynObjFileFormat.h
new file mode 100644
index 0000000..9b77e91
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjFileFormat.h
@@ -0,0 +1,38 @@
+//===- ELFDynObjFileFormat.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
+#define MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/ELFFileFormat.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFDynObjFileFormat
+ *  \brief ELFDynObjFileFormat describes the format for ELF dynamic objects.
+ */
+class ELFDynObjFileFormat : public ELFFileFormat
+{
+public:
+  ELFDynObjFileFormat(GNULDBackend& pBackend) : ELFFileFormat(pBackend)
+  {}
+
+  void initObjectType(MCLinker& pLinker);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjReader.h b/include/mcld/LD/ELFDynObjReader.h
new file mode 100644
index 0000000..72a3336
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjReader.h
@@ -0,0 +1,51 @@
+//===- ELFDynObjReader.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
+#define MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/DynObjReader.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+class ELFReaderIF;
+
+/** \class ELFDynObjReader
+ *  \brief ELFDynObjReader reads ELF dynamic shared objects.
+ *
+ */
+class ELFDynObjReader : public DynObjReader
+{
+public:
+  ELFDynObjReader(GNULDBackend& pBackend, MCLinker& pLinker);
+  ~ELFDynObjReader();
+
+  // -----  observers  ----- //
+  bool isMyFormat(Input &pFile) const;
+
+  // -----  readers  ----- //
+  bool readDSO(Input& pFile);
+
+  bool readSymbols(Input& pInput);
+
+private:
+  ELFReaderIF *m_pELFReader;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjWriter.h b/include/mcld/LD/ELFDynObjWriter.h
new file mode 100644
index 0000000..dc0e37b
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjWriter.h
@@ -0,0 +1,53 @@
+//===- ELFDynObjWriter.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SHARED_OBJECT_WRITER_H
+#define MCLD_ELF_DYNAMIC_SHARED_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/DenseMap.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/LD/DynObjWriter.h>
+#include <mcld/LD/ELFWriter.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/Support/MemoryArea.h>
+#include <vector>
+#include <utility>
+
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFDynObjWriter
+ *  \brief ELFDynObjWriter writes the dynamic sections.
+ */
+class ELFDynObjWriter : public DynObjWriter, private ELFWriter
+{
+public:
+  typedef ELFWriter::FileOffset FileOffset;
+
+public:
+  ELFDynObjWriter(GNULDBackend& pBackend, MCLinker& pLinker);
+  ~ELFDynObjWriter();
+
+  llvm::error_code writeDynObj(Output& pOutput);
+
+private:
+  GNULDBackend& m_Backend;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFExecFileFormat.h b/include/mcld/LD/ELFExecFileFormat.h
new file mode 100644
index 0000000..315300a
--- /dev/null
+++ b/include/mcld/LD/ELFExecFileFormat.h
@@ -0,0 +1,38 @@
+//===- ELFExecFileFormat.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_EXEC_FILE_FORMAT_H
+#define MCLD_ELF_EXEC_FILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/ELFFileFormat.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFExecFileFormat
+ *  \brief ELFExecFileFormat describes the format for ELF dynamic objects.
+ */
+class ELFExecFileFormat : public ELFFileFormat
+{
+public:
+  ELFExecFileFormat(GNULDBackend& pBackend) : ELFFileFormat(pBackend)
+  {}
+
+  void initObjectType(MCLinker& pLinker)
+  { /** TODO **/ }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFFileFormat.h b/include/mcld/LD/ELFFileFormat.h
new file mode 100644
index 0000000..94d3df3
--- /dev/null
+++ b/include/mcld/LD/ELFFileFormat.h
@@ -0,0 +1,654 @@
+//===- LDFileFormat.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_FILE_FORMAT_H
+#define MCLD_ELF_FILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDSection.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFFileFormat
+ *  \brief ELFFileFormat describes the common file formats in ELF.
+ *  LDFileFormats control the formats of the output file.
+ *
+ *  @ref "Object Files," Ch. 4, in System V Application Binary Interface,
+ *  Fourth Edition.
+ *
+ *  @ref "Object Format," Ch. 10, in ISO/IEC 23360 Part 1:2010(E), Linux
+ *  Standard Base Core Specification 4.1.
+ */
+class ELFFileFormat : public LDFileFormat
+{
+public:
+  ELFFileFormat(GNULDBackend& pBackend);
+
+  virtual ~ELFFileFormat();
+
+  virtual void initObjectFormat(MCLinker& pLinker);
+
+  virtual void initObjectType(MCLinker& pLinker) = 0;
+
+  // -----  capacity  ----- //
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  bool hasNULLSection() const
+  { return (NULL != f_pNULLSection) && (0 != f_pNULLSection->size()); }
+
+  bool hasGOT() const
+  { return (NULL != f_pGOT) && (0 != f_pGOT->size()); }
+
+  bool hasPLT() const
+  { return (NULL != f_pPLT) && (0 != f_pPLT->size()); }
+
+  bool hasRelDyn() const
+  { return (NULL != f_pRelDyn) && (0 != f_pRelDyn->size()); }
+
+  bool hasRelPlt() const
+  { return (NULL != f_pRelPlt) && (0 != f_pRelPlt->size()); }
+
+  bool hasRelaDyn() const
+  { return (NULL != f_pRelaDyn) && (0 != f_pRelaDyn->size()); }
+
+  bool hasRelaPlt() const
+  { return (NULL != f_pRelaPlt) && (0 != f_pRelaPlt->size()); }
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  bool hasComment() const
+  { return (NULL != f_pComment) && (0 != f_pComment->size()); }
+
+  bool hasData1() const
+  { return (NULL != f_pData1) && (0 != f_pData1->size()); }
+
+  bool hasDebug() const
+  { return (NULL != f_pDebug) && (0 != f_pDebug->size()); }
+
+  bool hasDynamic() const
+  { return (NULL != f_pDynamic) && (0 != f_pDynamic->size()); }
+
+  bool hasDynStrTab() const
+  { return (NULL != f_pDynStrTab) && (0 != f_pDynStrTab->size()); }
+
+  bool hasDynSymTab() const
+  { return (NULL != f_pDynSymTab) && (0 != f_pDynSymTab->size()); }
+
+  bool hasFini() const
+  { return (NULL != f_pFini) && (0 != f_pFini->size()); }
+
+  bool hasFiniArray() const
+  { return (NULL != f_pFiniArray) && (0 != f_pFiniArray->size()); }
+
+  bool hasHashTab() const
+  { return (NULL != f_pHashTab) && (0 != f_pHashTab->size()); }
+
+  bool hasInit() const
+  { return (NULL != f_pInit) && (0 != f_pInit->size()); }
+
+  bool hasInitArray() const
+  { return (NULL != f_pInitArray) && (0 != f_pInitArray->size()); }
+
+  bool hasInterp() const
+  { return (NULL != f_pInterp) && (0 != f_pInterp->size()); }
+
+  bool hasLine() const
+  { return (NULL != f_pLine) && (0 != f_pLine->size()); }
+
+  bool hasNote() const
+  { return (NULL != f_pNote) && (0 != f_pNote->size()); }
+
+  bool hasPreInitArray() const
+  { return (NULL != f_pPreInitArray) && (0 != f_pPreInitArray->size()); }
+
+  bool hasROData1() const
+  { return (NULL != f_pROData1) && (0 != f_pROData1->size()); }
+
+  bool hasShStrTab() const
+  { return (NULL != f_pShStrTab) && (0 != f_pShStrTab->size()); }
+
+  bool hasStrTab() const
+  { return (NULL != f_pStrTab) && (0 != f_pStrTab->size()); }
+
+  bool hasSymTab() const
+  { return (NULL != f_pSymTab) && (0 != f_pSymTab->size()); }
+
+  bool hasTBSS() const
+  { return (NULL != f_pTBSS) && (0 != f_pTBSS->size()); }
+
+  bool hasTData() const
+  { return (NULL != f_pTData) && (0 != f_pTData->size()); }
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  bool hasCtors() const
+  { return (NULL != f_pCtors) && (0 != f_pCtors->size()); }
+
+  bool hasDataRelRo() const
+  { return (NULL != f_pDataRelRo) && (0 != f_pDataRelRo->size()); }
+
+  bool hasDtors() const
+  { return (NULL != f_pDtors) && (0 != f_pDtors->size()); }
+
+  bool hasEhFrame() const
+  { return (NULL != f_pEhFrame) && (0 != f_pEhFrame->size()); }
+
+  bool hasEhFrameHdr() const
+  { return (NULL != f_pEhFrameHdr) && (0 != f_pEhFrameHdr->size()); }
+
+  bool hasGCCExceptTable() const
+  { return (NULL != f_pGCCExceptTable) && (0 != f_pGCCExceptTable->size()); }
+
+  bool hasGNUVersion() const
+  { return (NULL != f_pGNUVersion) && (0 != f_pGNUVersion->size()); }
+
+  bool hasGNUVersionD() const
+  { return (NULL != f_pGNUVersionD) && (0 != f_pGNUVersionD->size()); }
+
+  bool hasGNUVersionR() const
+  { return (NULL != f_pGNUVersionR) && (0 != f_pGNUVersionR->size()); }
+
+  bool hasGOTPLT() const
+  { return (NULL != f_pGOTPLT) && (0 != f_pGOTPLT->size()); }
+
+  bool hasJCR() const
+  { return (NULL != f_pJCR) && (0 != f_pJCR->size()); }
+
+  bool hasNoteABITag() const
+  { return (NULL != f_pNoteABITag) && (0 != f_pNoteABITag->size()); }
+
+  bool hasStab() const
+  { return (NULL != f_pStab) && (0 != f_pStab->size()); }
+
+  bool hasStabStr() const
+  { return (NULL != f_pStabStr) && (0 != f_pStabStr->size()); }
+
+  // -----  access functions  ----- //
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  LDSection& getNULLSection() {
+    assert(NULL != f_pNULLSection);
+    return *f_pNULLSection;
+  }
+
+  const LDSection& getNULLSection() const {
+    assert(NULL != f_pNULLSection);
+    return *f_pNULLSection;
+  }
+
+  LDSection& getGOT() {
+    assert(NULL != f_pGOT);
+    return *f_pGOT;
+  }
+
+  const LDSection& getGOT() const {
+    assert(NULL != f_pGOT);
+    return *f_pGOT;
+  }
+
+  LDSection& getPLT() {
+    assert(NULL != f_pPLT);
+    return *f_pPLT;
+  }
+
+  const LDSection& getPLT() const {
+    assert(NULL != f_pPLT);
+    return *f_pPLT;
+  }
+
+  LDSection& getRelDyn() {
+    assert(NULL != f_pRelDyn);
+    return *f_pRelDyn;
+  }
+
+  const LDSection& getRelDyn() const {
+    assert(NULL != f_pRelDyn);
+    return *f_pRelDyn;
+  }
+
+  LDSection& getRelPlt() {
+    assert(NULL != f_pRelPlt);
+    return *f_pRelPlt;
+  }
+
+  const LDSection& getRelPlt() const {
+    assert(NULL != f_pRelPlt);
+    return *f_pRelPlt;
+  }
+
+  LDSection& getRelaDyn() {
+    assert(NULL != f_pRelaDyn);
+    return *f_pRelaDyn;
+  }
+
+  const LDSection& getRelaDyn() const {
+    assert(NULL != f_pRelaDyn);
+    return *f_pRelaDyn;
+  }
+
+  LDSection& getRelaPlt() {
+    assert(NULL != f_pRelaPlt);
+    return *f_pRelaPlt;
+  }
+
+  const LDSection& getRelaPlt() const {
+    assert(NULL != f_pRelaPlt);
+    return *f_pRelaPlt;
+  }
+
+  LDSection& getComment() {
+    assert(NULL != f_pComment);
+    return *f_pComment;
+  }
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  const LDSection& getComment() const {
+    assert(NULL != f_pComment);
+    return *f_pComment;
+  }
+
+  LDSection& getData1() {
+    assert(NULL != f_pData1);
+    return *f_pData1;
+  }
+
+  const LDSection& getData1() const {
+    assert(NULL != f_pData1);
+    return *f_pData1;
+  }
+
+  LDSection& getDebug() {
+    assert(NULL != f_pDebug);
+    return *f_pDebug;
+  }
+
+  const LDSection& getDebug() const {
+    assert(NULL != f_pDebug);
+    return *f_pDebug;
+  }
+
+  LDSection& getDynamic() {
+    assert(NULL != f_pDynamic);
+    return *f_pDynamic;
+  }
+
+  const LDSection& getDynamic() const {
+    assert(NULL != f_pDynamic);
+    return *f_pDynamic;
+  }
+
+  LDSection& getDynStrTab() {
+    assert(NULL != f_pDynStrTab);
+    return *f_pDynStrTab;
+  }
+
+  const LDSection& getDynStrTab() const {
+    assert(NULL != f_pDynStrTab);
+    return *f_pDynStrTab;
+  }
+
+  LDSection& getDynSymTab() {
+    assert(NULL != f_pDynSymTab);
+    return *f_pDynSymTab;
+  }
+
+  const LDSection& getDynSymTab() const {
+    assert(NULL != f_pDynSymTab);
+    return *f_pDynSymTab;
+  }
+
+  LDSection& getFini() {
+    assert(NULL != f_pFini);
+    return *f_pFini;
+  }
+
+  const LDSection& getFini() const {
+    assert(NULL != f_pFini);
+    return *f_pFini;
+  }
+
+  LDSection& getFiniArray() {
+    assert(NULL != f_pFiniArray);
+    return *f_pFiniArray;
+  }
+
+  const LDSection& getFiniArray() const {
+    assert(NULL != f_pFiniArray);
+    return *f_pFiniArray;
+  }
+
+  LDSection& getHashTab() {
+    assert(NULL != f_pHashTab);
+    return *f_pHashTab;
+  }
+
+  const LDSection& getHashTab() const {
+    assert(NULL != f_pHashTab);
+    return *f_pHashTab;
+  }
+
+  LDSection& getInit() {
+    assert(NULL != f_pInit);
+    return *f_pInit;
+  }
+
+  const LDSection& getInit() const {
+    assert(NULL != f_pInit);
+    return *f_pInit;
+  }
+
+  LDSection& getInitArray() {
+    assert(NULL != f_pInitArray);
+    return *f_pInitArray;
+  }
+
+  const LDSection& getInitArray() const {
+    assert(NULL != f_pInitArray);
+    return *f_pInitArray;
+  }
+
+  LDSection& getInterp() {
+    assert(NULL != f_pInterp);
+    return *f_pInterp;
+  }
+
+  const LDSection& getInterp() const {
+    assert(NULL != f_pInterp);
+    return *f_pInterp;
+  }
+
+  LDSection& getLine() {
+    assert(NULL != f_pLine);
+    return *f_pLine;
+  }
+
+  const LDSection& getLine() const {
+    assert(NULL != f_pLine);
+    return *f_pLine;
+  }
+
+  LDSection& getNote() {
+    assert(NULL != f_pNote);
+    return *f_pNote;
+  }
+
+  const LDSection& getNote() const {
+    assert(NULL != f_pNote);
+    return *f_pNote;
+  }
+
+  LDSection& getPreInitArray() {
+    assert(NULL != f_pPreInitArray);
+    return *f_pPreInitArray;
+  }
+
+  const LDSection& getPreInitArray() const {
+    assert(NULL != f_pPreInitArray);
+    return *f_pPreInitArray;
+  }
+
+  LDSection& getROData1() {
+    assert(NULL != f_pROData1);
+    return *f_pROData1;
+  }
+
+  const LDSection& getROData1() const {
+    assert(NULL != f_pROData1);
+    return *f_pROData1;
+  }
+
+  LDSection& getShStrTab() {
+    assert(NULL != f_pShStrTab);
+    return *f_pShStrTab;
+  }
+
+  const LDSection& getShStrTab() const {
+    assert(NULL != f_pShStrTab);
+    return *f_pShStrTab;
+  }
+
+  LDSection& getStrTab() {
+    assert(NULL != f_pStrTab);
+    return *f_pStrTab;
+  }
+
+  const LDSection& getStrTab() const {
+    assert(NULL != f_pStrTab);
+    return *f_pStrTab;
+  }
+
+  LDSection& getSymTab() {
+    assert(NULL != f_pSymTab);
+    return *f_pSymTab;
+  }
+
+  const LDSection& getSymTab() const {
+    assert(NULL != f_pSymTab);
+    return *f_pSymTab;
+  }
+
+  LDSection& getTBSS() {
+    assert(NULL != f_pTBSS);
+    return *f_pTBSS;
+  }
+
+  const LDSection& getTBSS() const {
+    assert(NULL != f_pTBSS);
+    return *f_pTBSS;
+  }
+
+  LDSection& getTData() {
+    assert(NULL != f_pTData);
+    return *f_pTData;
+  }
+
+  const LDSection& getTData() const {
+    assert(NULL != f_pTData);
+    return *f_pTData;
+  }
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  LDSection& getCtors() {
+    assert(NULL != f_pCtors);
+    return *f_pCtors;
+  }
+
+  const LDSection& getCtors() const {
+    assert(NULL != f_pCtors);
+    return *f_pCtors;
+  }
+
+  LDSection& getDataRelRo() {
+    assert(NULL != f_pDataRelRo);
+    return *f_pDataRelRo;
+  }
+
+  const LDSection& getDataRelRo() const {
+    assert(NULL != f_pDataRelRo);
+    return *f_pDataRelRo;
+  }
+
+  LDSection& getDtors() {
+    assert(NULL != f_pDtors);
+    return *f_pDtors;
+  }
+
+  const LDSection& getDtors() const {
+    assert(NULL != f_pDtors);
+    return *f_pDtors;
+  }
+
+  LDSection& getEhFrame() {
+    assert(NULL != f_pEhFrame);
+    return *f_pEhFrame;
+  }
+
+  const LDSection& getEhFrame() const {
+    assert(NULL != f_pEhFrame);
+    return *f_pEhFrame;
+  }
+
+  LDSection& getEhFrameHdr() {
+    assert(NULL != f_pEhFrameHdr);
+    return *f_pEhFrameHdr;
+  }
+
+  const LDSection& getEhFrameHdr() const {
+    assert(NULL != f_pEhFrameHdr);
+    return *f_pEhFrameHdr;
+  }
+
+  LDSection& getGCCExceptTable() {
+    assert(NULL != f_pGCCExceptTable);
+    return *f_pGCCExceptTable;
+  }
+
+  const LDSection& getGCCExceptTable() const {
+    assert(NULL != f_pGCCExceptTable);
+    return *f_pGCCExceptTable;
+  }
+
+  LDSection& getGNUVersion() {
+    assert(NULL != f_pGNUVersion);
+    return *f_pGNUVersion;
+  }
+
+  const LDSection& getGNUVersion() const {
+    assert(NULL != f_pGNUVersion);
+    return *f_pGNUVersion;
+  }
+
+  LDSection& getGNUVersionD() {
+    assert(NULL != f_pGNUVersionD);
+    return *f_pGNUVersionD;
+  }
+
+  const LDSection& getGNUVersionD() const {
+    assert(NULL != f_pGNUVersionD);
+    return *f_pGNUVersionD;
+  }
+
+  LDSection& getGNUVersionR() {
+    assert(NULL != f_pGNUVersionR);
+    return *f_pGNUVersionR;
+  }
+
+  const LDSection& getGNUVersionR() const {
+    assert(NULL != f_pGNUVersionR);
+    return *f_pGNUVersionR;
+  }
+
+  LDSection& getGOTPLT() {
+    assert(NULL != f_pGOTPLT);
+    return *f_pGOTPLT;
+  }
+
+  const LDSection& getGOTPLT() const {
+    assert(NULL != f_pGOTPLT);
+    return *f_pGOTPLT;
+  }
+
+  LDSection& getJCR() {
+    assert(NULL != f_pJCR);
+    return *f_pJCR;
+  }
+
+  const LDSection& getJCR() const {
+    assert(NULL != f_pJCR);
+    return *f_pJCR;
+  }
+
+  LDSection& getNoteABITag() {
+    assert(NULL != f_pNoteABITag);
+    return *f_pNoteABITag;
+  }
+
+  const LDSection& getNoteABITag() const {
+    assert(NULL != f_pNoteABITag);
+    return *f_pNoteABITag;
+  }
+
+  LDSection& getStab() {
+    assert(NULL != f_pStab);
+    return *f_pStab;
+  }
+
+  const LDSection& getStab() const {
+    assert(NULL != f_pStab);
+    return *f_pStab;
+  }
+
+  LDSection& getStabStr() {
+    assert(NULL != f_pStabStr);
+    return *f_pStabStr;
+  }
+
+  const LDSection& getStabStr() const {
+    assert(NULL != f_pStabStr);
+    return *f_pStabStr;
+  }
+
+protected:
+  GNULDBackend& f_Backend;
+
+  //         variable name         :  ELF
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  LDSection* f_pNULLSection;
+  LDSection* f_pGOT;               // .got
+  LDSection* f_pPLT;               // .plt
+  LDSection* f_pRelDyn;            // .rel.dyn
+  LDSection* f_pRelPlt;            // .rel.plt
+  LDSection* f_pRelaDyn;           // .rela.dyn
+  LDSection* f_pRelaPlt;           // .rela.plt
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  LDSection* f_pComment;           // .comment
+  LDSection* f_pData1;             // .data1
+  LDSection* f_pDebug;             // .debug
+  LDSection* f_pDynamic;           // .dynamic
+  LDSection* f_pDynStrTab;         // .dynstr
+  LDSection* f_pDynSymTab;         // .dynsym
+  LDSection* f_pFini;              // .fini
+  LDSection* f_pFiniArray;         // .fini_array
+  LDSection* f_pHashTab;           // .hash
+  LDSection* f_pInit;              // .init
+  LDSection* f_pInitArray;         // .init_array
+  LDSection* f_pInterp;            // .interp
+  LDSection* f_pLine;              // .line
+  LDSection* f_pNote;              // .note
+  LDSection* f_pPreInitArray;      // .preinit_array
+  LDSection* f_pROData1;           // .rodata1
+  LDSection* f_pShStrTab;          // .shstrtab
+  LDSection* f_pStrTab;            // .strtab
+  LDSection* f_pSymTab;            // .symtab
+  LDSection* f_pTBSS;              // .tbss
+  LDSection* f_pTData;             // .tdata
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  LDSection* f_pCtors;             // .ctors
+  LDSection* f_pDataRelRo;         // .data.rel.ro
+  LDSection* f_pDtors;             // .dtors
+  LDSection* f_pEhFrame;           // .eh_frame
+  LDSection* f_pEhFrameHdr;        // .eh_frame_hdr
+  LDSection* f_pGCCExceptTable;    // .gcc_except_table
+  LDSection* f_pGNUVersion;        // .gnu.version
+  LDSection* f_pGNUVersionD;       // .gnu.version_d
+  LDSection* f_pGNUVersionR;       // .gnu.version_r
+  LDSection* f_pGOTPLT;            // .got.plt
+  LDSection* f_pJCR;               // .jcr
+  LDSection* f_pNoteABITag;        // .note.ABI-tag
+  LDSection* f_pStab;              // .stab
+  LDSection* f_pStabStr;           // .stabstr
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFObjectReader.h b/include/mcld/LD/ELFObjectReader.h
new file mode 100644
index 0000000..ac11261
--- /dev/null
+++ b/include/mcld/LD/ELFObjectReader.h
@@ -0,0 +1,59 @@
+//===- ELFObjectReader.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_OBJECT_READER_H
+#define MCLD_ELF_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/ObjectReader.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+class ELFReaderIF;
+
+/** \lclass ELFObjectReader
+ *  \brief ELFObjectReader reads target-independent parts of ELF object file
+ */
+class ELFObjectReader : public ObjectReader
+{
+public:
+  ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker);
+
+  ~ELFObjectReader();
+
+  // -----  observers  ----- //
+  bool isMyFormat(Input &pFile) const;
+
+  // -----  readers  ----- //
+  bool readObject(Input& pFile);
+
+  virtual bool readSections(Input& pFile);
+
+  virtual bool readSymbols(Input& pFile);
+
+  /// readRelocations - read relocation sections
+  ///
+  /// This function should be called after symbol resolution.
+  virtual bool readRelocations(Input& pFile);
+
+private:
+  ELFReaderIF* m_pELFReader;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFObjectWriter.h b/include/mcld/LD/ELFObjectWriter.h
new file mode 100644
index 0000000..a6b9a87
--- /dev/null
+++ b/include/mcld/LD/ELFObjectWriter.h
@@ -0,0 +1,47 @@
+//===- ELFObjectWriter.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_OBJECT_WRITER_H
+#define MCLD_ELF_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+#include <mcld/LD/ObjectWriter.h>
+#include <mcld/LD/ELFWriter.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+
+/** \class ELFObjectWriter
+ *  \brief ELFObjectWriter writes the target-independent parts of object files.
+ *  ELFObjectWriter reads a MCLDFile and writes into raw_ostream
+ *
+ */
+class ELFObjectWriter : public ObjectWriter, protected ELFWriter
+{
+public:
+  ELFObjectWriter(GNULDBackend& pBackend, MCLinker& pLinker);
+
+  ~ELFObjectWriter();
+
+  llvm::error_code writeObject(Output& pOutput)
+  { return llvm::make_error_code(llvm::errc::not_supported); }
+
+private:
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
new file mode 100644
index 0000000..cac0175
--- /dev/null
+++ b/include/mcld/LD/ELFReader.h
@@ -0,0 +1,224 @@
+//===- ELFReader.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_READER_INTERFACE_H
+#define MCLD_ELF_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/Host.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Support/MemoryRegion.h>
+
+namespace mcld
+{
+
+/** \class ELFReaderIF
+ *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
+ */
+class ELFReaderIF
+{
+public:
+  ELFReaderIF(GNULDBackend& pBackend)
+    : m_Backend(pBackend)
+  { }
+
+  virtual ~ELFReaderIF() { }
+
+  /// ELFHeaderSize - return the size of the ELFHeader
+  virtual size_t getELFHeaderSize() const = 0;
+
+  /// isELF - is this a ELF file
+  virtual bool isELF(void* pELFHeader) const = 0;
+
+  /// isMyEndian - is this ELF file in the same endian to me?
+  virtual bool isMyEndian(void* pELFHeader) const = 0;
+
+  /// isMyMachine - is this ELF file generated for the same machine.
+  virtual bool isMyMachine(void* pELFHeader) const = 0;
+
+  /// fileType - the file type of this file
+  virtual MCLDFile::Type fileType(void* pELFHeader) const = 0;
+
+  /// target - the target backend
+  GNULDBackend& target()
+  { return m_Backend; }
+
+  /// target - the target backend
+  const GNULDBackend& target() const
+  { return m_Backend; }
+
+  /// readSectionHeaders - read ELF section header table and create LDSections
+  virtual bool readSectionHeaders(Input& pInput,
+                                  MCLinker& pLinker,
+                                  void* pELFHeader) const = 0;
+
+  /// readRegularSection - read a regular section and create fragments.
+  virtual bool readRegularSection(Input& pInput,
+                                  MCLinker& pLinker,
+                                  LDSection& pSectHdr) const = 0;
+
+  /// readRegularSection - read a target section and create fragments.
+  virtual bool readTargetSection(Input& pInput,
+                                 MCLinker& pLinker,
+                                 LDSection& pSectHdr) = 0;
+
+  /// readSymbols - read ELF symbols and create LDSymbol
+  virtual bool readSymbols(Input& pInput,
+                           MCLinker& pLinker,
+                           const MemoryRegion& pRegion,
+                           const char* StrTab) const = 0;
+
+  /// readSymbol - read a symbol from the given Input and index in symtab
+  virtual ResolveInfo* readSymbol(Input& pInput,
+                                  LDSection& pSymTab,
+                                  MCLDInfo& pLDInfo,
+                                  uint32_t pSymIdx) const = 0;
+
+  /// readRela - read ELF rela and create Relocation
+  virtual bool readRela(Input& pInput,
+                        MCLinker& pLinker,
+                        LDSection& pSection,
+                        const MemoryRegion& pRegion) const = 0;
+
+  /// readRel - read ELF rel and create Relocation
+  virtual bool readRel(Input& pInput,
+                       MCLinker& pLinker,
+                       LDSection& pSection,
+                       const MemoryRegion& pRegion) const = 0;
+protected:
+  /// LinkInfo - some section needs sh_link and sh_info, remember them.
+  struct LinkInfo {
+    LDSection* section;
+    uint32_t sh_link;
+    uint32_t sh_info;
+  };
+
+  typedef std::vector<LinkInfo> LinkInfoList;
+
+protected:
+  LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const;
+
+  ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;
+
+  ResolveInfo::Binding getSymBinding(uint8_t pBinding,
+                                     uint16_t pShndx,
+                                     uint8_t pVisibility) const;
+
+  uint64_t getSymValue(uint64_t pValue,
+                       uint16_t pShndx,
+                       const Input& pInput) const;
+
+  MCFragmentRef* getSymFragmentRef(Input& pInput,
+                                   MCLinker& pLinker,
+                                   uint16_t pShndx,
+                                   uint32_t pOffset) const;
+
+  ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;
+
+private:
+  GNULDBackend& m_Backend;
+};
+
+/** \class ELFReader
+ *  \brief ELFReader is a template scaffolding for partial specification.
+ */
+template<size_t BIT, bool LITTLEENDIAN>
+class ELFReader
+{ };
+
+/** \class ELFReader<32, true>
+ *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
+ */
+template<>
+class ELFReader<32, true> : public ELFReaderIF
+{
+public:
+  typedef llvm::ELF::Elf32_Ehdr ELFHeader;
+  typedef llvm::ELF::Elf32_Shdr SectionHeader;
+  typedef llvm::ELF::Elf32_Sym  Symbol;
+  typedef llvm::ELF::Elf32_Rel  Rel;
+  typedef llvm::ELF::Elf32_Rela Rela;
+
+public:
+  inline ELFReader(GNULDBackend& pBackend);
+
+  inline ~ELFReader();
+
+  /// ELFHeaderSize - return the size of the ELFHeader
+  inline size_t getELFHeaderSize() const
+  { return sizeof(ELFHeader); }
+
+  /// isELF - is this a ELF file
+  inline bool isELF(void* pELFHeader) const;
+
+  /// isMyEndian - is this ELF file in the same endian to me?
+  inline bool isMyEndian(void* pELFHeader) const;
+
+  /// isMyMachine - is this ELF file generated for the same machine.
+  inline bool isMyMachine(void* pELFHeader) const;
+
+  /// fileType - the file type of this file
+  inline MCLDFile::Type fileType(void* pELFHeader) const;
+
+  /// readSectionHeaders - read ELF section header table and create LDSections
+  inline bool readSectionHeaders(Input& pInput,
+                          MCLinker& pLinker,
+                          void* pELFHeader) const;
+
+  /// readRegularSection - read a regular section and create fragments.
+  inline bool readRegularSection(Input& pInput,
+                                 MCLinker& pLinker,
+                                 LDSection& pInputSectHdr) const;
+
+  /// readRegularSection - read a target section and create fragments.
+  inline bool readTargetSection(Input& pInput,
+                                MCLinker& pLinker,
+                                LDSection& pInputSectHdr);
+
+  /// readSymbols - read ELF symbols and create LDSymbol
+  inline bool readSymbols(Input& pInput,
+                          MCLinker& pLinker,
+                          const MemoryRegion& pRegion,
+                          const char* StrTab) const;
+
+  /// readSymbol - read a symbol from the given Input and index in symtab
+  inline ResolveInfo* readSymbol(Input& pInput,
+                                 LDSection& pSymTab,
+                                 MCLDInfo& pLDInfo,
+                                 uint32_t pSymIdx) const;
+
+  /// readRela - read ELF rela and create Relocation
+  inline bool readRela(Input& pInput,
+                       MCLinker& pLinker,
+                       LDSection& pSection,
+                       const MemoryRegion& pRegion) const;
+
+  /// readRel - read ELF rel and create Relocation
+  inline bool readRel(Input& pInput,
+                      MCLinker& pLinker,
+                      LDSection& pSection,
+                      const MemoryRegion& pRegion) const;
+};
+
+#include "ELFReader.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFReader.tcc b/include/mcld/LD/ELFReader.tcc
new file mode 100644
index 0000000..693a780
--- /dev/null
+++ b/include/mcld/LD/ELFReader.tcc
@@ -0,0 +1,532 @@
+//===- ELFReader.tcc ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file is the template implemenation of ELFReaders
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// ELFReader<32, true>
+#include <cstring>
+#include <vector>
+
+/// constructor
+ELFReader<32, true>::ELFReader(GNULDBackend& pBackend)
+  : ELFReaderIF(pBackend) {
+}
+
+/// destructor
+ELFReader<32, true>::~ELFReader()
+{
+}
+
+/// isELF - is this a ELF file
+bool ELFReader<32, true>::isELF(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+  if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4))
+    return true;
+  return false;
+}
+
+/// isMyEndian - is this ELF file in the same endian to me?
+bool ELFReader<32, true>::isMyEndian(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB);
+}
+
+/// isMyMachine - is this ELF file generated for the same machine.
+bool ELFReader<32, true>::isMyMachine(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  if (llvm::sys::isLittleEndianHost())
+    return (hdr->e_machine == target().machine());
+  return (bswap16(hdr->e_machine) == target().machine());
+}
+
+/// fileType - return the file type
+MCLDFile::Type ELFReader<32, true>::fileType(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+  uint32_t type = 0x0;
+  if (llvm::sys::isLittleEndianHost())
+    type = hdr->e_type;
+  else
+    type = bswap16(hdr->e_type);
+
+  switch(type) {
+  case llvm::ELF::ET_REL:
+    return MCLDFile::Object;
+  case llvm::ELF::ET_EXEC:
+    return MCLDFile::Exec;
+  case llvm::ELF::ET_DYN:
+    return MCLDFile::DynObj;
+  case llvm::ELF::ET_CORE:
+    return MCLDFile::CoreFile;
+  case llvm::ELF::ET_NONE:
+  default:
+    return MCLDFile::Unknown;
+  }
+}
+
+/// readSectionHeaders - read ELF section header table and create LDSections
+bool ELFReader<32, true>::readSectionHeaders(Input& pInput,
+                                             MCLinker& pLinker,
+                                             void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* ehdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  uint32_t shoff     = 0x0;
+  uint16_t shentsize = 0x0;
+  uint16_t shnum     = 0x0;
+  uint16_t shstrtab  = 0x0;
+
+  if (llvm::sys::isLittleEndianHost()) {
+    shoff     = ehdr->e_shoff;
+    shentsize = ehdr->e_shentsize;
+    shnum     = ehdr->e_shnum;
+    shstrtab  = ehdr->e_shstrndx;
+  }
+  else {
+    shoff     = bswap32(ehdr->e_shoff);
+    shentsize = bswap16(ehdr->e_shentsize);
+    shnum     = bswap16(ehdr->e_shnum);
+    shstrtab  = bswap16(ehdr->e_shstrndx);
+  }
+
+  // If the file has no section header table, e_shoff holds zero.
+  if (0x0 == shoff)
+    return true;
+
+  MemoryRegion* shdr_region = pInput.memArea()->request(shoff, shnum*shentsize);
+  llvm::ELF::Elf32_Shdr* shdrTab =
+                reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());
+
+  uint32_t sh_name      = 0x0;
+  uint32_t sh_type      = 0x0;
+  uint32_t sh_flags     = 0x0;
+  uint32_t sh_offset    = 0x0;
+  uint32_t sh_size      = 0x0;
+  uint32_t sh_link      = 0x0;
+  uint32_t sh_info      = 0x0;
+  uint32_t sh_addralign = 0x0;
+
+  // get .shstrtab first
+  llvm::ELF::Elf32_Shdr* shdr = &shdrTab[shstrtab];
+  if (llvm::sys::isLittleEndianHost()) {
+    sh_offset = shdr->sh_offset;
+    sh_size   = shdr->sh_size;
+  }
+  else {
+    sh_offset = bswap32(shdr->sh_offset);
+    sh_size   = bswap32(shdr->sh_size);
+  }
+
+  MemoryRegion* sect_name_region = pInput.memArea()->request(sh_offset, sh_size);
+  const char* sect_name = reinterpret_cast<const char*>(sect_name_region->start());
+
+  LinkInfoList link_info_list;
+
+  // create all LDSections
+  for (size_t idx = 0; idx < shnum; ++idx) {
+    if (llvm::sys::isLittleEndianHost()) {
+      sh_name      = shdrTab[idx].sh_name;
+      sh_type      = shdrTab[idx].sh_type;
+      sh_flags     = shdrTab[idx].sh_flags;
+      sh_offset    = shdrTab[idx].sh_offset;
+      sh_size      = shdrTab[idx].sh_size;
+      sh_link      = shdrTab[idx].sh_link;
+      sh_info      = shdrTab[idx].sh_info;
+      sh_addralign = shdrTab[idx].sh_addralign;
+    }
+    else {
+      sh_name      = bswap32(shdrTab[idx].sh_name);
+      sh_type      = bswap32(shdrTab[idx].sh_type);
+      sh_flags     = bswap32(shdrTab[idx].sh_flags);
+      sh_offset    = bswap32(shdrTab[idx].sh_offset);
+      sh_size      = bswap32(shdrTab[idx].sh_size);
+      sh_link      = bswap32(shdrTab[idx].sh_link);
+      sh_info      = bswap32(shdrTab[idx].sh_info);
+      sh_addralign = bswap32(shdrTab[idx].sh_addralign);
+    }
+
+    LDFileFormat::Kind kind = getLDSectionKind(sh_type,
+                                               sect_name+sh_name);
+
+    LDSection& section = pLinker.createSectHdr(sect_name+sh_name,
+                                               kind,
+                                               sh_type,
+                                               sh_flags);
+
+    section.setSize(sh_size);
+    section.setOffset(sh_offset);
+    section.setIndex(pInput.context()->numOfSections());
+    section.setInfo(sh_info);
+    section.setAlign(sh_addralign);
+
+    if (sh_link != 0x0 || sh_info != 0x0) {
+      LinkInfo link_info = { &section, sh_link, sh_info };
+      link_info_list.push_back(link_info);
+    }
+
+    pInput.context()->getSectionTable().push_back(&section);
+  } // end of for
+
+  // set up InfoLink
+  LinkInfoList::iterator info, infoEnd = link_info_list.end();
+  for (info = link_info_list.begin(); info != infoEnd; ++info) {
+    if (LDFileFormat::NamePool == info->section->kind() ||
+        LDFileFormat::Group == info->section->kind()) {
+      info->section->setLink(pInput.context()->getSection(info->sh_link));
+      continue;
+    }
+    if (LDFileFormat::Relocation == info->section->kind()) {
+      info->section->setLink(pInput.context()->getSection(info->sh_info));
+      continue;
+    }
+  }
+
+  pInput.memArea()->release(shdr_region);
+  pInput.memArea()->release(sect_name_region);
+
+  return true;
+}
+
+/// readRegularSection - read a regular section and create fragments.
+bool ELFReader<32, true>::readRegularSection(Input& pInput,
+                                             MCLinker& pLinker,
+                                             LDSection& pInputSectHdr) const
+{
+  LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(),
+                                                         pInputSectHdr.kind(),
+                                                         pInputSectHdr.type(),
+                                                         pInputSectHdr.flag());
+
+  MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
+                                                   pInputSectHdr.size());
+
+  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
+
+  llvm::MCFragment* frag = NULL;
+  if (NULL == region) {
+    // If the input section's size is zero, we got a NULL region.
+    // use a virtual fill fragment
+    frag = new llvm::MCFillFragment(0x0, 0, 0);
+  }
+  else
+    frag = new MCRegionFragment(*region);
+
+  uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                     sect_data,
+                                                     pInputSectHdr.align());
+
+  out_sect.setSize(out_sect.size() + size);
+  return true;
+}
+
+/// readRegularSection - read a target section and create fragments.
+bool ELFReader<32, true>::readTargetSection(Input& pInput,
+                                            MCLinker& pLinker,
+                                            LDSection& pInputSectHdr)
+{
+  return target().readSection(pInput, pLinker, pInputSectHdr);
+}
+
+/// readSymbols - read ELF symbols and create LDSymbol
+bool ELFReader<32, true>::readSymbols(Input& pInput,
+                                      MCLinker& pLinker,
+                                      const MemoryRegion& pRegion,
+                                      const char* pStrTab) const
+{
+  // get number of symbols
+  size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym);
+  llvm::ELF::Elf32_Sym* symtab =
+                      reinterpret_cast<llvm::ELF::Elf32_Sym*>(pRegion.start());
+
+  uint32_t st_name  = 0x0;
+  uint32_t st_value = 0x0;
+  uint32_t st_size  = 0x0;
+  uint8_t  st_info  = 0x0;
+  uint8_t  st_other = 0x0;
+  uint16_t st_shndx = 0x0;
+  // skip the first NULL symbol
+  pInput.context()->addSymbol(NULL);
+
+  for (size_t idx = 1; idx < entsize; ++idx) {
+    st_info  = symtab[idx].st_info;
+    st_other = symtab[idx].st_other;
+
+    if (llvm::sys::isLittleEndianHost()) {
+      st_name  = symtab[idx].st_name;
+      st_value = symtab[idx].st_value;
+      st_size  = symtab[idx].st_size;
+      st_shndx = symtab[idx].st_shndx;
+    }
+    else {
+      st_name  = bswap32(symtab[idx].st_name);
+      st_value = bswap32(symtab[idx].st_value);
+      st_size  = bswap32(symtab[idx].st_size);
+      st_shndx = bswap16(symtab[idx].st_shndx);
+    }
+
+    // If the section should not be included, set the st_shndx SHN_UNDEF
+    // - A section in interrelated groups are not included.
+    if (pInput.type() == Input::Object &&
+        st_shndx < llvm::ELF::SHN_LORESERVE &&
+        st_shndx != llvm::ELF::SHN_UNDEF) {
+      if (NULL == pInput.context()->getSection(st_shndx))
+        st_shndx = llvm::ELF::SHN_UNDEF;
+    }
+
+    // get ld_name
+    llvm::StringRef ld_name(pStrTab + st_name);
+
+    // get ld_type
+    ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
+
+    // get ld_desc
+    ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
+
+    // get ld_binding
+    ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
+
+    // get ld_value - ld_value must be section relative.
+    uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);
+
+    // get the input fragment
+    MCFragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
+                                                   pLinker,
+                                                   st_shndx,
+                                                   ld_value);
+
+    // get ld_vis
+    ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
+
+    // push into MCLinker
+    LDSymbol* input_sym = NULL;
+
+    if (pInput.type() == Input::Object) {
+      input_sym = pLinker.addSymbol<Input::Object>(ld_name,
+                                                   ld_type,
+                                                   ld_desc,
+                                                   ld_binding,
+                                                   st_size,
+                                                   ld_value,
+                                                   ld_frag_ref,
+                                                   ld_vis);
+      // push into the input file
+      pInput.context()->addSymbol(input_sym);
+      continue;
+    }
+    else if (pInput.type() == Input::DynObj) {
+      input_sym = pLinker.addSymbol<Input::DynObj>(ld_name,
+                                                   ld_type,
+                                                   ld_desc,
+                                                   ld_binding,
+                                                   st_size,
+                                                   ld_value,
+                                                   ld_frag_ref,
+                                                   ld_vis);
+      continue;
+    }
+
+  } // end of for loop
+  return true;
+}
+
+/// readSymbol - read a symbol from the given Input and index in symtab
+ResolveInfo* ELFReader<32, true>::readSymbol(Input& pInput,
+                                             LDSection& pSymTab,
+                                             MCLDInfo& pLDInfo,
+                                             uint32_t pSymIdx) const
+{
+  LDSection* symtab = &pSymTab;
+  LDSection* strtab = symtab->getLink();
+  assert(NULL != symtab && NULL != strtab);
+
+  uint32_t offset = symtab->offset() + sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
+  MemoryRegion* symbol_region =
+                pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym));
+  llvm::ELF::Elf32_Sym* entry =
+                reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start());
+
+  uint32_t st_name  = 0x0;
+  uint32_t st_value = 0x0;
+  uint32_t st_size  = 0x0;
+  uint8_t  st_info  = 0x0;
+  uint8_t  st_other = 0x0;
+  uint16_t st_shndx = 0x0;
+  st_info  = entry->st_info;
+  st_other = entry->st_other;
+  if (llvm::sys::isLittleEndianHost()) {
+    st_name  = entry->st_name;
+    st_value = entry->st_value;
+    st_size  = entry->st_size;
+    st_shndx = entry->st_shndx;
+  }
+  else {
+    st_name  = bswap32(entry->st_name);
+    st_value = bswap32(entry->st_value);
+    st_size  = bswap32(entry->st_size);
+    st_shndx = bswap16(entry->st_shndx);
+  }
+
+  MemoryRegion* strtab_region =
+                    pInput.memArea()->request(strtab->offset(), strtab->size());
+
+  // get ld_name
+  llvm::StringRef ld_name(reinterpret_cast<char*>(strtab_region->start() + st_name));
+
+  // get ld_type
+  ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
+
+  // get ld_desc
+  ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
+
+  // get ld_binding
+  ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
+
+  // get ld_vis
+  ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
+
+  ResolveInfo* result =
+         pLDInfo.getStrSymPool().createSymbol(ld_name,
+                                              pInput.type() == Input::DynObj,
+                                              ld_type,
+                                              ld_desc,
+                                              ld_binding,
+                                              st_size,
+                                              ld_vis);
+  // release regions
+  pInput.memArea()->release(symbol_region);
+  pInput.memArea()->release(strtab_region);
+
+  return result;
+}
+
+/// readRela - read ELF rela and create Relocation
+bool ELFReader<32, true>::readRela(Input& pInput,
+                                   MCLinker& pLinker,
+                                   LDSection& pSection,
+                                   const MemoryRegion& pRegion) const
+{
+  // get the number of rela
+  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela);
+  llvm::ELF::Elf32_Rela* relaTab =
+                     reinterpret_cast<llvm::ELF::Elf32_Rela*>(pRegion.start());
+
+  for (size_t idx=0; idx < entsize; ++idx) {
+    uint32_t r_offset = 0x0;
+    uint32_t r_info   = 0x0;
+    int32_t  r_addend = 0;
+    if (llvm::sys::isLittleEndianHost()) {
+      r_offset = relaTab[idx].r_offset;
+      r_info   = relaTab[idx].r_info;
+      r_addend = relaTab[idx].r_addend;
+    }
+    else {
+      r_offset = bswap32(relaTab[idx].r_offset);
+      r_info   = bswap32(relaTab[idx].r_info);
+      r_addend = bswap32(relaTab[idx].r_addend);
+    }
+
+    uint8_t  r_type = static_cast<unsigned char>(r_info);
+    uint32_t r_sym  = (r_info >> 8);
+    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
+    if (NULL == symbol) {
+      llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
+                               llvm::Twine(r_sym) +
+                               llvm::Twine(" in file `") +
+                               pInput.path().native() +
+                               llvm::Twine("'.\n"));
+    }
+
+    ResolveInfo* resolve_info = symbol->resolveInfo();
+
+    MCFragmentRef* frag_ref =
+         pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
+
+    if (NULL == frag_ref) {
+      llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
+                               llvm::Twine(pSection.getLink()->index()) +
+                               llvm::Twine(" of the relocation section `") +
+                               pSection.name() +
+                               llvm::Twine("' in file `") +
+                               pInput.path().native() +
+                               llvm::Twine(".\n"));
+    }
+
+    pLinker.addRelocation(r_type, *symbol,  *resolve_info, *frag_ref, r_addend);
+  }
+  return true;
+}
+
+/// readRel - read ELF rel and create Relocation
+bool ELFReader<32, true>::readRel(Input& pInput,
+                                  MCLinker& pLinker,
+                                  LDSection& pSection,
+                                  const MemoryRegion& pRegion) const
+{
+  // get the number of rel
+  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel);
+  llvm::ELF::Elf32_Rel* relTab =
+                      reinterpret_cast<llvm::ELF::Elf32_Rel*>(pRegion.start());
+
+  for (size_t idx=0; idx < entsize; ++idx) {
+    uint32_t r_offset = 0x0;
+    uint32_t r_info   = 0x0;
+    if (llvm::sys::isLittleEndianHost()) {
+      r_offset = relTab[idx].r_offset;
+      r_info   = relTab[idx].r_info;
+    }
+    else {
+      r_offset = bswap32(relTab[idx].r_offset);
+      r_info   = bswap32(relTab[idx].r_info);
+    }
+
+    uint8_t  r_type = static_cast<unsigned char>(r_info);
+    uint32_t r_sym  = (r_info >> 8);
+
+    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
+    if (NULL == symbol) {
+      llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
+                               llvm::Twine(r_sym) +
+                               llvm::Twine(" in file `") +
+                               pInput.path().native() +
+                               llvm::Twine("'.\n"));
+    }
+
+    ResolveInfo* resolve_info = symbol->resolveInfo();
+
+    MCFragmentRef* frag_ref =
+         pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
+
+    if (NULL == frag_ref) {
+      llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
+                               llvm::Twine(pSection.getLink()->index()) +
+                               llvm::Twine(" of the relocation section `") +
+                               pSection.name() +
+                               llvm::Twine("' in file `") +
+                               pInput.path().native() +
+                               llvm::Twine(".\n"));
+    }
+
+    pLinker.addRelocation(r_type, *symbol, *resolve_info, *frag_ref);
+  }
+  return true;
+}
+
diff --git a/include/mcld/LD/ELFSegment.h b/include/mcld/LD/ELFSegment.h
new file mode 100644
index 0000000..24f9458
--- /dev/null
+++ b/include/mcld/LD/ELFSegment.h
@@ -0,0 +1,163 @@
+//===- ELFSegment.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_SEGMENT_H
+#define MCLD_ELF_SEGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/LD/LDSection.h>
+#include <cassert>
+#include <vector>
+
+namespace mcld
+{
+
+/** \class ELFSegment
+ *  \brief decribe the program header for ELF executable or shared object
+ */
+class ELFSegment
+{
+public:
+  typedef std::vector<LDSection*>::iterator sect_iterator;
+  typedef std::vector<LDSection*>::const_iterator const_sect_iterator;
+public:
+  ELFSegment(uint32_t pType,
+             uint32_t pFlag = llvm::ELF::PF_R,
+             uint64_t pOffset = 0,
+             uint64_t pVaddr = 0,
+             uint64_t pPaddr = 0,
+             uint64_t pFilesz = 0,
+             uint64_t pMemsz = 0,
+             uint64_t pAlign = 0);
+  ~ELFSegment();
+
+  ///  -----  iterators  -----  ///
+  sect_iterator sectBegin()
+  { return m_SectionList.begin(); }
+
+  sect_iterator sectEnd()
+  { return m_SectionList.end(); }
+
+  const_sect_iterator sectBegin() const
+  { return m_SectionList.begin(); }
+
+  const_sect_iterator sectEnd() const
+  { return m_SectionList.end(); }
+
+  const LDSection* getFirstSection()
+  {
+    if (0 == m_SectionList.size())
+      return NULL;
+    return m_SectionList[0];
+  }
+
+  const LDSection* getLastSection()
+  {
+    size_t size = m_SectionList.size();
+    if (0 == size)
+      return NULL;
+    return m_SectionList[size - 1];
+  }
+
+  const LDSection* getFirstSection() const
+  {
+    if (0 == m_SectionList.size())
+      return NULL;
+    return m_SectionList[0];
+  }
+
+  const LDSection* getLastSection() const
+  {
+    size_t size = m_SectionList.size();
+    if (0 == size)
+      return NULL;
+    return m_SectionList[size - 1];
+  }
+
+  ///  -----  observers  -----  ///
+  uint32_t type() const
+  { return m_Type; }
+
+  uint64_t offset() const
+  { return m_Offset; }
+
+  uint64_t vaddr() const
+  { return m_Vaddr; }
+
+  uint64_t paddr() const
+  { return m_Paddr; }
+
+  uint64_t filesz() const
+  { return m_Filesz; }
+
+  uint64_t memsz() const
+  { return m_Memsz; }
+
+  uint32_t flag() const
+  { return m_Flag; }
+
+  uint64_t align() const
+  { return m_Align; }
+
+  size_t numOfSections() const
+  { return m_SectionList.size(); }
+
+  ///  -----  modifiers  -----  ///
+  void setOffset(uint64_t pOffset)
+  { m_Offset = pOffset; }
+
+  void setVaddr(uint64_t pVaddr)
+  { m_Vaddr = pVaddr; }
+
+  void setPaddr(uint64_t pPaddr)
+  { m_Paddr = pPaddr; }
+
+  void setFilesz(uint64_t pFilesz)
+  { m_Filesz = pFilesz; }
+
+  void setMemsz(uint64_t pMemsz)
+  { m_Memsz = pMemsz; }
+
+  void setFlag(uint32_t pFlag)
+  { m_Flag = pFlag; }
+
+  void updateFlag(uint32_t pFlag)
+  {
+    // PT_TLS segment should be PF_R
+    if (llvm::ELF::PT_TLS != m_Type)
+      m_Flag |= pFlag;
+  }
+
+  void setAlign(uint64_t pAlign)
+  { m_Align = pAlign; }
+
+  void addSection(LDSection* pSection)
+  {
+    assert(NULL != pSection);
+    m_SectionList.push_back(pSection);
+  }
+
+private:
+  uint32_t m_Type;    // Type of segment
+  uint32_t m_Flag;    // Segment flags
+  uint64_t m_Offset;  // File offset where segment is located, in bytes
+  uint64_t m_Vaddr;   // Virtual address of beginning of segment
+  uint64_t m_Paddr;   // Physical address of beginning of segment (OS-specific)
+  uint64_t m_Filesz;  // Num. of bytes in file image of segment (may be zero)
+  uint64_t m_Memsz;   // Num. of bytes in mem image of segment (may be zero)
+  uint64_t m_Align;   // Segment alignment constraint
+  std::vector<LDSection*> m_SectionList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFSegmentFactory.h b/include/mcld/LD/ELFSegmentFactory.h
new file mode 100644
index 0000000..5dd55cb
--- /dev/null
+++ b/include/mcld/LD/ELFSegmentFactory.h
@@ -0,0 +1,43 @@
+//===- ELFSegmentFactory.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELFSEGMENT_FACTORY_H
+#define MCLD_ELFSEGMENT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/ELFSegment.h>
+
+namespace mcld
+{
+
+/** \class ELFSegmentFactory
+ *  \brief provide the interface to create and delete an ELFSegment
+ */
+class ELFSegmentFactory : public GCFactory<ELFSegment, 0>
+{
+public:
+  /// ELFSegmentFactory - the factory of ELFSegment
+  /// pNum is the magic number of the ELF segments in the output
+  ELFSegmentFactory(size_t pNum);
+  ~ELFSegmentFactory();
+
+  /// produce - produce an empty ELF segment information.
+  /// this function will create an ELF segment
+  /// @param pType - p_type in ELF program header
+  ELFSegment* produce(uint32_t pType);
+
+  /// destroy - destruct the ELF segment
+  void destroy(ELFSegment*& pSegment);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFWriter.h b/include/mcld/LD/ELFWriter.h
new file mode 100644
index 0000000..e9db7f5
--- /dev/null
+++ b/include/mcld/LD/ELFWriter.h
@@ -0,0 +1,122 @@
+//===- ELFWriter.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_WRITER_H
+#define MCLD_ELF_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDOutput.h>
+
+namespace llvm {
+class MCSectionData;
+}
+
+namespace mcld
+{
+
+class MCLDInfo;
+class Layout;
+class GNULDBackend;
+class Relocation;
+class LDSection;
+
+/** \class ELFWriter
+ *  \brief ELFWriter provides basic functions to write ELF sections, symbols,
+ *  and so on.
+ */
+class ELFWriter
+{
+public:
+  typedef uint64_t FileOffset;
+
+protected:
+  ELFWriter(GNULDBackend& pBackend)
+  : f_Backend(pBackend) {
+  }
+
+public:
+  virtual ~ELFWriter() { }
+
+  GNULDBackend& target()
+  { return f_Backend; }
+
+  const GNULDBackend& target() const
+  { return f_Backend; }
+
+  virtual void writeELF32Header(const MCLDInfo& pInfo,
+                                const Layout& pLayout,
+                                const GNULDBackend& pBackend,
+                                Output& pOutput) const;
+
+  virtual void writeELF64Header(const MCLDInfo& pInfo,
+                                const Layout& pLayout,
+                                const GNULDBackend& pBackend,
+                                Output& pOutput) const;
+
+  virtual uint64_t getEntryPoint(const MCLDInfo& pInfo,
+                                 const Layout& pLayout,
+                                 const GNULDBackend& pBackend,
+                                 const Output& pOutput) const;
+
+protected:
+  void emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const;
+
+  // emitShStrTab - emit .shstrtab
+  void emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitSectionData(const Layout& pLayout,
+                       const LDSection& pSection,
+                       MemoryRegion& pRegion) const;
+
+  void emitRelocation(const Layout& pLayout,
+                      const Output& pOutput,
+                      const LDSection& pSection,
+                      MemoryRegion& pRegion) const;
+
+  void emitRel(const Layout& pLayout,
+               const Output& pOutput,
+               const llvm::MCSectionData& pSectionData,
+               MemoryRegion& pRegion) const;
+
+  void emitRela(const Layout& pLayout,
+                const Output& pOutput,
+                const llvm::MCSectionData& pSectionData,
+                MemoryRegion& pRegion) const;
+
+private:
+  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
+  uint64_t getELF32SectEntrySize(const LDSection& pSection) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
+  uint64_t getELF64SectEntrySize(const LDSection& pSection) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_link
+  uint64_t getSectLink(const LDSection& pSection, const Output& pOutput) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_info
+  uint64_t getSectInfo(const LDSection& pSection, const Output& pOutput) const;
+
+  uint64_t getELF32LastStartOffset(const Output& pOutput) const;
+
+  uint64_t getELF64LastStartOffset(const Output& pOutput) const;
+
+protected:
+  GNULDBackend& f_Backend;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/GNUArchiveReader.h b/include/mcld/LD/GNUArchiveReader.h
new file mode 100644
index 0000000..57aee10
--- /dev/null
+++ b/include/mcld/LD/GNUArchiveReader.h
@@ -0,0 +1,86 @@
+//===- GNUArchiveReader.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GNU_ARCHIVE_READER_H
+#define MCLD_GNU_ARCHIVE_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/LD/ArchiveReader.h"
+#include "mcld/Support/Path.h"
+#include <llvm/ADT/OwningPtr.h>
+
+#include <vector>
+#include <string>
+
+namespace llvm
+{
+class MemoryBuffer;
+
+}
+
+namespace mcld
+{
+class MCLDInfo;
+class Input;
+class InputTree;
+
+/** \class GNUArchiveReader
+ *  \brief GNUArchiveReader reads GNU archive files.
+ */
+class GNUArchiveReader : public ArchiveReader
+{
+private:
+  struct ArchiveMemberHeader;
+  struct SymbolTableEntry;
+
+public:
+  explicit GNUArchiveReader(MCLDInfo &pLDInfo, LDReader::Endian endian)
+  : m_pLDInfo(pLDInfo),
+    m_endian(endian)
+  { }
+
+  ~GNUArchiveReader()
+  { }
+
+  /// Read an archive and extract each member in.
+  /// Construct the coresponding Input for each member.
+  InputTree *readArchive(Input &input);
+
+  bool isMyFormat(Input &input) const;
+
+  LDReader::Endian endian(Input& pFile) const;
+
+private:
+  /// set up the archive, including
+  /// first, read symbol table
+  /// second, read extended file name which is used in thin archive
+  InputTree *setupNewArchive(Input &pInput, size_t off);
+
+  /// parse the archive header, and return the member size
+  size_t parseMemberHeader(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                   off_t off,
+                   std::string *p_Name,
+                   off_t *nestedOff,
+                   std::string &p_ExtendedName);
+
+  void readSymbolTable(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                      std::vector<SymbolTableEntry> &pSymbolTable,
+                      off_t start,
+                      size_t size);
+
+private:
+  MCLDInfo &m_pLDInfo;
+  LDReader::Endian m_endian;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Group.h b/include/mcld/LD/Group.h
new file mode 100644
index 0000000..31c4a68
--- /dev/null
+++ b/include/mcld/LD/Group.h
@@ -0,0 +1,28 @@
+//===- Group.h ------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_GROUP_H
+#define LD_GROUP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class Group
+ *  \brief Group records the grouping of all regions
+ */
+class Group
+{
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/InputSymbolTable.h b/include/mcld/LD/InputSymbolTable.h
new file mode 100644
index 0000000..c5e3864
--- /dev/null
+++ b/include/mcld/LD/InputSymbolTable.h
@@ -0,0 +1,46 @@
+//===- InputSymbolTable.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INPUTSYMBOLTABLE_H
+#define INPUTSYMBOLTABLE_H
+#include <llvm/ADT/StringRef.h>
+#include "mcld/LD/SymbolTableIF.h"
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class InputSymbolTable
+ *  \brief Input symbol table, for MCLDInput.
+ *
+ *  \see
+ */
+class InputSymbolTable : public SymbolTableIF
+{
+  /* draft. */
+  friend class SymbolTableFactory;
+private:
+  InputSymbolTable(StrSymPool &pStrSymPool,
+                   size_t pNumOfSymbols,
+                   StringTable &pEntireStringTable,
+                   StringTable &pDynamicStringTable);
+private:
+  virtual void doInsertSymbol(LDSymbol *);
+  virtual void doMerge(const SymbolTableIF &);
+public:
+  virtual ~InputSymbolTable();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDContext.h b/include/mcld/LD/LDContext.h
new file mode 100644
index 0000000..878ba8d
--- /dev/null
+++ b/include/mcld/LD/LDContext.h
@@ -0,0 +1,105 @@
+//===- LDContext.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDCONTEXT_H
+#define MCLD_LDCONTEXT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+#include <mcld/LD/LDFileFormat.h>
+#include <llvm/Support/DataTypes.h>
+#include <string>
+#include <cassert>
+
+namespace llvm {
+class StringRef;
+}
+
+namespace mcld
+{
+
+class LDSymbol;
+class LDSection;
+
+/** \class LDContext
+ *  \brief LDContext stores the data which a object file should has
+ */
+class LDContext
+{
+public:
+  typedef std::vector<LDSection*> SectionTable;
+  typedef SectionTable::iterator sect_iterator;
+  typedef SectionTable::const_iterator const_sect_iterator;
+
+  typedef std::vector<LDSymbol*> SymbolTable;
+  typedef SymbolTable::iterator sym_iterator;
+  typedef SymbolTable::const_iterator const_sym_iterator;
+
+public:
+  LDContext();
+
+  ~LDContext();
+
+  // -----  sections  ----- //
+  SectionTable& getSectionTable()
+  { return m_SectionTable; }
+
+  const SectionTable& getSectionTable() const
+  { return m_SectionTable; }
+
+  sect_iterator sectBegin()
+  { return m_SectionTable.begin(); }
+
+  sect_iterator sectEnd()
+  { return m_SectionTable.end(); }
+
+  const_sect_iterator sectBegin() const
+  { return m_SectionTable.begin(); }
+
+  const_sect_iterator sectEnd() const
+  { return m_SectionTable.end(); }
+
+  LDSection* getSection(unsigned int pIdx);
+
+  const LDSection* getSection(unsigned int pIdx) const;
+
+  LDSection* getSection(const std::string& pName);
+
+  const LDSection* getSection(const std::string& pName) const;
+
+  size_t getSectionIdx(const std::string& pName) const;
+
+  size_t numOfSections() const
+  { return m_SectionTable.size(); }
+
+  // -----  symbols  ----- //
+  LDSymbol* getSymbol(unsigned int pIdx);
+
+  const LDSymbol* getSymbol(unsigned int pIdx) const;
+
+  LDSymbol* getSymbol(const llvm::StringRef& pName);
+
+  const LDSymbol* getSymbol(const llvm::StringRef& pName) const;
+
+  void addSymbol(LDSymbol* pSym)
+  { m_SymTab.push_back(pSym); }
+
+private:
+  SectionTable m_SectionTable;
+  SymbolTable m_SymTab;
+
+  // FIXME : maintain a map<section name, section index>
+};
+
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDFileFormat.h b/include/mcld/LD/LDFileFormat.h
new file mode 100644
index 0000000..df80f67
--- /dev/null
+++ b/include/mcld/LD/LDFileFormat.h
@@ -0,0 +1,113 @@
+//===- LDFileFormat.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDFILE_FORMAT_H
+#define MCLD_LDFILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <cstdio>
+#include <cassert>
+
+namespace mcld
+{
+
+class MCLinker;
+class LDSection;
+
+/** \class LDFileFormat
+ *  \brief LDFileFormat describes the common file formats.
+ */
+class LDFileFormat
+{
+public:
+  enum Kind {
+    Null,
+    Regular,
+    BSS,
+    NamePool,
+    Relocation,
+    Debug,
+    Target,
+    Exception,
+    Version,
+    Note,
+    MetaData,
+    Group,
+  };
+
+protected:
+  LDFileFormat();
+
+public:
+  virtual ~LDFileFormat();
+
+  /// initStdSections - initialize all standard sections.
+  void initStdSections(MCLinker& pLinker);
+
+  /// initObjectFormat - different format, such as ELF and MachO, should
+  /// implement this
+  virtual void initObjectFormat(MCLinker& pLinker) = 0;
+
+  /// initObjectType - different types, such as shared object, executable
+  /// files, should implement this
+  virtual void initObjectType(MCLinker& pLinker) = 0;
+
+  // -----  access functions  ----- //
+  LDSection& getText() {
+    assert(NULL != f_pTextSection);
+    return *f_pTextSection;
+  }
+
+  const LDSection& getText() const {
+    assert(NULL != f_pTextSection);
+    return *f_pTextSection;
+  }
+
+  LDSection& getData() {
+    assert(NULL != f_pDataSection);
+    return *f_pDataSection;
+  }
+
+  const LDSection& getData() const {
+    assert(NULL != f_pDataSection);
+    return *f_pDataSection;
+  }
+
+  LDSection& getBSS() {
+    assert(NULL != f_pBSSSection);
+    return *f_pBSSSection;
+  }
+
+  const LDSection& getBSS() const {
+    assert(NULL != f_pBSSSection);
+    return *f_pBSSSection;
+  }
+
+  LDSection& getReadOnly() {
+    assert(NULL != f_pReadOnlySection);
+    return *f_pReadOnlySection;
+  }
+
+  const LDSection& getReadOnly() const {
+    assert(NULL != f_pReadOnlySection);
+    return *f_pReadOnlySection;
+  }
+protected:
+  //         variable name         :  ELF               MachO
+  LDSection* f_pTextSection;       // .text             __text
+  LDSection* f_pDataSection;       // .data             __data
+  LDSection* f_pBSSSection;        // .bss              __bss
+  LDSection* f_pReadOnlySection;   // .rodata           __const
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDReader.h b/include/mcld/LD/LDReader.h
new file mode 100644
index 0000000..4fde9f0
--- /dev/null
+++ b/include/mcld/LD/LDReader.h
@@ -0,0 +1,47 @@
+//===- LDReader.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_READER_INTERFACE_H
+#define MCLD_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+
+namespace mcld
+{
+
+class Input;
+
+/** \class LDReader
+ *  \brief LDReader provides the basic interfaces for all readers. It also
+ *  provides basic functions to read data stream.
+ */
+class LDReader
+{
+public:
+  enum Endian {
+    LittleEndian,
+    BigEndian
+  };
+
+protected:
+  LDReader() { }
+
+public:
+  virtual ~LDReader() { }
+
+  virtual bool isMyFormat(Input& pInput) const = 0;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSection.h b/include/mcld/LD/LDSection.h
new file mode 100644
index 0000000..4c793de
--- /dev/null
+++ b/include/mcld/LD/LDSection.h
@@ -0,0 +1,205 @@
+//===- LDSection.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LD_LDSECTION_H
+#define MCLD_LD_LDSECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCSection.h>
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <string>
+
+namespace llvm {
+
+class MCAsmInfo;
+class raw_ostream;
+
+} // namespace of llvm
+
+namespace mcld {
+/** \class LDSection
+ *  \brief LDSection represents a section header entry. It is a unified
+ *  abstraction for various file formats.
+ *
+ *  LDSection contains both the format-dependent data and LLVM specific data.
+ *
+ */
+class LDSection : public llvm::MCSection
+{
+public:
+  LDSection(const std::string& pName,
+            LDFileFormat::Kind pKind,
+            uint32_t pType,
+            uint32_t pFlag,
+            uint64_t pSize = 0,
+            uint64_t pOffset = 0,
+            uint64_t pAddr = 0);
+
+  /// name - the name of this section.
+  const std::string& name() const
+  { return m_Name; }
+
+  /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
+  /// from LDFileFormat::Kind
+  LDFileFormat::Kind kind() const
+  { return m_Kind; }
+
+  /// type - The categorizes the section's contents and semantics. It's
+  /// different from llvm::SectionKind. Type is format-dependent, but
+  /// llvm::SectionKind is format independent and is used for bit-code.
+  ///   In ELF, it is sh_type
+  ///   In MachO, it's type field of struct section::flags
+  uint32_t type() const
+  { return m_Type; }
+
+  /// flag - An integer describes miscellaneous attributes.
+  ///   In ELF, it is sh_flags.
+  ///   In MachO, it's attribute field of struct section::flags
+  uint32_t flag() const
+  { return m_Flag; }
+
+  /// size - An integer specifying the size in bytes of the virtual memory
+  /// occupied by this section.
+  ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
+  ///   Before layouting, output's LDSection::size() should return zero.
+  uint64_t size() const
+  { return m_Size; }
+
+  /// offset - An integer specifying the offset of this section in the file.
+  ///   Before layouting, output's LDSection::offset() should return zero.
+  uint64_t offset() const
+  { return m_Offset; }
+
+  /// addr - An integer specifying the virtual address of this section in the
+  /// virtual image.
+  ///   Before layouting, output's LDSection::offset() should return zero.
+  ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
+  ///   constraint is set in MCSectionData::setAlignment. addr() contains the
+  ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
+  ///   MachO uses the same scenario.
+  ///
+  ///   Because addr() in output is changing during linking, MCLinker does not
+  ///   store the address of the output here. The address is in Layout
+  uint64_t addr() const
+  { return m_Addr; }
+
+  /// align - An integer specifying the align of this section in the file.
+  ///   Before layouting, output's LDSection::align() should return zero.
+  uint32_t align() const
+  { return m_Align; }
+
+  size_t index() const
+  { return m_Index; }
+
+  /// getLink - return the Link. When a section A needs the other section B
+  /// during linking or loading, we say B is A's Link section.
+  /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
+  ///
+  /// @return if the section needs no other sections, return NULL
+  LDSection* getLink()
+  { return m_pLink; }
+
+  const LDSection* getLink() const
+  { return m_pLink; }
+
+  size_t getInfo() const
+  { return m_Info; }
+
+  void setKind(LDFileFormat::Kind pKind)
+  { m_Kind = pKind; }
+
+  void setSize(uint64_t size)
+  { m_Size = size; }
+
+  void setOffset(uint64_t Offset)
+  { m_Offset = Offset; }
+
+  void setAddr(uint64_t addr)
+  { m_Addr = addr; }
+
+  void setAlign(uint32_t align)
+  { m_Align = align; }
+
+  void setFlag(uint32_t flag)
+  { m_Flag = flag; }
+
+  void setType(uint32_t type)
+  { m_Type = type; }
+
+  static bool classof(const MCSection *S)
+  { return S->getVariant() == SV_LDContext; }
+
+  static bool classof(const LDSection *)
+  { return true; }
+
+  // -----  methods for adapt to llvm::MCSection  ----- //
+  void PrintSwitchToSection(const llvm::MCAsmInfo &MAI,
+                            llvm::raw_ostream &OS) const
+  { }
+
+  bool UseCodeAlign() const
+  { return true; }
+
+  bool isVirtualSection() const
+  { return false; }
+
+  llvm::MCSectionData* getSectionData()
+  { return m_pSectionData; }
+
+  const llvm::MCSectionData* getSectionData() const
+  { return m_pSectionData; }
+
+  void setSectionData(llvm::MCSectionData* pSD)
+  { m_pSectionData = pSD; }
+
+  bool hasSectionData() const
+  { return (NULL != m_pSectionData); }
+
+  /// setLink - set the sections should link with.
+  /// if pLink is NULL, no Link section is set.
+  void setLink(LDSection* pLink)
+  { m_pLink = pLink; }
+
+  void setInfo(size_t pInfo)
+  { m_Info = pInfo; }
+
+  void setIndex(size_t pIndex)
+  { m_Index = pIndex; }
+
+private:
+  std::string m_Name;
+  LDFileFormat::Kind m_Kind;
+  uint32_t m_Type;
+  uint32_t m_Flag;
+
+  uint64_t m_Size;
+  uint64_t m_Offset;
+  uint64_t m_Addr;
+  uint32_t m_Align;
+
+  size_t m_Info;
+  LDSection* m_pLink;
+
+  // pointer to MCSectionData.
+  llvm::MCSectionData* m_pSectionData;
+
+  // the index of the file
+  size_t m_Index;
+
+}; // end of LDSection
+
+} // end namespace mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSectionFactory.h b/include/mcld/LD/LDSectionFactory.h
new file mode 100644
index 0000000..49b11c7
--- /dev/null
+++ b/include/mcld/LD/LDSectionFactory.h
@@ -0,0 +1,58 @@
+//===- LDSectionFactory.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDSECTION_FACTORY_H
+#define MCLD_LDSECTION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class LDSectionFactory
+ *  \brief provide the interface to create and delete section data for output
+ */
+class LDSectionFactory : public GCFactory<LDSection, 0>
+{
+public:
+  /// LDSectionFactory - the factory of LDSection
+  /// pNum is the average number of the LDSections in the system.
+  LDSectionFactory(size_t pNum);
+  ~LDSectionFactory();
+
+  /// produce - produce an empty section information.
+  /// This function will create an empty MCSectionData and its LDSection.
+  /// @param pName - The name of the section.
+  /// @param pKind - The kind of the section. Used to create default section map
+  /// @param pType - sh_type in ELF.
+  /// @param pFlag - is the same as sh_flags.
+  LDSection* produce(const std::string& pName,
+                     LDFileFormat::Kind pKind,
+                     uint32_t pType,
+                     uint32_t pFlag);
+
+  /// destroy - destruct the LDSection.
+  /// @oaram - the reference of the pointer to the destructed LDSection.
+  ///          after the destruction, the pointer is set to zero.
+  void destroy(LDSection*& pSD);
+
+  /// find - find the LDSection* in factory from the given section name.
+  ///        return NULL if not found.
+  /// @param pName - the name of section
+  LDSection* find(const std::string& pName);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSymbol.h b/include/mcld/LD/LDSymbol.h
new file mode 100644
index 0000000..45c0b75
--- /dev/null
+++ b/include/mcld/LD/LDSymbol.h
@@ -0,0 +1,128 @@
+//===- LDSymbol.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_SYMBOL_H
+#define MCLD_LD_SYMBOL_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/LD/ResolveInfo.h"
+#include "mcld/MC/MCFragmentRef.h"
+#include <llvm/MC/MCAssembler.h>
+#include <assert.h>
+
+namespace mcld
+{
+
+/** \class LDSymbol
+ *  \brief LDSymbol provides a consistent abstraction for different formats
+ *  in different targets.
+ */
+class LDSymbol
+{
+public:
+  // FIXME: use SizeTrait<32> or SizeTrait<64> instead of big type
+  typedef ResolveInfo::SizeType SizeType;
+  typedef uint64_t ValueType;
+  typedef MCFragmentRef::Offset Offset;
+
+public:
+  LDSymbol();
+  LDSymbol(const LDSymbol& pCopy);
+  LDSymbol& operator=(const LDSymbol& pCopy);
+  ~LDSymbol();
+
+  // -----  observers  ----- //
+  const char* name() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->name();
+  }
+
+  unsigned int nameSize() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->nameSize();
+  }
+
+  llvm::StringRef str() const {
+    assert(NULL != m_pResolveInfo);
+    return llvm::StringRef(m_pResolveInfo->name(), m_pResolveInfo->nameSize());
+  }
+
+  bool isDyn() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->isDyn();
+  }
+
+  unsigned int type() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->type();
+  }
+ unsigned int desc() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->desc();
+  }
+  unsigned int binding() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->binding();
+  }
+
+  uint8_t other() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->other();
+  }
+
+  uint8_t visibility() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->other();
+  }
+
+  ValueType value() const
+  { return m_Value; }
+
+  const MCFragmentRef* fragRef() const
+  { return m_pFragRef; }
+
+  SizeType size() const
+  { return m_pResolveInfo->size(); }
+
+  ResolveInfo* resolveInfo()
+  { return m_pResolveInfo; }
+
+  const ResolveInfo* resolveInfo() const 
+  { return m_pResolveInfo; }
+
+  bool hasFragRef() const
+  { return (NULL != m_pFragRef); }
+
+  // -----  modifiers  ----- //
+  void setSize(SizeType pSize) {
+    assert(NULL != m_pResolveInfo);
+    m_pResolveInfo->setSize(pSize);
+  }
+
+  void setValue(ValueType pValue)
+  { m_Value = pValue; }
+ 
+  void setFragmentRef(MCFragmentRef* pFragmentRef);
+
+  void setResolveInfo(const ResolveInfo& pInfo);
+
+private:
+  // -----  Symbol's fields  ----- //
+  ResolveInfo* m_pResolveInfo;
+  MCFragmentRef* m_pFragRef;
+  ValueType m_Value;
+
+};
+
+} // namespace mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDWriter.h b/include/mcld/LD/LDWriter.h
new file mode 100644
index 0000000..78c2871
--- /dev/null
+++ b/include/mcld/LD/LDWriter.h
@@ -0,0 +1,41 @@
+//===- LDWriter.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  LDWriter provides an interface used by MCLinker,
+//  which writes the result of linking into a .so file or a executable.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_WRITER_INTERFACE_H
+#define MCLD_WRITER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Target/TargetLDBackend.h>
+
+namespace mcld
+{
+
+/** \class LDWriter
+ *  \brief LDWriter provides the basic interfaces for all writers.
+ *  (ObjectWriter, DynObjWriter, and EXEObjWriter)
+ */
+class LDWriter
+{
+protected:
+  LDWriter() { }
+
+public:
+  virtual ~LDWriter() { }
+
+};
+
+} //end namespace
+
+#endif
+
diff --git a/include/mcld/LD/Layout.h b/include/mcld/LD/Layout.h
new file mode 100644
index 0000000..28f2d83
--- /dev/null
+++ b/include/mcld/LD/Layout.h
@@ -0,0 +1,270 @@
+//===- Layout.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LAYOUT_H
+#define MCLD_LAYOUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/ADT/DenseMap.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/MC/MCFragmentRef.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/LDSection.h>
+#include <map>
+
+namespace mcld
+{
+class MCLinker;
+class Output;
+class TargetLDBackend;
+
+/** \class Layout
+ *  \brief Layout maintains the mapping between sections and fragments.
+ *
+ *  MCLinker is a fragment-based linker. But readers and target backends
+ *  still need section information. Layout is used to maintain the mapping
+ *  between sections and fragments. Layout helps readers and target backends
+ *  get the input or output section information from a fragment.
+ */
+class Layout
+{
+public:
+  typedef std::vector<LDSection*> SectionOrder;
+  typedef SectionOrder::iterator sect_iterator;
+  typedef SectionOrder::const_iterator const_sect_iterator;
+
+public:
+  /// constructor
+  Layout();
+
+  /// destructor
+  ~Layout();
+
+  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in input
+  LDSection* getInputLDSection(const llvm::MCFragment& pFrag);
+
+  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in input
+  const LDSection* getInputLDSection(const llvm::MCFragment& pFrag) const;
+
+  /// getFragmentRef - give a LDSection in input file and an offset, return
+  /// the fragment reference.
+  ///
+  /// @param pInputSection - the given input section
+  /// @param pOffset - the offset, cannot be larger than this input section.
+  /// @return if found, return the fragment. Otherwise, return NULL.
+  MCFragmentRef*
+  getFragmentRef(const LDSection& pInputSection, uint64_t pOffset);
+
+  /// getFragmentRef - give a fragment and a big offset, return the fragment
+  /// reference in the section data.
+  ///
+  /// @param pFrag - the given fragment
+  /// @param pBigOffset - the offset, can be larger than the fragment, but can
+  ///                     not larger than this input section.
+  /// @return if found, return the fragment. Otherwise, return NULL.
+  MCFragmentRef*
+  getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset);
+
+  /// getOutputOffset - Get the offset of the given fragment inside the
+  /// the output's MCSectionData.
+  uint64_t getOutputOffset(const llvm::MCFragment& pFrag);
+
+  /// getOutputOffset - Get the offset of the given fragment inside the
+  /// the output's MCSectionData.
+  uint64_t getOutputOffset(const llvm::MCFragment& pFrag) const;
+
+  /// getOutputOffset - Get the offset of the given fragment inside
+  /// the output's MCSectionData.
+  ///
+  /// @return return -1 if the fragment is not found in output's MCSectionData.
+
+  uint64_t getOutputOffset(const MCFragmentRef& pFragRef);
+  /// getOutputOffset - Get the offset of the given fragment inside
+  /// the output's MCSectionData.
+  ///
+  /// @return return -1 if the fragment is not found in output's MCSectionData.
+  uint64_t getOutputOffset(const MCFragmentRef& pFragRef) const;
+
+  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in the output
+  LDSection* getOutputLDSection(const llvm::MCFragment& pFrag);
+
+  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in the output
+  const LDSection* getOutputLDSection(const llvm::MCFragment& pFrag) const;
+
+  // -----  modifiers  ----- //
+  bool layout(Output& pOutput, const TargetLDBackend& pBackend);
+
+  /// addInputRange
+  void addInputRange(const llvm::MCSectionData& pSD,
+                     const LDSection& pInputHdr);
+
+  /// appendFragment - append the given MCFragment to the given MCSectionData,
+  /// and insert a MCAlignFragment to preserve the required align constraint if
+  /// needed
+  /// @return return the inserted size, i.e., the size of pFrag and alignment
+  /// size if any
+  uint64_t appendFragment(llvm::MCFragment& pFrag,
+                          llvm::MCSectionData& pSD,
+                          uint32_t pAlignConstraint = 1);
+private:
+  /** \class Range
+   *  \brief Range is a <input's LDSection, previous rear fragment> pair
+   */
+  struct Range : public llvm::ilist_node<Range>
+  {
+  public:
+    Range();
+    Range(const LDSection& pHeader);
+    ~Range();
+
+  public:
+    LDSection* header;
+    llvm::MCFragment* prevRear;
+  };
+
+  typedef llvm::iplist<Range> RangeList;
+
+  typedef std::map<const llvm::MCSectionData*, RangeList*> SDRangeMap;
+
+  typedef GCFactory<MCFragmentRef, 0> FragRefFactory;
+
+private:
+  inline bool isFirstRange(const Range& pRange) const
+  { return (NULL == pRange.prevRear); }
+
+  inline bool isLastRange(const Range& pRange) const
+  { return (NULL == pRange.getNextNode()); }
+
+  inline bool isEmptyRange(const Range& pRange) const
+  {
+    if (isFirstRange(pRange)) {
+      if (!pRange.header->hasSectionData() ||
+          pRange.header->getSectionData()->getFragmentList().empty())
+        return true;
+      else
+        return false;
+    }
+    return (NULL == pRange.prevRear->getNextNode());
+  }
+
+  // get the front fragment in the range.
+  inline llvm::MCFragment* getFront(Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isFirstRange(pRange))
+      return &pRange.header->getSectionData()->getFragmentList().front();
+
+    if (isEmptyRange(pRange))
+      return NULL;
+
+    return pRange.prevRear->getNextNode();
+  }
+
+  inline const llvm::MCFragment* getFront(const Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isFirstRange(pRange))
+      return &pRange.header->getSectionData()->getFragmentList().front();
+
+    if (isEmptyRange(pRange))
+      return NULL;
+
+    return pRange.prevRear->getNextNode();
+  }
+
+  // get the rear fragment in the range.
+  inline llvm::MCFragment* getRear(Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isLastRange(pRange)) {
+      if (isEmptyRange(pRange))
+        return NULL;
+      return &pRange.header->getSectionData()->getFragmentList().back();
+    }
+    return pRange.getNextNode()->prevRear;
+  }
+
+  inline const llvm::MCFragment* getRear(const Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isLastRange(pRange)) {
+      if (isEmptyRange(pRange))
+        return NULL;
+      return &pRange.header->getSectionData()->getFragmentList().back();
+    }
+    return pRange.getNextNode()->prevRear;
+  }
+
+  MCFragmentRef* getFragmentRef(Range &pRange, uint64_t pOffset);
+
+  MCFragmentRef* getFragmentRef(llvm::MCFragment& pFront,
+                                llvm::MCFragment& pRear,
+                                uint64_t pOffset);
+
+  bool hasLayoutOrder(const llvm::MCFragment& pFragment) const
+  { return (pFragment.getLayoutOrder() != ~(0U)); }
+
+  bool hasLayoutOffset(const llvm::MCFragment& pFragment) const
+  { return (pFragment.Offset != ~UINT64_C(0)); }
+
+  bool isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const;
+
+  void setFragmentLayoutOrder(llvm::MCFragment* pFragment);
+
+  void setFragmentLayoutOffset(llvm::MCFragment* pFragment);
+
+  /// sortSectionOrder - perform sorting on m_SectionOrder to get final layout
+  /// ordering
+  void sortSectionOrder(const Output& pOutput,
+                        const TargetLDBackend& pBackend);
+
+private:
+  /// a vector to describe the order of sections
+  SectionOrder m_SectionOrder;
+
+  /// the map from MCSectionData* to its own RangeList.
+  SDRangeMap m_SDRangeMap;
+
+  FragRefFactory m_FragRefFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ObjectReader.h b/include/mcld/LD/ObjectReader.h
new file mode 100644
index 0000000..9dbe9ac
--- /dev/null
+++ b/include/mcld/LD/ObjectReader.h
@@ -0,0 +1,69 @@
+//===- ObjectReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OBJECT_READER_H
+#define MCLD_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+#include <llvm/Support/system_error.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/StringHash.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+
+namespace mcld
+{
+
+class Input;
+
+/** \class ObjectReader
+ *  \brief ObjectReader provides an common interface for different object
+ *  formats.
+ */
+class ObjectReader : public LDReader
+{
+protected:
+  typedef HashTable<ResolveInfo,
+                    StringHash<ELF>,
+                    ResolveInfoFactory> GroupSignatureMap;
+
+protected:
+  ObjectReader()
+  { }
+
+public:
+  virtual ~ObjectReader() { }
+
+  virtual bool readObject(Input& pFile) = 0;
+
+  virtual bool readSymbols(Input& pFile) = 0;
+
+  virtual bool readSections(Input& pFile) = 0;
+
+  /// readRelocations - read relocation sections
+  ///
+  /// This function should be called after symbol resolution.
+  virtual bool readRelocations(Input& pFile) = 0;
+
+  GroupSignatureMap& signatures()
+  { return f_GroupSignatureMap; }
+
+  const GroupSignatureMap& signatures() const
+  { return f_GroupSignatureMap; }
+
+protected:
+  GroupSignatureMap f_GroupSignatureMap;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ObjectWriter.h b/include/mcld/LD/ObjectWriter.h
new file mode 100644
index 0000000..0c48723
--- /dev/null
+++ b/include/mcld/LD/ObjectWriter.h
@@ -0,0 +1,39 @@
+//===- ObjectWriter.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OBJECT_WRITER_INTERFACE_H
+#define MCLD_OBJECT_WRITER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Output;
+class GNULDBackend;
+
+/** \class ObjectWriter
+ *  \brief ObjectWriter provides a common interface for object file writers.
+ */
+class ObjectWriter
+{
+protected:
+  ObjectWriter(GNULDBackend& pBackend);
+
+public:
+  virtual ~ObjectWriter();
+
+  virtual llvm::error_code writeObject(Output& pOutput) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/OutputSymbolTable.h b/include/mcld/LD/OutputSymbolTable.h
new file mode 100644
index 0000000..fdcf0bc
--- /dev/null
+++ b/include/mcld/LD/OutputSymbolTable.h
@@ -0,0 +1,44 @@
+//===- OutputSymbolTable.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef OUTPUTSYMBOLTABLE_H
+#define OUTPUTSYMBOLTABLE_H
+#include <llvm/ADT/StringRef.h>
+#include "mcld/LD/SymbolTableIF.h"
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class OutputSymbolTable
+ *  \brief Output symbol table, for MCLDOutput.
+ *
+ *  \see
+ */
+class OutputSymbolTable : public SymbolTableIF
+{
+  /* draft. */
+  friend class SymbolTableFactory;
+private:
+  OutputSymbolTable(StrSymPool &pStrSymPool,
+                    size_t pNumOfSymbols,
+                    StringTable &pEntireStringTable,
+                    StringTable &pDynamicStringTable);
+private:
+  virtual void doInsertSymbol(LDSymbol *);
+  virtual void doMerge(const SymbolTableIF &);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Relocation.h b/include/mcld/LD/Relocation.h
new file mode 100644
index 0000000..09ff6e4
--- /dev/null
+++ b/include/mcld/LD/Relocation.h
@@ -0,0 +1,115 @@
+//===- Relocation.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_RELOCATION_H
+#define LD_RELOCATION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/MC/MCFragmentRef.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDSymbol.h>
+
+
+namespace mcld
+{
+class Layout;
+class RelocationFactory;
+class MCLDInfo;
+
+class Relocation : public llvm::MCFragment
+{
+friend class RelocationFactory;
+
+public:
+  typedef uint64_t Address; // FIXME: use SizeTrait<T>::Address instead
+  typedef uint64_t DWord; // FIXME: use SizeTrait<T>::Word instead
+  typedef uint8_t Type;
+
+private:
+  Relocation(Type pType,
+             MCFragmentRef* pTargetRef,
+             Address pAddend,
+             DWord pTargetData);
+
+public:
+  ~Relocation();
+
+  /// type - relocation type
+  Type type() const
+  { return m_Type; }
+
+  /// symValue - S value - the symbol address
+  Address symValue() const;
+
+  /// addend - A value
+  Address addend() const
+  { return m_Addend; }
+
+  /// place - P value - address of the place being relocated
+  Address place(const Layout& pLayout) const;
+
+  /// symbol info - binding, type
+  const ResolveInfo* symInfo() const
+  { return m_pSymInfo; }
+
+  /// symbol info - binding, type
+  ResolveInfo* symInfo()
+  { return m_pSymInfo; }
+
+  /// target - the target data to relocate
+  DWord& target();
+
+  /// target - the target data to relocate
+  const DWord& target() const;
+
+  /// targetRef - the reference of the target data
+  MCFragmentRef& targetRef()
+  { return m_TargetAddress; }
+
+  /// targetRef - the reference of the target data
+  const MCFragmentRef& targetRef() const
+  { return m_TargetAddress; }
+
+  void apply(RelocationFactory& pRelocFactory, const MCLDInfo& pLDInfo);
+
+  /// ----- modifiers ----- ///
+  void setType(Type pType);
+
+  void setAddend(Address pAddend);
+
+  void setSymInfo(ResolveInfo* pSym);
+
+  // Relocation is a kind of MCFragment with type of FT_Reloc
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == MCFragment::FT_Reloc;}
+  static bool classof(const Relocation *) { return true; }
+
+private:
+  /// m_Type - the type of the relocation entries
+  Type m_Type;
+
+  /// m_TargetData - target data of the place being relocated
+  DWord m_TargetData;
+
+  /// m_pSymInfo - resolved symbol info of relocation target symbol
+  ResolveInfo* m_pSymInfo;
+
+  /// m_TargetAddress - MCFragmentRef of the place being relocated
+  MCFragmentRef m_TargetAddress;
+
+  /// m_Addend - the addend
+  Address m_Addend;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/RelocationFactory.h b/include/mcld/LD/RelocationFactory.h
new file mode 100644
index 0000000..eed3eae
--- /dev/null
+++ b/include/mcld/LD/RelocationFactory.h
@@ -0,0 +1,81 @@
+//===- Relocation.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_RELOCATION_FACTORY_H
+#define LD_RELOCATION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/Relocation.h>
+
+namespace mcld
+{
+
+class LDSymbol;
+class ResolveInfo;
+class MCFragmentRef;
+class Layout;
+class GOT;
+class TargetLDBackend;
+class MCLDInfo;
+
+/** \class RelocationFactory
+ *  \brief RelocationFactory provides the interface for generating target
+ *  relocation
+ *
+ */
+class RelocationFactory : public GCFactory<Relocation, 0>
+{
+public:
+  typedef Relocation::Type Type;
+  typedef Relocation::Address Address;
+  typedef Relocation::DWord DWord;
+
+public:
+  explicit RelocationFactory(size_t pNum);
+
+  virtual ~RelocationFactory();
+
+  /// apply - general apply function
+  virtual void applyRelocation(Relocation& pRelocation,
+                               const MCLDInfo& pLDInfo) = 0;
+
+  // ----- production ----- //
+  /// produce - produce a relocation entry
+  /// @param pType - the type of the relocation entry
+  /// @param pFragRef - the place to apply the relocation
+  /// @param pAddend - the addend of the relocation entry
+  Relocation* produce(Type pType,
+                      MCFragmentRef& pFragRef,
+                      Address pAddend = 0);
+
+  /// produceEmptyEntry - produce an empty relocation which
+  /// occupied memory space but all contents set to zero.
+  Relocation* produceEmptyEntry();
+
+  void destroy(Relocation* pRelocation);
+
+  void setLayout(const Layout& pLayout);
+
+  // ------ observers -----//
+  const Layout& getLayout() const;
+
+  virtual TargetLDBackend& getTarget() = 0;
+
+  virtual const TargetLDBackend& getTarget() const = 0;
+
+private:
+  const Layout* m_pLayout;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ResolveInfo.h b/include/mcld/LD/ResolveInfo.h
new file mode 100644
index 0000000..f48f1c2
--- /dev/null
+++ b/include/mcld/LD/ResolveInfo.h
@@ -0,0 +1,279 @@
+//===- ResolveInfo.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_RESOLVE_INFO_H
+#define MCLD_RESOLVE_INFO_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class ResolveInfo
+ *  \brief ResolveInfo records the information about how to resolve a symbol.
+ *
+ *  A symbol must have some `attributes':
+ *  - Desc - Defined, Reference, Common or Indirect
+ *  - Binding - Global, Local, Weak
+ *  - IsDyn - appear in dynamic objects or regular objects
+ *  - Type - what the symbol points to
+ *  - Size  - the size of the symbol point to
+ *  - Value - the pointer to another LDSymbol
+ *  In order to save the memory and speed up the performance, MCLinker uses
+ *  a bit field to store all attributes.
+ *
+ *  The maximum string length is (2^16 - 1)
+ */
+class ResolveInfo
+{
+friend class ResolveInfoFactory;
+friend class MCLinker;
+public:
+  typedef uint64_t SizeType;
+
+  /** \enum Type
+   *  \brief What the symbol stand for
+   *
+   *  It is like ELF32_ST_TYPE
+   *  MachO does not need this, and can not jump between Thumb and ARM code.
+   */
+  enum Type {
+    NoType        = 0,
+    Object        = 1,
+    Function      = 2,
+    Section       = 3,
+    File          = 4,
+    CommonBlock   = 5,
+    ThreadLocal    = 6,
+    LoProc        = 13,
+    HiProc        = 15
+  };
+
+  /** \enum Desc
+   *  \brief Description of the symbols.
+   *
+   *   Follow the naming in MachO. Like MachO nlist::n_desc
+   *   In ELF, is a part of st_shndx
+   */
+  enum Desc {
+    Undefined    = 0,
+    Define       = 1,
+    Common       = 2,
+    Indirect     = 3,
+    NoneDesc
+  };
+
+  enum Binding {
+    Global       = 0,
+    Weak         = 1,
+    Local        = 2,
+    Absolute     = 3,
+    NoneBinding
+  };
+
+  enum Visibility {
+    Default      = 0,
+    Internal     = 1,
+    Hidden       = 2,
+    Protected    = 3
+  };
+
+  // -----  For HashTable  ----- //
+  typedef llvm::StringRef key_type;
+
+public:
+  // -----  modifiers  ----- //
+  /// setRegular - set the source of the file is a regular object
+  void setRegular();
+
+  /// setDynamic - set the source of the file is a dynamic object
+  void setDynamic();
+
+  /// setSource - set the source of the file
+  /// @param pIsDyn is the source from a dynamic object?
+  void setSource(bool pIsDyn);
+
+  void setType(uint32_t pType);
+
+  void setDesc(uint32_t pDesc);
+
+  void setBinding(uint32_t pBinding);
+
+  void setOther(uint32_t pOther);
+
+  void setVisibility(Visibility pVisibility);
+
+  void setIsSymbol(bool pIsSymbol);
+
+  void setReserved(uint32_t pReserved);
+
+  void setSize(SizeType pSize)
+  { m_Size = pSize; }
+
+  void override(const ResolveInfo& pForm);
+
+  void overrideAttributes(const ResolveInfo& pFrom);
+
+  void overrideVisibility(const ResolveInfo& pFrom);
+
+  void setSymPtr(const LDSymbol* pSymPtr)
+  { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
+
+  void setLink(const ResolveInfo* pTarget) {
+    m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget);
+    m_BitField |= indirect_flag;
+  }
+
+
+  // -----  observers  ----- //
+  bool isSymbol() const;
+
+  bool isString() const;
+
+  bool isGlobal() const;
+
+  bool isWeak() const;
+
+  bool isLocal() const;
+
+  bool isAbsolute() const;
+
+  bool isDefine() const;
+
+  bool isUndef() const;
+
+  bool isDyn() const;
+
+  bool isCommon() const;
+
+  bool isIndirect() const;
+
+  uint32_t type() const;
+
+  uint32_t desc() const;
+
+  uint32_t binding() const;
+
+  uint32_t reserved() const;
+
+  uint8_t other() const
+  { return (uint8_t)visibility(); }
+
+  Visibility visibility() const;
+
+  LDSymbol* outSymbol()
+  { return m_Ptr.sym_ptr; }
+
+  const LDSymbol* outSymbol() const
+  { return m_Ptr.sym_ptr; }
+
+  ResolveInfo* link()
+  { return m_Ptr.info_ptr; }
+
+  const ResolveInfo* link() const
+  { return m_Ptr.info_ptr; }
+
+  SizeType size() const
+  { return m_Size; }
+
+  const char* name() const
+  { return m_Name; }
+
+  unsigned int nameSize() const
+  { return (m_BitField >> NAME_LENGTH_OFFSET); }
+
+  uint32_t info() const
+  { return (m_BitField & INFO_MASK); }
+
+  uint32_t bitfield() const
+  { return m_BitField; }
+
+  // -----  For HashTable  ----- //
+  bool compare(const key_type& pKey);
+
+private:
+  static const uint32_t GLOBAL_OFFSET      = 0;
+  static const uint32_t GLOBAL_MASK        = 1;
+
+  static const uint32_t DYN_OFFSET         = 1;
+  static const uint32_t DYN_MASK           = 1   << DYN_OFFSET;
+
+  static const uint32_t DESC_OFFSET        = 2;
+  static const uint32_t DESC_MASK          = 0x3 << DESC_OFFSET;
+
+  static const uint32_t LOCAL_OFFSET       = 4;
+  static const uint32_t LOCAL_MASK         = 1   << LOCAL_OFFSET;
+
+  static const uint32_t BINDING_MASK       = GLOBAL_MASK | LOCAL_MASK;
+
+  static const uint32_t VISIBILITY_OFFSET  = 5;
+  static const uint32_t VISIBILITY_MASK    = 0x3 << VISIBILITY_OFFSET;
+
+  static const uint32_t TYPE_OFFSET        = 7;
+  static const uint32_t TYPE_MASK          = 0xF << TYPE_OFFSET;
+
+  static const uint32_t SYMBOL_OFFSET      = 11;
+  static const uint32_t SYMBOL_MASK        = 1   << SYMBOL_OFFSET;
+
+  static const uint32_t RESERVED_OFFSET    = 12;
+  static const uint32_t RESERVED_MASK      = 0xF << RESERVED_OFFSET;
+  static const uint32_t NAME_LENGTH_OFFSET = 16;
+  static const uint32_t INFO_MASK          = 0xF;
+  static const uint32_t RESOLVE_MASK       = 0xFFFF;
+
+  union SymOrInfo {
+    LDSymbol*    sym_ptr;
+    ResolveInfo* info_ptr;
+  };
+
+public:
+  static const uint32_t global_flag    = 0        << GLOBAL_OFFSET;
+  static const uint32_t weak_flag      = 1        << GLOBAL_OFFSET;
+  static const uint32_t regular_flag   = 0        << DYN_OFFSET;
+  static const uint32_t dynamic_flag   = 1        << DYN_OFFSET;
+  static const uint32_t undefine_flag  = 0        << DESC_OFFSET;
+  static const uint32_t define_flag    = 1        << DESC_OFFSET;
+  static const uint32_t common_flag    = 2        << DESC_OFFSET;
+  static const uint32_t indirect_flag  = 3        << DESC_OFFSET;
+  static const uint32_t local_flag     = 1        << LOCAL_OFFSET;
+  static const uint32_t absolute_flag  = BINDING_MASK;
+  static const uint32_t object_flag    = Object   << TYPE_OFFSET;
+  static const uint32_t function_flag  = Function << TYPE_OFFSET;
+  static const uint32_t section_flag   = Section  << TYPE_OFFSET;
+  static const uint32_t file_flag      = File     << TYPE_OFFSET;
+  static const uint32_t string_flag    = 0        << SYMBOL_OFFSET;
+  static const uint32_t symbol_flag    = 1        << SYMBOL_OFFSET;
+
+private:
+  ResolveInfo();
+  ResolveInfo(const ResolveInfo& pCopy);
+  ResolveInfo& operator=(const ResolveInfo& pCopy);
+  ~ResolveInfo();
+
+private:
+  SizeType m_Size;
+  SymOrInfo m_Ptr;
+
+  /** m_BitField
+   *  31     ...    16 15    12 11     10..7 6      ..    5 4     3   2   1   0
+   * |length of m_Name|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak|
+   */
+  uint32_t m_BitField;
+  char m_Name[0];
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ResolveInfoFactory.h b/include/mcld/LD/ResolveInfoFactory.h
new file mode 100644
index 0000000..fcadf48
--- /dev/null
+++ b/include/mcld/LD/ResolveInfoFactory.h
@@ -0,0 +1,37 @@
+//===- ResolveInfoFactory.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_RESOLVE_INFO_FACTORY_H
+#define MCLD_RESOLVE_INFO_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/ResolveInfo.h"
+
+namespace mcld
+{
+
+/** \class ResolveInfoFactory
+ *  \brief ResolveInfoFactory creates ResolveInfos.
+ */
+class ResolveInfoFactory
+{
+public:
+  typedef ResolveInfo           entry_type;
+  typedef ResolveInfo::key_type key_type;
+
+public:
+  entry_type* produce(const key_type& pKey);
+  void destroy(entry_type* pEntry);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Resolver.h b/include/mcld/LD/Resolver.h
new file mode 100644
index 0000000..98dfe2c
--- /dev/null
+++ b/include/mcld/LD/Resolver.h
@@ -0,0 +1,100 @@
+//===- Resolver.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_RESOLVER_H
+#define MCLD_SYMBOL_RESOLVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <string>
+#include <utility>
+
+namespace mcld
+{
+
+class ResolveInfo;
+class StrSymPool;
+
+/** \class Resolver
+ *  \brief Resolver binds a symbol reference from one file to a symbol
+ *   definition of another file.
+ *
+ *  Resolver seals up the algorithm of symbol resolution. The resolution of
+ *  two symbols depends on their type, binding and whether it is belonging to
+ *  a shared object.
+ */
+class Resolver
+{
+public:
+  enum Action {
+    Success,
+    Warning,
+    Abort,
+    LastAction
+  };
+
+  /** \class Resolver::Result
+   *  \brief the result of symbol resolution
+   *   - info, the pointer to overrided info
+   *   - existent, if true, the info is existent
+   *   - overriden, if true, the info is being overriden.
+   */
+  struct Result {
+    ResolveInfo* info;
+    bool existent;
+    bool overriden;
+  };
+
+public:
+  Resolver();
+
+  Resolver(const Resolver& pCopy);
+
+  virtual ~Resolver();
+
+  /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew?
+  /// @return the action should be taken.
+  /// @param pOld the symbol which may be overridden.
+  /// @param pNew the symbol which is used to replace pOld
+  virtual unsigned int resolve(ResolveInfo & __restrict__ pOld,
+                               const ResolveInfo & __restrict__ pNew,
+                               bool &pOverride) = 0;
+
+  /// resolveAgain - Can override by derived classes.
+  /// @return the pointer to resolved ResolveInfo
+  /// @return is the symbol existent?
+  virtual void resolveAgain(StrSymPool& pStrSymPool,
+                              unsigned int pAction,
+                              ResolveInfo& __restrict__ pOld,
+                              const ResolveInfo& __restrict__ pNew,
+                              Result& pResult) {
+    pResult.info = NULL;
+    pResult.existent = false;
+    pResult.overriden = false;
+  }
+
+  const std::string& mesg() const
+  { return m_Mesg; }
+
+  void clearMesg();
+
+  Resolver* clone() const {
+    return doClone();
+  }
+
+protected:
+  std::string m_Mesg;
+
+private:
+  virtual Resolver* doClone() const = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SectionMap.h b/include/mcld/LD/SectionMap.h
new file mode 100644
index 0000000..424d785
--- /dev/null
+++ b/include/mcld/LD/SectionMap.h
@@ -0,0 +1,105 @@
+//===- SectionMap.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTION_MAP_H
+#define MCLD_SECTION_MAP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+
+/** \class SectionMap
+ *  \brief descirbe the mappings of input section's name (or prefix) to
+ *         its associated output section's name and offset
+ */
+class SectionMap
+{
+public:
+  // a mapping in SectionMap is the triple of
+  // {input substr, output section's name, output section's offset}
+  struct Mapping {
+    std::string inputSubStr;
+    std::string outputStr;
+    uint64_t offset;
+  };
+
+  typedef std::vector<struct Mapping> SectionMappingTy;
+
+  typedef SectionMappingTy::iterator iterator;
+  typedef SectionMappingTy::const_iterator const_iterator;
+
+public:
+  SectionMap();
+  ~SectionMap();
+
+  // get the possible output section name based on the mapping table
+  // return NULL if not found
+  const std::string& getOutputSectName(const std::string& pInput);
+
+  // add a mapping from input substr to output name and offset.
+  bool push_back(const std::string& pInput,
+                 const std::string& pOutput,
+                 const uint64_t pOffset = 0);
+
+  // find - return the iterator to the mapping
+  iterator find(const std::string& pInput);
+
+  // at - return the pointer to the mapping
+  Mapping* at(const std::string& pInput);
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return m_SectMap.empty(); }
+
+  size_t size() const
+  { return m_SectMap.size(); }
+
+  size_t capacity () const
+  { return m_SectMap.capacity(); }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_SectMap.begin(); }
+
+  iterator end()
+  { return m_SectMap.end(); }
+
+  const_iterator begin() const
+  { return m_SectMap.begin(); }
+
+  const_iterator end() const
+  { return m_SectMap.end(); }
+
+  // initStdSectionMap - add common mappings of ELF and other formats
+  // to SectionMap
+  bool initStdSectionMap();
+
+private:
+  struct SectionNameMapping {
+    const char* from;
+    const char* to;
+  };
+
+  // used to store common mappings of ELF and other formants
+  static const SectionNameMapping m_StdSectionMap[];
+
+  static const int m_StdSectionMapSize;
+
+  SectionMappingTy m_SectMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SectionMerger.h b/include/mcld/LD/SectionMerger.h
new file mode 100644
index 0000000..40f1453
--- /dev/null
+++ b/include/mcld/LD/SectionMerger.h
@@ -0,0 +1,98 @@
+//===- SectionMerger.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTION_MERGER_H
+#define MCLD_SECTION_MERGER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+#include <string>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/SectionMap.h>
+
+namespace mcld
+{
+class MCLinker;
+
+/** \class SectionMerger
+ *  \brief maintain the mappings of substr of input section name to associated
+ *         output section (data)
+ */
+class SectionMerger
+{
+public:
+  struct Mapping {
+    std::string inputSubStr;
+    LDSection* outputSection;
+  };
+  typedef std::vector<Mapping> LDSectionMapTy;
+
+  typedef LDSectionMapTy::iterator iterator;
+  typedef LDSectionMapTy::const_iterator const_iterator;
+
+public:
+  SectionMerger(SectionMap& pSectionMap, LDContext& pContext);
+  ~SectionMerger();
+
+  /// getOutputSectHdr - return a associated output section header
+  LDSection* getOutputSectHdr(const std::string& pName);
+
+  /// getOutputSectData - return a associated output section data
+  llvm::MCSectionData* getOutputSectData(const std::string& pName);
+
+  /// addMapping - add a mapping as creating one new output LDSection
+  /// @param pName - a input section name
+  /// @param pSection - the output LDSection*
+  bool addMapping(const std::string& pName, LDSection* pSection);
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return m_LDSectionMap.empty(); }
+
+  size_t size() const
+  { return m_LDSectionMap.size(); }
+
+  size_t capacity () const
+  { return m_LDSectionMap.capacity(); }
+
+  // -----  iterators  ----- //
+  iterator find(const std::string& pName);
+
+  iterator begin()
+  { return m_LDSectionMap.begin(); }
+
+  iterator end()
+  { return m_LDSectionMap.end(); }
+
+  const_iterator begin() const
+  { return m_LDSectionMap.begin(); }
+
+  const_iterator end() const
+  { return m_LDSectionMap.end(); }
+
+private:
+  /// initOutputSectMap - initialize the map from input substr to associated
+  /// output LDSection*
+  void initOutputSectMap();
+
+private:
+  SectionMap& m_SectionNameMap;
+
+  LDContext& m_Output;
+
+  LDSectionMapTy m_LDSectionMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StaticResolver.h b/include/mcld/LD/StaticResolver.h
new file mode 100644
index 0000000..5bf5c5d
--- /dev/null
+++ b/include/mcld/LD/StaticResolver.h
@@ -0,0 +1,145 @@
+//===- StaticResolver.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_STATIC_SYMBOL_RESOLVER_H
+#define MCLD_STATIC_SYMBOL_RESOLVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <string>
+#include <mcld/LD/Resolver.h>
+#include <mcld/LD/ResolveInfo.h>
+
+namespace mcld
+{
+
+class StrSymPool;
+
+/** \class StaticResolver
+ */
+class StaticResolver : public Resolver
+{
+public:
+  /** \enum LinkAction
+   *  LinkAction follows BFD:linker.c (binary file descriptor).
+   *  List all actions to take in the state table
+   */
+  enum LinkAction
+  {
+    FAIL,         /* abort.  */
+    NOACT,        /* no action.  */
+    UND,          /* override by symbol undefined symbol.  */
+    WEAK,         /* override by symbol weak undefined.  */
+    DEF,          /* override by symbol defined.  */
+    DEFW,         /* override by symbol weak defined.  */
+    DEFD,         /* override by symbol dynamic defined.  */
+    DEFWD,        /* override by symbol dynamic weak defined.  */
+    MDEFD,        /* mark symbol dynamic defined.  */
+    MDEFWD,       /* mark symbol dynamic weak defined.  */
+    DUND,         /* override dynamic defined symbol by undefined one.  */
+    DUNDW,        /* oevrride dynamic defined symbol by weak undefined one.  */
+    COM,          /* override by symbol common.  */
+    CREF,         /* Possibly warn about common reference to defined symbol.  */
+    CDEF,         /* redefine existing common symbol.  */
+    BIG,          /* override by symbol common using largest size.  */
+    MBIG,         /* mark common symbol by larger size.  */
+    IND,          /* override by indirect symbol.  */
+    CIND,         /* mark indirect symbol from existing common symbol.  */
+    MDEF,         /* multiple definition error.  */
+    MIND,         /* multiple indirect symbols.  */
+    REFC          /* Mark indirect symbol referenced and then CYCLE.  */
+  };
+
+private:
+  // These are the values generated by the bit codes.
+  /** Encoding:
+   *  D -> define
+   *  U -> undefine
+   *  d -> dynamic
+   *  w -> weak
+   *  C -> common
+   *  I -> indirect
+   */
+  enum
+  {
+    U    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,
+    w_U  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,
+    d_U  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,
+    wd_U = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,
+    D    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag,
+    w_D  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::define_flag,
+    d_D  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,
+    wd_D = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,
+    C    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, 
+    w_C  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::common_flag,
+    d_C  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,
+    wd_C = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,
+    I    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,
+    w_I  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,
+    d_I  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag,
+    wd_I = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag
+  };
+
+  enum ORDINATE
+  {
+    U_ORD,
+    w_U_ORD,
+    d_U_ORD,
+    wd_U_ORD,
+    D_ORD,
+    w_D_ORD,
+    d_D_ORD,
+    wd_D_ORD,
+    C_ORD,
+    w_C_ORD,
+    Cs_ORD,
+    Is_ORD,
+    LAST_ORD
+  };
+
+public:
+  StaticResolver();
+
+  StaticResolver(const StaticResolver& pCopy);
+
+  virtual ~StaticResolver();
+
+  /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew?
+  /// @return the action should be taken.
+  /// @param pOld the symbol which may be overridden.
+  /// @param pNew the symbol which is used to replace pOld
+  virtual unsigned int resolve(ResolveInfo & __restrict__ pOld,
+                               const ResolveInfo & __restrict__ pNew,
+                               bool &pOverride);
+
+  StaticResolver* doClone() const {
+    return new StaticResolver(*this);
+  }
+
+private:
+  inline unsigned int getOrdinate(const ResolveInfo& pInfo) const {
+    if (pInfo.isAbsolute() && pInfo.isDyn())
+      return d_D_ORD;
+    if (pInfo.isAbsolute())
+      return D_ORD;
+    if (pInfo.isCommon() && pInfo.isDyn())
+      return Cs_ORD;
+    if (pInfo.isCommon() && pInfo.isDefine())
+      return C_ORD;
+    if (pInfo.isCommon() && pInfo.isWeak())
+      return w_C_ORD;
+    if (pInfo.isIndirect())
+      return Is_ORD;
+    return pInfo.info();
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StrSymPool.h b/include/mcld/LD/StrSymPool.h
new file mode 100644
index 0000000..da5ed1f
--- /dev/null
+++ b/include/mcld/LD/StrSymPool.h
@@ -0,0 +1,111 @@
+//===- StrSymPool.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_STRING_SYMBOL_POOL_H
+#define MCLD_STRING_SYMBOL_POOL_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/StringRef.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/StringHash.h>
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/Resolver.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+#include <utility>
+
+namespace llvm
+{
+  class MCSectionData;
+}
+
+namespace mcld
+{
+
+class Resolver;
+class StringTable;
+class SymbolTableIF;
+
+/** \class StrSymPool
+ *  \brief Store symbol and search symbol by name. Can help symbol resolution.
+ *
+ *  - MCLinker is responsed for creating StrSymPool.
+ */
+class StrSymPool : private Uncopyable
+{
+public:
+  typedef HashTable<ResolveInfo, StringHash<ELF>, ResolveInfoFactory> Table;
+  typedef size_t size_type;
+
+public:
+  StrSymPool(const Resolver& pResolver, size_type pSize = 3);
+  ~StrSymPool();
+
+  // -----  modifiers  ----- //
+  /// createSymbol - create a symbol but do not insert into the pool.
+  ResolveInfo* createSymbol(const llvm::StringRef& pName,
+                            bool pIsDyn,
+                            ResolveInfo::Type pType,
+                            ResolveInfo::Desc pDesc,
+                            ResolveInfo::Binding pBinding,
+                            ResolveInfo::SizeType pSize,
+                            ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+  
+  /// insertSymbol - insert a symbol and resolve the symbol immediately
+  /// @param pOldInfo - if pOldInfo is not NULL, the old ResolveInfo being
+  ///                   overriden is kept in pOldInfo.
+  /// @param pResult the result of symbol resultion.
+  /// @note pResult.override is true if the output LDSymbol also need to be
+  ///       overriden
+  void insertSymbol(const llvm::StringRef& pName,
+                    bool pIsDyn,
+                    ResolveInfo::Type pType,
+                    ResolveInfo::Desc pDesc,
+                    ResolveInfo::Binding pBinding,
+                    ResolveInfo::SizeType pSize,
+                    ResolveInfo::Visibility pVisibility,
+                    ResolveInfo* pOldInfo,
+                    Resolver::Result& pResult);
+
+  /// findSymbol - find the resolved output LDSymbol
+  LDSymbol* findSymbol(const llvm::StringRef& pName);
+  const LDSymbol* findSymbol(const llvm::StringRef& pName) const;
+
+  /// findInfo - find the resolved ResolveInfo
+  ResolveInfo* findInfo(const llvm::StringRef& pName);
+  const ResolveInfo* findInfo(const llvm::StringRef& pName) const;
+
+  /// insertString - insert a string
+  /// if the string has existed, modify pString to the existing string
+  /// @return the StringRef points to the hash table
+  llvm::StringRef insertString(const llvm::StringRef& pString);
+
+  // -----  observers  ----- //
+  size_type size() const
+  { return m_Table.numOfEntries(); }
+
+  bool empty() const
+  { return m_Table.empty(); }
+
+  // -----  capacity  ----- //
+  void reserve(size_type pN);
+
+  size_type capacity() const;
+
+private:
+  Resolver* m_pResolver;
+  Table m_Table;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StringUnorderedMap.h b/include/mcld/LD/StringUnorderedMap.h
new file mode 100644
index 0000000..05788aa
--- /dev/null
+++ b/include/mcld/LD/StringUnorderedMap.h
@@ -0,0 +1,225 @@
+//===- StringUnorderedMap.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SEARCH_TABLE_H
+#define MCLD_SEARCH_TABLE_H
+#include <vector>
+// For std::allocate.
+#include <memory>
+// For uint32_t.
+#include <stdint.h>
+#include <cassert>
+// For memset.
+#include <cstring>
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+/* FIXME: Move StringUnorderedMap under ADT. */
+
+namespace mcld
+{
+
+struct StringUnorderedMapDefaultHash
+{
+  size_t operator()(const char *pStr) {
+    size_t hashVal = 31;
+    while (*pStr)
+      hashVal = hashVal * 131 + (*pStr++);
+    return hashVal;
+  }
+};
+
+template<typename ValueType,
+         typename KeyType>
+struct StringUnorderedMapEntryInit
+{
+  template <typename InitType>
+  void operator()(KeyType &pKey, ValueType &pValue,
+                  const KeyType &pStr, InitType pInitVal) {
+    ::new ((void*)&pKey) KeyStorageType(pStr);
+    ::new ((void*)&pValue) ValueType(pInitVal);
+  }
+};
+
+uint32_t findNextPrime(uint32_t x);
+
+/** \class StringUnorderedMap
+ *  \brief The most simple hash of linked list version.
+ *
+ *  \see
+ */
+template<typename KeyType,
+         typename ValueType,
+         typename KeyCompareFunctor,
+         typename HashFunction = StringUnorderedMapDefaultHash,
+         typename Allocator = std::allocator<std::pair<KeyType, ValueType> > >
+class StringUnorderedMap
+{
+public:
+  explicit StringUnorderedMap(size_t pCapacity = 17)
+  : m_Impl(pCapacity)
+  {}
+
+  ~StringUnorderedMap();
+
+  void reserve(size_t pCapacity);
+
+  ValueType &getOrCreate(const KeyType &pStr, const ValueType &pInitVal);
+
+  ValueType &getOrCreate(const KeyType &pStr);
+
+  bool empty()
+  { return m_Size == 0; }
+
+  size_t capacity() const
+  { return m_Capacity; }
+
+  void clear();
+
+private:
+  struct HashEntry {
+    size_t hashVal;
+    std::pair<KeyType, ValueType>
+    HashEntry *next;
+  };
+  typedef Allocator::template rebind<HashEntry>::other HashEntryAllocator;
+  void rehash(size_t pCapacity);
+
+private:
+  size_t m_Capacity;
+  size_t m_Size;
+  // array of pointers to hash entries
+  HashEntry **m_HashTable;
+  HashEntryAllocator m_HashEntryAllocator;
+};
+
+
+// =================================implementation============================
+// StringUnorderedMap::StringUnorderedMapImpl
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::StringUnorderedMapImpl(size_t pCapacity)
+  : m_Capacity(0), m_Size(0), m_HashTable(0)
+{
+  this->reserve(pCapacity);
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::reserve(size_t pCapacity)
+{
+  if (pCapacity < this->m_Capacity)
+    return;
+  size_t nextSize = findNextPrime(static_cast<uint32_t>(pCapacity));
+  // FIXME: Error handling.
+  assert(nextSize > this->m_Capacity && "findNextPrime error.");
+  if (this->m_Capacity != nextSize)
+    this->rehash(nextSize);
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::rehash(size_t pCapacity)
+{
+  HashEntry **tmpTable = new HashEntry*[pCapacity];
+  std::memset(tmpTable, 0, pCapacity * sizeof(HashEntry*));
+  if (this->m_HashTable) {
+    for (size_t i = 0; i < this->m_Capacity; ++i)
+      for (HashEntry *j = this->m_HashTable[i]; j != 0; ) {
+        HashEntry *nextJ = j->next;
+        j->next = tmpTable[j->hashVal % pCapacity];
+        tmpTable[j->hashVal % pCapacity] = j;
+        j = nextJ;
+      }
+    delete[] m_HashTable;
+  }
+  this->m_Capacity = pCapacity;
+  this->m_HashTable = tmpTable;
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+template<typename InitType>
+ValueType &
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::getOrCreate(const KeyType &pStr, ValueType &pInitVal)
+{
+  HashFunction hash;
+  size_t hashVal = hash(pStr);
+  HashEntry *&head =  this->m_HashTable[hashVal % this->m_Capacity];
+
+  HashEntry *ans = 0;
+  for(HashEntry *ptr = head; ptr != 0; ptr = ptr->next)
+    if(hashVal == ptr->hashVal && pStr.equals(ptr->str)) {
+      ans = ptr;
+      break;
+    }
+  if (ans == 0) {
+    ans = this->allocate(1);
+    ans->hashVal = hashVal;
+    StringUnorderedMapEntryInit<ValueType, KeyStorageType> init;
+    init(ans->str, ans->value, pStr, pInitVal);
+    ans->next = head;
+    head = ans;
+    ++m_Size;
+    if(this->m_Size * 4LL >= this->m_Capacity * 3LL) // load factor = 0.75
+      this->reserve(this->m_Capacity+1);
+  }
+
+  return ans->value;
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::clear()
+{
+  if (this->m_HashTable) {
+    for (size_t i = 0; i < this->m_Capacity; ++i)
+      for (HashEntry *j = this->m_HashTable[i]; j != 0; ) {
+        HashEntry *nextJ = j->next;
+        this->destroy(j);
+        this->deallocate(j, 1);
+        j = nextJ;
+      }
+    delete[] m_HashTable;
+  }
+}
+
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::~StringUnorderedMapImpl()
+{
+  this->clear();
+}
+
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SymbolTableFactory.h b/include/mcld/LD/SymbolTableFactory.h
new file mode 100644
index 0000000..cc02241
--- /dev/null
+++ b/include/mcld/LD/SymbolTableFactory.h
@@ -0,0 +1,73 @@
+//===- SymbolTableFactory.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_TABLE_FACTORY_H
+#define MCLD_SYMBOL_TABLE_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/InputSymbolTable.h"
+#include "mcld/LD/OutputSymbolTable.h"
+
+namespace mcld
+{
+
+class StringTable;
+class StrSymPool;
+
+/** \class SymbolTableFactory
+ *  \brief SymbolTableFactory manages SymbolTableIFs.
+ *
+ *  SymbolTableFactory is responsed for construction and destruction of 
+ *  SymbolTableIF. Since different MCLDFiles have different type of 
+ *  SymbolTableIF, SymbolTableFactory separates the construction of 
+ *  SymbolTableIF into createInputTable() and createOutputTable().
+ *
+ *  @see SymbolTableIF InputSymbolTable OutputSymbolTable
+ */
+class SymbolTableFactory
+{
+public:
+  /// SymbolTableFactory - constructor
+  //  @param pNumOfSymbolTables is the most appropriate number of created 
+  //  symbol tables.
+  //  @param pStorage the real storage of created symbols
+  explicit SymbolTableFactory(size_t pNumOfSymbolTables,
+                              StrSymPool& pStrSymPool);
+  /// ~SymbolTableFactory - destructor
+  //  destructor destroys all created symbol tables.
+  ~SymbolTableFactory();
+
+  /// createInputTable - create a symbol table for an input file
+  //  @param pEntireStringTable the string table of created Symbols.
+  //  @param pDynamicStringTable the string table of created Dynamic Symbols.
+  //  @param pReserve Created symbol table must reserve pReserve number of 
+  //  storages of symbol for creating symbols.
+  SymbolTableIF *createInputTable(StringTable &pEntireStringTable,
+                                  StringTable &pDynamicStringTable,
+                                  size_t pReserve=256);
+
+  /// createOutputTable - create a symbol table for an output file
+  //  @param pEntireStringTable the string table of created Symbols.
+  //  @param pDynamicStringTable the string table of created Dynamic Symbols.
+  //  @param pReserve Created symbol table must reserve pReserve number of 
+  //  storages of symbol for creating symbols.
+  SymbolTableIF *createOutputTable(StringTable &pEntireStringTable,
+                                   StringTable &pDynamicStringTable,
+                                   size_t pReserve=256);
+private:
+  StrSymPool &m_StrSymPool;
+  GCFactory<InputSymbolTable, 0> m_InputFactory;
+  GCFactory<OutputSymbolTable, 0> m_OutputFactory;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/AttributeFactory.h b/include/mcld/MC/AttributeFactory.h
new file mode 100644
index 0000000..eb4368b
--- /dev/null
+++ b/include/mcld/MC/AttributeFactory.h
@@ -0,0 +1,99 @@
+//===- AttributeFactory.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ATTRIBUTE_FACTORY_H
+#define MCLD_ATTRIBUTE_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/MC/MCLDAttribute.h"
+
+namespace mcld
+{
+
+/** \class AttributeFactory
+ *  \brief AttributeFactory contructs the AttributeProxys.
+ *
+ *  Since the number of AttributeProxys is usually small, sequential search
+ *  on a small vector is enough.
+ */
+class AttributeFactory : private Uncopyable
+{
+private:
+  typedef std::vector<Attribute*> AttrSet;
+
+public:
+  typedef AttrSet::iterator iterator;
+  typedef AttrSet::const_iterator const_iterator;
+
+public:
+  AttributeFactory();
+  explicit AttributeFactory(size_t pNum);
+  ~AttributeFactory();
+
+  // reserve - reserve the memory space for attributes
+  // @param pNum the number of reserved attributes
+  void reserve(size_t pNum);
+
+  // predefined - return the predefined attribute
+  Attribute& predefined();
+  const Attribute& predefined() const;
+  
+  // constraint - return the constraint of attributes
+  AttrConstraint& constraint()
+  { return m_Constraint; }
+
+  const AttrConstraint& constraint() const
+  { return m_Constraint; }
+
+  // produce - produce a attribute, but do not record it yet.
+  // the produced attribute is identical to the pre-defined attribute.
+  AttributeProxy* produce();
+
+  // last - the last touched attribute.
+  AttributeProxy& last();
+  const AttributeProxy& last() const;
+
+  // exists- return the recorded attribute whose content is identical to the
+  // input attribute.
+  Attribute *exists(const Attribute& pAttr) const;
+
+  // record - record the attribute no mater if it has been recorded.
+  void record(Attribute& pAttr);
+
+  // -----  observers  ----- //
+  size_t size() const
+  { return m_AttrSet.size(); }
+
+  bool empty() const
+  { return m_AttrSet.empty(); }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_AttrSet.begin(); }
+
+  iterator end()
+  { return m_AttrSet.end(); }
+
+  const_iterator begin() const
+  { return m_AttrSet.begin(); }
+
+  const_iterator end() const
+  { return m_AttrSet.end(); }
+
+private:
+  AttrSet m_AttrSet;
+  AttrConstraint m_Constraint;
+  AttributeProxy *m_pLast;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/ContextFactory.h b/include/mcld/MC/ContextFactory.h
new file mode 100644
index 0000000..1ae0d45
--- /dev/null
+++ b/include/mcld/MC/ContextFactory.h
@@ -0,0 +1,47 @@
+//===- ContextFactory.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_CONTEXT_FACTORY_H
+#define MCLD_CONTEXT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDContext.h>
+#include <mcld/Support/UniqueGCFactory.h>
+#include <mcld/Support/Path.h>
+
+namespace mcld
+{
+/** \class ContextFactory
+ *  \brief ContextFactory avoids the duplicated LDContext of the same file.
+ *
+ *  MCLinker is designed for efficient memory usage. Because user can give
+ *  MCLinker the same input file many times on the command line, MCLinker must
+ *  avoid opening identical file twice.
+ *
+ *  ContextFactory is the guard to prevent redundant opening. MCLinker does not
+ *  create LDContext directly. Instead, it creates LDContext by ContextFactory.
+ *  ContextFactory returns the identical reference of LDContext if it's openend.
+ *
+ *  @see LDContext
+ *  @see UniqueGCFactoryBase
+ */
+class ContextFactory : public UniqueGCFactoryBase<sys::fs::Path, LDContext, 0>
+{
+public:
+  explicit ContextFactory(size_t pNum);
+  ~ContextFactory();
+
+  LDContext* produce(const sys::fs::Path& pPath);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/InputFactory.h b/include/mcld/MC/InputFactory.h
new file mode 100644
index 0000000..5dc99c4
--- /dev/null
+++ b/include/mcld/MC/InputFactory.h
@@ -0,0 +1,56 @@
+//===- InputFactory.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_INPUT_FACTORY_H
+#define MCLD_INPUT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/GCFactory.h"
+#include "mcld/MC/MCLDInput.h"
+
+namespace mcld
+{
+
+class AttributeFactory;
+
+/** \class InputFactory
+ *  \brief InputFactory controls the production and destruction of
+ *  MCLDInput.
+ *
+ *  All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
+ *  while MCLDFileFactory is destructed.
+ *
+ *  FIXME: the number of the Inputs should be passed in by Target or any
+ *  target specific class.
+ *
+ *  \see llvm::sys::Path
+ */
+class InputFactory : public GCFactory<Input,0>
+{
+public:
+  typedef GCFactory<Input, 0> Alloc;
+
+public:
+  InputFactory(size_t pNum, AttributeFactory& pAttrFactory);
+  ~InputFactory();
+
+  // -----  production  ----- //
+  Input* produce(llvm::StringRef pName,
+                 const sys::fs::Path& pPath,
+                 unsigned int pType = Input::Unknown,
+                 off_t pFileOffset = 0);
+
+private:
+  AttributeFactory &m_AttrFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCBitcodeInterceptor.h b/include/mcld/MC/MCBitcodeInterceptor.h
new file mode 100644
index 0000000..182b157
--- /dev/null
+++ b/include/mcld/MC/MCBitcodeInterceptor.h
@@ -0,0 +1,75 @@
+//===- MCBitcodeInterceptor.h ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BITCODE_INTERCEPTOR_H
+#define MCLD_BITCODE_INTERCEPTOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCObjectWriter.h>
+
+
+namespace llvm
+{
+  class MCStreamer;
+  class MCObjectStreamer;
+  class MCAsmLayout;
+  class MCAssembler;
+  class MCFixup;
+  class MCFragment;
+  class MCSymbol;
+  class MCSymbolData;
+  class MCSymbolRefExpr;
+  class MCValue;
+  class raw_ostream;
+} // namespace of llvm
+
+namespace mcld
+{
+
+class MCLDInfo;
+class TargetLDBackend;
+
+/** \class MCBitcodeInterceptor
+ *  \brief MCBitcodeInterceptor converts bitcode into LDContext
+ *
+ *  @see LDContext
+ *  @see MCObjectWriter
+ */
+class MCBitcodeInterceptor : public llvm::MCObjectWriter
+{
+public:
+  MCBitcodeInterceptor(llvm::MCObjectStreamer&, TargetLDBackend&, MCLDInfo&);
+  ~MCBitcodeInterceptor();
+
+  void ExecutePostLayoutBinding(llvm::MCAssembler &Asm,
+                                const llvm::MCAsmLayout &Layout);
+
+  /// RecordRelocation - record relocations
+  //  make a LDRelocation and recordds in the LDContext.
+  void RecordRelocation(const llvm::MCAssembler &Asm,
+                        const llvm::MCAsmLayout &Layout,
+                        const llvm::MCFragment *Fragment,
+                        const llvm::MCFixup &Fixup,
+                        llvm::MCValue Target,
+                        uint64_t &FixedValue);
+
+  /// WriteObject - not really write out a object. Instead, load data to
+  /// LDContext
+  void WriteObject(llvm::MCAssembler &Asm, const llvm::MCAsmLayout &Layout);
+
+private:
+  TargetLDBackend& m_Backend;
+  MCLDInfo& m_LDInfo;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCDataFragment.h b/include/mcld/MC/MCDataFragment.h
new file mode 100644
index 0000000..330c9be
--- /dev/null
+++ b/include/mcld/MC/MCDataFragment.h
@@ -0,0 +1,85 @@
+//===- MCDataFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCDATAFRAGMENT_H
+#define MCDATAFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCInst.h>
+#include <llvm/ADT/SmallString.h>
+#include "mcld/LD/Relocation.h"
+
+namespace mcld
+{
+
+/** \class MCDataFragment
+ *  \brief MCDataFragment for mcld
+ *
+ *  \see
+ *  \author Diana Chen <diana.chen@mediatek.com>
+ */
+class MCDataFragment : public  llvm::MCFragment
+{
+public:
+   typedef std::vector<Relocation*> RelocationsType;
+private:
+
+  ///  m_pFragment - llvm MCDataFragment for this MCDataFragment
+  llvm::MCDataFragment* m_pFragment;
+ 
+  /// m_Relocation - The list of relocations in this fragment
+  RelocationsType m_Relocations;
+
+public:
+  typedef RelocationsType::const_iterator const_relocation_iterator;
+  typedef RelocationsType::iterator relocation_iterator;
+
+public:
+  MCDataFragment(llvm::MCDataFragment& pFragment)
+    : m_pFragment(&pFragment) {
+    setParent( pFragment.getParent() );
+    setAtom( pFragment.getAtom() );
+    setLayoutOrder( pFragment.getLayoutOrder());
+  }
+  ~MCDataFragment(){}
+   
+  // ------ observers ------//
+  llvm::SmallString<32> &getContents() { return m_pFragment->getContents();  }
+  const llvm::SmallString<32> &getContents() const { return m_pFragment->getContents();  }
+
+  // relocation access
+  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
+  
+  RelocationsType &getRelocations() { return m_Relocations; }
+  const RelocationsType &getRelcoations() const { return m_Relocations; }
+
+  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
+  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
+
+  relocation_iterator relocation_end() {return m_Relocations.end();}
+  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
+
+  size_t relocations_size() const { return m_Relocations.size(); }
+
+  // fragment identification
+  static bool classof(const MCFragment *pF) {
+    return pF->getKind() == llvm::MCFragment::FT_Data;
+  }
+  static bool classof(const MCDataFragment *) { return true; }
+  
+  // overwrite parent method
+  FragmentType getKind() const { return m_pFragment->getKind(); } 
+  
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCFragmentRef.h b/include/mcld/MC/MCFragmentRef.h
new file mode 100644
index 0000000..b7d94cd
--- /dev/null
+++ b/include/mcld/MC/MCFragmentRef.h
@@ -0,0 +1,85 @@
+//===- MCFragmentRef.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCFRAGMENT_REFERENCE_H
+#define MCLD_MCFRAGMENT_REFERENCE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/ADT/TypeTraits.h>
+
+namespace mcld
+{
+
+class Layout;
+
+/// compunteFragmentSize - compute the specific MCFragment size
+uint64_t computeFragmentSize(const Layout& pLayout,
+                             const llvm::MCFragment& pFrag);
+
+/** \class MCFragmentRef
+ *  \brief MCFragmentRef is a reference of a MCFragment's contetnt.
+ *
+ */
+class MCFragmentRef
+{
+public:
+  typedef uint64_t Offset; // FIXME: use SizeTraits<T>::Offset
+  typedef NonConstTraits<unsigned char>::pointer Address;
+  typedef ConstTraits<unsigned char>::pointer ConstAddress;
+
+public:
+  MCFragmentRef();
+  MCFragmentRef(llvm::MCFragment& pFrag, Offset pOffset = 0);
+  ~MCFragmentRef();
+
+  // -----  modifiers  ----- //
+  MCFragmentRef& assign(const MCFragmentRef& pCopy);
+
+  MCFragmentRef& assign(llvm::MCFragment& pFrag, Offset pOffset = 0);
+
+  /// memcpy - copy memory
+  /// copy memory from the fragment to the pDesc.
+  /// @pDest - the destination address
+  /// @pNBytes - copies pNBytes from the fragment[offset()+pOffset]
+  /// @pOffset - additional offset. 
+  ///            the start address offset from fragment[offset()]
+  void memcpy(void* pDest, size_t pNBytes, Offset pOffset = 0) const;
+
+  // -----  observers  ----- //
+  llvm::MCFragment* frag()
+  { return m_pFragment; }
+
+  const llvm::MCFragment* frag() const
+  { return m_pFragment; }
+
+  Offset offset() const
+  { return m_Offset; }
+
+  // -----  dereference  ----- //
+  Address deref();
+
+  ConstAddress deref() const;
+
+  Address operator*()
+  { return deref(); }
+
+  ConstAddress operator*() const
+  { return deref(); }
+  
+private:
+  llvm::MCFragment* m_pFragment;
+  Offset m_Offset;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCInstFragment.h b/include/mcld/MC/MCInstFragment.h
new file mode 100644
index 0000000..8625c42
--- /dev/null
+++ b/include/mcld/MC/MCInstFragment.h
@@ -0,0 +1,95 @@
+//===- MCInstFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCINSTFRAGMENT_H
+#define MCINSTFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCInst.h>
+#include <llvm/ADT/SmallString.h>
+#include <llvm/ADT/ilist.h>
+#include "mcld/LD/Relocation.h"
+
+
+namespace mcld
+{
+
+/** \class MCInstFragment
+ *  \brief MCInstFragment for mcld
+ *
+ *  \see
+ *  \author Diana Chen <diana.chen@mediatek.com>
+ */
+class MCInstFragment : public  llvm::MCFragment
+{
+public:
+  typedef std::vector<Relocation*> RelocationsType;
+private:
+
+  ///  m_pFragment - llvm MCInstFragment for this MCInstFragment
+  llvm::MCInstFragment* m_pFragment;
+  
+  /// m_Relocation - The list of relocations in this fragment
+  RelocationsType m_Relocations;
+  
+public:
+  typedef RelocationsType::const_iterator const_relocation_iterator;
+  typedef RelocationsType::iterator relocation_iterator;
+
+public:
+  MCInstFragment( llvm::MCInstFragment& pFragment )
+      : m_pFragment(&pFragment){
+    setParent( pFragment.getParent() );
+    setAtom( pFragment.getAtom() );
+    setLayoutOrder( pFragment.getLayoutOrder());
+  }
+  ~MCInstFragment(){}
+   
+  // ------ observers ------//
+  llvm::SmallVectorImpl<char> &getCode() { return m_pFragment->getCode(); }
+  const llvm::SmallVectorImpl<char> &getCode() const { return m_pFragment->getCode(); }
+
+  unsigned getInstSize() const { return m_pFragment->getCode().size(); }
+
+  llvm::MCInst &getInst() { return m_pFragment->getInst(); }
+  const llvm::MCInst &getInst() const { return m_pFragment->getInst(); }
+  
+  // ----- modifiers ------//
+  void setInst(llvm::MCInst pValue) { m_pFragment->setInst(pValue); }
+
+  // relocation access
+  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
+  
+  RelocationsType &getRelocations() { return m_Relocations; }
+  const RelocationsType &getRelcoations() const { return m_Relocations; }
+
+  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
+  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
+
+  relocation_iterator relocation_end() {return m_Relocations.end();}
+  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
+
+  size_t relocations_size() const { return m_Relocations.size(); }
+
+  // fragment identification
+  static bool classof(const MCFragment *pF) {
+    return pF->getKind() == llvm::MCFragment::FT_Inst;
+  }
+  static bool classof(const MCInstFragment *) { return true; }
+  
+  // overwrite parent method
+  FragmentType getKind() const { return m_pFragment->getKind(); } 
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDAttribute.h b/include/mcld/MC/MCLDAttribute.h
new file mode 100644
index 0000000..829cf61
--- /dev/null
+++ b/include/mcld/MC/MCLDAttribute.h
@@ -0,0 +1,247 @@
+//===- MCLDAttribute.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ATTRIBUTE_H
+#define MCLD_ATTRIBUTE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+class AttributeFactory;
+
+/** \class AttributeBase
+ *  \brief AttributeBase provides the real storage for attributes of options.
+ *
+ *  Attributes are options affecting the link editing of input files.
+ *  Some options affects the input files mentioned on the command line after
+ *  them. For example, --whole-archive option affects archives mentioned on
+ *  the command line after the --whole-archve option. We call such options
+ *  "attributes of input files"
+ *
+ *  AttributeBase is the storage for attributes of input files. Each input
+ *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
+ *  most attributes of input files are identical, our design lets input files
+ *  which have identical attributes share common attribute. AttributeBase is
+ *  the shared storage for attribute.
+ */
+class AttributeBase
+{
+public:
+  AttributeBase()
+  : m_WholeArchive(false),
+    m_AsNeeded(false),
+    m_AddNeeded(true),
+    m_Static(false)
+  { }
+
+  AttributeBase(const AttributeBase& pBase)
+  : m_WholeArchive(pBase.m_WholeArchive),
+    m_AsNeeded(pBase.m_AsNeeded),
+    m_AddNeeded(pBase.m_AddNeeded),
+    m_Static(pBase.m_Static)
+  { }
+
+  virtual ~AttributeBase()
+  { }
+
+  // ----- observers  ----- //
+  // represent GNU ld --whole-archive/--no-whole-archive options
+  bool isWholeArchive() const
+  { return m_WholeArchive; }
+
+  // represent GNU ld --as-needed/--no-as-needed options
+  bool isAsNeeded() const
+  { return m_AsNeeded; }
+
+  // represent GNU ld --add-needed/--no-add-needed options
+  bool isAddNeeded() const
+  { return m_AddNeeded; }
+
+  // represent GNU ld -static option
+  bool isStatic() const
+  { return m_Static; }
+
+  // represent GNU ld -call_shared option
+  bool isDynamic() const
+  { return !m_Static; }
+public:
+  bool m_WholeArchive : 1;
+  bool m_AsNeeded : 1;
+  bool m_AddNeeded : 1;
+  bool m_Static : 1;
+};
+
+/** \class Attribute
+ *  \brief The base class of attributes. Providing the raw operations of an
+ *  attributes
+ *
+ *  For conventience and producing less bugs, we move the stoarges of attributes
+ *  onto AttributeBase, and modifiers remains with the class Attribute.
+ */
+class Attribute : public AttributeBase
+{
+public:
+  // -----  modifiers  ----- //
+  void setWholeArchive()
+  { m_WholeArchive = true; }
+
+  void unsetWholeArchive()
+  { m_WholeArchive = false; }
+
+  void setAsNeeded()
+  { m_AsNeeded = true; }
+
+  void unsetAsNeeded()
+  { m_AsNeeded = false; }
+
+  void setAddNeeded()
+  { m_AddNeeded = true; }
+
+  void unsetAddNeeded()
+  { m_AddNeeded = false; }
+
+  void setStatic()
+  { m_Static = true; }
+
+  void setDynamic()
+  { m_Static = false; }
+};
+
+/** \class AttrConstraint
+ *  \brief AttrConstarint is the constraint of a system.
+ *
+ *  Some systems can not enable certain attributes of a input file.
+ *  For example, systems which have no shared libraries can not enable
+ *  --call_shared options. We call the ability of enabling attributes
+ *  as the constraint of attributes of a system.
+ *
+ *  Systems enable attributes at the target implementation of SectLinker.
+ *
+ *  @see SectLinker
+ */
+class AttrConstraint : public AttributeBase
+{
+public:
+  void enableWholeArchive()
+  { m_WholeArchive = true; }
+
+  void disableWholeArchive()
+  { m_WholeArchive = false; }
+
+  void enableAsNeeded()
+  { m_AsNeeded = true; }
+
+  void disableAsNeeded()
+  { m_AsNeeded = false; }
+
+  void enableAddNeeded()
+  { m_AddNeeded = true; }
+
+  void disableAddNeeded()
+  { m_AddNeeded = false; }
+
+  void setSharedSystem()
+  { m_Static = false; }
+
+  void setStaticSystem()
+  { m_Static = true; }
+
+  bool isSharedSystem() const
+  { return !m_Static; }
+
+  bool isStaticSystem() const
+  { return m_Static; }
+  
+  bool isLegal(const Attribute& pAttr, std::string& pErrMesg) const;
+};
+
+/** \class AttributeProxy
+ *  \brief AttributeProxys is the illusion of private attribute of each
+ *  input file.
+ *
+ *  We designers want to hide the details of sharing common attributes
+ *  between input files. We want input files under the illusion that they
+ *  have their own private attributes to simplify the linking algorithms.
+ *
+ *  AttributeProxy hides the reality of sharing. An input file can change
+ *  its attribute without explicit searching of existing attributes
+ *  as it has a private ownership of the attribute. AttributeProxy does
+ *  the searching in the AttributeFactory and changes the pointer of
+ *  the attribute of the input file. If the searching fails, AttributeProxy
+ *  requests a new attribute from the AttributeFactory.
+ */
+class AttributeProxy
+{
+private:
+  friend class AttributeFactory;
+
+  explicit AttributeProxy(AttributeFactory& pParent, Attribute& pBase);
+  ~AttributeProxy();
+
+public:
+  // ----- observers  ----- //
+  bool isWholeArchive() const;
+
+  bool isAsNeeded() const;
+
+  bool isAddNeeded() const;
+
+  bool isStatic() const;
+
+  bool isDynamic() const;
+
+  Attribute* attr()
+  { return m_pBase; }
+
+  const Attribute* attr() const
+  { return m_pBase; }
+
+  // -----  modifiers  ----- //
+  void setWholeArchive();
+  void unsetWholeArchive();
+  void setAsNeeded();
+  void unsetAsNeeded();
+  void setAddNeeded();
+  void unsetAddNeeded();
+  void setStatic();
+  void setDynamic();
+
+private:
+  AttributeProxy* clone() const;
+
+  void change(Attribute* pBase)
+  { m_pBase = pBase; }
+
+private:
+  AttributeFactory &m_AttrPool;
+  Attribute *m_pBase;
+};
+
+
+// -----  comparisons  ----- //
+inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
+{
+  return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
+    (pLHS.isAsNeeded() == pRHS.isAsNeeded()) && 
+    (pLHS.isAddNeeded() == pRHS.isAddNeeded()) && 
+    (pLHS.isStatic() == pRHS.isStatic()));
+}
+
+inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
+{
+  return !(pLHS == pRHS);
+}
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDDirectory.h b/include/mcld/MC/MCLDDirectory.h
new file mode 100644
index 0000000..988f9d3
--- /dev/null
+++ b/include/mcld/MC/MCLDDirectory.h
@@ -0,0 +1,53 @@
+//===- MCLDDirectory.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCLDDIRECTORY_H
+#define MCLD_MCLDDIRECTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/Directory.h"
+#include "mcld/Support/FileSystem.h"
+#include <llvm/ADT/StringRef.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class MCLDDirectory
+ *  \brief MCLDDirectory is an directory entry for library search.
+ *
+ */
+class MCLDDirectory : public sys::fs::Directory
+{
+public:
+  MCLDDirectory();
+  MCLDDirectory(const char* pName);
+  MCLDDirectory(const std::string& pName);
+  MCLDDirectory(llvm::StringRef pName);
+  virtual ~MCLDDirectory();
+
+public:
+  MCLDDirectory &assign(llvm::StringRef pName);
+  bool isInSysroot() const;
+
+  /// setSysroot - if MCLDDirectory is in sysroot, modify the path.
+  void setSysroot(const sys::fs::Path& pPath);
+
+  const std::string& name() const
+  { return m_Name; }
+
+private:
+  std::string m_Name;
+  bool m_bInSysroot;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDDriver.h b/include/mcld/MC/MCLDDriver.h
new file mode 100644
index 0000000..b4a7288
--- /dev/null
+++ b/include/mcld/MC/MCLDDriver.h
@@ -0,0 +1,117 @@
+//===- MCLDDriver.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// MCLDDriver plays the same role as GNU collect2 to prepare all implicit
+// parameters for MCLinker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LDDRIVER_H
+#define MCLD_LDDRIVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/SectionMap.h>
+namespace mcld
+{
+
+class MCLinker;
+class MCLDInfo;
+class TargetLDBackend;
+
+//===----------------------------------------------------------------------===//
+/// MCLDDriver - MCLDDriver prepares parameters for MCLinker.
+///
+class MCLDDriver
+{
+public:
+  MCLDDriver(MCLDInfo& pLDInfo, TargetLDBackend& pLDBackend);
+  ~MCLDDriver();
+
+  /// normalize - normalize the input files
+  void normalize();
+
+  /// linkable - check the linkability of current MCLDInfo
+  ///  Check list:
+  ///  - check the Attributes are not violate the constaint
+  ///  - check every Input has a correct Attribute
+  bool linkable() const;
+
+  /// initMCLinker - initialize MCLinker
+  ///  Connect all components in MCLinker
+  bool initMCLinker();
+
+  /// readSections - read all input section headers
+  bool readSections();
+
+  /// mergeSections - put allinput sections into output sections
+  bool mergeSections();
+
+  /// readSymbolTables - read symbol tables from the input files.
+  ///  for each input file, loads its symbol table from file.
+  bool readSymbolTables();
+
+  /// mergeSymbolTables - merge the symbol tables of input files into the
+  /// output's symbol table.
+  bool mergeSymbolTables();
+
+  /// addStandardSymbols - shared object and executable files need some
+  /// standard symbols
+  ///   @return if there are some input symbols with the same name to the
+  ///   standard symbols, return false
+  bool addStandardSymbols();
+
+  /// addTargetSymbols - some targets, such as MIPS and ARM, need some
+  /// target-dependent symbols
+  ///   @return if there are some input symbols with the same name to the
+  ///   target symbols, return false
+  bool addTargetSymbols();
+
+  /// readRelocations - read all relocation entries
+  bool readRelocations();
+
+  /// prelayout - help backend to do some modification before layout
+  bool prelayout();
+
+  /// layout - linearly layout all output sections and reserve some space
+  /// for GOT/PLT
+  ///   Because we do not support instruction relaxing in this early version,
+  ///   if there is a branch can not jump to its target, we return false
+  ///   directly
+  bool layout();
+
+  /// postlayout - help backend to do some modification after layout
+  bool postlayout();
+
+  /// relocate - applying relocation entries and create relocation
+  /// section in the output files
+  /// Create relocation section, asking TargetLDBackend to
+  /// read the relocation information into RelocationEntry
+  /// and push_back into the relocation section
+  bool relocate();
+
+  /// finalizeSymbolValue - finalize the symbol value
+  bool finalizeSymbolValue();
+
+  /// emitOutput - emit the output file.
+  bool emitOutput();
+
+  /// postProcessing - do modificatiion after all processes
+  bool postProcessing();
+
+private:
+  MCLDInfo& m_LDInfo;
+  TargetLDBackend &m_LDBackend;
+  MCLinker* m_pLinker;
+  SectionMap m_SectionMap;
+};
+
+} // end namespace mcld
+#endif
diff --git a/include/mcld/MC/MCLDFile.h b/include/mcld/MC/MCLDFile.h
new file mode 100644
index 0000000..30cac7e
--- /dev/null
+++ b/include/mcld/MC/MCLDFile.h
@@ -0,0 +1,173 @@
+//===- MCLDFile.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// MCLDFile represents a file, the content of the file is stored in LDContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LDFILE_H
+#define MCLD_LDFILE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/LD/LDContext.h"
+#include "mcld/Support/Path.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/GCFactory.h"
+#include "mcld/Support/MemoryArea.h"
+#include <llvm/ADT/StringRef.h>
+#include <string>
+#include <sys/stat.h>
+
+
+namespace mcld
+{
+class MemoryArea;
+
+/** \class MCLDFile
+ *  \brief MCLDFile represents the file being linked or produced.
+ *
+ *  MCLDFile is the storage of name, path and type
+ *  A MCLDFile just refers to LDContext, not owns it.
+ *
+ *  @see mcld::sys::fs::Path LDContext
+ */
+class MCLDFile : private Uncopyable
+{
+public:
+  enum Type {
+    Unknown,
+    Object,
+    Exec,
+    DynObj,
+    CoreFile,
+    Script,
+    Archive
+  };
+
+public:
+  MCLDFile();
+  MCLDFile(llvm::StringRef pName);
+  MCLDFile(llvm::StringRef pName,
+           const sys::fs::Path& pPath,
+           unsigned int pType = Unknown);
+
+  virtual ~MCLDFile();
+
+  // -----  modifiers  ----- //
+  void setType(unsigned int pType)
+  { m_Type = pType; }
+
+  void setContext(LDContext* pContext)
+  { m_pContext = pContext; }
+
+  void setPath(const sys::fs::Path& pPath)
+  { m_Path = pPath; }
+
+  void setMemArea(MemoryArea* pMemArea)
+  {
+    m_pMemArea = pMemArea;
+  }
+
+  /// setSOName - set the name of the shared object.
+  /// In ELF, this will be written in DT_SONAME
+  void setSOName(const std::string& pName);
+
+  // -----  observers  ----- //
+  unsigned int type() const
+  { return m_Type; }
+
+  const std::string& name() const
+  { return m_Name; }
+
+  const sys::fs::Path& path() const
+  { return m_Path; }
+
+  bool hasContext() const
+  { return (0 != m_pContext); }
+
+  LDContext* context()
+  { return m_pContext; }
+
+  const LDContext* context() const
+  { return m_pContext; }
+
+  bool hasMemArea() const
+  { return (0 != m_pMemArea); }
+
+  MemoryArea* memArea()
+  { return m_pMemArea; }
+
+  const MemoryArea* memArea() const
+  { return m_pMemArea; }
+
+protected:
+  unsigned int m_Type;
+  LDContext *m_pContext;
+  sys::fs::Path m_Path;
+  std::string m_Name;
+  MemoryArea* m_pMemArea;
+};
+
+/** \class MCLDFileFactory
+ *  \brief MCLDFileFactory controls the production and destruction of
+ *  MCLDFiles.
+ *
+ *  All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
+ *  while MCLDFileFactory is destructed.
+ *
+ *  MCLDFileFactory also provides the MCLCContextFactory to MCLDFile.
+ *  MCLDFile is responsed for the life of LDContext, therefore, the best
+ *  idea is let MCLDFile control the life of LDContext. Since SectLinker
+ *  has the need to count the number of LDContext, we give a central factory
+ *  for LDContext.
+ *
+ *  \see llvm::sys::Path
+ */
+template<size_t NUM>
+class MCLDFileFactory : public GCFactory<MCLDFile, NUM>
+{
+public:
+  typedef GCFactory<MCLDFile, NUM> Alloc;
+
+public:
+  // -----  production  ----- //
+  MCLDFile* produce(llvm::StringRef pName,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = MCLDFile::Unknown);
+
+  MCLDFile* produce();
+};
+
+} // namespace of mcld
+
+//===----------------------------------------------------------------------===//
+// MCLDFileFactory
+template<size_t NUM>
+mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce(llvm::StringRef pName,
+                                   const mcld::sys::fs::Path& pPath,
+                                   unsigned int pType)
+{
+    mcld::MCLDFile* result = Alloc::allocate();
+    new (result) mcld::MCLDFile(pName, pPath, pType);
+    return result;
+}
+
+template<size_t NUM>
+mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce()
+{
+    mcld::MCLDFile* result = Alloc::allocate();
+    new (result) mcld::MCLDFile();
+    return result;
+}
+
+#endif
+
diff --git a/include/mcld/MC/MCLDInfo.h b/include/mcld/MC/MCLDInfo.h
new file mode 100644
index 0000000..15e70ff
--- /dev/null
+++ b/include/mcld/MC/MCLDInfo.h
@@ -0,0 +1,138 @@
+//===- MCLDInfo.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDINFO_H
+#define MCLD_LDINFO_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/Triple.h>
+
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Support/MemoryAreaFactory.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLDOptions.h>
+#include <mcld/MC/MCLDInputTree.h>
+#include <mcld/MC/AttributeFactory.h>
+#include <mcld/MC/ContextFactory.h>
+#include <mcld/LD/StrSymPool.h>
+
+#include <string>
+#include <cassert>
+
+namespace mcld
+{
+
+/** \class MCLDInfo
+ *  \brief MCLDInfo is composed of argumments of MCLinker.
+ *   options()        - the general options.
+ *   inputs()         - the tree of inputs
+ *   bitcode()        - the bitcode being linked
+ *   output()         - the output file
+ *   inputFactory()   - the list of all inputs
+ *   attrFactory()    - the list of all attributes
+ *   contextFactory() - the list of all contexts.
+ *   memAreaFactory() - the list of all MemoryAreas.
+ */
+class MCLDInfo
+{
+public:
+  explicit MCLDInfo(const std::string &pTripleString,
+                    size_t pAttrNum,
+                    size_t InputSize);
+
+  virtual ~MCLDInfo();
+
+  GeneralOptions& options()
+  { return m_Options; }
+
+  const GeneralOptions& options() const
+  { return m_Options; }
+
+  void setBitcode(const Input& pInput);
+  Input& bitcode();
+  const Input& bitcode() const;
+
+  Output& output()
+  { return *m_pOutput; }
+
+  const Output& output() const
+  { return *m_pOutput; }
+
+  InputTree& inputs()
+  { return *m_pInputTree; }
+
+  const InputTree& inputs() const
+  { return *m_pInputTree; }
+
+  InputFactory& inputFactory()
+  { return *m_pInputFactory; }
+
+  const InputFactory& inputFactory() const
+  { return *m_pInputFactory; }
+
+  AttributeFactory& attrFactory()
+  { return *m_pAttrFactory; }
+
+
+  const AttributeFactory& attrFactory() const
+  { return *m_pAttrFactory; }
+
+  ContextFactory& contextFactory()
+  { return *m_pCntxtFactory; }
+
+  const ContextFactory& contextFactory() const
+  { return *m_pCntxtFactory; }
+
+  MemoryAreaFactory& memAreaFactory()
+  { return *m_pMemAreaFactory; }
+
+  const MemoryAreaFactory& memAreaFactory() const
+  { return *m_pMemAreaFactory; }
+
+  const llvm::Triple& triple() const
+  { return m_Triple; }
+
+  static const char* version();
+
+  void setNamePool(StrSymPool& pPool)
+  { m_pStrSymPool = &pPool; }
+
+  StrSymPool& getStrSymPool() {
+    assert(NULL != m_pStrSymPool);
+    return *m_pStrSymPool;
+  }
+
+  const StrSymPool& getStrSymPool() const {
+    assert(NULL != m_pStrSymPool);
+    return *m_pStrSymPool;
+  }
+
+private:
+  // -----  General Options  ----- //
+  GeneralOptions m_Options;
+  InputTree *m_pInputTree;
+  Input* m_pBitcode;
+  Output* m_pOutput;
+  llvm::Triple m_Triple;
+
+  // -----  factories  ----- //
+  InputFactory *m_pInputFactory;
+  AttributeFactory *m_pAttrFactory;
+  ContextFactory *m_pCntxtFactory;
+  MemoryAreaFactory *m_pMemAreaFactory;
+
+  // -----  string and symbols  ----- //
+  StrSymPool* m_pStrSymPool;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDInput.h b/include/mcld/MC/MCLDInput.h
new file mode 100644
index 0000000..097b8f6
--- /dev/null
+++ b/include/mcld/MC/MCLDInput.h
@@ -0,0 +1,86 @@
+//===- MCLDInput.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Input class inherits MCLDFile, which is used to represent a input file
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_INPUT_H
+#define MCLD_INPUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/MC/MCLDFile.h"
+
+namespace mcld
+{
+
+class AttributeProxy;
+class Attribute;
+class InputFactory;
+
+/** \class Input
+ *  \brief Input provides the information of a input file.
+ *
+ *  @see MCLDFile
+ */
+class Input : public MCLDFile
+{
+friend class InputFactory;
+public:
+  enum Type {
+    Unknown = MCLDFile::Unknown,
+    Object = MCLDFile::Object,
+    DynObj = MCLDFile::DynObj,
+    Archive = MCLDFile::Archive,
+    Script = MCLDFile::Script
+  };
+
+private:
+  explicit Input(llvm::StringRef pName,
+                 const AttributeProxy& pAttr);
+
+  Input(llvm::StringRef pName,
+        const sys::fs::Path& pPath,
+        const AttributeProxy& pAttr,
+        unsigned int pType = Unknown,
+        off_t pFileOffset = 0);
+
+public:
+  ~Input();
+
+  bool isRecognized() const
+  { return (m_Type != Unknown); }
+
+  const Attribute* attribute() const
+  { return m_pAttr; }
+
+  bool isNeeded() const
+  { return m_bNeeded; }
+
+  void setNeeded()
+  { m_bNeeded = true; }
+
+  off_t fileOffset() const
+  { return m_fileOffset; }
+
+  void setFileOffset(off_t pFileOffset)
+  { m_fileOffset = pFileOffset; }
+
+private:
+  Attribute *m_pAttr;
+  bool m_bNeeded;
+  off_t m_fileOffset;
+};
+
+} // namespace of mcld
+ 
+#endif
+
diff --git a/include/mcld/MC/MCLDInputTree.h b/include/mcld/MC/MCLDInputTree.h
new file mode 100644
index 0000000..7d8050c
--- /dev/null
+++ b/include/mcld/MC/MCLDInputTree.h
@@ -0,0 +1,237 @@
+//===- MCLDInputTree.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_INPUT_TREE_H
+#define MCLD_INPUT_TREE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/BinTree.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/MC/MCLDInput.h"
+#include "mcld/MC/InputFactory.h"
+#include "mcld/Support/FileSystem.h"
+
+#include <string>
+
+
+namespace mcld
+{
+
+/** \class template<typename Traits, typename Iterator> PolicyIterator<mcld::Input>
+ *  \brief PolicyIterator<mcld::Input> is a partially specific PolicyIterator
+ */
+template<typename Traits, typename IteratorType>
+class PolicyIterator<mcld::Input, Traits, IteratorType> : public PolicyIteratorBase<Input, Traits, IteratorType>
+{
+public:
+  typedef PolicyIterator<Input, Traits, IteratorType> Self;
+  typedef PolicyIteratorBase<Input, Traits, IteratorType> Base;
+  typedef PolicyIterator<Input, typename Traits::nonconst_traits, IteratorType> iterator;
+  typedef PolicyIterator<Input, typename Traits::const_traits, IteratorType>    const_iterator;
+
+public:
+  PolicyIterator()
+    : Base() {}
+
+  PolicyIterator(const iterator &X)
+    : Base(X.m_pNode) {}
+
+  explicit PolicyIterator(NodeBase* X)
+    : Base(X) {}
+
+  virtual ~PolicyIterator() {}
+
+  bool isGroup() const
+  { return !Base::hasData(); }
+
+  Self& operator++() {
+    IteratorType::advance();
+    if (isGroup())
+      IteratorType::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp(*this);
+    IteratorType::advance();
+    if (isGroup())
+      IteratorType::advance();
+    return tmp;
+  }
+};
+
+/** \class InputTree
+ *  \brief InputTree is the input tree to contains all inputs from the
+ *  command line.
+ *
+ *  InputTree, of course, is uncopyable.
+ *
+ *  @see Input
+ */
+class InputTree : public BinaryTree<Input>
+{
+private:
+  typedef BinaryTree<Input> BinTreeTy;
+
+public:
+  enum Direction {
+    Inclusive  = TreeIteratorBase::Leftward,
+    Positional = TreeIteratorBase::Rightward
+  };
+
+  typedef BinaryTree<Input>::iterator       iterator;
+  typedef BinaryTree<Input>::const_iterator const_iterator;
+
+public:
+  struct Connector {
+    virtual ~Connector() {}
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const = 0;
+    virtual void move(iterator& pNode) const = 0;
+  };
+
+  struct Succeeder : public Connector {
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+      proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
+    }
+
+    virtual void move(iterator& pNode) const {
+      pNode.move<Positional>();
+    }
+  };
+
+  struct Includer : public Connector {
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+      proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
+    }
+
+    virtual void move(iterator& pNode) const {
+      pNode.move<Inclusive>();
+    }
+  };
+
+public:
+  static Succeeder Afterward;
+  static Includer  Downward;
+
+public:
+
+  using BinTreeTy::merge;
+
+  InputTree(InputFactory& pInputFactory);
+  ~InputTree();
+
+  // -----  modify  ----- //
+  /// insert - create a leaf node and merge it in the tree.
+  //  This version of join determines the direction at run time.
+  //  @param position the parent node
+  //  @param value the value being pushed.
+  //  @param pConnector the direction of the connecting edge of the parent node.
+  template<size_t DIRECT>
+  InputTree& insert(iterator pPosition,
+                    const std::string& pNamespec,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = Input::Unknown);
+
+  template<size_t DIRECT>
+  InputTree& enterGroup(iterator pPosition);
+
+  template<size_t DIRECT>
+  InputTree& insert(iterator pPosition,
+                    const Input& pInput);
+
+  InputTree& merge(iterator pPosition, 
+                   const Connector& pConnector,
+                   InputTree& pTree);
+
+  InputTree& insert(iterator pPosition,
+                    const Connector& pConnector,
+                    const std::string& pNamespec,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = Input::Unknown);
+
+  InputTree& insert(iterator pPosition,
+                    const Connector& pConnector,
+                    const Input& pInput);
+
+  InputTree& enterGroup(iterator pPosition,
+                        const Connector& pConnector);
+
+  // -----  observers  ----- //
+  unsigned int numOfInputs() const
+  { return m_FileFactory.size(); }
+
+  bool hasInput() const
+  { return !m_FileFactory.empty(); }
+
+private:
+  InputFactory& m_FileFactory;
+
+};
+
+bool isGroup(const InputTree::iterator& pos);
+bool isGroup(const InputTree::const_iterator& pos);
+bool isGroup(const InputTree::dfs_iterator& pos);
+bool isGroup(const InputTree::const_dfs_iterator& pos);
+bool isGroup(const InputTree::bfs_iterator& pos);
+bool isGroup(const InputTree::const_bfs_iterator& pos);
+
+} // namespace of mcld
+
+//===----------------------------------------------------------------------===//
+// template member functions
+template<size_t DIRECT>
+mcld::InputTree&
+mcld::InputTree::insert(mcld::InputTree::iterator pPosition,
+                        const std::string& pNamespec,
+                        const mcld::sys::fs::Path& pPath,
+                        unsigned int pType)
+{
+  BinTreeTy::node_type* node = createNode();
+  node->data = m_FileFactory.produce(pNamespec, pPath, pType); 
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  return *this;
+}
+
+template<size_t DIRECT>
+mcld::InputTree&
+mcld::InputTree::enterGroup(mcld::InputTree::iterator pPosition)
+{
+  BinTreeTy::node_type* node = createNode(); 
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  return *this;
+}
+
+template<size_t DIRECT>
+mcld::InputTree& mcld::InputTree::insert(mcld::InputTree::iterator pPosition,
+	                                 const mcld::Input& pInput)
+{
+  BinTreeTy::node_type* node = createNode();
+  node->data = const_cast<mcld::Input*>(&pInput);
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+                                         const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+                        const_cast<const node_type*>(node));
+  return *this;
+}
+
+#endif
+
diff --git a/include/mcld/MC/MCLDOptions.h b/include/mcld/MC/MCLDOptions.h
new file mode 100644
index 0000000..06097aa
--- /dev/null
+++ b/include/mcld/MC/MCLDOptions.h
@@ -0,0 +1,98 @@
+//===- MCLDOptions.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OPTIONS_H
+#define MCLD_OPTIONS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/RealPath.h"
+#include "mcld/MC/SearchDirs.h"
+#include "mcld/Support/FileSystem.h"
+
+namespace mcld
+{
+class Input;
+
+/** \class ScriptOptions
+ *
+ */
+class ScriptOption
+{
+};
+
+/** \class GeneralOptions
+ *  \brief GeneralOptions collects the options that not be one of the
+ *     - input files
+ *     - attribute of input files
+ *     - script options
+ */
+class GeneralOptions
+{
+public:
+  /// default link script
+  bool hasDefaultLDScript() const;
+  const char* defaultLDScript() const;
+  void setDefaultLDScript(const std::string& pFilename);
+
+  /// sysroot
+  const sys::fs::Path& sysroot() const
+  { return m_Sysroot; }
+
+  void setSysroot(const sys::fs::Path &pPath);
+
+  /// search directory
+  SearchDirs& directories()
+  { return m_SearchDirs; }
+
+  const SearchDirs& directories() const
+  { return m_SearchDirs; }
+
+  /// trace
+  void setTrace(bool pEnableTrace = true)
+  { m_bTrace = pEnableTrace; }
+
+  bool trace() const
+  { return m_bTrace; }
+
+  void setVerbose(bool pVerbose = true)
+  { m_bVerbose = pVerbose; }
+
+  bool verbose() const
+  { return m_bVerbose; }
+
+  void setBsymbolic(bool pBsymbolic = false)
+  { m_Bsymbolic = pBsymbolic; }
+
+  bool Bsymbolic() const
+  { return m_Bsymbolic; }
+
+  bool hasEntry() const
+  { return !m_Entry.empty(); }
+
+  void setEntry(const std::string& pEntry)
+  { m_Entry = pEntry; }
+
+  const std::string& entry() const
+  { return m_Entry; }
+
+private:
+  Input* m_pDefaultBitcode;
+  std::string m_DefaultLDScript;
+  sys::fs::RealPath m_Sysroot;
+  SearchDirs m_SearchDirs;
+  bool m_bTrace;
+  bool m_bVerbose;
+  bool m_Bsymbolic;
+  std::string m_Entry;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDOutput.h b/include/mcld/MC/MCLDOutput.h
new file mode 100644
index 0000000..14768ce
--- /dev/null
+++ b/include/mcld/MC/MCLDOutput.h
@@ -0,0 +1,52 @@
+//===- MCLDOutput.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Output class inherits MCLDFile, which is used to represent a output file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_OUTPUT_H
+#define MCLD_OUTPUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/MC/MCLDFile.h>
+#include <mcld/Support/RealPath.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class MCLDOutput
+ *  \brief MCLDOutput provides the information about the output.
+ *
+ *  @see MCLDFile
+ */
+class Output : public MCLDFile
+{
+public:
+  enum Type {
+    Object = MCLDFile::Object,
+    DynObj = MCLDFile::DynObj,
+    Exec   = MCLDFile::Exec
+  };
+
+public:
+  Output();
+  explicit Output(const sys::fs::Path& pRealPath,
+                  Type pType);
+
+  ~Output();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLinker.h b/include/mcld/MC/MCLinker.h
new file mode 100644
index 0000000..8de7148
--- /dev/null
+++ b/include/mcld/MC/MCLinker.h
@@ -0,0 +1,279 @@
+//===- MCLinker.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a number of APIs used by SectLinker.
+// These APIs do the things which a linker should do.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCLINKER_H
+#define MCLD_MCLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/LD/StrSymPool.h>
+#include <mcld/LD/StaticResolver.h>
+#include <mcld/LD/LDSectionFactory.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/Relocation.h>
+#include <mcld/LD/SectionMerger.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/Support/GCFactoryListTraits.h>
+#include <set>
+#include <string>
+
+namespace mcld {
+
+class TargetLDBackend;
+class MCLDInfo;
+class LDSection;
+class LDSectionFactory;
+class SectionMap;
+class Output;
+
+/** \class MCLinker
+ *  \brief MCLinker provides a pass to link object files.
+ */
+class MCLinker
+{
+public:
+  enum DefinePolicy
+  {
+    Force,
+    AsRefered
+  };
+
+  enum ResolvePolicy
+  {
+    Unresolve,
+    Resolve
+  };
+
+public:
+  MCLinker(TargetLDBackend& pBackend,
+           MCLDInfo& pLDInfo,
+           LDContext& pContext,
+           SectionMap& pSectionMap,
+           const Resolver& pResolver = StaticResolver());
+  ~MCLinker();
+
+  // ----- about symbols  ----- //
+  /// addDynSymbol - add a symbol and resolve it immediately
+  template<Input::Type FROM>
+  LDSymbol* addSymbol(const llvm::StringRef& pName,
+                      ResolveInfo::Type pType,
+                      ResolveInfo::Desc pDesc,
+                      ResolveInfo::Binding pBinding,
+                      ResolveInfo::SizeType pSize,
+                      LDSymbol::ValueType pValue,
+                      MCFragmentRef* pFragmentRef,
+                      ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+
+  /// defineSymbol - add a symbol
+  /// defineSymbol define a output symbol
+  ///
+  /// @tparam POLICY idicate how to define the symbol.
+  ///   - Force
+  ///     - Define the symbol forcefully. If the symbol has existed, override
+  ///       it. Otherwise, define it.
+  ///   - AsRefered
+  ///     - If the symbol has existed, override it. Otherwise, return NULL
+  ///       immediately.
+  ///
+  /// @tparam RESOLVE indicate whether to resolve the symbol or not.
+  ///   - Unresolve
+  ///      - Do not resolve the symbol, and override the symbol immediately.
+  ///   - Resolve
+  ///      - Resolve the defined symbol.
+  ///
+  /// @return If the output symbol has existed, return it. Otherwise, create
+  ///         a new symbol and return the new one.
+  template<DefinePolicy POLICY, ResolvePolicy RESOLVE>
+  LDSymbol* defineSymbol(const llvm::StringRef& pName,
+                         bool pIsDyn,
+                         ResolveInfo::Type pType,
+                         ResolveInfo::Desc pDesc,
+                         ResolveInfo::Binding pBinding,
+                         ResolveInfo::SizeType pSize,
+                         LDSymbol::ValueType pValue,
+                         MCFragmentRef* pFragmentRef,
+                         ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+
+  /// mergeSymbolTable - merge the symbol table and resolve symbols.
+  ///   Since in current design, MCLinker resolves symbols when reading symbol
+  ///   tables, this function do nothing.
+  bool mergeSymbolTable(Input& pInput)
+  { return true; }
+
+  bool finalizeSymbols();
+
+  // -----  sections  ----- //
+  /// getSectionMap - getSectionMap to change the behavior of SectionMerger
+  /// SectionMap& getSectionMap()
+  /// { return m_SectionMap; }
+
+  /// createSectHdr - for reader and standard/target format to create a section
+  /// header. This function will create a new LDSection and return it. If the
+  /// output has no related LDSection, this function will also create one and
+  /// push into the output.
+  LDSection& createSectHdr(const std::string& pName,
+                           LDFileFormat::Kind pKind,
+                           uint32_t pType,
+                           uint32_t pFlag);
+
+  /// getOrCreateOutputSectHdr - for reader and standard/target format to get
+  /// or create the output's section header
+  LDSection& getOrCreateOutputSectHdr(const std::string& pName,
+                                      LDFileFormat::Kind pKind,
+                                      uint32_t pType,
+                                      uint32_t pFlag,
+                                      uint32_t pAlign = 0x0);
+
+  /// getOrCreateSectData - for reader to map and perform section merging immediately
+  llvm::MCSectionData& getOrCreateSectData(LDSection& pSection);
+
+  // -----  relocations ----- //
+  /// addRelocation - add a relocation entry in MCLinker (only for object file)
+  /// @param pType - the type of the relocation
+  /// @param pResolveInfo - the symbol should be the symbol in the input file. MCLinker
+  ///                  computes the real applied address by the output symbol.
+  /// @param pFragmentRef - the fragment reference of the applied address.
+  /// @param pAddend - the addend value for applying relocation
+  Relocation* addRelocation(Relocation::Type pType,
+                            const LDSymbol& pSym,
+                            ResolveInfo& pResolveInfo,
+                            MCFragmentRef& pFragmentRef,
+                            Relocation::Address pAddend = 0);
+
+  /// applyRelocations - apply all relocation enties.
+  bool applyRelocations();
+
+  /// syncRelocationResult - After applying relocation, write back relocation target
+  /// data to output file.
+  void syncRelocationResult();
+
+  // -----  layout  ----- //
+  Layout& getLayout()
+  { return m_Layout; }
+
+  const Layout& getLayout() const
+  { return m_Layout; }
+
+  bool layout();
+
+  // -----  output symbols  ----- //
+  SymbolCategory& getOutputSymbols()
+  { return m_OutputSymbols; }
+
+  const SymbolCategory& getOutputSymbols() const
+  { return m_OutputSymbols; }
+
+  // -----  capacity  ----- //
+  MCLDInfo& getLDInfo()
+  { return m_Info; }
+
+  const MCLDInfo& getLDInfo() const
+  { return m_Info; }
+
+private:
+  LDSymbol* defineSymbolForcefully(const llvm::StringRef& pName,
+                                   bool pIsDyn,
+                                   ResolveInfo::Type pType,
+                                   ResolveInfo::Desc pDesc,
+                                   ResolveInfo::Binding pBinding,
+                                   ResolveInfo::SizeType pSize,
+                                   LDSymbol::ValueType pValue,
+                                   MCFragmentRef* pFragmentRef,
+                                   ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
+                                             bool pIsDyn,
+                                             ResolveInfo::Type pType,
+                                             ResolveInfo::Desc pDesc,
+                                             ResolveInfo::Binding pBinding,
+                                             ResolveInfo::SizeType pSize,
+                                             LDSymbol::ValueType pValue,
+                                             MCFragmentRef* pFragmentRef,
+                                             ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineSymbolAsRefered(const llvm::StringRef& pName,
+                                  bool pIsDyn,
+                                  ResolveInfo::Type pType,
+                                  ResolveInfo::Desc pDesc,
+                                  ResolveInfo::Binding pBinding,
+                                  ResolveInfo::SizeType pSize,
+                                  LDSymbol::ValueType pValue,
+                                  MCFragmentRef* pFragmentRef,
+                                  ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
+                                            bool pIsDyn,
+                                            ResolveInfo::Type pType,
+                                            ResolveInfo::Desc pDesc,
+                                            ResolveInfo::Binding pBinding,
+                                            ResolveInfo::SizeType pSize,
+                                            LDSymbol::ValueType pValue,
+                                            MCFragmentRef* pFragmentRef,
+                                            ResolveInfo::Visibility pVisibility);
+
+  bool shouldForceLocal(const ResolveInfo& pInfo) const;
+
+  LDSymbol* addSymbolFromDynObj(const llvm::StringRef& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                MCFragmentRef* pFragmentRef,
+                                ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                MCFragmentRef* pFragmentRef,
+                                ResolveInfo::Visibility pVisibility);
+private:
+  typedef GCFactory<LDSymbol, 0> LDSymbolFactory;
+  typedef GCFactory<llvm::MCSectionData, 0> LDSectionDataFactory;
+  typedef llvm::iplist<llvm::MCFragment,
+                       GCFactoryListTraits<llvm::MCFragment> > RelocationListType;
+  typedef std::set<LDSymbol*> ForceLocalSymbolTable;
+  typedef std::vector<LDSymbol*> OutputSymbolTable;
+
+private:
+  TargetLDBackend& m_Backend;
+  MCLDInfo& m_Info;
+  LDContext& m_Output;
+  SectionMap& m_SectionMap;
+  LDSymbolFactory m_LDSymbolFactory;
+  LDSectionFactory m_LDSectHdrFactory;
+  LDSectionDataFactory m_LDSectDataFactory;
+  SectionMerger m_SectionMerger;
+  StrSymPool m_StrSymPool;
+  Layout m_Layout;
+  RelocationListType m_RelocationList;
+  SymbolCategory m_OutputSymbols;
+
+};
+
+#include "MCLinker.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLinker.tcc b/include/mcld/MC/MCLinker.tcc
new file mode 100644
index 0000000..19a83ec
--- /dev/null
+++ b/include/mcld/MC/MCLinker.tcc
@@ -0,0 +1,105 @@
+//===- MCLinker.tcc -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/// addSymbol - add a symbol and resolve it immediately
+template<Input::Type FROM>
+LDSymbol* MCLinker::addSymbol(const llvm::StringRef& pName,
+                              ResolveInfo::Type pType,
+                              ResolveInfo::Desc pDesc,
+                              ResolveInfo::Binding pBinding,
+                              ResolveInfo::SizeType pSize,
+                              LDSymbol::ValueType pValue,
+                              MCFragmentRef* pFragmentRef,
+                              ResolveInfo::Visibility pVisibility)
+{
+  // These if/else should be optimized by compiler.
+  // This function is defined for clarity.
+  if (FROM == Input::DynObj)
+    return addSymbolFromDynObj(pName,
+                               pType,
+                               pDesc,
+                               pBinding,
+                               pSize,
+                               pValue,
+                               pFragmentRef,
+                               pVisibility);
+
+  if (FROM == Input::Object)
+    return addSymbolFromObject(pName,
+                               pType,
+                               pDesc,
+                               pBinding,
+                               pSize,
+                               pValue,
+                               pFragmentRef,
+                               pVisibility);
+
+  llvm::report_fatal_error("add a symbol from unknown file type.\n");
+  return NULL;
+}
+
+// defineSymbol - define a new symbol
+template<MCLinker::DefinePolicy POLICY, MCLinker::ResolvePolicy RESOLVE>
+LDSymbol* MCLinker::defineSymbol(const llvm::StringRef& pName,
+                                 bool pIsDyn,
+                                 ResolveInfo::Type pType,
+                                 ResolveInfo::Desc pDesc,
+                                 ResolveInfo::Binding pBinding,
+                                 ResolveInfo::SizeType pSize,
+                                 LDSymbol::ValueType pValue,
+                                 MCFragmentRef* pFragmentRef,
+                                 ResolveInfo::Visibility pVisibility)
+{
+  // These if/return should be optimized by compiler.
+  // This function is defined for clarity.
+  if (MCLinker::Force == POLICY && MCLinker::Unresolve == RESOLVE)
+    return defineSymbolForcefully(pName,
+                                  pIsDyn,
+                                  pType,
+                                  pDesc,
+                                  pBinding,
+                                  pSize,
+                                  pValue,
+                                  pFragmentRef,
+                                  pVisibility);
+
+  if (MCLinker::AsRefered == POLICY && MCLinker::Unresolve == RESOLVE)
+    return defineSymbolAsRefered(pName,
+                                 pIsDyn,
+                                 pType,
+                                 pDesc,
+                                 pBinding,
+                                 pSize,
+                                 pValue,
+                                 pFragmentRef,
+                                 pVisibility);
+
+  if (MCLinker::Force == POLICY && MCLinker::Resolve == RESOLVE)
+    return defineAndResolveSymbolForcefully(pName,
+                                            pIsDyn,
+                                            pType,
+                                            pDesc,
+                                            pBinding,
+                                            pSize,
+                                            pValue,
+                                            pFragmentRef,
+                                            pVisibility);
+
+  if (MCLinker::AsRefered == POLICY && MCLinker::Resolve == RESOLVE)
+    return defineAndResolveSymbolAsRefered(pName,
+                                           pIsDyn,
+                                           pType,
+                                           pDesc,
+                                           pBinding,
+                                           pSize,
+                                           pValue,
+                                           pFragmentRef,
+                                           pVisibility);
+}
+
diff --git a/include/mcld/MC/MCRegionFragment.h b/include/mcld/MC/MCRegionFragment.h
new file mode 100644
index 0000000..7dd088b
--- /dev/null
+++ b/include/mcld/MC/MCRegionFragment.h
@@ -0,0 +1,53 @@
+//===- MCRegionFragment.h - MCFragment containing MemoryRegion ------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_REGION_FRAGMENT_H
+#define MCLD_REGION_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/MemoryRegion.h>
+#include <llvm/MC/MCAssembler.h>
+
+namespace mcld
+{
+
+/** \class MCRegionFragment
+ *  \brief MCRegionFragment is a kind of MCFragment containing 
+ *  mcld::MemoryRegion
+ */
+class MCRegionFragment : public llvm::MCFragment
+{
+public:
+  MCRegionFragment(MemoryRegion& pRegion, llvm::MCSectionData* pSD = 0);
+  ~MCRegionFragment();
+
+  MemoryRegion& getRegion()
+  { return m_Region; }
+
+  const MemoryRegion& getRegion() const
+  { return m_Region; }
+
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == llvm::MCFragment::FT_Region; }
+
+  static bool classof(const MCRegionFragment *)
+  { return true; }
+
+private:
+  MemoryRegion& m_Region;
+  llvm::MCSectionData* m_pSectionData;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCTargetFragment.h b/include/mcld/MC/MCTargetFragment.h
new file mode 100644
index 0000000..4050708
--- /dev/null
+++ b/include/mcld/MC/MCTargetFragment.h
@@ -0,0 +1,48 @@
+//===- MCTargetFragment.h - MCFragment containing MemoryRegion ------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_TARGET_FRAGMENT_H
+#define MCLD_TARGET_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCAssembler.h>
+
+namespace mcld
+{
+
+/** \class MCTargetFragment
+ *  \brief MCTargetFragment is a kind of MCFragment inherited by
+ *  target-depedent MCFragment.
+ */
+class MCTargetFragment : public llvm::MCFragment
+{
+protected:
+  MCTargetFragment(llvm::MCFragment::FragmentType pKind,
+                   llvm::MCSectionData* pSD = 0) :
+                   llvm::MCFragment(pKind, pSD) {}
+
+public:
+  virtual ~MCTargetFragment() {}
+
+  virtual size_t getSize() const = 0;
+
+public:
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == llvm::MCFragment::FT_Target; }
+
+  static bool classof(const MCTargetFragment *)
+  { return true; }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/SearchDirs.h b/include/mcld/MC/SearchDirs.h
new file mode 100644
index 0000000..1a22cf4
--- /dev/null
+++ b/include/mcld/MC/SearchDirs.h
@@ -0,0 +1,76 @@
+//===- SearchDirs.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SEARCHDIRS_H
+#define SEARCHDIRS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/MC/MCLDInput.h"
+
+namespace mcld
+{
+
+class MCLDFile;
+class MCLDDirectory;
+
+namespace sys {
+namespace fs {
+class Path;
+} // namespace of fs
+} // namespace of sys
+
+/** \class SearchDirs
+ *  \brief SearchDirs contains the list of paths that MCLinker will search for
+ *  archive libraries and control scripts.
+ *
+ *  SearchDirs is customized for linking. It handles -L on the command line
+ *  and SEARCH_DIR macro in the link script.
+ *
+ *  @see MCLDDirectory.
+ */
+class SearchDirs : private Uncopyable
+{
+public:
+  typedef std::vector<MCLDDirectory*> DirList;
+  typedef DirList::iterator iterator;
+  typedef DirList::const_iterator const_iterator;
+
+public:
+  SearchDirs();
+  ~SearchDirs();
+
+  /// find - give a namespec, return a real path of the shared object.
+  sys::fs::Path* find(const std::string& pNamespec, mcld::Input::Type pType);
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_DirList.begin(); }
+
+  iterator end()
+  { return m_DirList.end(); }
+
+  const_iterator begin() const
+  { return m_DirList.begin(); }
+
+  const_iterator end() const
+  { return m_DirList.end(); }
+
+  // -----  modifiers  ----- //
+  void add(const MCLDDirectory& pDirectory);
+
+private:
+  DirList m_DirList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/SymbolCategory.h b/include/mcld/MC/SymbolCategory.h
new file mode 100644
index 0000000..9432c2a
--- /dev/null
+++ b/include/mcld/MC/SymbolCategory.h
@@ -0,0 +1,158 @@
+//===- SymbolCategory.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_CATEGORY_H
+#define MCLD_SYMBOL_CATEGORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/ADT/TypeTraits.h>
+#include <vector>
+
+namespace mcld
+{
+
+class LDSymbol;
+class ResolveInfo;
+/** \class SymbolCategory
+ *  \brief SymbolCategory groups output LDSymbol into different categories.
+ */
+class SymbolCategory
+{
+private:
+  typedef std::vector<LDSymbol*> OutputSymbols;
+
+public:
+  typedef OutputSymbols::iterator iterator;
+  typedef OutputSymbols::const_iterator const_iterator;
+
+public:
+  SymbolCategory();
+
+  ~SymbolCategory();
+
+  // -----  modifiers  ----- //
+  SymbolCategory& add(LDSymbol& pSymbol);
+
+  SymbolCategory& forceLocal(LDSymbol& pSymbol);
+
+  SymbolCategory& arrange(LDSymbol& pSymbol, const ResolveInfo& pSourceInfo);
+
+  SymbolCategory& changeCommonsToGlobal();
+
+  // -----  access  ----- //
+  LDSymbol& at(size_t pPosition)
+  { return *m_OutputSymbols.at(pPosition); }
+
+  const LDSymbol& at(size_t pPosition) const
+  { return *m_OutputSymbols.at(pPosition); }
+
+  LDSymbol& operator[](size_t pPosition)
+  { return *m_OutputSymbols[pPosition]; }
+
+  const LDSymbol& operator[](size_t pPosition) const
+  { return *m_OutputSymbols[pPosition]; }
+
+  // -----  observers  ----- //
+  size_t numOfSymbols() const;
+
+  size_t numOfLocals() const;
+
+  size_t numOfCommons() const;
+
+  size_t numOfRegulars() const;
+
+  bool empty() const;
+
+  bool emptyLocals() const;
+  
+  bool emptyCommons() const;
+
+  bool emptyRegulars() const;
+
+  // -----  iterators  ----- //
+  iterator begin();
+  iterator end();
+  const_iterator begin() const;
+  const_iterator end() const;
+
+  iterator localBegin();
+  iterator localEnd();
+  const_iterator localBegin() const;
+  const_iterator localEnd() const;
+
+  iterator commonBegin();
+  iterator commonEnd();
+  const_iterator commonBegin() const;
+  const_iterator commonEnd() const;
+
+  iterator regularBegin();
+  iterator regularEnd();
+  const_iterator regularBegin() const;
+  const_iterator regularEnd() const;
+
+private:
+  class Category
+  {
+  public:
+    enum Type {
+      File,
+      Local,
+      Common,
+      Weak,
+      Global
+    };
+
+  public:
+    Type type;
+
+    size_t begin;
+    size_t end;
+
+    Category* prev;
+    Category* next;
+
+  public:
+    Category(Type pType)
+      : type(pType),
+        begin(0),
+        end(0),
+        prev(NULL),
+        next(NULL) {
+    }
+
+    size_t size() const
+    { return (end - begin); }
+
+    bool empty() const
+    { return (begin == end); }
+
+    bool isFirst() const
+    { return (NULL == prev); }
+
+    bool isLast() const
+    { return (NULL == next); }
+
+    static Type categorize(const ResolveInfo& pInfo);
+
+  };
+
+private:
+  OutputSymbols m_OutputSymbols;
+
+  Category* m_pFile;
+  Category* m_pLocal;
+  Category* m_pCommon;
+  Category* m_pWeak;
+  Category* m_pGlobal;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Allocators.h b/include/mcld/Support/Allocators.h
new file mode 100644
index 0000000..962c900
--- /dev/null
+++ b/include/mcld/Support/Allocators.h
@@ -0,0 +1,439 @@
+//===- Allocators.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ALLOCATORS_H
+#define LLVM_ALLOCATORS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/LD/LDContext.h"
+#include <cstdlib>
+
+namespace mcld
+{
+
+/** \class Chunk
+ *  \brief Chunk is the basic unit of the storage of the LinearAllocator
+ *
+ *  @see LinearAllocator
+ */
+template<typename DataType, size_t ChunkSize>
+struct Chunk
+{
+public:
+  typedef DataType value_type;
+public:
+  Chunk()
+  : next(0), bound(0)
+  { }
+
+  static size_t size() { return ChunkSize; }
+
+public:
+  Chunk* next;
+  size_t bound;
+  DataType data[ChunkSize];
+};
+
+template<typename DataType>
+struct Chunk<DataType, 0>
+{
+public:
+  typedef DataType value_type;
+
+public:
+  Chunk()
+  : next(0), bound(0) {
+    if (0 != m_Size)
+      data = (DataType*)malloc(sizeof(DataType)*m_Size);
+    else
+      data = 0;
+  }
+
+  ~Chunk() {
+    if (data)
+      free(data);
+  }
+
+  static size_t size()              { return m_Size; }
+  static void setSize(size_t pSize) { m_Size = pSize; }
+
+public:
+  Chunk* next;
+  size_t bound;
+  DataType *data;
+  static size_t m_Size;
+};
+
+template<typename DataType>
+size_t Chunk<DataType, 0>::m_Size = 0;
+
+template<typename ChunkType>
+class LinearAllocatorBase : private Uncopyable
+{
+public:
+  typedef ChunkType                             chunk_type;
+  typedef typename ChunkType::value_type        value_type;
+  typedef typename ChunkType::value_type*       pointer;
+  typedef typename ChunkType::value_type&       reference;
+  typedef const typename ChunkType::value_type* const_pointer;
+  typedef const typename ChunkType::value_type& const_reference;
+  typedef size_t                                size_type;
+  typedef ptrdiff_t                             difference_type;
+  typedef unsigned char                         byte_type;
+
+protected:
+  LinearAllocatorBase()
+    : m_pRoot(0),
+      m_pCurrent(0),
+      m_AllocatedNum(0) {
+  }
+
+  // LinearAllocatorBase does NOT mean to destroy the allocated memory.
+  // If you want a memory allocator to release memory at destruction, please
+  // use GCFactory series.
+  virtual ~LinearAllocatorBase()
+  { }
+
+public:
+  pointer address(reference X) const
+  { return &X; }
+
+  const_pointer address(const_reference X) const
+  { return &X; }
+
+  /// standard construct - constructing an object on the location pointed by
+  //  pPtr, and using its copy constructor to initialized its value to pValue.
+  //
+  //  @param pPtr the address where the object to be constructed
+  //  @param pValue the value to be constructed
+  void construct(pointer pPtr, const_reference pValue)
+  { new (pPtr) value_type(pValue); }
+
+  /// default construct - constructing an object on the location pointed by
+  //  pPtr, and using its default constructor to initialized its value to
+  //  pValue.
+  //
+  //  @param pPtr the address where the object to be constructed
+  void construct(pointer pPtr)
+  { new (pPtr) value_type(); }
+
+  /// standard destroy - destroy data on arbitrary address
+  //  @para pPtr the address where the data to be destruected.
+  void destroy(pointer pPtr)
+  { pPtr->~value_type(); }
+
+  /// allocate - allocate N data in order.
+  //  - Disallow to allocate a chunk whose size is bigger than a chunk.
+  //
+  //  @param N the number of allocated data.
+  //  @return the start address of the allocated memory
+  pointer allocate(size_type N) {
+    if (0 == N || N > chunk_type::size())
+      return 0;
+
+    if (empty())
+      initialize();
+
+    size_type rest_num_elem = chunk_type::size() - m_pCurrent->bound;
+    pointer result = 0;
+    if (N > rest_num_elem)
+      createChunk();
+    result = const_cast<pointer>(&(m_pCurrent->data[m_pCurrent->bound]));
+    m_pCurrent->bound += N;
+    return result;
+  }
+
+  /// allocate - clone function of allocating one datum.
+  pointer allocate() {
+    if (empty())
+      initialize();
+
+    pointer result = 0;
+    if (chunk_type::size() == m_pCurrent->bound)
+      createChunk();
+    result = const_cast<pointer>(&(m_pCurrent->data[m_pCurrent->bound]));
+    ++m_pCurrent->bound;
+    return result;
+  }
+
+  /// deallocate - deallocate N data from the pPtr
+  //  - if we can simply release some memory, then do it. Otherwise, do
+  //    nothing.
+  void deallocate(pointer &pPtr, size_type N) {
+    if (0 == N ||
+        N > chunk_type::size() ||
+        0 == m_pCurrent->bound ||
+        N >= m_pCurrent->bound)
+      return;
+    if (!isAvailable(pPtr))
+      return;
+    m_pCurrent->bound -= N;
+    pPtr = 0;
+  }
+
+  /// deallocate - clone function of deallocating one datum
+  void deallocate(pointer &pPtr) {
+    if (0 == m_pCurrent->bound)
+      return;
+    if (!isAvailable(pPtr))
+      return;
+    m_pCurrent->bound -= 1;
+    pPtr = 0;
+  }
+
+  /// isIn - whether the pPtr is in the current chunk?
+  bool isIn(pointer pPtr) const {
+    if (pPtr >= &(m_pCurrent->data[0]) &&
+        pPtr <= &(m_pCurrent->data[chunk_type::size()-1]))
+      return true;
+    return false;
+  }
+
+  /// isIn - whether the pPtr is allocated, and can be constructed.
+  bool isAvailable(pointer pPtr) const {
+    if (pPtr >= &(m_pCurrent->data[m_pCurrent->bound]) &&
+        pPtr <= &(m_pCurrent->data[chunk_type::size()-1]))
+      return true;
+    return false;
+  }
+
+  void reset() {
+    m_pRoot = 0;
+    m_pCurrent = 0;
+    m_AllocatedNum = 0;
+  }
+
+  /// clear - clear all chunks
+  void clear() {
+    chunk_type *cur = m_pRoot, *prev;
+    while (0 != cur) {
+      unsigned int idx=0;
+      prev = cur;
+      cur = cur->next;
+      while (idx != prev->bound) {
+        destroy(&prev->data[idx]);
+        ++idx;
+      }
+      delete prev;
+    }
+    reset();
+  }
+
+  // -----  observers  ----- //
+  bool empty() const {
+    return (0 == m_pRoot);
+  }
+
+  size_type max_size() const
+  { return m_AllocatedNum; }
+
+protected:
+  inline void initialize() {
+    m_pRoot = new chunk_type();
+    m_pCurrent = m_pRoot;
+    m_AllocatedNum += chunk_type::size();
+  }
+
+  inline chunk_type *createChunk() {
+    chunk_type *result = new chunk_type();
+    m_pCurrent->next = result;
+    m_pCurrent = result;
+    m_AllocatedNum += chunk_type::size();
+    return result;
+  }
+
+protected:
+  chunk_type *m_pRoot;
+  chunk_type *m_pCurrent;
+  size_type   m_AllocatedNum;
+};
+
+/** \class LinearAllocator
+ *  \brief LinearAllocator is another bump pointer allocator which should be
+ *  limited in use of two-phase memory allocation.
+ *
+ *  Two-phase memory allocation clear separates the use of memory into 'claim'
+ *  and 'release' phases. There are no interleaving allocation and
+ *  deallocation. Interleaving 'allocate' and 'deallocate' increases the size
+ *  of allocated memory, and causes bad locality.
+ *
+ *  The underlying concept of LinearAllocator is a memory pool. LinearAllocator
+ *  is a simple implementation of boost::pool's ordered_malloc() and
+ *  ordered_free().
+ *
+ *  template argument DataType is the DataType to be allocated
+ *  template argument ChunkSize is the number of bytes of a chunk
+ */
+template<typename DataType, size_t ChunkSize>
+class LinearAllocator : public LinearAllocatorBase<Chunk<DataType, ChunkSize> >
+{
+public:
+  template<typename NewDataType>
+  struct rebind {
+    typedef LinearAllocator<NewDataType, ChunkSize> other;
+  };
+
+public:
+  LinearAllocator()
+    : LinearAllocatorBase<Chunk<DataType, ChunkSize> >() {
+  }
+
+  virtual ~LinearAllocator()
+  { }
+};
+
+template<typename DataType>
+class LinearAllocator<DataType, 0> : public LinearAllocatorBase<Chunk<DataType, 0> >
+{
+public:
+  template<typename NewDataType>
+  struct rebind {
+    typedef LinearAllocator<NewDataType, 0> other;
+  };
+
+public:
+  explicit LinearAllocator(size_t pNum)
+    : LinearAllocatorBase<Chunk<DataType, 0> >() {
+    Chunk<DataType, 0>::setSize(pNum);
+  }
+
+  virtual ~LinearAllocator()
+  { }
+};
+
+template<typename DataType>
+class MallocAllocator
+{
+public:
+  typedef size_t          size_type;
+  typedef ptrdiff_t       difference_type;
+  typedef DataType*       pointer;
+  typedef const DataType* const_pointer;
+  typedef DataType&       reference;
+  typedef const DataType& const_reference;
+  typedef DataType        value_type;
+
+  template<typename OtherDataType>
+  struct rebind
+  {
+    typedef MallocAllocator<OtherDataType> other;
+  };
+
+public:
+  MallocAllocator() throw()
+  { }
+
+  MallocAllocator(const MallocAllocator&) throw()
+  { }
+
+  ~MallocAllocator() throw()
+  { }
+
+  pointer address(reference X) const
+  { return &X; }
+
+  const_pointer address(const_reference X) const
+  { return &X; }
+
+  pointer allocate(size_type pNumOfElements, const void* = 0)
+  {
+    return static_cast<DataType*>(
+                       std::malloc(pNumOfElements*sizeof(DataType)));
+  }
+
+  void deallocate(pointer pObject, size_type)
+  { std::free(static_cast<void*>(pObject)); }
+
+  size_type max_size() const throw()
+  { return size_t(-1) / sizeof(DataType); }
+
+  void construct(pointer pObject, const DataType& pValue)
+  { ::new((void *)pObject) value_type(pValue); }
+
+  void destroy(pointer pObject)
+  { pObject->~DataType(); }
+
+};
+
+template<>
+class MallocAllocator<void>
+{
+public:
+  typedef size_t      size_type;
+  typedef ptrdiff_t   difference_type;
+  typedef void*       pointer;
+  typedef const void* const_pointer;
+  typedef void*       reference;
+  typedef const void* const_reference;
+  typedef void*       value_type;
+
+  template<typename OtherDataType>
+  struct rebind
+  {
+    typedef MallocAllocator<OtherDataType> other;
+  };
+
+public:
+  MallocAllocator() throw()
+  { }
+
+  MallocAllocator(const MallocAllocator&) throw()
+  { }
+
+  ~MallocAllocator() throw()
+  { }
+
+  size_type max_size() const throw()
+  { return size_t(-1) / sizeof(void*); }
+
+  pointer address(reference X) const
+  { return X; }
+
+  const_pointer address(const_reference X) const
+  { return X; }
+
+  template<typename DataType>
+  DataType* allocate(size_type pNumOfElements, const void* = 0) {
+    return static_cast<DataType*>(
+                       std::malloc(pNumOfElements*sizeof(DataType)));
+  }
+
+  pointer allocate(size_type pNumOfElements, const void* = 0) {
+    return std::malloc(pNumOfElements);
+  }
+
+  template<typename DataType>
+  void deallocate(DataType* pObject, size_type)
+  { std::free(static_cast<void*>(pObject)); }
+
+  void deallocate(pointer pObject, size_type)
+  { std::free(pObject); }
+
+  template<typename DataType>
+  void construct(DataType* pObject, const DataType& pValue)
+  { /* do nothing */ }
+
+  void construct(pointer pObject, const_reference pValue)
+  { /* do nothing */ }
+
+  template<typename DataType>
+  void destroy(DataType* pObject)
+  { /* do nothing */ }
+
+  void destroy(pointer pObject)
+  { /* do nothing */ }
+};
+
+} // namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
new file mode 100644
index 0000000..e52c4a3
--- /dev/null
+++ b/include/mcld/Support/CommandLine.h
@@ -0,0 +1,63 @@
+//===- CommandLine.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_COMMANDLINE_H
+#define MCLD_COMMANDLINE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/CommandLine.h>
+#include "mcld/Support/FileSystem.h"
+#include "mcld/MC/MCLDDirectory.h"
+
+//--------------------------------------------------
+// parser<mcld::sys::fs::Path>
+//
+namespace llvm {
+namespace cl {
+
+template<>
+class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path>
+{
+public:
+  bool parse(Option &O,
+             StringRef ArgName,
+             StringRef Arg,
+             mcld::sys::fs::Path &Val);
+
+  virtual const char *getValueName() const { return "path"; }
+  void printOptionDiff(const Option &O,
+                       const mcld::sys::fs::Path &V,
+                       OptVal Default,
+                       size_t GlobalWidth) const;
+  virtual void anchor();
+};
+
+//--------------------------------------------------
+// parser<mcld::MCLDDirectory>
+//
+template<>
+class parser<mcld::MCLDDirectory> : public llvm::cl::basic_parser<mcld::MCLDDirectory>
+{
+public:
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, mcld::MCLDDirectory &Val);
+
+  virtual const char *getValueName() const { return "directory"; }
+  void printOptionDiff(const Option &O,
+                       const mcld::MCLDDirectory &V,
+                       OptVal Default,
+                       size_t GlobalWidth) const;
+  virtual void anchor();
+};
+
+} // namespace of cl
+} // namespace of llvm
+
+#endif
+
diff --git a/include/mcld/Support/DerivedPositionDependentOptions.h b/include/mcld/Support/DerivedPositionDependentOptions.h
new file mode 100644
index 0000000..2254a5f
--- /dev/null
+++ b/include/mcld/Support/DerivedPositionDependentOptions.h
@@ -0,0 +1,137 @@
+//===- DerivedPositionDependentOptions.h ----------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DERIVEDPOSITIONDEPENDENTOPTIONS_H
+#define MCLD_DERIVEDPOSITIONDEPENDENTOPTIONS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <string>
+
+#include "mcld/Support/RealPath.h"
+#include "mcld/Support/PositionDependentOption.h"
+
+namespace mcld
+{
+
+  /** \class DerivedPositionDependentOptions
+   *  \brief This file contains the declarations of classes derived from PositionDependentOption.
+   */
+
+  class FileOption : public PositionDependentOption {
+  private:
+    sys::fs::RealPath m_Path;
+
+  protected:
+    FileOption(unsigned pPosition, Type pType, const sys::fs::Path &pPath)
+      : PositionDependentOption(pPosition, pType)
+    { m_Path.assign(pPath); }
+
+  public:
+    inline const sys::fs::Path *path() const { return &m_Path; }
+  };
+
+  class NamespecOption : public PositionDependentOption {
+  private:
+    std::string m_pNamespec;
+
+  public:
+    NamespecOption(unsigned pPosition, const std::string &pNamespec)
+      : PositionDependentOption(pPosition, PositionDependentOption::NAMESPEC),
+        m_pNamespec(pNamespec) { }
+
+    inline const std::string &namespec() const { return m_pNamespec; }
+  };
+
+  class BitcodeOption : public FileOption {
+  public:
+    BitcodeOption(unsigned pPosition, const sys::fs::Path &pPath)
+      : FileOption(pPosition, PositionDependentOption::BITCODE, pPath) { }
+  };
+
+  class StartGroupOption : public PositionDependentOption {
+  public:
+    StartGroupOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::START_GROUP) { }
+  };
+
+  class EndGroupOption : public PositionDependentOption {
+  public:
+    EndGroupOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::END_GROUP) { }
+  };
+
+  class InputFileOption : public FileOption {
+  public:
+    InputFileOption(unsigned pPosition, const sys::fs::Path &pPath)
+      : FileOption(pPosition, PositionDependentOption::INPUT_FILE, pPath) { }
+  };
+
+  class WholeArchiveOption : public PositionDependentOption {
+  public:
+    WholeArchiveOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::WHOLE_ARCHIVE) { }
+  };
+
+  class NoWholeArchiveOption : public PositionDependentOption {
+  public:
+    NoWholeArchiveOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_WHOLE_ARCHIVE) { }
+  };
+
+  class AsNeededOption : public PositionDependentOption {
+  public:
+    AsNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::AS_NEEDED) { }
+  };
+
+  class NoAsNeededOption : public PositionDependentOption {
+  public:
+    NoAsNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_AS_NEEDED) { }
+  };
+
+  class AddNeededOption : public PositionDependentOption {
+  public:
+    AddNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::ADD_NEEDED) { }
+  };
+
+  class NoAddNeededOption : public PositionDependentOption {
+  public:
+    NoAddNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_ADD_NEEDED) { }
+  };
+
+  class BDynamicOption : public PositionDependentOption {
+  public:
+    BDynamicOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::BDYNAMIC) { }
+  };
+
+  class BStaticOption : public PositionDependentOption {
+  public:
+    BStaticOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::BSTATIC) { }
+  };
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Directory.h b/include/mcld/Support/Directory.h
new file mode 100644
index 0000000..8383e9e
--- /dev/null
+++ b/include/mcld/Support/Directory.h
@@ -0,0 +1,153 @@
+//===- Directory.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DIRECTORY_H
+#define MCLD_DIRECTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+#include "mcld/Support/PathCache.h"
+#include <llvm/Support/Allocator.h>
+
+
+namespace mcld {
+namespace sys {
+namespace fs {
+
+class DirIterator;
+
+/** \class Directory
+ *  \brief A Directory object stores a Path object, a FileStatus object for
+ *   non-symbolic link status, and a FileStatus object for symbolic link
+ *   status. The FileStatus objects act as value caches.
+ */
+class Directory
+{
+friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
+friend void detail::open_dir(Directory& pDir);
+friend void detail::close_dir(Directory& pDir);
+private:
+  friend class DirIterator;
+
+public:
+  typedef DirIterator iterator;
+
+public:
+  /// default constructor
+  Directory();
+
+  /// constructor - a directory whose path is pPath
+  explicit Directory(const Path& pPath,
+                     FileStatus st = FileStatus(),
+                     FileStatus symlink_st = FileStatus());
+
+  /// copy constructor
+  /// when a copying construction happens, the cache is not copied.
+  Directory(const Directory& pCopy);
+
+  /// assignment
+  /// When an assignment occurs, the cache is clear.
+  Directory& operator=(const Directory& pCopy);
+
+  /// destructor, inheritable.
+  virtual ~Directory();
+
+  /// Since we have default construtor, we must provide assign.
+  void assign(const Path& pPath,
+              FileStatus st = FileStatus(),
+              FileStatus symlink_st = FileStatus());
+
+  /// clear - clear the cache and close the directory handler
+  void clear();
+
+  bool isGood() const;
+
+  /// path - the path of the directory
+  const Path& path() const
+  { return m_Path; }
+
+  FileStatus status() const;
+  FileStatus symlinkStatus() const;
+
+  // -----  iterators  ----- //
+  // While the iterators move, the direcotry is modified.
+  // Thus, we only provide non-constant iterator.
+  iterator begin();
+  iterator end();
+
+protected:
+  mcld::sys::fs::Path m_Path;
+  mutable FileStatus m_FileStatus;
+  mutable FileStatus m_SymLinkStatus;
+  intptr_t m_Handler;
+  // the cache of directory
+  mcld::sys::fs::PathCache m_Cache;
+  bool m_CacheFull;
+};
+
+/** \class DirIterator
+ *  \brief A DirIterator object can traverse all entries in a Directory
+ *
+ *  DirIterator will open the directory and add entry into Directory::m_Cache
+ *  DirIterator() is the end of a directory.
+ *  If the end of the directory elements is reached, the iterator becomes
+ *  equal to the end iterator value - DirIterator().
+ *
+ *  @see Directory
+ */
+class DirIterator
+{
+friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
+friend class Directory;
+public:
+  typedef mcld::sys::fs::PathCache            DirCache;
+
+public:
+  typedef Directory                       value_type;
+  typedef ConstTraits<Directory>          const_traits;
+  typedef NonConstTraits<Directory>       non_const_traits;
+  typedef std::input_iterator_tag         iterator_category;
+  typedef size_t                          size_type;
+  typedef ptrdiff_t                       difference_type;
+
+private:
+  explicit DirIterator(Directory* pParent,
+                       const DirCache::iterator& pIter);
+
+public:
+  // Since StringMapIterator has no default constructor, we also have none.
+  DirIterator(const DirIterator &X);
+  ~DirIterator();
+  DirIterator& operator=(const DirIterator& pCopy);
+
+  DirIterator& operator++();
+  DirIterator operator++(int);
+
+  Path* generic_path();
+
+  Path* path();
+  const Path* path() const;
+
+  bool operator==(const DirIterator& y) const;
+  bool operator!=(const DirIterator& y) const;
+
+private:
+  Directory* m_pParent; // get handler
+  DirCache::iterator m_Iter; // for full situation
+  DirCache::entry_type* m_pEntry;
+};
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/FileSystem.h b/include/mcld/Support/FileSystem.h
new file mode 100644
index 0000000..28dc563
--- /dev/null
+++ b/include/mcld/Support/FileSystem.h
@@ -0,0 +1,119 @@
+//===- FileSystem.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the mcld::sys::fs:: namespace. It follows TR2/boost
+// filesystem (v3), but modified to remove exception handling and the
+// path class.
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_FILE_SYSTEM_H
+#define MCLD_FILE_SYSTEM_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/PathCache.h"
+#include <string>
+#include <iosfwd>
+#include <locale>
+
+namespace mcld {
+namespace sys {
+namespace fs {
+
+enum FileType
+{
+  StatusError,
+  StatusUnknown = StatusError,
+  FileNotFound,
+  RegularFile,
+  DirectoryFile,
+  SymlinkFile,
+  BlockFile,
+  CharacterFile,
+  FifoFile,
+  SocketFile,
+  ReparseFile,
+  TypeUnknown,
+  StatusKnown,
+  IsSymLink
+};
+
+/** \class FileStatus
+ *  \brief FileStatus
+ */
+class FileStatus
+{
+public:
+  FileStatus()
+    : m_Value(StatusError) {}
+
+  explicit FileStatus(FileType v)
+    : m_Value(v) {}
+
+  void setType(FileType v)   { m_Value = v; }
+  FileType type() const   { return m_Value; }
+
+private:
+  FileType m_Value;
+};
+
+inline bool operator==(const FileStatus& rhs, const FileStatus& lhs) {
+  return rhs.type() == lhs.type();
+}
+
+inline bool operator!=(const FileStatus& rhs, const FileStatus& lhs ) {
+  return !(rhs == lhs);
+}
+
+class Path;
+class DirIterator;
+class Directory;
+
+bool exists(const Path &pPath);
+bool is_directory(const Path &pPath);
+
+inline static bool exists(FileStatus f) {
+  return (f.type() != StatusError)&&(f.type() != FileNotFound);
+}
+
+inline static bool is_directory(FileStatus f) {
+  return f.type() == mcld::sys::fs::DirectoryFile;
+}
+
+namespace detail
+{
+
+typedef unsigned char* Address;
+typedef off_t Offset;
+extern std::string static_library_extension;
+extern std::string shared_library_extension;
+extern std::string executable_extension;
+extern std::string relocatable_extension;
+extern std::string assembly_extension;
+extern std::string bitcode_extension;
+
+size_t canonicalize(std::string& pPathName);
+bool not_found_error(int perrno);
+void status(const Path& p, FileStatus& pFileStatus);
+void symlink_status(const Path& p, FileStatus& pFileStatus);
+mcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter);
+void open_dir(Directory& pDir);
+void close_dir(Directory& pDir);
+void get_pwd(std::string& pPWD);
+size_t pread(int pFD, Address pBuf, size_t pCount, off_t pOffset);
+size_t pwrite(int pFD, const Address pBuf, size_t pCount, off_t pOffset);
+char *strerror(int pErrnum);
+
+} // namespace of detail
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/GCFactory.h b/include/mcld/Support/GCFactory.h
new file mode 100644
index 0000000..103188e
--- /dev/null
+++ b/include/mcld/Support/GCFactory.h
@@ -0,0 +1,230 @@
+//===- GCFactory.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_H
+#define MCLD_GC_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/Allocators.h"
+
+#include <assert.h>
+#include <iterator>
+
+namespace mcld
+{
+
+/** \class DataIteratorBase
+ *  \brief DataIteratorBase provides the basic functions of DataIterator
+ *  @see DataIterator
+ */
+template<typename ChunkType>
+struct DataIteratorBase
+{
+public:
+  ChunkType* m_pChunk;
+  unsigned int m_Pos;
+
+public:
+  DataIteratorBase(ChunkType* X, unsigned int pPos)
+  : m_pChunk(X), m_Pos(pPos)
+  { }
+
+  inline void advance() {
+    ++m_Pos;
+    if ((m_Pos == m_pChunk->bound) && (0 == m_pChunk->next))
+      return;
+    if (m_Pos == m_pChunk->bound) {
+      m_pChunk = m_pChunk->next;
+      m_Pos = 0;
+    }
+  }
+
+  bool operator==(const DataIteratorBase& y) const
+  { return ((this->m_pChunk == y.m_pChunk) && (this->m_Pos == y.m_Pos)); }
+
+  bool operator!=(const DataIteratorBase& y) const
+  { return ((this->m_pChunk != y.m_pChunk) || (this->m_Pos != y.m_Pos)); }
+};
+
+/** \class DataIterator
+ *  \brief DataIterator provides STL compatible iterator for allocators
+ */
+template<typename ChunkType, class Traits>
+class DataIterator : public DataIteratorBase<ChunkType>
+{
+public:
+  typedef typename ChunkType::value_type  value_type;
+  typedef Traits                          traits;
+  typedef typename traits::pointer        pointer;
+  typedef typename traits::reference      reference;
+  typedef DataIterator<ChunkType, Traits> Self;
+  typedef DataIteratorBase<ChunkType>     Base;
+
+  typedef typename traits::nonconst_traits         nonconst_traits;
+  typedef DataIterator<ChunkType, nonconst_traits> iterator;
+  typedef typename traits::const_traits            const_traits;
+  typedef DataIterator<ChunkType, const_traits>    const_iterator;
+  typedef std::forward_iterator_tag                iterator_category;
+  typedef size_t                                   size_type;
+  typedef ptrdiff_t                                difference_type;
+
+public:
+  DataIterator()
+  : Base(0, 0)
+  { }
+
+  DataIterator(ChunkType* pChunk, unsigned int pPos)
+  : Base(pChunk, pPos)
+  { }
+
+  DataIterator(const DataIterator& pCopy)
+  : Base(pCopy.m_pChunk, pCopy.m_Pos)
+  { }
+
+  ~DataIterator()
+  { }
+
+  // -----  operators  ----- //
+  reference operator*() {
+    if (0 == this->m_pChunk)
+      assert(0 && "data iterator goes to a invalid position");
+    return this->m_pChunk->data[Base::m_Pos];
+  }
+
+  Self& operator++() {
+    this->Base::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->Base::advance();
+    return tmp;
+  }
+};
+
+template<typename Alloc>
+class GCFactoryBase : public Alloc
+{
+public:
+  typedef DataIterator<typename Alloc::chunk_type,
+                       NonConstTraits<
+                         typename Alloc::value_type> > iterator;
+  typedef DataIterator<typename Alloc::chunk_type,
+                       ConstTraits<
+                         typename Alloc::value_type> > const_iterator;
+
+  typedef typename Alloc::value_type value_type;
+  typedef typename Alloc::pointer    pointer;
+  typedef typename Alloc::reference  reference;
+  typedef typename Alloc::size_type  size_type;
+
+protected:
+  GCFactoryBase()
+  : Alloc(), m_NumAllocData(0)
+  { }
+
+  GCFactoryBase(size_t pNum)
+  : Alloc(pNum), m_NumAllocData(0)
+  { }
+
+public:
+  virtual ~GCFactoryBase()
+  { Alloc::clear(); }
+
+  // -----  modifiers  ----- //
+  value_type* allocate(size_t N) {
+    value_type* result = Alloc::allocate(N);
+    if (0 != result)
+      m_NumAllocData += N;
+    return result;
+  }
+
+  value_type* allocate() {
+    ++m_NumAllocData;
+    return Alloc::allocate();
+  }
+
+  void deallocate(pointer &pPtr, size_type N) {
+    Alloc::deallocate(pPtr, N);
+    if (0 == pPtr)
+      m_NumAllocData -= N;
+  }
+
+  void deallocate(pointer &pPtr) {
+    Alloc::deallocate(pPtr);
+    if (0 == pPtr)
+      --m_NumAllocData;
+  }
+
+  void reset() {
+    Alloc::reset();
+    m_NumAllocData = 0;
+  }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return iterator(Alloc::m_pRoot, 0); }
+
+  const_iterator begin() const
+  { return const_iterator(Alloc::m_pRoot, 0); }
+
+  iterator end() {
+    return (0 == Alloc::m_pCurrent)? 
+             begin():
+             iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
+  }
+
+  const_iterator end() const {
+    return (0 == Alloc::m_pCurrent)? 
+             begin():
+             const_iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
+  }
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return Alloc::empty(); }
+
+  unsigned int capacity() const
+  { return Alloc::max_size(); }
+
+  unsigned int size() const
+  { return m_NumAllocData; }
+
+protected:
+  unsigned int m_NumAllocData;
+};
+
+/** \class GCFactory
+ *  \brief GCFactory provides a factory that guaratees to remove all allocated
+ *  data.
+ */
+template<typename DataType, size_t ChunkSize>
+class GCFactory : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
+{
+public:
+  GCFactory()
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
+  { }
+};
+
+template<typename DataType>
+class GCFactory<DataType, 0> : public GCFactoryBase<LinearAllocator<DataType, 0> >
+{
+public:
+  GCFactory(size_t pNum)
+  : GCFactoryBase<LinearAllocator<DataType, 0> >(pNum)
+  { }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/GCFactoryListTraits.h b/include/mcld/Support/GCFactoryListTraits.h
new file mode 100644
index 0000000..418ec57
--- /dev/null
+++ b/include/mcld/Support/GCFactoryListTraits.h
@@ -0,0 +1,65 @@
+//===- GCFactoryListTraits.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_LIST_TRAITS_H
+#define MCLD_GC_FACTORY_LIST_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/ADT/ilist.h>
+
+#include <assert.h>
+
+namespace mcld
+{
+
+/** \class GCFactoryListTraits
+ *  \brief GCFactoryListTraits provides trait class for llvm::iplist when
+ *  the nodes in the list is produced by GCFactory.
+ */
+template<typename DataType>
+class GCFactoryListTraits : public llvm::ilist_default_traits<DataType> {
+private:
+  class SentinelNode : public llvm::ilist_node<DataType> {
+  public:
+    SentinelNode() : llvm::ilist_node<DataType>() { }
+  };
+
+public:
+  // override the traits provided in llvm::ilist_sentinel_traits since we've
+  // defined our own sentinel.
+  DataType *createSentinel() const
+  { return reinterpret_cast<DataType*>(&mSentinel); }
+
+  static void destroySentinel(DataType*) { }
+
+  DataType *provideInitialHead() const
+  { return createSentinel(); }
+
+  DataType *ensureHead(DataType*) const
+  { return createSentinel(); }
+
+  static void noteHead(DataType*, DataType*) { }
+
+  // override the traits provided in llvm::ilist_node_traits since
+  static DataType *createNode(const DataType &V) {
+    assert(false && "Only GCFactory knows how to create a node.");
+  }
+  static void deleteNode(DataType *V) {
+    // No action. GCFactory will handle it by itself.
+  }
+
+private:
+  mutable SentinelNode mSentinel;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/LEB128.h b/include/mcld/Support/LEB128.h
new file mode 100644
index 0000000..816ed72
--- /dev/null
+++ b/include/mcld/Support/LEB128.h
@@ -0,0 +1,117 @@
+//===- LEB128.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LEB128_H
+#define MCLD_LEB128_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace mcld {
+
+namespace leb128 {
+
+typedef unsigned char ByteType;
+
+/* Forward declarations */
+template<typename IntType>
+size_t encode(ByteType *&pBuf, IntType pValue);
+
+template<typename IntType>
+IntType decode(const ByteType *pBuf, size_t &pSize);
+
+template<typename IntType>
+IntType decode(const ByteType *&pBuf);
+
+/*
+ * Given an integer, this function returns the number of bytes required to
+ * encode it in ULEB128 format.
+ */
+template<typename IntType>
+size_t size(IntType pValue) {
+  size_t size = 1;
+  while (pValue > 0x80) {
+    pValue >>= 7;
+    ++size;
+  }
+  return size;
+}
+
+/*
+ * Write an unsigned integer in ULEB128 to the given buffer. The client should
+ * ensure there's enough space in the buffer to hold the result. Update the
+ * given buffer pointer to the point just past the end of the write value and
+ * return the number of bytes being written.
+ */
+template<>
+size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue);
+
+template<>
+size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue);
+
+/*
+ * Encoding functions for signed LEB128.
+ */
+template<>
+size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue);
+
+template<>
+size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue);
+
+/*
+ * Read an integer encoded in ULEB128 format from the given buffer. pSize will
+ * contain the number of bytes used in the buffer to encode the returned
+ * integer.
+ */
+template<>
+uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize);
+
+/*
+ * Read an integer encoded in ULEB128 format from the given buffer. Update the
+ * given buffer pointer to the point just past the end of the read value.
+ */
+template<>
+uint64_t decode<uint64_t>(const ByteType *&pBuf);
+
+/*
+ * Decoding functions for signed LEB128.
+ */
+template<>
+int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize);
+
+template<>
+int64_t decode<int64_t>(const ByteType *&pBuf);
+
+/*
+ * The functions below handle the signed byte stream. This helps the user to get
+ * rid of annoying type conversions when using the LEB128 encoding/decoding APIs
+ * defined above.
+ */
+template<typename IntType>
+size_t encode(char *&pBuf, IntType pValue) {
+  return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
+}
+
+template<typename IntType>
+IntType decode(const char *pBuf, size_t &pSize) {
+  return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
+}
+
+template<typename IntType>
+IntType decode(const char *&pBuf) {
+  return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf));
+}
+
+} // namespace of leb128
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/MemoryArea.h b/include/mcld/Support/MemoryArea.h
new file mode 100644
index 0000000..2c04aff
--- /dev/null
+++ b/include/mcld/Support/MemoryArea.h
@@ -0,0 +1,260 @@
+//===- MemoryArea.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MEMORY_AREA_H
+#define MCLD_MEMORY_AREA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <fcntl.h>
+#include <string>
+#include <list>
+
+#if defined(ENABLE_UNITTEST)
+namespace mcldtest
+{
+  class MemoryAreaTest;
+} // namespace of mcldtest
+
+#endif
+namespace mcld
+{
+
+class MemoryRegion;
+class RegionFactory;
+
+/** \class MemoryArea
+ *  \brief MemoryArea is used to manage distinct MemoryRegions of address space.
+ *
+ *  Good linkers must well manipulate memory mapped I/O and dynamic memory.
+ *  In MCLinker, MemoryArea is the decision-maker to use memory mapped I/O or
+ *  dynamic memory. When a client requests MemoryArea for a piece of memory
+ *  to hold a part of a file, MemoryArea is going to see whether the requested
+ *  part of the file is already in any existing memory which is requested
+ *  before. If it is, MemoryArea creates a new MemoryRegion within the memory
+ *  requested before. Otherwise, MemoryArea uses memory mapped I/O or dynamic
+ *  memory to load the file.
+ *
+ *  If the part a file being loaded is larger than 3/4 pages, MemoryArea uses
+ *  memory mapped I/O to load the file. Otherwise, MemoryArea uses dynamic
+ *  memory to read the content of file into the memory space.
+ */
+class MemoryArea : private Uncopyable
+{
+#if defined(ENABLE_UNITTEST)
+friend class mcldtest::MemoryAreaTest;
+#endif
+public:
+  enum IOState
+  {
+    GoodBit    = 0,
+    BadBit     = 1L << 0,
+    EOFBit     = 1L << 1,
+    FailBit    = 1L << 2,
+    IOStateEnd = 1L << 16
+  };
+
+  enum AccessMode
+  {
+    ReadOnly = O_RDONLY,
+    WriteOnly = O_WRONLY,
+    ReadWrite = O_RDWR,
+    AccessMask = O_ACCMODE
+  };
+
+private:
+  typedef sys::fs::detail::Address Address;
+
+  friend class MemoryRegion;
+  friend class RegionFactory;
+  struct Space : public llvm::ilist_node<Space>
+  {
+  public:
+    enum Type
+    {
+      ALLOCATED_ARRAY,
+      MMAPED,
+      UNALLOCATED
+    };
+
+  public:
+    Space()
+    : m_pParent(NULL),
+      type(UNALLOCATED),
+      file_offset(0),
+      size(0),
+      data(0),
+      region_num(0)
+    { }
+
+    Space(MemoryArea* pParent, size_t pOffset, size_t pLength)
+    : m_pParent(pParent),
+      type(UNALLOCATED),
+      file_offset(pOffset),
+      size(pLength),
+      data(0),
+      region_num(0)
+    { }
+
+    ~Space()
+    { }
+
+    void sync()
+    { m_pParent->write(*this); }
+
+  private:
+    MemoryArea* m_pParent;
+
+  public:
+    Type type;
+    size_t file_offset;
+    size_t size;
+    sys::fs::detail::Address data;
+    size_t region_num;
+  };
+
+  friend class Space;
+  typedef llvm::iplist<Space> SpaceList;
+
+public:
+  // constructor
+  // @param pRegionFactory the factory to manage MemoryRegions
+  MemoryArea(RegionFactory& pRegionFactory);
+
+  // destructor
+  ~MemoryArea();
+
+  // request - create a MemoryRegion within a sufficient space
+  // find an existing space to hold the MemoryRegion.
+  // if MemoryArea does not find such space, then it creates a new space and
+  // assign a MemoryRegion into the space.
+  MemoryRegion* request(size_t pOffset, size_t pLength);
+
+  // release - release a MemoryRegion.
+  // release a MemoryRegion does not cause
+  void release(MemoryRegion* pRegion);
+
+  // clean - release all MemoryRegion and unmap all spaces.
+  void clean();
+
+  // sync - sync all MemoryRegion
+  void sync();
+
+  // map - open the file pPath and mapped it onto MemoryArea
+  // @param flags see man 2 open
+  void map(const sys::fs::Path& pPath, int flags);
+
+  // map - open the file pPath and mapped it onto MemoryArea
+  // @param flags see man 2 open
+  // @param mode see man 2 open
+  void map(const sys::fs::Path& pPath, int flags, int mode);
+
+  // unmap - close the opened file and unmap the MemoryArea
+  void unmap();
+
+  // path - the path of the mapped file.
+  const sys::fs::Path& path() const
+  { return m_FilePath; }
+
+  // size - the real size of the mapped file.
+  size_t size() const
+  { return m_FileSize; }
+
+  // isMapped - check if MemoryArea is mapped to a file
+  bool isMapped() const;
+
+  // isGood - check if the state of the opened area is good for read/write
+  // operations
+  bool isGood() const;
+
+  // isBad - check if an error causes the loss of integrity of the memory space
+  bool isBad() const;
+
+  // isFailed - check if an error related to the internal logic of the operation
+  // itself occurs
+  bool isFailed() const;
+
+  // isEOF - check if we reach the end of the file
+  bool isEOF() const;
+
+  // isReadable - check if the memory area is readable
+  bool isReadable() const;
+
+  // isWriteable - check if the memory area is writable
+  bool isWritable() const;
+
+  // rdstate - get error state flags
+  // Returns the current internal error state flags of the stream
+  int rdstate() const;
+
+  // setState - set error state flag
+  void setState(IOState pState);
+
+  // clear - set error state flag
+  void clear(IOState pState = GoodBit);
+
+private:
+  // readToBuffer - read data from the file behind this MemorySpace and store
+  // those bytes in pBuf. Return the number of byte read or -1 on error.
+  ssize_t readToBuffer(sys::fs::detail::Address pBuf,
+                       size_t pSize, size_t pOffset);
+
+private:
+  // find - first fit search
+  Space* find(size_t pOffset, size_t pLength);
+
+  // release a Space, but does not remove it from space list
+  void release(Space* pSpace);
+
+  // read - read data from mapped file into virtual memroy of pSpace. Return
+  // false on error.
+  bool read(Space& pSpace);
+
+  // write - write back the virtual memory of pSpace into mapped file.
+  void write(const Space& pSpace);
+
+  // truncate - truncate the file size to length.
+  void truncate(size_t pLength);
+
+  // policy - decide whehter to use dynamic memory or memory mapped I/O
+  Space::Type policy(off_t pOffset, size_t pLength);
+
+  // the size of one page
+  static const off_t PageSize = 4096;
+
+  // page_boundary - Given a file size, return the size to read integral pages.
+  // return the first page boundary after pFileOffset
+  static off_t page_boundary(off_t pFileOffset)
+  { return (pFileOffset + (PageSize - 1)) & ~ (PageSize - 1); }
+
+  // Given a file offset, return the page offset.
+  // return the first page boundary before pFileOffset
+  static off_t page_offset(off_t pFileOffset)
+  { return pFileOffset & ~ (PageSize - 1); }
+
+private:
+  RegionFactory& m_RegionFactory;
+  sys::fs::Path m_FilePath;
+  int m_FileDescriptor;
+  size_t m_FileSize;
+  int m_AccessFlags;
+  int m_State;
+
+  SpaceList m_SpaceList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/MemoryAreaFactory.h b/include/mcld/Support/MemoryAreaFactory.h
new file mode 100644
index 0000000..f9ffa6e
--- /dev/null
+++ b/include/mcld/Support/MemoryAreaFactory.h
@@ -0,0 +1,64 @@
+//===- MemoryAreaFactory.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MEMORY_AREA_FACTORY_H
+#define MCLD_MEMORY_AREA_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/UniqueGCFactory.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/Path.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+namespace mcld
+{
+
+class RegionFactory;
+/** \class MemoryAreaFactory
+ *  \brief MemoryAreaFactory avoids creating duplicated MemoryAreas of the
+ *   same file.
+ *
+ *  Users can give duplicated input files on the command line. In order to 
+ *  prevent opening the same file twice, and create redundant MemoryRegions,
+ *  mcld::Input should not create MemoryArea directly. Instead, it should ask
+ *  MemoryAreaFactory and get the unique MemoryArea.
+ *
+ *  The timing of opening and closing files is not strictly bound to the
+ *  constructor and destructor of MCLDFile. For mcld::Output, MCLinker
+ *  opens the file rather after assigning offset to sections. On the other
+ *  aside, mcld::Input opens the file at constructor. In order to hide the
+ *  file operations, MemoryAreaFactory actually open the file untill the first
+ *  MemoryRegion is requested.
+ *
+ *  @see MemoryRegion
+ *  @see UniqueGCFactoryBase
+ */
+class MemoryAreaFactory : public UniqueGCFactoryBase<sys::fs::Path, MemoryArea, 0>
+{
+public:
+  explicit MemoryAreaFactory(size_t pNum);
+  ~MemoryAreaFactory();
+
+  // produce - create a MemoryArea and open its file
+  // If the file fails to be opened, the returned MemoryArea::isMapped() 
+  // should be false
+  MemoryArea* produce(const sys::fs::Path& pPath, int pFlags);
+  MemoryArea* produce(const sys::fs::Path& pPath, int pFlags, mode_t pMode);
+
+private:
+  RegionFactory* m_pRegionFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/MemoryRegion.h b/include/mcld/Support/MemoryRegion.h
new file mode 100644
index 0000000..49f5fda
--- /dev/null
+++ b/include/mcld/Support/MemoryRegion.h
@@ -0,0 +1,97 @@
+//===- MemoryRegion.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_MEMORY_REGION_H
+#define LD_MEMORY_REGION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Support/MemoryArea.h>
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld
+{
+
+/** \class MemoryRegion
+ *  \brief MemoryRegion is a range of virtual memory which is mapped onto a
+ *  range of files which is opened by MemoryArea.
+ *
+ *  MemoryArea maps a file onto virtual memory. Clients can get a range of
+ *  mapped memory space by requesting a MemoryRegion from MemoryArea, and
+ *  read/write the mapped file through the MemoryRegion.
+ *
+ *  When two different MemoryRegion may overlap memory space, race condition
+ *  may occurs. Clients must call MemoryRegion::sync() explicit to tell the
+ *  MemoryArea when to synchronize the virtual memory space with the mapped
+ *  file.
+ */
+class MemoryRegion : private Uncopyable
+{
+friend class RegionFactory;
+friend class MemoryArea;
+
+public:
+typedef NonConstTraits<mcld::sys::fs::detail::Address>::value_type Address;
+typedef ConstTraits<mcld::sys::fs::detail::Address>::value_type    ConstAddress;
+typedef NonConstTraits<mcld::sys::fs::detail::Offset>::value_type  Offset;
+typedef ConstTraits<mcld::sys::fs::detail::Offset>::value_type     ConstOffset;
+
+private:
+  MemoryRegion(MemoryArea::Space* pParentSpace,
+               const Address pVMAStart,
+               size_t pSize);
+
+  // drift - leave parent space
+  void drift();
+
+  MemoryArea::Space* parent()
+  { return m_pParentSpace; }
+
+  const MemoryArea::Space* parent() const
+  { return m_pParentSpace; }
+
+public:
+  ~MemoryRegion();
+
+  Address start()
+  { return m_VMAStart; }
+
+  ConstAddress start() const
+  { return m_VMAStart; }
+
+  Address end()
+  { return m_VMAStart+m_Length; }
+
+  ConstAddress end() const
+  { return m_VMAStart+m_Length; }
+
+  size_t size() const
+  { return m_Length; }
+
+  Address getBuffer(Offset pOffset = 0)
+  { return m_VMAStart+pOffset; }
+
+  ConstAddress getBuffer(Offset pOffset = 0) const
+  { return m_VMAStart+pOffset; }
+ 
+private:
+  MemoryArea::Space* m_pParentSpace;
+  Address m_VMAStart;
+  size_t m_Length;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
new file mode 100644
index 0000000..f5ee56c
--- /dev/null
+++ b/include/mcld/Support/Path.h
@@ -0,0 +1,179 @@
+//===- Path.h -------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the mcld::sys::fs:: namespace. It follows TR2/boost
+// filesystem (v3), but modified to remove exception handling and the
+// path class.
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_PATH_H
+#define MCLD_PATH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/raw_ostream.h>
+#include <functional>
+#include <string>
+
+//#include "mcld/Support/Directory.h"
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+#ifdef LLVM_ON_WIN32
+const wchar_t       separator = L'\\';
+const wchar_t       preferred_separator = L'\\';
+#else
+const char          separator = '/';
+const char          preferred_separator = '/';
+#endif
+
+/** \class Path
+ *  \brief Path provides an abstraction for the path to a file or directory in
+ *   the operating system's filesystem.
+ *
+ *  FIXME: current Path library only support UTF-8 chararcter set.
+ *
+ */
+class Path
+{
+public:
+#ifdef LLVM_ON_WIN32
+  typedef wchar_t                            ValueType;
+#else
+  typedef char                               ValueType;
+#endif
+  typedef std::basic_string<ValueType>       StringType;
+
+public:
+  Path();
+  Path(const ValueType* s);
+  Path(const StringType &s);
+  Path(const Path& pCopy);
+  virtual ~Path();
+
+  // -----  assignments  ----- //
+  template <class InputIterator>
+  Path& assign(InputIterator begin, InputIterator end);
+  Path& assign(const StringType &s);
+  Path& assign(const ValueType* s, unsigned int length);
+
+  //  -----  appends  ----- //
+  template <class InputIterator>
+  Path& append(InputIterator begin, InputIterator end);
+  Path& append(const Path& pPath);
+
+  //  -----  observers  ----- //
+  bool empty() const;
+
+  bool isFromRoot() const;
+  bool isFromPWD() const;
+
+  const StringType &native() const
+  { return m_PathName; }
+
+  StringType &native()
+  { return m_PathName; }
+
+  const ValueType* c_str() const
+  { return m_PathName.c_str(); }
+
+  std::string string() const;
+
+  // -----  decomposition  ----- //
+  Path stem() const;
+  Path extension() const;
+
+  // -----  generic form observers  ----- //
+  StringType generic_string() const;
+  bool canonicalize();
+
+public:
+  StringType::size_type m_append_separator_if_needed();
+  void m_erase_redundant_separator(StringType::size_type sep_pos);
+
+protected:
+  StringType m_PathName;
+};
+
+bool operator==(const Path& pLHS,const Path& pRHS);
+bool operator!=(const Path& pLHS,const Path& pRHS);
+
+//--------------------------------------------------------------------------//
+//                              non-member functions                        //
+//--------------------------------------------------------------------------//
+
+/// is_separator - is the given character a separator of a path.
+// @param value a character
+// @result true if \a value is a path separator character on the host OS
+//bool status_known(FileStatus f) { return f.type() != StatusError; }
+
+bool is_separator(char value);
+
+bool exists(const Path &pPath);
+
+bool is_directory(const Path &pPath);
+
+
+std::ostream &operator<<(std::ostream& pOS, const Path& pPath);
+
+std::istream &operator>>(std::istream& pOS, Path& pPath);
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Path &pPath);
+
+
+//--------------------------------------------------------------------------------------//
+//                     class path member template implementation                        //
+//--------------------------------------------------------------------------------------//
+template <class InputIterator>
+Path& Path::assign(InputIterator begin, InputIterator end)
+{
+  m_PathName.clear();
+  if (begin != end)
+    m_PathName.append<InputIterator>(begin, end);
+  return *this;
+}
+
+template <class InputIterator>
+Path& Path::append(InputIterator begin, InputIterator end)
+{
+  if (begin == end)
+    return *this;
+  StringType::size_type sep_pos(m_append_separator_if_needed());
+  m_PathName.append<InputIterator>(begin, end);
+  if (sep_pos)
+    m_erase_redundant_separator(sep_pos);
+  return *this;
+}
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+//-------------------------------------------------------------------------//
+//                              STL compatible functions                   //
+//-------------------------------------------------------------------------//
+namespace std {
+
+template<>
+struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path,
+                                                         mcld::sys::fs::Path,
+                                                         bool>
+{
+  bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const {
+    if (pX.generic_string().size() < pY.generic_string().size())
+      return true;
+    return (pX.generic_string() < pY.generic_string());
+  }
+};
+
+} // namespace of std
+
+#endif
+
diff --git a/include/mcld/Support/PathCache.h b/include/mcld/Support/PathCache.h
new file mode 100644
index 0000000..89ec513
--- /dev/null
+++ b/include/mcld/Support/PathCache.h
@@ -0,0 +1,38 @@
+//===- PathCache.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_PATHCACHE_H
+#define MCLD_PATHCACHE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/HashEntry.h"
+#include "mcld/ADT/HashTable.h"
+#include "mcld/ADT/StringHash.h"
+#include "mcld/Support/Path.h"
+
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+namespace {
+  typedef HashEntry<llvm::StringRef,
+                    mcld::sys::fs::Path*,
+                    StringCompare<llvm::StringRef> > HashEntryType;
+} // anonymous namespace
+
+typedef HashTable<HashEntryType, StringHash<BKDR>, EntryFactory<HashEntryType> > PathCache;
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/PositionDependentOption.h b/include/mcld/Support/PositionDependentOption.h
new file mode 100644
index 0000000..b5d60e8
--- /dev/null
+++ b/include/mcld/Support/PositionDependentOption.h
@@ -0,0 +1,63 @@
+//===- PositionDependentOption.h ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_POSITIONDEPENDENTOPTION_H
+#define MCLD_POSITIONDEPENDENTOPTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+
+namespace mcld
+{
+
+  /** \class PositionDependentOption
+   *  \brief PositionDependentOptions converts LLVM options into MCLDInfo
+   */
+  class PositionDependentOption
+  {
+  public:
+    enum Type {
+      BITCODE,
+      NAMESPEC,
+      INPUT_FILE,
+      START_GROUP,
+      END_GROUP,
+      WHOLE_ARCHIVE,
+      NO_WHOLE_ARCHIVE,
+      AS_NEEDED,
+      NO_AS_NEEDED,
+      ADD_NEEDED,
+      NO_ADD_NEEDED,
+      BDYNAMIC,
+      BSTATIC
+    };
+
+  protected:
+    PositionDependentOption(unsigned pPosition, Type pType)
+      : m_Type(pType),
+        m_Position(pPosition) {}
+
+  public:
+    inline const Type& type() const
+    { return m_Type; }
+
+    inline unsigned position() const
+    { return m_Position; }
+
+  private:
+    Type m_Type;
+    unsigned m_Position;
+  };
+
+  typedef std::vector<PositionDependentOption*> PositionDependentOptions;
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/RealPath.h b/include/mcld/Support/RealPath.h
new file mode 100644
index 0000000..6c0cd40
--- /dev/null
+++ b/include/mcld/Support/RealPath.h
@@ -0,0 +1,72 @@
+//===- RealPath.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_REAL_PATH_H
+#define MCLD_REAL_PATH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/Path.h"
+#include <string>
+
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+/** \class RealPath
+ *  \brief The canonicalized absolute pathname.
+ *
+ */
+class RealPath : public Path
+{
+public:
+  typedef Path::ValueType  ValueType;
+  typedef Path::StringType StringType;
+
+public:
+  RealPath();
+  explicit RealPath(const ValueType* s );
+  explicit RealPath(const StringType &s );
+  explicit RealPath(const Path& pPath);
+
+  ~RealPath();
+
+  RealPath& assign(const Path& pPath);
+
+protected:
+  void initialize();
+};
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+//-------------------------------------------------------------------------//
+//                              STL compatible functions                   //
+//-------------------------------------------------------------------------//
+namespace std {
+
+template<>
+struct less<mcld::sys::fs::RealPath> : public binary_function<
+                                                     mcld::sys::fs::RealPath,
+                                                     mcld::sys::fs::RealPath,
+                                                     bool>
+{
+  bool operator() (const mcld::sys::fs::RealPath& pX,
+                   const mcld::sys::fs::RealPath& pY) const {
+    if (pX.native().size() < pY.native().size())
+      return true;
+    return (pX.native() < pY.native());
+  }
+};
+
+} // namespace of std
+
+
+#endif
+
diff --git a/include/mcld/Support/RegionFactory.h b/include/mcld/Support/RegionFactory.h
new file mode 100644
index 0000000..ba9a88d
--- /dev/null
+++ b/include/mcld/Support/RegionFactory.h
@@ -0,0 +1,48 @@
+//===- RegionFactory.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_REGION_FACTORY_H
+#define MCLD_REGION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/GCFactory.h"
+#include "mcld/Support/MemoryRegion.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/FileSystem.h"
+
+namespace mcld
+{
+
+class MemoryArea;
+
+/** \class RegionFactory
+ *  \brief RegionFactory produces and destroys MemoryRegions
+ *
+ */
+class RegionFactory : public GCFactory<MemoryRegion, 0>
+{
+public:
+  typedef GCFactory<MemoryRegion, 0> Alloc;
+
+public:
+  RegionFactory(size_t pNum);
+  ~RegionFactory();
+
+  // ----- production ----- //
+  MemoryRegion* produce(MemoryArea::Space* pSpace,
+                        const sys::fs::detail::Address pVMAStart,
+                        size_t pSize);
+
+  void destruct(MemoryRegion* pRegion);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetRegistry.h b/include/mcld/Support/TargetRegistry.h
new file mode 100644
index 0000000..a9ad875
--- /dev/null
+++ b/include/mcld/Support/TargetRegistry.h
@@ -0,0 +1,230 @@
+//===- TargetRegistry.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGET_REGISTRY_H
+#define TARGET_REGISTRY_H
+#include <llvm/Support/TargetRegistry.h>
+#include <string>
+#include <list>
+
+namespace llvm {
+class TargetMachine;
+class MCCodeEmitter;
+class MCContext;
+class AsmPrinter;
+} // namespace of llvm
+
+namespace mcld {
+class LLVMTargetMachine;
+class TargetRegistry;
+class SectLinker;
+class SectLinkerOption;
+class TargetLDBackend;
+class AttributeFactory;
+class InputFactory;
+class ContextFactory;
+
+//===----------------------------------------------------------------------===//
+/// Target - mcld::Target is an object adapter of llvm::Target
+///
+class Target
+{
+  friend class mcld::LLVMTargetMachine;
+  friend class mcld::TargetRegistry;
+public:
+  typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
+                                                          llvm::TargetMachine &,
+                                                          const std::string&);
+
+  typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple,
+                                          SectLinkerOption &,
+                                          TargetLDBackend&);
+
+  typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const llvm::Target&,
+                                                     const std::string&);
+
+private:
+  TargetMachineCtorTy TargetMachineCtorFn;
+  SectLinkerCtorTy SectLinkerCtorFn;
+  TargetLDBackendCtorTy TargetLDBackendCtorFn;
+
+public:
+  Target();
+
+  void setTarget(const llvm::Target& pTarget) {
+    m_pT = &pTarget;
+  }
+
+  mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple,
+                          const std::string &pCPU, const std::string &pFeatures,
+                          const llvm::TargetOptions &Options,
+                          llvm::Reloc::Model RM = llvm::Reloc::Default,
+                          llvm::CodeModel::Model CM = llvm::CodeModel::Default,
+                          llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const {
+    if (TargetMachineCtorFn && m_pT) {
+      llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL);
+      if (tm)
+        return TargetMachineCtorFn(*this, *tm, pTriple);
+    }
+    return 0;
+  }
+
+  /// createSectLinker - create target-specific SectLinker
+  ///
+  /// @return created SectLinker
+  SectLinker *createSectLinker(const std::string &pTriple,
+                               SectLinkerOption &pOption,
+                               TargetLDBackend &pLDBackend) const {
+    if (!SectLinkerCtorFn)
+      return 0;
+    return SectLinkerCtorFn(pTriple,
+                            pOption,
+                            pLDBackend);
+  }
+
+  /// createLDBackend - create target-specific LDBackend
+  ///
+  /// @return created TargetLDBackend
+  TargetLDBackend *createLDBackend(const llvm::Target& T, const std::string& Triple) const {
+    if (!TargetLDBackendCtorFn)
+      return 0;
+    return TargetLDBackendCtorFn(T, Triple);
+  }
+
+  const llvm::Target* get() const {
+    return m_pT;
+  }
+
+private:
+  const llvm::Target* m_pT;
+};
+
+//===----------------------------------------------------------------------===//
+/// TargetRegistry - mcld::TargetRegistry is an object adapter of
+/// llvm::TargetRegistry
+///
+class TargetRegistry
+{
+public:
+  typedef std::list<mcld::Target*> TargetListTy;
+  typedef TargetListTy::iterator iterator;
+
+private:
+  static TargetListTy s_TargetList;
+
+public:
+  static iterator begin() { return s_TargetList.begin(); }
+  static iterator end() { return s_TargetList.end(); }
+
+  static size_t size() { return s_TargetList.size(); }
+  static bool empty() { return s_TargetList.empty(); }
+
+  /// RegisterTarget - Register the given target. Attempts to register a
+  /// target which has already been registered will be ignored.
+  ///
+  /// Clients are responsible for ensuring that registration doesn't occur
+  /// while another thread is attempting to access the registry. Typically
+  /// this is done by initializing all targets at program startup.
+  ///
+  /// @param T - The target being registered.
+  static void RegisterTarget(mcld::Target &T);
+
+  /// RegisterTargetMachine - Register a TargetMachine implementation for the
+  /// given target.
+  ///
+  /// @param T - The target being registered.
+  /// @param Fn - A function to construct a TargetMachine for the target.
+  static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) {
+    // Ignore duplicate registration.
+    if (!T.TargetMachineCtorFn)
+      T.TargetMachineCtorFn = Fn;
+  }
+
+  /// RegisterSectLinker - Register a SectLinker implementation for the given
+  /// target.
+  ///
+  /// @param T - the target being registered
+  /// @param Fn - A function to create SectLinker for the target
+  static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn) {
+    if (!T.SectLinkerCtorFn)
+      T.SectLinkerCtorFn = Fn;
+  }
+
+  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
+  /// the given target.
+  ///
+  /// @param T - The target being registered
+  /// @param Fn - A function to create TargetLDBackend for the target
+  static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) {
+    if (!T.TargetLDBackendCtorFn)
+      T.TargetLDBackendCtorFn = Fn;
+  }
+
+  /// lookupTarget - Lookup a target based on a llvm::Target.
+  ///
+  /// @param T - The llvm::Target to find
+  static const mcld::Target *lookupTarget(const llvm::Target& T);
+
+  /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget
+  ///
+  /// @param Triple - The Triple string
+  /// @param Error  - The returned error message
+  static const mcld::Target *lookupTarget(const std::string &Triple,
+                                          std::string &Error);
+};
+
+/// RegisterTarget - Helper function for registering a target, for use in the
+/// target's initialization function. Usage:
+///
+/// Target TheFooTarget; // The global target instance.
+///
+/// extern "C" void LLVMInitializeFooTargetInfo() {
+///   RegisterTarget X(TheFooTarget, "foo", "Foo description");
+/// }
+struct RegisterTarget
+{
+  RegisterTarget(mcld::Target &T, const char *Name) {
+    llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end();
+    // lookup llvm::Target
+    for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) {
+      if( 0==strcmp(TIter->getName(), Name) )
+        break;
+    }
+    T.setTarget(*TIter);
+
+    TargetRegistry::RegisterTarget(T);
+  }
+};
+
+/// RegisterTargetMachine - Helper template for registering a target machine
+/// implementation, for use in the target machine initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+///   extern mcld::Target TheFooTarget;
+///   RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget);
+/// }
+template<class TargetMachineImpl>
+struct RegisterTargetMachine
+{
+  RegisterTargetMachine(mcld::Target &T) {
+    TargetRegistry::RegisterTargetMachine(T, &Allocator);
+  }
+
+private:
+  static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T,
+                                            llvm::TargetMachine& TM,
+                                            const std::string &Triple) {
+    return new TargetMachineImpl(TM, T, Triple);
+  }
+};
+
+} //end namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetSelect.h b/include/mcld/Support/TargetSelect.h
new file mode 100644
index 0000000..e040ae2
--- /dev/null
+++ b/include/mcld/Support/TargetSelect.h
@@ -0,0 +1,77 @@
+//===- TargetSelect.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGETSELECT_H
+#define TARGETSELECT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+extern "C" {
+  // Declare all of the target-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##LDTargetInfo();
+#include "mcld/Config/Targets.def"
+
+  // Declare all of the target-dependent functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##LDTarget();
+#include "mcld/Config/Targets.def"
+
+  // Declare all of the target-depedent linker information
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##LDInfo();
+#include "mcld/Config/Linkers.def"
+
+  // Declare all of the available linker environment.
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##SectLinker();
+#include "mcld/Config/Linkers.def"
+
+  // Declare all of the available target-specific linker
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##LDBackend();
+#include "mcld/Config/Linkers.def"
+} // extern "C"
+
+namespace mcld
+{
+  /// InitializeAllTargetInfos - The main program should call this function if
+  /// it wants access to all available targets that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargetInfos() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##LDTargetInfo();
+#include "mcld/Config/Targets.def"
+  }
+
+  /// InitializeAllTargets - The main program should call this function if it
+  /// wants access to all available target machines that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargets() {
+    mcld::InitializeAllTargetInfos();
+
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##LDTarget();
+#include "mcld/Config/Targets.def"
+  }
+
+  /// InitializeAllLinkers - The main program should call this function if it
+  /// wants all linkers that LLVM is configured to support, to make them
+  /// available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllLinkers() {
+#define LLVM_LINKER(TargetName) LLVMInitialize##TargetName##SectLinker();
+#include "mcld/Config/Linkers.def"
+
+#define LLVM_LINKER(TargetName) LLVMInitialize##TargetName##LDBackend();
+#include "mcld/Config/Linkers.def"
+  }
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/UniqueGCFactory.h b/include/mcld/Support/UniqueGCFactory.h
new file mode 100644
index 0000000..3147bab
--- /dev/null
+++ b/include/mcld/Support/UniqueGCFactory.h
@@ -0,0 +1,94 @@
+//===- UniqueGCFactory.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNIQUE_GCFACTORY_H
+#define MCLD_UNIQUE_GCFACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/GCFactory.h"
+#include <map>
+#include <utility>
+
+namespace mcld
+{
+
+/** \class UniqueGCFactoryBase
+ *  \brief UniqueGCFactories are unique associative factories, meaning that
+ *  no two elements have the same key.
+ */
+template<typename KeyType, typename DataType, size_t ChunkSize>
+class UniqueGCFactoryBase : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
+{
+protected:
+  typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc;
+  typedef std::map<KeyType, DataType*> KeyMap;
+
+protected:
+  UniqueGCFactoryBase()
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
+  { }
+
+  UniqueGCFactoryBase(size_t pNum)
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum)
+  { }
+
+public:
+  virtual ~UniqueGCFactoryBase()
+  { f_KeyMap.clear(); }
+
+  DataType* find(const KeyType& pKey) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end())
+      return dataIter->second;
+    return 0;
+  }
+
+  const DataType* find(const KeyType& pKey) const {
+    typename KeyMap::const_iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end())
+      return dataIter->second;
+    return 0;
+  }
+
+  DataType* produce(const KeyType& pKey, bool& pExist) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end()) {
+      pExist = true;
+      return dataIter->second;
+    }
+    DataType* data = Alloc::allocate();
+    construct(data);
+    f_KeyMap.insert(std::make_pair(pKey, data));
+    pExist = false;
+    return data;
+  }
+
+  DataType* produce(const KeyType& pKey, const DataType& pValue, bool& pExist) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end()) {
+      pExist = true;
+      return dataIter->second;
+    }
+    DataType* data = Alloc::allocate();
+    construct(data, pValue);
+    f_KeyMap.insert(std::make_pair(pKey, data));
+    pExist = false;
+    return data;
+  }
+
+protected:
+  KeyMap f_KeyMap;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/AndroidSectLinker.h b/include/mcld/Target/AndroidSectLinker.h
new file mode 100644
index 0000000..dd68ff2
--- /dev/null
+++ b/include/mcld/Target/AndroidSectLinker.h
@@ -0,0 +1,42 @@
+//===- AndroidSectLinker.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AndroidSectLinker is a customized linker pass for Android platform.
+// This pass set up default parameters for Android.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ANDROID_SECTLINKER_H
+#define ANDROID_SECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/CodeGen/SectLinker.h>
+
+namespace mcld
+{
+
+class AndroidSectLinker : public SectLinker
+{
+public:
+  AndroidSectLinker(SectLinkerOption &pOption,
+                    mcld::TargetLDBackend &pLDBackend);
+
+  virtual ~AndroidSectLinker();
+
+  // addTargetInputs - add Android-specific linker options
+  virtual void addTargetOptions(llvm::Module &pM,
+                                SectLinkerOption &pOption);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/DarwinLDBackend.h b/include/mcld/Target/DarwinLDBackend.h
new file mode 100644
index 0000000..d55055a
--- /dev/null
+++ b/include/mcld/Target/DarwinLDBackend.h
@@ -0,0 +1,31 @@
+//===- DarwinLDBackend.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DARWINLDBACKEND_H
+#define DARWINLDBACKEND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class DarwinLDBackend
+ *  \brief DarwinLDBackend provides a common interface for all Darwin OS LDBackend.
+ *
+ *  \see
+ */
+class DarwinLDBackend
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/ELFDynamic.h b/include/mcld/Target/ELFDynamic.h
new file mode 100644
index 0000000..ed18dc0
--- /dev/null
+++ b/include/mcld/Target/ELFDynamic.h
@@ -0,0 +1,174 @@
+//===- ELFDynamic.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SECTION_H
+#define MCLD_ELF_DYNAMIC_SECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/LD/LDSection.h>
+#include <vector>
+#include <cstring>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class ELFFileFormat;
+class MCLDInfo;
+class MemoryRegion;
+
+namespace elf_dynamic {
+
+/** \class EntryIF
+*  \brief EntryIF provides a common interface for one entry in the dynamic
+*  section
+*/
+class EntryIF
+{
+protected:
+  EntryIF();
+
+public:
+  virtual ~EntryIF(); 
+
+  virtual EntryIF* clone() const = 0;
+  virtual size_t size() const = 0;
+  virtual size_t symbolSize() const = 0;
+  virtual size_t relSize() const = 0;
+  virtual size_t relaSize() const = 0;
+  virtual size_t emit(uint8_t* pAddress) const = 0;
+  virtual void setValue(uint64_t pTag, uint64_t pValue) = 0;
+};
+
+template<size_t BITNUMBER, bool LITTLEENDIAN>
+class Entry
+{ };
+
+template<>
+class Entry<32, true> : public EntryIF
+{
+public:
+  typedef llvm::ELF::Elf32_Dyn  Pair;
+  typedef llvm::ELF::Elf32_Sym  Symbol;
+  typedef llvm::ELF::Elf32_Rel  Rel;
+  typedef llvm::ELF::Elf32_Rela Rela;
+
+public:
+  inline Entry();
+
+  inline ~Entry();
+
+  Entry* clone() const
+  { return new Entry(); }
+
+  size_t size() const
+  { return sizeof(Pair); }
+
+  size_t symbolSize() const
+  { return sizeof(Symbol); }
+
+  size_t relSize() const
+  { return sizeof(Rel); }
+
+  size_t relaSize() const
+  { return sizeof(Rela); }
+
+  inline void setValue(uint64_t pTag, uint64_t pValue);
+
+  inline size_t emit(uint8_t* pAddress) const;
+
+private:
+  Pair m_Pair;
+}; 
+
+#include "ELFDynamic.tcc"
+
+} // namespace of elf_dynamic
+
+/** \class ELFDynamic
+ *  \brief ELFDynamic is the .dynamic section in ELF shared and executable
+ *  files.
+ */
+class ELFDynamic
+{
+public:
+  typedef std::vector<elf_dynamic::EntryIF*> EntryListType;
+  typedef EntryListType::iterator iterator;
+  typedef EntryListType::const_iterator const_iterator;
+
+public:
+  ELFDynamic(const GNULDBackend& pParent);
+
+  virtual ~ELFDynamic();
+
+  size_t size() const;
+
+  size_t entrySize() const;
+
+  size_t numOfBytes() const;
+
+  /// reserveEntries - reserve entries
+  void reserveEntries(const MCLDInfo& pInfo,
+                      const ELFFileFormat& pFormat);
+
+  /// reserveNeedEntry - reserve on DT_NEED entry.
+  void reserveNeedEntry();
+  
+  /// applyEntries - apply entries
+  void applyEntries(const MCLDInfo& pInfo,
+                    const ELFFileFormat& pFormat);
+
+  void applySoname(uint64_t pStrTabIdx);
+
+  iterator needBegin()
+  { return m_NeedList.begin(); }
+
+  iterator needEnd()
+  { return m_NeedList.end(); }
+
+  const_iterator needBegin() const
+  { return m_NeedList.begin(); }
+
+  const_iterator needEnd() const
+  { return m_NeedList.end(); }
+
+  /// emit
+  void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
+
+protected:
+  /// reserveTargetEntries - reserve target dependent entries
+  virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0;
+
+  /// applyTargetEntries - apply target-dependant
+  virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0;
+
+protected:
+  void reserveOne(uint64_t pTag);
+
+  void applyOne(uint64_t pTag, uint64_t pValue);
+
+  size_t symbolSize() const;
+
+private:
+  EntryListType m_EntryList;
+  EntryListType m_NeedList;
+  elf_dynamic::EntryIF* m_pEntryFactory;
+
+  // The entry reserved and the entry being applied are not must matched.
+  // For better performance, we use a simple counter and apply entry one-by-one
+  // by the counter. m_Idx is the counter indicating to the entry being applied.
+  size_t m_Idx;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/ELFDynamic.tcc b/include/mcld/Target/ELFDynamic.tcc
new file mode 100644
index 0000000..8b04651
--- /dev/null
+++ b/include/mcld/Target/ELFDynamic.tcc
@@ -0,0 +1,33 @@
+//===- ELFDynamic.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+Entry<32, true>::Entry()
+{
+  m_Pair.d_tag = 0;
+  m_Pair.d_un.d_val = 0;
+}
+
+Entry<32, true>::~Entry()
+{
+}
+
+void Entry<32, true>::setValue(uint64_t pTag, uint64_t pValue)
+{
+  m_Pair.d_tag = pTag;
+  m_Pair.d_un.d_val = pValue;
+}
+
+size_t Entry<32, true>::emit(uint8_t* pAddress) const
+{
+  memcpy(reinterpret_cast<void*>(pAddress),
+         reinterpret_cast<const void*>(&m_Pair),
+         sizeof(Pair));
+  return sizeof(Pair);
+}
+
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
new file mode 100644
index 0000000..7f51448
--- /dev/null
+++ b/include/mcld/Target/GNULDBackend.h
@@ -0,0 +1,322 @@
+//===- GNULDBackend.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_GNU_LDBACKEND_H
+#define MCLD_TARGET_GNU_LDBACKEND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/HashEntry.h>
+#include <mcld/LD/ELFDynObjReader.h>
+#include <mcld/LD/ELFDynObjWriter.h>
+#include <mcld/LD/ELFObjectReader.h>
+#include <mcld/LD/ELFObjectWriter.h>
+#include <mcld/LD/ELFDynObjFileFormat.h>
+#include <mcld/LD/ELFExecFileFormat.h>
+#include <mcld/LD/ELFSegment.h>
+#include <mcld/LD/GNUArchiveReader.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/Target/ELFDynamic.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/LD/ELFSegmentFactory.h>
+
+namespace mcld
+{
+
+struct SymCompare
+{
+  bool operator()(const LDSymbol* X, const LDSymbol* Y) const
+  { return (X==Y); }
+};
+
+struct PtrHash
+{
+  size_t operator()(const LDSymbol* pKey) const
+  {
+    return (unsigned((uintptr_t)pKey) >> 4) ^
+           (unsigned((uintptr_t)pKey) >> 9);
+  }
+};
+
+class MCLDInfo;
+class Layout;
+class SymbolCategory;
+
+/** \class GNULDBackend
+ *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
+ *  LDBackend.
+ */
+class GNULDBackend : public TargetLDBackend
+{
+  // These dynamic section tags are GNU extension.
+  enum {
+    DT_RELACOUNT  = 0x6ffffff9,
+    DT_RELCOUNT   = 0x6ffffffa,
+    DT_FLAGS_1    = 0x6ffffffb,
+    DT_VERDEF     = 0x6ffffffc,
+    DT_VERDEFNUM  = 0x6ffffffd,
+    DT_VERNEED    = 0x6ffffffe,
+    DT_VERNEEDNUM = 0x6fffffff
+  };
+
+protected:
+  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
+  // refer gold linker to add more enumerations to handle Regular and BSS kind
+  enum SectionOrder {
+    SHO_INTERP = 1,          // .interp
+    SHO_RO_NOTE,             // .note.ABI-tag, .note.gnu.build-id
+    SHO_NAMEPOOL,            // *.hash, .dynsym, .dynstr
+    SHO_RELOCATION,          // .rel.*, .rela.*
+    SHO_REL_PLT,             // .rel.plt should come after other .rel.*
+    SHO_INIT,                // .init
+    SHO_PLT,                 // .plt
+    SHO_TEXT,                // .text
+    SHO_FINI,                // .fini
+    SHO_RO,                  // .rodata
+    SHO_EHFRAME,             // .eh_frame_hdr, .eh_frame
+    SHO_TLS_DATA,            // .tdata
+    SHO_TLS_BSS,             // .tbss
+    SHO_RELRO_LOCAL,         // .data.rel.ro.local
+    SHO_RELRO,               // .data.rel.ro,
+    SHO_RELRO_LAST,          // for x86 to adjust .got if needed
+    SHO_NON_RELRO_FIRST,     // for x86 to adjust .got.plt if needed
+    SHO_DATA,                // .data
+    SHO_LARGE_DATA,          // .ldata
+    SHO_RW_NOTE,             //
+    SHO_SMALL_DATA,          // .sdata
+    SHO_SMALL_BSS,           // .sbss
+    SHO_BSS,                 // .bss
+    SHO_LARGE_BSS,           // .lbss
+    SHO_UNDEFINED = ~(0U)    // default order
+  };
+
+protected:
+  GNULDBackend();
+
+public:
+  virtual ~GNULDBackend();
+
+  bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo);
+  bool initObjectReader(MCLinker& pLinker);
+  bool initDynObjReader(MCLinker& pLinker);
+  bool initObjectWriter(MCLinker& pLinker);
+  bool initDynObjWriter(MCLinker& pLinker);
+
+  bool initExecSections(MCLinker& pMCLinker);
+  bool initDynObjSections(MCLinker& pMCLinker);
+
+  bool initStandardSymbols(MCLinker& pLinker);
+
+  GNUArchiveReader *getArchiveReader();
+  GNUArchiveReader *getArchiveReader() const;
+
+  ELFObjectReader *getObjectReader();
+  ELFObjectReader *getObjectReader() const;
+
+  ELFDynObjReader *getDynObjReader();
+  ELFDynObjReader *getDynObjReader() const;
+
+  ELFObjectWriter *getObjectWriter();
+  ELFObjectWriter *getObjectWriter() const;
+
+  ELFDynObjWriter *getDynObjWriter();
+  ELFDynObjWriter *getDynObjWriter() const;
+
+  ELFDynObjFileFormat* getDynObjFileFormat();
+  ELFDynObjFileFormat* getDynObjFileFormat() const;
+
+  ELFExecFileFormat* getExecFileFormat();
+  ELFExecFileFormat* getExecFileFormat() const;
+
+  size_t sectionStartOffset() const;
+
+  /// The return value of machine() it the same as e_machine in the ELF header*/
+  virtual uint32_t machine() const = 0;
+
+  /// ELFVersion - the value of e_ident[EI_VERSION]
+  virtual uint8_t ELFVersion() const
+  { return llvm::ELF::EV_CURRENT; }
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  virtual uint8_t OSABI() const = 0;
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  virtual uint8_t ABIVersion() const = 0;
+
+  /// flags - the value of ElfXX_Ehdr::e_flags
+  virtual uint64_t flags() const = 0;
+
+  /// entry - the symbol name of the entry point
+  virtual const char* entry() const
+  { return "_start"; }
+
+  /// sizeNamePools - compute the size of regular name pools
+  /// In ELF executable files, regular name pools are .symtab, .strtab.,
+  /// .dynsym, .dynstr, and .hash
+  virtual void sizeNamePools(const Output& pOutput,
+                             const SymbolCategory& pSymbols,
+                             const MCLDInfo& pLDInfo);
+
+  /// emitSectionData - emit target-dependent section data
+  virtual uint64_t emitSectionData(const Output& pOutput,
+                                   const LDSection& pSection,
+                                   const MCLDInfo& pInfo,
+                                   MemoryRegion& pRegion) const = 0;
+
+  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
+  virtual void emitRegNamePools(Output& pOutput,
+                                SymbolCategory& pSymbols,
+                                const Layout& pLayout,
+                                const MCLDInfo& pLDInfo);
+
+  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
+  virtual void emitDynNamePools(Output& pOutput,
+                                SymbolCategory& pSymbols,
+                                const Layout& pLayout,
+                                const MCLDInfo& pLDInfo);
+
+  /// getSectionOrder - compute the layout order of the section
+  /// Layout calls this function to get the default order of the pSectHdr.
+  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
+  /// will call getTargetSectionOrder().
+  ///
+  /// If targets favors certain order for general sections, please override
+  /// this function.
+  ///
+  /// @see getTargetSectionOrder
+  virtual unsigned int getSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const;
+
+  /// getTargetSectionOrder - compute the layout order of target section
+  /// If the target favors certain order for the given gSectHdr, please
+  /// override this function.
+  ///
+  /// By default, this function returns the maximun order, and pSectHdr
+  /// will be the last section to be laid out.
+  virtual unsigned int
+  getTargetSectionOrder(const Output& pOutput, const LDSection& pSectHdr) const
+  { return (unsigned int)-1; }
+
+  /// emitProgramHdrs - emit ELF program headers
+  /// if the target favors other ways to emit program header, please override
+  /// this function
+  virtual void emitProgramHdrs(Output& pOutput);
+
+  /// numOfSegments - return the number of segments
+  /// if the target favors other ways to emit program header, please override
+  /// this function
+  virtual unsigned int numOfSegments() const
+  { return m_ELFSegmentTable.size(); }
+
+  /// pagesize - the page size of the target machine, we set it to 4K here.
+  /// If target favors tht different size of page, please override this function
+  virtual unsigned int pagesize() const
+  { return 0x1000; }
+
+  /// getSymbolIdx - get the symbol index of ouput symbol table
+  size_t getSymbolIdx(LDSymbol* pSymbol) const;
+
+private:
+  /// createProgramHdrs - base on output sections to create the program headers
+  void createProgramHdrs(LDContext& pContext);
+
+  /// writeELF32ProgramHdrs - write out the ELF32 program headers
+  void writeELF32ProgramHdrs(Output& pOutput);
+
+  /// writeELF64ProgramHdrs - write out the ELF64 program headers
+  void writeELF64ProgramHdrs(Output& pOutput);
+
+  /// getSegmentFlag - give a section flag and return the corresponding segment
+  /// flag
+  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag)
+  {
+    uint32_t flag = llvm::ELF::PF_R;
+    if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE))
+      flag |= llvm::ELF::PF_W;
+    if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR))
+      flag |= llvm::ELF::PF_X;
+    return flag;
+  }
+
+  /// preLayout - Backend can do any needed modification before layout
+  void preLayout(const Output& pOutput,
+                 const MCLDInfo& pInfo,
+                 MCLinker& pLinker);
+
+  /// postLayout -Backend can do any needed modification after layout
+  void postLayout(const Output& pOutput,
+                 const MCLDInfo& pInfo,
+                 MCLinker& pLinker);
+
+protected:
+  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const;
+
+private:
+  /// preLayout - Backend can do any needed modification before layout
+  virtual void doPreLayout(const Output& pOutput,
+                         const MCLDInfo& pInfo,
+                         MCLinker& pLinker) = 0;
+
+  /// postLayout -Backend can do any needed modification after layout
+  virtual void doPostLayout(const Output& pOutput,
+                          const MCLDInfo& pInfo,
+                          MCLinker& pLinker) = 0;
+
+  /// dynamic - the dynamic section of the target machine.
+  virtual ELFDynamic& dynamic() = 0;
+
+  /// dynamic - the dynamic section of the target machine.
+  virtual const ELFDynamic& dynamic() const = 0;
+
+protected:
+  // ----- readers and writers ----- //
+  GNUArchiveReader* m_pArchiveReader;
+  ELFObjectReader* m_pObjectReader;
+  ELFDynObjReader* m_pDynObjReader;
+  ELFObjectWriter* m_pObjectWriter;
+  ELFDynObjWriter* m_pDynObjWriter;
+
+  // -----  file formats  ----- //
+  ELFDynObjFileFormat* m_pDynObjFileFormat;
+  ELFExecFileFormat* m_pExecFileFormat;
+
+  // -----  ELF segment factory  ----- //
+  ELFSegmentFactory m_ELFSegmentTable;
+
+  // -----  ELF special sections  ----- //
+
+protected:
+  /// getHashBucketCount - calculate hash bucket count.
+  /// @ref Google gold linker, dynobj.cc:791
+  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
+
+  /// isDynamicSymbol
+  /// @ref Google gold linker: symtab.cc:311
+  static bool isDynamicSymbol(const LDSymbol& pSymbol, const Output& pOutput);
+
+protected:
+  typedef HashEntry<LDSymbol*, size_t, SymCompare> HashEntryType;
+  typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableType;
+
+  /// m_pSymIndexMap - Map the LDSymbol to its index in the output symbol table
+  HashTableType* m_pSymIndexMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h
new file mode 100644
index 0000000..eb0873a
--- /dev/null
+++ b/include/mcld/Target/GOT.h
@@ -0,0 +1,106 @@
+//===- GOT.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GOT_H
+#define MCLD_GOT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDSection.h>
+#include <mcld/MC/MCTargetFragment.h>
+
+namespace mcld
+{
+
+class GOT;
+class ResolveInfo;
+
+/** \class GOTEntry
+ *  \brief The entry of Global Offset Table
+ */
+class GOTEntry : public MCTargetFragment
+{
+public:
+  explicit GOTEntry(uint64_t pContent, size_t pEntrySize,
+                    llvm::MCSectionData* pParent);
+
+  virtual ~GOTEntry();
+
+  uint64_t& getContent()
+  { return f_Content; }
+
+  uint64_t getContent() const
+  { return f_Content; }
+
+  void setContent(uint64_t pValue)
+  { f_Content = pValue; }
+
+  static bool classof(const MCFragment *pFrag)
+  { return pFrag->getKind() == llvm::MCFragment::FT_Target; }
+
+  static bool classof(const GOTEntry* pFrag)
+  { return true; }
+
+  // Override pure virtual function
+  size_t getSize() const
+  { return m_EntrySize; }
+
+protected:
+  uint64_t f_Content;
+  size_t m_EntrySize;
+};
+
+/** \class GOT
+ *  \brief The Global Offset Table
+ */
+class GOT
+{
+protected:
+  GOT(LDSection& pSection,
+      llvm::MCSectionData& pSectionData,
+      size_t pEntrySize);
+
+public:
+  virtual ~GOT();
+
+  /// entrySize - the number of bytes per entry
+  size_t getEntrySize() const;
+
+  const LDSection& getSection() const
+  { return m_Section; }
+
+  llvm::MCSectionData& getSectionData()
+  { return m_SectionData; }
+
+  const llvm::MCSectionData& getSectionData() const
+  { return m_SectionData; }
+
+public:
+  /// reserveEntry - reseve number of pNum of empty entries
+  /// Before layout, we scan all relocations to determine if GOT entries are
+  /// needed. If an entry is needed, the empty entry is reserved for layout
+  /// to adjust the fragment offset. After that, we fill up the entries when
+  /// applying relocations.
+  virtual void reserveEntry(size_t pNum = 1) = 0;
+
+  /// getEntry - get an empty entry or an exitsted filled entry with pSymbol.
+  /// @param pSymbol - the target symbol
+  /// @param pExist - ture if a filled entry with pSymbol existed, otherwise false.
+  virtual GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist) = 0;
+
+protected:
+  LDSection& m_Section;
+  llvm::MCSectionData& m_SectionData;
+  size_t f_EntrySize;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/OutputRelocSection.h b/include/mcld/Target/OutputRelocSection.h
new file mode 100644
index 0000000..c0cb5ca
--- /dev/null
+++ b/include/mcld/Target/OutputRelocSection.h
@@ -0,0 +1,71 @@
+//===- OutputRelocSection.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef OUTPUTRELOCSECTION_H
+#define OUTPUTRELOCSECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/ADT/DenseMap.h>
+#include <mcld/LD/RelocationFactory.h>
+
+namespace mcld
+{
+
+class ResolveInfo;
+class Relocation;
+
+/** \class OutputRelocSection
+ *  \brief Dynamic relocation section for ARM .rel.dyn and .rel.plt
+ */
+class OutputRelocSection
+{
+public:
+  typedef llvm::DenseMap<const ResolveInfo*, Relocation*> SymRelMapType;
+  typedef SymRelMapType::iterator SymRelMapIterator;
+
+  typedef llvm::MCSectionData::iterator MCFragmentIterator;
+
+public:
+  OutputRelocSection(LDSection& pSection,
+                   llvm::MCSectionData& pSectionData,
+                   unsigned int pEntrySize);
+  ~OutputRelocSection();
+
+  void reserveEntry(RelocationFactory& pRelFactory, size_t pNum=1);
+
+  Relocation* getEntry(const ResolveInfo& pSymbol,
+                       bool isForGOT,
+                       bool& pExist);
+
+private:
+  /// m_pSection - LDSection of this Section
+  LDSection* m_pSection;
+
+  /// m_SectionData - MCSectionData which contains the dynamic relocations
+  llvm::MCSectionData* m_pSectionData;
+
+  /// m_EntryBytes - size of a relocation entry
+  unsigned int m_EntryBytes;
+
+  /// m_isVisit - First time visit the function getEntry() or not
+  bool m_isVisit ;
+
+  /// m_ValidEntryIterator - point to the first valid entry
+  MCFragmentIterator m_ValidEntryIterator;
+
+  /// m_SymRelMap - map the resolved symbol to the Relocation entry
+  SymRelMapType m_SymRelMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h
new file mode 100644
index 0000000..6a7522a
--- /dev/null
+++ b/include/mcld/Target/PLT.h
@@ -0,0 +1,86 @@
+//===- PLT.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PROCEDURE_LINKAGE_TABLE_H
+#define PROCEDURE_LINKAGE_TABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDSection.h>
+#include <mcld/MC/MCTargetFragment.h>
+#include <llvm/ADT/ilist.h>
+
+namespace mcld
+{
+
+class ResolveInfo;
+
+/** \class PLTEntry
+ */
+class PLTEntry : public MCTargetFragment
+{
+public:
+  PLTEntry(size_t pSize, llvm::MCSectionData* pParent);
+  virtual ~PLTEntry();
+
+  size_t getEntrySize() const
+  { return m_EntrySize; }
+
+  void setContent(unsigned char* pContent)
+  { m_pContent = pContent; }
+
+  const unsigned char* getContent() const
+  { return m_pContent; }
+
+  //Used by llvm::cast<>.
+  static bool classof(const MCFragment *O)
+  { return true; }
+
+  size_t getSize() const
+  { return m_EntrySize; }
+
+protected:
+  size_t m_EntrySize;
+  unsigned char* m_pContent;
+};
+
+/** \class PLT
+ *  \brief Procedure linkage table
+ */
+class PLT
+{
+public:
+  PLT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+  virtual ~PLT();
+
+  const LDSection& getSection() const
+  { return m_Section; }
+
+  const llvm::MCSectionData& getSectionData() const
+  { return m_SectionData; }
+
+public:
+  /// reserveEntry - reseve the number of pNum of empty entries
+  /// The empty entris are reserved for layout to adjust the fragment offset.
+  virtual void reserveEntry(size_t pNum = 1) = 0;
+
+  /// getPLTEntry - get an empty entry or an exitsted filled entry with pSymbol.
+  /// @param pSymbol - the target symbol
+  /// @param pExist - ture if the a filled entry with pSymbol existed, otherwise false.
+  virtual PLTEntry* getPLTEntry(const ResolveInfo& pSymbol, bool& pExist) = 0;
+
+protected:
+  LDSection& m_Section;
+  llvm::MCSectionData& m_SectionData;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/Stub.h b/include/mcld/Target/Stub.h
new file mode 100644
index 0000000..3bc778f
--- /dev/null
+++ b/include/mcld/Target/Stub.h
@@ -0,0 +1,30 @@
+//===- Stub.h -------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_STUB_H
+#define LD_STUB_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/Relocation.h"
+
+namespace mcld
+{
+
+/** \class Stub
+ *  \brief Stub is a piece of jumpping code.
+ */
+class Stub
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h
new file mode 100644
index 0000000..781b86f
--- /dev/null
+++ b/include/mcld/Target/TargetLDBackend.h
@@ -0,0 +1,146 @@
+//===-- llvm/Target/TargetLDBackend.h - Target LD Backend -----*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TARGET_TARGETLDBACKEND_H
+#define LLVM_TARGET_TARGETLDBACKEND_H
+
+#include <llvm/Support/DataTypes.h>
+#include <mcld/MC/MCLDOutput.h>
+
+namespace mcld {
+
+class MCLinker;
+class Relocation;
+class RelocationFactory;
+class Layout;
+class ArchiveReader;
+class ObjectReader;
+class DynObjReader;
+class ObjectWriter;
+class DynObjWriter;
+class LDContext;
+class SectionMap;
+class Output;
+class MCLDInfo;
+class SymbolCategory;
+class Input;
+class LDFileFormat;
+class GOT;
+
+//===----------------------------------------------------------------------===//
+/// TargetLDBackend - Generic interface to target specific assembler backends.
+///
+class TargetLDBackend
+{
+  TargetLDBackend(const TargetLDBackend &);   // DO NOT IMPLEMENT
+  void operator=(const TargetLDBackend &);  // DO NOT IMPLEMENT
+
+protected:
+  TargetLDBackend();
+
+public:
+  virtual ~TargetLDBackend();
+
+  // -----  target dependent  ----- //
+  virtual bool initTargetSectionMap(SectionMap& pSectionMap) { return true;}
+  virtual void initTargetSegments(MCLinker& pLinker) { }
+  virtual void initTargetSections(MCLinker& pLinker) { }
+  virtual void initTargetSymbols(MCLinker& pLinker) { }
+  virtual void initTargetRelocation(MCLinker& pLinker) { }
+  virtual bool initStandardSymbols(MCLinker& pLinker) = 0;
+  virtual bool initRelocFactory(const MCLinker& pLinker) = 0;
+
+  virtual RelocationFactory* getRelocFactory() = 0;
+
+  /// scanRelocation - When read in relocations, backend can do any modification
+  /// to relocation and generate empty entries, such as GOT, dynamic relocation
+  /// entries and other target dependent entries. These entries are generated
+  /// for layout to adjust the ouput offset.
+  /// @param pReloc - a read in relocation entry
+  /// @param pInputSym - the input LDSymbol of relocation target symbol
+  /// @param pOutput - the ouput file
+  virtual void scanRelocation(Relocation& pReloc,
+                              const LDSymbol& pInputSym,
+                              MCLinker& pLinker,
+                              const MCLDInfo& pLDInfo,
+                              const Output& pOutput) = 0;
+
+  // -----  format dependent  ----- //
+  virtual bool initArchiveReader(MCLinker&, MCLDInfo&) = 0;
+  virtual bool initObjectReader(MCLinker&) = 0;
+  virtual bool initDynObjReader(MCLinker&) = 0;
+  virtual bool initObjectWriter(MCLinker&) = 0;
+  virtual bool initDynObjWriter(MCLinker&) = 0;
+
+  virtual bool initExecSections(MCLinker&) = 0;
+  virtual bool initDynObjSections(MCLinker&) = 0;
+
+  virtual ArchiveReader *getArchiveReader() = 0;
+  virtual ObjectReader *getObjectReader() = 0;
+  virtual DynObjReader *getDynObjReader() = 0;
+  virtual ObjectWriter *getObjectWriter() = 0;
+  virtual DynObjWriter *getDynObjWriter() = 0;
+
+  virtual LDFileFormat* getDynObjFileFormat() = 0;
+  virtual LDFileFormat* getExecFileFormat() = 0;
+
+  /// preLayout - Backend can do any needed modification before layout
+  virtual void preLayout(const Output& pOutput,
+                         const MCLDInfo& pInfo,
+                         MCLinker& pLinker) = 0;
+
+  /// postLayout -Backend can do any needed modification after layout
+  virtual void postLayout(const Output& pOutput,
+                          const MCLDInfo& pInfo,
+                          MCLinker& pLinker) = 0;
+
+  /// Is the target machine little endian? **/
+  virtual bool isLittleEndian() const = 0;
+
+  /// bit class. the bit length of the target machine, 32 or 64 **/
+  virtual unsigned int bitclass() const = 0;
+
+  /// the page size of the target machine
+  virtual unsigned int pagesize() const = 0;
+
+  /// section start offset in the output file
+  virtual size_t sectionStartOffset() const = 0;
+
+  /// computeSectionOrder - compute the layout order of the given section
+  virtual unsigned int getSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const = 0;
+
+  /// sizeNamePools - compute the size of regular name pools
+  /// In ELF executable files, regular name pools are .symtab, .strtab.,
+  /// .dynsym, .dynstr, and .hash
+  virtual void
+  sizeNamePools(const Output& pOutput,
+                const SymbolCategory& pSymbols,
+                const MCLDInfo& pLDInfo) = 0;
+
+  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
+  /// then it will ask backend to finalize the symbol value.
+  /// @return ture - if backend set the symbol value sucessfully
+  /// @return false - if backend do not recognize the symbol
+  virtual bool finalizeSymbol(LDSymbol& pSymbol) const = 0;
+
+  /// allocateCommonSymbols - allocate common symbols in the corresponding
+  /// sections.
+  virtual bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const = 0;
+
+  /// readSection - read a target dependent section
+  virtual bool readSection(Input& pInput,
+                           MCLinker& pLinker,
+                           LDSection& pInputSectHdr)
+  { return true; }
+
+};
+
+} // End mcld namespace
+
+#endif
diff --git a/include/mcld/Target/TargetMachine.h b/include/mcld/Target/TargetMachine.h
new file mode 100644
index 0000000..438edfd
--- /dev/null
+++ b/include/mcld/Target/TargetMachine.h
@@ -0,0 +1,127 @@
+//===- TargetMachine.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_MACHINE_H
+#define MCLD_TARGET_MACHINE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Target/TargetMachine.h>
+#include <string>
+#include "mcld/MC/MCLDFile.h"
+
+namespace llvm
+{
+class Target;
+class TargetData;
+class TargetMachine;
+class PassManagerBase;
+class formatted_raw_ostream;
+
+} // namespace of llvm
+
+namespace mcld
+{
+
+class Target;
+class MCLDInfo;
+class SectLinkerOption;
+using namespace llvm;
+
+enum CodeGenFileType {
+  CGFT_ASMFile,
+  CGFT_OBJFile,
+  CGFT_ARCFile,
+  CGFT_DSOFile,
+  CGFT_EXEFile,
+  CGFT_NULLFile
+};
+
+
+/** \class mcld::LLVMTargetMachine
+ *  \brief mcld::LLVMTargetMachine is a object adapter of
+ *  llvm::LLVMTargetMachine.
+ *
+ *  mcld::LLVMTargetMachine is also in charge of MCLDInfo.
+ *
+ *  @see MCLDInfo
+ */
+class LLVMTargetMachine
+{
+public:
+  /// Adapter of llvm::TargetMachine
+  ///
+  LLVMTargetMachine(llvm::TargetMachine &pTM,
+                    const mcld::Target &pTarget,
+                    const std::string &pTriple);
+  virtual ~LLVMTargetMachine();
+
+  /// getTarget - adapt llvm::TargetMachine::getTarget
+  const mcld::Target& getTarget() const;
+
+  /// getTM - return adapted the llvm::TargetMachine.
+  const llvm::TargetMachine& getTM() const { return m_TM; }
+  llvm::TargetMachine& getTM() { return m_TM; }
+
+  /// getLDInfo - return the mcld::MCLDInfo
+  virtual mcld::MCLDInfo& getLDInfo() = 0;
+  virtual const mcld::MCLDInfo& getLDInfo() const = 0;
+
+  /// appPassesToEmitFile - The target function which we has to modify as
+  /// upstreaming.
+  bool addPassesToEmitFile(PassManagerBase &,
+                           formatted_raw_ostream &Out,
+                           const std::string &pOutputFilename,
+                           mcld::CodeGenFileType,
+                           CodeGenOpt::Level,
+                           SectLinkerOption *pLinkerOpt = NULL,
+                           bool DisableVerify = true);
+
+  /// getTargetData
+  const TargetData *getTargetData() const { return m_TM.getTargetData(); }
+
+  /// setAsmVerbosityDefault
+  static void setAsmVerbosityDefault(bool pAsmVerbose) {
+    llvm::TargetMachine::setAsmVerbosityDefault(pAsmVerbose);
+  }
+
+private:
+  /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
+  /// both emitting to assembly files or machine code output.
+  bool addCommonCodeGenPasses(PassManagerBase &,
+                              mcld::CodeGenFileType,
+                              CodeGenOpt::Level,
+                              bool DisableVerify,
+                              llvm::MCContext *&OutCtx);
+
+  bool addCompilerPasses(PassManagerBase &,
+                         formatted_raw_ostream &Out,
+                         const std::string& pOutputFilename,
+                         llvm::MCContext *&OutCtx);
+
+  bool addAssemblerPasses(PassManagerBase &,
+                          formatted_raw_ostream &Out,
+                          const std::string& pOutputFilename,
+                          llvm::MCContext *&OutCtx);
+
+  bool addLinkerPasses(PassManagerBase &,
+                       SectLinkerOption *pLinkerOpt,
+                       const std::string& pOutputFilename,
+                       MCLDFile::Type pOutputLinkType,
+                       llvm::MCContext *&OutCtx);
+
+private:
+  llvm::TargetMachine &m_TM;
+  const mcld::Target *m_pTarget;
+  const std::string& m_Triple;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
new file mode 100644
index 0000000..8754d65
--- /dev/null
+++ b/lib/CodeGen/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_codegen_SRC_FILES := \
+  LLVMTargetMachine.cpp \
+  SectLinker.cpp  \
+  SectLinkerOption.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_codegen_SRC_FILES)
+LOCAL_MODULE:= libmcldCodeGen
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_codegen_SRC_FILES)
+LOCAL_MODULE:= libmcldCodeGen
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
new file mode 100644
index 0000000..acf5254
--- /dev/null
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -0,0 +1,412 @@
+//===- LLVMTargetMachine.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/CodeGen/SectLinker.h"
+#include "mcld/CodeGen/SectLinkerOption.h"
+#include "mcld/MC/MCBitcodeInterceptor.h"
+#include "mcld/MC/MCLDFile.h"
+#include "mcld/Support/RealPath.h"
+#include "mcld/Support/TargetRegistry.h"
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Target/TargetLDBackend.h"
+
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/Analysis/Passes.h>
+#include <llvm/Analysis/Verifier.h>
+#include <llvm/Assembly/PrintModulePass.h>
+#include <llvm/CodeGen/AsmPrinter.h>
+#include <llvm/CodeGen/MachineFunctionAnalysis.h>
+#include <llvm/CodeGen/MachineModuleInfo.h>
+#include <llvm/CodeGen/GCStrategy.h>
+#include <llvm/CodeGen/Passes.h>
+#include <llvm/MC/MCAsmInfo.h>
+#include <llvm/MC/MCStreamer.h>
+#include <llvm/MC/MCInstrInfo.h>
+#include <llvm/MC/MCSubtargetInfo.h>
+#include <llvm/MC/MCObjectStreamer.h>
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCObjectWriter.h>
+#include <llvm/MC/MCContext.h>
+#include <llvm/PassManager.h>
+#include <llvm/Support/CommandLine.h>
+#include <llvm/Support/Debug.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/FormattedStream.h>
+#include <llvm/Support/ToolOutputFile.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Target/TargetInstrInfo.h>
+#include <llvm/Target/TargetLowering.h>
+#include <llvm/Target/TargetOptions.h>
+#include <llvm/Target/TargetSubtargetInfo.h>
+#include <llvm/Target/TargetLoweringObjectFile.h>
+#include <llvm/Target/TargetRegisterInfo.h>
+#include <llvm/Transforms/Scalar.h>
+
+#include <string>
+
+using namespace mcld;
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+/// Arguments
+// Enable or disable FastISel. Both options are needed, because
+// FastISel is enabled by default with -fast, and we wish to be
+// able to enable or disable fast-isel independently from -O0.
+
+static cl::opt<cl::boolOrDefault>
+ArgEnableFastISelOption("lfast-isel", cl::Hidden,
+  cl::desc("Enable the \"fast\" instruction selector"));
+
+static cl::opt<bool>
+ArgShowMCEncoding("lshow-mc-encoding",
+                cl::Hidden,
+                cl::desc("Show encoding in .s output"));
+
+static cl::opt<bool>
+ArgShowMCInst("lshow-mc-inst",
+              cl::Hidden,
+              cl::desc("Show instruction structure in .s output"));
+
+static cl::opt<cl::boolOrDefault>
+ArgAsmVerbose("fverbose-asm",
+              cl::desc("Put extra commentary information in the \
+                       generated assembly code to make it more readable."),
+              cl::init(cl::BOU_UNSET));
+
+static bool getVerboseAsm() {
+  switch (ArgAsmVerbose) {
+  default:
+  case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault();
+  case cl::BOU_TRUE:  return true;
+  case cl::BOU_FALSE: return false;
+  }
+}
+
+
+//===---------------------------------------------------------------------===//
+/// LLVMTargetMachine
+mcld::LLVMTargetMachine::LLVMTargetMachine(llvm::TargetMachine &pTM,
+                                           const mcld::Target& pTarget,
+                                           const std::string& pTriple )
+  : m_TM(pTM), m_pTarget(&pTarget), m_Triple(pTriple) {
+}
+
+mcld::LLVMTargetMachine::~LLVMTargetMachine() {
+  m_pTarget = 0;
+}
+
+const mcld::Target& mcld::LLVMTargetMachine::getTarget() const
+{
+  return *m_pTarget;
+}
+
+/// Turn exception handling constructs into something the code generators can
+/// handle.
+static void addPassesToHandleExceptions(llvm::TargetMachine *TM,
+                                        PassManagerBase &PM) {
+  switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
+  case llvm::ExceptionHandling::SjLj:
+    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
+    // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
+    // catch info can get misplaced when a selector ends up more than one block
+    // removed from the parent invoke(s). This could happen when a landing
+    // pad is shared by multiple invokes and is also a target of a normal
+    // edge from elsewhere.
+    PM.add(createSjLjEHPass(TM->getTargetLowering()));
+    // FALLTHROUGH
+  case llvm::ExceptionHandling::DwarfCFI:
+  case llvm::ExceptionHandling::ARM:
+  case llvm::ExceptionHandling::Win64:
+    PM.add(createDwarfEHPass(TM));
+    break;
+  case llvm::ExceptionHandling::None:
+    PM.add(createLowerInvokePass(TM->getTargetLowering()));
+
+    // The lower invoke pass may create unreachable code. Remove it.
+    PM.add(createUnreachableBlockEliminationPass());
+    break;
+  }
+}
+
+
+static llvm::MCContext *addPassesToGenerateCode(llvm::LLVMTargetMachine *TM,
+                                     PassManagerBase &PM,
+                                     bool DisableVerify)
+{
+  // Targets may override createPassConfig to provide a target-specific sublass.
+  TargetPassConfig *PassConfig = TM->createPassConfig(PM);
+
+  // Set PassConfig options provided by TargetMachine.
+  PassConfig->setDisableVerify(DisableVerify);
+
+  PM.add(PassConfig);
+
+  PassConfig->addIRPasses();
+
+  addPassesToHandleExceptions(TM, PM);
+
+  PassConfig->addISelPrepare();
+
+  // Install a MachineModuleInfo class, which is an immutable pass that holds
+  // all the per-module stuff we're generating, including MCContext.
+  MachineModuleInfo *MMI =
+    new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
+                          &TM->getTargetLowering()->getObjFileLowering());
+  PM.add(MMI);
+  MCContext *Context = &MMI->getContext(); // Return the MCContext by-ref.
+
+  // Set up a MachineFunction for the rest of CodeGen to work on.
+  PM.add(new MachineFunctionAnalysis(*TM));
+
+  // Enable FastISel with -fast, but allow that to be overridden.
+  if (ArgEnableFastISelOption == cl::BOU_TRUE ||
+      (TM->getOptLevel() == CodeGenOpt::None &&
+       ArgEnableFastISelOption != cl::BOU_FALSE))
+    TM->setFastISel(true);
+
+  // Ask the target for an isel.
+  if (PassConfig->addInstSelector())
+    return NULL;
+
+  PassConfig->addMachinePasses();
+
+  PassConfig->setInitialized();
+
+  return Context;
+
+}
+
+bool mcld::LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &pPM,
+                                             formatted_raw_ostream &Out,
+                                             const std::string& pOutputFilename,
+                                             mcld::CodeGenFileType pFileType,
+                                             CodeGenOpt::Level pOptLvl,
+                                             SectLinkerOption *pLinkerOpt,
+                                             bool pDisableVerify)
+{
+
+  llvm::MCContext* Context =
+          addPassesToGenerateCode(static_cast<llvm::LLVMTargetMachine*>(&m_TM),
+                                  pPM, pDisableVerify);
+  if (!Context)
+    return true;
+
+  switch(pFileType) {
+  default:
+  case mcld::CGFT_NULLFile:
+    assert(0 && "fatal: file type is not set!");
+    break;
+  case CGFT_ASMFile: {
+    assert(Context != 0 && "Failed to get MCContext");
+
+    if (getTM().hasMCSaveTempLabels())
+      Context->setAllowTemporaryLabels(false);
+
+    if (addCompilerPasses(pPM,
+                          Out,
+                          pOutputFilename,
+                          Context))
+      return true;
+
+    pPM.add(createGCInfoDeleter()); // not in addPassesToMC
+    break;
+  }
+  case CGFT_OBJFile: {
+    assert(Context != 0 && "Failed to get MCContext");
+
+    if (getTM().hasMCSaveTempLabels())
+      Context->setAllowTemporaryLabels(false);
+    if (addAssemblerPasses(pPM,
+                           Out,
+                           pOutputFilename,
+                           Context))
+      return true;
+
+    pPM.add(createGCInfoDeleter()); // not in addPassesToMC
+    break;
+  }
+  case CGFT_ARCFile: {
+    assert(0 && "Output to archive file has not been supported yet!");
+    break;
+  }
+  case CGFT_EXEFile: {
+    if (pLinkerOpt == NULL)
+      return true;
+
+    if (addLinkerPasses(pPM,
+                        pLinkerOpt,
+                        pOutputFilename,
+                        MCLDFile::Exec,
+                        Context))
+      return true;
+    break;
+  }
+  case CGFT_DSOFile: {
+    if (pLinkerOpt == NULL)
+      return true;
+
+    if (addLinkerPasses(pPM,
+                        pLinkerOpt,
+                        pOutputFilename,
+                        MCLDFile::DynObj,
+                        Context))
+      return true;
+    break;
+  }
+  } // switch
+  return false;
+}
+
+bool mcld::LLVMTargetMachine::addCompilerPasses(PassManagerBase &pPM,
+                                                formatted_raw_ostream &Out,
+                                                const std::string& pOutputFilename,
+                                                llvm::MCContext *&Context)
+{
+  const MCAsmInfo &MAI = *getTM().getMCAsmInfo();
+  const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
+
+  MCInstPrinter *InstPrinter =
+    getTarget().get()->createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
+                                           Context->getRegisterInfo(), STI);
+
+  MCCodeEmitter* MCE = 0;
+  MCAsmBackend *MAB = 0;
+  if (ArgShowMCEncoding) {
+    MCE = getTarget().get()->createMCCodeEmitter(*(getTM().getInstrInfo()), STI, *Context);
+    MAB = getTarget().get()->createMCAsmBackend(m_Triple);
+  }
+
+
+  // now, we have MCCodeEmitter and MCAsmBackend, we can create AsmStreamer.
+  OwningPtr<MCStreamer> AsmStreamer(
+    getTarget().get()->createAsmStreamer(*Context, Out,
+                                         getVerboseAsm(),
+                                         getTM().hasMCUseLoc(),
+                                         getTM().hasMCUseCFI(),
+                                         getTM().hasMCUseDwarfDirectory(),
+                                         InstPrinter,
+                                         MCE, MAB,
+                                         ArgShowMCInst));
+
+  llvm::MachineFunctionPass* funcPass =
+    getTarget().get()->createAsmPrinter(getTM(), *AsmStreamer.get());
+
+  if (funcPass == 0)
+    return true;
+  // If successful, createAsmPrinter took ownership of AsmStreamer
+  AsmStreamer.take();
+  pPM.add(funcPass);
+  return false;
+}
+
+bool mcld::LLVMTargetMachine::addAssemblerPasses(PassManagerBase &pPM,
+                                                 formatted_raw_ostream &Out,
+                                                 const std::string& pOutputFilename,
+                                                 llvm::MCContext *&Context)
+{
+  // MCCodeEmitter
+  const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
+  MCCodeEmitter* MCE = getTarget().get()->createMCCodeEmitter(*getTM().getInstrInfo(), STI, *Context);
+
+  // MCAsmBackend
+  MCAsmBackend* MAB = getTarget().get()->createMCAsmBackend(m_Triple);
+  if (MCE == 0 || MAB == 0)
+    return true;
+
+  // now, we have MCCodeEmitter and MCAsmBackend, we can create AsmStreamer.
+  OwningPtr<MCStreamer> AsmStreamer(getTarget().get()->createMCObjectStreamer(
+                                                              m_Triple,
+                                                              *Context,
+                                                              *MAB,
+                                                              Out,
+                                                              MCE,
+                                                              getTM().hasMCRelaxAll(),
+                                                              getTM().hasMCNoExecStack()));
+  AsmStreamer.get()->InitSections();
+  MachineFunctionPass *funcPass = getTarget().get()->createAsmPrinter(getTM(),
+                                                                      *AsmStreamer.get());
+  if (funcPass == 0)
+    return true;
+  // If successful, createAsmPrinter took ownership of AsmStreamer
+  AsmStreamer.take();
+  pPM.add(funcPass);
+  return false;
+}
+
+bool mcld::LLVMTargetMachine::addLinkerPasses(PassManagerBase &pPM,
+                                              SectLinkerOption *pLinkerOpt,
+                                              const std::string &pOutputFilename,
+                                              MCLDFile::Type pOutputLinkType,
+                                              llvm::MCContext *&Context)
+{
+// FIXME: when MCLinker can directly turn bitcode into shared object, turn on this
+// block of code.
+#if 0
+  // Initialize MCAsmStreamer first, than chain its output into SectLinker.
+  // MCCodeEmitter
+  const MCSubtargetInfo &STI = getTM().getSubtarget<MCSubtargetInfo>();
+  MCCodeEmitter* MCE = getTarget().get()->createMCCodeEmitter(*getTM().getInstrInfo(),
+                                                              STI,
+                                                              *Context);
+  // MCAsmBackend
+  MCAsmBackend *MAB = getTarget().get()->createMCAsmBackend(m_Triple);
+  if (MCE == 0 || MAB == 0)
+    return true;
+
+  // now, we have MCCodeEmitter and MCAsmBackend, we can create AsmStreamer.
+  MCStreamer* AsmStreamer =
+    getTarget().get()->createMCObjectStreamer(m_Triple,
+                                              *Context,
+                                              *MAB,
+                                              llvm::nulls(),
+                                              MCE,
+                                              getTM().hasMCRelaxAll(),
+                                              getTM().hasMCNoExecStack());
+  if (0 == AsmStreamer)
+    return true;
+
+  AsmStreamer->InitSections();
+  AsmPrinter* printer = getTarget().get()->createAsmPrinter(getTM(), *AsmStreamer);
+  if (0 == printer)
+    return true;
+  pPM.add(printer);
+#endif
+  TargetLDBackend* ldBackend = getTarget().createLDBackend(*getTarget().get(), m_Triple);
+  if (0 == ldBackend)
+    return true;
+
+// FIXME: when MCLinker can directly turn bitcode into shared object, turn on this
+// block of code.
+#if 0
+  MCBitcodeInterceptor* objReader = new MCBitcodeInterceptor(
+                                 static_cast<MCObjectStreamer&>(*AsmStreamer),
+                                 *ldBackend,
+                                 getLDInfo());
+#endif
+  // set up output's SOName
+  if (pOutputLinkType == MCLDFile::DynObj &&
+      pLinkerOpt->info().output().name().empty()) {
+    // if the output is a shared object, and the option -soname was not
+    // enable, set soname as the output file name.
+    pLinkerOpt->info().output().setSOName(pOutputFilename);
+  }
+
+  pLinkerOpt->info().output().setPath(sys::fs::RealPath(pOutputFilename));
+  pLinkerOpt->info().output().setType(pOutputLinkType);
+
+  MachineFunctionPass* funcPass = getTarget().createSectLinker(m_Triple,
+                                                               *pLinkerOpt,
+                                                               *ldBackend);
+  if (0 == funcPass)
+    return true;
+
+  pPM.add(funcPass);
+  return false;
+}
+
diff --git a/lib/CodeGen/SectLinker.cpp b/lib/CodeGen/SectLinker.cpp
new file mode 100644
index 0000000..95e9e4f
--- /dev/null
+++ b/lib/CodeGen/SectLinker.cpp
@@ -0,0 +1,315 @@
+//===- SectLinker.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SectLinker class.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/ADT/BinTree.h>
+#include <mcld/CodeGen/SectLinker.h>
+#include <mcld/CodeGen/SectLinkerOption.h>
+#include <mcld/MC/MCLDInputTree.h>
+#include <mcld/MC/MCLDDriver.h>
+#include <mcld/Support/DerivedPositionDependentOptions.h>
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Target/TargetLDBackend.h>
+
+#include <llvm/Module.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/raw_ostream.h>
+
+#include <algorithm>
+#include <stack>
+#include <string>
+
+using namespace mcld;
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Forward declarations
+char SectLinker::m_ID = 0;
+static bool CompareOption(const PositionDependentOption* X,
+                          const PositionDependentOption* Y);
+
+//===----------------------------------------------------------------------===//
+// SectLinker
+SectLinker::SectLinker(SectLinkerOption &pOption,
+                       TargetLDBackend& pLDBackend)
+  : MachineFunctionPass(m_ID),
+    m_pOption(&pOption),
+    m_pLDBackend(&pLDBackend),
+    m_pLDDriver(NULL) { }
+
+SectLinker::~SectLinker()
+{
+  delete m_pLDDriver;
+  // FIXME: current implementation can not change the order of delete.
+  //
+  // Instance of TargetLDBackend was created outside and is not managed by
+  // SectLinker. It should not be destroyed here and by SectLinker. However, in
+  // order to follow the LLVM convention - that is, the pass manages all the
+  // objects it used during the processing, we destroy the object of
+  // TargetLDBackend here.
+  delete m_pLDBackend;
+}
+
+bool SectLinker::doInitialization(Module &pM)
+{
+  MCLDInfo &info = m_pOption->info();
+
+  // setup the output
+  info.output().setContext(info.contextFactory().produce(info.output().path()));
+
+  int mode = (Output::Object == info.output().type())? 0544 : 0755;
+  info.output().setMemArea(
+      info.memAreaFactory().produce(info.output().path(),
+                                    O_RDWR | O_CREAT | O_TRUNC,
+                                    mode));
+
+  //   make sure output is openend successfully.
+  if (!info.output().hasMemArea())
+    report_fatal_error("output is not given on the command line\n");
+
+  if (!info.output().memArea()->isGood())
+    report_fatal_error("can not open output file :"+info.output().path().native());
+
+  // let the target override the target-specific parameters
+  addTargetOptions(pM, *m_pOption);
+
+  // ----- convert position dependent options into tree of input files  ----- //
+  PositionDependentOptions &PosDepOpts = m_pOption->pos_dep_options();
+  std::stable_sort(PosDepOpts.begin(), PosDepOpts.end(), CompareOption);
+  initializeInputTree(PosDepOpts);
+
+  // Now, all input arguments are prepared well, send it into MCLDDriver
+  m_pLDDriver = new MCLDDriver(info, *m_pLDBackend);
+
+  return false;
+}
+
+bool SectLinker::doFinalization(Module &pM)
+{
+  const MCLDInfo &info = m_pOption->info();
+
+  // 3. - initialize output's standard segments and sections
+  if (!m_pLDDriver->initMCLinker())
+    return true;
+
+  // 4. - normalize the input tree
+  m_pLDDriver->normalize();
+
+  if (info.options().verbose()) {
+    outs() << "MCLinker (LLVM Sub-project) - ";
+    outs() << MCLDInfo::version();
+    outs() << "\n";
+  }
+
+  if (info.options().trace()) {
+    static int counter = 0;
+    outs() << "** name\ttype\tpath\tsize (" << info.inputs().size() << ")\n";
+    InputTree::const_dfs_iterator input, inEnd = info.inputs().dfs_end();
+    for (input=info.inputs().dfs_begin(); input!=inEnd; ++input) {
+      outs() << counter++ << " *  " << (*input)->name();
+      switch((*input)->type()) {
+      case Input::Archive:
+        outs() << "\tarchive\t(";
+        break;
+      case Input::Object:
+        outs() << "\tobject\t(";
+        break;
+      case Input::DynObj:
+        outs() << "\tshared\t(";
+        break;
+      case Input::Script:
+        outs() << "\tscript\t(";
+        break;
+      default:
+        report_fatal_error("** Trace a unsupported file. It must be an internal bug!");
+      }
+      outs() << (*input)->path().c_str() << ")\n";
+    }
+  }
+
+  // 5. - check if we can do static linking and if we use split-stack.
+  if (!m_pLDDriver->linkable())
+    return true;
+
+
+  // 6. - read all sections
+  if (!m_pLDDriver->readSections() ||
+      !m_pLDDriver->mergeSections())
+    return true;
+
+  // 7. - read all symbol tables of input files and resolve them
+  if (!m_pLDDriver->readSymbolTables() ||
+      !m_pLDDriver->mergeSymbolTables())
+    return true;
+
+  // 7.a - add standard symbols and target-dependent symbols
+  // m_pLDDriver->addUndefSymbols();
+  if (!m_pLDDriver->addStandardSymbols() ||
+      !m_pLDDriver->addTargetSymbols())
+    return true;
+
+  // 8. - read all relocation entries from input files
+  m_pLDDriver->readRelocations();
+
+  // 9. - pre-layout
+  m_pLDDriver->prelayout();
+
+  // 10. - linear layout
+  m_pLDDriver->layout();
+
+  // 10.b - post-layout
+  m_pLDDriver->postlayout();
+
+  // 11. - finalize symbol value
+  m_pLDDriver->finalizeSymbolValue();
+
+  // 12. - apply relocations
+  m_pLDDriver->relocate();
+
+  // 13. - write out output
+  m_pLDDriver->emitOutput();
+
+  // 14. - post processing
+  m_pLDDriver->postProcessing();
+  return false;
+}
+
+bool SectLinker::runOnMachineFunction(MachineFunction& pF)
+{
+  // basically, linkers do nothing during function is generated.
+  return false;
+}
+
+void SectLinker::initializeInputTree(const PositionDependentOptions &pPosDepOptions) const
+{
+  if (pPosDepOptions.empty())
+    return;
+
+  MCLDInfo &info = m_pOption->info();
+  PositionDependentOptions::const_iterator cur_char = pPosDepOptions.begin();
+  if (1 == pPosDepOptions.size() &&
+      ((*cur_char)->type() != PositionDependentOption::INPUT_FILE &&
+       (*cur_char)->type() != PositionDependentOption::NAMESPEC))
+    return;
+
+  InputTree::Connector *prev_ward = &InputTree::Downward;
+
+  std::stack<InputTree::iterator> returnStack;
+  InputTree::iterator cur_node = info.inputs().root();
+
+  PositionDependentOptions::const_iterator charEnd = pPosDepOptions.end();
+  while (cur_char != charEnd ) {
+    switch ((*cur_char)->type()) {
+    case PositionDependentOption::BITCODE: {
+      // threat bitcode as a script in this version.
+      const BitcodeOption *bitcode_option =
+          static_cast<const BitcodeOption*>(*cur_char);
+      info.inputs().insert(cur_node,
+                           *prev_ward,
+                           bitcode_option->path()->native(),
+                           *(bitcode_option->path()),
+                           Input::Script);
+      info.setBitcode(**cur_node);
+      prev_ward->move(cur_node);
+      prev_ward = &InputTree::Afterward;
+      break;
+    }
+    case PositionDependentOption::INPUT_FILE: {
+      const InputFileOption *input_file_option =
+          static_cast<const InputFileOption*>(*cur_char);
+      info.inputs().insert(cur_node,
+                           *prev_ward,
+                           input_file_option->path()->native(),
+                           *(input_file_option->path()));
+      prev_ward->move(cur_node);
+      prev_ward = &InputTree::Afterward;
+      break;
+    }
+    case PositionDependentOption::NAMESPEC: {
+      sys::fs::Path* path = 0;
+      const NamespecOption *namespec_option =
+          static_cast<const NamespecOption*>(*cur_char);
+      if (info.attrFactory().last().isStatic()) {
+        path = info.options().directories().find(namespec_option->namespec(),
+                                                 Input::Archive);
+      }
+      else {
+        path = info.options().directories().find(namespec_option->namespec(),
+                                                 Input::DynObj);
+      }
+
+      if (0 == path) {
+        llvm::report_fatal_error(std::string("Can't find namespec: ")+
+                                 namespec_option->namespec());
+      }
+      info.inputs().insert(cur_node,
+                           *prev_ward,
+                           namespec_option->namespec(),
+                           *path);
+      prev_ward->move(cur_node);
+      prev_ward = &InputTree::Afterward;
+      break;
+    }
+    case PositionDependentOption::START_GROUP:
+      info.inputs().enterGroup(cur_node, *prev_ward);
+      prev_ward->move(cur_node);
+      returnStack.push(cur_node);
+      prev_ward = &InputTree::Downward;
+      break;
+    case PositionDependentOption::END_GROUP:
+      cur_node = returnStack.top();
+      returnStack.pop();
+      prev_ward = &InputTree::Afterward;
+      break;
+    case PositionDependentOption::WHOLE_ARCHIVE:
+      info.attrFactory().last().setWholeArchive();
+      break;
+    case PositionDependentOption::NO_WHOLE_ARCHIVE:
+      info.attrFactory().last().unsetWholeArchive();
+      break;
+    case PositionDependentOption::AS_NEEDED:
+      info.attrFactory().last().setAsNeeded();
+      break;
+    case PositionDependentOption::NO_AS_NEEDED:
+      info.attrFactory().last().unsetAsNeeded();
+      break;
+    case PositionDependentOption::ADD_NEEDED:
+      info.attrFactory().last().setAddNeeded();
+      break;
+    case PositionDependentOption::NO_ADD_NEEDED:
+      info.attrFactory().last().unsetAddNeeded();
+      break;
+    case PositionDependentOption::BSTATIC:
+      info.attrFactory().last().setStatic();
+      break;
+    case PositionDependentOption::BDYNAMIC:
+      info.attrFactory().last().setDynamic();
+      break;
+    default:
+      report_fatal_error("can not find the type of input file");
+    }
+    ++cur_char;
+  }
+
+  if (!returnStack.empty()) {
+    report_fatal_error("no matched --start-group and --end-group");
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Non-member functions
+static bool CompareOption(const PositionDependentOption* X,
+                          const PositionDependentOption* Y)
+{
+  return (X->position() < Y->position());
+}
+
diff --git a/lib/CodeGen/SectLinkerOption.cpp b/lib/CodeGen/SectLinkerOption.cpp
new file mode 100644
index 0000000..85d6b10
--- /dev/null
+++ b/lib/CodeGen/SectLinkerOption.cpp
@@ -0,0 +1,24 @@
+//===- SectLinkerOption.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/CodeGen/SectLinkerOption.h"
+#include "mcld/Support/DerivedPositionDependentOptions.h"
+#include "mcld/Support/RealPath.h"
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// SectLinkerOption
+SectLinkerOption::SectLinkerOption(MCLDInfo &pLDInfo)
+  : m_pLDInfo(&pLDInfo) { }
+
+SectLinkerOption::~SectLinkerOption() {
+  for (PositionDependentOptions::iterator pdoption = m_PosDepOptions.begin(),
+       pdoptionEnd = m_PosDepOptions.end(); pdoption != pdoptionEnd; ++pdoption)
+    delete *pdoption;
+}
diff --git a/lib/LD/Android.mk b/lib/LD/Android.mk
new file mode 100644
index 0000000..dc356c7
--- /dev/null
+++ b/lib/LD/Android.mk
@@ -0,0 +1,96 @@
+LOCAL_PATH:= $(call my-dir)
+
+# =====================================================
+# Static library: libmcldLD
+# =====================================================
+
+mcld_ld_SRC_FILES := \
+  ArchiveReader.cpp \
+  BranchIsland.cpp  \
+  DynObjReader.cpp  \
+  DynObjWriter.cpp  \
+  ELFSegment.cpp  \
+  ELFSegmentFactory.cpp \
+  Layout.cpp  \
+  LDContext.cpp \
+  LDFileFormat.cpp  \
+  LDReader.cpp  \
+  LDSection.cpp \
+  LDSectionFactory.cpp  \
+  LDSymbol.cpp  \
+  LDWriter.cpp  \
+  ObjectWriter.cpp  \
+  Relocation.cpp  \
+  RelocationFactory.cpp \
+  ResolveInfo.cpp \
+  ResolveInfoFactory.cpp  \
+  Resolver.cpp  \
+  SectionMap.cpp  \
+  SectionMerger.cpp \
+  StaticResolver.cpp  \
+  StrSymPool.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_ld_SRC_FILES)
+LOCAL_MODULE:= libmcldLD
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_ld_SRC_FILES)
+LOCAL_MODULE:= libmcldLD
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+# =====================================================
+# Static library: libmcldLDVariant
+# =====================================================
+
+mcld_ld_variant_SRC_FILES := \
+  BSDArchiveReader.cpp  \
+  GNUArchiveReader.cpp  \
+  ELFDynObjFileFormat.cpp \
+  ELFDynObjReader.cpp \
+  ELFDynObjWriter.cpp \
+  ELFExecFileFormat.cpp \
+  ELFFileFormat.cpp \
+  ELFObjectReader.cpp \
+  ELFObjectWriter.cpp \
+  ELFReader.cpp \
+  ELFWriter.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_ld_variant_SRC_FILES)
+LOCAL_MODULE:= libmcldLDVariant
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_ld_variant_SRC_FILES)
+LOCAL_MODULE:= libmcldLDVariant
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/LD/ArchiveReader.cpp b/lib/LD/ArchiveReader.cpp
new file mode 100644
index 0000000..f43c057
--- /dev/null
+++ b/lib/LD/ArchiveReader.cpp
@@ -0,0 +1,22 @@
+//===- ArchiveReader.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/ArchiveReader.h"
+
+using namespace mcld;
+
+//==========================
+// MCELFArchiveReader
+ArchiveReader::ArchiveReader()
+{
+}
+
+ArchiveReader::~ArchiveReader()
+{
+}
+ 
diff --git a/lib/LD/BSDArchiveReader.cpp b/lib/LD/BSDArchiveReader.cpp
new file mode 100644
index 0000000..1264824
--- /dev/null
+++ b/lib/LD/BSDArchiveReader.cpp
@@ -0,0 +1,34 @@
+//===- BSDArchiveReader.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInput.h"
+#include "mcld/MC/MCLDInputTree.h"
+#include "mcld/LD/BSDArchiveReader.h"
+
+using namespace mcld;
+
+BSDArchiveReader::BSDArchiveReader()
+{
+}
+
+BSDArchiveReader::~BSDArchiveReader()
+{
+}
+
+InputTree *BSDArchiveReader::readArchive(Input &input)
+{
+  // TODO
+  return NULL;
+}
+
+bool BSDArchiveReader::isMyFormat(Input& pInput) const
+{
+  // TODO
+  return false;
+}
+
diff --git a/lib/LD/BranchIsland.cpp b/lib/LD/BranchIsland.cpp
new file mode 100644
index 0000000..7a42717
--- /dev/null
+++ b/lib/LD/BranchIsland.cpp
@@ -0,0 +1,15 @@
+//===- BranchIsland.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/BranchIsland.h"
+
+using namespace mcld;
+
+//==========================
+// BranchIsland
+
diff --git a/lib/LD/DynObjReader.cpp b/lib/LD/DynObjReader.cpp
new file mode 100644
index 0000000..60b5cf7
--- /dev/null
+++ b/lib/LD/DynObjReader.cpp
@@ -0,0 +1,16 @@
+//===- DynObjReader.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/DynObjReader.h"
+#include "mcld/Target/TargetLDBackend.h"
+#include "mcld/MC/MCLDInput.h"
+
+using namespace mcld;
+
+//==========================
+// ObjectReader
diff --git a/lib/LD/DynObjWriter.cpp b/lib/LD/DynObjWriter.cpp
new file mode 100644
index 0000000..6f031ff
--- /dev/null
+++ b/lib/LD/DynObjWriter.cpp
@@ -0,0 +1,16 @@
+//===- DynObjWriter.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/DynObjWriter.h"
+#include "mcld/Target/TargetLDBackend.h"
+#include "mcld/MC/MCLDInput.h"
+
+using namespace mcld;
+
+//==========================
+// DynObjWriter
diff --git a/lib/LD/ELFDynObjFileFormat.cpp b/lib/LD/ELFDynObjFileFormat.cpp
new file mode 100644
index 0000000..77034eb
--- /dev/null
+++ b/lib/LD/ELFDynObjFileFormat.cpp
@@ -0,0 +1,81 @@
+//===- ELFDynObjFileFormat.cpp --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFDynObjFileFormat.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/MC/MCLinker.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/Target/GNULDBackend.h>
+
+using namespace mcld;
+
+void ELFDynObjFileFormat::initObjectType(MCLinker& pLinker)
+{
+  f_pDynSymTab    = &pLinker.getOrCreateOutputSectHdr(".dynsym",
+                                           LDFileFormat::NamePool,
+                                           llvm::ELF::SHT_DYNSYM,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pDynStrTab    = &pLinker.getOrCreateOutputSectHdr(".dynstr",
+                                           LDFileFormat::NamePool,
+                                           llvm::ELF::SHT_STRTAB,
+                                           llvm::ELF::SHF_ALLOC,
+                                           0x1);
+  f_pInterp       = &pLinker.getOrCreateOutputSectHdr(".interp",
+                                           LDFileFormat::Note,
+                                           llvm::ELF::SHT_PROGBITS,
+                                           llvm::ELF::SHF_ALLOC,
+                                           0x1);
+  f_pHashTab      = &pLinker.getOrCreateOutputSectHdr(".hash",
+                                           LDFileFormat::NamePool,
+                                           llvm::ELF::SHT_HASH,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pDynamic      = &pLinker.getOrCreateOutputSectHdr(".dynamic",
+                                           LDFileFormat::NamePool,
+                                           llvm::ELF::SHT_DYNAMIC,
+                                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                           f_Backend.bitclass() / 8);
+  f_pRelaDyn      = &pLinker.getOrCreateOutputSectHdr(".rela.dyn",
+                                           LDFileFormat::Relocation,
+                                           llvm::ELF::SHT_RELA,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pRelaPlt      = &pLinker.getOrCreateOutputSectHdr(".rela.plt",
+                                           LDFileFormat::Relocation,
+                                           llvm::ELF::SHT_RELA,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pRelDyn      = &pLinker.getOrCreateOutputSectHdr(".rel.dyn",
+                                           LDFileFormat::Relocation,
+                                           llvm::ELF::SHT_REL,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pRelPlt      = &pLinker.getOrCreateOutputSectHdr(".rel.plt",
+                                           LDFileFormat::Relocation,
+                                           llvm::ELF::SHT_REL,
+                                           llvm::ELF::SHF_ALLOC,
+                                           f_Backend.bitclass() / 8);
+  f_pGOT          = &pLinker.getOrCreateOutputSectHdr(".got",
+                                           LDFileFormat::Target,
+                                           llvm::ELF::SHT_PROGBITS,
+                                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                           f_Backend.bitclass() / 8);
+  f_pPLT          = &pLinker.getOrCreateOutputSectHdr(".plt",
+                                           LDFileFormat::Target,
+                                           llvm::ELF::SHT_PROGBITS,
+                                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                           f_Backend.bitclass() / 8);
+  f_pGOTPLT       = &pLinker.getOrCreateOutputSectHdr(".got.plt",
+                                           LDFileFormat::Target,
+                                           llvm::ELF::SHT_PROGBITS,
+                                           llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                           f_Backend.bitclass() / 8);
+}
+
diff --git a/lib/LD/ELFDynObjReader.cpp b/lib/LD/ELFDynObjReader.cpp
new file mode 100644
index 0000000..12e6d7c
--- /dev/null
+++ b/lib/LD/ELFDynObjReader.cpp
@@ -0,0 +1,99 @@
+//===- ELFDynObjReader.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/ADT/Twine.h>
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/Support/ErrorHandling.h>
+
+#include <mcld/LD/ELFDynObjReader.h>
+#include <mcld/LD/ELFReader.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Support/MemoryRegion.h>
+
+#include <string>
+
+using namespace mcld;
+
+//==========================
+// ELFDynObjReader
+ELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend, MCLinker& pLinker)
+  : DynObjReader(),
+    m_pELFReader(0),
+    m_Linker(pLinker) {
+  if (32 == pBackend.bitclass() && pBackend.isLittleEndian())
+    m_pELFReader = new ELFReader<32, true>(pBackend);
+}
+
+ELFDynObjReader::~ELFDynObjReader()
+{
+  delete m_pELFReader;
+}
+
+/// isMyFormat
+bool ELFDynObjReader::isMyFormat(Input &pInput) const
+{
+  assert(pInput.hasMemArea());
+
+  // Don't warning about the frequently requests.
+  // MemoryArea has a list of cache to handle this.
+  size_t hdr_size = m_pELFReader->getELFHeaderSize();
+  MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+
+  uint8_t* ELF_hdr = region->start();
+  bool result = true;
+  if (!m_pELFReader->isELF(ELF_hdr))
+    result = false;
+  else if (!m_pELFReader->isMyEndian(ELF_hdr))
+    result = false;
+  else if (!m_pELFReader->isMyMachine(ELF_hdr))
+    result = false;
+  else if (MCLDFile::DynObj != m_pELFReader->fileType(ELF_hdr))
+    result = false;
+  pInput.memArea()->release(region);
+  return result;
+}
+
+/// readDSO
+bool ELFDynObjReader::readDSO(Input& pInput)
+{
+  assert(pInput.hasMemArea());
+
+  size_t hdr_size = m_pELFReader->getELFHeaderSize();
+  MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+  uint8_t* ELF_hdr = region->start();
+
+  bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
+  pInput.memArea()->release(region);
+  return result;
+}
+
+/// readSymbols
+bool ELFDynObjReader::readSymbols(Input& pInput)
+{
+  assert(pInput.hasMemArea());
+
+  LDSection* symtab_shdr = pInput.context()->getSection(".dynsym");
+  LDSection* strtab_shdr = symtab_shdr->getLink();
+  if (NULL == symtab_shdr || NULL == strtab_shdr)
+    return false;
+
+  MemoryRegion* symtab_region = pInput.memArea()->request(symtab_shdr->offset(),
+                                                          symtab_shdr->size());
+
+  MemoryRegion* strtab_region = pInput.memArea()->request(strtab_shdr->offset(),
+                                                          strtab_shdr->size());
+  char* strtab = reinterpret_cast<char*>(strtab_region->start());
+  bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region, strtab);
+  pInput.memArea()->release(symtab_region);
+  pInput.memArea()->release(strtab_region);
+
+  return result;
+}
+
diff --git a/lib/LD/ELFDynObjWriter.cpp b/lib/LD/ELFDynObjWriter.cpp
new file mode 100644
index 0000000..21cd8e4
--- /dev/null
+++ b/lib/LD/ELFDynObjWriter.cpp
@@ -0,0 +1,138 @@
+//===- ELFDynObjWriter.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFDynObjWriter.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLinker.h>
+#include <llvm/Support/ELF.h>
+#include <vector>
+
+using namespace llvm;
+using namespace mcld;
+
+
+//==========================
+// ELFDynObjWriter
+ELFDynObjWriter::ELFDynObjWriter(GNULDBackend& pBackend, MCLinker& pLinker)
+  : DynObjWriter(pBackend),
+    ELFWriter(pBackend),
+    m_Backend(pBackend),
+    m_Linker(pLinker) {
+
+}
+
+ELFDynObjWriter::~ELFDynObjWriter()
+{
+}
+
+llvm::error_code ELFDynObjWriter::writeDynObj(Output& pOutput)
+{
+  // Write out name pool sections: .dynsym, .dynstr, .hash
+  target().emitDynNamePools(pOutput,
+                            m_Linker.getOutputSymbols(),
+                            m_Linker.getLayout(),
+                            m_Linker.getLDInfo());
+
+  // Write out name pool sections: .symtab, .strtab
+  target().emitRegNamePools(pOutput,
+                            m_Linker.getOutputSymbols(),
+                            m_Linker.getLayout(),
+                            m_Linker.getLDInfo());
+
+  // Write out regular ELF sections
+  unsigned int secIdx = 0;
+  unsigned int secEnd = pOutput.context()->numOfSections();
+  for (secIdx = 0; secIdx < secEnd; ++secIdx) {
+    LDSection* sect = pOutput.context()->getSection(secIdx);
+    MemoryRegion* region = NULL;
+    // request output region
+    switch(sect->kind()) {
+      case LDFileFormat::Regular:
+      case LDFileFormat::Relocation:
+      case LDFileFormat::Target: {
+        region = pOutput.memArea()->request(sect->offset(), sect->size());
+        if (NULL == region) {
+          llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") +
+                                   llvm::Twine(secIdx) +
+                                   llvm::Twine("] - `") +
+                                   sect->name() +
+                                   llvm::Twine("'.\n"));
+        }
+        break;
+      }
+      case LDFileFormat::Null:
+      case LDFileFormat::NamePool:
+      case LDFileFormat::BSS:
+      case LDFileFormat::Debug:
+      case LDFileFormat::Note:
+      case LDFileFormat::MetaData:
+      case LDFileFormat::Exception:
+      case LDFileFormat::Version:
+        // ignore these sections
+        continue;
+      default: {
+        llvm::errs() << "WARNING: unsupported section kind: "
+                     << sect->kind()
+                     << " of section "
+                     << sect->name()
+                     << ".\n";
+        continue;
+      }
+    }
+
+    // write out sections with data
+    switch(sect->kind()) {
+      case LDFileFormat::Regular: {
+        emitSectionData(m_Linker.getLayout(), *sect, *region);
+        break;
+      }
+      case LDFileFormat::Relocation:
+        emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region);
+        break;
+      case LDFileFormat::Target:
+        target().emitSectionData(pOutput, *sect, m_Linker.getLDInfo(), *region);
+        break;
+      default:
+        continue;
+    }
+  } // end of for loop
+
+  if (32 == target().bitclass()) {
+    // Write out ELF header
+    // Write out section header table
+    emitELF32ShStrTab(pOutput, m_Linker);
+
+    writeELF32Header(m_Linker.getLDInfo(),
+                     m_Linker.getLayout(),
+                     target(),
+                     pOutput);
+
+    emitELF32SectionHeader(pOutput, m_Linker);
+  }
+  else if (64 == target().bitclass()) {
+    // Write out ELF header
+    // Write out section header table
+    emitELF64ShStrTab(pOutput, m_Linker);
+
+    writeELF64Header(m_Linker.getLDInfo(),
+                     m_Linker.getLayout(),
+                     target(),
+                     pOutput);
+
+    emitELF64SectionHeader(pOutput, m_Linker);
+  }
+  else
+    return make_error_code(errc::not_supported);
+
+  return llvm::make_error_code(llvm::errc::success);
+}
+
diff --git a/lib/LD/ELFExecFileFormat.cpp b/lib/LD/ELFExecFileFormat.cpp
new file mode 100644
index 0000000..f10d764
--- /dev/null
+++ b/lib/LD/ELFExecFileFormat.cpp
@@ -0,0 +1,13 @@
+//===- ELFExecFileFormat.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFExecFileFormat.h>
+#include <mcld/MC/MCLinker.h>
+
+using namespace mcld;
+
diff --git a/lib/LD/ELFFileFormat.cpp b/lib/LD/ELFFileFormat.cpp
new file mode 100644
index 0000000..9394e44
--- /dev/null
+++ b/lib/LD/ELFFileFormat.cpp
@@ -0,0 +1,242 @@
+//===- ELFFileFormat.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFFileFormat.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCLDFile.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/Target/GNULDBackend.h>
+
+using namespace mcld;
+
+ELFFileFormat::ELFFileFormat(GNULDBackend& pBackend)
+  : f_Backend(pBackend),
+    f_pNULLSection(NULL),
+    f_pGOT(NULL),
+    f_pPLT(NULL),
+    f_pRelDyn(NULL),
+    f_pRelPlt(NULL),
+    f_pRelaDyn(NULL),
+    f_pRelaPlt(NULL),
+    f_pComment(NULL),
+    f_pData1(NULL),
+    f_pDebug(NULL),
+    f_pDynamic(NULL),
+    f_pDynStrTab(NULL),
+    f_pDynSymTab(NULL),
+    f_pFini(NULL),
+    f_pFiniArray(NULL),
+    f_pHashTab(NULL),
+    f_pInit(NULL),
+    f_pInitArray(NULL),
+    f_pInterp(NULL),
+    f_pLine(NULL),
+    f_pNote(NULL),
+    f_pPreInitArray(NULL),
+    f_pROData1(NULL),
+    f_pShStrTab(NULL),
+    f_pStrTab(NULL),
+    f_pSymTab(NULL),
+    f_pTBSS(NULL),
+    f_pTData(NULL),
+    f_pCtors(NULL),
+    f_pDataRelRo(NULL),
+    f_pDtors(NULL),
+    f_pEhFrame(NULL),
+    f_pEhFrameHdr(NULL),
+    f_pGCCExceptTable(NULL),
+    f_pGNUVersion(NULL),
+    f_pGNUVersionD(NULL),
+    f_pGNUVersionR(NULL),
+    f_pGOTPLT(NULL),
+    f_pJCR(NULL),
+    f_pNoteABITag(NULL),
+    f_pStab(NULL),
+    f_pStabStr(NULL) {
+
+}
+
+ELFFileFormat::~ELFFileFormat()
+{
+}
+
+void ELFFileFormat::initObjectFormat(MCLinker& pLinker)
+{
+  f_pTextSection     = &pLinker.getOrCreateOutputSectHdr(".text",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                              0x1);
+  f_pNULLSection     = &pLinker.getOrCreateOutputSectHdr("",
+                                              LDFileFormat::Null,
+                                              llvm::ELF::SHT_NULL,
+                                              0x0);
+  f_pReadOnlySection = &pLinker.getOrCreateOutputSectHdr(".rodata",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+
+  f_pBSSSection      = &pLinker.getOrCreateOutputSectHdr(".bss",
+                                              LDFileFormat::BSS,
+                                              llvm::ELF::SHT_NOBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pComment         = &pLinker.getOrCreateOutputSectHdr(".comment",
+                                              LDFileFormat::MetaData,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              0x0,
+                                              0x1);
+  f_pDataSection     = &pLinker.getOrCreateOutputSectHdr(".data",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pData1           = &pLinker.getOrCreateOutputSectHdr(".data1",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pDebug           = &pLinker.getOrCreateOutputSectHdr(".debug",
+                                              LDFileFormat::Debug,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              0x0,
+                                              0x1);
+  f_pInit            = &pLinker.getOrCreateOutputSectHdr(".init",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                              0x1);
+  f_pInitArray       = &pLinker.getOrCreateOutputSectHdr(".init_array",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_INIT_ARRAY,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pFini            = &pLinker.getOrCreateOutputSectHdr(".fini",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
+                                              0x1);
+  f_pFiniArray       = &pLinker.getOrCreateOutputSectHdr(".fini_array",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_FINI_ARRAY,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pLine            = &pLinker.getOrCreateOutputSectHdr(".line",
+                                              LDFileFormat::Debug,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              0x0,
+                                              0x1);
+  f_pPreInitArray    = &pLinker.getOrCreateOutputSectHdr(".preinit_array",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PREINIT_ARRAY,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  // the definition of SHF_XXX attributes of rodata in Linux Standard Base
+  // conflicts with System V standard. We follow System V standard.
+  f_pROData1         = &pLinker.getOrCreateOutputSectHdr(".rodata1",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pShStrTab        = &pLinker.getOrCreateOutputSectHdr(".shstrtab",
+                                              LDFileFormat::NamePool,
+                                              llvm::ELF::SHT_STRTAB,
+                                              0x0,
+                                              0x1);
+  // In ELF Spec Book I, p1-16. If symbol table and string table are in 
+  // loadable segments, set the attribute to SHF_ALLOC bit. But in the
+  // real world, this bit always turn off.
+  f_pSymTab       = &pLinker.getOrCreateOutputSectHdr(".symtab",
+                                              LDFileFormat::NamePool,
+                                              llvm::ELF::SHT_SYMTAB,
+                                              0x0,
+                                              f_Backend.bitclass() / 8);
+  f_pStrTab       = &pLinker.getOrCreateOutputSectHdr(".strtab",
+                                              LDFileFormat::NamePool,
+                                              llvm::ELF::SHT_STRTAB,
+                                              0x0,
+                                              0x1);
+  f_pTBSS         = &pLinker.getOrCreateOutputSectHdr(".tbss",
+                                              LDFileFormat::BSS,
+                                              llvm::ELF::SHT_NOBITS,
+                                              llvm::ELF::SHF_ALLOC |
+                                              llvm::ELF::SHF_WRITE |
+                                              llvm::ELF::SHF_TLS,
+                                              0x1);
+  f_pTData        = &pLinker.getOrCreateOutputSectHdr(".tdata",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC |
+                                              llvm::ELF::SHF_WRITE |
+                                              llvm::ELF::SHF_TLS,
+                                              0x1);
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  f_pCtors          = &pLinker.getOrCreateOutputSectHdr(".ctor",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pDataRelRo      = &pLinker.getOrCreateOutputSectHdr(".data.rel.ro",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pDtors          = &pLinker.getOrCreateOutputSectHdr(".dtors",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pEhFrame        = &pLinker.getOrCreateOutputSectHdr(".eh_frame",
+                                              LDFileFormat::Exception,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pEhFrameHdr     = &pLinker.getOrCreateOutputSectHdr(".eh_frame_hdr",
+                                              LDFileFormat::Exception,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pGCCExceptTable = &pLinker.getOrCreateOutputSectHdr(".gcc_except_table",
+                                              LDFileFormat::Exception,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pGNUVersion     = &pLinker.getOrCreateOutputSectHdr(".gnu.version",
+                                              LDFileFormat::Version,
+                                              llvm::ELF::SHT_GNU_versym,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pGNUVersionD    = &pLinker.getOrCreateOutputSectHdr(".gnu.version_d",
+                                              LDFileFormat::Version,
+                                              llvm::ELF::SHT_GNU_verdef,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pGNUVersionR    = &pLinker.getOrCreateOutputSectHdr(".gnu.version_r",
+                                              LDFileFormat::Version,
+                                              llvm::ELF::SHT_GNU_verneed,
+                                              llvm::ELF::SHF_ALLOC,
+                                              0x1);
+  f_pJCR            = &pLinker.getOrCreateOutputSectHdr(".jcr",
+                                              LDFileFormat::Regular,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
+                                              0x1);
+  f_pStab           = &pLinker.getOrCreateOutputSectHdr(".stab",
+                                              LDFileFormat::Debug,
+                                              llvm::ELF::SHT_PROGBITS,
+                                              0x0,
+                                              0x1);
+  f_pStabStr        = &pLinker.getOrCreateOutputSectHdr(".stabstr",
+                                              LDFileFormat::Debug,
+                                              llvm::ELF::SHT_STRTAB,
+                                              0x0,
+                                              0x1);
+}
+
diff --git a/lib/LD/ELFObjectReader.cpp b/lib/LD/ELFObjectReader.cpp
new file mode 100644
index 0000000..abc3d30
--- /dev/null
+++ b/lib/LD/ELFObjectReader.cpp
@@ -0,0 +1,243 @@
+//===- ELFObjectReader.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/ELF.h>
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/LD/ELFObjectReader.h>
+#include <mcld/LD/ELFReader.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/Target/GNULDBackend.h>
+
+#include <string>
+#include <cassert>
+
+using namespace llvm;
+using namespace mcld;
+
+//==========================
+// ELFObjectReader
+/// constructor
+ELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker)
+  : ObjectReader(),
+    m_pELFReader(0),
+    m_Linker(pLinker)
+{
+  if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
+    m_pELFReader = new ELFReader<32, true>(pBackend);
+  }
+}
+
+/// destructor
+ELFObjectReader::~ELFObjectReader()
+{
+  delete m_pELFReader;
+}
+
+/// isMyFormat
+bool ELFObjectReader::isMyFormat(Input &pInput) const
+{
+  assert(pInput.hasMemArea());
+
+  // Don't warning about the frequently requests.
+  // MemoryArea has a list of cache to handle this.
+  size_t hdr_size = m_pELFReader->getELFHeaderSize();
+  MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+
+  uint8_t* ELF_hdr = region->start();
+  bool result = true;
+  if (!m_pELFReader->isELF(ELF_hdr))
+    result = false;
+  else if (!m_pELFReader->isMyEndian(ELF_hdr))
+    result = false;
+  else if (!m_pELFReader->isMyMachine(ELF_hdr))
+    result = false;
+  else if (MCLDFile::Object != m_pELFReader->fileType(ELF_hdr))
+    result = false;
+  pInput.memArea()->release(region);
+  return result;
+}
+
+/// readObject - read section header and create LDSections.
+bool ELFObjectReader::readObject(Input& pInput)
+{
+  assert(pInput.hasMemArea());
+
+  size_t hdr_size = m_pELFReader->getELFHeaderSize();
+  MemoryRegion* region = pInput.memArea()->request(0, hdr_size);
+  uint8_t* ELF_hdr = region->start();
+  bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
+  pInput.memArea()->release(region);
+  return result;
+}
+
+/// readSections - read all regular sections.
+bool ELFObjectReader::readSections(Input& pInput)
+{
+  // handle sections
+  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
+  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
+    // ignore the section if the LDSection* in input context is NULL
+    if (NULL == *section)
+        continue;
+
+    switch((*section)->kind()) {
+      /** group sections **/
+      case LDFileFormat::Group: {
+        assert(NULL != (*section)->getLink());
+        ResolveInfo* signature =
+              m_pELFReader->readSymbol(pInput,
+                                       *(*section)->getLink(),
+                                       m_Linker.getLDInfo(),
+                                       (*section)->getInfo());
+
+        bool exist = false;
+        signatures().insert(signature->name(), exist);
+
+        if (exist) {
+          // if this is not the first time we see this group signature, then
+          // ignore all the members in this group (set NULL)
+          MemoryRegion* region =
+              pInput.memArea()->request((*section)->offset(),
+                                        (*section)->size());
+          llvm::ELF::Elf32_Word* value =
+                      reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
+
+          size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
+          if (llvm::ELF::GRP_COMDAT == *value) {
+            for (size_t index = 1; index < size; ++index)
+              pInput.context()->getSectionTable()[value[index]] = NULL;
+          }
+          pInput.memArea()->release(region);
+        }
+        break;
+      }
+      /** relocation sections **/
+      case LDFileFormat::Relocation: {
+        assert(NULL != (*section)->getLink());
+        size_t link_index = (*section)->getLink()->index();
+        if (NULL == pInput.context()->getSectionTable()[link_index]) {
+          // Relocation sections of group members should also be part of the
+          // group. Thus, if the associated member sections are ignored, the
+          // related relocations should be also ignored.
+          *section = NULL;
+        }
+        break;
+      }
+      /** normal sections **/
+      // FIXME: support Debug, Exception and Version Kinds
+      case LDFileFormat::Debug:
+      case LDFileFormat::Exception:
+      case LDFileFormat::Version:
+      /** Fall through **/
+      case LDFileFormat::Regular:
+      case LDFileFormat::Note:
+      case LDFileFormat::MetaData: {
+        if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
+          llvm::report_fatal_error(
+                                llvm::Twine("can not read regular section `") +
+                                (*section)->name() +
+                                llvm::Twine("'.\n"));
+        break;
+      }
+      /** target dependent sections **/
+      case LDFileFormat::Target: {
+        if (!m_pELFReader->readTargetSection(pInput, m_Linker, **section))
+          llvm::report_fatal_error(
+                        llvm::Twine("can not read target dependentsection `") +
+                        (*section)->name() +
+                        llvm::Twine("'.\n"));
+        break;
+      }
+      /** BSS sections **/
+      case LDFileFormat::BSS: {
+        LDSection& output_bss = m_Linker.getOrCreateOutputSectHdr(
+                                               (*section)->name(),
+                                               LDFileFormat::BSS,
+                                               llvm::ELF::SHT_NOBITS,
+                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE);
+
+        llvm::MCSectionData& sect_data = m_Linker.getOrCreateSectData(**section);
+                                         /*  value, valsize, size*/
+        llvm::MCFillFragment* frag =
+                    new llvm::MCFillFragment(0x0,   1,       (*section)->size());
+
+        uint64_t size = m_Linker.getLayout().appendFragment(*frag,
+                                                            sect_data,
+                                                            (*section)->align());
+        output_bss.setSize(output_bss.size() + size);
+        break;
+      }
+      // ignore
+      case LDFileFormat::Null:
+      case LDFileFormat::NamePool:
+        continue;
+
+    }
+  } // end of for all sections
+
+  return true;
+}
+
+/// readSymbols - read symbols into MCLinker from the input relocatable object.
+bool ELFObjectReader::readSymbols(Input& pInput)
+{
+  assert(pInput.hasMemArea());
+
+  LDSection* symtab_shdr = pInput.context()->getSection(".symtab");
+  LDSection* strtab_shdr = symtab_shdr->getLink();
+  if (NULL == symtab_shdr || NULL == strtab_shdr)
+    return false;
+
+  MemoryRegion* symtab_region = pInput.memArea()->request(symtab_shdr->offset(),
+                                                          symtab_shdr->size());
+  MemoryRegion* strtab_region = pInput.memArea()->request(strtab_shdr->offset(),
+                                                          strtab_shdr->size());
+  char* strtab = reinterpret_cast<char*>(strtab_region->start());
+  bool result = m_pELFReader->readSymbols(pInput,
+                                          m_Linker,
+                                          *symtab_region,
+                                          strtab);
+  pInput.memArea()->release(symtab_region);
+  pInput.memArea()->release(strtab_region);
+  return result;
+}
+
+bool ELFObjectReader::readRelocations(Input& pInput)
+{
+  assert(pInput.hasMemArea());
+
+  MemoryArea* mem = pInput.memArea();
+  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
+  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
+    // ignore the section if the LDSection* in input context is NULL
+    if (NULL == *section)
+        continue;
+
+    if ((*section)->type() == llvm::ELF::SHT_RELA &&
+        (*section)->kind() == LDFileFormat::Relocation) {
+      MemoryRegion* region = mem->request((*section)->offset(), (*section)->size());
+      bool result = m_pELFReader->readRela(pInput, m_Linker, **section, *region);
+      mem->release(region);
+      if (!result)
+        return false;
+    }
+    else if ((*section)->type() == llvm::ELF::SHT_REL &&
+             (*section)->kind() == LDFileFormat::Relocation) {
+      MemoryRegion* region = mem->request((*section)->offset(), (*section)->size());
+      bool result = m_pELFReader->readRel(pInput, m_Linker, **section, *region);
+      mem->release(region);
+      if (!result)
+        return false;
+    }
+  }
+  return true;
+}
+
diff --git a/lib/LD/ELFObjectWriter.cpp b/lib/LD/ELFObjectWriter.cpp
new file mode 100644
index 0000000..2795d3f
--- /dev/null
+++ b/lib/LD/ELFObjectWriter.cpp
@@ -0,0 +1,23 @@
+//===- ELFObjectWriter.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/ELFObjectWriter.h"
+
+using namespace mcld;
+
+//==========================
+// ELFObjectWriter
+ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, MCLinker& pLinker)
+  : ObjectWriter(pBackend), ELFWriter(pBackend), m_Linker(pLinker) {
+}
+
+ELFObjectWriter::~ELFObjectWriter()
+{
+}
+
+
diff --git a/lib/LD/ELFReader.cpp b/lib/LD/ELFReader.cpp
new file mode 100644
index 0000000..1fd2a13
--- /dev/null
+++ b/lib/LD/ELFReader.cpp
@@ -0,0 +1,188 @@
+//===- ELFReader.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/Support/ELF.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/Host.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/LD/ELFReader.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <cstring>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// ELFReaderIF
+/// getLDSectionKind
+LDFileFormat::Kind
+ELFReaderIF::getLDSectionKind(uint32_t pType, const char* pName) const
+{
+  // name rules
+  llvm::StringRef name(pName);
+  if (llvm::StringRef::npos != name.find(".debug"))
+    return LDFileFormat::Debug;
+  if (name.startswith(".comment"))
+    return LDFileFormat::MetaData;
+  if (name.startswith(".interp") || name.startswith(".dynamic"))
+    return LDFileFormat::Note;
+  if (name.startswith(".eh_frame") ||
+      name.startswith(".eh_frame_hdr") ||
+      name.startswith(".gcc_except_table"))
+    return LDFileFormat::Exception;
+
+  // type rules
+  switch(pType) {
+  case llvm::ELF::SHT_NULL:
+    return LDFileFormat::Null;
+  case llvm::ELF::SHT_INIT_ARRAY:
+  case llvm::ELF::SHT_FINI_ARRAY:
+  case llvm::ELF::SHT_PREINIT_ARRAY:
+  case llvm::ELF::SHT_PROGBITS:
+    return LDFileFormat::Regular;
+  case llvm::ELF::SHT_SYMTAB:
+  case llvm::ELF::SHT_DYNSYM:
+  case llvm::ELF::SHT_STRTAB:
+    return LDFileFormat::NamePool;
+  case llvm::ELF::SHT_RELA:
+  case llvm::ELF::SHT_REL:
+    return LDFileFormat::Relocation;
+  case llvm::ELF::SHT_NOBITS:
+    return LDFileFormat::BSS;
+  case llvm::ELF::SHT_DYNAMIC:
+  case llvm::ELF::SHT_NOTE:
+    return LDFileFormat::Note;
+  case llvm::ELF::SHT_HASH:
+  case llvm::ELF::SHT_SHLIB:
+    return LDFileFormat::MetaData;
+  case llvm::ELF::SHT_GROUP:
+    return LDFileFormat::Group;
+  case llvm::ELF::SHT_GNU_versym:
+  case llvm::ELF::SHT_GNU_verdef:
+  case llvm::ELF::SHT_GNU_verneed:
+    return LDFileFormat::Version;
+  default:
+    if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
+        (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
+        (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
+      return LDFileFormat::Target;
+    llvm::report_fatal_error(llvm::Twine("unsupported ELF section type: ") +
+                             llvm::Twine(pType) + llvm::Twine(".\n"));
+  }
+  return LDFileFormat::MetaData;
+}
+
+/// getSymDesc
+ResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx, const Input& pInput) const
+{
+  if (pShndx == llvm::ELF::SHN_UNDEF)
+    return ResolveInfo::Undefined;
+
+  if (pShndx < llvm::ELF::SHN_LORESERVE) {
+    // an ELF symbol defined in a section which we are not including
+    // must be treated as an Undefined.
+    // @ref Google gold linker: symtab.cc: 1086
+    if (NULL == pInput.context()->getSection(pShndx))
+      return ResolveInfo::Undefined;
+    return ResolveInfo::Define;
+  }
+
+  if (pShndx == llvm::ELF::SHN_ABS)
+    return ResolveInfo::Define;
+
+  if (pShndx == llvm::ELF::SHN_COMMON)
+    return ResolveInfo::Common;
+
+  // FIXME: ELF weak alias should be ResolveInfo::Indirect
+  return ResolveInfo::NoneDesc;
+}
+
+/// getSymBinding
+ResolveInfo::Binding
+ELFReaderIF::getSymBinding(uint8_t pBinding, uint16_t pShndx, uint8_t pVis) const
+{
+
+  // TODO:
+  // if --just-symbols option is enabled, the symbol must covert to Absolute
+
+  switch(pBinding) {
+  case llvm::ELF::STB_LOCAL:
+    return ResolveInfo::Local;
+  case llvm::ELF::STB_GLOBAL:
+    return ResolveInfo::Global;
+  case llvm::ELF::STB_WEAK:
+    return ResolveInfo::Weak;
+  }
+
+  if (pShndx == llvm::ELF::SHN_ABS)
+    return ResolveInfo::Absolute;
+
+  return ResolveInfo::NoneBinding;
+}
+
+/// getSymFragmentRef
+MCFragmentRef*
+ELFReaderIF::getSymFragmentRef(Input& pInput,
+                               MCLinker& pLinker,
+                               uint16_t pShndx,
+                               uint32_t pOffset) const
+{
+  
+  if (pShndx == llvm::ELF::SHN_UNDEF || pShndx >= llvm::ELF::SHN_LORESERVE)
+    return NULL;
+
+  LDSection* sect_hdr = pInput.context()->getSection(pShndx);
+
+  if (NULL == sect_hdr) {
+    llvm::report_fatal_error(llvm::Twine("section[") +
+                             llvm::Twine(pShndx) +
+                             llvm::Twine("] is invalid in file `") +
+                             pInput.path().native() +
+                             llvm::Twine("'.\n"));
+  }
+  
+  MCFragmentRef* result = pLinker.getLayout().getFragmentRef(*sect_hdr, pOffset);
+  return result;
+}
+
+/// getSymVisibility
+ResolveInfo::Visibility
+ELFReaderIF::getSymVisibility(uint8_t pVis) const
+{
+  return static_cast<ResolveInfo::Visibility>(pVis);
+}
+
+/// getSymValue - get the section offset of the symbol.
+uint64_t ELFReaderIF::getSymValue(uint64_t pValue,
+                                  uint16_t pShndx,
+                                  const Input& pInput) const
+{
+  if (Input::Object == pInput.type()) {
+    // In relocatable files, st_value holds alignment constraints for a symbol
+    // whose section index is SHN_COMMON
+    if (pShndx == llvm::ELF::SHN_COMMON || pShndx == llvm::ELF::SHN_ABS) {
+      return pValue;
+    }
+
+    // In relocatable files, st_value holds a section offset for a defined symbol.
+    // TODO:
+    // if --just-symbols option are enabled, convert the value from section offset
+    // to virtual address by adding input section's virtual address.
+    // The section's virtual address in relocatable files is normally zero, but
+    // people can use link script to change it.
+    return pValue;
+  }
+
+  // In executable and shared object files, st_value holds a virtual address.
+  // the virtual address is useless during linking.
+  return 0x0;
+}
+
diff --git a/lib/LD/ELFSegment.cpp b/lib/LD/ELFSegment.cpp
new file mode 100644
index 0000000..a08641b
--- /dev/null
+++ b/lib/LD/ELFSegment.cpp
@@ -0,0 +1,35 @@
+//===- ELFSegment.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFSegment.h>
+
+using namespace mcld;
+
+//==========================
+// ELFSegment
+ELFSegment::ELFSegment(uint32_t pType,
+                       uint32_t pFlag,
+                       uint64_t pOffset,
+                       uint64_t pVaddr,
+                       uint64_t pPaddr,
+                       uint64_t pFilesz,
+                       uint64_t pMemsz,
+                       uint64_t pAlign)
+  : m_Type(pType),
+    m_Flag(pFlag),
+    m_Offset(pOffset),
+    m_Vaddr(pVaddr),
+    m_Paddr(pPaddr),
+    m_Filesz(pFilesz),
+    m_Memsz(pMemsz),
+    m_Align(pAlign) {
+}
+
+ELFSegment::~ELFSegment()
+{
+}
diff --git a/lib/LD/ELFSegmentFactory.cpp b/lib/LD/ELFSegmentFactory.cpp
new file mode 100644
index 0000000..d8ad3cc
--- /dev/null
+++ b/lib/LD/ELFSegmentFactory.cpp
@@ -0,0 +1,40 @@
+//===- ELFSegmentFactory.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ELFSegmentFactory.h>
+
+using namespace mcld;
+
+//==========================
+// ELFSegmentFactory
+
+ELFSegmentFactory::ELFSegmentFactory(size_t pNum)
+  : GCFactory<ELFSegment, 0>(pNum)
+{
+}
+
+ELFSegmentFactory::~ELFSegmentFactory()
+{
+}
+
+/// produce - produce an empty ELF segment information.
+/// this function will create an ELF segment
+/// @param pType - p_type in ELF program header
+ELFSegment* ELFSegmentFactory::produce(uint32_t pType)
+{
+  ELFSegment* segment = allocate();
+  new (segment) ELFSegment(pType);
+  return segment;
+}
+
+/// destroy - destruct the ELF segment
+void ELFSegmentFactory::destroy(ELFSegment*& pSegment)
+{
+  deallocate(pSegment);
+}
+
diff --git a/lib/LD/ELFWriter.cpp b/lib/LD/ELFWriter.cpp
new file mode 100644
index 0000000..a94fd5c
--- /dev/null
+++ b/lib/LD/ELFWriter.cpp
@@ -0,0 +1,583 @@
+//===- ELFWriter.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/ELFWriter.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <cstdlib>
+#include <cstring>
+
+using namespace llvm::ELF;
+using namespace mcld;
+
+/// writeELF32Header - write ELF header
+void ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo,
+                                 const Layout& pLayout,
+                                 const GNULDBackend& pBackend,
+                                 Output& pOutput) const
+{
+    assert(pOutput.hasMemArea());
+
+    // ELF header must start from 0x0
+    MemoryRegion *region = pOutput.memArea()->request(0,
+                                                      sizeof(Elf32_Ehdr));
+    Elf32_Ehdr* header = (Elf32_Ehdr*)region->start();
+
+    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
+
+    header->e_ident[EI_CLASS]      = ELFCLASS32;
+    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
+                                       ELFDATA2LSB : ELFDATA2MSB;
+    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
+    header->e_ident[EI_OSABI]      = pBackend.OSABI();
+    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
+
+    // FIXME: add processor-specific and core file types.
+    switch(pOutput.type()) {
+    case Output::Object:
+      header->e_type = ET_REL;
+      break;
+    case Output::DynObj:
+      header->e_type = ET_DYN;
+      break;
+    case Output::Exec:
+      header->e_type = ET_EXEC;
+      break;
+    default:
+      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
+      header->e_type = ET_NONE;
+    }
+    header->e_machine   = pBackend.machine();
+    header->e_version   = header->e_ident[EI_VERSION];
+    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
+    header->e_phoff     = sizeof(Elf32_Ehdr);
+    header->e_shoff     = getELF32LastStartOffset(pOutput);
+    header->e_flags     = pBackend.flags();
+    header->e_ehsize    = sizeof(Elf32_Ehdr);
+    header->e_phentsize = sizeof(Elf32_Phdr);
+    header->e_phnum     = pBackend.numOfSegments();
+    header->e_shentsize = sizeof(Elf32_Shdr);
+    header->e_shnum     = pOutput.context()->numOfSections();
+    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
+}
+
+/// writeELF64Header - write ELF header
+void ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo,
+                                 const Layout& pLayout,
+                                 const GNULDBackend& pBackend,
+                                 Output& pOutput) const
+{
+    assert(pOutput.hasMemArea());
+
+    // ELF header must start from 0x0
+    MemoryRegion *region = pOutput.memArea()->request(0,
+                                                      sizeof(Elf64_Ehdr));
+    Elf64_Ehdr* header = (Elf64_Ehdr*)region->start();
+
+    memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
+
+    header->e_ident[EI_CLASS]      = ELFCLASS64;
+    header->e_ident[EI_DATA]       = pBackend.isLittleEndian()?
+                                       ELFDATA2LSB : ELFDATA2MSB;
+    header->e_ident[EI_VERSION]    = pBackend.ELFVersion();
+    header->e_ident[EI_OSABI]      = pBackend.OSABI();
+    header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion();
+
+    // FIXME: add processor-specific and core file types.
+    switch(pOutput.type()) {
+    case Output::Object:
+      header->e_type = ET_REL;
+      break;
+    case Output::DynObj:
+      header->e_type = ET_DYN;
+      break;
+    case Output::Exec:
+      header->e_type = ET_EXEC;
+      break;
+    default:
+      llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n";
+      header->e_type = ET_NONE;
+    }
+    header->e_machine   = pBackend.machine();
+    header->e_version   = header->e_ident[EI_VERSION];
+    header->e_entry     = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput);
+    header->e_phoff     = sizeof(Elf64_Ehdr);
+    header->e_shoff     = getELF64LastStartOffset(pOutput);
+    header->e_flags     = pBackend.flags();
+    header->e_ehsize    = sizeof(Elf64_Ehdr);
+    header->e_phentsize = sizeof(Elf64_Phdr);
+    header->e_phnum     = pBackend.numOfSegments();
+    header->e_shentsize = sizeof(Elf64_Shdr);
+    header->e_shnum     = pOutput.context()->numOfSections();
+    header->e_shstrndx  = pOutput.context()->getSectionIdx(".shstrtab");
+}
+
+/// getEntryPoint
+uint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo,
+                                  const Layout& pLayout,
+                                  const GNULDBackend& pBackend,
+                                  const Output& pOutput) const
+{
+
+  llvm::StringRef entry_name;
+  if (pLDInfo.options().hasEntry())
+    entry_name = pLDInfo.options().entry();
+  else
+    entry_name = pBackend.entry();
+  
+  uint64_t result = 0x0;
+
+  bool issue_warning = (pLDInfo.options().hasEntry()
+                       && (pOutput.type() != Output::Object)
+                       && (pOutput.type() != Output::DynObj));
+
+  const LDSymbol* entry_symbol = pLDInfo.getStrSymPool().findSymbol(entry_name);
+
+  // found the symbol
+  if (NULL != entry_symbol) {
+    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
+      llvm::errs() << "WARNING: entry symbol '"
+                   << entry_symbol->name()
+                   << "' exists but is not defined.\n";
+    }
+    result = entry_symbol->value();
+  }
+  // not in the symbol pool
+  else {
+    // We should parse entry as a number.
+    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
+    char* endptr;
+    result = strtoull(entry_name.data(), &endptr, 0);
+    if (*endptr != '\0') {
+      if (issue_warning) {
+        llvm::errs() << "cannot find entry symbol '"
+                     << entry_name.data()
+                     << "'.\n";
+      }
+      result = 0x0;
+    }
+  }
+  return result;
+}
+
+/// emitELF32SectionHeader - emit Elf32_Shdr
+void
+ELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const
+{
+  // emit section header
+  unsigned int sectNum = pOutput.context()->numOfSections();
+  unsigned int header_size = sizeof(Elf32_Shdr) * sectNum;
+  MemoryRegion* region = pOutput.memArea()->request(
+                                   getELF32LastStartOffset(pOutput),
+                                   header_size);
+  Elf32_Shdr* shdr = (Elf32_Shdr*)region->start();
+
+  // Iterate the SectionTable in LDContext
+  unsigned int sectIdx = 0;
+  unsigned int shstridx = 0; // NULL section has empty name
+  for (; sectIdx < sectNum; ++sectIdx) {
+    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
+    shdr[sectIdx].sh_name      = shstridx;
+    shdr[sectIdx].sh_type      = ld_sect->type();
+    shdr[sectIdx].sh_flags     = ld_sect->flag();
+    shdr[sectIdx].sh_addr      = ld_sect->addr();
+    shdr[sectIdx].sh_offset    = ld_sect->offset();
+    shdr[sectIdx].sh_size      = ld_sect->size();
+    shdr[sectIdx].sh_addralign = ld_sect->align();
+    shdr[sectIdx].sh_entsize   = getELF32SectEntrySize(*ld_sect);
+    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
+    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
+
+    // adjust strshidx
+    shstridx += ld_sect->name().size() + 1;
+  }
+}
+
+/// emitELF64SectionHeader - emit Elf64_Shdr
+void
+ELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const
+{
+  // emit section header
+  unsigned int sectNum = pOutput.context()->numOfSections();
+  unsigned int header_size = sizeof(Elf64_Shdr) * sectNum;
+  MemoryRegion* region = pOutput.memArea()->request(
+                                     getELF64LastStartOffset(pOutput),
+                                     header_size);
+  Elf64_Shdr* shdr = (Elf64_Shdr*)region->start();
+
+  // Iterate the SectionTable in LDContext
+  unsigned int sectIdx = 0;
+  unsigned int shstridx = 0; // NULL section has empty name
+  for (; sectIdx < sectNum; ++sectIdx) {
+    const LDSection *ld_sect = pOutput.context()->getSection(sectIdx);
+    shdr[sectIdx].sh_name      = shstridx;
+    shdr[sectIdx].sh_type      = ld_sect->type();
+    shdr[sectIdx].sh_flags     = ld_sect->flag();
+    shdr[sectIdx].sh_addr      = ld_sect->addr();
+    shdr[sectIdx].sh_offset    = ld_sect->offset();
+    shdr[sectIdx].sh_size      = ld_sect->size();
+    shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())?
+                                   ld_sect->getSectionData()->getAlignment():
+                                   0x0;
+
+    shdr[sectIdx].sh_entsize   = getELF64SectEntrySize(*ld_sect);
+    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pOutput);
+    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect, pOutput);
+
+    // adjust strshidx
+    shstridx += ld_sect->name().size() + 1;
+  }
+}
+
+/// emitELF32ShStrTab - emit section string table
+void ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const
+{
+  uint64_t shstroffset = getELF32LastStartOffset(pOutput);
+
+  // get shstrtab
+  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
+                                                         LDFileFormat::NamePool,
+                                                         SHT_STRTAB,
+                                                         0x0);
+  if (0 != shstrtab.size())
+    llvm::report_fatal_error(".shstrtab has been set.\n");
+
+  // compute size
+  unsigned int shstrsize = 0;
+  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
+  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
+    shstrsize += (*section)->name().size() + 1;
+  }
+
+  shstrtab.setSize(shstrsize);
+  shstrtab.setOffset(shstroffset);
+
+  // write out data
+  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
+                                                    shstrtab.size());
+  unsigned char* data = region->start();
+  shstrsize = 0;
+  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
+    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
+    shstrsize += (*section)->name().size() + 1;
+  }
+
+  shstrtab.setKind(LDFileFormat::NamePool);
+  shstrtab.setType(llvm::ELF::SHT_STRTAB);
+  shstrtab.setFlag(0x0);
+  shstrtab.setAddr(0x0);
+}
+
+
+/// emitELF64ShStrTab - emit section string table
+void ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const
+{
+  uint64_t shstroffset = getELF64LastStartOffset(pOutput);
+
+  // get shstrtab
+  LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab",
+                                                         LDFileFormat::NamePool,
+                                                         SHT_STRTAB,
+                                                         0x0);
+  if (0 != shstrtab.size())
+    llvm::report_fatal_error(".shstrtab has been set.\n");
+
+  // compute offset
+
+  // compute size
+  unsigned int shstrsize = 0;
+  LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd();
+  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
+    shstrsize += (*section)->name().size() + 1;
+  }
+
+  shstrtab.setSize(shstrsize);
+  shstrtab.setOffset(shstroffset);
+
+  // write out data
+  MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(),
+                                                    shstrtab.size());
+  unsigned char* data = region->start();
+  shstrsize = 0;
+  for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) {
+    strcpy((char*)(data + shstrsize), (*section)->name().c_str());
+    shstrsize += (*section)->name().size() + 1;
+  }
+
+  shstrtab.setKind(LDFileFormat::NamePool);
+  shstrtab.setType(llvm::ELF::SHT_STRTAB);
+  shstrtab.setFlag(0x0);
+  shstrtab.setAddr(0x0);
+}
+
+/// emitSectionData
+void
+ELFWriter::emitSectionData(const Layout& pLayout,
+                           const LDSection& pSection,
+                           MemoryRegion& pRegion) const
+{
+  const llvm::MCSectionData* data = pSection.getSectionData();
+  llvm::MCSectionData::const_iterator fragIter, fragEnd = data->end();
+  size_t cur_offset = 0;
+  for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) {
+    size_t size = computeFragmentSize(pLayout, *fragIter);
+    switch(fragIter->getKind()) {
+      case llvm::MCFragment::FT_Region: {
+        const MCRegionFragment& region_frag = llvm::cast<MCRegionFragment>(*fragIter);
+        const uint8_t* from = region_frag.getRegion().start();
+        memcpy(pRegion.getBuffer(cur_offset), from, size);
+        break;
+      }
+      case llvm::MCFragment::FT_Align: {
+        // TODO: emit values with different sizes (> 1 byte), and emit nops
+        llvm::MCAlignFragment& align_frag = llvm::cast<llvm::MCAlignFragment>(*fragIter);
+        uint64_t count = size / align_frag.getValueSize();
+        switch (align_frag.getValueSize()) {
+          case 1u:
+            std::memset(pRegion.getBuffer(cur_offset),
+                        align_frag.getValue(),
+                        count);
+            break;
+          default:
+            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
+            break;
+        }
+        break;
+      }
+      case llvm::MCFragment::FT_Fill: {
+        llvm::MCFillFragment& fill_frag = llvm::cast<llvm::MCFillFragment>(*fragIter);
+        if (0 == size ||
+            0 == fill_frag.getValueSize() ||
+            0 == fill_frag.getSize()) {
+          // ignore virtual fillment
+          break;
+        }
+
+        uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize();
+        for (uint64_t i = 0; i != num_tiles; ++i) {
+          std::memset(pRegion.getBuffer(cur_offset),
+                      fill_frag.getValue(),
+                      fill_frag.getValueSize());
+        }
+        break;
+      }
+      case llvm::MCFragment::FT_Data:
+      case llvm::MCFragment::FT_Inst:
+      case llvm::MCFragment::FT_Org:
+      case llvm::MCFragment::FT_Dwarf:
+      case llvm::MCFragment::FT_DwarfFrame:
+      case llvm::MCFragment::FT_LEB: {
+        llvm::report_fatal_error("unsupported fragment yet.\n");
+        break;
+      }
+      case llvm::MCFragment::FT_Reloc:
+        llvm::report_fatal_error("relocation fragment should not be in a regular section.\n");
+        break;
+      case llvm::MCFragment::FT_Target:
+        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
+        break;
+      default:
+        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
+        break;
+    }
+    cur_offset += size;
+  }
+}
+
+/// emitRelocation
+void ELFWriter::emitRelocation(const Layout& pLayout,
+                               const Output& pOutput,
+                               const LDSection& pSection,
+                               MemoryRegion& pRegion) const
+{
+  const llvm::MCSectionData* SectionData = pSection.getSectionData();
+  assert(SectionData && "SectionData is NULL in emitRelocation!");
+
+  if (pSection.type() == SHT_REL)
+    emitRel(pLayout, pOutput, *SectionData, pRegion);
+  else if (pSection.type() == SHT_RELA)
+    emitRela(pLayout, pOutput, *SectionData, pRegion);
+  else
+    llvm::report_fatal_error("unsupported relocation section type!");
+}
+
+
+/// emitRel
+void ELFWriter::emitRel(const Layout& pLayout,
+                        const Output& pOutput,
+                        const llvm::MCSectionData& pSectionData,
+                        MemoryRegion& pRegion) const
+{
+  Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start());
+
+  Relocation* relocation = 0;
+  MCFragmentRef* FragmentRef = 0;
+
+  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
+       ie = pSectionData.end(); it != ie; ++it, ++rel) {
+
+    relocation = &(llvm::cast<Relocation>(*it));
+    FragmentRef = &(relocation->targetRef());
+
+    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
+      rel->r_offset = static_cast<Elf32_Addr>(
+                      llvm::cast<LDSection>(
+                      FragmentRef->frag()->getParent()->getSection()).addr() +
+                      pLayout.getOutputOffset(*FragmentRef));
+    }
+    else {
+      rel->r_offset = static_cast<Elf32_Addr>(
+                      llvm::cast<LDSection>(
+                      FragmentRef->frag()->getParent()->getSection()).offset() +
+                      pLayout.getOutputOffset(*FragmentRef));
+    }
+
+    Elf32_Word Index;
+    if( relocation->symInfo() == NULL )
+      Index = 0;
+    else
+      Index = static_cast<Elf32_Word>(
+              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
+
+    rel->setSymbolAndType(Index, relocation->type());
+  }
+}
+
+/// emitRela
+void ELFWriter::emitRela(const Layout& pLayout,
+                         const Output& pOutput,
+                         const llvm::MCSectionData& pSectionData,
+                         MemoryRegion& pRegion) const
+{
+  Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start());
+
+  Relocation* relocation = 0;
+  MCFragmentRef* FragmentRef = 0;
+
+  for (llvm::MCSectionData::const_iterator it = pSectionData.begin(),
+       ie = pSectionData.end(); it != ie; ++it, ++rel) {
+
+    relocation = &(llvm::cast<Relocation>(*it));
+    FragmentRef = &(relocation->targetRef());
+
+    if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) {
+      rel->r_offset = static_cast<Elf32_Addr>(
+                      llvm::cast<LDSection>(
+                      FragmentRef->frag()->getParent()->getSection()).addr() +
+                      pLayout.getOutputOffset(*FragmentRef));
+    }
+    else {
+      rel->r_offset = static_cast<Elf32_Addr>(
+                      llvm::cast<LDSection>(
+                      FragmentRef->frag()->getParent()->getSection()).offset() +
+                      pLayout.getOutputOffset(*FragmentRef));
+    }
+
+    Elf32_Word Index;
+    if( relocation->symInfo() == NULL )
+      Index = 0;
+    else
+      Index = static_cast<Elf32_Word>(
+              f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol()));
+
+    rel->setSymbolAndType(Index, relocation->type());
+    rel->r_addend = relocation->addend();
+  }
+}
+
+/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize
+uint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const
+{
+  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
+      llvm::ELF::SHT_SYMTAB == pSection.type())
+    return sizeof(llvm::ELF::Elf32_Sym);
+  if (llvm::ELF::SHT_REL == pSection.type())
+    return sizeof(llvm::ELF::Elf32_Rel);
+  if (llvm::ELF::SHT_RELA == pSection.type())
+    return sizeof(llvm::ELF::Elf32_Rela);
+  if (llvm::ELF::SHT_HASH == pSection.type())
+    return sizeof(llvm::ELF::Elf32_Word);
+  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
+    return sizeof(llvm::ELF::Elf32_Dyn);
+  return 0x0;
+}
+
+/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize
+uint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const
+{
+  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
+      llvm::ELF::SHT_SYMTAB == pSection.type())
+    return sizeof(llvm::ELF::Elf64_Sym);
+  if (llvm::ELF::SHT_REL == pSection.type())
+    return sizeof(llvm::ELF::Elf64_Rel);
+  if (llvm::ELF::SHT_RELA == pSection.type())
+    return sizeof(llvm::ELF::Elf64_Rela);
+  if (llvm::ELF::SHT_HASH == pSection.type())
+    return sizeof(llvm::ELF::Elf64_Word);
+  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
+    return sizeof(llvm::ELF::Elf64_Dyn);
+  return 0x0;
+}
+
+/// getSectLink - compute ElfXX_Shdr::sh_link
+uint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const
+{
+  const LDContext* context = pOutput.context();
+  if (llvm::ELF::SHT_SYMTAB == pSection.type())
+    return context->getSectionIdx(".strtab");
+  if (llvm::ELF::SHT_DYNSYM == pSection.type())
+    return context->getSectionIdx(".dynstr");
+  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
+    return context->getSectionIdx(".dynstr");
+  if (llvm::ELF::SHT_HASH == pSection.type())
+    return context->getSectionIdx(".dynsym");
+  if (llvm::ELF::SHT_REL == pSection.type() ||
+      llvm::ELF::SHT_RELA == pSection.type()) {
+    if (pOutput.type() == Output::Object)
+      return context->getSectionIdx(".symtab");
+    else
+      return context->getSectionIdx(".dynsym");
+  }
+  return llvm::ELF::SHN_UNDEF;
+}
+
+/// getSectInfo - compute ElfXX_Shdr::sh_info
+uint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const
+{
+  const LDSection* info_link = pSection.getLink();
+  if (NULL == info_link)
+    return 0x0;
+  return info_link->index();
+}
+
+/// getELF32LastStartOffset
+uint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const
+{
+  LDSection* lastSect = pOutput.context()->getSectionTable().back();
+  assert(lastSect != NULL);
+  return Align<32>(lastSect->offset() + lastSect->size());
+}
+
+/// getELF64LastStartOffset
+uint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const
+{
+  LDSection* lastSect = pOutput.context()->getSectionTable().back();
+  assert(lastSect != NULL);
+  return Align<64>(lastSect->offset() + lastSect->size());
+}
+
diff --git a/lib/LD/GNUArchiveReader.cpp b/lib/LD/GNUArchiveReader.cpp
new file mode 100644
index 0000000..3fa00b8
--- /dev/null
+++ b/lib/LD/GNUArchiveReader.cpp
@@ -0,0 +1,356 @@
+//===- GNUArchiveReader.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInfo.h"
+#include "mcld/MC/MCLDInput.h"
+#include "mcld/MC/MCLDInputTree.h"
+#include "mcld/LD/GNUArchiveReader.h"
+
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Support/system_error.h>
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <cstdlib>
+
+using namespace std;
+using namespace mcld;
+
+typedef size_t sectionSizeTy;
+typedef uint32_t elfWord;
+
+/// Archive Header, Magic number, etc..
+
+const unsigned archiveMagicSize = 8;
+const char archiveMagic[archiveMagicSize] = { '!', '<', 'a', 'r', 'c', 'h', '>', '\n' };
+const char thinArchiveMagic[archiveMagicSize] = { '!', '<', 't', 'h', 'i', 'n', '>', '\n' };
+const char archiveFinalMagic[2] = { '`', '\n' };
+
+struct GNUArchiveReader::ArchiveMemberHeader
+{
+  char name[16];
+  char date[12];
+  char uid[6];
+  char gid[6];
+  char mode[8];
+  char size[10];
+  char finalMagic[2];
+};
+
+struct GNUArchiveReader::SymbolTableEntry
+{
+  off_t fileOffset;
+  std::string name;
+};
+
+inline void endian_swap(unsigned int& x)
+{
+  x = (x>>24) |
+      ((x<<8) & 0x00FF0000) |
+      ((x>>8) & 0x0000FF00) |
+      (x<<24);
+}
+
+
+/// convert string to size_t
+template<class Type>
+Type stringToType(const std::string &str)
+{
+  Type n;
+  std::stringstream ss(str);
+  ss >> n;
+  return n;
+}
+
+
+/// GNUArchiveReader Operations
+/// Public API
+bool GNUArchiveReader::isMyFormat(Input &pInput) const
+{
+  llvm::OwningPtr<llvm::MemoryBuffer> mapFile;
+  llvm::MemoryBuffer::getFile(pInput.path().c_str(), mapFile);
+  const char* pFile = mapFile->getBufferStart();
+
+  /// check archive format.
+  if(mapFile->getBufferSize() <= archiveMagicSize)
+    return false;
+  bool isThinArchive = memcmp(pFile, thinArchiveMagic, archiveMagicSize) == 0;
+  if(!isThinArchive && memcmp(pFile, archiveMagic, archiveMagicSize) != 0)
+    return false;
+  return true;
+}
+
+LDReader::Endian GNUArchiveReader::endian(Input& pFile) const
+{
+  return m_endian;
+}
+
+InputTree *GNUArchiveReader::readArchive(Input &pInput)
+{
+  return setupNewArchive(pInput, 0);
+}
+
+/// Read Input as archive. First create a null InputTree.
+/// Then Construct Input object for corresponding member of this archive
+/// and insert the Input object into the InputTree.
+/// Finally, return the InputTree.
+InputTree *GNUArchiveReader::setupNewArchive(Input &pInput,
+                                            size_t off)
+{
+  llvm::OwningPtr<llvm::MemoryBuffer> mapFile;
+  if(llvm::MemoryBuffer::getFile(pInput.path().c_str(), mapFile))
+  {
+    assert(0 && "GNUArchiveReader:can't map a file to MemoryBuffer\n");
+    return NULL;
+  }
+
+  InputTree *resultTree = new InputTree(m_pLDInfo.inputFactory());
+  std::vector<SymbolTableEntry> symbolTable;
+  std::string archiveMemberName;
+  std::string extendedName;
+  bool isThinArchive;
+  const char *pFile = mapFile->getBufferStart();
+
+  /// check archive format.
+  if(mapFile->getBufferSize() <= archiveMagicSize)
+    return NULL;
+  else
+  {
+    isThinArchive = memcmp(pFile, thinArchiveMagic, archiveMagicSize) == 0;
+    if(!isThinArchive && memcmp(pFile, archiveMagic, archiveMagicSize) != 0)
+      return NULL;
+  }
+
+  off += archiveMagicSize ;
+  size_t symbolTableSize = parseMemberHeader(mapFile, off, &archiveMemberName,
+                                            NULL, extendedName);
+  /// read archive symbol table
+  if(archiveMemberName.empty())
+  {
+    readSymbolTable(mapFile, symbolTable,
+                    off+sizeof(GNUArchiveReader::ArchiveMemberHeader), symbolTableSize);
+    off = off + sizeof(GNUArchiveReader::ArchiveMemberHeader) + symbolTableSize;
+  }
+  else
+  {
+    assert(0 && "fatal error : need symbol table\n");
+    return NULL;
+  }
+
+  if((off&1) != 0)
+    ++off;
+
+  size_t extendedSize = parseMemberHeader(mapFile, off, &archiveMemberName,
+                                          NULL, extendedName);
+  /// read long Name table if exist
+  if(archiveMemberName == "/")
+  {
+    off += sizeof(GNUArchiveReader::ArchiveMemberHeader);
+    pFile += off;
+    extendedName.assign(pFile,extendedSize);
+  }
+
+  /// traverse all the archive members
+  InputTree::iterator node = resultTree->root();
+  set<string> haveSeen;
+  for(unsigned i=0 ; i<symbolTable.size() ; ++i)
+  {
+    /// We shall get each member at this archive.
+    /// Construct a corresponding mcld::Input, and insert it into
+    /// the original InputTree, resultTree.
+    off_t nestedOff = 0;
+
+    parseMemberHeader(mapFile, symbolTable[i].fileOffset, &archiveMemberName,
+                      &nestedOff, extendedName);
+
+    if(haveSeen.find(archiveMemberName)==haveSeen.end())
+      haveSeen.insert(archiveMemberName);
+    else
+      continue;
+
+    if(!isThinArchive)
+    {
+      /// New a Input object and assign fileOffset in MCLDFile.
+      /// Insert the object to resultTree and move ahead.
+      off_t fileOffset = symbolTable[i].fileOffset + sizeof(ArchiveMemberHeader);
+      Input *insertObjectFile = m_pLDInfo.inputFactory().produce(archiveMemberName,
+                                                                 pInput.path(),
+                                                                 MCLDFile::Object,
+                                                                 fileOffset);
+      resultTree->insert<InputTree::Positional>(node, *insertObjectFile);
+      if(i==0)
+        node.move<InputTree::Inclusive>();
+      else
+        node.move<InputTree::Positional>();
+
+      continue;
+    }
+
+    /// create the real path
+    sys::fs::RealPath realPath(archiveMemberName);
+    if(nestedOff > 0)
+    {
+      /// This is a member of a nested archive.
+      /// Create an Input for this archive ,and recursive call setupNewArchive
+      /// Finally, merge the new InputTree with the old one
+      Input *newArchive = m_pLDInfo.inputFactory().produce(archiveMemberName,
+                                                           realPath,
+                                                           MCLDFile::Archive,
+                                                           0);
+
+      resultTree->insert<InputTree::Positional>(node, *newArchive);
+      if(i==0)
+        node.move<InputTree::Inclusive>();
+      else
+        node.move<InputTree::Positional>();
+      InputTree *newArchiveTree = setupNewArchive(*newArchive, 0);
+      resultTree->merge<InputTree::Inclusive>(node, *newArchiveTree);
+      continue;
+    }
+    /// External member , open it as normal object file
+    /// add new Input to InputTree
+    Input *insertObjectFile = m_pLDInfo.inputFactory().produce(archiveMemberName,
+                                                               realPath,
+                                                               MCLDFile::Object,
+                                                               0);
+    resultTree->insert<InputTree::Positional>(node, *insertObjectFile);
+    if(i==0)
+      node.move<InputTree::Inclusive>();
+    else
+      node.move<InputTree::Positional>();
+  }
+  return resultTree;
+}
+
+
+/// Parse the member header and return the size of member
+/// Archive member names in System 5 style :
+///
+/// "/                  " - symbol table, must be the first member
+/// "//                 " - long name table
+/// "filename.o/        " - regular file with short name
+/// "/5566              " - name at offset 5566 at long name table
+
+size_t GNUArchiveReader::parseMemberHeader(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                                           off_t off,
+                                           std::string *p_Name,
+                                           off_t *p_NestedOff,
+                                           std::string &p_ExtendedName)
+{
+  const char *pFile = mapFile->getBufferStart();
+  pFile += off;
+  const ArchiveMemberHeader *header = reinterpret_cast<const ArchiveMemberHeader *>(pFile);
+
+  /// check magic number of member header
+  if(memcmp(header->finalMagic, archiveFinalMagic, sizeof archiveFinalMagic))
+  {
+    assert(0 && "archive member header magic number false");
+    return 0;
+  }
+
+  /// evaluate member size
+  std::string sizeString(header->size, sizeof(header->size)+1);
+  size_t memberSize = stringToType<size_t>(sizeString);
+  if(memberSize == 0)
+  {
+    assert(0 && "member Size Error");
+    return 0;
+  }
+
+  if(header->name[0] != '/')
+  {
+    /// This is a regular file with short name
+    const char* nameEnd = strchr(header->name, '/');
+    size_t nameLen = ((nameEnd == NULL) ? 0 : (nameEnd - header->name));
+    if((nameLen <= 0) || (nameLen >= sizeof(header->name)))
+    {
+      assert(0 && "header name format error\n");
+      return 0;
+    }
+    p_Name->assign(header->name, nameLen);
+
+    if(!p_NestedOff)
+      p_NestedOff = 0;
+  }
+  else if(header->name[1] == ' ')
+  {
+    /// This is symbol table
+    if(!p_Name->empty())
+      p_Name->clear();
+  }
+  else if(header->name[1] == '/')
+  {
+    /// This is long name table
+    p_Name->assign(1,'/');
+  }
+  else
+  {
+    /// This is regular file with long name
+    char *end;
+    long extendedNameOff = strtol(header->name+1, &end, 10);
+    long nestedOff = 0;
+    if(*end == ':')
+      nestedOff = strtol(end+1, &end, 10);
+
+    if(*end != ' '
+       || extendedNameOff < 0
+       || static_cast<size_t>(extendedNameOff) >= p_ExtendedName.size())
+    {
+      assert(0 && "extended name");
+      return 0;
+    }
+
+    const char *name = p_ExtendedName.data() + extendedNameOff;
+    const char *nameEnd = strchr(name, '\n');
+    if(nameEnd[-1] != '/'
+       || static_cast<size_t>(nameEnd-name) > p_ExtendedName.size())
+    {
+      assert(0 && "p_ExtendedName substring is not end with / \n");
+      return 0;
+    }
+    p_Name->assign(name, nameEnd-name-1);
+    if(p_NestedOff)
+     *p_NestedOff = nestedOff;
+  }
+
+  return memberSize;
+}
+
+void GNUArchiveReader::readSymbolTable(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                                       std::vector<SymbolTableEntry> &pSymbolTable,
+                                       off_t start,
+                                       size_t size)
+{
+  const char *startPtr = mapFile->getBufferStart() + start;
+  const elfWord *p_Word = reinterpret_cast<const elfWord *>(startPtr);
+  unsigned int symbolNum = *p_Word;
+
+  /// Portable Issue on Sparc platform
+  /// Intel, ARM and Mips are littel-endian , Sparc is little-endian after verion 9
+  /// symbolNum in symbol table is always big-endian
+  if(m_endian == LDReader::LittleEndian)
+    endian_swap(symbolNum);
+  ++p_Word;
+
+  const char *p_Name = reinterpret_cast<const char *>(p_Word + symbolNum);
+
+  pSymbolTable.resize(symbolNum);
+  for(unsigned int i=0 ; i<symbolNum ; ++i)
+  {
+    /// assign member offset
+    unsigned int memberOffset = *p_Word;
+    endian_swap(memberOffset);
+    pSymbolTable[i].fileOffset = static_cast<off_t>(memberOffset);
+    ++p_Word;
+    /// assign member name
+    off_t nameEnd = strlen(p_Name) + 1;
+    pSymbolTable[i].name.assign(p_Name, nameEnd);
+    p_Name += nameEnd;
+  }
+}
diff --git a/lib/LD/InputSymbolTable.cpp b/lib/LD/InputSymbolTable.cpp
new file mode 100644
index 0000000..e34679c
--- /dev/null
+++ b/lib/LD/InputSymbolTable.cpp
@@ -0,0 +1,48 @@
+//===- InputSymbolTable.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/InputSymbolTable.h"
+#include <vector>
+
+using namespace mcld;
+
+//==========================
+// InputSymbolTable
+
+InputSymbolTable::InputSymbolTable(StrSymPool &pStrSymPool,
+                                   size_t pNumOfSymbols,
+                                   StringTable &pEntireStringTable,
+                                   StringTable &pDynamicStringTable)
+  : SymbolTableIF(pStrSymPool)
+{
+  f_StrSymPool.addIndirectClient(*this);
+
+  f_pCategorySet->at(CategorySet::Entire).reserve(pNumOfSymbols);
+
+  f_pCategorySet->at(CategorySet::Entire).interpose(&pEntireStringTable);
+  f_pCategorySet->at(CategorySet::Dynamic).interpose(&pDynamicStringTable);
+}
+
+void InputSymbolTable::doInsertSymbol(LDSymbol *pSym)
+{
+  f_pCategorySet->insertSymbolPointer(pSym);
+}
+
+void InputSymbolTable::doMerge(const SymbolTableIF &pSymTab)
+{
+  if (this == &pSymTab)
+     return;
+  for (size_t i = 0; i < CategorySet::NumOfCategories; ++i)
+    f_pCategorySet->at(i).insert(f_pCategorySet->at(i).end(),
+                                 pSymTab.begin(i),
+                                 pSymTab.end(i));
+}
+
+InputSymbolTable::~InputSymbolTable()
+{
+}
diff --git a/lib/LD/LDContext.cpp b/lib/LD/LDContext.cpp
new file mode 100644
index 0000000..f6556f3
--- /dev/null
+++ b/lib/LD/LDContext.cpp
@@ -0,0 +1,103 @@
+//===- LDContext.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDSymbol.h>
+#include <llvm/ADT/StringRef.h>
+
+using namespace mcld;
+
+//==========================
+// LDReader
+LDContext::LDContext()
+{
+}
+
+LDContext::~LDContext()
+{
+}
+
+LDSection* LDContext::getSection(unsigned int pIdx)
+{
+  if (pIdx >= m_SectionTable.size())
+    return NULL;
+  return m_SectionTable[pIdx];
+}
+
+const LDSection* LDContext::getSection(unsigned int pIdx) const
+{
+  if (pIdx >= m_SectionTable.size())
+    return NULL;
+  return m_SectionTable[pIdx];
+}
+
+LDSection* LDContext::getSection(const std::string& pName)
+{
+  sect_iterator sect_iter, sect_end = sectEnd();
+  for (sect_iter = sectBegin(); sect_iter != sect_end; ++sect_iter) {
+    if(NULL != *sect_iter && (*sect_iter)->name() == pName)
+      return *sect_iter;
+  }
+  return NULL;
+}
+
+const LDSection* LDContext::getSection(const std::string& pName) const
+{
+  const_sect_iterator sect_iter, sect_end = sectEnd();
+  for (sect_iter = sectBegin(); sect_iter != sect_end; ++sect_iter) {
+    if(NULL != *sect_iter && (*sect_iter)->name() == pName)
+      return *sect_iter;
+  }
+  return NULL;
+}
+
+size_t LDContext::getSectionIdx(const std::string& pName) const
+{
+  size_t result = 1;
+  size_t size = m_SectionTable.size();
+  for (; result != size; ++result)
+    if (m_SectionTable[result]->name() == pName)
+      return result;
+  return 0;
+}
+
+LDSymbol* LDContext::getSymbol(unsigned int pIdx)
+{
+  if (pIdx >= m_SymTab.size())
+    return NULL;
+  return m_SymTab[pIdx];
+}
+
+const LDSymbol* LDContext::getSymbol(unsigned int pIdx) const
+{
+  if (pIdx >= m_SymTab.size())
+    return NULL;
+  return m_SymTab[pIdx];
+}
+
+
+LDSymbol* LDContext::getSymbol(const llvm::StringRef& pName)
+{
+  size_t sym = 1;
+  size_t size = m_SymTab.size();
+  for (; sym < size; ++sym)
+    if (m_SymTab[sym]->name() == pName)
+      return m_SymTab[sym];
+  return NULL;
+}
+
+const LDSymbol* LDContext::getSymbol(const llvm::StringRef& pName) const
+{
+  size_t sym = 1;
+  size_t size = m_SymTab.size();
+  for (; sym < size; ++sym)
+    if (m_SymTab[sym]->name() == pName)
+      return m_SymTab[sym];
+  return NULL;
+}
diff --git a/lib/LD/LDFileFormat.cpp b/lib/LD/LDFileFormat.cpp
new file mode 100644
index 0000000..c1ddb52
--- /dev/null
+++ b/lib/LD/LDFileFormat.cpp
@@ -0,0 +1,32 @@
+//===- LDFileFormat.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/MC/MCLinker.h>
+
+using namespace mcld;
+
+//==========================
+// LDFileInfo
+LDFileFormat::LDFileFormat()
+  : f_pTextSection(NULL),
+    f_pDataSection(NULL),
+    f_pBSSSection(NULL),
+    f_pReadOnlySection(NULL) {
+}
+
+LDFileFormat::~LDFileFormat()
+{
+}
+
+void LDFileFormat::initStdSections(MCLinker& pLinker)
+{
+  initObjectFormat(pLinker);
+  initObjectType(pLinker);
+}
+
diff --git a/lib/LD/LDObjectWriter.cpp b/lib/LD/LDObjectWriter.cpp
new file mode 100644
index 0000000..d08c6a7
--- /dev/null
+++ b/lib/LD/LDObjectWriter.cpp
@@ -0,0 +1,23 @@
+//===- LDObjectWriter.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCObjectWriter.h"
+
+using namespace mcld;
+
+//==========================
+// MCObjectWriter
+
+
+MCObjectWriter::MCObjectWriter() 
+{
+}
+
+MCObjectWriter::~MCObjectWriter() 
+{
+}
diff --git a/lib/LD/LDReader.cpp b/lib/LD/LDReader.cpp
new file mode 100644
index 0000000..b74fc68
--- /dev/null
+++ b/lib/LD/LDReader.cpp
@@ -0,0 +1,14 @@
+//===- LDReader.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDReader.h>
+
+using namespace mcld;
+
+//==========================
+// LDReader
diff --git a/lib/LD/LDSection.cpp b/lib/LD/LDSection.cpp
new file mode 100644
index 0000000..1ec9c13
--- /dev/null
+++ b/lib/LD/LDSection.cpp
@@ -0,0 +1,35 @@
+//===- LDSection.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDSection.h>
+#include <llvm/MC/SectionKind.h>
+
+using namespace mcld;
+
+LDSection::LDSection(const std::string& pName,
+                     LDFileFormat::Kind pKind,
+                     uint32_t pType,
+                     uint32_t pFlag,
+                     uint64_t pSize,
+                     uint64_t pOffset,
+                     uint64_t pAddr)
+  : llvm::MCSection(llvm::MCSection::SV_LDContext, llvm::SectionKind::getMetadata()),
+    m_Name(pName),
+    m_Kind(pKind),
+    m_Type(pType),
+    m_Flag(pFlag),
+    m_Size(pSize),
+    m_Offset(pOffset),
+    m_Addr(pAddr),
+    m_Align(0),
+    m_Info(0),
+    m_pLink(NULL),
+    m_pSectionData(NULL),
+    m_Index(0) {
+}
+
diff --git a/lib/LD/LDSectionFactory.cpp b/lib/LD/LDSectionFactory.cpp
new file mode 100644
index 0000000..a81c839
--- /dev/null
+++ b/lib/LD/LDSectionFactory.cpp
@@ -0,0 +1,49 @@
+//===- LDSectionFactory.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDSectionFactory.h>
+
+using namespace mcld;
+
+//==========================
+// LDSectionFactory
+LDSectionFactory::LDSectionFactory(size_t pNum)
+  : GCFactory<LDSection, 0>(pNum) {
+}
+
+LDSectionFactory::~LDSectionFactory()
+{
+}
+
+LDSection* LDSectionFactory::produce(const std::string& pName,
+                                   LDFileFormat::Kind pKind,
+                                   uint32_t pType,
+                                   uint32_t pFlag)
+{
+  // create a LDSection
+  LDSection* result = allocate();
+  new (result) LDSection(pName, pKind, pType, pFlag);
+  return result;
+}
+
+void LDSectionFactory::destroy(LDSection*& pSection)
+{
+  // do not recycle LDSection. HeaderFactory will do that job.
+  deallocate(pSection);
+}
+
+LDSection* LDSectionFactory::find(const std::string& pName)
+{
+  iterator sect_iter, sect_end = end();
+  for (sect_iter = begin(); sect_iter != sect_end; ++sect_iter)
+    if ((*sect_iter).name() == pName)
+      break;
+  if (sect_iter == sect_end)
+    return NULL;
+  return &(*sect_iter);
+}
diff --git a/lib/LD/LDSymbol.cpp b/lib/LD/LDSymbol.cpp
new file mode 100644
index 0000000..f26e052
--- /dev/null
+++ b/lib/LD/LDSymbol.cpp
@@ -0,0 +1,45 @@
+//===- LDSymbol.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/LDSymbol.h"
+#include <cstring>
+
+using namespace mcld;
+
+LDSymbol::LDSymbol()
+  : m_pResolveInfo(NULL), m_pFragRef(NULL), m_Value(0) {
+}
+
+LDSymbol::~LDSymbol()
+{
+}
+
+LDSymbol::LDSymbol(const LDSymbol& pCopy)
+  : m_pResolveInfo(pCopy.m_pResolveInfo),
+    m_pFragRef(pCopy.m_pFragRef),
+    m_Value(pCopy.m_Value) {
+}
+
+LDSymbol& LDSymbol::operator=(const LDSymbol& pCopy)
+{
+  m_pResolveInfo = pCopy.m_pResolveInfo;
+  m_pFragRef = pCopy.m_pFragRef;
+  m_Value = pCopy.m_Value;
+  return (*this);
+}
+
+void LDSymbol::setFragmentRef(MCFragmentRef* pFragmentRef)
+{
+  m_pFragRef = pFragmentRef;
+}
+
+void LDSymbol::setResolveInfo(const ResolveInfo& pInfo)
+{
+  m_pResolveInfo = const_cast<ResolveInfo*>(&pInfo);
+}
+
diff --git a/lib/LD/LDWriter.cpp b/lib/LD/LDWriter.cpp
new file mode 100644
index 0000000..e78f087
--- /dev/null
+++ b/lib/LD/LDWriter.cpp
@@ -0,0 +1,15 @@
+//===- LDWriter.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/LDWriter.h"
+
+using namespace mcld;
+
+//==========================
+// LDReader
+
diff --git a/lib/LD/Layout.cpp b/lib/LD/Layout.cpp
new file mode 100644
index 0000000..9328d74
--- /dev/null
+++ b/lib/LD/Layout.cpp
@@ -0,0 +1,671 @@
+//===- Layout.cpp ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <cassert>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// Range
+Layout::Range::Range()
+  : header(NULL),
+    prevRear(NULL) {
+}
+
+Layout::Range::Range(const LDSection& pHdr)
+  : header(const_cast<LDSection*>(&pHdr)),
+    prevRear(NULL) {
+}
+
+Layout::Range::~Range()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// Layout
+Layout::Layout()
+  : m_FragRefFactory(32) /** magic number **/ {
+}
+
+Layout::~Layout()
+{
+}
+
+void Layout::setFragmentLayoutOrder(llvm::MCFragment* pFrag)
+{
+  if (NULL == pFrag)
+    return;
+  // compute the most-recent fragment whose order was set.
+  llvm::MCFragment* first = pFrag;
+
+  while (!hasLayoutOrder(*first)) {
+    if (NULL == first->getPrevNode())
+      break;
+    first = first->getPrevNode();
+  }
+
+  // set all layout order
+  unsigned int layout_order = 0;
+  llvm::MCFragment* frag_not_set = NULL;
+
+  if (NULL == first->getPrevNode()) {
+    layout_order = 0;
+    frag_not_set = first;
+  }
+  else {
+    layout_order = first->getLayoutOrder();
+    frag_not_set = first->getNextNode();
+  }
+
+  // set up all layout order
+  while(NULL != frag_not_set) {
+    frag_not_set->setLayoutOrder(layout_order);
+    ++layout_order;
+    frag_not_set = frag_not_set->getNextNode();
+  }
+}
+
+/// setFragmentLayoutOffset - set the fragment's layout offset. This function
+/// also set up the layout offsets of all the fragments in the same range.
+/// If the offset of the fragment was set before, return immediately.
+void Layout::setFragmentLayoutOffset(llvm::MCFragment* pFrag)
+{
+  if (NULL == pFrag)
+    return;
+  // compute the most-recent fragment whose offset was set.
+  llvm::MCFragment* first = pFrag;
+
+  while (!hasLayoutOffset(*first)) {
+    if (NULL == first->getPrevNode())
+      break;
+    first = first->getPrevNode();
+  }
+
+  // set all layout order
+  uint64_t offset = 0;
+  llvm::MCFragment* frag_not_set = NULL;
+  if (NULL == first->getPrevNode()) {
+    offset = 0;
+    frag_not_set = first;
+  }
+  else {
+    offset = first->Offset;
+    offset += computeFragmentSize(*this, *first);
+    frag_not_set = first->getNextNode();
+  }
+
+  while(NULL != frag_not_set) {
+    frag_not_set->Offset = offset;
+    offset += computeFragmentSize(*this, *frag_not_set);
+    frag_not_set = frag_not_set->getNextNode();
+  }
+}
+
+/// addInputRange
+///   1. add a new range <pInputHdr, previous rear fragment>
+///   2. compute the layout order of all previous ranges.
+void Layout::addInputRange(const llvm::MCSectionData& pSD,
+                           const LDSection& pInputHdr)
+{
+  RangeList* range_list = NULL;
+
+  // get or create the range_list
+  if (pSD.getFragmentList().empty() || 0 == m_SDRangeMap.count(&pSD)) {
+    range_list = new RangeList();
+    m_SDRangeMap[&pSD] = range_list;
+  }
+  else {
+    range_list = m_SDRangeMap[&pSD];
+#ifdef MCLD_DEBUG
+    RangeList::iterator rangeIter, rangeEnd = range_list->end();
+    for (rangeIter = range_list->begin(); rangeIter != rangeEnd; ++rangeIter) {
+      if (&pInputHdr == rangeIter->header) {
+        llvm::report_fatal_error(llvm::Twine("Trying to map the same LDSection: ") +
+                                 pInputHdr.name() +
+                                 llvm::Twine(" into the different ranges.\n"));
+      }
+    }
+#endif
+  }
+
+  // make a range and push it into the range list
+  Range* range = new Range(pInputHdr);
+  range_list->push_back(range);
+
+  // set up previous rear of the range.
+  // FIXME: in current design, we can not add a range before finishing adding
+  // fragments in the previous range. If the limitation keeps, we can set
+  // prevRear to the last fragment in the MCSectionData simply.
+  //
+  // if the pSD's fragment list is empty, the range.prevRear keeps NULL.
+  if (!pSD.getFragmentList().empty()) {
+    range->prevRear =
+                  const_cast<llvm::MCFragment*>(&pSD.getFragmentList().back());
+  }
+
+  // compute the layout order of the previous range.
+  if (!isFirstRange(*range)) {
+    setFragmentLayoutOrder(range->prevRear);
+    setFragmentLayoutOffset(range->prevRear);
+  }
+}
+
+/// appendFragment - append the given MCFragment to the given MCSectionData,
+/// and insert a MCAlignFragment to preserve the required align constraint if
+/// needed
+uint64_t Layout::appendFragment(llvm::MCFragment& pFrag,
+                                llvm::MCSectionData& pSD,
+                                uint32_t pAlignConstraint)
+{
+  // insert MCAlignFragment into MCSectionData first if needed
+  llvm::MCAlignFragment* align_frag = NULL;
+  if (pAlignConstraint > 1) {
+    align_frag = new llvm::MCAlignFragment(pAlignConstraint, // alignment
+                                           0x0, // the filled value
+                                           1u,  // the size of filled value
+                                           pAlignConstraint - 1, // max bytes to emit
+                                           &pSD);
+  }
+
+  // append the fragment to the MCSectionData
+  pFrag.setParent(&pSD);
+  pSD.getFragmentList().push_back(&pFrag);
+
+  // update the alignment of associated output LDSection if needed
+  LDSection* output_sect = getOutputLDSection(pFrag);
+  assert(NULL != output_sect);
+  if (pAlignConstraint > output_sect->align())
+    output_sect->setAlign(pAlignConstraint);
+
+  // compute the fragment order and offset
+  setFragmentLayoutOrder(&pFrag);
+  setFragmentLayoutOffset(&pFrag);
+
+  if (NULL != align_frag)
+    return pFrag.Offset - align_frag->Offset + computeFragmentSize(*this, pFrag);
+  else
+    return computeFragmentSize(*this, pFrag);
+}
+
+/// getInputLDSection - give a MCFragment, return the corresponding input
+/// LDSection*
+LDSection*
+Layout::getInputLDSection(const llvm::MCFragment& pFrag)
+{
+  const llvm::MCSectionData* sect_data = pFrag.getParent();
+  // check the MCSectionData
+  if (NULL == sect_data) {
+    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
+                             llvm::Twine(" any MCSectionData.\n"));
+  }
+
+  // check the MCSectionData's range list
+  if (0 == m_SDRangeMap.count(sect_data)) {
+    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
+                             llvm::Twine("the input's MCSectionData is not ") +
+                             llvm::Twine("registered in the Layout.\nPlease ") +
+                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
+                             llvm::Twine("to get input's MCSectionData.\n"));
+  }
+
+  RangeList* range_list = m_SDRangeMap[sect_data];
+  // the fragment who has the layout order is not in the last range.
+  if (hasLayoutOrder(pFrag)) {
+    Range range = range_list->back();
+    if (isFirstRange(range)) {
+      return range.header;
+    }
+    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
+      if (NULL != range.getPrevNode())
+        range = *range.getPrevNode();
+      else
+        return NULL;
+    }
+    return range.header;
+  }
+  // the fragment who has no layout order should be in the last range
+  else {
+    if (range_list->empty())
+      return NULL;
+    return range_list->back().header;
+  }
+}
+
+/// getInputLDSection - give a MCFragment, return the corresponding input
+/// LDSection*
+const LDSection*
+Layout::getInputLDSection(const llvm::MCFragment& pFrag) const
+{
+  const llvm::MCSectionData* sect_data = pFrag.getParent();
+  // check the MCSectionData
+  if (NULL == sect_data) {
+    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
+                             llvm::Twine(" any MCSectionData.\n"));
+  }
+
+  // check the MCSectionData's range list
+  if (0 == m_SDRangeMap.count(sect_data)) {
+    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
+                             llvm::Twine("the input's MCSectionData is not ") +
+                             llvm::Twine("registered in the Layout.\nPlease ") +
+                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
+                             llvm::Twine("to get input's MCSectionData.\n"));
+  }
+
+  SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data);
+  const RangeList* range_list = range_list_iter->second;
+  // the fragment who has the layout order is not in the last range.
+  if (hasLayoutOrder(pFrag)) {
+    Range range = range_list->back();
+    if (isFirstRange(range)) {
+      return range.header;
+    }
+    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
+      if (NULL != range.getPrevNode())
+        range = *range.getPrevNode();
+      else
+        return NULL;
+    }
+    return range.header;
+  }
+  // the fragment who has no layout order should be in the last range
+  else {
+    if (range_list->empty())
+      return NULL;
+    return range_list->back().header;
+  }
+}
+
+/// getOutputLDSection
+LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag)
+{
+  llvm::MCSectionData* sect_data = pFrag.getParent();
+  if (NULL == sect_data)
+    return NULL;
+
+  return const_cast<LDSection*>(llvm::cast<LDSection>(&sect_data->getSection()));
+}
+
+/// getOutputLDSection
+const LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag) const
+{
+  const llvm::MCSectionData* sect_data = pFrag.getParent();
+  if (NULL == sect_data)
+    return NULL;
+
+  return llvm::cast<LDSection>(&sect_data->getSection());
+}
+
+/// getFragmentRef - assume the ragne exist, find the fragment reference
+MCFragmentRef*
+Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
+{
+  if (isEmptyRange(pRange))
+    return NULL;
+
+  llvm::MCFragment* front = getFront(pRange);
+  if (NULL == front)
+    return NULL;
+
+  llvm::MCFragment* rear = getRear(pRange);
+  if (NULL == rear)
+    return NULL;
+
+  return getFragmentRef(*front, *rear, pOffset);
+}
+
+// @param pFront is the first fragment in the range.
+// @param pRear is the last fragment in the range.
+// @pOffset is the offset started from pFront.
+MCFragmentRef*
+Layout::getFragmentRef(llvm::MCFragment& pFront,
+                       llvm::MCFragment& pRear,
+                       uint64_t pOffset)
+{
+  llvm::MCFragment* front = &pFront;
+  llvm::MCFragment* rear  = &pRear;
+
+  if (!hasLayoutOffset(*rear)) {
+    // compute layout order, offset
+    setFragmentLayoutOrder(rear);
+    setFragmentLayoutOffset(rear);
+  }
+
+  // compute the offset from overall start fragment.
+  uint64_t target_offset = pFront.Offset + pOffset;
+
+  // from front to rear, find the offset which is as large as possible
+  // but smaller than the target_offset.
+  while (front != rear) {
+    if (llvm::MCFragment::FT_Align == front->getKind()) {
+      // alignment fragments were not counted in target_offset.
+      // Count in the size of alignment fragmen in target_offset here.
+      uint64_t align_size = 0x0;
+      if (NULL == front->getNextNode()) {
+        // If the alignment fragment is the last fragment, increase
+        // the target_offset by the alignment fragment's size.
+        align_size = computeFragmentSize(*this, *front);
+      }
+      else {
+        // If the alignment fragment is not the last fragment, the alignment
+        // fragment's size is the distance between the two fragment.
+        align_size = front->getNextNode()->Offset - front->Offset;
+      }
+      target_offset += align_size;
+      front = front->getNextNode();
+      continue;
+    }
+
+    if (target_offset >= front->getNextNode()->Offset) {
+      front = front->getNextNode();
+    }
+    else {
+      // found
+      MCFragmentRef* result = m_FragRefFactory.allocate();
+      new (result) MCFragmentRef(*front, target_offset - front->Offset);
+      return result;
+    }
+  }
+
+  if (front == rear) {
+    if (llvm::MCFragment::FT_Align == front->getKind())
+      return NULL;
+
+    if (!isValidOffset(*front, target_offset))
+      return NULL;
+
+    MCFragmentRef* result = m_FragRefFactory.allocate();
+    new (result) MCFragmentRef(*front, target_offset - front->Offset);
+    return result;
+  }
+  return NULL;
+}
+
+/// getFragmentRef - give a LDSection in input file and an offset, return
+/// the fragment reference.
+MCFragmentRef*
+Layout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset)
+{
+  // find out which SectionData covers the range of input section header
+  const llvm::MCSectionData* sect_data = pInputSection.getSectionData();
+
+  // check range list
+  if (0 == m_SDRangeMap.count(sect_data))
+    return NULL;
+
+  if (sect_data->getFragmentList().empty())
+    return NULL;
+
+  RangeList* range_list = m_SDRangeMap[sect_data];
+
+  // find out the specific part in SectionData range
+  RangeList::iterator range, rangeEnd = range_list->end();
+  for (range = range_list->begin(); range != rangeEnd; ++range) {
+    // found the range
+    if (&pInputSection == range->header) {
+      break;
+    }
+  }
+
+  // range not found
+  if (range == rangeEnd) {
+    llvm::report_fatal_error(llvm::Twine("section ") +
+                             pInputSection.name() +
+                             llvm::Twine(" never be in the range list.\n"));
+  }
+
+  return getFragmentRef(*range, pOffset);
+}
+
+/// getFragmentRef - give a fragment and a big offset, return the fragment
+/// reference in the section data.
+///
+/// @param pFrag - the given fragment
+/// @param pBigOffset - the offset, can be larger than the fragment, but can
+///                     not larger than this input section.
+/// @return if found, return the fragment. Otherwise, return NULL.
+MCFragmentRef*
+Layout::getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset)
+{
+  if (!hasLayoutOffset(pFrag)) {
+    // compute layout order, offset
+    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
+    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
+  }
+
+  // find out which SectionData covers the range of input section header
+  const llvm::MCSectionData* sect_data = pFrag.getParent();
+
+  // check range list
+  if (0 == m_SDRangeMap.count(sect_data)) {
+    llvm::report_fatal_error(llvm::Twine("MCSectionData has no") +
+                             llvm::Twine(" correponding range list.\n"));
+  }
+
+  if (sect_data->getFragmentList().empty())
+    return NULL;
+
+  RangeList* range_list = m_SDRangeMap[sect_data];
+
+  // find out the specific part in SectionData range
+  uint64_t target_offset = pBigOffset + pFrag.Offset;
+
+  RangeList::iterator range, rangeEnd = range_list->end();
+  for (range = range_list->begin(); range != rangeEnd; ++range) {
+    if (isEmptyRange(*range))
+      continue;
+    if (getRear(*range)->Offset >= target_offset) {
+      break;
+    }
+  }
+
+  // range not found
+  if (range == rangeEnd) {
+    llvm::report_fatal_error(llvm::Twine("the offset is too big that") +
+                             llvm::Twine(" never be in the range list.\n"));
+  }
+
+  return getFragmentRef(*range, target_offset);
+}
+
+uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag)
+{
+  if (!hasLayoutOffset(pFrag)) {
+    // compute layout order, offset
+    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
+    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
+  }
+  return pFrag.Offset;
+}
+
+uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag) const
+{
+  if (!hasLayoutOffset(pFrag)) {
+    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
+                             llvm::Twine("the function ") +
+                             llvm::Twine(__func__) +
+                             llvm::Twine(" can not be used before layout().\n"));
+  }
+  return pFrag.Offset;
+}
+
+uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef)
+{
+  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
+}
+
+uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef) const
+{
+  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
+}
+
+void Layout::sortSectionOrder(const Output& pOutput,
+                              const TargetLDBackend& pBackend)
+{
+  typedef std::pair<LDSection*, unsigned int> SectOrder;
+  typedef std::vector<SectOrder > SectListTy;
+  SectListTy sect_list;
+  // get section order from backend
+  for (size_t index = 0; index < m_SectionOrder.size(); ++index)
+    sect_list.push_back(std::make_pair(
+                    m_SectionOrder[index],
+                    pBackend.getSectionOrder(pOutput, *m_SectionOrder[index])));
+
+  // simple insertion sort should be fine for general cases such as so and exec
+  for (unsigned int i = 1; i < sect_list.size(); ++i) {
+    SectOrder order = sect_list[i];
+    int j = i - 1;
+    while (j >= 0 && sect_list[j].second > order.second) {
+      sect_list[j + 1] = sect_list[j];
+      --j;
+    }
+    sect_list[j + 1] = order;
+  }
+
+  // update the sorted ordering to m_SectionOrder
+  m_SectionOrder.clear();
+  for (size_t index = 0; index < sect_list.size(); ++index) {
+    m_SectionOrder.push_back(sect_list[index].first);
+  }
+}
+
+bool Layout::layout(Output& pOutput, const TargetLDBackend& pBackend)
+{
+  // determine what sections in output context will go into final output, and
+  // push the needed sections into m_SectionOrder for later processing
+  assert(pOutput.hasContext());
+  LDContext& output_context = *pOutput.context();
+  LDContext::sect_iterator it, itEnd = output_context.sectEnd();
+  for (it = output_context.sectBegin(); it != itEnd; ++it) {
+    LDSection* sect = *it;
+
+    switch (sect->kind()) {
+      // ignore if there is no SectionData for certain section kinds
+      case LDFileFormat::Regular:
+      case LDFileFormat::Note:
+      case LDFileFormat::Target:
+      case LDFileFormat::MetaData:
+      case LDFileFormat::BSS:
+        if (0 != sect->size()) {
+          if (NULL != sect->getSectionData() &&
+              !sect->getSectionData()->getFragmentList().empty()) {
+            // make sure that all fragments are valid
+            llvm::MCFragment& frag =
+              sect->getSectionData()->getFragmentList().back();
+            setFragmentLayoutOrder(&frag);
+            setFragmentLayoutOffset(&frag);
+          }
+          m_SectionOrder.push_back(sect);
+        }
+        break;
+      // take NULL directly
+      case LDFileFormat::Null:
+        m_SectionOrder.push_back(sect);
+        break;
+      // ignore if section size is 0
+      case LDFileFormat::NamePool:
+      case LDFileFormat::Relocation:
+        if (0 != sect->size())
+          m_SectionOrder.push_back(sect);
+        break;
+      case LDFileFormat::Group:
+        if (MCLDFile::Object == pOutput.type()) {
+          //TODO: support incremental linking
+          ;
+        }
+        break;
+      case LDFileFormat::Debug:
+        if (0 != sect->size()) {
+          m_SectionOrder.push_back(sect);
+          llvm::errs() << "WARNING: DWRAF debugging has not been fully supported yet.\n"
+                       << "section `" << sect->name() << "'.\n";
+        }
+        break;
+      case LDFileFormat::Exception:
+        if (0 != sect->size()) {
+          llvm::errs() << "WARNING: Exception handling has not been fully supported yet.\n"
+                       << "section `" << sect->name() << "'.\n";
+          if (NULL != sect->getSectionData() &&
+              !sect->getSectionData()->getFragmentList().empty()) {
+            // make sure that all fragments are valid
+            llvm::MCFragment& frag =
+              sect->getSectionData()->getFragmentList().back();
+            setFragmentLayoutOrder(&frag);
+            setFragmentLayoutOffset(&frag);
+          }
+          m_SectionOrder.push_back(sect);
+        }
+        break;
+      case LDFileFormat::Version:
+        if (0 != sect->size()) {
+          m_SectionOrder.push_back(sect);
+          llvm::errs() << "WARNING: Symbolic versioning has not been fully supported yet.\n"
+                       << "section `" << sect->name() << "'.\n";
+        }
+        break;
+      default:
+        llvm::report_fatal_error(llvm::Twine("Unsupported section kind of `") +
+                                 sect->name() +
+                                 llvm::Twine("': ") +
+                                 llvm::Twine(sect->kind()) +
+                                 llvm::Twine(".\n"));
+        break;
+    }
+  }
+
+  // perform sorting on m_SectionOrder to get a ordering for final layout
+  sortSectionOrder(pOutput, pBackend);
+
+  // Backend defines the section start offset for section 1.
+  uint64_t offset = pBackend.sectionStartOffset();
+  // compute the section offset and handle alignment also. And ignore section 0
+  // (NULL in ELF/COFF), and MachO starts from section 1.
+  for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
+    // we should not preserve file space for the BSS section.
+    if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind())
+      offset += m_SectionOrder[index - 1]->size();
+
+    alignAddress(offset, m_SectionOrder[index]->align());
+
+    m_SectionOrder[index]->setOffset(offset);
+  }
+
+  // FIXME: Currently Writer bases on the section table in output context to
+  // write out sections, so we have to update its content..
+  output_context.getSectionTable().clear();
+  for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
+    output_context.getSectionTable().push_back(m_SectionOrder[index]);
+    // after sorting, update the correct output section indices
+    m_SectionOrder[index]->setIndex(index);
+  }
+  return true;
+}
+
+bool Layout::isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const
+{
+  uint64_t size = computeFragmentSize(*this, pFrag);
+  if (0x0 == size)
+    return (pTargetOffset == pFrag.Offset);
+
+  if (NULL != pFrag.getNextNode())
+    return (pTargetOffset >= pFrag.Offset && pTargetOffset < pFrag.getNextNode()->Offset);
+
+  return (pTargetOffset >= pFrag.Offset && pTargetOffset < (pFrag.Offset + size));
+}
+
diff --git a/lib/LD/ObjectWriter.cpp b/lib/LD/ObjectWriter.cpp
new file mode 100644
index 0000000..15691f2
--- /dev/null
+++ b/lib/LD/ObjectWriter.cpp
@@ -0,0 +1,24 @@
+//===- ObjectWriter.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/ObjectWriter.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Target/GNULDBackend.h>
+
+using namespace mcld;
+
+//==========================
+// ObjectWriter
+ObjectWriter::ObjectWriter(GNULDBackend& pBackend)
+{
+}
+
+ObjectWriter::~ObjectWriter()
+{
+}
+
diff --git a/lib/LD/OutputSymbolTable.cpp b/lib/LD/OutputSymbolTable.cpp
new file mode 100644
index 0000000..a17a211
--- /dev/null
+++ b/lib/LD/OutputSymbolTable.cpp
@@ -0,0 +1,41 @@
+//===- OutputSymbolTable.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/OutputSymbolTable.h"
+
+using namespace mcld;
+
+//==========================
+// OutputSymbolTable
+
+
+OutputSymbolTable::OutputSymbolTable(StrSymPool &pStrSymPool,
+                                     size_t pNumOfSymbols,
+                                     StringTable &pEntireStringTable,
+                                     StringTable &pDynamicStringTable)
+  : SymbolTableIF(pStrSymPool)
+{
+  f_StrSymPool.addDirectClient(*this);
+
+  f_pCategorySet->at(CategorySet::Entire).reserve(pNumOfSymbols);
+
+  f_pCategorySet->at(CategorySet::Entire).interpose(&pEntireStringTable);
+  f_pCategorySet->at(CategorySet::Dynamic).interpose(&pDynamicStringTable);
+}
+
+void OutputSymbolTable::doInsertSymbol(LDSymbol *sym)
+{
+  // OutputSymbolTable didn't have any real containers,
+  // so no need to do anything.
+}
+
+void OutputSymbolTable::doMerge(const SymbolTableIF &pSymTab)
+{
+  // OutputSymbolTable didn't have any real containers,
+  // so no need to do anything.
+}
diff --git a/lib/LD/Relocation.cpp b/lib/LD/Relocation.cpp
new file mode 100644
index 0000000..73db39b
--- /dev/null
+++ b/lib/LD/Relocation.cpp
@@ -0,0 +1,81 @@
+//===- Relocation.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/MC/MCAssembler.h>
+//#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/Relocation.h>
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/LD/Layout.h>
+
+using namespace mcld;
+
+Relocation::Relocation(Relocation::Type pType,
+                       MCFragmentRef* pTargetRef,
+                       Relocation::Address pAddend,
+                       Relocation::DWord pTargetData)
+  : MCFragment(llvm::MCFragment::FT_Reloc),
+    m_Type(pType),
+    m_TargetData(pTargetData),
+    m_pSymInfo(NULL),
+    m_Addend(pAddend)
+{
+  if(NULL != pTargetRef)
+     m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ;
+}
+
+Relocation::~Relocation()
+{
+}
+
+Relocation::Address Relocation::place(const Layout& pLayout) const
+{
+  Address sect_addr = pLayout.getOutputLDSection(*(m_TargetAddress.frag()))->addr();
+  return sect_addr + pLayout.getOutputOffset(m_TargetAddress);
+}
+
+Relocation::Address Relocation::symValue() const
+{
+  if(m_pSymInfo->type() == ResolveInfo::Section &&
+     m_pSymInfo->outSymbol()->hasFragRef()) {
+    return llvm::cast<LDSection>(
+      m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection()).addr();
+  }
+  return m_pSymInfo->outSymbol()->value();
+}
+
+void Relocation::apply(RelocationFactory& pRelocFactory,
+                       const MCLDInfo& pLDInfo)
+{
+  pRelocFactory.applyRelocation(*this, pLDInfo);
+}
+
+void Relocation::setType(Type pType)
+{
+  m_Type = pType;
+}
+
+void Relocation::setAddend(Address pAddend)
+{
+  m_Addend = pAddend;
+}
+
+void Relocation::setSymInfo(ResolveInfo* pSym)
+{
+  m_pSymInfo = pSym;
+}
+
+Relocation::DWord& Relocation::target()
+{
+  return m_TargetData;
+}
+
+const Relocation::DWord& Relocation::target() const
+{
+  return m_TargetData;
+}
+
diff --git a/lib/LD/RelocationFactory.cpp b/lib/LD/RelocationFactory.cpp
new file mode 100644
index 0000000..2bcfeb3
--- /dev/null
+++ b/lib/LD/RelocationFactory.cpp
@@ -0,0 +1,91 @@
+//===- RelocationFactory.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/Target/GOT.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <llvm/Support/Host.h>
+#include <cstring>
+#include <cassert>
+
+using namespace mcld;
+
+//==========================
+// RelocationFactory
+RelocationFactory::RelocationFactory(size_t pNum)
+  : GCFactory<Relocation, 0>(pNum),
+    m_pLayout(NULL) {
+}
+
+RelocationFactory::~RelocationFactory()
+{
+}
+
+Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
+                                       MCFragmentRef& pFragRef,
+                                       Address pAddend)
+{
+  // target_data is the place where the relocation applys to.
+  // Use TargetDataFactory to generate temporary data, and copy the
+  // content of the fragment into this data.
+  DWord target_data = 0;
+
+  // byte swapping if the host and target have different endian
+  if(llvm::sys::isLittleEndianHost() != getTarget().isLittleEndian()) {
+     uint32_t tmp_data;
+
+     switch(getTarget().bitclass()) {
+      case 32u:
+        pFragRef.memcpy(&tmp_data, 4);
+        tmp_data = bswap32(tmp_data);
+        target_data = tmp_data;
+        break;
+
+      case 64u:
+        pFragRef.memcpy(&target_data, 8);
+        target_data = bswap64(target_data);
+        break;
+
+      default:
+        break;
+    }
+  }
+  else {
+    pFragRef.memcpy(&target_data, (getTarget().bitclass()/8));
+  }
+
+  Relocation *result = allocate();
+  new (result) Relocation(pType, &pFragRef, pAddend, target_data);
+  return result;
+}
+
+Relocation* RelocationFactory::produceEmptyEntry()
+{
+  // FIXME: To prevent relocations from double free by both iplist and
+  // GCFactory, currently we new relocations directly and let iplist
+  // delete them.
+
+  return new Relocation(0, 0, 0, 0);
+}
+
+void RelocationFactory::destroy(Relocation* pRelocation)
+{
+   /** GCFactory will recycle the relocation **/
+}
+
+void RelocationFactory::setLayout(const Layout& pLayout)
+{
+  m_pLayout = &pLayout;
+}
+
+const Layout& RelocationFactory::getLayout() const
+{
+  assert(0 != m_pLayout);
+  return *m_pLayout;
+}
+
diff --git a/lib/LD/ResolveInfo.cpp b/lib/LD/ResolveInfo.cpp
new file mode 100644
index 0000000..b931d19
--- /dev/null
+++ b/lib/LD/ResolveInfo.cpp
@@ -0,0 +1,228 @@
+//===- ResolveInfo.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/ResolveInfo.h"
+#include <cstring>
+
+using namespace mcld;
+
+//==========================
+// ResolveInfo
+ResolveInfo::ResolveInfo()
+  : m_Size(0), m_BitField(0) {
+  m_Ptr.sym_ptr = 0;
+}
+
+ResolveInfo::~ResolveInfo()
+{
+}
+
+void ResolveInfo::override(const ResolveInfo& pFrom)
+{
+  m_Size = pFrom.m_Size;
+  overrideAttributes(pFrom);
+  overrideVisibility(pFrom);
+}
+
+void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
+{
+  m_BitField &= ~RESOLVE_MASK;
+  m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
+}
+
+/// overrideVisibility - override the visibility
+///   always use the most strict visibility
+void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
+{
+  // Reference: Google gold linker: resolve.cc
+  //
+  // The rule for combining visibility is that we always choose the
+  // most constrained visibility.  In order of increasing constraint,
+  // visibility goes PROTECTED, HIDDEN, INTERNAL.  This is the reverse
+  // of the numeric values, so the effect is that we always want the
+  // smallest non-zero value.
+  //
+  // enum {
+  //   STV_DEFAULT = 0,
+  //   STV_INTERNAL = 1,
+  //   STV_HIDDEN = 2,
+  //   STV_PROTECTED = 3
+  // };
+
+  Visibility from_vis = pFrom.visibility();
+  Visibility cur_vis = visibility();
+  if (0 != from_vis ) {
+    if (0 == cur_vis)
+      setVisibility(from_vis);
+    else if (cur_vis > from_vis)
+      setVisibility(from_vis);
+  }
+}
+
+void ResolveInfo::setRegular()
+{
+  m_BitField &= (~dynamic_flag);
+}
+
+void ResolveInfo::setDynamic()
+{
+  m_BitField |= dynamic_flag;
+}
+
+void ResolveInfo::setSource(bool pIsDyn)
+{
+  if (pIsDyn)
+    m_BitField |= dynamic_flag;
+  else
+    m_BitField &= (~dynamic_flag);
+}
+
+void ResolveInfo::setType(uint32_t pType)
+{
+  m_BitField &= ~TYPE_MASK;
+  m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
+}
+
+void ResolveInfo::setDesc(uint32_t pDesc)
+{
+  m_BitField &= ~DESC_MASK;
+  m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
+}
+
+void ResolveInfo::setBinding(uint32_t pBinding)
+{
+  m_BitField &= ~BINDING_MASK;
+  if (pBinding == Local || pBinding == Absolute)
+    m_BitField |= local_flag;
+  if (pBinding == Weak || pBinding == Absolute)
+    m_BitField |= weak_flag;
+}
+
+void ResolveInfo::setReserved(uint32_t pReserved)
+{
+  m_BitField &= ~RESERVED_MASK;
+  m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
+}
+
+void ResolveInfo::setOther(uint32_t pOther)
+{
+  setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
+}
+
+void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
+{
+  m_BitField &= ~VISIBILITY_MASK;
+  m_BitField |= pVisibility << VISIBILITY_OFFSET;
+}
+
+void ResolveInfo::setIsSymbol(bool pIsSymbol)
+{
+  if (pIsSymbol)
+    m_BitField |= symbol_flag;
+  else
+    m_BitField &= ~symbol_flag;
+}
+
+bool ResolveInfo::isDyn() const
+{
+  return (dynamic_flag == (m_BitField & DYN_MASK));
+}
+
+bool ResolveInfo::isUndef() const
+{
+  return (undefine_flag == (m_BitField & DESC_MASK));
+}
+
+bool ResolveInfo::isDefine() const
+{
+  return (define_flag == (m_BitField & DESC_MASK));
+}
+
+bool ResolveInfo::isCommon() const
+{
+  return (common_flag == (m_BitField & DESC_MASK));
+}
+
+bool ResolveInfo::isIndirect() const
+{
+  return (indirect_flag == (m_BitField & DESC_MASK));
+}
+
+// isGlobal - [L,W] == [0, 0]
+bool ResolveInfo::isGlobal() const
+{
+  return (global_flag == (m_BitField & BINDING_MASK));
+}
+
+// isWeak - [L,W] == [0, 1]
+bool ResolveInfo::isWeak() const
+{
+  return (weak_flag == (m_BitField & BINDING_MASK));
+}
+
+// isLocal - [L,W] == [1, 0]
+bool ResolveInfo::isLocal() const
+{
+  return (local_flag == (m_BitField & BINDING_MASK));
+}
+
+// isAbsolute - [L,W] == [1, 1]
+bool ResolveInfo::isAbsolute() const
+{
+  return (absolute_flag == (m_BitField & BINDING_MASK));
+}
+
+bool ResolveInfo::isSymbol() const
+{
+  return (symbol_flag == (m_BitField & SYMBOL_MASK));
+}
+
+bool ResolveInfo::isString() const
+{
+  return (string_flag == (m_BitField & SYMBOL_MASK));
+}
+
+uint32_t ResolveInfo::type() const
+{
+  return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
+}
+
+uint32_t ResolveInfo::desc() const
+{
+  return (m_BitField & DESC_MASK) >> DESC_OFFSET;
+}
+
+uint32_t ResolveInfo::binding() const
+{
+  if (m_BitField & LOCAL_MASK) {
+    if (m_BitField & GLOBAL_MASK) {
+      return ResolveInfo::Absolute;
+    }
+    return ResolveInfo::Local;
+  }
+  return m_BitField & GLOBAL_MASK;
+}
+
+uint32_t ResolveInfo::reserved() const
+{
+  return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
+}
+
+ResolveInfo::Visibility ResolveInfo::visibility() const
+{
+  return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
+}
+
+bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
+{
+  size_t length = nameSize();
+  if (length != pKey.size())
+    return false;
+  return (0 == std::memcmp(m_Name, pKey.data(), length));
+}
+
diff --git a/lib/LD/ResolveInfoFactory.cpp b/lib/LD/ResolveInfoFactory.cpp
new file mode 100644
index 0000000..feb52a3
--- /dev/null
+++ b/lib/LD/ResolveInfoFactory.cpp
@@ -0,0 +1,40 @@
+//===- ResolveInfoFactory.cpp ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/ResolveInfoFactory.h"
+#include <cstring>
+#include <cstdlib>
+
+using namespace mcld;
+
+//==========================
+// ResolveInfoFactory
+ResolveInfoFactory::entry_type*
+ResolveInfoFactory::produce(const ResolveInfoFactory::key_type& pKey)
+{
+  entry_type* result = static_cast<entry_type*>(
+                                    malloc(sizeof(entry_type)+pKey.size()+1));
+  if (NULL == result)
+    return NULL;
+
+  new (result) entry_type();
+  std::memcpy(result->m_Name, pKey.data(), pKey.size());
+  result->m_Name[pKey.size()] = '\0';
+  result->m_BitField &= ~ResolveInfo::RESOLVE_MASK;
+  result->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET);
+  return result;
+}
+
+void ResolveInfoFactory::destroy(ResolveInfoFactory::entry_type* pEntry)
+{
+  if (NULL != pEntry) {
+    pEntry->~entry_type();
+    free(pEntry);
+  }
+}
+
diff --git a/lib/LD/Resolver.cpp b/lib/LD/Resolver.cpp
new file mode 100644
index 0000000..0f7f06e
--- /dev/null
+++ b/lib/LD/Resolver.cpp
@@ -0,0 +1,33 @@
+//===- Resolver.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/Resolver.h"
+#include <cassert>
+
+using namespace mcld;
+
+//==========================
+// Resolver
+Resolver::Resolver()
+  : m_Mesg() {
+}
+
+Resolver::Resolver(const Resolver& pCopy)
+  : m_Mesg(pCopy.m_Mesg) {
+}
+
+Resolver::~Resolver()
+{
+  m_Mesg.clear();
+}
+
+void Resolver::clearMesg()
+{
+  m_Mesg.clear();
+}
+
diff --git a/lib/LD/SectionMap.cpp b/lib/LD/SectionMap.cpp
new file mode 100644
index 0000000..d81dfdd
--- /dev/null
+++ b/lib/LD/SectionMap.cpp
@@ -0,0 +1,142 @@
+//===- SectionMap.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <cassert>
+#include <cstring>
+#include <mcld/LD/SectionMap.h>
+
+using namespace mcld;
+
+//==========================
+// SectionMap
+
+SectionMap::SectionMap()
+{
+}
+
+SectionMap::~SectionMap()
+{
+}
+
+const std::string& SectionMap::getOutputSectName(const std::string& pInput)
+{
+  iterator it;
+  for (it = begin(); it != end(); ++it) {
+    if (0 == strncmp(pInput.c_str(),
+                     (*it).inputSubStr.c_str(),
+                     (*it).inputSubStr.length()))
+      break;
+    // wildcard to a user-defined output section.
+    else if (0 == strcmp("*", (*it).inputSubStr.c_str()))
+      break;
+  }
+  // if still no matching, just let a output seciton has the same input name
+  if (it == end())
+    return pInput;
+  
+  return (*it).outputStr;
+}
+
+bool SectionMap::push_back(const std::string& pInput,
+                           const std::string& pOutput,
+                           const uint64_t pOffset)
+{
+  // Now only check if the mapping exists in the map already
+  // TODO: handle the cases such as overriding the exist mapping and drawing
+  //       exception from the given SECTIONS command
+  iterator it;
+  for (it = begin(); it != end(); ++it) {
+    if (pInput == (*it).inputSubStr)
+      return false;
+  }
+  struct Mapping mapping = {
+    pInput,
+    pOutput,
+    pOffset,
+  };
+  m_SectMap.push_back(mapping);
+  return true;
+}
+
+SectionMap::iterator SectionMap::find(const std::string& pInput)
+{
+  iterator it;
+  for (it = begin(); it != end(); ++it) {
+    if(pInput == (*it).inputSubStr)
+      break;
+  }
+  return it;
+}
+
+SectionMap::Mapping* SectionMap::at(const std::string& pInput)
+{
+  iterator it;
+  for (it = begin(); it != end(); ++it) {
+    if(pInput == (*it).inputSubStr)
+      break;
+  }
+  if (end() == it)
+    return NULL;
+  return &(*it);
+}
+
+// Common mappings of ELF and other formants. Now only ELF specific mappings are added
+const SectionMap::SectionNameMapping SectionMap::m_StdSectionMap[] =
+{
+  {".text", ".text"},
+  {".rodata", ".rodata"},
+  {".data.rel.ro.local", ".data.rel.ro.local"},
+  {".data.rel.ro", ".data.rel.ro"},
+  {".data", ".data"},
+  {".bss", ".bss"},
+  {".tdata", ".tdata"},
+  {".tbss", ".tbss"},
+  {".init_array", ".init_array"},
+  {".fini_array", ".fini_array"},
+  // TODO: Support DT_INIT_ARRAY for all constructors?
+  {".ctors", ".ctors"},
+  {".dtors", ".dtors"},
+  {".sdata", ".sdata"},
+  {".sbss", ".sbss"},
+  // FIXME: in GNU ld, if we are creating a shared object .sdata2 and .sbss2
+  // sections would be handled differently.
+  {".sdata2", ".sdata"},
+  {".sbss2", ".sbss"},
+  {".lrodata", ".lrodata"},
+  {".ldata", ".ldata"},
+  {".lbss", ".lbss"},
+  {".gcc_except_table", ".gcc_except_table"},
+  {".gnu.linkonce.d.rel.ro.local", ".data.rel.ro.local"},
+  {".gnu.linkonce.d.rel.ro", ".data.rel.ro"},
+  {".gnu.linkonce.t", ".text"},
+  {".gnu.linkonce.r", ".rodata"},
+  {".gnu.linkonce.d", ".data"},
+  {".gnu.linkonce.b", ".bss"},
+  {".gnu.linkonce.s", ".sdata"},
+  {".gnu.linkonce.sb", ".sbss"},
+  {".gnu.linkonce.s2", ".sdata"},
+  {".gnu.linkonce.sb2", ".sbss"},
+  {".gnu.linkonce.wi", ".debug_info"},
+  {".gnu.linkonce.td", ".tdata"},
+  {".gnu.linkonce.tb", ".tbss"},
+  {".gnu.linkonce.lr", ".lrodata"},
+  {".gnu.linkonce.l", ".ldata"},
+  {".gnu.linkonce.lb", ".lbss"},
+};
+
+const int SectionMap::m_StdSectionMapSize =
+  (sizeof(SectionMap::m_StdSectionMap) / sizeof(SectionMap::m_StdSectionMap[0]));
+
+bool SectionMap::initStdSectionMap()
+{
+  for (int i = 0; i < m_StdSectionMapSize; ++i) {
+    if (!push_back(m_StdSectionMap[i].from, m_StdSectionMap[i].to))
+      return false;
+  }
+  return true;
+}
diff --git a/lib/LD/SectionMerger.cpp b/lib/LD/SectionMerger.cpp
new file mode 100644
index 0000000..f6aef9e
--- /dev/null
+++ b/lib/LD/SectionMerger.cpp
@@ -0,0 +1,93 @@
+//===- SectionMerger.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <cassert>
+#include <cstring>
+#include <mcld/LD/SectionMerger.h>
+
+using namespace mcld;
+
+//==========================
+// SectionMerger
+
+SectionMerger::SectionMerger(SectionMap& pSectionMap, LDContext& pContext)
+: m_SectionNameMap(pSectionMap),
+  m_Output(pContext),
+  m_LDSectionMap(pSectionMap.size())
+{
+}
+
+SectionMerger::~SectionMerger()
+{
+}
+
+SectionMerger::iterator SectionMerger::find(const std::string& pName)
+{
+  if (empty())
+    initOutputSectMap();
+
+  iterator it;
+  for (it = begin(); it != end(); ++it) {
+    if (0 == strncmp(pName.c_str(),
+                     (*it).inputSubStr.c_str(),
+                     (*it).inputSubStr.length()))
+      break;
+    // wildcard to a user-defined output section.
+    else if(0 == strcmp("*", (*it).inputSubStr.c_str()))
+      break;
+  }
+  return it;
+}
+
+LDSection* SectionMerger::getOutputSectHdr(const std::string& pName)
+{
+  LDSection* section;
+  iterator it = find(pName);
+
+  // check if we can find a matched LDSection.
+  // If not, we need to find it in output context. But this should be rare.
+  if (it != end())
+    section = (*it).outputSection;
+  else
+    section = m_Output.getSection(pName);
+
+  assert(NULL != section);
+  return section;
+}
+
+llvm::MCSectionData* SectionMerger::getOutputSectData(const std::string& pName)
+{
+  return getOutputSectHdr(pName)->getSectionData();
+}
+
+bool SectionMerger::addMapping(const std::string& pName, LDSection* pSection)
+{
+  iterator it = find(pName);
+  if (it != end()) {
+    assert(NULL == (*it).outputSection);
+    (*it).outputSection = pSection;
+    return true;
+  }
+  // the mapping rule is not in SectionMap, and this is handled in getOutputSectHdr.
+  return false;
+}
+
+void SectionMerger::initOutputSectMap()
+{
+  // Based on SectionMap to initialize the map from a input substr to its 
+  // associated output LDSection*
+  SectionMap::iterator it;
+  for (it = m_SectionNameMap.begin(); it != m_SectionNameMap.end(); ++it) {
+    struct Mapping mapping = {
+      (*it).inputSubStr,
+      NULL,
+    };
+    m_LDSectionMap.push_back(mapping);
+  }
+  assert(m_SectionNameMap.size() == m_LDSectionMap.size());
+}
diff --git a/lib/LD/StaticResolver.cpp b/lib/LD/StaticResolver.cpp
new file mode 100644
index 0000000..3ba49e2
--- /dev/null
+++ b/lib/LD/StaticResolver.cpp
@@ -0,0 +1,230 @@
+//===- StaticResolver.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/StaticResolver.h>
+#include <mcld/LD/LDSymbol.h>
+#include <cassert>
+
+using namespace mcld;
+
+
+//==========================
+// StaticResolver
+StaticResolver::StaticResolver()
+{
+}
+
+StaticResolver::~StaticResolver()
+{
+}
+
+StaticResolver::StaticResolver(const StaticResolver& pCopy)
+  : Resolver(pCopy) {
+}
+
+unsigned int StaticResolver::resolve(ResolveInfo& __restrict__ pOld,
+                                     const ResolveInfo& __restrict__ pNew,
+                                     bool &pOverride)
+{
+
+  /* The state table itself.
+   * The first index is a link_row and the second index is a bfd_link_hash_type.
+   *
+   * Cs -> all rest kind of common (d_C, wd_C)
+   * Is -> all kind of indeirect
+   */
+  static const enum LinkAction link_action[LAST_ORD][LAST_ORD] =
+  {
+    /* new\old  U       w_U     d_U    wd_U   D      w_D    d_D    wd_D   C      w_C,   Cs,    Is   */
+    /* U    */ {NOACT,  UND,    UND,   UND,   NOACT, NOACT, DUND,  DUNDW, NOACT, NOACT, NOACT, REFC },
+    /* w_U  */ {NOACT,  NOACT,  NOACT, WEAK,  NOACT, NOACT, DUND,  DUNDW, NOACT, NOACT, NOACT, REFC },
+    /* d_U  */ {NOACT,  NOACT,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
+    /* wd_U */ {NOACT,  NOACT,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
+    /* D    */ {DEF,    DEF,    DEF,   DEF,   MDEF,  DEF,   DEF,   DEF,   CDEF,  CDEF,  CDEF,  MDEF },
+    /* w_D  */ {DEFW,   DEFW,   DEFW,  DEFW,  NOACT, NOACT, DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT},
+    /* d_D  */ {DEFD,   MDEFD,  DEFD,  DEFD,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, MDEF },
+    /* wd_D */ {MDEFWD, MDEFWD, DEFWD, DEFWD, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT},
+    /* C    */ {COM,    COM,    COM,   COM,   CREF,  COM,   COM,   COM,   MBIG,  COM,   BIG,   REFC },
+    /* w_C  */ {COM,    COM,    COM,   COM,   NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
+    /* Cs   */ {COM,    COM,    COM,   COM,   NOACT, NOACT, NOACT, NOACT, MBIG,  MBIG,  MBIG,  REFC },
+    /* Is   */ {IND,    IND,    IND,   IND,   MDEF,  IND,   IND,   IND,   CIND,  CIND,  CIND,  MIND }
+  };
+
+  // Special cases:
+  // * when a dynamic defined symbol meets a dynamic weak defined symbol, act
+  //   noting.
+  // * when a undefined symbol meets a dynamic defined symbol, override by
+  //   dynamic defined first, then recover back to undefined symbol later.
+  // * when a dynamic defined symbol meets a undefined symbol or a weak
+  //   undefined symbol, do not override, instead of marking.
+  // * When a undefined symbol meets a dynamic defined symbol or a weak
+  //   undefined symbol meets a dynamic defined symbol, should override.
+  // * When a common symbol meets a weak common symbol, adjust the size of
+  //   common symbol (ref: Google gold linker: resolve.cc)
+
+  unsigned int row = getOrdinate(pNew);
+  unsigned int col = getOrdinate(pOld);
+
+  bool cycle = false;
+  unsigned int result = Resolver::Success;
+  pOverride = false;
+  ResolveInfo* old = &pOld;
+  LinkAction action;
+  do {
+    result = Resolver::Success;
+    cycle = false;
+    action = link_action[row][col];
+
+    switch(action) {
+      case FAIL: {       /* abort.  */
+        m_Mesg = std::string("internal error [StaticResolver.cpp:loc 86].\n") +
+                 std::string("Please report to `mclinker@googlegroups.com'.\n");
+        result = Resolver::Abort;
+        break;
+      }
+      case NOACT: {      /* no action.  */
+        pOverride = false;
+        old->overrideVisibility(pNew);
+        result = Resolver::Success;
+        break;
+      }
+      case UND:          /* override by symbol undefined symbol.  */
+      case WEAK:         /* override by symbol weak undefined.  */
+      case DEF:          /* override by symbol defined.  */
+      case DEFW:         /* override by symbol weak defined.  */
+      case DEFD:         /* override by symbol dynamic defined.  */
+      case DEFWD:        /* override by symbol dynamic weak defined. */
+      case COM: {        /* override by symbol common defined.  */
+        pOverride = true;
+        old->override(pNew);
+        result = Resolver::Success;
+        break;
+      }
+      case MDEFD:        /* mark symbol dynamic defined.  */
+      case MDEFWD: {     /* mark symbol dynamic weak defined.  */
+        uint32_t binding = old->binding();
+        old->override(pNew);
+        old->setBinding(binding);
+        m_Mesg = std::string("symbol `") +
+                 old->name() +
+                 std::string("' uses the type, dynamic, size and type in the dynamic symbol.");
+        pOverride = true;
+        result = Resolver::Warning;
+        break;
+      }
+      case DUND:
+      case DUNDW: {
+        if (old->binding() == ResolveInfo::Weak &&
+            pNew.binding() != ResolveInfo::Weak) {
+          old->setBinding(pNew.binding());
+        }
+        old->overrideVisibility(pNew);
+        pOverride = false;
+        result = Resolver::Success;
+        break;
+      }
+      case CREF: {       /* Possibly warn about common reference to defined symbol.  */
+        // A common symbol does not override a definition.
+        m_Mesg = std::string("common '") +
+                 pNew.name() +
+                 std::string("' overriden by previous definition.");
+        pOverride = false;
+        result = Resolver::Warning;
+        break;
+      }
+      case CDEF: {       /* redefine existing common symbol.  */
+        // We've seen a common symbol and now we see a definition.  The
+        // definition overrides.
+        //
+	// NOTE: m_Mesg uses 'name' instead of `name' for being compatible to GNU ld.
+        m_Mesg = std::string("definition of '") +
+                 old->name() +
+                 std::string("' is overriding common.");
+        old->override(pNew);
+        pOverride = true;
+        result = Resolver::Warning;
+        break;
+      }
+      case BIG: {        /* override by symbol common using largest size.  */
+        if (old->size() < pNew.size())
+          old->setSize(pNew.size());
+        old->overrideAttributes(pNew);
+        old->overrideVisibility(pNew);
+        pOverride = true;
+        result = Resolver::Success;
+        break;
+      }
+      case MBIG: {       /* mark common symbol by larger size. */
+        if (old->size() < pNew.size())
+          old->setSize(pNew.size());
+        old->overrideVisibility(pNew);
+        pOverride = false;
+        result = Resolver::Success;
+        break;
+      }
+      case CIND: {       /* mark indirect symbol from existing common symbol.  */
+         m_Mesg = std::string("indirect symbol `") +
+                  pNew.name()+
+                  std::string("' point to a common symbol.\n");
+         result = Resolver::Warning;
+      }
+      /* Fall through */
+      case IND: {        /* override by indirect symbol.  */
+        if (0 == pNew.link()) {
+          m_Mesg = std::string("indirect symbol `") +
+                   pNew.name() +
+                   std::string("' point to a inexistent symbol.");
+          result = Resolver::Abort;
+          break;
+        }
+
+        /** Should detect the loop of indirect symbol during file reading **/
+        // if (pNew.link()->isIndirect() && pNew.link()->link() == &pNew) {
+        //  m_Mesg = "indirect symbol `"+pNew.name()+"' to `"+pNew.link()->name()+"' is a loop.";
+        //  return Resolver::Abort;
+        //}
+
+        // change the old symbol to the indirect symbol
+        old->setLink(pNew.link());
+        pOverride = true;
+        break;
+      }
+      case MIND: {       /* multiple indirect symbols.  */
+        // it is OK if they both point to the same symbol
+        if (old->link() == pNew.link()) {
+          pOverride = false;
+          break;
+        }
+      }
+      /* Fall through */
+      case MDEF: {       /* multiple definition error.  */
+        m_Mesg = std::string("multiple definitions of `") +
+                 pNew.name() +
+                 std::string("'.");
+        result = Resolver::Abort;
+        break;
+      }
+      case REFC: {       /* Mark indirect symbol referenced and then CYCLE.  */
+        if (0 == old->link()) {
+          m_Mesg = std::string("indirect symbol `") +
+                   old->name() +
+                   std::string("' point to a inexistent symbol.");
+          result = Resolver::Abort;
+          break;
+        }
+
+        old = old->link();
+        col = getOrdinate(*old);
+        cycle = true;
+        break;
+      }
+    } // end of the big switch (action)
+  } while(cycle);
+  return result;
+}
+
diff --git a/lib/LD/StrSymPool.cpp b/lib/LD/StrSymPool.cpp
new file mode 100644
index 0000000..abe3fb7
--- /dev/null
+++ b/lib/LD/StrSymPool.cpp
@@ -0,0 +1,179 @@
+//===- StrSymPool.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/LD/StrSymPool.h"
+#include "mcld/LD/Resolver.h"
+#include <llvm/Support/raw_ostream.h>
+
+using namespace mcld;
+
+//==========================
+// StrSymPool
+StrSymPool::StrSymPool(const Resolver& pResolver, StrSymPool::size_type pSize)
+  : m_pResolver(pResolver.clone()), m_Table(pSize) {
+}
+
+StrSymPool::~StrSymPool()
+{
+  if (0 != m_pResolver)
+    delete m_pResolver;
+}
+
+/// createSymbol - create a symbol
+ResolveInfo* StrSymPool::createSymbol(const llvm::StringRef& pName,
+                                      bool pIsDyn,
+                                      ResolveInfo::Type pType,
+                                      ResolveInfo::Desc pDesc,
+                                      ResolveInfo::Binding pBinding,
+                                      ResolveInfo::SizeType pSize,
+                                      ResolveInfo::Visibility pVisibility)
+{
+  ResolveInfo* result = m_Table.getEntryFactory().produce(pName);
+  result->setIsSymbol(true);
+  result->setSource(pIsDyn);
+  result->setType(pType);
+  result->setDesc(pDesc);
+  result->setBinding(pBinding);
+  result->setVisibility(pVisibility);
+  result->setSize(pSize);
+  return result;
+}
+
+/// insertSymbol - insert a symbol and resolve it immediately
+/// @return the pointer of resolved ResolveInfo
+/// @return is the symbol existent?
+void StrSymPool::insertSymbol(const llvm::StringRef& pName,
+                              bool pIsDyn,
+                              ResolveInfo::Type pType,
+                              ResolveInfo::Desc pDesc,
+                              ResolveInfo::Binding pBinding,
+                              ResolveInfo::SizeType pSize,
+                              ResolveInfo::Visibility pVisibility,
+                              ResolveInfo* pOldInfo,
+                              Resolver::Result& pResult)
+{
+  // We should check if there is any symbol with the same name existed.
+  // If it already exists, we should use resolver to decide which symbol
+  // should be reserved. Otherwise, we insert the symbol and set up its
+  // attributes.
+  bool exist = false;
+  ResolveInfo* old_symbol = m_Table.insert(pName, exist);
+  ResolveInfo* new_symbol = NULL;
+  if (exist && old_symbol->isSymbol()) {
+    exist = true;
+    new_symbol = m_Table.getEntryFactory().produce(pName);
+  }
+  else {
+    exist = false;
+    new_symbol = old_symbol;
+  }
+
+  new_symbol->setIsSymbol(true);
+  new_symbol->setSource(pIsDyn);
+  new_symbol->setType(pType);
+  new_symbol->setDesc(pDesc);
+  new_symbol->setBinding(pBinding);
+  new_symbol->setVisibility(pVisibility);
+  new_symbol->setSize(pSize);
+
+  if (!exist) {
+    // not exit or not a symbol
+    pResult.info      = new_symbol;
+    pResult.existent  = false;
+    pResult.overriden = true;
+    return;
+  }
+  else if (NULL != pOldInfo) {
+    // existent, remember its attribute
+    pOldInfo->override(*old_symbol);
+  }
+
+  // exit and is a symbol
+  // symbol resolution
+  bool override = false;
+  unsigned int action = Resolver::LastAction;
+  switch(m_pResolver->resolve(*old_symbol, *new_symbol, override)) {
+    case Resolver::Success: {
+      pResult.info      = old_symbol;
+      pResult.existent  = true;
+      pResult.overriden = override;
+      break;
+    }
+    case Resolver::Warning: {
+      llvm::errs() << "WARNING: " << m_pResolver->mesg() << "\n";
+      m_pResolver->clearMesg();
+      pResult.info      = old_symbol;
+      pResult.existent  = true;
+      pResult.overriden = override;
+      break;
+    }
+    case Resolver::Abort: {
+      llvm::report_fatal_error(m_pResolver->mesg());
+      pResult.info      = old_symbol;
+      pResult.existent  = true;
+      pResult.overriden = override;
+      break;
+    }
+    default: {
+      m_pResolver->resolveAgain(*this, action, *old_symbol, *new_symbol, pResult);
+      break;
+    }
+  }
+  return;
+}
+
+llvm::StringRef StrSymPool::insertString(const llvm::StringRef& pString)
+{
+  bool exist = false;
+  ResolveInfo* resolve_info = m_Table.insert(pString, exist);
+  return llvm::StringRef(resolve_info->name(), resolve_info->nameSize());
+}
+
+void StrSymPool::reserve(StrSymPool::size_type pSize)
+{
+  m_Table.rehash(pSize);
+}
+
+StrSymPool::size_type StrSymPool::capacity() const
+{
+  return (m_Table.numOfBuckets() - m_Table.numOfEntries());
+}
+
+/// findInfo - find the resolved ResolveInfo
+ResolveInfo* StrSymPool::findInfo(const llvm::StringRef& pName)
+{
+  Table::iterator iter = m_Table.find(pName);
+  return iter.getEntry();
+}
+
+/// findInfo - find the resolved ResolveInfo
+const ResolveInfo* StrSymPool::findInfo(const llvm::StringRef& pName) const
+{
+  Table::const_iterator iter = m_Table.find(pName);
+  return iter.getEntry();
+}
+
+/// findSymbol - find the resolved output LDSymbol
+LDSymbol* StrSymPool::findSymbol(const llvm::StringRef& pName)
+{
+  ResolveInfo* info = findInfo(pName);
+  if (NULL == info)
+    return NULL;
+  return info->outSymbol();
+}
+
+/// findSymbol - find the resolved output LDSymbol
+const LDSymbol* StrSymPool::findSymbol(const llvm::StringRef& pName) const
+{
+  const ResolveInfo* info = findInfo(pName);
+  if (NULL == info)
+    return NULL;
+  return info->outSymbol();
+}
+
diff --git a/lib/LD/SymbolTableFactory.cpp b/lib/LD/SymbolTableFactory.cpp
new file mode 100644
index 0000000..180a4a9
--- /dev/null
+++ b/lib/LD/SymbolTableFactory.cpp
@@ -0,0 +1,52 @@
+//===- SymbolTableFactory.cpp ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/SymbolTableFactory.h"
+
+using namespace mcld;
+
+//==========================
+// SymbolTableFactory
+
+SymbolTableFactory::SymbolTableFactory(size_t pNumOfSymbolTables,
+                                       StrSymPool& pStrSymPool)
+  : m_StrSymPool(pStrSymPool),
+    m_InputFactory(pNumOfSymbolTables),
+    m_OutputFactory(pNumOfSymbolTables)
+{
+}
+
+SymbolTableFactory::~SymbolTableFactory()
+{
+}
+
+SymbolTableIF *SymbolTableFactory::
+createInputTable(StringTable &pEntireStringTable,
+                 StringTable &pDynamicStringTable,
+                 size_t pReserve)
+{
+  InputSymbolTable *inputSymTab = m_InputFactory.allocate();
+  new (inputSymTab) InputSymbolTable(m_StrSymPool,
+                                     pReserve,
+                                     pEntireStringTable,
+                                     pDynamicStringTable);
+  return inputSymTab;
+}
+
+SymbolTableIF *SymbolTableFactory::
+createOutputTable(StringTable &pEntireStringTable,
+                  StringTable &pDynamicStringTable,
+                  size_t pReserve)
+{
+  OutputSymbolTable *outputSymTab = m_OutputFactory.allocate();
+  new (outputSymTab) OutputSymbolTable(m_StrSymPool,
+                                       pReserve,
+                                       pEntireStringTable,
+                                       pDynamicStringTable);
+  return outputSymTab;
+}
diff --git a/lib/MC/Android.mk b/lib/MC/Android.mk
new file mode 100644
index 0000000..044b027
--- /dev/null
+++ b/lib/MC/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_mc_SRC_FILES := \
+  AttributeFactory.cpp  \
+  ContextFactory.cpp  \
+  InputFactory.cpp  \
+  MCBitcodeInterceptor.cpp  \
+  MCFragmentRef.cpp \
+  MCLDAttribute.cpp \
+  MCLDDirectory.cpp \
+  MCLDDriver.cpp  \
+  MCLDFile.cpp  \
+  MCLDInfo.cpp  \
+  MCLDInput.cpp \
+  MCLDInputTree.cpp \
+  MCLDOptions.cpp \
+  MCLDOutput.cpp  \
+  MCLinker.cpp  \
+  MCRegionFragment.cpp  \
+  SearchDirs.cpp  \
+  SymbolCategory.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mc_SRC_FILES)
+LOCAL_MODULE:= libmcldMC
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mc_SRC_FILES)
+LOCAL_MODULE:= libmcldMC
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/MC/AttributeFactory.cpp b/lib/MC/AttributeFactory.cpp
new file mode 100644
index 0000000..f6f4428
--- /dev/null
+++ b/lib/MC/AttributeFactory.cpp
@@ -0,0 +1,91 @@
+//===- AttributeFactory.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDAttribute.h"
+#include "mcld/MC/AttributeFactory.h"
+
+using namespace mcld;
+
+//==========================
+// AttributeFactory
+AttributeFactory::AttributeFactory()
+  : m_AttrSet() {
+  m_AttrSet.push_back(new mcld::Attribute());
+  m_pLast = new AttributeProxy(*this, *m_AttrSet.front());
+}
+
+AttributeFactory::AttributeFactory(size_t pNum)
+  : m_AttrSet() {
+  m_AttrSet.reserve(pNum);
+  m_AttrSet.push_back(new mcld::Attribute());
+  m_pLast = new AttributeProxy(*this, *m_AttrSet.front());
+}
+
+AttributeFactory::~AttributeFactory()
+{
+  iterator cur = m_AttrSet.begin();
+  iterator aEnd = m_AttrSet.end();
+  while(cur != aEnd) {
+    delete (*cur);
+    ++cur;
+  }
+  m_AttrSet.clear();
+  delete m_pLast;
+}
+
+void AttributeFactory::reserve(size_t pNum)
+{
+  m_AttrSet.reserve(pNum);
+}
+
+Attribute &AttributeFactory::predefined()
+{
+  return *m_AttrSet.front();
+}
+
+const Attribute &AttributeFactory::predefined() const
+{
+  return *m_AttrSet.front();
+}
+
+AttributeProxy* AttributeFactory::produce()
+{
+  m_pLast->change(m_AttrSet.front());
+  return m_pLast->clone();
+}
+
+AttributeProxy& AttributeFactory::last()
+{
+  return *m_pLast;
+}
+
+const AttributeProxy& AttributeFactory::last() const
+{
+  return *m_pLast;
+}
+
+Attribute* AttributeFactory::exists(const Attribute& pAttr) const
+{
+  const_iterator cur = m_AttrSet.begin();
+  const_iterator aEnd = m_AttrSet.end();
+  while(cur != aEnd) {
+    if (*(*cur) == pAttr) {
+      m_pLast->change(*cur);
+      return *cur;
+    }
+    ++cur;
+  }
+  return 0;
+}
+
+void AttributeFactory::record(mcld::Attribute &pAttr)
+{
+  m_AttrSet.push_back(&pAttr);
+  m_pLast->change(m_AttrSet.back());
+}
+
diff --git a/lib/MC/ContextFactory.cpp b/lib/MC/ContextFactory.cpp
new file mode 100644
index 0000000..d32ea8b
--- /dev/null
+++ b/lib/MC/ContextFactory.cpp
@@ -0,0 +1,35 @@
+//===- ContextFactory.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDContext.h>
+#include <mcld/MC/ContextFactory.h>
+
+using namespace mcld;
+
+//===---------------------------------------------------------------------===//
+// LDContextFactory
+ContextFactory::ContextFactory(size_t pNum)
+  : UniqueGCFactoryBase<sys::fs::Path, LDContext, 0>(pNum)
+{
+}
+
+ContextFactory::~ContextFactory()
+{
+}
+
+LDContext* ContextFactory::produce(const sys::fs::Path& pPath)
+{
+  LDContext* result = find(pPath);
+  if (0 == result) {
+    result = UniqueGCFactoryBase<sys::fs::Path, LDContext, 0>::allocate();
+    new (result) LDContext();
+    f_KeyMap.insert(std::make_pair(pPath, result));
+  }
+  return result;
+}
+
diff --git a/lib/MC/InputFactory.cpp b/lib/MC/InputFactory.cpp
new file mode 100644
index 0000000..d4d9cc2
--- /dev/null
+++ b/lib/MC/InputFactory.cpp
@@ -0,0 +1,33 @@
+//===- InputFactory.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/InputFactory.h"
+#include "mcld/MC/AttributeFactory.h"
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// InputFactory
+InputFactory::InputFactory(size_t pNum, AttributeFactory& pAttrFactory)
+  : GCFactory<Input,0>(pNum), m_AttrFactory(pAttrFactory) {
+}
+
+InputFactory::~InputFactory()
+{
+}
+
+Input* InputFactory::produce(llvm::StringRef pName,
+                             const sys::fs::Path& pPath,
+                             unsigned int pType,
+                             off_t pFileOffset)
+{
+  mcld::Input* result = Alloc::allocate();
+  new (result) mcld::Input(pName, pPath, m_AttrFactory.last(), pType, pFileOffset);
+  return result;
+}
+
diff --git a/lib/MC/MCBitcodeInterceptor.cpp b/lib/MC/MCBitcodeInterceptor.cpp
new file mode 100644
index 0000000..a79c904
--- /dev/null
+++ b/lib/MC/MCBitcodeInterceptor.cpp
@@ -0,0 +1,70 @@
+//===- MCBitcodeInterceptor.cpp -------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/Relocation.h>
+#include <mcld/MC/MCBitcodeInterceptor.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCExpr.h>
+#include <llvm/MC/MCValue.h>
+#include <llvm/MC/MCFixup.h>
+#include <llvm/MC/MCFixupKindInfo.h>
+#include <llvm/MC/MCSymbol.h>
+#include <llvm/MC/MCAsmLayout.h>
+#include <llvm/MC/MCAsmBackend.h>
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/MC/MCObjectStreamer.h>
+#include <llvm/Support/Casting.h>
+#include <llvm/Support/ELF.h>
+
+using namespace llvm;
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// non-member functions
+
+//===----------------------------------------------------------------------===//
+// MCBitcodeInterceptor
+MCBitcodeInterceptor::MCBitcodeInterceptor(MCObjectStreamer &pStreamer,
+                                           TargetLDBackend& pBackend,
+                                           MCLDInfo& pLDInfo)
+  : MCObjectWriter(llvm::nulls(),
+                   pStreamer.getAssembler().getWriter().isLittleEndian()),
+    m_Backend(pBackend),
+    m_LDInfo(pLDInfo) {
+  pStreamer.getAssembler().setWriter(*this);
+}
+
+MCBitcodeInterceptor::~MCBitcodeInterceptor()
+{
+}
+
+void MCBitcodeInterceptor::ExecutePostLayoutBinding(MCAssembler &Asm,
+                                                 const MCAsmLayout &Layout)
+{
+}
+
+
+void MCBitcodeInterceptor::RecordRelocation(const MCAssembler &Asm,
+                                         const MCAsmLayout &Layout,
+                                         const MCFragment *Fragment,
+                                         const MCFixup &Fixup,
+                                         MCValue Target,
+                                         uint64_t &FixedValue)
+{
+}
+
+/// WriteObject - not really write out a object. Instead, load data to LDContext
+void MCBitcodeInterceptor::WriteObject(MCAssembler &Asm,
+                                       const MCAsmLayout &Layout)
+{
+}
+
+
diff --git a/lib/MC/MCFragmentRef.cpp b/lib/MC/MCFragmentRef.cpp
new file mode 100644
index 0000000..69a865e
--- /dev/null
+++ b/lib/MC/MCFragmentRef.cpp
@@ -0,0 +1,199 @@
+//===- MCFragmentRef.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/MathExtras.h>
+#include <mcld/MC/MCFragmentRef.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/MC/MCTargetFragment.h>
+#include <mcld/LD/Layout.h>
+#include <cstring>
+#include <cassert>
+
+using namespace mcld;
+
+/// compunteFragmentSize - compute the specific MCFragment size
+uint64_t mcld::computeFragmentSize(const Layout& pLayout,
+                                   const llvm::MCFragment& pFrag)
+{
+  switch (pFrag.getKind()) {
+    case llvm::MCFragment::FT_Data:
+      return static_cast<const llvm::MCDataFragment&>(pFrag).getContents().size();
+    case llvm::MCFragment::FT_Fill:
+      return static_cast<const llvm::MCFillFragment&>(pFrag).getSize();
+    case llvm::MCFragment::FT_Inst:
+      return static_cast<const llvm::MCInstFragment&>(pFrag).getInstSize();
+
+    case llvm::MCFragment::FT_LEB:
+      return static_cast<const llvm::MCLEBFragment&>(pFrag).getContents().size();
+
+    case llvm::MCFragment::FT_Align: {
+      uint64_t offset = pLayout.getOutputOffset(pFrag);
+      const llvm::MCAlignFragment& align_frag = static_cast<const llvm::MCAlignFragment&>(pFrag);
+      uint64_t size = llvm::OffsetToAlignment(offset, align_frag.getAlignment());
+      if (size > align_frag.getMaxBytesToEmit())
+        return 0;
+      return size;
+    }
+
+    case llvm::MCFragment::FT_Org: {
+      // TODO
+      assert(0 && "FT_Org: Not implemented yet");
+      return 0;
+    }
+
+    case llvm::MCFragment::FT_Dwarf:
+      return static_cast<const llvm::MCDwarfLineAddrFragment&>(pFrag).getContents().size();
+    case llvm::MCFragment::FT_DwarfFrame:
+      return static_cast<const llvm::MCDwarfCallFrameFragment&>(pFrag).getContents().size();
+
+    case llvm::MCFragment::FT_Region:
+      return static_cast<const MCRegionFragment&>(pFrag).getRegion().size();
+
+    case llvm::MCFragment::FT_Target:
+      return static_cast<const MCTargetFragment&>(pFrag).getSize();
+
+    case llvm::MCFragment::FT_Reloc:
+      assert(0 && "the size of FT_Reloc fragment is handled by backend");
+      return 0;
+
+    default:
+      assert(0 && "invalid fragment kind");
+      return 0;
+  }
+}
+
+//==========================
+// MCFragmentRef
+MCFragmentRef::MCFragmentRef()
+  : m_pFragment(NULL), m_Offset(0) {
+}
+
+MCFragmentRef::MCFragmentRef(llvm::MCFragment& pFrag,
+                             MCFragmentRef::Offset pOffset)
+  : m_pFragment(&pFrag), m_Offset(pOffset) {
+}
+
+MCFragmentRef::~MCFragmentRef()
+{
+  m_pFragment = NULL;
+  m_Offset = 0;
+}
+
+MCFragmentRef& MCFragmentRef::assign(const MCFragmentRef& pCopy)
+{
+  m_pFragment = const_cast<llvm::MCFragment*>(pCopy.m_pFragment);
+  m_Offset = pCopy.m_Offset;
+  return *this;
+}
+
+MCFragmentRef& MCFragmentRef::assign(llvm::MCFragment& pFrag, MCFragmentRef::Offset pOffset)
+{
+  m_pFragment = &pFrag;
+  m_Offset = pOffset;
+  return *this;
+}
+
+void MCFragmentRef::memcpy(void* pDest, size_t pNBytes, Offset pOffset) const
+{
+  // check if the offset is still in a legal range.
+  if (NULL == m_pFragment)
+    return;
+  unsigned int total_offset = m_Offset + pOffset;
+  switch(m_pFragment->getKind()) {
+    case llvm::MCFragment::FT_Inst: {
+      llvm::MCInstFragment* inst_frag = static_cast<llvm::MCInstFragment*>(m_pFragment);
+      unsigned int total_length = inst_frag->getCode().size();
+      if (total_length < (total_offset+pNBytes))
+        pNBytes = total_length - total_offset;
+
+      std::memcpy(pDest, (inst_frag->getCode().data()+total_offset), pNBytes);
+      return;
+    }
+    case llvm::MCFragment::FT_Data: {
+      llvm::MCDataFragment* data_frag = static_cast<llvm::MCDataFragment*>(m_pFragment);
+      unsigned int total_length = data_frag->getContents().size();
+      if (total_length < (total_offset+pNBytes))
+        pNBytes = total_length - total_offset;
+
+      std::memcpy(pDest, (data_frag->getContents().data()+total_offset), pNBytes);
+      return;
+    }
+    case llvm::MCFragment::FT_Region: {
+      MCRegionFragment* region_frag = static_cast<mcld::MCRegionFragment*>(m_pFragment);
+      unsigned int total_length = region_frag->getRegion().size();
+      if (total_length < (total_offset+pNBytes))
+        pNBytes = total_length - total_offset;
+
+      std::memcpy(pDest, region_frag->getRegion().getBuffer(total_offset), pNBytes);
+      return;
+    }
+    case llvm::MCFragment::FT_Align:
+    case llvm::MCFragment::FT_Fill:
+    case llvm::MCFragment::FT_Org:
+    case llvm::MCFragment::FT_Dwarf:
+    case llvm::MCFragment::FT_DwarfFrame:
+    case llvm::MCFragment::FT_LEB:
+    default:
+      return;
+  }
+}
+
+MCFragmentRef::Address MCFragmentRef::deref()
+{
+  if (NULL == m_pFragment)
+    return NULL;
+  Address base = NULL;
+  switch(m_pFragment->getKind()) {
+    case llvm::MCFragment::FT_Inst:
+      base = (Address)static_cast<llvm::MCInstFragment*>(m_pFragment)->getCode().data();
+      break;
+    case llvm::MCFragment::FT_Data:
+      base = (Address)static_cast<llvm::MCDataFragment*>(m_pFragment)->getContents().data();
+      break;
+    case llvm::MCFragment::FT_Region:
+      base = static_cast<mcld::MCRegionFragment*>(m_pFragment)->getRegion().getBuffer();
+      break;
+    case llvm::MCFragment::FT_Align:
+    case llvm::MCFragment::FT_Fill:
+    case llvm::MCFragment::FT_Org:
+    case llvm::MCFragment::FT_Dwarf:
+    case llvm::MCFragment::FT_DwarfFrame:
+    case llvm::MCFragment::FT_LEB:
+    default:
+      return NULL;
+  }
+  return base + m_Offset;
+}
+
+MCFragmentRef::ConstAddress MCFragmentRef::deref() const
+{
+  if (NULL == m_pFragment)
+    return NULL;
+  ConstAddress base = NULL;
+  switch(m_pFragment->getKind()) {
+    case llvm::MCFragment::FT_Inst:
+      base = (ConstAddress)static_cast<const llvm::MCInstFragment*>(m_pFragment)->getCode().data();
+      break;
+    case llvm::MCFragment::FT_Data:
+      base = (ConstAddress)static_cast<const llvm::MCDataFragment*>(m_pFragment)->getContents().data();
+      break;
+    case llvm::MCFragment::FT_Region:
+      base = static_cast<const mcld::MCRegionFragment*>(m_pFragment)->getRegion().getBuffer();
+      break;
+    case llvm::MCFragment::FT_Align:
+    case llvm::MCFragment::FT_Fill:
+    case llvm::MCFragment::FT_Org:
+    case llvm::MCFragment::FT_Dwarf:
+    case llvm::MCFragment::FT_DwarfFrame:
+    case llvm::MCFragment::FT_LEB:
+    default:
+      return NULL;
+  }
+  return base + m_Offset;
+}
+
diff --git a/lib/MC/MCLDAttribute.cpp b/lib/MC/MCLDAttribute.cpp
new file mode 100644
index 0000000..a361691
--- /dev/null
+++ b/lib/MC/MCLDAttribute.cpp
@@ -0,0 +1,172 @@
+//===- MCLDAttribute.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDAttribute.h"
+#include "mcld/MC/AttributeFactory.h"
+
+using namespace mcld;
+
+//==========================
+// AttrConstraint
+bool AttrConstraint::isLegal(const Attribute& pAttr, std::string &pErrMesg) const
+{
+  if (!isWholeArchive() && pAttr.isWholeArchive()) {
+    pErrMesg = std::string("Target does not support --whole-archive");
+    return false;
+  }
+  if (!isAsNeeded() && pAttr.isAsNeeded()) {
+    pErrMesg = std::string("Target does not support --as-needed");
+    return false;
+  }
+  if (!isAddNeeded() && pAttr.isAddNeeded()) {
+    pErrMesg = std::string("Target does not support --add-needed");
+    return false;
+  }
+  if (isStaticSystem() && pAttr.isDynamic()) {
+    pErrMesg = std::string("Target does not support --Bdynamic");
+    return false;
+  }
+  // FIXME: may be it's legal, but ignored by GNU ld.
+  if (isStaticSystem() && pAttr.isAsNeeded()) {
+    pErrMesg = std::string("Can't enable --as-needed on a target which does not support dynamic linking");
+    return false;
+  }
+  // FIXME: may be it's legal, but ignored by GNU ld.
+  if (pAttr.isAsNeeded() && pAttr.isStatic()) {
+    pErrMesg = std::string("Can't mix --static with --as-needed");
+    return false;
+  }
+  return true;
+}
+
+//==========================
+// AttributeProxy
+AttributeProxy::AttributeProxy(AttributeFactory& pParent, Attribute& pBase)
+  : m_AttrPool(pParent), m_pBase(&pBase) {
+}
+
+AttributeProxy::~AttributeProxy()
+{
+}
+
+bool AttributeProxy::isWholeArchive() const
+{
+  if (m_AttrPool.constraint().isWholeArchive())
+    return m_pBase->isWholeArchive();
+  else
+    return false;
+}
+
+bool AttributeProxy::isAsNeeded() const
+{
+  if (m_AttrPool.constraint().isAsNeeded())
+    return m_pBase->isAsNeeded();
+  else
+    return false;
+}
+
+bool AttributeProxy::isAddNeeded() const
+{
+  if (m_AttrPool.constraint().isAddNeeded())
+    return m_pBase->isAddNeeded();
+  else
+    return false;
+}
+
+bool AttributeProxy::isStatic() const
+{
+  if (m_AttrPool.constraint().isSharedSystem())
+    return m_pBase->isStatic();
+  else
+    return true;
+}
+
+bool AttributeProxy::isDynamic() const
+{
+  if (m_AttrPool.constraint().isSharedSystem())
+    return m_pBase->isDynamic();
+  else
+    return false;
+}
+
+static inline void ReplaceOrRecord(AttributeFactory& pParent,
+                                   Attribute *&pBase,
+                                   Attribute *&pCopy)
+{
+  Attribute *result = pParent.exists(*pCopy);
+  if (0 == result) { // can not find
+    pParent.record(*pCopy);
+    pBase = pCopy;
+  }
+  else { // find
+    delete pCopy;
+    pBase = result;
+  }
+}
+
+void AttributeProxy::setWholeArchive()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->setWholeArchive();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::unsetWholeArchive()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->unsetWholeArchive();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::setAsNeeded()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->setAsNeeded();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::unsetAsNeeded()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->unsetAsNeeded();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::setAddNeeded()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->setAddNeeded();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::unsetAddNeeded()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->unsetAddNeeded();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::setStatic()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->setStatic();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+void AttributeProxy::setDynamic()
+{
+  Attribute *copy = new Attribute(*m_pBase);
+  copy->setDynamic();
+  ReplaceOrRecord(m_AttrPool, m_pBase, copy);
+}
+
+AttributeProxy* AttributeProxy::clone() const
+{
+  return new AttributeProxy(m_AttrPool, *m_pBase);
+}
+
diff --git a/lib/MC/MCLDDirectory.cpp b/lib/MC/MCLDDirectory.cpp
new file mode 100644
index 0000000..1d7c649
--- /dev/null
+++ b/lib/MC/MCLDDirectory.cpp
@@ -0,0 +1,103 @@
+//===- MCLDDirectory.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDDirectory.h"
+#include "mcld/Support/FileSystem.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+
+//==========================
+// MCLDDirectory
+MCLDDirectory::MCLDDirectory()
+  : Directory(), m_Name(), m_bInSysroot(false) {
+}
+
+MCLDDirectory::MCLDDirectory(const char* pName)
+  : Directory(), m_Name(pName) {
+  Directory::m_Path.assign(pName);
+
+  if (!Directory::m_Path.empty())
+    m_bInSysroot = ('=' == Directory::m_Path.native()[0]);
+
+  Directory::m_Path.m_append_separator_if_needed();
+  if (m_bInSysroot)
+    Directory::m_Path.native().erase(Directory::m_Path.native().begin());
+  else
+    detail::open_dir(*this);
+}
+
+MCLDDirectory::MCLDDirectory(const std::string &pName)
+  : Directory(), m_Name(pName) {
+  Directory::m_Path.assign(pName);
+
+  if (!Directory::m_Path.empty())
+    m_bInSysroot = ('=' == Directory::m_Path.native()[0]);
+
+  Directory::m_Path.m_append_separator_if_needed();
+  if (m_bInSysroot)
+    Directory::m_Path.native().erase(Directory::m_Path.native().begin());
+  else
+    detail::open_dir(*this);
+}
+
+MCLDDirectory::MCLDDirectory(llvm::StringRef pName)
+  : Directory(), m_Name(pName.data(), pName.size()) {
+  Directory::m_Path.assign(pName.str());
+
+  if (!Directory::m_Path.empty())
+    m_bInSysroot = ('=' == Directory::m_Path.native()[0]);
+
+  Directory::m_Path.m_append_separator_if_needed();
+  if (m_bInSysroot)
+    Directory::m_Path.native().erase(Directory::m_Path.native().begin());
+  else
+    detail::open_dir(*this);
+}
+
+MCLDDirectory &MCLDDirectory::assign(llvm::StringRef pName)
+{
+  m_Name.assign(pName.data(), pName.size());
+  Directory::m_Path.assign(pName.str());
+
+  if (!Directory::m_Path.empty())
+    m_bInSysroot = ('=' == Directory::m_Path.native()[0]);
+
+  Directory::m_Path.m_append_separator_if_needed();
+  if (m_bInSysroot)
+    Directory::m_Path.native().erase(Directory::m_Path.native().begin());
+  else
+    detail::open_dir(*this);
+  Directory::m_FileStatus = FileStatus();
+  Directory::m_SymLinkStatus = FileStatus();
+  Directory::m_Cache.clear();
+  Directory::m_Handler = 0;
+  return (*this);
+}
+
+MCLDDirectory::~MCLDDirectory()
+{
+}
+
+bool MCLDDirectory::isInSysroot() const
+{
+  return m_bInSysroot;
+}
+
+void MCLDDirectory::setSysroot(const sys::fs::Path& pSysroot)
+{
+  if (m_bInSysroot) {
+    std::string old_path = Directory::m_Path.native();
+    Directory::m_Path.native() = pSysroot.native();
+    Directory::m_Path.m_append_separator_if_needed();
+    Directory::m_Path.native() += old_path;
+    detail::canonicalize(Directory::m_Path.native());
+    detail::open_dir(*this);
+  }
+}
+
diff --git a/lib/MC/MCLDDriver.cpp b/lib/MC/MCLDDriver.cpp
new file mode 100644
index 0000000..5e89097
--- /dev/null
+++ b/lib/MC/MCLDDriver.cpp
@@ -0,0 +1,358 @@
+//===- MCLDDriver.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCLDInputTree.h>
+#include <mcld/MC/MCLDDriver.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/ArchiveReader.h>
+#include <mcld/LD/ObjectReader.h>
+#include <mcld/LD/DynObjReader.h>
+#include <mcld/LD/ObjectWriter.h>
+#include <mcld/LD/DynObjWriter.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/Support/RealPath.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <llvm/Support/ErrorHandling.h>
+
+using namespace llvm;
+using namespace mcld;
+
+MCLDDriver::MCLDDriver(MCLDInfo& pLDInfo, TargetLDBackend& pLDBackend)
+  : m_LDInfo(pLDInfo),
+    m_LDBackend(pLDBackend),
+    m_pLinker(0) {
+}
+
+MCLDDriver::~MCLDDriver()
+{
+  if (0 != m_pLinker)
+    delete m_pLinker;
+}
+
+void MCLDDriver::normalize() {
+
+  InputTree::dfs_iterator input, inEnd = m_LDInfo.inputs().dfs_end();
+  for (input = m_LDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
+    // already got type - for example, bitcode
+    if ((*input)->type() == Input::Script ||
+        (*input)->type() == Input::Object ||
+        (*input)->type() == Input::DynObj  ||
+        (*input)->type() == Input::Archive)
+      continue;
+
+
+    MemoryArea *input_memory =
+        m_LDInfo.memAreaFactory().produce((*input)->path(), O_RDONLY);
+    if ((input_memory != NULL) && input_memory->isGood()) {
+      (*input)->setMemArea(input_memory);
+    }
+    else {
+      llvm::report_fatal_error("can not open file: " + (*input)->path().native());
+      return;
+    }
+
+    // is a relocatable object file
+    if (m_LDBackend.getObjectReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::Object);
+      (*input)->setContext(m_LDInfo.contextFactory().produce((*input)->path()));
+      m_LDBackend.getObjectReader()->readObject(**input);
+    }
+    // is a shared object file
+    else if (m_LDBackend.getDynObjReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::DynObj);
+      (*input)->setContext(m_LDInfo.contextFactory().produce((*input)->path()));
+      (*input)->setSOName((*input)->path().native());
+      m_LDBackend.getDynObjReader()->readDSO(**input);
+    }
+    // is an archive
+    else if (m_LDBackend.getArchiveReader()->isMyFormat(*(*input))) {
+      (*input)->setType(Input::Archive);
+      mcld::InputTree* archive_member = m_LDBackend.getArchiveReader()->readArchive(**input);
+      if(!archive_member)  {
+        llvm::report_fatal_error("wrong format archive" + (*input)->path().string());
+        return;
+      }
+
+      m_LDInfo.inputs().merge<InputTree::Inclusive>(input, *archive_member);
+    }
+    else {
+      llvm::report_fatal_error(llvm::Twine("can not recognize file format: ") +
+                               (*input)->path().native() +
+                               llvm::Twine("\nobject format or target machine is wrong\n"));
+    }
+  }
+}
+
+
+bool MCLDDriver::linkable() const
+{
+  // check all attributes are legal
+  mcld::AttributeFactory::const_iterator attr, attrEnd = m_LDInfo.attrFactory().end();
+  for (attr=m_LDInfo.attrFactory().begin(); attr!=attrEnd; ++attr) {
+    std::string error_code;
+    if (!m_LDInfo.attrFactory().constraint().isLegal((**attr), error_code)) {
+      report_fatal_error(error_code);
+      return false;
+    }
+  }
+
+
+  bool hasDynObj = false;
+  // can not mix -static with shared objects
+  mcld::InputTree::const_bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
+  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
+    if ((*input)->type() == mcld::Input::DynObj ) {
+      hasDynObj = true;
+      if((*input)->attribute()->isStatic()) {
+        report_fatal_error("Can't link shared object with -static option");
+        return false;
+      }
+    }
+  }
+
+  // can not mix -r with shared objects
+  return true;
+}
+
+/// initMCLinker - initialize MCLinker
+///  Connect all components with MCLinker
+bool MCLDDriver::initMCLinker()
+{
+  if (0 == m_pLinker)
+    m_pLinker = new MCLinker(m_LDBackend,
+                             m_LDInfo,
+                             *m_LDInfo.output().context(),
+                             m_SectionMap);
+
+  // initialize the readers and writers
+  // Because constructor can not be failed, we initalize all readers and
+  // writers outside the MCLinker constructors.
+  if (!m_LDBackend.initArchiveReader(*m_pLinker, m_LDInfo) ||
+      !m_LDBackend.initObjectReader(*m_pLinker) ||
+      !m_LDBackend.initDynObjReader(*m_pLinker) ||
+      !m_LDBackend.initObjectWriter(*m_pLinker) ||
+      !m_LDBackend.initDynObjWriter(*m_pLinker))
+    return false;
+
+  /// initialize section mapping for standard format, target-dependent section,
+  /// (and user-defined mapping)
+  if (!m_SectionMap.initStdSectionMap() ||
+      !m_LDBackend.initTargetSectionMap(m_SectionMap))
+    return false;
+
+  // initialize standard segments and sections
+  switch (m_LDInfo.output().type()) {
+    case Output::DynObj: {
+      // intialize standard and target-dependent sections
+      if (!m_LDBackend.initDynObjSections(*m_pLinker))
+        return false;
+      break;
+    }
+    case Output::Exec: {
+      // intialize standard and target-dependent sections
+      if (!m_LDBackend.initExecSections(*m_pLinker))
+        return false;
+      break;
+    }
+    case Output::Object: {
+      llvm::report_fatal_error(llvm::Twine("output type is not implemented yet. file: `") +
+                               m_LDInfo.output().name() +
+                               llvm::Twine("'."));
+      return false;
+    }
+    default: {
+      llvm::report_fatal_error(llvm::Twine("unknown output type of file `") +
+                               m_LDInfo.output().name() +
+                               llvm::Twine("'."));
+       return false;
+    }
+  } // end of switch
+
+  // initialize target-dependent segments and sections
+  m_LDBackend.initTargetSections(*m_pLinker);
+
+  // initialize RelocationFactory
+  m_LDBackend.initRelocFactory(*m_pLinker);
+
+  return true;
+}
+
+/// readSections - read all input section headers
+bool MCLDDriver::readSections()
+{
+  // Bitcode is read by the other path. This function reads sections in object
+  // files.
+  mcld::InputTree::bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
+  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
+    if ((*input)->type() == Input::Object) {
+      if (!m_LDBackend.getObjectReader()->readSections(**input))
+        return false;
+    }
+  }
+  return true;
+}
+
+/// mergeSections - put allinput sections into output sections
+bool MCLDDriver::mergeSections()
+{
+  // TODO: when MCLinker can read other object files, we have to merge
+  // sections
+  return true;
+}
+
+/// readSymbolTables - read symbol tables from the input files.
+///  for each input file, loads its symbol table from file.
+bool MCLDDriver::readSymbolTables()
+{
+  mcld::InputTree::dfs_iterator input, inEnd = m_LDInfo.inputs().dfs_end();
+  for (input=m_LDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
+    switch((*input)->type()) {
+    case Input::DynObj:
+      if (!m_LDBackend.getDynObjReader()->readSymbols(**input))
+        return false;
+      break;
+    case Input::Object:
+      if (!m_LDBackend.getObjectReader()->readSymbols(**input))
+        return false;
+      break;
+    }
+  }
+  return true;
+}
+
+/// mergeSymbolTables - merge the symbol tables of input files into the
+/// output's symbol table.
+bool MCLDDriver::mergeSymbolTables()
+{
+  mcld::InputTree::dfs_iterator input, inEnd = m_LDInfo.inputs().dfs_end();
+  for (input=m_LDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
+    if (!m_pLinker->mergeSymbolTable(**input))
+      return false;
+  }
+  return true;
+}
+
+/// addStandardSymbols - shared object and executable files need some
+/// standard symbols
+///   @return if there are some input symbols with the same name to the
+///   standard symbols, return false
+bool MCLDDriver::addStandardSymbols()
+{
+  return m_LDBackend.initStandardSymbols(*m_pLinker);
+}
+
+/// addTargetSymbols - some targets, such as MIPS and ARM, need some
+/// target-dependent symbols
+///   @return if there are some input symbols with the same name to the
+///   target symbols, return false
+bool MCLDDriver::addTargetSymbols()
+{
+  m_LDBackend.initTargetSymbols(*m_pLinker);
+  return true;
+}
+
+/// readRelocations - read all relocation entries
+///
+/// All symbols should be read and resolved before this function.
+bool MCLDDriver::readRelocations()
+{
+  // Bitcode is read by the other path. This function reads relocation sections
+  // in object files.
+  mcld::InputTree::bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
+  for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
+    if ((*input)->type() == Input::Object) {
+      if (!m_LDBackend.getObjectReader()->readRelocations(**input))
+        return false;
+    }
+    // ignore the other kinds of files.
+  }
+  return true;
+}
+
+/// prelayout - help backend to do some modification before layout
+bool MCLDDriver::prelayout()
+{
+  m_LDBackend.preLayout(m_LDInfo.output(),
+                        m_LDInfo,
+                        *m_pLinker);
+
+  m_LDBackend.allocateCommonSymbols(m_LDInfo, *m_pLinker);
+
+  /// measure NamePools - compute the size of name pool sections
+  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
+  /// and .hash sections.
+  ///
+  /// dump all symbols and strings from MCLinker and build the format-dependent
+  /// hash table.
+  m_LDBackend.sizeNamePools(m_LDInfo.output(), m_pLinker->getOutputSymbols(), m_LDInfo);
+
+  return true;
+}
+
+/// layout - linearly layout all output sections and reserve some space
+/// for GOT/PLT
+///   Because we do not support instruction relaxing in this early version,
+///   if there is a branch can not jump to its target, we return false
+///   directly
+bool MCLDDriver::layout()
+{
+  return m_pLinker->layout();
+}
+
+/// prelayout - help backend to do some modification after layout
+bool MCLDDriver::postlayout()
+{
+  m_LDBackend.postLayout(m_LDInfo.output(),
+                         m_LDInfo,
+                         *m_pLinker);
+  return true;
+}
+
+/// relocate - applying relocation entries and create relocation
+/// section in the output files
+/// Create relocation section, asking TargetLDBackend to
+/// read the relocation information into RelocationEntry
+/// and push_back into the relocation section
+bool MCLDDriver::relocate()
+{
+  return m_pLinker->applyRelocations();
+}
+
+/// finalizeSymbolValue - finalize the resolved symbol value.
+///   Before relocate(), after layout(), MCLinker should correct value of all
+///   symbol.
+bool MCLDDriver::finalizeSymbolValue()
+{
+  return m_pLinker->finalizeSymbols();
+}
+
+/// emitOutput - emit the output file.
+bool MCLDDriver::emitOutput()
+{
+  switch(m_LDInfo.output().type()) {
+    case Output::Object:
+      m_LDBackend.getObjectWriter()->writeObject(m_LDInfo.output());
+      return true;
+    case Output::DynObj:
+      m_LDBackend.getDynObjWriter()->writeDynObj(m_LDInfo.output());
+      return true;
+    /** TODO: open the executable file writer **/
+    // case Output::Exec:
+      // m_LDBackend.getExecWriter()->writeObject(m_LDInfo.output());
+      // return true;
+  }
+  return false;
+}
+
+/// postProcessing - do modification after all processes
+bool MCLDDriver::postProcessing()
+{
+  m_pLinker->syncRelocationResult();
+  return true;
+}
diff --git a/lib/MC/MCLDFile.cpp b/lib/MC/MCLDFile.cpp
new file mode 100644
index 0000000..e6bbbc4
--- /dev/null
+++ b/lib/MC/MCLDFile.cpp
@@ -0,0 +1,46 @@
+//===- MCLDFile.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDFile.h"
+#include "mcld/LD/LDContext.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/MemoryArea.h"
+#include <cstring>
+#include <cstdlib>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// MCLDFile
+MCLDFile::MCLDFile()
+  : m_Type(Unknown), m_pContext(0), m_Path(), m_Name(), m_pMemArea(0) {
+}
+
+MCLDFile::MCLDFile(llvm::StringRef pName)
+  : m_Type(Unknown), m_pContext(0), m_Path(), m_Name(pName.data()), m_pMemArea(0) {
+}
+
+MCLDFile::MCLDFile(llvm::StringRef pName,
+                   const sys::fs::Path& pPath,
+                   unsigned int pType)
+  : m_Type(pType), m_pContext(0), m_Path(pPath), m_Name(pName.data()), m_pMemArea(0) {
+}
+
+MCLDFile::~MCLDFile()
+{
+}
+
+void MCLDFile::setSOName(const std::string& pName)
+{
+  size_t pos = pName.find_last_of(sys::fs::separator);
+  if (std::string::npos == pos)
+    m_Name = pName;
+  else
+    m_Name = pName.substr(pos + 1);
+}
+
diff --git a/lib/MC/MCLDInfo.cpp b/lib/MC/MCLDInfo.cpp
new file mode 100644
index 0000000..3cd0838
--- /dev/null
+++ b/lib/MC/MCLDInfo.cpp
@@ -0,0 +1,67 @@
+//===- MCLDInfo.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/Support/FileSystem.h>
+#include <mcld/MC/InputFactory.h>
+#include <mcld/MC/AttributeFactory.h>
+#include <mcld/MC/ContextFactory.h>
+#include <mcld/Config/Config.h>
+#include <string>
+
+using namespace mcld;
+
+//==========================
+// MCLDInfo
+MCLDInfo::MCLDInfo(const std::string& pTripleString,
+                   size_t pAttrNum,
+                   size_t pInputNum)
+  : m_Options(),
+    m_pBitcode(0),
+    m_Triple(pTripleString),
+    m_pStrSymPool(0)
+{
+  m_pAttrFactory = new AttributeFactory(pAttrNum);
+  m_pCntxtFactory = new ContextFactory(pInputNum);
+  m_pMemAreaFactory = new MemoryAreaFactory(pInputNum);
+  m_pInputFactory = new InputFactory(pInputNum, *m_pAttrFactory);
+  m_pInputTree = new InputTree(*m_pInputFactory);
+  m_pOutput = new mcld::Output();
+}
+
+MCLDInfo::~MCLDInfo()
+{
+  delete m_pOutput;
+  delete m_pAttrFactory;
+  delete m_pCntxtFactory;
+  delete m_pMemAreaFactory;
+  delete m_pInputFactory;
+  delete m_pInputTree;
+}
+
+void MCLDInfo::setBitcode(const Input& pInput)
+{
+  m_pBitcode = const_cast<Input*>(&pInput);
+}
+
+Input& MCLDInfo::bitcode()
+{
+  assert((0 != m_pBitcode) && "default bitcode is not set");
+  return *m_pBitcode;
+}
+
+const Input& MCLDInfo::bitcode() const
+{
+  assert((0 != m_pBitcode) && "default bitcode is not set");
+  return *m_pBitcode;
+}
+
+const char* MCLDInfo::version()
+{
+  return mcld::internal::version;
+}
diff --git a/lib/MC/MCLDInput.cpp b/lib/MC/MCLDInput.cpp
new file mode 100644
index 0000000..81a8b60
--- /dev/null
+++ b/lib/MC/MCLDInput.cpp
@@ -0,0 +1,37 @@
+//===- MCLDInput.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInput.h"
+#include "mcld/MC/MCLDAttribute.h"
+
+using namespace mcld;
+
+//==========================
+// MCInput
+Input::Input(llvm::StringRef pName, const AttributeProxy& pProxy)
+ : MCLDFile(pName),
+   m_pAttr(const_cast<Attribute*>(pProxy.attr())),
+   m_bNeeded(false) {
+}
+
+Input::Input(llvm::StringRef pName,
+        const sys::fs::Path& pPath,
+        const AttributeProxy& pProxy,
+        unsigned int pType,
+        off_t pFileOffset)
+  : MCLDFile(pName, pPath, pType),
+    m_pAttr(const_cast<Attribute*>(pProxy.attr())),
+    m_bNeeded(false),
+    m_fileOffset(pFileOffset) {
+}
+
+Input::~Input()
+{
+  // do nothing. Attribute is deleted by AttributeFactory
+}
+
diff --git a/lib/MC/MCLDInputTree.cpp b/lib/MC/MCLDInputTree.cpp
new file mode 100644
index 0000000..b423988
--- /dev/null
+++ b/lib/MC/MCLDInputTree.cpp
@@ -0,0 +1,107 @@
+//===- MCLDInputTree.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInputTree.h"
+#include "mcld/MC/InputFactory.h"
+
+using namespace mcld;
+
+InputTree::Succeeder InputTree::Afterward;
+InputTree::Includer  InputTree::Downward;
+
+//===----------------------------------------------------------------------===//
+// InputTree
+InputTree::InputTree(InputFactory& pInputFactory)
+  : m_FileFactory(pInputFactory) {
+}
+
+InputTree::~InputTree()
+{
+}
+
+InputTree& InputTree::merge(InputTree::iterator pPosition, 
+                            const InputTree::Connector& pConnector,
+                            InputTree& pTree)
+{
+  if (this == &pTree)
+    return *this;
+
+  if (!pTree.empty()) {
+    pConnector.connect(pPosition, iterator(pTree.m_Root.node.right));
+    BinaryTreeBase<Input>::m_Root.summon(
+        pTree.BinaryTreeBase<Input>::m_Root);
+    BinaryTreeBase<Input>::m_Root.delegate(pTree.m_Root);
+    pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
+  }
+  return *this;
+}
+
+InputTree& InputTree::insert(InputTree::iterator pPosition,
+                             const InputTree::Connector& pConnector,
+                             const std::string& pNamespec,
+                             const sys::fs::Path& pPath,
+                             unsigned int pType)
+{
+  BinaryTree<Input>::node_type* node = createNode();
+  node->data = m_FileFactory.produce(pNamespec, pPath, pType);
+  pConnector.connect(pPosition, iterator(node));
+  return *this;
+}
+
+InputTree& InputTree::enterGroup(InputTree::iterator pPosition,
+                                 const InputTree::Connector& pConnector)
+{
+  NodeBase* node = createNode();
+  pConnector.connect(pPosition, iterator(node));
+  return *this;
+}
+
+InputTree& InputTree::insert(InputTree::iterator pPosition,
+                             const InputTree::Connector& pConnector,
+                             const mcld::Input& pInput)
+{
+  BinaryTree<Input>::node_type* node = createNode();
+  node->data = const_cast<mcld::Input*>(&pInput);
+  pConnector.connect(pPosition, iterator(node));
+  return *this;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// non-member functions
+bool mcld::isGroup(const InputTree::iterator& pos)
+{
+  return !pos.hasData();
+}
+
+bool mcld::isGroup(const InputTree::const_iterator& pos)
+{
+  return !pos.hasData();
+}
+
+bool mcld::isGroup(const InputTree::dfs_iterator& pos)
+{
+  return !pos.hasData();
+}
+
+bool mcld::isGroup(const InputTree::const_dfs_iterator& pos)
+{
+  return !pos.hasData();
+}
+
+bool mcld::isGroup(const InputTree::bfs_iterator& pos)
+{
+  return !pos.hasData();
+}
+
+bool mcld::isGroup(const InputTree::const_bfs_iterator& pos)
+{
+  return !pos.hasData();
+}
+
diff --git a/lib/MC/MCLDOptions.cpp b/lib/MC/MCLDOptions.cpp
new file mode 100644
index 0000000..ae07f26
--- /dev/null
+++ b/lib/MC/MCLDOptions.cpp
@@ -0,0 +1,34 @@
+//===- MCLDOptions.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDOptions.h"
+#include "mcld/MC/MCLDInput.h"
+
+using namespace mcld;
+
+//==========================
+// MCLDOptions
+bool GeneralOptions::hasDefaultLDScript() const
+{
+  return true;
+}
+
+const char* GeneralOptions::defaultLDScript() const
+{
+  return NULL;
+}
+
+void GeneralOptions::setDefaultLDScript(const std::string& pFilename)
+{
+}
+
+void GeneralOptions::setSysroot(const mcld::sys::fs::Path &pSysroot)
+{
+  m_Sysroot.assign(pSysroot);
+}
+
diff --git a/lib/MC/MCLDOutput.cpp b/lib/MC/MCLDOutput.cpp
new file mode 100644
index 0000000..c27ee01
--- /dev/null
+++ b/lib/MC/MCLDOutput.cpp
@@ -0,0 +1,27 @@
+//===- MCLDOutput.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDOutput.h"
+
+using namespace mcld;
+
+//==========================
+// MCLDOutput
+Output::Output()
+  : MCLDFile("") {
+}
+
+Output::Output(const sys::fs::Path& pRealPath,
+               Output::Type pType)
+  : MCLDFile("", pRealPath, pType) {
+}
+                  
+Output::~Output()
+{
+}
+
diff --git a/lib/MC/MCLinker.cpp b/lib/MC/MCLinker.cpp
new file mode 100644
index 0000000..e5327e8
--- /dev/null
+++ b/lib/MC/MCLinker.cpp
@@ -0,0 +1,644 @@
+//===- MCLinker.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MCLinker class
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/Resolver.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/LDSectionFactory.h>
+#include <mcld/LD/SectionMap.h>
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <llvm/Support/Host.h>
+#include <llvm/Support/raw_ostream.h>
+
+using namespace mcld;
+
+/// Constructor
+MCLinker::MCLinker(TargetLDBackend& pBackend,
+                   MCLDInfo& pInfo,
+                   LDContext& pContext,
+                   SectionMap& pSectionMap,
+                   const Resolver& pResolver)
+: m_Backend(pBackend),
+  m_Info(pInfo),
+  m_Output(pContext),
+  m_SectionMap(pSectionMap),
+  m_LDSymbolFactory(128),
+  m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.)
+  m_LDSectDataFactory(10),
+  m_SectionMerger(pSectionMap, pContext),
+  m_StrSymPool(pResolver, 128)
+{
+  m_Info.setNamePool(m_StrSymPool);
+}
+
+/// Destructor
+MCLinker::~MCLinker()
+{
+}
+
+/// addSymbolFromObject - add a symbol from object file and resolve it
+/// immediately
+LDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName,
+                                        ResolveInfo::Type pType,
+                                        ResolveInfo::Desc pDesc,
+                                        ResolveInfo::Binding pBinding,
+                                        ResolveInfo::SizeType pSize,
+                                        LDSymbol::ValueType pValue,
+                                        MCFragmentRef* pFragmentRef,
+                                        ResolveInfo::Visibility pVisibility)
+{
+
+  // resolved_result is a triple <resolved_info, existent, override>
+  Resolver::Result resolved_result;
+  ResolveInfo old_info; // used for arrange output symbols
+
+  if (pBinding == ResolveInfo::Local) {
+    // if the symbol is a local symbol, create a LDSymbol for input, but do not
+    // resolve them.
+    resolved_result.info     = m_StrSymPool.createSymbol(pName,
+                                                         false,
+                                                         pType,
+                                                         pDesc,
+                                                         pBinding,
+                                                         pSize,
+                                                         pVisibility);
+
+    // No matter if there is a symbol with the same name, insert the symbol
+    // into output symbol table. So, we let the existent false.
+    resolved_result.existent  = false;
+    resolved_result.overriden = true;
+  }
+  else {
+    // if the symbol is not local, insert and resolve it immediately
+    m_StrSymPool.insertSymbol(pName, false, pType, pDesc, pBinding, pSize,
+                              pVisibility, &old_info, resolved_result);
+  }
+
+  // the return ResolveInfo should not NULL
+  assert(NULL != resolved_result.info);
+
+  // create a LDSymbol for the input file.
+  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
+  new (input_sym) LDSymbol();
+
+  // set the relation between input LDSymbol and its ResolveInfo
+  input_sym->setResolveInfo(*resolved_result.info);
+
+  // set up input LDSymbol
+  input_sym->setFragmentRef(pFragmentRef);
+  input_sym->setValue(pValue);
+
+  LDSymbol* output_sym = resolved_result.info->outSymbol();
+  bool has_output_sym = (NULL != output_sym);
+  if (!resolved_result.existent || !has_output_sym) {
+    // it is a new symbol, the output_sym should be NULL.
+    assert(NULL == output_sym);
+
+    // if it is a new symbol, create a LDSymbol for the output
+    output_sym = m_LDSymbolFactory.allocate();
+    new (output_sym) LDSymbol();
+
+    // set up the relation between output LDSymbol and its ResolveInfo
+    output_sym->setResolveInfo(*resolved_result.info);
+    resolved_result.info->setSymPtr(output_sym);
+  }
+
+  if (resolved_result.overriden || !has_output_sym) {
+    // symbol can be overriden only if it exists.
+    assert(output_sym != NULL);
+
+    // should override output LDSymbol
+    output_sym->setFragmentRef(pFragmentRef);
+    output_sym->setValue(pValue);
+  }
+
+  // After symbol resolution, visibility is changed to the most restrict one.
+  // we need to arrange its position in the output symbol .
+  if (pType != ResolveInfo::Section) {
+    if (!has_output_sym) {
+      // We merge sections when reading them. So we do not need to output symbols
+      // with section type
+
+      // No matter the symbol is already in the output or not, add it if it
+      // should be forcefully set local.
+      if (shouldForceLocal(*resolved_result.info))
+        m_OutputSymbols.forceLocal(*output_sym);
+      else {
+        // the symbol should not be forcefully local.
+        m_OutputSymbols.add(*output_sym);
+      }
+    }
+    else if (resolved_result.overriden) {
+      if (!shouldForceLocal(old_info) ||
+          !shouldForceLocal(*resolved_result.info)) {
+        // If the old info and the new info are both forcefully local, then
+        // we should keep the output_sym in forcefully local category. Else,
+        // we should re-sort the output_sym
+        m_OutputSymbols.arrange(*output_sym, old_info);
+      }
+    }
+  }
+
+  return input_sym;
+}
+
+/// addSymbolFromDynObj - add a symbol from object file and resolve it
+/// immediately
+LDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName,
+                                        ResolveInfo::Type pType,
+                                        ResolveInfo::Desc pDesc,
+                                        ResolveInfo::Binding pBinding,
+                                        ResolveInfo::SizeType pSize,
+                                        LDSymbol::ValueType pValue,
+                                        MCFragmentRef* pFragmentRef,
+                                        ResolveInfo::Visibility pVisibility)
+{
+  // We merge sections when reading them. So we do not need symbols with
+  // section type
+  if (pType == ResolveInfo::Section)
+    return NULL;
+
+  // ignore symbols with local binding or that have internal or hidden
+  // visibility
+  if (pBinding == ResolveInfo::Local ||
+      pVisibility == ResolveInfo::Internal ||
+      pVisibility == ResolveInfo::Hidden)
+    return NULL;
+
+  // A protected symbol in a shared library must be treated as a
+  // normal symbol when viewed from outside the shared library.
+  if (pVisibility == ResolveInfo::Protected)
+    pVisibility = ResolveInfo::Default;
+
+  // insert symbol and resolve it immediately
+  // resolved_result is a triple <resolved_info, existent, override>
+  Resolver::Result resolved_result;
+  m_StrSymPool.insertSymbol(pName, true, pType, pDesc, pBinding, pSize, pVisibility,
+                            NULL, resolved_result);
+
+  // the return ResolveInfo should not NULL
+  assert(NULL != resolved_result.info);
+
+  // create a LDSymbol for the input file.
+  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
+  new (input_sym) LDSymbol();
+
+  // set up the relation between input LDSymbol and its ResolveInfo
+  input_sym->setResolveInfo(*resolved_result.info);
+
+  // set up input LDSymbol
+  input_sym->setFragmentRef(pFragmentRef);
+  input_sym->setValue(pValue);
+
+  LDSymbol* output_sym = NULL;
+  if (!resolved_result.existent) {
+    // we get a new symbol, leave it as NULL
+    resolved_result.info->setSymPtr(NULL);
+  }
+  else {
+    // we saw the symbol before, but the output_sym still may be NULL.
+    output_sym = resolved_result.info->outSymbol();
+  }
+
+  if (output_sym != NULL) {
+    // After symbol resolution, visibility is changed to the most restrict one.
+    // If we are not doing incremental linking, then any symbol with hidden
+    // or internal visibility is forcefully set as a local symbol.
+    if (shouldForceLocal(*resolved_result.info)) {
+      m_OutputSymbols.forceLocal(*output_sym);
+    }
+  }
+
+  return input_sym;
+}
+
+/// defineSymbolForcefully - define an output symbol and override it immediately
+LDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName,
+                                           bool pIsDyn,
+                                           ResolveInfo::Type pType,
+                                           ResolveInfo::Desc pDesc,
+                                           ResolveInfo::Binding pBinding,
+                                           ResolveInfo::SizeType pSize,
+                                           LDSymbol::ValueType pValue,
+                                           MCFragmentRef* pFragmentRef,
+                                           ResolveInfo::Visibility pVisibility)
+{
+  ResolveInfo* info = m_StrSymPool.findInfo(pName);
+  LDSymbol* output_sym = NULL;
+  if (NULL == info) {
+    // the symbol is not in the pool, create a new one.
+    // create a ResolveInfo
+    Resolver::Result result;
+    m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
+                              NULL, result);
+    assert(!result.existent);
+
+    // create a output LDSymbol
+    output_sym = m_LDSymbolFactory.allocate();
+    new (output_sym) LDSymbol();
+
+    output_sym->setResolveInfo(*result.info);
+    result.info->setSymPtr(output_sym);
+
+    if (shouldForceLocal(*result.info))
+      m_OutputSymbols.forceLocal(*output_sym);
+    else
+      m_OutputSymbols.add(*output_sym);
+  }
+  else {
+    // the symbol is already in the pool, override it
+    ResolveInfo old_info;
+    old_info.override(*info);
+
+    info->setSource(pIsDyn);
+    info->setType(pType);
+    info->setDesc(pDesc);
+    info->setBinding(pBinding);
+    info->setVisibility(pVisibility);
+    info->setIsSymbol(true);
+    info->setSize(pSize);
+
+    output_sym = info->outSymbol();
+    if (NULL != output_sym)
+      m_OutputSymbols.arrange(*output_sym, old_info);
+    else {
+      // create a output LDSymbol
+      output_sym = m_LDSymbolFactory.allocate();
+      new (output_sym) LDSymbol();
+
+      output_sym->setResolveInfo(*info);
+      info->setSymPtr(output_sym);
+
+      m_OutputSymbols.add(*output_sym);
+    }
+  }
+
+  if (NULL != output_sym) {
+    output_sym->setFragmentRef(pFragmentRef);
+    output_sym->setValue(pValue);
+  }
+
+  return output_sym;
+}
+
+/// defineSymbolAsRefered - define an output symbol and override it immediately
+LDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName,
+                                           bool pIsDyn,
+                                           ResolveInfo::Type pType,
+                                           ResolveInfo::Desc pDesc,
+                                           ResolveInfo::Binding pBinding,
+                                           ResolveInfo::SizeType pSize,
+                                           LDSymbol::ValueType pValue,
+                                           MCFragmentRef* pFragmentRef,
+                                           ResolveInfo::Visibility pVisibility)
+{
+  ResolveInfo* info = m_StrSymPool.findInfo(pName);
+
+  if (NULL == info || !info->isUndef()) {
+    // only undefined symbol can make a reference.
+    return NULL;
+  }
+
+  // the symbol is already in the pool, override it
+  ResolveInfo old_info;
+  old_info.override(*info);
+
+  info->setSource(pIsDyn);
+  info->setType(pType);
+  info->setDesc(pDesc);
+  info->setBinding(pBinding);
+  info->setVisibility(pVisibility);
+  info->setIsSymbol(true);
+  info->setSize(pSize);
+
+  LDSymbol* output_sym = info->outSymbol();
+  if (NULL != output_sym) {
+    output_sym->setFragmentRef(pFragmentRef);
+    output_sym->setValue(pValue);
+    m_OutputSymbols.arrange(*output_sym, old_info);
+  }
+  else {
+    // create a output LDSymbol
+    output_sym = m_LDSymbolFactory.allocate();
+    new (output_sym) LDSymbol();
+
+    output_sym->setResolveInfo(*info);
+    info->setSymPtr(output_sym);
+
+    m_OutputSymbols.add(*output_sym);
+  }
+
+  return output_sym;
+}
+
+/// defineAndResolveSymbolForcefully - define an output symbol and resolve it
+/// immediately
+LDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
+                                                     bool pIsDyn,
+                                                     ResolveInfo::Type pType,
+                                                     ResolveInfo::Desc pDesc,
+                                                     ResolveInfo::Binding pBinding,
+                                                     ResolveInfo::SizeType pSize,
+                                                     LDSymbol::ValueType pValue,
+                                                     MCFragmentRef* pFragmentRef,
+                                                     ResolveInfo::Visibility pVisibility)
+{
+  // Result is <info, existent, override>
+  Resolver::Result result;
+  ResolveInfo old_info;
+  m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
+                            &old_info, result);
+
+  LDSymbol* output_sym = result.info->outSymbol();
+  bool has_output_sym = (NULL != output_sym);
+
+  if (!result.existent || !has_output_sym) {
+    output_sym = m_LDSymbolFactory.allocate();
+    new (output_sym) LDSymbol();
+    output_sym->setResolveInfo(*result.info);
+    result.info->setSymPtr(output_sym);
+  }
+
+  if (result.overriden || !has_output_sym) {
+    output_sym->setFragmentRef(pFragmentRef);
+    output_sym->setValue(pValue);
+  }
+
+  // After symbol resolution, the visibility is changed to the most restrict.
+  // arrange the output position
+  if (shouldForceLocal(*result.info))
+    m_OutputSymbols.forceLocal(*output_sym);
+  else if (has_output_sym)
+    m_OutputSymbols.arrange(*output_sym, old_info);
+  else
+    m_OutputSymbols.add(*output_sym);
+
+  return output_sym;
+}
+
+/// defineAndResolveSymbolAsRefered - define an output symbol and resolve it
+/// immediately.
+LDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
+                                                    bool pIsDyn,
+                                                    ResolveInfo::Type pType,
+                                                    ResolveInfo::Desc pDesc,
+                                                    ResolveInfo::Binding pBinding,
+                                                    ResolveInfo::SizeType pSize,
+                                                    LDSymbol::ValueType pValue,
+                                                    MCFragmentRef* pFragmentRef,
+                                                    ResolveInfo::Visibility pVisibility)
+{
+  ResolveInfo* info = m_StrSymPool.findInfo(pName);
+
+  if (NULL == info || !info->isUndef()) {
+    // only undefined symbol can make a reference
+    return NULL;
+  }
+
+  return defineAndResolveSymbolForcefully(pName,
+                                          pIsDyn,
+                                          pType,
+                                          pDesc,
+                                          pBinding,
+                                          pSize,
+                                          pValue,
+                                          pFragmentRef,
+                                          pVisibility);
+}
+
+/// createSectHdr - create the input section header
+LDSection& MCLinker::createSectHdr(const std::string& pName,
+                                   LDFileFormat::Kind pKind,
+                                   uint32_t pType,
+                                   uint32_t pFlag)
+{
+  // for user such as reader, standard/target fromat
+  LDSection* result =
+    m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag);
+
+  // check if we need to create a output section for output LDContext
+  std::string sect_name = m_SectionMap.getOutputSectName(pName);
+  LDSection* output_sect = m_Output.getSection(sect_name);
+
+  if (NULL == output_sect) {
+  // create a output section and push it into output LDContext
+    output_sect =
+      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
+    m_Output.getSectionTable().push_back(output_sect);
+    m_SectionMerger.addMapping(pName, output_sect);
+  }
+  return *result;
+}
+
+/// getOrCreateOutputSectHdr - for reader and standard/target format to get
+/// or create the output's section header
+LDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName,
+                                              LDFileFormat::Kind pKind,
+                                              uint32_t pType,
+                                              uint32_t pFlag,
+                                              uint32_t pAlign)
+{
+  // check if we need to create a output section for output LDContext
+  std::string sect_name = m_SectionMap.getOutputSectName(pName);
+  LDSection* output_sect = m_Output.getSection(sect_name);
+
+  if (NULL == output_sect) {
+  // create a output section and push it into output LDContext
+    output_sect =
+      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
+    output_sect->setAlign(pAlign);
+    m_Output.getSectionTable().push_back(output_sect);
+    m_SectionMerger.addMapping(pName, output_sect);
+  }
+  return *output_sect;
+}
+
+/// getOrCreateSectData - get or create MCSectionData
+/// pSection is input LDSection
+llvm::MCSectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
+{
+  // if there is already a section data pointed by section, return it.
+  llvm::MCSectionData* sect_data = pSection.getSectionData();
+  if (NULL != sect_data) {
+    m_Layout.addInputRange(*sect_data, pSection);
+    return *sect_data;
+  }
+
+  // try to get one from output LDSection
+  LDSection* output_sect =
+    m_SectionMerger.getOutputSectHdr(pSection.name());
+
+  assert(NULL != output_sect);
+
+  sect_data = output_sect->getSectionData();
+
+  if (NULL != sect_data) {
+    pSection.setSectionData(sect_data);
+    m_Layout.addInputRange(*sect_data, pSection);
+    return *sect_data;
+  }
+
+  // if the output LDSection also has no MCSectionData, then create one.
+  sect_data = m_LDSectDataFactory.allocate();
+  new (sect_data) llvm::MCSectionData(*output_sect);
+  pSection.setSectionData(sect_data);
+  output_sect->setSectionData(sect_data);
+  m_Layout.addInputRange(*sect_data, pSection);
+  return *sect_data;
+}
+
+/// addRelocation - add a relocation entry in MCLinker (only for object file)
+///
+/// All symbols should be read and resolved before calling this function.
+Relocation* MCLinker::addRelocation(Relocation::Type pType,
+                                    const LDSymbol& pSym,
+                                    ResolveInfo& pResolveInfo,
+                                    MCFragmentRef& pFragmentRef,
+                                    Relocation::Address pAddend)
+{
+  Relocation* relocation = m_Backend.getRelocFactory()->produce(pType,
+                                                                pFragmentRef,
+                                                                pAddend);
+
+  relocation->setSymInfo(&pResolveInfo);
+
+  m_RelocationList.push_back(relocation);
+
+  m_Backend.scanRelocation(*relocation, pSym, *this, m_Info,
+                           m_Info.output());
+
+  return relocation;
+}
+
+bool MCLinker::applyRelocations()
+{
+  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
+
+  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
+    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
+    static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_Info);
+  }
+  return true;
+}
+
+void MCLinker::syncRelocationResult()
+{
+
+  m_Info.output().memArea()->clean();
+  MemoryRegion* region = m_Info.output().memArea()->request(0,
+                              m_Info.output().memArea()->size());
+
+  uint8_t* data = region->getBuffer();
+
+  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
+  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
+
+    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
+    Relocation* reloc = static_cast<Relocation*>(frag);
+
+    // get output file offset
+    size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() +
+                        m_Layout.getOutputOffset(reloc->targetRef());
+
+    uint8_t* target_addr = data + out_offset;
+    // byte swapping if target and host has different endian, and then write back
+    if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) {
+       uint64_t tmp_data = 0;
+
+       switch(m_Backend.bitclass()) {
+         case 32u:
+           tmp_data = bswap32(reloc->target());
+           std::memcpy(target_addr, &tmp_data, 4);
+           break;
+
+         case 64u:
+           tmp_data = bswap64(reloc->target());
+           std::memcpy(target_addr, &tmp_data, 8);
+           break;
+
+         default:
+           break;
+      }
+    }
+    else {
+      std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8);
+    }
+  } // end of for
+
+  m_Info.output().memArea()->sync();
+}
+
+
+bool MCLinker::layout()
+{
+  return m_Layout.layout(m_Info.output(), m_Backend);
+}
+
+bool MCLinker::finalizeSymbols()
+{
+  SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
+  for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
+
+    if (0x0 != (*symbol)->resolveInfo()->reserved()) {
+      // if the symbol is target reserved, target backend is responsible
+      // for finalizing the value.
+      // if target backend does not know this symbol, it will return false
+      // and we have to take over the symbol.
+      if (m_Backend.finalizeSymbol(**symbol))
+        continue;
+    }
+
+    if ((*symbol)->resolveInfo()->isAbsolute() ||
+        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
+      // absolute symbols and symbols with function type should have
+      // zero value
+      (*symbol)->setValue(0x0);
+      continue;
+    }
+
+    if ((*symbol)->hasFragRef()) {
+      // set the virtual address of the symbol. If the output file is
+      // relocatable object file, the section's virtual address becomes zero.
+      // And the symbol's value become section relative offset.
+      uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
+      assert(NULL != (*symbol)->fragRef()->frag());
+      uint64_t addr  = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
+      (*symbol)->setValue(value + addr);
+      continue;
+    }
+  }
+
+  return true;
+}
+
+bool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
+{
+  // forced local symbol matches all rules:
+  // 1. We are not doing incremental linking.
+  // 2. The symbol is with Hidden or Internal visibility.
+  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
+  // 4. The symbol is defined or common
+  if (m_Info.output().type() != Output::Object &&
+      (pInfo.visibility() == ResolveInfo::Hidden ||
+         pInfo.visibility() == ResolveInfo::Internal) &&
+      (pInfo.isGlobal() || pInfo.isWeak()) &&
+      (pInfo.isDefine() || pInfo.isCommon()))
+    return true;
+  return false;
+}
+
diff --git a/lib/MC/MCRegionFragment.cpp b/lib/MC/MCRegionFragment.cpp
new file mode 100644
index 0000000..59b109a
--- /dev/null
+++ b/lib/MC/MCRegionFragment.cpp
@@ -0,0 +1,24 @@
+//===- MCRegionFragment.cpp - MCRegionFragment implementation -------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/MC/MCRegionFragment.h"
+
+using namespace mcld;
+using namespace llvm;
+
+//==========================
+// MCRegionFragment
+MCRegionFragment::MCRegionFragment(MemoryRegion& pRegion, MCSectionData* pSD)
+  : MCFragment((llvm::MCFragment::FragmentType)FT_Region, pSD), m_Region(pRegion) {
+}
+
+MCRegionFragment::~MCRegionFragment()
+{
+}
+
diff --git a/lib/MC/README b/lib/MC/README
new file mode 100644
index 0000000..f020b50
--- /dev/null
+++ b/lib/MC/README
@@ -0,0 +1,8 @@
+MCLDStreamer is similar to MCObjectStreamer
+MCLinker is similar to MCAssembler
+MCLDWriter is similar to MCObjectWriter
+
+MCELFObjectReader parses ELF object files
+to MCInst classes
+
+
diff --git a/lib/MC/SearchDirs.cpp b/lib/MC/SearchDirs.cpp
new file mode 100644
index 0000000..0d21e46
--- /dev/null
+++ b/lib/MC/SearchDirs.cpp
@@ -0,0 +1,92 @@
+//===- SearchDirs.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/ADT/Twine.h>
+
+#include "mcld/MC/SearchDirs.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/MC/MCLDDirectory.h"
+
+using namespace mcld;
+
+//==========================
+// Non-member functions
+static void SpecToFilename(const std::string& pSpec, std::string& pFile)
+{
+  pFile = "lib";
+  pFile += pSpec;
+}
+
+//==========================
+// SearchDirs
+SearchDirs::SearchDirs()
+{
+  // a magic number 8, no why.
+  // please prove it or change it
+  m_DirList.reserve(8);
+}
+
+SearchDirs::~SearchDirs()
+{
+  iterator dir, dirEnd = end();
+  for (dir = begin(); dir!=dirEnd; ++dir) {
+    delete (*dir);
+  }
+}
+
+void SearchDirs::add(const MCLDDirectory& pDirectory)
+{
+  m_DirList.push_back(new MCLDDirectory(pDirectory));
+}
+
+mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType)
+{
+  std::string file;
+  SpecToFilename(pNamespec, file);
+  // for all MCLDDirectorys
+  DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
+  for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
+    // for all entries in MCLDDirectory
+    MCLDDirectory::iterator entry = (*mcld_dir)->begin();
+    MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
+
+    switch(pType) {
+      case Input::DynObj: {
+        while (entry!=enEnd) {
+          if (file == entry.path()->stem().native() ) {
+            if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
+              return entry.path();
+            }
+          }
+
+          ++entry;
+        }
+      }
+
+      case Input::Archive : {
+        entry = (*mcld_dir)->begin();
+        enEnd = (*mcld_dir)->end();
+        while ( entry!=enEnd ) {
+          if (file == entry.path()->stem().native() &&
+            mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
+            return entry.path();
+          }
+          ++entry;
+       }
+     }
+     default: {
+       llvm::report_fatal_error(llvm::Twine("SearchDir can not recoginize namespec: `") +
+                                pNamespec +
+                                llvm::Twine("'."));
+     }
+    }
+  }
+  return 0;
+}
+
diff --git a/lib/MC/SymbolCategory.cpp b/lib/MC/SymbolCategory.cpp
new file mode 100644
index 0000000..4b5e0f7
--- /dev/null
+++ b/lib/MC/SymbolCategory.cpp
@@ -0,0 +1,337 @@
+//===- SymbolCategory.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <algorithm>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// Category
+SymbolCategory::Category::Type
+SymbolCategory::Category::categorize(const ResolveInfo& pInfo)
+{
+  if (ResolveInfo::File == pInfo.type())
+    return Category::File;
+  if (ResolveInfo::Local == pInfo.binding())
+    return Category::Local;
+  if (ResolveInfo::Common == pInfo.desc())
+    return Category::Common;
+  if (ResolveInfo::Weak == pInfo.binding())
+    return Category::Weak;
+  return Category::Global;
+}
+
+//===----------------------------------------------------------------------===//
+// SymbolCategory
+SymbolCategory::SymbolCategory()
+{
+  m_pFile   = new Category(Category::File);
+  m_pLocal  = new Category(Category::Local);
+  m_pCommon = new Category(Category::Common);
+  m_pWeak   = new Category(Category::Weak);
+  m_pGlobal = new Category(Category::Global);
+
+  m_pFile->next   = m_pLocal;
+  m_pLocal->next  = m_pCommon;
+  m_pCommon->next = m_pWeak;
+  m_pWeak->next   = m_pGlobal;
+
+  m_pGlobal->prev = m_pWeak;
+  m_pWeak->prev   = m_pCommon;
+  m_pCommon->prev = m_pLocal;
+  m_pLocal->prev   = m_pFile;
+}
+
+SymbolCategory::~SymbolCategory()
+{
+  Category* current = m_pFile;
+  while (NULL != current) {
+    Category* tmp = current;
+    current = current->next;
+    delete tmp;
+  }
+}
+
+SymbolCategory& SymbolCategory::add(LDSymbol& pSymbol)
+{
+  m_OutputSymbols.push_back(&pSymbol);
+
+  assert(NULL != pSymbol.resolveInfo());
+  Category::Type target = Category::categorize(*pSymbol.resolveInfo());
+
+  Category* current = m_pGlobal;
+
+  // use non-stable bubble sort to arrange the order of symbols.
+  while (NULL != current) {
+    if (current->type == target) {
+      current->end++;
+      break;
+    }
+    else {
+      if (!current->empty()) {
+        std::swap(m_OutputSymbols[current->begin],
+                  m_OutputSymbols[current->end]);
+      }
+      current->end++;
+      current->begin++;
+      current = current->prev;
+    }
+  }
+  return *this;
+}
+
+SymbolCategory& SymbolCategory::forceLocal(LDSymbol& pSymbol)
+{
+  m_OutputSymbols.insert(localEnd(), &pSymbol);
+  m_pLocal->end++;
+  m_pCommon->begin++;
+  m_pCommon->end++;
+  m_pWeak->begin++;
+  m_pWeak->end++;
+  m_pGlobal->begin++;
+  m_pGlobal->end++;
+
+  return *this;
+}
+
+SymbolCategory& SymbolCategory::arrange(LDSymbol& pSymbol, const ResolveInfo& pSourceInfo)
+{
+  assert(NULL != pSymbol.resolveInfo());
+  Category::Type source = Category::categorize(pSourceInfo);
+  Category::Type target = Category::categorize(*pSymbol.resolveInfo());
+
+  int distance = target - source;
+  if (0 == distance) {
+    // in the same category, do not need to re-arrange
+    return *this;
+  }
+
+  // source and target are not in the same category
+  // find the category of source
+  Category* current = m_pFile;
+  while(NULL != current) {
+    if (source == current->type)
+      break;
+    current = current->next;
+  }
+
+  assert(NULL != current);
+  assert(!current->empty());
+
+  // find the position of source
+  size_t pos = current->begin;
+  while (pos != current->end) {
+    if (m_OutputSymbols[pos] == &pSymbol)
+      break;
+    ++pos;
+  }
+
+  assert(current->end != pos);
+
+  // The distance is positive. It means we should bubble sort downward.
+  if (distance > 0) {
+    // downward
+    size_t rear;
+    do {
+      if (current->type == target) {
+        break;
+      }
+      else {
+        assert(!current->isLast() && "target category is wrong.");
+        rear = current->end - 1;
+        std::swap(m_OutputSymbols[pos], m_OutputSymbols[rear]);
+        pos = rear;
+        current->next->begin--;
+        current->end--;
+      }
+      current = current->next;
+    } while(NULL != current);
+
+    return *this;
+  } // downward
+
+  // The distance is negative. It means we should bubble sort upward.
+  if (distance < 0) {
+
+    // upward
+    do {
+      if (current->type == target) {
+        break;
+      }
+      else {
+        assert(!current->isFirst() && "target category is wrong.");
+        std::swap(m_OutputSymbols[current->begin], m_OutputSymbols[pos]);
+        pos = current->begin;
+        current->begin++;
+        current->prev->end++;
+      }
+      current = current->prev;
+    } while(NULL != current);
+
+    return *this;
+  } // upward
+  return *this;
+}
+
+SymbolCategory& SymbolCategory::changeCommonsToGlobal()
+{
+  if (emptyCommons())
+    return *this;
+
+  size_t com_rear = m_pCommon->end - 1;
+  size_t com_front = m_pCommon->begin;
+  size_t weak_rear = m_pWeak->end - 1;
+  size_t weak_size = m_pWeak->end - m_pWeak->begin;
+  for (size_t sym = com_rear; sym >= com_front; --sym) {
+    std::swap(m_OutputSymbols[weak_rear], m_OutputSymbols[sym]);
+    --weak_rear;
+  }
+
+  m_pWeak->begin = m_pCommon->begin;
+  m_pWeak->end = m_pCommon->begin + weak_size;
+  m_pGlobal->begin = m_pWeak->end;
+  m_pCommon->begin = m_pCommon->end = m_pWeak->begin;
+
+  return *this;
+}
+
+size_t SymbolCategory::numOfSymbols() const
+{
+  return m_OutputSymbols.size();
+}
+
+size_t SymbolCategory::numOfLocals() const
+{
+  return (m_pFile->size() + m_pLocal->size());
+}
+
+size_t SymbolCategory::numOfCommons() const
+{
+  return m_pCommon->size();
+}
+
+size_t SymbolCategory::numOfRegulars() const
+{
+  return (m_pWeak->size() + m_pGlobal->size());
+}
+
+bool SymbolCategory::empty() const
+{
+  return (emptyLocals() &&
+          emptyCommons() &&
+          emptyRegulars());
+}
+
+bool SymbolCategory::emptyLocals() const
+{
+  return (m_pFile->empty() && m_pLocal->empty());
+}
+
+bool SymbolCategory::emptyCommons() const
+{
+  return m_pCommon->empty();
+}
+
+bool SymbolCategory::emptyRegulars() const
+{
+  return (m_pWeak->empty() && m_pGlobal->empty());
+}
+
+SymbolCategory::iterator SymbolCategory::begin()
+{
+  return m_OutputSymbols.begin();
+}
+
+SymbolCategory::iterator SymbolCategory::end()
+{
+  return m_OutputSymbols.end();
+}
+
+SymbolCategory::const_iterator SymbolCategory::begin() const
+{
+  return m_OutputSymbols.begin();
+}
+
+SymbolCategory::const_iterator SymbolCategory::end() const
+{
+  return m_OutputSymbols.end();
+}
+
+SymbolCategory::iterator SymbolCategory::localBegin()
+{
+  return m_OutputSymbols.begin();
+}
+
+SymbolCategory::iterator SymbolCategory::localEnd()
+{
+  iterator iter = m_OutputSymbols.begin();
+  iter += m_pFile->size();
+  iter += m_pLocal->size();
+  return iter;
+}
+
+SymbolCategory::const_iterator SymbolCategory::localBegin() const
+{
+  return m_OutputSymbols.begin();
+}
+
+SymbolCategory::const_iterator SymbolCategory::localEnd() const
+{
+  const_iterator iter = m_OutputSymbols.begin();
+  iter += m_pFile->size();
+  iter += m_pLocal->size();
+  return iter;
+}
+
+SymbolCategory::iterator SymbolCategory::commonBegin()
+{
+  return localEnd();
+}
+
+SymbolCategory::iterator SymbolCategory::commonEnd()
+{
+  iterator iter = localEnd();
+  iter += m_pCommon->size();
+  return iter;
+}
+
+SymbolCategory::const_iterator SymbolCategory::commonBegin() const
+{
+  return localEnd();
+}
+
+SymbolCategory::const_iterator SymbolCategory::commonEnd() const
+{
+  const_iterator iter = localEnd();
+  iter += m_pCommon->size();
+  return iter;
+}
+
+SymbolCategory::iterator SymbolCategory::regularBegin()
+{
+  return commonEnd();
+}
+
+SymbolCategory::iterator SymbolCategory::regularEnd()
+{
+  return m_OutputSymbols.end();
+}
+
+SymbolCategory::const_iterator SymbolCategory::regularBegin() const
+{
+  return commonEnd();
+}
+
+SymbolCategory::const_iterator SymbolCategory::regularEnd() const
+{
+  return m_OutputSymbols.end();
+}
+
diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk
new file mode 100644
index 0000000..952ba53
--- /dev/null
+++ b/lib/Support/Android.mk
@@ -0,0 +1,38 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_support_SRC_FILES := \
+  CommandLine.cpp \
+  Directory.cpp \
+  FileSystem.cpp  \
+  LEB128.cpp  \
+  MemoryArea.cpp  \
+  MemoryAreaFactory.cpp \
+  MemoryRegion.cpp  \
+  Path.cpp  \
+  RealPath.cpp  \
+  RegionFactory.cpp \
+  TargetRegistry.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_support_SRC_FILES)
+LOCAL_MODULE:= libmcldSupport
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_support_SRC_FILES)
+LOCAL_MODULE:= libmcldSupport
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
new file mode 100644
index 0000000..57b82df
--- /dev/null
+++ b/lib/Support/CommandLine.cpp
@@ -0,0 +1,84 @@
+//===- CommandLine.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/CommandLine.h"
+#include <llvm/ADT/StringRef.h>
+
+using namespace llvm;
+using namespace llvm::cl;
+
+//--------------------------------------------------
+// parser<mcld::sys::fs::Path>
+//
+bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option &O,
+                       llvm::StringRef ArgName,
+                       llvm::StringRef Arg,
+                       mcld::sys::fs::Path &Val)
+{
+  Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end());
+  return false;
+}
+
+static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
+
+void parser<mcld::sys::fs::Path>::printOptionDiff(const llvm::cl::Option &O,
+                                                  const mcld::sys::fs::Path &V,
+                                                  parser<mcld::sys::fs::Path>::OptVal Default,
+                                                  size_t GlobalWidth) const
+{
+  printOptionName(O, GlobalWidth);
+  outs() << "= " << V;
+  size_t VSize = V.native().size();
+  size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
+  outs().indent(NumSpaces) << " (default: ";
+  if (Default.hasValue())
+    outs() << Default.getValue().c_str();
+  else
+    outs() << "*no default*";
+  outs() << ")\n";
+}
+
+void parser<mcld::sys::fs::Path>::anchor()
+{
+  // do nothing
+}
+
+//--------------------------------------------------
+// parser<mcld::MCLDDirectory>
+//
+bool parser<mcld::MCLDDirectory>::parse(llvm::cl::Option &O,
+                                llvm::StringRef ArgName,
+                                llvm::StringRef Arg,
+                                mcld::MCLDDirectory &Val)
+{
+  Val.assign(Arg);
+  return false;
+}
+
+void parser<mcld::MCLDDirectory>::printOptionDiff(const llvm::cl::Option &O,
+                                                  const mcld::MCLDDirectory &V,
+                                                  parser<mcld::MCLDDirectory>::OptVal Default,
+                                                  size_t GlobalWidth) const
+{
+  printOptionName(O, GlobalWidth);
+  outs() << "= " << V.name();
+  size_t VSize = V.name().size();
+  size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
+  outs().indent(NumSpaces) << " (default: ";
+  if (Default.hasValue())
+    outs() << Default.getValue().name();
+  else
+    outs() << "*no default*";
+  outs() << ")\n";
+}
+
+void parser<mcld::MCLDDirectory>::anchor()
+{
+  // do nothing
+}
+
diff --git a/lib/Support/Directory.cpp b/lib/Support/Directory.cpp
new file mode 100644
index 0000000..211b42a
--- /dev/null
+++ b/lib/Support/Directory.cpp
@@ -0,0 +1,252 @@
+//===- Directory.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/Directory.h"
+#include "mcld/Support/FileSystem.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+
+namespace { // anonymous
+
+bool status_known(FileStatus f)
+{
+  return f.type() != StatusError;
+}
+
+bool is_symlink(FileStatus f)
+{
+  return f.type() == SymlinkFile;
+}
+
+} // namespace of anonymous
+
+//==========================
+// Directory
+Directory::Directory()
+  : m_Path(),
+    m_FileStatus(),
+    m_SymLinkStatus(),
+    m_Handler(NULL),
+    m_Cache(),
+    m_CacheFull(false) {
+}
+
+Directory::Directory(const Path& pPath,
+                     FileStatus st,
+                     FileStatus symlink_st)
+  : m_Path(pPath),
+    m_FileStatus(st),
+    m_SymLinkStatus(symlink_st),
+    m_Handler(NULL),
+    m_Cache(),
+    m_CacheFull(false) {
+  if (m_Path.native() == ".")
+    detail::get_pwd(m_Path.native());
+  m_Path.m_append_separator_if_needed();
+  mcld::sys::fs::detail::open_dir(*this);
+}
+
+Directory::Directory(const Directory& pCopy)
+  : m_Path(pCopy.m_Path),
+    m_FileStatus(pCopy.m_FileStatus),
+    m_SymLinkStatus(pCopy.m_SymLinkStatus),
+    m_Handler(NULL),
+    m_Cache(),
+    m_CacheFull(false) {
+  mcld::sys::fs::detail::open_dir(*this);
+}
+
+Directory::~Directory()
+{
+  detail::close_dir(*this);
+}
+
+bool Directory::isGood() const
+{
+  return (0 != m_Handler);
+}
+
+Directory& Directory::operator=(const Directory& pCopy)
+{
+  assign(pCopy.m_Path, pCopy.m_FileStatus, pCopy.m_SymLinkStatus);
+  return *this;
+}
+
+void Directory::assign(const Path& pPath,
+                       FileStatus st,
+                       FileStatus symlink_st)
+{
+  if (isGood())
+    clear();
+
+  m_Path = pPath;
+  if (m_Path.native() == ".")
+    detail::get_pwd(m_Path.native());
+  m_Path.m_append_separator_if_needed();
+
+  m_FileStatus = st;
+  m_SymLinkStatus = symlink_st;
+  detail::open_dir(*this);
+}
+
+FileStatus Directory::status() const
+{
+  if (!status_known(m_FileStatus))
+  {
+    // optimization: if the symlink status is known, and it isn't a symlink,
+    // then status and symlink_status are identical so just copy the
+    // symlink status to the regular status.
+    if (status_known(m_SymLinkStatus)
+      && !is_symlink(m_SymLinkStatus))
+    {
+      m_FileStatus = m_SymLinkStatus;
+    }
+    else detail::status(m_Path,m_FileStatus);
+  }
+  return m_FileStatus;
+
+}
+
+FileStatus Directory::symlinkStatus() const
+{
+  if (!status_known(m_SymLinkStatus))
+     detail::symlink_status(m_Path,m_SymLinkStatus);
+  return  m_SymLinkStatus;
+}
+
+Directory::iterator Directory::begin()
+{
+  if (m_CacheFull && m_Cache.empty())
+    return end();
+  PathCache::iterator iter = m_Cache.begin();
+  if (NULL == iter.getEntry())
+    ++iter;
+  return iterator(this, iter);
+}
+
+Directory::iterator Directory::end()
+{
+  return iterator(0, m_Cache.end());
+}
+
+void Directory::clear()
+{
+  m_Path.native().clear();
+  m_FileStatus = FileStatus();
+  m_SymLinkStatus = FileStatus();
+  m_Cache.clear();
+  detail::close_dir(*this);
+}
+
+//==========================
+// DirIterator
+DirIterator::DirIterator(Directory* pParent,
+                         const DirIterator::DirCache::iterator& pIter)
+  : m_pParent(pParent),
+    m_Iter(pIter) {
+  m_pEntry = m_Iter.getEntry();
+}
+
+DirIterator::DirIterator(const DirIterator& pCopy)
+  : m_pParent(pCopy.m_pParent),
+    m_Iter(pCopy.m_Iter),
+    m_pEntry(pCopy.m_pEntry) {
+}
+
+DirIterator::~DirIterator()
+{
+}
+
+Path* DirIterator::path()
+{
+  if (m_pParent == 0) // end
+    return 0;
+  return m_pEntry->value();
+}
+
+const Path* DirIterator::path() const
+{
+  if (m_pParent == 0) // end
+    return 0;
+  return m_pEntry->value();
+}
+
+DirIterator& DirIterator::operator=(const DirIterator& pCopy)
+{
+  m_pParent = pCopy.m_pParent;
+  m_Iter = pCopy.m_Iter;
+  m_pEntry = pCopy.m_pEntry;
+  return (*this);
+}
+
+DirIterator& DirIterator::operator++()
+{
+  if (0 == m_pParent)
+    return *this;
+
+  // move forward one step first.
+  ++m_Iter;
+
+  if (m_pParent->m_Cache.end() == m_Iter) {
+    if (!m_pParent->m_CacheFull) {
+      m_pEntry = detail::bring_one_into_cache(*this);
+      if (0 == m_pEntry && m_pParent->m_CacheFull)
+        m_pParent = 0;
+      return *this;
+    }
+    m_pParent = 0;
+    return *this;
+  }
+
+  m_pEntry = m_Iter.getEntry();
+  return *this;
+}
+
+DirIterator DirIterator::operator++(int)
+{
+  DirIterator tmp(*this);
+
+  // move forward one step first.
+  ++m_Iter;
+
+  if (m_pParent->m_Cache.end() == m_Iter) {
+    if (!m_pParent->m_CacheFull) {
+      m_pEntry = detail::bring_one_into_cache(*this);
+      if (0 == m_pEntry && m_pParent->m_CacheFull)
+        m_pParent = 0;
+      return tmp;
+    }
+    m_pParent = 0;
+    return tmp;
+  }
+
+  m_pEntry = m_Iter.getEntry();
+  return tmp;
+}
+
+bool DirIterator::operator==(const DirIterator& y) const
+{
+  if (m_pParent != y.m_pParent)
+    return false;
+  if (0 == m_pParent)
+    return true;
+  const Path* x_path = path();
+  const Path* y_path = y.path();
+  if (0 == x_path && 0 == y_path)
+    return true;
+  if (0 == x_path || 0 == y_path)
+    return false;
+  return (*x_path == *y_path);
+}
+
+bool DirIterator::operator!=(const DirIterator& y) const
+{
+  return !this->operator==(y);
+}
+
diff --git a/lib/Support/FileSystem.cpp b/lib/Support/FileSystem.cpp
new file mode 100644
index 0000000..d3366c0
--- /dev/null
+++ b/lib/Support/FileSystem.cpp
@@ -0,0 +1,33 @@
+//===- FileSystem.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+
+#if defined(ANDROID)
+#include <llvm/Config/config.h>
+#endif
+
+using namespace mcld::sys::fs;
+
+
+//===--------------------------------------------------------------------===//
+// SearchDirs
+
+//===--------------------------------------------------------------------===//
+// non-member functions
+
+// Include the truly platform-specific parts.
+#if defined(LLVM_ON_UNIX)
+#include "Unix/FileSystem.inc"
+#include "Unix/PathV3.inc"
+#endif
+#if defined(LLVM_ON_WIN32)
+#include "Windows/FileSystem.inc"
+#include "Windows/PathV3.inc"
+#endif
diff --git a/lib/Support/LEB128.cpp b/lib/Support/LEB128.cpp
new file mode 100644
index 0000000..02d7f24
--- /dev/null
+++ b/lib/Support/LEB128.cpp
@@ -0,0 +1,228 @@
+//===- LEB128.cpp ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/LEB128.h>
+
+namespace mcld {
+
+namespace leb128 {
+
+//===---------------------- LEB128 Encoding APIs -------------------------===//
+template<>
+size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue) {
+  size_t size = 0;
+  do {
+    ByteType byte = pValue & 0x7f;
+    pValue >>= 7;
+    if (pValue)
+      byte |= 0x80;
+    *pBuf++ = byte;
+    size++;
+  } while (pValue);
+
+  return size;
+}
+
+/*
+ * Fast version for encoding 32-bit integer. This unrolls the loop in the
+ * generic version defined above.
+ */
+template<>
+size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue) {
+  if ((pValue & ~0x7f) == 0) {
+    *pBuf++ = static_cast<ByteType>(pValue);
+    return 1;
+  } else if ((pValue & ~0x3fff) == 0){
+    *pBuf++ = static_cast<ByteType>((pValue         & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>((pValue  >>  7) & 0x7f);
+    return 2;
+  } else if ((pValue & ~0x1fffff) == 0) {
+    *pBuf++ = static_cast<ByteType>((pValue         & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >>  7) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>((pValue  >> 14) & 0x7f);
+    return 3;
+  } else if ((pValue & ~0xfffffff) == 0) {
+    *pBuf++ = static_cast<ByteType>((pValue         & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >>  7) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >> 14) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>((pValue  >> 21) & 0x7f);
+    return 4;
+  } else {
+    *pBuf++ = static_cast<ByteType>((pValue         & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >>  7) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >> 14) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>(((pValue >> 21) & 0x7f) | 0x80);
+    *pBuf++ = static_cast<ByteType>((pValue  >> 28) & 0x7f);
+    return 5;
+  }
+  // unreachable
+}
+
+template<>
+size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue) {
+  size_t size = 0;
+  bool more = true;
+
+  do {
+    ByteType byte = pValue & 0x7f;
+    pValue >>= 7;
+
+    if (((pValue ==  0) && ((byte & 0x40) == 0)) ||
+        ((pValue == -1) && ((byte & 0x40) == 0x40)))
+      more = false;
+    else
+      byte |= 0x80;
+
+    *pBuf++ = byte;
+    size++;
+  } while (more);
+
+  return size;
+}
+
+template<>
+size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue) {
+  return encode<int64_t>(pBuf, static_cast<int64_t>(pValue));
+}
+
+//===---------------------- LEB128 Decoding APIs -------------------------===//
+
+template<>
+uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize) {
+  uint64_t result = 0;
+
+  if ((*pBuf & 0x80) == 0) {
+    pSize = 1;
+    return *pBuf;
+  } else if ((*(pBuf + 1) & 0x80) == 0) {
+    pSize = 2;
+    return ((*(pBuf + 1) & 0x7f) << 7) |
+           (*pBuf & 0x7f);
+  } else if ((*(pBuf + 2) & 0x80) == 0) {
+    pSize = 3;
+    return ((*(pBuf + 2) & 0x7f) << 14) |
+           ((*(pBuf + 1) & 0x7f) <<  7) |
+           (*pBuf & 0x7f);
+  } else {
+    pSize = 4;
+    result = ((*(pBuf + 3) & 0x7f) << 21) |
+             ((*(pBuf + 2) & 0x7f) << 14) |
+             ((*(pBuf + 1) & 0x7f) <<  7) |
+             (*pBuf & 0x7f);
+  }
+
+  if ((*(pBuf + 3) & 0x80) != 0) {
+    // Large number which is an unusual case.
+    unsigned shift;
+    ByteType byte;
+
+    // Start the read from the 4th byte.
+    shift = 28;
+    pBuf += 4;
+    do {
+      byte = *pBuf;
+      pBuf++;
+      pSize++;
+      result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
+      shift += 7;
+    } while (byte & 0x80);
+  }
+
+  return result;
+}
+
+template<>
+uint64_t decode<uint64_t>(const ByteType *&pBuf) {
+  ByteType byte;
+  uint64_t result;
+
+  byte = *pBuf++;
+  result = byte & 0x7f;
+  if ((byte & 0x80) == 0) {
+    return result;
+  } else {
+    byte = *pBuf++;
+    result |=  ((byte & 0x7f) << 7);
+    if ((byte & 0x80) == 0) {
+      return result;
+    } else {
+      byte = *pBuf++;
+      result |= (byte & 0x7f) << 14;
+      if ((byte & 0x80) == 0) {
+        return result;
+      } else {
+        byte = *pBuf++;
+        result |= (byte & 0x7f) << 21;
+        if ((byte & 0x80) == 0) {
+          return result;
+        }
+      }
+    }
+  }
+
+  // Large number which is an unusual case.
+  unsigned shift;
+
+  // Start the read from the 4th byte.
+  shift = 28;
+  do {
+    byte = *pBuf++;
+    result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
+    shift += 7;
+  } while (byte & 0x80);
+
+  return result;
+}
+
+/*
+ * Signed LEB128 decoding is Similar to the unsigned version but setup the sign
+ * bit if necessary. This is rarely used, therefore we don't provide unrolling
+ * version like decode() to save the code size.
+ */
+template<>
+int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize) {
+  uint64_t result = 0;
+  ByteType byte;
+  unsigned shift = 0;
+
+  pSize = 0;
+  do {
+    byte = *pBuf;
+    pBuf++;
+    pSize++;
+    result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
+    shift += 7;
+  } while (byte & 0x80);
+
+  if ((shift < (8 * sizeof(result))) && (byte & 0x40))
+    result |= ((static_cast<uint64_t>(-1)) << shift);
+
+  return result;
+}
+
+template<>
+int64_t decode<int64_t>(const ByteType *&pBuf) {
+  uint64_t result = 0;
+  ByteType byte;
+  unsigned shift = 0;
+
+  do {
+    byte = *pBuf;
+    pBuf++;
+    result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
+    shift += 7;
+  } while (byte & 0x80);
+
+  if ((shift < (8 * sizeof(result))) && (byte & 0x40))
+    result |= ((static_cast<uint64_t>(-1)) << shift);
+
+  return result;
+}
+
+} // namespace of leb128
+} // namespace of mcld
diff --git a/lib/Support/MemoryArea.cpp b/lib/Support/MemoryArea.cpp
new file mode 100644
index 0000000..f388e94
--- /dev/null
+++ b/lib/Support/MemoryArea.cpp
@@ -0,0 +1,426 @@
+//===- MemoryArea.cpp -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/ADT/Twine.h>
+
+#include <mcld/Support/RegionFactory.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Support/FileSystem.h>
+
+#include <cerrno>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+using namespace mcld;
+
+//===--------------------------------------------------------------------===//
+// MemoryArea
+MemoryArea::MemoryArea(RegionFactory& pRegionFactory)
+  : m_RegionFactory(pRegionFactory),
+    m_FileDescriptor(-1),
+    m_FileSize(0),
+    m_AccessFlags(ReadOnly),
+    m_State(BadBit) {
+}
+
+MemoryArea::~MemoryArea()
+{
+  // truncate the file to real size
+  if (isWritable())
+    truncate(m_FileSize);
+
+  unmap();
+}
+
+void MemoryArea::truncate(size_t pLength)
+{
+  if (!isWritable())
+    return;
+
+  if (-1 == ::ftruncate(m_FileDescriptor, static_cast<off_t>(pLength))) {
+    llvm::report_fatal_error(llvm::Twine("Cannot truncate `") +
+                             m_FilePath.native() +
+                             llvm::Twine("' to size: ") +
+                             llvm::Twine(pLength) +
+                             llvm::Twine(".\n"));
+  }
+}
+
+void MemoryArea::map(const sys::fs::Path& pPath, int pFlags)
+{
+  m_AccessFlags = pFlags;
+  m_FilePath = pPath;
+  m_FileDescriptor = ::open(m_FilePath.c_str(), m_AccessFlags);
+
+  if (-1 == m_FileDescriptor) {
+    m_State |= FailBit;
+  }
+  else {
+    struct stat st;
+    int stat_result = ::stat(m_FilePath.native().c_str(), &st);
+    if (0x0 == stat_result) {
+      m_FileSize = static_cast<size_t>(st.st_size);
+      m_State = GoodBit;
+    }
+    else {
+      m_FileSize = 0x0;
+      m_State |= FailBit;
+      m_State |= BadBit;
+    }
+  }
+}
+
+void MemoryArea::map(const sys::fs::Path& pPath, int pFlags, int pMode)
+{
+  m_AccessFlags = pFlags;
+  m_FilePath = pPath;
+  m_FileDescriptor = ::open(m_FilePath.c_str(), m_AccessFlags, pMode);
+
+  if (-1 == m_FileDescriptor) {
+    m_State |= FailBit;
+  }
+  else {
+    struct stat st;
+    int stat_result = ::stat(m_FilePath.native().c_str(), &st);
+    if (0x0 == stat_result) {
+      m_FileSize = static_cast<size_t>(st.st_size);
+      m_State = GoodBit;
+    }
+    else {
+      m_FileSize = 0x0;
+      m_State |= FailBit;
+      m_State |= BadBit;
+    }
+  }
+}
+
+void MemoryArea::unmap()
+{
+  if (isMapped()) {
+    if (-1 == ::close(m_FileDescriptor))
+      m_State |= FailBit;
+    else {
+      m_FileDescriptor = -1;
+      m_AccessFlags = ReadOnly;
+    }
+  }
+}
+
+bool MemoryArea::isMapped() const
+{
+  return (-1 != m_FileDescriptor);
+}
+
+bool MemoryArea::isGood() const
+{
+  return 0x0 == (m_State & (BadBit | FailBit));
+}
+
+bool MemoryArea::isBad() const
+{
+  return 0x0 != (m_State & BadBit);
+}
+
+bool MemoryArea::isFailed() const
+{
+  return 0x0 != (m_State & FailBit);
+}
+
+bool MemoryArea::isEOF() const
+{
+  return 0x0 != (m_State & EOFBit);
+}
+
+bool MemoryArea::isReadable() const
+{
+  return (((m_AccessFlags & AccessMask) == ReadOnly) ||
+         ((m_AccessFlags & AccessMask) == ReadWrite));
+}
+
+bool MemoryArea::isWritable() const
+{
+  return (((m_AccessFlags & AccessMask) == WriteOnly) ||
+         ((m_AccessFlags & AccessMask) == ReadWrite));
+}
+
+int MemoryArea::rdstate() const
+{
+  return m_State;
+}
+
+void MemoryArea::setState(MemoryArea::IOState pState)
+{
+  m_State |= pState;
+}
+
+void MemoryArea::clear(MemoryArea::IOState pState)
+{
+  m_State = pState;
+}
+
+// The layout of MemorySpace in the virtual memory space
+//
+// |  : page boundary
+// [,]: MemoryRegion
+// -  : fillment
+// =  : data
+//
+// |---[=|====|====|==]--|
+// ^   ^              ^  ^
+// |   |              |  |
+// | r_start      +r_len |
+// space.data      +space.size
+//
+// space.file_offset is the offset of the mapped file segment from the start of
+// the file. if the MemorySpace's type is ALLOCATED_ARRAY, the distances of
+// (space.data, r_start) and (r_len, space.size) are zero.
+//
+MemoryRegion* MemoryArea::request(size_t pOffset, size_t pLength)
+{
+  if (!isMapped() || !isGood())
+    return NULL;
+
+  if (0x0 == pLength)
+    return NULL;
+
+  if (!isWritable() && (pOffset + pLength) > m_FileSize)
+    return NULL;
+
+  if (isWritable() && (pOffset + pLength) > m_FileSize) {
+    // If the memory area is writable, user can expand the size of file by
+    // request a region larger than the file.
+    // MemoryArea should enlarge the file if the requested region is larger
+    // than the file.
+    m_FileSize = page_boundary(pOffset + pLength + 1);
+    truncate(m_FileSize);
+  }
+
+  Space* space = find(pOffset, pLength);
+  MemoryArea::Address r_start = 0;
+  if (NULL == space) {
+    // the space does not exist, create a new space.
+    space = new Space(this, pOffset, pLength);
+    m_SpaceList.push_back(space);
+    switch(space->type = policy(pOffset, pLength)) {
+      case Space::MMAPED: {
+        int mm_prot, mm_flag;
+        if (isWritable()) {
+          mm_prot = PROT_READ | PROT_WRITE;
+          mm_flag = MAP_FILE | MAP_SHARED;
+        }
+        else {
+          mm_prot = PROT_READ;
+          mm_flag = MAP_FILE | MAP_PRIVATE;
+        }
+
+        space->file_offset = page_offset(pOffset);
+
+        // The space's size may be larger than filesize.
+        space->size = page_boundary(pLength + pOffset + 1 - space->file_offset);
+        space->data = (Address) ::mmap(NULL,
+                                       space->size,
+                                       mm_prot, mm_flag,
+                                       m_FileDescriptor,
+                                       space->file_offset);
+
+        if (space->data == MAP_FAILED) {
+          llvm::report_fatal_error(llvm::Twine("cannot open memory map file :") +
+                                   m_FilePath.native() +
+                                   llvm::Twine(" (") +
+                                   sys::fs::detail::strerror(errno) +
+                                   llvm::Twine(").\n"));
+        }
+
+        r_start = space->data + (pOffset - space->file_offset);
+        break;
+      }
+      case Space::ALLOCATED_ARRAY: {
+        // space->offset and space->size are set in constructor. We only need
+        // to set up data.
+        space->data = new unsigned char[pLength];
+        r_start = space->data;
+        if ((m_AccessFlags & AccessMask) != WriteOnly) {
+          // Read data from the backend file.
+          if (!read(*space)) {
+            llvm::report_fatal_error(llvm::Twine("Failed to read data from ") +
+                                     m_FilePath.native() +
+                                     llvm::Twine(" (") +
+                                     sys::fs::detail::strerror(errno) +
+                                     llvm::Twine(") at offset ") +
+                                     llvm::Twine(pOffset) +
+                                     llvm::Twine(" lenght ") +
+                                     llvm::Twine(pLength) + llvm::Twine(".\n"));
+          }
+        }
+        break;
+      } // case
+      default: {
+        llvm::report_fatal_error("unhandled space type\n");
+      }
+    } // switch
+  }
+  else { // found
+    off_t distance = pOffset - space->file_offset;
+    r_start = space->data + distance;
+  }
+
+  // now, we have a legal space to hold the new MemoryRegion
+  return m_RegionFactory.produce(space, r_start, pLength);
+}
+
+// release - release a MemoryRegion
+void MemoryArea::release(MemoryRegion* pRegion)
+{
+  if (!isMapped() || !isGood())
+    return;
+
+  Space *space = pRegion->parent();
+  m_RegionFactory.destruct(pRegion);
+
+  if (0 == space->region_num) {
+    write(*space);
+    m_SpaceList.remove(*space);
+    release(space);
+  }
+}
+
+void MemoryArea::clean()
+{
+  m_RegionFactory.clear();
+
+  SpaceList::iterator sIter, sEnd = m_SpaceList.end();
+  for (sIter = m_SpaceList.begin(); sIter!=sEnd; ++sIter) {
+    write(*sIter);
+    release(sIter);
+  }
+  m_SpaceList.clear();
+}
+
+void MemoryArea::sync()
+{
+  SpaceList::iterator sIter, sEnd = m_SpaceList.end();
+  for (sIter = m_SpaceList.begin(); sIter!=sEnd; ++sIter) {
+    write(*sIter);
+  }
+}
+
+MemoryArea::Space* MemoryArea::find(size_t pOffset, size_t pLength)
+{
+  SpaceList::iterator sIter, sEnd = m_SpaceList.end();
+  for (sIter = m_SpaceList.begin(); sIter!=sEnd; ++sIter) {
+    if (sIter->file_offset <= pOffset &&
+       (pOffset+pLength) <= (sIter->file_offset+sIter->size) ) { // within
+      return sIter;
+    }
+  }
+  return NULL;
+}
+
+void MemoryArea::release(MemoryArea::Space* pSpace)
+{
+  switch (pSpace->type) {
+    case Space::ALLOCATED_ARRAY: {
+      delete [] pSpace->data;
+      break;
+    }
+    case Space::MMAPED: {
+      ::munmap(pSpace->data, pSpace->size);
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+MemoryArea::Space::Type MemoryArea::policy(off_t pOffset, size_t pLength)
+{
+  const size_t threshold = (PageSize*3)/4; // 3/4 page size in Linux
+  if (pLength < threshold)
+    return Space::ALLOCATED_ARRAY;
+  else
+    return Space::MMAPED;
+}
+
+ssize_t MemoryArea::readToBuffer(sys::fs::detail::Address pBuf,
+                                 size_t pSize, size_t pOffset) {
+  assert(((m_AccessFlags & AccessMask) != WriteOnly) &&
+         "Write-only file cannot be read!");
+
+  ssize_t read_bytes = sys::fs::detail::pread(m_FileDescriptor, pBuf,
+                                              pSize, pOffset);
+  if (static_cast<size_t>(read_bytes) != pSize) {
+    // Some error occurred during pread().
+    if (read_bytes < 0) {
+      m_State |= FailBit;
+    }
+    else if (static_cast<size_t>(read_bytes) < pSize) {
+      m_State |= EOFBit;
+      if ((m_AccessFlags & AccessMask) != ReadWrite) {
+        // Files which is not read-write are not allowed read beyonds the EOF
+        // marker.
+        m_State |= BadBit;
+      }
+    }
+    else {
+      m_State |= BadBit;
+    }
+  }
+  return read_bytes;
+}
+
+bool MemoryArea::read(Space& pSpace) {
+  if (!isGood() || !isReadable())
+    return false;
+
+  if (pSpace.type == Space::ALLOCATED_ARRAY) {
+    readToBuffer(pSpace.data, pSpace.size, pSpace.file_offset);
+    return isGood();
+  }
+  else {
+    // Data associated with mmap()'ed space is already at the position the
+    // pSpace points to.
+    assert((pSpace.type == Space::MMAPED) && "Unknown type of Space!");
+    return true;
+  }
+}
+
+
+void MemoryArea::write(const Space& pSpace)
+{
+  if (!isMapped() || !isGood() || !isWritable())
+    return;
+
+  switch(pSpace.type) {
+    case Space::MMAPED: {
+      if(-1 == ::msync(pSpace.data, pSpace.size, MS_SYNC))
+        m_State |= FailBit;
+      return;
+    }
+    case Space::ALLOCATED_ARRAY: {
+      ssize_t write_bytes = sys::fs::detail::pwrite(m_FileDescriptor,
+                                                    pSpace.data,
+                                                    pSpace.size,
+                                                    pSpace.file_offset);
+      if (0 > write_bytes) {
+        m_State |= FailBit;
+        return;
+      }
+      if (0 == write_bytes && 0 != pSpace.size)
+        m_State |= BadBit;
+      if ( pSpace.size > static_cast<size_t>(write_bytes) )
+        m_State |= EOFBit;
+      return;
+    }
+    default:
+      return;
+  }
+}
+
diff --git a/lib/Support/MemoryAreaFactory.cpp b/lib/Support/MemoryAreaFactory.cpp
new file mode 100644
index 0000000..1f7e523
--- /dev/null
+++ b/lib/Support/MemoryAreaFactory.cpp
@@ -0,0 +1,52 @@
+//===- MemoryAreaFactory.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/RegionFactory.h"
+
+using namespace mcld;
+
+//==========================
+// MemoryAreaFactory
+MemoryAreaFactory::MemoryAreaFactory(size_t pNum)
+  : UniqueGCFactoryBase<sys::fs::Path, MemoryArea, 0>(pNum) {
+  // For each loaded file, MCLinker must load ELF header, section header,
+  // symbol table, and string table. So, we set the size of chunk quadruple
+  // larger than the number of input files.
+  m_pRegionFactory = new RegionFactory(pNum*4);
+}
+
+MemoryAreaFactory::~MemoryAreaFactory()
+{
+  delete m_pRegionFactory;
+}
+
+MemoryArea* MemoryAreaFactory::produce(const sys::fs::Path& pPath, int pFlags)
+{
+  MemoryArea* result = find(pPath);
+  if (0 == result) {
+    result = allocate();
+    new (result) MemoryArea(*m_pRegionFactory);
+    result->map(pPath, pFlags);
+    f_KeyMap.insert(std::make_pair(pPath, result));
+  }
+  return result;
+}
+
+MemoryArea* MemoryAreaFactory::produce(const sys::fs::Path& pPath, int pFlags, mode_t pMode)
+{
+  MemoryArea* result = find(pPath);
+  if (0 == result) {
+    result = allocate();
+    new (result) MemoryArea(*m_pRegionFactory);
+    result->map(pPath, pFlags, pMode);
+    f_KeyMap.insert(std::make_pair(pPath, result));
+  }
+  return result;
+}
+
diff --git a/lib/Support/MemoryRegion.cpp b/lib/Support/MemoryRegion.cpp
new file mode 100644
index 0000000..3a35f4e
--- /dev/null
+++ b/lib/Support/MemoryRegion.cpp
@@ -0,0 +1,34 @@
+//===- MemoryRegion.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/MemoryRegion.h>
+
+using namespace mcld;
+
+//==========================
+// MemoryRegion
+MemoryRegion::MemoryRegion(MemoryArea::Space *pParentSpace,
+                           const MemoryRegion::Address pVMAStart,
+                           size_t pSize)
+  : m_pParentSpace(pParentSpace), m_VMAStart(pVMAStart), m_Length(pSize) {
+  m_pParentSpace->region_num++;
+}
+
+MemoryRegion::~MemoryRegion()
+{
+  drift();
+}
+
+void MemoryRegion::drift()
+{
+  if (NULL == m_pParentSpace)
+    return;
+  m_pParentSpace->region_num--;
+  m_pParentSpace = NULL;
+}
+
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
new file mode 100644
index 0000000..ffb449f
--- /dev/null
+++ b/lib/Support/Path.cpp
@@ -0,0 +1,211 @@
+//===- Path.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+#include <llvm/ADT/StringRef.h>
+
+#include <locale>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+
+//===--------------------------------------------------------------------===//
+// Path
+Path::Path()
+  : m_PathName() {
+}
+
+Path::Path(const Path::ValueType* s )
+  : m_PathName(s) {
+}
+
+Path::Path(const Path::StringType &s )
+  : m_PathName(s) {
+}
+
+Path::Path(const Path& pCopy)
+ : m_PathName(pCopy.m_PathName) {
+}
+
+Path::~Path()
+{
+}
+
+bool Path::isFromRoot() const
+{
+  if (m_PathName.empty())
+    return false;
+  return (separator == m_PathName[0]);
+}
+
+bool Path::isFromPWD() const
+{
+  if (2 > m_PathName.size())
+    return false;
+  return ('.' == m_PathName[0] && separator == m_PathName[1]);
+}
+
+Path& Path::assign(const Path::StringType &s)
+{
+  m_PathName.assign(s);
+  return *this;
+}
+
+Path& Path::assign(const Path::ValueType* s, unsigned int length)
+{
+  if (0 == s || 0 == length)
+    assert(0 && "assign a null or empty string to Path");
+  m_PathName.assign(s, length);
+  return *this;
+}
+
+//a,/b a/,b a/,b/ a,b is a/b
+Path& Path::append(const Path& pPath)
+{
+  //first path is a/,second path is /b
+  if(m_PathName[m_PathName.length()-1] == separator &&
+     pPath.native()[0] == separator) {
+    unsigned int old_size = m_PathName.size()-1;
+    unsigned int new_size = old_size + pPath.native().size();
+
+    m_PathName.resize(new_size);
+    strcpy(const_cast<char*>(m_PathName.data()+old_size), pPath.native().data());
+  }
+  //first path is a,second path is b
+  else if(this->string()[this->native().size()-1] != separator &&
+          pPath.string()[0] != separator) {
+    m_PathName.append("/");
+    m_PathName.append(pPath.native());
+  }
+  // a/,b or a,/b just append
+  else {
+    m_PathName.append(pPath.native());
+  }
+  return *this;
+}
+
+bool Path::empty() const
+{
+  return m_PathName.empty();
+}
+
+std::string Path::string() const
+{
+  return m_PathName;
+}
+
+Path::StringType Path::generic_string() const
+{
+  std::string result = m_PathName;
+  detail::canonicalize(result);
+  return result;
+}
+
+bool Path::canonicalize()
+{
+  return detail::canonicalize(m_PathName);
+}
+
+Path::StringType::size_type Path::m_append_separator_if_needed()
+{
+  if (!m_PathName.empty() &&
+#ifdef LLVM_ON_WIN32
+      *(m_PathName.end()-1) != colon &&
+#endif
+      !is_separator(*(m_PathName.end()-1))) {
+        StringType::size_type tmp(m_PathName.size());
+        m_PathName += preferred_separator;
+        return tmp;
+  }
+  return 0;
+}
+
+void Path::m_erase_redundant_separator(Path::StringType::size_type pSepPos)
+{
+  size_t begin=pSepPos;
+  // skip '/'
+  while(separator == m_PathName[pSepPos])
+    ++pSepPos;
+
+  if(begin!=pSepPos)
+    m_PathName.erase(begin+1,pSepPos-begin-1);
+}
+
+Path Path::stem() const
+{
+  size_t begin_pos = m_PathName.find_last_of(separator)+1;
+  size_t end_pos   = m_PathName.find_first_of(".", begin_pos);
+  Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
+  return result_path;
+}
+
+Path Path::extension() const
+{
+  size_t begin_pos = m_PathName.find_last_of('.');
+  Path result_path(m_PathName.substr(begin_pos));
+  return result_path;
+}
+
+//===--------------------------------------------------------------------===//
+// non-member functions
+bool mcld::sys::fs::operator==(const Path& pLHS,const Path& pRHS)
+{
+  return (pLHS.generic_string()==pRHS.generic_string());
+}
+
+bool mcld::sys::fs::operator!=(const Path& pLHS,const Path& pRHS)
+{
+  return !(pLHS==pRHS);
+}
+
+bool mcld::sys::fs::is_separator(char value)
+{
+  return (value == separator
+#ifdef LLVM_ON_WIN32
+          || value == preferred_separator
+#endif
+          );
+}
+
+bool mcld::sys::fs::exists(const Path &pPath)
+{
+  FileStatus pFileStatus;
+  detail::status(pPath, pFileStatus);
+  return exists(pFileStatus);
+}
+
+bool mcld::sys::fs::is_directory(const Path &pPath)
+{
+  FileStatus pFileStatus;
+  detail::status(pPath, pFileStatus);
+  return is_directory(pFileStatus);
+}
+
+std::ostream &mcld::sys::fs::operator<<(std::ostream& pOS,
+                                        const Path& pPath)
+{
+  return pOS << pPath.native();
+}
+
+std::istream &mcld::sys::fs::operator>>(std::istream& pOS,
+                                        Path& pPath)
+{
+  return pOS >> pPath.native();
+}
+
+llvm::raw_ostream &mcld::sys::fs::operator<<(llvm::raw_ostream &pOS,
+                                             const Path &pPath)
+{
+  return pOS << pPath.native();
+}
+
diff --git a/lib/Support/RealPath.cpp b/lib/Support/RealPath.cpp
new file mode 100644
index 0000000..2b641e8
--- /dev/null
+++ b/lib/Support/RealPath.cpp
@@ -0,0 +1,59 @@
+//===- RealPath.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/RealPath.h"
+#include "mcld/Support/FileSystem.h"
+
+using namespace mcld::sys::fs;
+
+//==========================
+// RealPath
+RealPath::RealPath()
+  : Path() {
+}
+
+RealPath::RealPath(const RealPath::ValueType* s )
+  : Path(s) {
+  initialize();
+}
+
+RealPath::RealPath(const RealPath::StringType &s )
+  : Path(s) {
+  initialize();
+}
+
+RealPath::RealPath(const Path& pPath)
+ : Path(pPath) {
+  initialize();
+}
+
+RealPath::~RealPath()
+{
+}
+
+RealPath& RealPath::assign(const Path& pPath)
+{
+  Path::m_PathName.assign(pPath.native());
+  return (*this);
+}
+
+void RealPath::initialize()
+{
+  if (isFromRoot()) {
+    detail::canonicalize(m_PathName);
+  }
+  else if (isFromPWD()) {
+    std::string path_name;
+    detail::get_pwd(path_name);
+    path_name += '/';
+    path_name += m_PathName;
+    detail::canonicalize(path_name);
+    m_PathName = path_name;
+  }
+}
+
diff --git a/lib/Support/RegionFactory.cpp b/lib/Support/RegionFactory.cpp
new file mode 100644
index 0000000..e87d389
--- /dev/null
+++ b/lib/Support/RegionFactory.cpp
@@ -0,0 +1,39 @@
+//===- RegionFactory.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/RegionFactory.h"
+#include "mcld/Support/MemoryArea.h"
+
+using namespace mcld;
+
+//==========================
+// RegionFactory
+RegionFactory::RegionFactory(size_t pNum)
+  : GCFactory<MemoryRegion, 0>(pNum) {
+}
+
+RegionFactory::~RegionFactory()
+{
+}
+
+MemoryRegion* RegionFactory::produce(MemoryArea::Space* pSpace,
+                                     const sys::fs::detail::Address pVMAStart,
+                                     size_t pSize)
+{
+  MemoryRegion* result = Alloc::allocate();
+  new (result) MemoryRegion(pSpace, pVMAStart, pSize);
+  return result;
+}
+
+void RegionFactory::destruct(MemoryRegion* pRegion)
+{
+  pRegion->drift();
+  destroy(pRegion);
+  deallocate(pRegion);
+}
+
diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp
new file mode 100644
index 0000000..246cbe8
--- /dev/null
+++ b/lib/Support/TargetRegistry.cpp
@@ -0,0 +1,42 @@
+//===- TargetRegistry.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/TargetRegistry.h"
+
+
+mcld::TargetRegistry::TargetListTy mcld::TargetRegistry::s_TargetList;
+
+/* ** */
+
+void mcld::TargetRegistry::RegisterTarget(mcld::Target &T)
+{
+  s_TargetList.push_back(&T);
+}
+
+const mcld::Target* mcld::TargetRegistry::lookupTarget(const llvm::Target &pTarget)
+{
+  mcld::Target *result = 0;
+  TargetListTy::const_iterator TIter, TEnd = s_TargetList.end();
+  for (TIter=s_TargetList.begin(); TIter!=TEnd; ++TIter) {
+    if ((*TIter)->get()==&pTarget) {
+      result = (*TIter);
+      break;
+    }
+  }
+  return result;
+}
+
+const mcld::Target *mcld::TargetRegistry::lookupTarget(const std::string &pTriple,
+                                                       std::string &pError) 
+{
+  const llvm::Target* target = llvm::TargetRegistry::lookupTarget( pTriple, pError );
+  if (!target)
+    return 0;
+  return lookupTarget( *target );
+}
+
diff --git a/lib/Support/UniqueGCFactory.cpp b/lib/Support/UniqueGCFactory.cpp
new file mode 100644
index 0000000..2352181
--- /dev/null
+++ b/lib/Support/UniqueGCFactory.cpp
@@ -0,0 +1,15 @@
+//===- UniqueGCFactory.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <UniqueGCFactory.h>
+
+using namespace mcld;
+
+//==========================
+// UniqueGCFactory
+
diff --git a/lib/Support/Unix/FileSystem.inc b/lib/Support/Unix/FileSystem.inc
new file mode 100644
index 0000000..6499d66
--- /dev/null
+++ b/lib/Support/Unix/FileSystem.inc
@@ -0,0 +1,45 @@
+//===- FileSystem.inc -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+namespace mcld{
+namespace sys{
+namespace fs{
+namespace detail{
+
+std::string static_library_extension = ".a";
+std::string shared_library_extension = ".so";
+std::string executable_extension = "";
+std::string relocatable_extension = ".o";
+std::string assembly_extension = ".s";
+std::string bitcode_extension = ".bc";
+
+size_t pread(int pFD, Address pBuf, size_t pCount, off_t pOffset)
+{
+  return ::pread(pFD, (void*) pBuf, pCount, pOffset);
+}
+
+size_t pwrite(int pFD, const Address pBuf, size_t pCount, off_t pOffset)
+{
+  return ::pwrite(pFD, (const void*) pBuf, pCount, pOffset);
+}
+
+char *strerror(int errnum)
+{
+  return ::strerror(errnum);
+}
+
+} // namespace of detail
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
diff --git a/lib/Support/Unix/PathV3.inc b/lib/Support/Unix/PathV3.inc
new file mode 100644
index 0000000..2e8e6d0
--- /dev/null
+++ b/lib/Support/Unix/PathV3.inc
@@ -0,0 +1,299 @@
+//===- PathV3.inc ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Support/Directory.h>
+#include <mcld/Support/Path.h>
+#include <llvm/Support/ErrorHandling.h>
+
+#include <cerrno>
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string>
+#include <stack>
+#include <unistd.h>
+
+namespace mcld{
+namespace sys{
+namespace fs{
+namespace detail{
+
+const char          separator = '/';
+const char          preferred_separator = '/';
+
+// return the last charactor being handled.
+size_t canonicalize(std::string& pathname)
+{
+  // Variable Index //
+  // SepTable - stack of result separators
+  // LR(1) Algorithm //
+  // traverse pPathName
+  //   if we meet '//', '///', '////', ...
+  //     -> ignore it
+  //     -> push current into stack
+  //     -> jump to the next not '/'
+  //   if we meet '/./'
+  //     -> ignore
+  //     -> jump to the next not '/'
+  //   if we meet '/../'
+  //     -> pop previous position of '/' P
+  //     -> erase P+1 to now
+  //   if we meet other else
+  //     -> go go go
+  //   if we meet '/.../', '/..../', ... -> illegal
+  if (pathname.empty())
+    return 0;
+
+  size_t handler = 0;
+  std::stack<size_t> slash_stack;
+  slash_stack.push(-1);
+  while (handler < pathname.size()) {
+    if (separator == pathname[handler]) { // handler = 1st '/'
+      size_t next = handler + 1;
+      if (next >= pathname.size())
+        return handler;
+      switch(pathname[next]) { // next = handler + 1;
+        case separator: { // '//'
+          while (next < pathname.size() && separator == pathname[next])
+            ++next;
+          // next is the last not '/'
+          pathname.erase(handler, next - handler - 1);
+          // handler is the first '/'
+          slash_stack.push(handler);
+          break;
+        }
+        case '.': { // '/.'
+          ++next; // next = handler + 2
+          if (next >= pathname.size()) // '/.'
+            return handler;
+          switch (pathname[next]) {
+            case separator: { // '/./'
+              pathname.erase(handler, 2);
+              break;
+            }
+            case '.': { // '/..'
+              ++next; // next = handler + 3;
+              if (next >= pathname.size()) // '/..?'
+                return handler;
+              switch(pathname[next]) {
+                case separator: { // '/../'
+                  handler = slash_stack.top();
+                  slash_stack.pop();
+                  pathname.erase(handler+1, next-handler);
+                  if (static_cast<size_t>(-1) == handler) {
+                    slash_stack.push(-1);
+                    handler = pathname.find_first_of(separator, handler);
+                  }
+                  break;
+                }
+                case '.': { // '/...', illegal
+                  return handler;
+                  break;
+                }
+                default : { // '/..a'
+                  slash_stack.push(handler);
+                  handler = pathname.find_first_of(separator, handler+3);
+                  break;
+                }
+              }
+              break;
+            }
+            default : { // '/.a'
+              slash_stack.push(handler);
+              handler = pathname.find_first_of(separator, handler+2);
+              break;
+            }
+          }
+          break;
+        }
+        default : { // '/a
+          slash_stack.push(handler);
+          handler = pathname.find_first_of(separator, handler+1);
+          break;
+        }
+      }
+    }
+    else {
+      handler = pathname.find_first_of(separator, handler);
+    }
+  }
+  return handler;
+}
+
+bool not_found_error(int perrno)
+{
+  return perrno == ENOENT || perrno == ENOTDIR;
+}
+
+void status(const Path& p, FileStatus& pFileStatus)
+{
+  struct stat path_stat;
+  if(stat(p.c_str(), &path_stat)!= 0)
+  {
+    if(not_found_error(errno))
+    {
+      pFileStatus.setType(FileNotFound);
+    }
+    else
+      pFileStatus.setType(StatusError);
+  }
+  else if(S_ISDIR(path_stat.st_mode))
+    pFileStatus.setType(DirectoryFile);
+  else if(S_ISREG(path_stat.st_mode))
+    pFileStatus.setType(RegularFile);
+  else if(S_ISBLK(path_stat.st_mode))
+    pFileStatus.setType(BlockFile);
+  else if(S_ISCHR(path_stat.st_mode))
+    pFileStatus.setType(CharacterFile);
+  else if(S_ISFIFO(path_stat.st_mode))
+    pFileStatus.setType(FifoFile);
+  else if(S_ISSOCK(path_stat.st_mode))
+    pFileStatus.setType(SocketFile);
+  else
+    pFileStatus.setType(TypeUnknown);
+}
+
+void symlink_status(const Path& p, FileStatus& pFileStatus)
+{
+  struct stat path_stat;
+  if(lstat(p.c_str(), &path_stat)!= 0)
+  {
+    if(errno == ENOENT || errno == ENOTDIR) // these are not errors
+    {
+      pFileStatus.setType(FileNotFound);
+    }
+    else
+      pFileStatus.setType(StatusError);
+  }
+  if(S_ISREG(path_stat.st_mode))
+    pFileStatus.setType(RegularFile);
+  if(S_ISDIR(path_stat.st_mode))
+    pFileStatus.setType(DirectoryFile);
+  if(S_ISLNK(path_stat.st_mode))
+    pFileStatus.setType(SymlinkFile);
+  if(S_ISBLK(path_stat.st_mode))
+    pFileStatus.setType(BlockFile);
+  if(S_ISCHR(path_stat.st_mode))
+    pFileStatus.setType(CharacterFile);
+  if(S_ISFIFO(path_stat.st_mode))
+    pFileStatus.setType(FifoFile);
+  if(S_ISSOCK(path_stat.st_mode))
+    pFileStatus.setType(SocketFile);
+  else
+    pFileStatus.setType(TypeUnknown);
+}
+
+/// read_dir - return true if we read one entry
+//  @return value -1: read error
+//                 0: read the end
+//                 1: success
+static int read_dir(intptr_t& pDir, std::string& pOutFilename)
+{
+  errno = 0;
+  dirent *cur_dir = ::readdir(reinterpret_cast<DIR*>(pDir));
+  if (0 == cur_dir && 0 != errno)
+    return -1;
+
+  // idx does not stay at the end, but all elements had beed put into cache.
+  if (NULL == cur_dir) {
+    return 0;
+  }
+
+  llvm::StringRef name(cur_dir->d_name, strlen(cur_dir->d_name));
+  if ((name.size() == 1 && name[0] == '.') ||
+      (name.size() == 2 && name[0] == '.' && name[1] == '.'))
+    return read_dir(pDir, pOutFilename);
+
+  // find a new directory
+  pOutFilename.append(name.data(), name.size());
+  return 1;
+}
+
+/// directory_iterator_increment - increment function implementation
+//
+//  iterator will call this function in two situations:
+//  1. All elements have been put into cache, and iterator stays at the end
+//     of cache. (a real end)
+//  2. Some but not all elements had beed put into cache, and we stoped.
+//     An iterator now is staying at the end of cache. (a temporal end)
+mcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter)
+{
+  mcld::sys::fs::PathCache::entry_type* entry = 0;
+  std::string path(pIter.m_pParent->m_Path.native());
+  switch (read_dir(pIter.m_pParent->m_Handler, path)) {
+  case 1: {
+    // read one
+    bool exist = false;
+    entry = pIter.m_pParent->m_Cache.insert(path, exist);
+    if (!exist)
+      entry->setValue(new Path(path));
+    break;
+  }
+  case 0:// meet real end
+    pIter.m_pParent->m_CacheFull = true;
+    break;
+  default:
+  case -1:
+    llvm::report_fatal_error(std::string("Can't read directory: ")+
+                             pIter.m_pParent->path().native());
+    break;
+  }
+  return entry;
+}
+
+void open_dir(Directory& pDir)
+{
+  pDir.m_Handler = reinterpret_cast<intptr_t>(opendir(pDir.path().c_str()));
+  if (pDir.m_Handler == 0) {
+    errno = 0; // opendir() will set errno if it failed to open directory.
+    pDir.m_CacheFull = true;
+    return;
+  }
+  // read one entry for advance the end element of the cache.
+  std::string path(pDir.path().native());
+  switch (read_dir(pDir.m_Handler, path)) {
+  case 1: {
+    // find a new directory
+    bool exist = false;
+    mcld::sys::fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist);
+    if (!exist)
+      entry->setValue(new Path(path));
+    return;
+  }
+  case 0:
+    // FIXME: a warning function
+    pDir.m_CacheFull = true;
+    return;
+  default:
+  case -1:
+    llvm::report_fatal_error(std::string("Can't read directory: ")+
+                             pDir.path().native());
+  }
+}
+
+void close_dir(Directory& pDir)
+{
+  if (pDir.m_Handler)
+    closedir(reinterpret_cast<DIR *>(pDir.m_Handler));
+  pDir.m_Handler = NULL;
+}
+
+void get_pwd(std::string& pPWD)
+{
+  char* pwd = (char*)malloc(PATH_MAX);
+  pPWD.assign(getcwd(pwd, PATH_MAX));
+  free(pwd);
+}
+
+} // namespace of detail
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
diff --git a/lib/Support/Windows/FileSystem.inc b/lib/Support/Windows/FileSystem.inc
new file mode 100644
index 0000000..4cacf4c
--- /dev/null
+++ b/lib/Support/Windows/FileSystem.inc
@@ -0,0 +1,28 @@
+//===- FileSystem.inc -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <string>
+
+namespace mcld{
+namespace sys{
+namespace fs{
+namespace detail{
+
+std::string static_library_extension = ".lib";
+std::string shared_library_extension = ".dll";
+std::string executable_extension = ".exe";
+std::string relocatable_extension = ".obj";
+std::string assembly_extension = ".s";
+std::string bitcode_extension = ".bc";
+
+
+} // namespace of detail
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
diff --git a/lib/Support/Windows/PathV3.inc b/lib/Support/Windows/PathV3.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/Support/Windows/PathV3.inc
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
new file mode 100644
index 0000000..a128998
--- /dev/null
+++ b/lib/Target/ARM/ARM.h
@@ -0,0 +1,24 @@
+//===- ARM.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_H
+#define MCLD_ARM_H
+#include <string>
+#include "mcld/Target/TargetMachine.h"
+
+namespace mcld {
+class TargetLDBackend;
+
+extern mcld::Target TheARMTarget;
+
+TargetLDBackend *createARMLDBackend(const llvm::Target&, const std::string&);
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMAndroidSectLinker.cpp b/lib/Target/ARM/ARMAndroidSectLinker.cpp
new file mode 100644
index 0000000..a704cfa
--- /dev/null
+++ b/lib/Target/ARM/ARMAndroidSectLinker.cpp
@@ -0,0 +1,35 @@
+//===- ARMAndroidSectLinker.cpp -------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARMAndroidSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+ARMAndroidSectLinker::ARMAndroidSectLinker(SectLinkerOption &pOption,
+                                           TargetLDBackend &pLDBackend)
+  : AndroidSectLinker(pOption,
+                      pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attributes
+  info.attrFactory().constraint().disableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().unsetWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+
+}
+
+ARMAndroidSectLinker::~ARMAndroidSectLinker()
+{
+}
+
diff --git a/lib/Target/ARM/ARMAndroidSectLinker.h b/lib/Target/ARM/ARMAndroidSectLinker.h
new file mode 100644
index 0000000..8a47a94
--- /dev/null
+++ b/lib/Target/ARM/ARMAndroidSectLinker.h
@@ -0,0 +1,40 @@
+//===- ARMAndroidSectLinker.h ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARM_ANDROIDSECTLINKER_H
+#define ARM_ANDROIDSECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Target/AndroidSectLinker.h>
+
+namespace mcld
+{
+
+class MCLDInfo;
+
+/** \class ARMAndroidSectLinker
+ *  \brief ARMAndroidSectLinker sets up the environment for linking.
+ *
+ *  \see
+ *  \author Anders Cheng <Anders.Cheng@mediatek.com>
+ */
+class ARMAndroidSectLinker : public AndroidSectLinker
+{
+public:
+  ARMAndroidSectLinker(SectLinkerOption &pOption,
+                       mcld::TargetLDBackend &pLDBackend);
+
+  ~ARMAndroidSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMELFArchiveReader.cpp b/lib/Target/ARM/ARMELFArchiveReader.cpp
new file mode 100644
index 0000000..4c6d775
--- /dev/null
+++ b/lib/Target/ARM/ARMELFArchiveReader.cpp
@@ -0,0 +1,14 @@
+//===- ARMELFArchiveReader.cpp --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMELFArchiveReader.h"
+
+using namespace mcld;
+
+//==========================
+// ARMELFArchiveReader
diff --git a/lib/Target/ARM/ARMELFArchiveReader.h b/lib/Target/ARM/ARMELFArchiveReader.h
new file mode 100644
index 0000000..b60a12d
--- /dev/null
+++ b/lib/Target/ARM/ARMELFArchiveReader.h
@@ -0,0 +1,29 @@
+//===- ARMELFArchiveReader.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef ARMELFARCHIVEREADER_H
+#define ARMELFARCHIVEREADER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/MC/MCELFArchiveTargetReader.h"
+
+namespace mcld
+{
+
+/// ARMELFArchiveReader - ARMELFArchiveReader is
+/// a target-dependent reader for ELF archive files.
+class ARMELFArchiveReader : public MCELFArchiveTargetReader
+{
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMELFDynamic.cpp b/lib/Target/ARM/ARMELFDynamic.cpp
new file mode 100644
index 0000000..c81a6f3
--- /dev/null
+++ b/lib/Target/ARM/ARMELFDynamic.cpp
@@ -0,0 +1,37 @@
+//===- ARMELFDynamic.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/ELFFileFormat.h>
+#include "ARMELFDynamic.h"
+
+using namespace mcld;
+
+ARMELFDynamic::ARMELFDynamic(const GNULDBackend& pParent)
+  : ELFDynamic(pParent)
+{
+}
+
+ARMELFDynamic::~ARMELFDynamic()
+{
+}
+
+void ARMELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat)
+{
+  // reservePLTGOT
+  if (pFormat.hasGOT())
+    reserveOne(llvm::ELF::DT_PLTGOT);
+}
+
+void ARMELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
+{
+  // applyPLTGOT
+  if (pFormat.hasGOT())
+    applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr());
+}
+
diff --git a/lib/Target/ARM/ARMELFDynamic.h b/lib/Target/ARM/ARMELFDynamic.h
new file mode 100644
index 0000000..914dcc4
--- /dev/null
+++ b/lib/Target/ARM/ARMELFDynamic.h
@@ -0,0 +1,31 @@
+//===- ARMELFDynamic.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_ELFDYNAMIC_SECTION_H
+#define MCLD_ARM_ELFDYNAMIC_SECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Target/ELFDynamic.h>
+
+namespace mcld {
+
+class ARMELFDynamic : public ELFDynamic {
+public:
+  ARMELFDynamic(const GNULDBackend& pParent);
+  ~ARMELFDynamic();
+
+private:
+  void reserveTargetEntries(const ELFFileFormat& pFormat);
+  void applyTargetEntries(const ELFFileFormat& pFormat);
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/ARM/ARMELFSectLinker.cpp b/lib/Target/ARM/ARMELFSectLinker.cpp
new file mode 100644
index 0000000..0395606
--- /dev/null
+++ b/lib/Target/ARM/ARMELFSectLinker.cpp
@@ -0,0 +1,34 @@
+//===- ARMELFSectLinker.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMELFSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+ARMELFSectLinker::ARMELFSectLinker(SectLinkerOption &pOption,
+                                   TargetLDBackend &pLDBackend)
+  : SectLinker(pOption,
+               pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attributes
+  info.attrFactory().constraint().enableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().setWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+
+}
+
+ARMELFSectLinker::~ARMELFSectLinker()
+{
+}
+
diff --git a/lib/Target/ARM/ARMELFSectLinker.h b/lib/Target/ARM/ARMELFSectLinker.h
new file mode 100644
index 0000000..7493d59
--- /dev/null
+++ b/lib/Target/ARM/ARMELFSectLinker.h
@@ -0,0 +1,36 @@
+//===- ARMELFSectLinker.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef ARM_ELFSECTLINKER_H
+#define ARM_ELFSECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/CodeGen/SectLinker.h>
+
+namespace mcld
+{
+
+/** \class ARMELFSectLinker
+ *  \brief ARMELFSectLinker sets up the environment for linking.
+ *
+ *  \see
+ */
+class ARMELFSectLinker : public SectLinker
+{
+public:
+  ARMELFSectLinker(SectLinkerOption &pOption,
+                   mcld::TargetLDBackend &pLDBackend);
+
+  ~ARMELFSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h
new file mode 100644
index 0000000..f42b940
--- /dev/null
+++ b/lib/Target/ARM/ARMFixupKinds.h
@@ -0,0 +1,98 @@
+//===- ARMFixupKinds.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LIB_TARGET_ARM_ARM_FIXUP_KINDS_H_
+#define MCLD_LIB_TARGET_ARM_ARM_FIXUP_KINDS_H_
+
+#include <llvm/MC/MCFixup.h>
+
+namespace mcld {
+namespace ARM {
+
+enum Fixups {
+  // fixup_arm_ldst_pcrel_12 - 12-bit PC relative relocation for symbol
+  // addresses
+  fixup_arm_ldst_pcrel_12 = FirstTargetFixupKind,
+
+  // fixup_t2_ldst_pcrel_12 - Equivalent to fixup_arm_ldst_pcrel_12, with
+  // the 16-bit halfwords reordered.
+  fixup_t2_ldst_pcrel_12,
+
+  // fixup_arm_pcrel_10 - 10-bit PC relative relocation for symbol addresses
+  // used in VFP instructions where the lower 2 bits are not encoded
+  // (so it's encoded as an 8-bit immediate).
+  fixup_arm_pcrel_10,
+  // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for
+  // the short-swapped encoding of Thumb2 instructions.
+  fixup_t2_pcrel_10,
+  // fixup_thumb_adr_pcrel_10 - 10-bit PC relative relocation for symbol
+  // addresses where the lower 2 bits are not encoded (so it's encoded as an
+  // 8-bit immediate).
+  fixup_thumb_adr_pcrel_10,
+  // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
+  // instruction.
+  fixup_arm_adr_pcrel_12,
+  // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
+  // instruction.
+  fixup_t2_adr_pcrel_12,
+  // fixup_arm_condbranch - 24-bit PC relative relocation for conditional branch
+  // instructions. 
+  fixup_arm_condbranch,
+  // fixup_arm_uncondbranch - 24-bit PC relative relocation for 
+  // branch instructions. (unconditional)
+  fixup_arm_uncondbranch,
+  // fixup_t2_condbranch - 20-bit PC relative relocation for Thumb2 direct
+  // unconditional branch instructions.
+  fixup_t2_condbranch,
+  // fixup_t2_uncondbranch - 20-bit PC relative relocation for Thumb2 direct
+  // branch unconditional branch instructions.
+  fixup_t2_uncondbranch,
+
+  // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
+  fixup_arm_thumb_br,
+
+  // fixup_arm_thumb_bl - Fixup for Thumb BL instructions.
+  fixup_arm_thumb_bl,
+
+  // fixup_arm_thumb_blx - Fixup for Thumb BLX instructions.
+  fixup_arm_thumb_blx,
+
+  // fixup_arm_thumb_cb - Fixup for Thumb branch instructions.
+  fixup_arm_thumb_cb,
+
+  // fixup_arm_thumb_cp - Fixup for Thumb load/store from constant pool instrs.
+  fixup_arm_thumb_cp,
+
+  // fixup_arm_thumb_bcc - Fixup for Thumb conditional branching instructions.
+  fixup_arm_thumb_bcc,
+
+  // The next two are for the movt/movw pair
+  // the 16bit imm field are split into imm{15-12} and imm{11-0}
+  fixup_arm_movt_hi16, // :upper16:
+  fixup_arm_movw_lo16, // :lower16:
+  fixup_t2_movt_hi16, // :upper16:
+  fixup_t2_movw_lo16, // :lower16:
+
+  // It is possible to create an "immediate" that happens to be pcrel.
+  // movw r0, :lower16:Foo-(Bar+8) and movt  r0, :upper16:Foo-(Bar+8)
+  // result in different reloc tags than the above two.
+  // Needed to support ELF::R_ARM_MOVT_PREL and ELF::R_ARM_MOVW_PREL_NC
+  fixup_arm_movt_hi16_pcrel, // :upper16:
+  fixup_arm_movw_lo16_pcrel, // :lower16:
+  fixup_t2_movt_hi16_pcrel, // :upper16:
+  fixup_t2_movw_lo16_pcrel, // :lower16:
+
+  // Marker
+  LastTargetFixupKind,
+  NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+
+} // namespace ARM
+} // namespace mcld
+
+#endif
diff --git a/lib/Target/ARM/ARMGOT.cpp b/lib/Target/ARM/ARMGOT.cpp
new file mode 100644
index 0000000..3eb8e4a
--- /dev/null
+++ b/lib/Target/ARM/ARMGOT.cpp
@@ -0,0 +1,185 @@
+//===- impl.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMGOT.h"
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <new>
+
+namespace {
+  const size_t ARMGOTEntrySize = 4;
+} // end of anonymous namespace
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// ARMGOT
+ARMGOT::ARMGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+             : GOT(pSection, pSectionData, ARMGOTEntrySize),
+               m_NormalGOTIterator(), m_GOTPLTIterator(),
+               m_GOTPLTBegin(), m_GOTPLTEnd()
+{
+  GOTEntry* Entry = 0;
+
+  // Create GOT0 entries.
+  for (int i = 0; i < 3; i++) {
+    Entry = new (std::nothrow) GOTEntry(0, ARMGOTEntrySize,
+                                        &m_SectionData);
+
+    if (!Entry)
+      llvm::report_fatal_error("Allocating GOT0 entries failed!");
+
+    m_Section.setSize(m_Section.size() + ARMGOTEntrySize);
+  }
+
+  // Skip GOT0 entries.
+  iterator it = m_SectionData.begin();
+  iterator ie = m_SectionData.end();
+
+  for (int i = 1; i < ARMGOT0Num; ++i) {
+    if (it == ie)
+      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
+
+    ++it;
+  }
+
+  m_NormalGOTIterator = it;
+  m_GOTPLTIterator = it;
+
+  m_GOTPLTBegin = it;
+  m_GOTPLTEnd = it;
+}
+
+ARMGOT::~ARMGOT()
+{
+}
+
+void ARMGOT::reserveEntry(size_t pNum)
+{
+  GOTEntry* Entry = 0;
+
+  for (size_t i = 0; i < pNum; i++) {
+    Entry = new (std::nothrow) GOTEntry(0, ARMGOTEntrySize,
+                                        &m_SectionData);
+
+    if (!Entry)
+      llvm::report_fatal_error("Allocating new memory for GOTEntry failed");
+
+    m_Section.setSize(m_Section.size() + ARMGOTEntrySize);
+  }
+}
+
+void ARMGOT::reserveGOTPLTEntry()
+{
+    GOTEntry* got_entry = 0;
+
+    got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData()));
+
+    if (!got_entry)
+      llvm::report_fatal_error("Allocating new memory for GOT failed!");
+
+    m_Section.setSize(m_Section.size() + getEntrySize());
+
+    ++m_GOTPLTEnd;
+    ++m_NormalGOTIterator;
+}
+
+GOTEntry* ARMGOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
+{
+  GOTEntry *&Entry = m_NormalGOTMap[&pInfo];
+  pExist = 1;
+
+  if (!Entry) {
+    pExist = 0;
+
+    ++m_NormalGOTIterator;
+    assert(m_NormalGOTIterator != m_SectionData.getFragmentList().end()
+           && "The number of GOT Entries and ResolveInfo doesn't match!");
+
+    Entry = llvm::cast<GOTEntry>(&(*m_NormalGOTIterator));
+  }
+
+  return Entry;
+}
+
+void ARMGOT::applyGOT0(uint64_t pAddress)
+{
+  llvm::cast<GOTEntry>
+    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
+}
+
+void ARMGOT::applyAllGOTPLT(uint64_t pPLTBase)
+{
+  iterator begin = getGOTPLTBegin();
+  iterator end = getGOTPLTEnd();
+
+  for (;begin != end ;++begin)
+    llvm::cast<GOTEntry>(*begin).setContent(pPLTBase);
+}
+
+GOTEntry*& ARMGOT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
+{
+  return m_GOTPLTMap[&pSymbol];
+}
+
+ARMGOT::iterator ARMGOT::begin()
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+ARMGOT::const_iterator ARMGOT::begin() const
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+ARMGOT::iterator ARMGOT::end()
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+ARMGOT::const_iterator ARMGOT::end() const
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+ARMGOT::iterator ARMGOT::getNextGOTPLTEntry()
+{
+  return ++m_GOTPLTIterator;
+}
+
+ARMGOT::iterator ARMGOT::getGOTPLTBegin()
+{
+  // Move to the first GOTPLT entry from last GOT0 entry.
+  iterator begin = m_GOTPLTBegin;
+  return ++begin;
+}
+
+const ARMGOT::iterator ARMGOT::getGOTPLTEnd()
+{
+  // Move to end or the first normal GOT entry from the last GOTPLT entry.
+  iterator end = m_GOTPLTEnd;
+  return ++end;
+}
+
+uint64_t ARMGOT::emit(MemoryRegion& pRegion)
+{
+  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
+
+  GOTEntry* got = 0;
+  unsigned int entry_size = getEntrySize();
+  uint64_t result = 0x0;
+  for (iterator it = begin(), ie = end();
+       it != ie; ++it, ++buffer) {
+      got = &(llvm::cast<GOTEntry>((*it)));
+      *buffer = static_cast<uint32_t>(got->getContent());
+      result += entry_size;
+  }
+  return result;
+}
+
diff --git a/lib/Target/ARM/ARMGOT.h b/lib/Target/ARM/ARMGOT.h
new file mode 100644
index 0000000..90f0f53
--- /dev/null
+++ b/lib/Target/ARM/ARMGOT.h
@@ -0,0 +1,92 @@
+//===- ARMGOT.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_GOT_H
+#define MCLD_ARM_GOT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Target/GOT.h>
+
+namespace mcld
+{
+class LDSection;
+class MemoryRegion;
+
+/** \class ARMGOT
+ *  \brief ARM Global Offset Table.
+ */
+class ARMGOT : public GOT
+{
+  typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+  enum {
+    ARMGOT0Num = 3
+  };
+
+public:
+  ARMGOT(LDSection &pSection, llvm::MCSectionData& pSectionData);
+
+  ~ARMGOT();
+
+  iterator begin();
+
+  const_iterator begin() const;
+
+  iterator end();
+
+  const_iterator end() const;
+
+  uint64_t emit(MemoryRegion& pRegion);
+// For GOT0
+public:
+  void applyGOT0(uint64_t pAddress);
+
+// For normal GOT
+public:
+  // Reserve normal GOT entries.
+  void reserveEntry(size_t pNum = 1);
+
+  GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist);
+
+// For GOTPLT
+public:
+  void reserveGOTPLTEntry();
+
+  void applyAllGOTPLT(uint64_t pPLTBase);
+
+  GOTEntry*& lookupGOTPLTMap(const ResolveInfo& pSymbol);
+
+  iterator getNextGOTPLTEntry();
+
+  iterator getGOTPLTBegin();
+
+  const iterator getGOTPLTEnd();
+
+private:
+  // For normal GOT entries
+  iterator m_NormalGOTIterator;
+  SymbolIndexMapType m_NormalGOTMap;
+
+  // For GOTPLT entries
+  iterator m_GOTPLTIterator;
+  SymbolIndexMapType m_GOTPLTMap;
+
+  iterator m_GOTPLTBegin;
+  iterator m_GOTPLTEnd;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp
new file mode 100644
index 0000000..105a957
--- /dev/null
+++ b/lib/Target/ARM/ARMLDBackend.cpp
@@ -0,0 +1,1018 @@
+//===- ARMLDBackend.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/ADT/Triple.h>
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/ErrorHandling.h>
+
+#include <mcld/LD/SectionMap.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Support/TargetRegistry.h>
+
+#include <cstring>
+
+#include "ARM.h"
+#include "ARMELFDynamic.h"
+#include "ARMLDBackend.h"
+#include "ARMRelocationFactory.h"
+
+using namespace mcld;
+
+ARMGNULDBackend::ARMGNULDBackend()
+  : m_pRelocFactory(NULL),
+    m_pGOT(NULL),
+    m_pPLT(NULL),
+    m_pRelDyn(NULL),
+    m_pRelPLT(NULL),
+    m_pDynamic(NULL),
+    m_pEXIDX(NULL),
+    m_pEXTAB(NULL),
+    m_pAttributes(NULL) {
+}
+
+ARMGNULDBackend::~ARMGNULDBackend()
+{
+  if (m_pRelocFactory)
+    delete m_pRelocFactory;
+  if(m_pGOT)
+    delete m_pGOT;
+  if(m_pPLT)
+    delete m_pPLT;
+  if(m_pRelDyn)
+    delete m_pRelDyn;
+  if(m_pRelPLT)
+    delete m_pRelPLT;
+  if(m_pDynamic)
+    delete m_pDynamic;
+}
+
+bool ARMGNULDBackend::initRelocFactory(const MCLinker& pLinker)
+{
+  if (NULL == m_pRelocFactory) {
+    m_pRelocFactory = new ARMRelocationFactory(1024, *this);
+    m_pRelocFactory->setLayout(pLinker.getLayout());
+  }
+  return true;
+}
+
+RelocationFactory* ARMGNULDBackend::getRelocFactory()
+{
+  assert(NULL != m_pRelocFactory);
+  return m_pRelocFactory;
+}
+
+bool ARMGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
+{
+  if (!pSectionMap.push_back(".ARM.exidx", ".ARM.exidx") ||
+      !pSectionMap.push_back(".ARM.extab", ".ARM.extab") ||
+      !pSectionMap.push_back(".ARM.attributes", ".ARM.attributes"))
+    return false;
+  return true;
+}
+
+void ARMGNULDBackend::initTargetSections(MCLinker& pLinker)
+{
+ // FIXME: Currently we set exidx and extab to "Exception" and directly emit
+ // them from input
+  m_pEXIDX        = &pLinker.getOrCreateOutputSectHdr(".ARM.exidx",
+                                                      LDFileFormat::Exception,
+                                                      llvm::ELF::SHT_ARM_EXIDX,
+                                                      llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_LINK_ORDER,
+                                                      bitclass() / 8);
+  m_pEXTAB        = &pLinker.getOrCreateOutputSectHdr(".ARM.extab",
+                                                      LDFileFormat::Exception,
+                                                      llvm::ELF::SHT_PROGBITS,
+                                                      llvm::ELF::SHF_ALLOC,
+                                                      0x1);
+  m_pAttributes   = &pLinker.getOrCreateOutputSectHdr(".ARM.attributes",
+                                                      LDFileFormat::Target,
+                                                      llvm::ELF::SHT_ARM_ATTRIBUTES,
+                                                      0x0,
+                                                      0x1);
+}
+
+void ARMGNULDBackend::initTargetSymbols(MCLinker& pLinker)
+{
+  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
+  // same name in input
+  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
+                   "_GLOBAL_OFFSET_TABLE_",
+                   false,
+                   ResolveInfo::Object,
+                   ResolveInfo::Define,
+                   ResolveInfo::Local,
+                   0x0,  // size
+                   0x0,  // value
+                   NULL, // FragRef
+                   ResolveInfo::Hidden);
+}
+
+void ARMGNULDBackend::doPreLayout(const Output& pOutput,
+                                  const MCLDInfo& pInfo,
+                                  MCLinker& pLinker)
+{
+  // when building shared object, the .got section is must.
+  if(pOutput.type() == Output::DynObj && (NULL == m_pGOT)) {
+      createARMGOT(pLinker, pOutput);
+  }
+}
+
+void ARMGNULDBackend::doPostLayout(const Output& pOutput,
+                                   const MCLDInfo& pInfo,
+                                   MCLinker& pLinker)
+{
+  // emit program headers
+  if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
+    emitProgramHdrs(pLinker.getLDInfo().output());
+
+  ELFFileFormat *file_format = getOutputFormat(pOutput);
+
+  // apply PLT
+  if (file_format->hasPLT()) {
+    // Since we already have the size of LDSection PLT, m_pPLT should not be
+    // NULL.
+    assert(NULL != m_pPLT);
+    m_pPLT->applyPLT0();
+    m_pPLT->applyPLT1();
+  }
+
+  // apply GOT
+  if (file_format->hasGOT()) {
+    // Since we already have the size of GOT, m_pGOT should not be NULL.
+    assert(NULL != m_pGOT);
+    if (pOutput.type() == Output::DynObj)
+      m_pGOT->applyGOT0(file_format->getDynamic().addr());
+    else {
+      // executable file and object file? should fill with zero.
+      m_pGOT->applyGOT0(0);
+    }
+  }
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+ARMELFDynamic& ARMGNULDBackend::dynamic()
+{
+  if (NULL == m_pDynamic)
+    m_pDynamic = new ARMELFDynamic(*this);
+
+  return *m_pDynamic;
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+const ARMELFDynamic& ARMGNULDBackend::dynamic() const
+{
+  assert( NULL != m_pDynamic);
+  return *m_pDynamic;
+}
+
+bool ARMGNULDBackend::isPIC(const MCLDInfo& pLDInfo, const Output& pOutput) const
+{
+  return (pOutput.type() == Output::DynObj);
+}
+
+void ARMGNULDBackend::createARMGOT(MCLinker& pLinker, const Output& pOutput)
+{
+  // get .got LDSection and create MCSectionData
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& got = file_format->getGOT();
+  m_pGOT = new ARMGOT(got, pLinker.getOrCreateSectData(got));
+
+  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
+  if( m_pGOTSymbol != NULL ) {
+    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+  else {
+    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+
+}
+
+void ARMGNULDBackend::createARMPLTandRelPLT(MCLinker& pLinker,
+                                            const Output& pOutput)
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  // get .plt and .rel.plt LDSection
+  LDSection& plt = file_format->getPLT();
+  LDSection& relplt = file_format->getRelPlt();
+  // create MCSectionData and ARMPLT
+  m_pPLT = new ARMPLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT);
+  // set info of .rel.plt to .plt
+  relplt.setLink(&plt);
+  // create MCSectionData and ARMRelDynSection
+  m_pRelPLT = new OutputRelocSection(relplt,
+                                     pLinker.getOrCreateSectData(relplt),
+                                     8);
+}
+
+void ARMGNULDBackend::createARMRelDyn(MCLinker& pLinker,
+                                      const Output& pOutput)
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  // get .rel.dyn LDSection and create MCSectionData
+  LDSection& reldyn = file_format->getRelDyn();
+  // create MCSectionData and ARMRelDynSection
+  m_pRelDyn = new OutputRelocSection(reldyn,
+                                     pLinker.getOrCreateSectData(reldyn),
+                                     8);
+}
+
+ELFFileFormat* ARMGNULDBackend::getOutputFormat(const Output& pOutput) const
+{
+  switch (pOutput.type()) {
+    case Output::DynObj:
+      return getDynObjFileFormat();
+    case Output::Exec:
+      return getExecFileFormat();
+    // FIXME: We do not support building .o now
+    case Output::Object:
+    default:
+      llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
+                               llvm::Twine(pOutput.type()));
+      return NULL;
+  }
+}
+
+bool ARMGNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym,
+                                       const MCLDInfo& pLDInfo,
+                                       const Output& pOutput) const
+{
+  return (Output::DynObj == pOutput.type() &&
+          ResolveInfo::Function == pSym.type() &&
+          (pSym.isDyn() || pSym.isUndef() ||
+            isSymbolPreemptible(pSym, pLDInfo, pOutput)));
+}
+
+bool ARMGNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym,
+                                          const Output& pOutput,
+                                          bool isAbsReloc) const
+{
+  if(pSym.isUndef() && (Output::Exec == pOutput.type()))
+    return false;
+  if(pSym.isAbsolute())
+    return false;
+  if(Output::DynObj == pOutput.type() && isAbsReloc)
+    return true;
+  if(pSym.isDyn() || pSym.isUndef())
+    return true;
+
+  return false;
+}
+
+bool ARMGNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym,
+                                          const MCLDInfo& pLDInfo,
+                                          const Output& pOutput) const
+{
+  if(pSym.other() != ResolveInfo::Default)
+    return false;
+
+  if(Output::DynObj != pOutput.type())
+    return false;
+
+  if(pLDInfo.options().Bsymbolic())
+    return false;
+
+  return true;
+}
+
+/// checkValidReloc - When we attempt to generate a dynamic relocation for
+/// ouput file, check if the relocation is supported by dynamic linker.
+void ARMGNULDBackend::checkValidReloc(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      const Output& pOutput) const
+{
+  // If not building a PIC object, no relocation type is invalid
+  if (!isPIC(pLDInfo, pOutput))
+    return;
+
+  switch(pReloc.type()) {
+    case llvm::ELF::R_ARM_RELATIVE:
+    case llvm::ELF::R_ARM_COPY:
+    case llvm::ELF::R_ARM_GLOB_DAT:
+    case llvm::ELF::R_ARM_JUMP_SLOT:
+    case llvm::ELF::R_ARM_ABS32:
+    case llvm::ELF::R_ARM_ABS32_NOI:
+    case llvm::ELF::R_ARM_PC24:
+    case llvm::ELF::R_ARM_TLS_DTPMOD32:
+    case llvm::ELF::R_ARM_TLS_DTPOFF32:
+    case llvm::ELF::R_ARM_TLS_TPOFF32:
+      break;
+
+    default:
+      llvm::report_fatal_error(llvm::Twine("Attempt to generate unsupported") +
+                               llvm::Twine(" relocation type ") +
+                               llvm::Twine((int)pReloc.type()) +
+                               llvm::Twine(" for symbol '") +
+                               llvm::Twine(pReloc.symInfo()->name()) +
+                               llvm::Twine("', recompile with -fPIC")
+                              );
+      break;
+  }
+}
+
+void ARMGNULDBackend::updateAddend(Relocation& pReloc,
+                                   const LDSymbol& pInputSym,
+                                   const Layout& pLayout) const
+{
+  // Update value keep in addend if we meet a section symbol
+  if(pReloc.symInfo()->type() == ResolveInfo::Section) {
+    pReloc.setAddend(pLayout.getOutputOffset(
+                     *pInputSym.fragRef()) + pReloc.addend());
+  }
+}
+
+void ARMGNULDBackend::scanLocalReloc(Relocation& pReloc,
+                                     const LDSymbol& pInputSym,
+                                     MCLinker& pLinker,
+                                     const MCLDInfo& pLDInfo,
+                                     const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  updateAddend(pReloc, pInputSym, pLinker.getLayout());
+
+  switch(pReloc.type()){
+
+    // Set R_ARM_TARGET1 to R_ARM_ABS32
+    // Ref: GNU gold 1.11 arm.cc, line 9892
+    case llvm::ELF::R_ARM_TARGET1:
+       pReloc.setType(llvm::ELF::R_ARM_ABS32);
+    case llvm::ELF::R_ARM_ABS32:
+    case llvm::ELF::R_ARM_ABS32_NOI: {
+      // If buiding PIC object (shared library or PIC executable),
+      // a dynamic relocations with RELATIVE type to this location is needed.
+      // Reserve an entry in .rel.dyn
+      if(isPIC(pLDInfo, pOutput)) {
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | 0x1u);
+        }
+      return;
+    }
+
+    case llvm::ELF::R_ARM_ABS16:
+    case llvm::ELF::R_ARM_ABS12:
+    case llvm::ELF::R_ARM_THM_ABS5:
+    case llvm::ELF::R_ARM_ABS8:
+    case llvm::ELF::R_ARM_BASE_ABS:
+    case llvm::ELF::R_ARM_MOVW_ABS_NC:
+    case llvm::ELF::R_ARM_MOVT_ABS:
+    case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
+    case llvm::ELF::R_ARM_THM_MOVT_ABS: {
+      // Update value keep in relocation place if we meet a section symbol
+      if(rsym->type() == ResolveInfo::Section) {
+        pReloc.target() = pLinker.getLayout().getOutputOffset(
+                            *pInputSym.fragRef()) + pReloc.target();
+      }
+
+      // If building PIC object (shared library or PIC executable),
+      // a dynamic relocation for this location is needed.
+      // Reserve an entry in .rel.dyn
+      if(isPIC(pLDInfo, pOutput)) {
+        checkValidReloc(pReloc, pLDInfo, pOutput);
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | 0x1u);
+      }
+      return;
+    }
+    case llvm::ELF::R_ARM_GOTOFF32:
+    case llvm::ELF::R_ARM_GOTOFF12: {
+      // A GOT section is needed
+      if(NULL == m_pGOT)
+        createARMGOT(pLinker, pOutput);
+      return;
+    }
+
+    // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
+    // Ref: GNU gold 1.11 arm.cc, line 9892
+    case llvm::ELF::R_ARM_TARGET2:
+      pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
+    case llvm::ELF::R_ARM_GOT_BREL:
+    case llvm::ELF::R_ARM_GOT_PREL: {
+      // A GOT entry is needed for these relocation type.
+      // return if we already create GOT for this symbol
+      if(rsym->reserved() & 0x6u)
+        return;
+      if(NULL == m_pGOT)
+        createARMGOT(pLinker, pOutput);
+      m_pGOT->reserveEntry();
+      // If building PIC object, a dynamic relocation with
+      // type RELATIVE is needed to relocate this GOT entry.
+      // Reserve an entry in .rel.dyn
+      if(isPIC(pLDInfo, pOutput)) {
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set GOTRel bit
+        rsym->setReserved(rsym->reserved() | 0x4u);
+        return;
+      }
+      // set GOT bit
+      rsym->setReserved(rsym->reserved() | 0x2u);
+      return;
+    }
+
+    case llvm::ELF::R_ARM_BASE_PREL: {
+      // FIXME: Currently we only support R_ARM_BASE_PREL against
+      // symbol _GLOBAL_OFFSET_TABLE_
+      if(rsym != m_pGOTSymbol->resolveInfo()) {
+        llvm::report_fatal_error(llvm::Twine("Do not support relocation '") +
+                                 llvm::Twine("R_ARM_BASE_PREL' against symbol '") +
+                                 llvm::Twine(rsym->name()) +
+                                 llvm::Twine(".'"));
+      }
+      return;
+    }
+    case llvm::ELF::R_ARM_COPY:
+    case llvm::ELF::R_ARM_GLOB_DAT:
+    case llvm::ELF::R_ARM_JUMP_SLOT:
+    case llvm::ELF::R_ARM_RELATIVE: {
+      // These are relocation type for dynamic linker, shold not
+      // appear in object file.
+      llvm::report_fatal_error(llvm::Twine("unexpected reloc ") +
+                               llvm::Twine((int)pReloc.type()) +
+                               llvm::Twine(" in object file"));
+      break;
+    }
+    default: {
+      break;
+    }
+  } // end switch
+}
+
+void ARMGNULDBackend::scanGlobalReloc(Relocation& pReloc,
+                                      const LDSymbol& pInputSym,
+                                      MCLinker& pLinker,
+                                      const MCLDInfo& pLDInfo,
+                                      const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  switch(pReloc.type()) {
+
+    // Set R_ARM_TARGET1 to R_ARM_ABS32
+    // Ref: GNU gold 1.11 arm.cc, line 9892
+    case llvm::ELF::R_ARM_TARGET1:
+      pReloc.setType(llvm::ELF::R_ARM_ABS32);
+    case llvm::ELF::R_ARM_ABS32:
+    case llvm::ELF::R_ARM_ABS16:
+    case llvm::ELF::R_ARM_ABS12:
+    case llvm::ELF::R_ARM_THM_ABS5:
+    case llvm::ELF::R_ARM_ABS8:
+    case llvm::ELF::R_ARM_BASE_ABS:
+    case llvm::ELF::R_ARM_MOVW_ABS_NC:
+    case llvm::ELF::R_ARM_MOVT_ABS:
+    case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
+    case llvm::ELF::R_ARM_THM_MOVT_ABS:
+    case llvm::ELF::R_ARM_ABS32_NOI: {
+      // Absolute relocation type, symbol may needs PLT entry or
+      // dynamic relocation entry
+      if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
+        // create plt for this symbol if it does not have one
+        if(!(rsym->reserved() & 0x8u)){
+          // Create .got section if it doesn't exist
+          if(NULL == m_pGOT)
+            createARMGOT(pLinker, pOutput);
+          // create .plt and .rel.plt if not exist
+          if(NULL == m_pPLT)
+            createARMPLTandRelPLT(pLinker, pOutput);
+          // Symbol needs PLT entry, we need to reserve a PLT entry
+          // and the corresponding GOT and dynamic relocation entry
+          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
+          // when calling ARMPLT->reserveEntry())
+          m_pPLT->reserveEntry();
+          m_pRelPLT->reserveEntry(*m_pRelocFactory);
+          // set PLT bit
+          rsym->setReserved(rsym->reserved() | 0x8u);
+        }
+      }
+
+      if(isSymbolNeedsDynRel(*rsym, pOutput, true)) {
+        checkValidReloc(pReloc, pLDInfo, pOutput);
+        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | 0x1u);
+      }
+      return;
+    }
+
+    case llvm::ELF::R_ARM_GOTOFF32:
+    case llvm::ELF::R_ARM_GOTOFF12: {
+      // A GOT section is needed
+      if(NULL == m_pGOT)
+        createARMGOT(pLinker, pOutput);
+      return;
+    }
+
+    case llvm::ELF::R_ARM_BASE_PREL:
+      // FIXME: Currently we only support R_ARM_BASE_PREL against
+      // symbol _GLOBAL_OFFSET_TABLE_
+      if(rsym != m_pGOTSymbol->resolveInfo()) {
+        llvm::report_fatal_error(llvm::Twine("Do not support relocation '") +
+                                 llvm::Twine("R_ARM_BASE_PREL' against symbol '") +
+                                 llvm::Twine(rsym->name()) +
+                                 llvm::Twine(".'"));
+      }
+    case llvm::ELF::R_ARM_REL32:
+    case llvm::ELF::R_ARM_LDR_PC_G0:
+    case llvm::ELF::R_ARM_SBREL32:
+    case llvm::ELF::R_ARM_THM_PC8:
+    case llvm::ELF::R_ARM_MOVW_PREL_NC:
+    case llvm::ELF::R_ARM_MOVT_PREL:
+    case llvm::ELF::R_ARM_THM_MOVW_PREL_NC:
+    case llvm::ELF::R_ARM_THM_MOVT_PREL:
+    case llvm::ELF::R_ARM_THM_ALU_PREL_11_0:
+    case llvm::ELF::R_ARM_THM_PC12:
+    case llvm::ELF::R_ARM_REL32_NOI:
+    case llvm::ELF::R_ARM_ALU_PC_G0_NC:
+    case llvm::ELF::R_ARM_ALU_PC_G0:
+    case llvm::ELF::R_ARM_ALU_PC_G1_NC:
+    case llvm::ELF::R_ARM_ALU_PC_G1:
+    case llvm::ELF::R_ARM_ALU_PC_G2:
+    case llvm::ELF::R_ARM_LDR_PC_G1:
+    case llvm::ELF::R_ARM_LDR_PC_G2:
+    case llvm::ELF::R_ARM_LDRS_PC_G0:
+    case llvm::ELF::R_ARM_LDRS_PC_G1:
+    case llvm::ELF::R_ARM_LDRS_PC_G2:
+    case llvm::ELF::R_ARM_LDC_PC_G0:
+    case llvm::ELF::R_ARM_LDC_PC_G1:
+    case llvm::ELF::R_ARM_LDC_PC_G2:
+    case llvm::ELF::R_ARM_ALU_SB_G0_NC:
+    case llvm::ELF::R_ARM_ALU_SB_G0:
+    case llvm::ELF::R_ARM_ALU_SB_G1_NC:
+    case llvm::ELF::R_ARM_ALU_SB_G1:
+    case llvm::ELF::R_ARM_ALU_SB_G2:
+    case llvm::ELF::R_ARM_LDR_SB_G0:
+    case llvm::ELF::R_ARM_LDR_SB_G1:
+    case llvm::ELF::R_ARM_LDR_SB_G2:
+    case llvm::ELF::R_ARM_LDRS_SB_G0:
+    case llvm::ELF::R_ARM_LDRS_SB_G1:
+    case llvm::ELF::R_ARM_LDRS_SB_G2:
+    case llvm::ELF::R_ARM_LDC_SB_G0:
+    case llvm::ELF::R_ARM_LDC_SB_G1:
+    case llvm::ELF::R_ARM_LDC_SB_G2:
+    case llvm::ELF::R_ARM_MOVW_BREL_NC:
+    case llvm::ELF::R_ARM_MOVT_BREL:
+    case llvm::ELF::R_ARM_MOVW_BREL:
+    case llvm::ELF::R_ARM_THM_MOVW_BREL_NC:
+    case llvm::ELF::R_ARM_THM_MOVT_BREL:
+    case llvm::ELF::R_ARM_THM_MOVW_BREL: {
+      // Relative addressing relocation, may needs dynamic relocation
+      if(isSymbolNeedsDynRel(*rsym, pOutput, false)) {
+        checkValidReloc(pReloc, pLDInfo, pOutput);
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | 0x1u);
+      }
+      return;
+    }
+
+    case llvm::ELF::R_ARM_THM_CALL:
+    case llvm::ELF::R_ARM_PLT32:
+    case llvm::ELF::R_ARM_CALL:
+    case llvm::ELF::R_ARM_JUMP24:
+    case llvm::ELF::R_ARM_THM_JUMP24:
+    case llvm::ELF::R_ARM_SBREL31:
+    case llvm::ELF::R_ARM_PREL31:
+    case llvm::ELF::R_ARM_THM_JUMP19:
+    case llvm::ELF::R_ARM_THM_JUMP6:
+    case llvm::ELF::R_ARM_THM_JUMP11:
+    case llvm::ELF::R_ARM_THM_JUMP8: {
+      // These are branch relocation (except PREL31)
+      // A PLT entry is needed when building shared library
+
+      // return if we already create plt for this symbol
+      if(rsym->reserved() & 0x8u)
+        return;
+
+      // if symbol is defined in the ouput file and it's not
+      // preemptible, no need plt
+      if(rsym->isDefine() && !rsym->isDyn() &&
+         !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
+        return;
+      }
+
+      // Create .got section if it doesn't exist
+      if(NULL == m_pGOT)
+        createARMGOT(pLinker, pOutput);
+
+      // create .plt and .rel.plt if not exist
+      if(NULL == m_pPLT)
+         createARMPLTandRelPLT(pLinker, pOutput);
+      // Symbol needs PLT entry, we need to reserve a PLT entry
+      // and the corresponding GOT and dynamic relocation entry
+      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
+      // when calling ARMPLT->reserveEntry())
+      m_pPLT->reserveEntry();
+      m_pRelPLT->reserveEntry(*m_pRelocFactory);
+      // set PLT bit
+      rsym->setReserved(rsym->reserved() | 0x8u);
+      return;
+    }
+
+    // Set R_ARM_TARGET2 to R_ARM_GOT_PREL
+    // Ref: GNU gold 1.11 arm.cc, line 9892
+    case llvm::ELF::R_ARM_TARGET2:
+      pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
+    case llvm::ELF::R_ARM_GOT_BREL:
+    case llvm::ELF::R_ARM_GOT_ABS:
+    case llvm::ELF::R_ARM_GOT_PREL: {
+      // Symbol needs GOT entry, reserve entry in .got
+      // return if we already create GOT for this symbol
+      if(rsym->reserved() & 0x6u)
+        return;
+      if(NULL == m_pGOT)
+        createARMGOT(pLinker, pOutput);
+      m_pGOT->reserveEntry();
+      // If building shared object or the symbol is undefined, a dynamic
+      // relocation is needed to relocate this GOT entry. Reserve an
+      // entry in .rel.dyn
+      if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createARMRelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set GOTRel bit
+        rsym->setReserved(rsym->reserved() | 0x4u);
+        return;
+      }
+      // set GOT bit
+      rsym->setReserved(rsym->reserved() | 0x2u);
+      return;
+    }
+
+    case llvm::ELF::R_ARM_COPY:
+    case llvm::ELF::R_ARM_GLOB_DAT:
+    case llvm::ELF::R_ARM_JUMP_SLOT:
+    case llvm::ELF::R_ARM_RELATIVE: {
+      // These are relocation type for dynamic linker, shold not
+      // appear in object file.
+      llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") +
+                               llvm::Twine((int)pReloc.type()) +
+                               llvm::Twine(" in object file"));
+      break;
+    }
+    default: {
+      break;
+    }
+  } // end switch
+}
+
+void ARMGNULDBackend::scanRelocation(Relocation& pReloc,
+                                     const LDSymbol& pInputSym,
+                                     MCLinker& pLinker,
+                                     const MCLDInfo& pLDInfo,
+                                     const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
+
+  // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
+  // entries should be created.
+  // FIXME: Below judgements concern only .so is generated as output
+  // FIXME: Below judgements concern nothing about TLS related relocation
+
+  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section
+  // is needed
+  if(NULL == m_pGOT && NULL != m_pGOTSymbol) {
+    if(rsym == m_pGOTSymbol->resolveInfo()) {
+      createARMGOT(pLinker, pOutput);
+    }
+  }
+
+  // rsym is local
+  if(rsym->isLocal())
+    scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
+
+  // rsym is external
+  else
+    scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
+
+}
+
+uint64_t ARMGNULDBackend::emitSectionData(const Output& pOutput,
+                                          const LDSection& pSection,
+                                          const MCLDInfo& pInfo,
+                                          MemoryRegion& pRegion) const
+{
+  assert(pRegion.size() && "Size of MemoryRegion is zero!");
+
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  if (&pSection == m_pAttributes) {
+    // FIXME: Currently Emitting .ARM.attributes directly from the input file.
+    const llvm::MCSectionData* sect_data = pSection.getSectionData();
+    assert(sect_data &&
+           "Emit .ARM.attribute failed, MCSectionData doesn't exist!");
+
+    uint8_t* start =
+              llvm::cast<MCRegionFragment>(
+                     sect_data->getFragmentList().front()).getRegion().start();
+
+    memcpy(pRegion.start(), start, pRegion.size());
+    return pRegion.size();
+  }
+
+  if (&pSection == &(file_format->getPLT())) {
+    assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
+    uint64_t result = m_pPLT->emit(pRegion);
+    return result;
+  }
+
+  if (&pSection == &(file_format->getGOT())) {
+    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
+    uint64_t result = m_pGOT->emit(pRegion);
+    return result;
+  }
+
+  llvm::report_fatal_error(llvm::Twine("Unable to emit section `") +
+                           pSection.name() +
+                           llvm::Twine("'.\n"));
+  return 0x0;
+}
+
+/// finalizeSymbol - finalize the symbol value
+/// If the symbol's reserved field is not zero, MCLinker will call back this
+/// function to ask the final value of the symbol
+bool ARMGNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
+{
+  return false;
+}
+
+/// allocateCommonSymbols - allocate common symbols in the corresponding
+/// sections.
+/// @refer Google gold linker: common.cc: 214
+bool
+ARMGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
+{
+  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
+
+  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
+    return true;
+
+  // addralign := max value of all common symbols
+  uint64_t addralign = 0x0;
+
+  // Due to the visibility, some common symbols may be forcefully local.
+  SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      if ((*com_sym)->value() > addralign)
+        addralign = (*com_sym)->value();
+    }
+  }
+
+  // global common symbols.
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    if ((*com_sym)->value() > addralign)
+      addralign = (*com_sym)->value();
+  }
+
+  // FIXME: If the order of common symbols is defined, then sort common symbols
+  // com_sym = symbol_list.commonBegin();
+  // std::sort(com_sym, com_end, some kind of order);
+
+  // get or create corresponding BSS LDSection
+  LDSection* bss_sect_hdr = NULL;
+  if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
+                                   ".tbss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+  else {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+
+  // get or create corresponding BSS MCSectionData
+  assert(NULL != bss_sect_hdr);
+  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
+
+  // allocate all common symbols
+  uint64_t offset = bss_sect_hdr->size();
+
+  // allocate all local common symbols
+  com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      // We have to reset the description of the symbol here. When doing
+      // incremental linking, the output relocatable object may have common
+      // symbols. Therefore, we can not treat common symbols as normal symbols
+      // when emitting the regular name pools. We must change the symbols'
+      // description here.
+      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
+      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+      uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                         bss_section,
+                                                         (*com_sym)->value());
+      offset += size;
+    }
+  }
+
+  // allocate all global common symbols
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    // We have to reset the description of the symbol here. When doing
+    // incremental linking, the output relocatable object may have common
+    // symbols. Therefore, we can not treat common symbols as normal symbols
+    // when emitting the regular name pools. We must change the symbols'
+    // description here.
+    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
+    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+    uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                       bss_section,
+                                                       (*com_sym)->value());
+    offset += size;
+  }
+
+  bss_sect_hdr->setSize(offset);
+  symbol_list.changeCommonsToGlobal();
+  return true;
+}
+
+bool ARMGNULDBackend::readSection(Input& pInput,
+                                  MCLinker& pLinker,
+                                  LDSection& pInputSectHdr)
+{
+  LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(),
+                                                         pInputSectHdr.kind(),
+                                                         pInputSectHdr.type(),
+                                                         pInputSectHdr.flag());
+  // FIXME: (Luba)
+  // Handle ARM attributes in the right way.
+  // In current milestone, MCLinker goes through the shortcut.
+  // It reads input's ARM attributes and copies the first ARM attributes
+  // into the output file. The correct way is merge these sections, not
+  // just copy.
+  if ((0 == out_sect.name().compare(".ARM.attributes")) &&
+      (0 != out_sect.size()))
+    return true;
+
+  MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
+                                                   pInputSectHdr.size());
+
+  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
+
+  new MCRegionFragment(*region, &sect_data);
+
+  out_sect.setSize(out_sect.size() + pInputSectHdr.size());
+  return true;
+}
+
+ARMGOT& ARMGNULDBackend::getGOT()
+{
+  assert(NULL != m_pGOT && "GOT section not exist");
+  return *m_pGOT;
+}
+
+const ARMGOT& ARMGNULDBackend::getGOT() const
+{
+  assert(NULL != m_pGOT && "GOT section not exist");
+  return *m_pGOT;
+}
+
+ARMPLT& ARMGNULDBackend::getPLT()
+{
+  assert(NULL != m_pPLT && "PLT section not exist");
+  return *m_pPLT;
+}
+
+const ARMPLT& ARMGNULDBackend::getPLT() const
+{
+  assert(NULL != m_pPLT && "PLT section not exist");
+  return *m_pPLT;
+}
+
+OutputRelocSection& ARMGNULDBackend::getRelDyn()
+{
+  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
+  return *m_pRelDyn;
+}
+
+const OutputRelocSection& ARMGNULDBackend::getRelDyn() const
+{
+  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
+  return *m_pRelDyn;
+}
+
+OutputRelocSection& ARMGNULDBackend::getRelPLT()
+{
+  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
+  return *m_pRelPLT;
+}
+
+const OutputRelocSection& ARMGNULDBackend::getRelPLT() const
+{
+  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
+  return *m_pRelPLT;
+}
+
+unsigned int
+ARMGNULDBackend::getTargetSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  if (&pSectHdr == &file_format->getGOT())
+    return SHO_DATA;
+
+  if (&pSectHdr == &file_format->getPLT())
+    return SHO_PLT;
+
+  return SHO_UNDEFINED;
+}
+
+namespace mcld {
+
+//===----------------------------------------------------------------------===//
+/// createARMLDBackend - the help funtion to create corresponding ARMLDBackend
+///
+TargetLDBackend* createARMLDBackend(const llvm::Target& pTarget,
+                                    const std::string& pTriple)
+{
+  Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker is not supported yet");
+    /**
+    return new ARMMachOLDBackend(createARMMachOArchiveReader,
+                               createARMMachOObjectReader,
+                               createARMMachOObjectWriter);
+    **/
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker is not supported yet");
+    /**
+    return new ARMCOFFLDBackend(createARMCOFFArchiveReader,
+                               createARMCOFFObjectReader,
+                               createARMCOFFObjectWriter);
+    **/
+  }
+  return new ARMGNULDBackend();
+}
+
+} // namespace of mcld
+
+//=============================
+// Force static initialization.
+extern "C" void LLVMInitializeARMLDBackend() {
+  // Register the linker backend
+  mcld::TargetRegistry::RegisterTargetLDBackend(TheARMTarget, createARMLDBackend);
+}
+
diff --git a/lib/Target/ARM/ARMLDBackend.h b/lib/Target/ARM/ARMLDBackend.h
new file mode 100644
index 0000000..440d9ee
--- /dev/null
+++ b/lib/Target/ARM/ARMLDBackend.h
@@ -0,0 +1,297 @@
+//===- ARMLDBackend.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_LDBACKEND_H
+#define MCLD_ARM_LDBACKEND_H
+
+#include "ARMELFDynamic.h"
+#include "ARMGOT.h"
+#include "ARMPLT.h"
+#include <mcld/LD/LDSection.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Target/OutputRelocSection.h>
+
+namespace mcld {
+
+class MCLDInfo;
+class MCLinker;
+class Output;
+class SectionMap;
+
+
+//===----------------------------------------------------------------------===//
+/// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
+///
+class ARMGNULDBackend : public GNULDBackend
+{
+public:
+  ARMGNULDBackend();
+  ~ARMGNULDBackend();
+public:
+  typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList;
+
+  /** \enum ReservedEntryType
+   *  \brief The reserved entry type of reserved space in ResolveInfo.
+   *
+   *  This is used for sacnRelocation to record what kinds of entries are
+   *  reserved for this resolved symbol
+   *
+   *  In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction.
+   *  GOT may needs a corresponding relocation to relocate itself, so we
+   *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
+   *  symbol, there might be two kinds of entries reserved for different location.
+   *  For example, reference to the same symbol, one may use GOT and the other may
+   *  use dynamic relocation.
+   *
+   *  bit:  3       2      1     0
+   *   | PLT | GOTRel | GOT | Rel |
+   *
+   *  value    Name         - Description
+   *
+   *  0000     None         - no reserved entry
+   *  0001     ReserveRel   - reserve an dynamic relocation entry
+   *  0010     ReserveGOT   - reserve an GOT entry
+   *  0011     GOTandRel    - For different relocation, we've reserved GOT and
+   *                          Rel for different location.
+   *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
+   *                          relocation entry which relocate this GOT entry
+   *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
+   *                          and relocation entry for different location.
+   *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
+   *                          Dynamic relocation entries
+   *  1001     PLTandRel    - For different relocation, we've reserved PLT and
+   *                          Rel for different location.
+   */
+  enum ReservedEntryType {
+    None         = 0,
+    ReserveRel   = 1,
+    ReserveGOT   = 2,
+    GOTandRel    = 3,
+    GOTRel       = 4,
+    GOTRelandRel = 5,
+    ReservePLT   = 8,
+    PLTandRel    = 9
+  };
+
+public:
+  /// initTargetSectionMap - initialize target dependent section mapping
+  bool initTargetSectionMap(SectionMap& pSectionMap);
+
+  /// initTargetSections - initialize target dependent sections in output.
+  void initTargetSections(MCLinker& pLinker);
+
+  /// initTargetSymbols - initialize target dependent symbols in output.
+  void initTargetSymbols(MCLinker& pLinker);
+
+  /// initRelocFactory - create and initialize RelocationFactory
+  bool initRelocFactory(const MCLinker& pLinker);
+
+  /// getRelocFactory
+  RelocationFactory* getRelocFactory();
+
+  /// scanRelocation - determine the empty entries are needed or not and create
+  /// the empty entries if needed.
+  /// For ARM, following entries are check to create:
+  /// - GOT entry (for .got section)
+  /// - PLT entry (for .plt section)
+  /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
+  void scanRelocation(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  uint32_t machine() const
+  { return llvm::ELF::EM_ARM; }
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  virtual uint8_t OSABI() const
+  { return llvm::ELF::ELFOSABI_NONE; }
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  virtual uint8_t ABIVersion() const
+  { return 0x0; }
+
+  /// flags - the value of ElfXX_Ehdr::e_flags
+  virtual uint64_t flags() const
+  { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); }
+
+  bool isLittleEndian() const
+  { return true; }
+
+  unsigned int bitclass() const
+  { return 32; }
+
+  /// doPreLayout - Backend can do any needed modification before layout
+  void doPreLayout(const Output& pOutput,
+                   const MCLDInfo& pInfo,
+                   MCLinker& pLinker);
+
+  /// doPostLayout -Backend can do any needed modification after layout
+  void doPostLayout(const Output& pOutput,
+                    const MCLDInfo& pInfo,
+                    MCLinker& pLinker);
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  ARMELFDynamic& dynamic();
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  const ARMELFDynamic& dynamic() const;
+
+
+  /// emitSectionData - write out the section data into the memory region.
+  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
+  /// call back target backend to emit the data.
+  ///
+  /// Backends handle the target-special tables (plt, gp,...) by themselves.
+  /// Backend can put the data of the tables in MCSectionData directly
+  ///  - LDSection.getSectionData can get the section data.
+  /// Or, backend can put the data into special data structure
+  ///  - backend can maintain its own map<LDSection, table> to get the table
+  /// from given LDSection.
+  ///
+  /// @param pOutput - the output file
+  /// @param pSection - the given LDSection
+  /// @param pInfo - all options in the command line.
+  /// @param pRegion - the region to write out data
+  /// @return the size of the table in the file.
+  uint64_t emitSectionData(const Output& pOutput,
+                           const LDSection& pSection,
+                           const MCLDInfo& pInfo,
+                           MemoryRegion& pRegion) const;
+
+  ARMGOT& getGOT();
+
+  const ARMGOT& getGOT() const;
+
+  ARMPLT& getPLT();
+
+  const ARMPLT& getPLT() const;
+
+  OutputRelocSection& getRelDyn();
+
+  const OutputRelocSection& getRelDyn() const;
+
+  OutputRelocSection& getRelPLT();
+
+  const OutputRelocSection& getRelPLT() const;
+
+  /// getTargetSectionOrder - compute the layout order of ARM target sections
+  unsigned int getTargetSectionOrder(const Output& pOutput,
+                                     const LDSection& pSectHdr) const;
+
+  /// finalizeSymbol - finalize the symbol value
+  /// If the symbol's reserved field is not zero, MCLinker will call back this
+  /// function to ask the final value of the symbol
+  bool finalizeSymbol(LDSymbol& pSymbol) const;
+
+  /// allocateCommonSymbols - allocate common symbols in the corresponding
+  /// sections.
+  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
+
+  /// readSection - read target dependent sections
+  bool readSection(Input& pInput,
+                   MCLinker& pLinker,
+                   LDSection& pInputSectHdr);
+
+public:
+  bool isSymbolPreemptible(const ResolveInfo& pSym,
+                           const MCLDInfo& pLDInfo,
+                           const Output& pOutput) const;
+
+  bool isPIC(const MCLDInfo& pLDInfo, const Output& pOutput) const;
+
+private:
+  void scanLocalReloc(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  void scanGlobalReloc(Relocation& pReloc,
+                       const LDSymbol& pInputSym,
+                       MCLinker& pLinker,
+                       const MCLDInfo& pLDInfo,
+                       const Output& pOutput);
+
+  bool isSymbolNeedsPLT(const ResolveInfo& pSym,
+                        const MCLDInfo& pLDInfo,
+                        const Output& pOutput) const;
+
+  bool isSymbolNeedsDynRel(const ResolveInfo& pSym,
+                           const Output& pOutput,
+                           bool isAbsReloc) const;
+
+
+  void checkValidReloc(Relocation& pReloc,
+                       const MCLDInfo& pLDInfo,
+                       const Output& pOutput) const;
+
+  /// updateAddend - update addend value of the relocation if the
+  /// the target symbol is a section symbol. Addend is the offset
+  /// in the section. This value should be updated after section
+  /// merged.
+  void updateAddend(Relocation& pReloc,
+                    const LDSymbol& pInputSym,
+                    const Layout& pLayout) const;
+
+  void createARMGOT(MCLinker& pLinker, const Output& pOutput);
+
+  /// createARMPLTandRelPLT - create PLT and RELPLT sections.
+  /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two
+  /// sections should be create together.
+  void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
+
+  void createARMRelDyn(MCLinker& pLinker, const Output& pOutput);
+
+  ELFFileFormat* getOutputFormat(const Output& pOutput) const;
+
+private:
+  RelocationFactory* m_pRelocFactory;
+  ARMGOT* m_pGOT;
+  ARMPLT* m_pPLT;
+  /// m_RelDyn - dynamic relocation table of .rel.dyn
+  OutputRelocSection* m_pRelDyn;
+  /// m_RelPLT - dynamic relocation table of .rel.plt
+  OutputRelocSection* m_pRelPLT;
+
+  ARMELFDynamic* m_pDynamic;
+  LDSymbol* m_pGOTSymbol;
+
+  //     variable name           :  ELF
+  LDSection* m_pEXIDX;           // .ARM.exidx
+  LDSection* m_pEXTAB;           // .ARM.extab
+  LDSection* m_pAttributes;      // .ARM.attributes
+//  LDSection* m_pPreemptMap;      // .ARM.preemptmap
+//  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
+//  LDSection* m_pOverlayTable;    // .ARM.overlay_table
+};
+
+//===----------------------------------------------------------------------===//
+/// ARMMachOLDBackend - linker backend of ARM target of MachO format
+///
+/**
+class ARMMachOLDBackend : public DarwinARMLDBackend
+{
+public:
+  ARMMachOLDBackend();
+  ~ARMMachOLDBackend();
+
+private:
+  MCMachOTargetArchiveReader *createTargetArchiveReader() const;
+  MCMachOTargetObjectReader *createTargetObjectReader() const;
+  MCMachOTargetObjectWriter *createTargetObjectWriter() const;
+
+};
+**/
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMPLT.cpp b/lib/Target/ARM/ARMPLT.cpp
new file mode 100644
index 0000000..3a79b52
--- /dev/null
+++ b/lib/Target/ARM/ARMPLT.cpp
@@ -0,0 +1,250 @@
+//===- ARMPLT.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMGOT.h"
+#include "ARMPLT.h"
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <new>
+
+namespace {
+
+const uint32_t arm_plt0[] = {
+  0xe52de004, // str   lr, [sp, #-4]!
+  0xe59fe004, // ldr   lr, [pc, #4]
+  0xe08fe00e, // add   lr, pc, lr
+  0xe5bef008, // ldr   pc, [lr, #8]!
+  0x00000000, // &GOT[0] - .
+};
+
+const uint32_t arm_plt1[] = {
+  0xe28fc600, // add   ip, pc, #0xNN00000
+  0xe28cca00, // add   ip, ip, #0xNN000
+  0xe5bcf000, // ldr   pc, [ip, #0xNNN]!
+};
+
+} // anonymous namespace
+
+using namespace mcld;
+
+ARMPLT0::ARMPLT0(llvm::MCSectionData* pParent)
+  : PLTEntry(sizeof(arm_plt0), pParent) {}
+
+ARMPLT1::ARMPLT1(llvm::MCSectionData* pParent)
+  : PLTEntry(sizeof(arm_plt1), pParent) {}
+
+//===----------------------------------------------------------------------===//
+// ARMPLT
+
+ARMPLT::ARMPLT(LDSection& pSection,
+               llvm::MCSectionData& pSectionData,
+               ARMGOT &pGOTPLT)
+  : PLT(pSection, pSectionData), m_GOT(pGOTPLT), m_PLTEntryIterator() {
+  ARMPLT0* plt0_entry = new ARMPLT0(&m_SectionData);
+
+  m_Section.setSize(m_Section.size() + plt0_entry->getEntrySize());
+
+  m_PLTEntryIterator = pSectionData.begin();
+}
+
+ARMPLT::~ARMPLT()
+{
+}
+
+void ARMPLT::reserveEntry(size_t pNum)
+{
+  ARMPLT1* plt1_entry = 0;
+
+  for (size_t i = 0; i < pNum; ++i) {
+    plt1_entry = new (std::nothrow) ARMPLT1(&m_SectionData);
+
+    if (!plt1_entry)
+      llvm::report_fatal_error("Allocating new memory for ARMPLT1 failed!");
+
+    m_Section.setSize(m_Section.size() + plt1_entry->getEntrySize());
+
+    m_GOT.reserveGOTPLTEntry();
+  }
+}
+
+PLTEntry* ARMPLT::getPLTEntry(const ResolveInfo& pSymbol, bool& pExist)
+{
+   ARMPLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol];
+
+   pExist = 1;
+
+   if (!PLTEntry) {
+     GOTEntry *&GOTPLTEntry = m_GOT.lookupGOTPLTMap(pSymbol);
+     assert(!GOTPLTEntry && "PLT entry and got.plt entry doesn't match!");
+
+     pExist = 0;
+
+     // This will skip PLT0.
+     ++m_PLTEntryIterator;
+     assert(m_PLTEntryIterator != m_SectionData.end() &&
+            "The number of PLT Entries and ResolveInfo doesn't match");
+
+     ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry();
+     ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd();
+     assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match");
+
+     PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator));
+     GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it));
+   }
+
+   return PLTEntry;
+}
+
+GOTEntry* ARMPLT::getGOTPLTEntry(const ResolveInfo& pSymbol, bool& pExist)
+{
+   GOTEntry *&GOTPLTEntry = m_GOT.lookupGOTPLTMap(pSymbol);
+
+   pExist = 1;
+
+   if (!GOTPLTEntry) {
+     ARMPLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol];
+     assert(!PLTEntry && "PLT entry and got.plt entry doesn't match!");
+
+     pExist = 0;
+
+     // This will skip PLT0.
+     ++m_PLTEntryIterator;
+     assert(m_PLTEntryIterator != m_SectionData.end() &&
+            "The number of PLT Entries and ResolveInfo doesn't match");
+
+     ARMGOT::iterator got_it = m_GOT.getNextGOTPLTEntry();
+     ARMGOT::iterator got_ie = m_GOT.getGOTPLTEnd();
+     assert(got_it != got_ie && "The number of GOTPLT and PLT doesn't match");
+
+     PLTEntry = llvm::cast<ARMPLT1>(&(*m_PLTEntryIterator));
+     GOTPLTEntry = llvm::cast<GOTEntry>(&(*got_it));
+   }
+
+   return GOTPLTEntry;
+}
+
+ARMPLT0* ARMPLT::getPLT0() const {
+
+  iterator first = m_SectionData.getFragmentList().begin();
+  iterator end = m_SectionData.getFragmentList().end();
+
+  assert(first!=end && "FragmentList is empty, getPLT0 failed!");
+
+  ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
+
+  return plt0;
+}
+
+void ARMPLT::applyPLT0() {
+
+  uint64_t plt_base = m_Section.addr();
+  assert(plt_base && ".plt base address is NULL!");
+
+  uint64_t got_base = m_GOT.getSection().addr();
+  assert(got_base && ".got base address is NULL!");
+
+  uint32_t offset = 0;
+
+  if (got_base > plt_base)
+    offset = got_base - (plt_base + 16);
+  else
+    offset = (plt_base + 16) - got_base;
+
+  iterator first = m_SectionData.getFragmentList().begin();
+  iterator end = m_SectionData.getFragmentList().end();
+
+  assert(first!=end && "FragmentList is empty, applyPLT0 failed!");
+
+  ARMPLT0* plt0 = &(llvm::cast<ARMPLT0>(*first));
+
+  uint32_t* data = 0;
+  data = static_cast<uint32_t*>(malloc(plt0->getEntrySize()));
+
+  if (!data)
+    llvm::report_fatal_error("Allocating new memory for plt0 failed!");
+
+  memcpy(data, arm_plt0, plt0->getEntrySize());
+  data[4] = offset;
+
+  plt0->setContent(reinterpret_cast<unsigned char*>(data));
+}
+
+void ARMPLT::applyPLT1() {
+
+  uint64_t plt_base = m_Section.addr();
+  assert(plt_base && ".plt base address is NULL!");
+
+  uint64_t got_base = m_GOT.getSection().addr();
+  assert(got_base && ".got base address is NULL!");
+
+  ARMPLT::iterator it = m_SectionData.begin();
+  ARMPLT::iterator ie = m_SectionData.end();
+  assert(it!=ie && "FragmentList is empty, applyPLT1 failed!");
+
+  uint32_t GOTEntrySize = m_GOT.getEntrySize();
+  uint32_t GOTEntryAddress =
+    got_base +  GOTEntrySize * 3;
+
+  uint64_t PLTEntryAddress =
+    plt_base + llvm::cast<ARMPLT0>((*it)).getEntrySize(); //Offset of PLT0
+
+  ++it; //skip PLT0
+  uint64_t PLT1EntrySize = llvm::cast<ARMPLT1>((*it)).getEntrySize();
+  ARMPLT1* plt1 = NULL;
+
+  uint32_t* Out = NULL;
+  while (it != ie) {
+    plt1 = &(llvm::cast<ARMPLT1>(*it));
+    Out = static_cast<uint32_t*>(malloc(plt1->getEntrySize()));
+
+    if (!Out)
+      llvm::report_fatal_error("Allocating new memory for plt1 failed!");
+
+    // Offset is the distance between the last PLT entry and the associated
+    // GOT entry.
+    int32_t Offset = (GOTEntryAddress - (PLTEntryAddress + 8));
+
+    Out[0] = arm_plt1[0] | ((Offset >> 20) & 0xFF);
+    Out[1] = arm_plt1[1] | ((Offset >> 12) & 0xFF);
+    Out[2] = arm_plt1[2] | (Offset & 0xFFF);
+
+    plt1->setContent(reinterpret_cast<unsigned char*>(Out));
+    ++it;
+
+    GOTEntryAddress += GOTEntrySize;
+    PLTEntryAddress += PLT1EntrySize;
+  }
+
+  m_GOT.applyAllGOTPLT(plt_base);
+}
+
+uint64_t ARMPLT::emit(MemoryRegion& pRegion)
+{
+  uint64_t result = 0x0;
+  iterator it = begin();
+  unsigned int plt0_size = llvm::cast<ARMPLT0>((*it)).getEntrySize();
+
+  unsigned char* buffer = pRegion.getBuffer();
+  memcpy(buffer, llvm::cast<ARMPLT0>((*it)).getContent(), plt0_size);
+  result += plt0_size;
+  ++it;
+
+  ARMPLT1* plt1 = 0;
+  ARMPLT::iterator ie = end();
+  unsigned int entry_size = 0;
+  while (it != ie) {
+    plt1 = &(llvm::cast<ARMPLT1>(*it));
+    entry_size = plt1->getEntrySize();
+    memcpy(buffer + result, plt1->getContent(), entry_size);
+    result += entry_size;
+    ++it;
+  }
+  return result;
+}
+
diff --git a/lib/Target/ARM/ARMPLT.h b/lib/Target/ARM/ARMPLT.h
new file mode 100644
index 0000000..f55aaa3
--- /dev/null
+++ b/lib/Target/ARM/ARMPLT.h
@@ -0,0 +1,87 @@
+//===- ARMPLT.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_PLT_H
+#define MCLD_ARM_PLT_H
+
+#include <mcld/Target/PLT.h>
+
+namespace mcld {
+
+class ARMGOT;
+class GOTEntry;
+class MemoryRegion;
+
+class ARMPLT0 : public PLTEntry {
+public:
+  ARMPLT0(llvm::MCSectionData* pParent);
+};
+
+class ARMPLT1 : public PLTEntry {
+public:
+  ARMPLT1(llvm::MCSectionData* pParent);
+};
+
+/** \class ARMPLT
+ *  \brief ARM Procedure Linkage Table
+ */
+class ARMPLT : public PLT
+{
+  typedef llvm::DenseMap<const ResolveInfo*, ARMPLT1*> SymbolIndexType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+public:
+  ARMPLT(LDSection& pSection,
+         llvm::MCSectionData& pSectionData,
+         ARMGOT& pGOTPLT);
+  ~ARMPLT();
+
+// Override virtual function.
+public:
+
+  // reserveEntry is ARMGOT friend function.
+  void reserveEntry(size_t pNum = 1) ;
+
+  PLTEntry* getPLTEntry(const ResolveInfo& pSymbol, bool& pExist) ;
+
+  GOTEntry* getGOTPLTEntry(const ResolveInfo& pSymbol, bool& pExist);
+
+public:
+  iterator begin() { return m_SectionData.begin(); }
+
+  const_iterator begin() const { return m_SectionData.begin(); }
+
+  iterator end() { return m_SectionData.end(); }
+
+  const_iterator end() const { return m_SectionData.end(); }
+
+  ARMPLT0* getPLT0() const;
+
+  void applyPLT0();
+
+  void applyPLT1();
+
+  uint64_t emit(MemoryRegion& pRegion);
+
+private:
+  ARMGOT& m_GOT;
+
+  // Used by getEntry() for mapping a ResolveInfo
+  // instance to a PLT1 Entry.
+  iterator m_PLTEntryIterator;
+
+  SymbolIndexType m_PLTEntryMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMRelocationFactory.cpp b/lib/Target/ARM/ARMRelocationFactory.cpp
new file mode 100644
index 0000000..2763b3b
--- /dev/null
+++ b/lib/Target/ARM/ARMRelocationFactory.cpp
@@ -0,0 +1,861 @@
+//===- ARMRelocationFactory.cpp  ----------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------------===//
+
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/DataTypes.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/Layout.h>
+
+#include "ARMRelocationFactory.h"
+#include "ARMRelocationFunctions.h"
+
+using namespace mcld;
+
+DECL_ARM_APPLY_RELOC_FUNCS
+
+//===--------------------------------------------------------------------===//
+// ARMRelocationFactory
+ARMRelocationFactory::ARMRelocationFactory(size_t pNum,
+                                           ARMGNULDBackend& pParent)
+  : RelocationFactory(pNum),
+    m_Target(pParent) {
+}
+
+ARMRelocationFactory::~ARMRelocationFactory()
+{
+}
+
+void ARMRelocationFactory::applyRelocation(Relocation& pRelocation,
+                                           const MCLDInfo& pLDInfo)
+{
+  Relocation::Type type = pRelocation.type();
+  if (type > 130) { // 131-255 doesn't noted in ARM spec
+    llvm::report_fatal_error(llvm::Twine("Unknown relocation type. "
+                                         "To symbol `") +
+                             pRelocation.symInfo()->name() +
+                             llvm::Twine("'."));
+    return;
+  }
+
+  /// the prototype of applying function
+  typedef Result (*ApplyFunctionType)(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent);
+
+  // the table entry of applying functions
+  struct ApplyFunctionTriple {
+    ApplyFunctionType func;
+    unsigned int type;
+    const char* name;
+  };
+
+  // declare the table of applying functions
+  static ApplyFunctionTriple apply_functions[] = {
+    DECL_ARM_APPLY_RELOC_FUNC_PTRS
+  };
+
+  // apply the relocation
+  Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
+
+  // check result
+  if (OK == result) {
+    return;
+  }
+  if (Overflow == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' causes overflow. on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+
+  if (BadReloc == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' encounters unexpected opcode. "
+                                         "on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+  if (Unsupport == result) {
+    llvm::report_fatal_error(llvm::Twine("Encounter unsupported relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// non-member functions
+static RelocationFactory::DWord getThumbBit(const Relocation& pReloc)
+{
+  // Set thumb bit if
+  // - symbol has type of STT_FUNC, is defined and with bit 0 of its value set
+  RelocationFactory::DWord thumbBit =
+       ((pReloc.symInfo()->desc() != ResolveInfo::Undefined) &&
+        (pReloc.symInfo()->type() == ResolveInfo::Function) &&
+        ((pReloc.symValue() & 0x1) != 0))?
+        1:0;
+  return thumbBit;
+}
+
+
+
+
+//=========================================//
+// Relocation helper function              //
+//=========================================//
+
+// Using uint64_t to make sure those complicate operations won't cause
+// undefined behavior.
+static
+uint64_t helper_sign_extend(uint64_t pVal, uint64_t pOri_width)
+{
+  assert(pOri_width <= 64);
+  uint64_t sign_bit = 1 << (pOri_width - 1);
+  return (pVal ^ sign_bit) - sign_bit;
+  // Reverse sign bit, then subtract sign bit.
+}
+
+static
+uint64_t helper_bit_select(uint64_t pA, uint64_t pB, uint64_t pMask)
+{
+  return (pA & ~pMask) | (pB & pMask) ;
+}
+
+// Check if symbol can use relocation R_ARM_RELATIVE
+static bool
+helper_use_relative_reloc(const ResolveInfo& pSym,
+                          const MCLDInfo& pLDInfo,
+                          const ARMRelocationFactory& pFactory)
+{
+  // if symbol is dynamic or undefine or preemptible
+  if(pSym.isDyn() ||
+     pSym.isUndef() ||
+     pFactory.getTarget().isSymbolPreemptible(pSym,
+                                              pLDInfo,
+                                              pLDInfo.output()))
+    return false;
+  return true;
+}
+
+static
+GOTEntry& helper_get_GOT_and_init(Relocation& pReloc,
+                                  const MCLDInfo& pLDInfo,
+                                  ARMRelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMGNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  GOTEntry& got_entry = *ld_backend.getGOT().getEntry(*rsym, exist);
+  if (!exist) {
+    // If we first get this GOT entry, we should initialize it.
+    if (rsym->reserved() & ARMGNULDBackend::ReserveGOT) {
+      // No corresponding dynamic relocation, initialize to the symbol value.
+      got_entry.setContent(pReloc.symValue());
+    }
+    else if (rsym->reserved() & ARMGNULDBackend::GOTRel) {
+
+      // Initialize corresponding dynamic relocation.
+      Relocation& rel_entry =
+        *ld_backend.getRelDyn().getEntry(*rsym, true, exist);
+      assert(!exist && "GOT entry not exist, but DynRel entry exist!");
+      if( rsym->isLocal() ||
+          helper_use_relative_reloc(*rsym, pLDInfo, pParent)) {
+        // Initialize got entry to target symbol address
+        got_entry.setContent(pReloc.symValue());
+        rel_entry.setType(llvm::ELF::R_ARM_RELATIVE);
+        rel_entry.setSymInfo(0);
+      }
+      else {
+        // Initialize got entry to 0 for corresponding dynamic relocation.
+        got_entry.setContent(0);
+        rel_entry.setType(llvm::ELF::R_ARM_GLOB_DAT);
+        rel_entry.setSymInfo(rsym);
+      }
+      rel_entry.targetRef().assign(got_entry);
+    }
+    else {
+      llvm::report_fatal_error("No GOT entry reserved for GOT type relocation!");
+    }
+  }
+  return got_entry;
+}
+
+static
+ARMRelocationFactory::Address helper_GOT_ORG(ARMRelocationFactory& pParent)
+{
+  return pParent.getTarget().getGOT().getSection().addr();
+}
+
+
+static
+ARMRelocationFactory::Address helper_GOT(Relocation& pReloc,
+                                         const MCLDInfo& pLDInfo,
+                                         ARMRelocationFactory& pParent)
+{
+  GOTEntry& got_entry = helper_get_GOT_and_init(pReloc, pLDInfo, pParent);
+  return helper_GOT_ORG(pParent) + pParent.getLayout().getOutputOffset(got_entry);
+}
+
+
+static
+PLTEntry& helper_get_PLT_and_init(Relocation& pReloc,
+                                  ARMRelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMGNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  PLTEntry& plt_entry = *ld_backend.getPLT().getPLTEntry(*rsym, exist);
+  if (!exist) {
+    // If we first get this PLT entry, we should initialize it.
+    if (rsym->reserved() & ARMGNULDBackend::ReservePLT) {
+      GOTEntry& gotplt_entry =
+        *ld_backend.getPLT().getGOTPLTEntry(*rsym, exist);
+      // Initialize corresponding dynamic relocation.
+      Relocation& rel_entry =
+        *ld_backend.getRelPLT().getEntry(*rsym, true, exist);
+      assert(!exist && "PLT entry not exist, but DynRel entry exist!");
+      rel_entry.setType(llvm::ELF::R_ARM_JUMP_SLOT);
+      rel_entry.targetRef().assign(gotplt_entry);
+      rel_entry.setSymInfo(rsym);
+    }
+    else {
+      llvm::report_fatal_error("No PLT entry reserved for PLT type relocation!");
+    }
+  }
+  return plt_entry;
+}
+
+
+
+static
+ARMRelocationFactory::Address helper_PLT_ORG(ARMRelocationFactory& pParent)
+{
+  return pParent.getTarget().getPLT().getSection().addr();
+}
+
+
+static
+ARMRelocationFactory::Address helper_PLT(Relocation& pReloc,
+                                         ARMRelocationFactory& pParent)
+{
+  PLTEntry& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
+  return helper_PLT_ORG(pParent) + pParent.getLayout().getOutputOffset(plt_entry);
+}
+
+// Get an relocation entry in .rel.dyn and set its type to pType,
+// its FragmentRef to pReloc->targetFrag() and its ResolveInfo to pReloc->symInfo()
+static
+void helper_DynRel(Relocation& pReloc,
+                   ARMRelocationFactory::Type pType,
+                   ARMRelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMGNULDBackend& ld_backend = pParent.getTarget();
+  bool exist;
+
+  Relocation& rel_entry =
+    *ld_backend.getRelDyn().getEntry(*rsym, false, exist);
+  rel_entry.setType(pType);
+  rel_entry.targetRef() = pReloc.targetRef();
+
+  if(pType == llvm::ELF::R_ARM_RELATIVE)
+    rel_entry.setSymInfo(0);
+  else
+    rel_entry.setSymInfo(rsym);
+}
+
+static ARMRelocationFactory::DWord
+helper_extract_movw_movt_addend(ARMRelocationFactory::DWord pTarget)
+{
+  // imm16: [19-16][11-0]
+  return helper_sign_extend((((pTarget >> 4)) & 0xf000U) | (pTarget & 0xfffU),
+                            16);
+}
+
+static ARMRelocationFactory::DWord
+helper_insert_val_movw_movt_inst(ARMRelocationFactory::DWord pTarget,
+                                 ARMRelocationFactory::DWord pImm)
+{
+  // imm16: [19-16][11-0]
+  pTarget &= 0xfff0f000U;
+  pTarget |= pImm & 0x0fffU;
+  pTarget |= (pImm & 0xf000U) << 4;
+  return pTarget;
+}
+
+static ARMRelocationFactory::DWord
+helper_extract_thumb_movw_movt_addend(ARMRelocationFactory::DWord pTarget)
+{
+  // TODO: By the rsloader experience: If we use 32bit, we need to consider
+  // endianness problem. We'd better have a thumb instruction type.
+  // imm16: [19-16][26][14-12][7-0]
+  return helper_sign_extend((((pTarget >> 4) & 0xf000U) |
+                             ((pTarget >> 15) & 0x0800U) |
+                             ((pTarget >> 4) & 0x0700U) |
+                             (pTarget & 0x00ffU)),
+                            16);
+}
+
+static ARMRelocationFactory::DWord
+helper_insert_val_thumb_movw_movt_inst(ARMRelocationFactory::DWord pTarget,
+                                       ARMRelocationFactory::DWord pImm)
+{
+  // TODO: By the rsloader experience: If we use 32bit, we need to consider
+  // endianness problem. We'd better have a thumb instruction type.
+  // imm16: [19-16][26][14-12][7-0]
+  pTarget &= 0xfbf08f00U;
+  pTarget |= (pImm & 0xf000U) << 4;
+  pTarget |= (pImm & 0x0800U) << 15;
+  pTarget |= (pImm & 0x0700U) << 4;
+  pTarget |= (pImm & 0x00ffU);
+  return pTarget;
+}
+
+static ARMRelocationFactory::DWord
+helper_thumb32_branch_offset(ARMRelocationFactory::DWord pUpper16,
+                             ARMRelocationFactory::DWord pLower16)
+{
+  ARMRelocationFactory::DWord s = (pUpper16 & (1U << 10)) >> 10,  // 26 bit
+                              u = pUpper16 & 0x3ffU,              // 25-16
+                              l = pLower16 & 0x7ffU,              // 10-0
+                             j1 = (pLower16 & (1U << 13)) >> 13,  // 13
+                             j2 = (pLower16 & (1U << 11)) >> 11;  // 11
+  ARMRelocationFactory::DWord i1 = j1 ^ s? 0: 1,
+                              i2 = j2 ^ s? 0: 1;
+
+  // [31-25][24][23][22][21-12][11-1][0]
+  //      0   s  i1  i2      u     l  0
+  return helper_sign_extend((s << 24) | (i1 << 23) | (i2 << 22) |
+                            (u << 12) | (l << 1),
+                            25);
+}
+
+static ARMRelocationFactory::DWord
+helper_thumb32_branch_upper(ARMRelocationFactory::DWord pUpper16,
+                            ARMRelocationFactory::DWord pOffset)
+{
+  uint32_t sign = ((pOffset & 0x80000000U) >> 31);
+  return (pUpper16 & ~0x7ffU) | ((pOffset >> 12) & 0x3ffU) | (sign << 10);
+}
+
+static ARMRelocationFactory::DWord
+helper_thumb32_branch_lower(ARMRelocationFactory::DWord pLower16,
+                            ARMRelocationFactory::DWord pOffset)
+{
+  uint32_t sign = ((pOffset & 0x80000000U) >> 31);
+  return ((pLower16 & ~0x2fffU) |
+          ((((pOffset >> 23) & 1) ^ !sign) << 13) |
+          ((((pOffset >> 22) & 1) ^ !sign) << 11) |
+          ((pOffset >> 1) & 0x7ffU));
+}
+
+// Return true if overflow
+static bool
+helper_check_signed_overflow(ARMRelocationFactory::DWord pValue,
+                             unsigned bits)
+{
+  int32_t signed_val = static_cast<int32_t>(pValue);
+  int32_t max = (1 << (bits - 1)) - 1;
+  int32_t min = -(1 << (bits - 1));
+  if (signed_val > max || signed_val < min) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+//=========================================//
+// Each relocation function implementation //
+//=========================================//
+
+// R_ARM_NONE
+ARMRelocationFactory::Result none(Relocation& pReloc,
+                                  const MCLDInfo& pLDInfo,
+                                  ARMRelocationFactory& pParent)
+{
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_ABS32: (S + A) | T
+ARMRelocationFactory::Result abs32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   ARMRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  ARMRelocationFactory::DWord S = pReloc.symValue();
+
+  if(rsym->isLocal() && (rsym->reserved() & 0x1u)) {
+    helper_DynRel(pReloc, llvm::ELF::R_ARM_RELATIVE, pParent);
+    pReloc.target() = (S + A) | T ;
+    return ARMRelocationFactory::OK;
+  }
+  else if(!rsym->isLocal()) {
+    if(rsym->reserved() & 0x8u) {
+      S = helper_PLT(pReloc, pParent);
+      T = 0 ; // PLT is not thumb
+      pReloc.target() = (S + A) | T;
+    }
+    // If we generate a dynamic relocation (except R_ARM_RELATIVE)
+    // for a place, we should not perform static relocation on it
+    // in order to keep the addend store in the place correct.
+    if(rsym->reserved() & 0x1u) {
+      if(helper_use_relative_reloc(*rsym, pLDInfo, pParent)) {
+        helper_DynRel(pReloc, llvm::ELF::R_ARM_RELATIVE, pParent);
+      }
+      else {
+        helper_DynRel(pReloc, pReloc.type(), pParent);
+        return ARMRelocationFactory::OK;
+      }
+    }
+  }
+
+  // perform static relocation
+  pReloc.target() = (S + A) | T;
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_REL32: ((S + A) | T) - P
+ARMRelocationFactory::Result rel32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   ARMRelocationFactory& pParent)
+{
+  // perform static relocation
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  pReloc.target() = ((pReloc.symValue() + A) | T)
+      - pReloc.place(pParent.getLayout());
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_BASE_PREL: B(S) + A - P
+ARMRelocationFactory::Result base_prel(Relocation& pReloc,
+                                       const MCLDInfo& pLDInfo,
+                                       ARMRelocationFactory& pParent)
+{
+  // perform static relocation
+  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  pReloc.target() = pReloc.symValue() + A - pReloc.place(pParent.getLayout());
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_GOTOFF32: ((S + A) | T) - GOT_ORG
+ARMRelocationFactory::Result gotoff32(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  ARMRelocationFactory::Address S = pReloc.symValue();
+
+  pReloc.target() = ((S + A) | T) - GOT_ORG;
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG
+ARMRelocationFactory::Result got_brel(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent)
+{
+  if(!(pReloc.symInfo()->reserved() & 0x6u)) {
+    return ARMRelocationFactory::BadReloc;
+  }
+  ARMRelocationFactory::Address GOT_S   = helper_GOT(pReloc, pLDInfo, pParent);
+  ARMRelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
+  ARMRelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  // Apply relocation.
+  pReloc.target() = GOT_S + A - GOT_ORG;
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_GOT_PREL: GOT(S) + A - P
+ARMRelocationFactory::Result got_prel(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent)
+{
+  if(!(pReloc.symInfo()->reserved() & 0x6u)) {
+    return ARMRelocationFactory::BadReloc;
+  }
+  ARMRelocationFactory::Address GOT_S   = helper_GOT(pReloc, pLDInfo, pParent);
+  ARMRelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
+  ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout());
+  // Apply relocation.
+  pReloc.target() = GOT_S + A - P;
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_PLT32: ((S + A) | T) - P
+// R_ARM_JUMP24: ((S + A) | T) - P
+// R_ARM_CALL: ((S + A) | T) - P
+ARMRelocationFactory::Result call(Relocation& pReloc,
+                                  const MCLDInfo& pLDInfo,
+                                  ARMRelocationFactory& pParent)
+{
+  // TODO: Some issue have not been considered, e.g. thumb, overflow?
+
+  // If target is undefined weak symbol, we only need to jump to the
+  // next instruction unless it has PLT entry.
+  if (pReloc.symInfo()->isWeak() && pReloc.symInfo()->isUndef() &&
+      !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) {
+    // change target to NOP : mov r0, r0
+    pReloc.target() = (pReloc.target() & 0xf0000000U) | 0x01a00000;
+    return ARMRelocationFactory::OK;
+  }
+
+  ARMRelocationFactory::Address S; // S dependent on exist PLT or not.
+  ARMRelocationFactory::DWord   T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord   A =
+    helper_sign_extend((pReloc.target() & 0x00FFFFFFu) << 2, 26)
+    + pReloc.addend();
+  ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout());
+
+  S = pReloc.symValue();
+  if( pReloc.symInfo()->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+    T = 0;  // PLT is not thumb.
+  }
+
+  ARMRelocationFactory::DWord X = ((S + A) | T) - P;
+
+  if (X & 0x03u) {  // Lowest two bit is not zero.
+    llvm::report_fatal_error("Target is thumb, need stub!");
+  }
+  // Check X is 24bit sign int. If not, we should use stub or PLT before apply.
+  assert(!helper_check_signed_overflow(X, 26) && "Jump or Call target too far!");
+  //                    Make sure the Imm is 0.          Result Mask.
+  pReloc.target() = (pReloc.target() & 0xFF000000u) | ((X & 0x03FFFFFEu) >> 2);
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_THM_CALL: ((S + A) | T) - P
+ARMRelocationFactory::Result thm_call(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent)
+{
+  // If target is undefined weak symbol, we only need to jump to the
+  // next instruction unless it has PLT entry.
+  if (pReloc.symInfo()->isWeak() && pReloc.symInfo()->isUndef() &&
+      !(pReloc.symInfo()->reserved() & ARMGNULDBackend::ReservePLT)) {
+    pReloc.target() = (0xe000U << 16) | 0xbf00U;
+    return ARMRelocationFactory::OK;
+  }
+
+  // TODO: By the rsloader experience: If we use 32bit, we need to consider
+  // endianness problem. Here is an ugly solution. We'd better have a thumb
+  // instruction type.
+  //uint16_t upper16 = *(
+  //    reinterpret_cast<uint16_t*>(&pReloc.target())
+  //  ),
+  //         lower16 = *(
+  //    reinterpret_cast<uint16_t*>(&pReloc.target()) + 1
+  //  );
+  ARMRelocationFactory::DWord upper16 = ((pReloc.target() & 0xffff0000U) >> 16),
+                              lower16 = (pReloc.target() & 0xffffU);
+
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A = helper_thumb32_branch_offset(upper16,
+                                                               lower16);
+  ARMRelocationFactory::Address P = pReloc.place(pParent.getLayout());
+  ARMRelocationFactory::Address S;
+
+  S = pReloc.symValue();
+  // if symbol has plt
+  if( pReloc.symInfo()->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+    T = 0;  // PLT is not thumb.
+  }
+
+  // TODO: If the target is not thumb, we should rewrite instruction to BLX.
+
+  ARMRelocationFactory::DWord X = ((S + A) | T) - P;
+  X >>= 1;
+
+  // FIXME: Check bit size is 24(thumb2) or 22?
+  if (helper_check_signed_overflow(X, 24)) {
+    assert(!"Offset is too far. We need stub or PLT for it.");
+    return ARMRelocationFactory::Overflow;
+  }
+
+  // For a BLX instruction, make sure that the relocation is rounded up
+  // to a word boundary. This follows the semantics of the instruction
+  // which specifies that bit 1 of the target address will come from bit
+  // 1 of the base address.
+  if ((X & 0x5000U) == 0x4000U) {
+    X = (X + 2) & ~0x3U;
+  }
+
+  upper16 = helper_thumb32_branch_upper(upper16, X);
+  lower16 = helper_thumb32_branch_lower(lower16, X);
+
+  // TODO: By the rsloader experience: If we use 32bit, we need to consider
+  // endianness problem. Here is an ugly solution. We'd better have a thumb
+  // instruction type.
+  //*(reinterpret_cast<uint16_t*>(&preloc.target())) = upper16;
+  //*(reinterpret_cast<uint16_t*>(&preloc.target()) + 1) = lower16;
+  pReloc.target() = (upper16 << 16);
+  pReloc.target() |= lower16;
+
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_MOVW_ABS_NC: (S + A) | T
+ARMRelocationFactory::Result movw_abs_nc(Relocation& pReloc,
+                                         const MCLDInfo& pLDInfo,
+                                         ARMRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A =
+      helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  // use plt
+  if(rsym->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+    T = 0 ; // PLT is not thumb
+  }
+  X = (S + A) | T ;
+  // perform static relocation
+  pReloc.target() = (S + A) | T;
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_MOVW_PREL_NC: ((S + A) | T) - P
+ARMRelocationFactory::Result movw_prel_nc(Relocation& pReloc,
+                                          const MCLDInfo& pLDInfo,
+                                          ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout());
+  ARMRelocationFactory::DWord A =
+      helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  X = ((S + A) | T) - P;
+
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_MOVT_ABS: S + A
+ARMRelocationFactory::Result movt_abs(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      ARMRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord A =
+    helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  // use plt
+  if(rsym->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+  }
+
+  X = S + A;
+  X >>= 16;
+  // perform static relocation
+  pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_MOVT_PREL: S + A - P
+ARMRelocationFactory::Result movt_prel(Relocation& pReloc,
+                                       const MCLDInfo& pLDInfo,
+                                       ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout());
+  ARMRelocationFactory::DWord A =
+      helper_extract_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  X = S + A - P;
+  X >>= 16;
+
+  pReloc.target() = helper_insert_val_movw_movt_inst(pReloc.target(), X);
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_THM_MOVW_ABS_NC: (S + A) | T
+ARMRelocationFactory::Result thm_movw_abs_nc(Relocation& pReloc,
+                                             const MCLDInfo& pLDInfo,
+                                             ARMRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A =
+      helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  // use plt
+  if(rsym->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+    T = 0; // PLT is not thumb
+  }
+  X = (S + A) | T;
+  // check 16-bit overflow
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(),
+                                                             X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_THM_MOVW_PREL_NC: ((S + A) | T) - P
+ARMRelocationFactory::Result thm_movw_prel_nc(Relocation& pReloc,
+                                              const MCLDInfo& pLDInfo,
+                                              ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout());
+  ARMRelocationFactory::DWord A =
+      helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  X = ((S + A) | T) - P;
+
+  // check 16-bit overflow
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(),
+                                                             X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_THM_MOVT_ABS: S + A
+ARMRelocationFactory::Result thm_movt_abs(Relocation& pReloc,
+                                          const MCLDInfo& pLDInfo,
+                                          ARMRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord A =
+      helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  // use plt
+  if(rsym->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+  }
+  X = S + A;
+  X >>= 16;
+
+  // check 16-bit overflow
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(),
+                                                             X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_THM_MOVT_PREL: S + A - P
+ARMRelocationFactory::Result thm_movt_prel(Relocation& pReloc,
+                                           const MCLDInfo& pLDInfo,
+                                           ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::Address S = pReloc.symValue();
+  ARMRelocationFactory::DWord P = pReloc.place(pParent.getLayout());
+  ARMRelocationFactory::DWord A =
+      helper_extract_thumb_movw_movt_addend(pReloc.target()) + pReloc.addend();
+  ARMRelocationFactory::DWord X;
+
+  X = S + A - P;
+  X >>= 16;
+
+  // check 16-bit overflow
+  if (helper_check_signed_overflow(X, 16)) {
+    return ARMRelocationFactory::Overflow;
+  } else {
+    pReloc.target() = helper_insert_val_thumb_movw_movt_inst(pReloc.target(),
+                                                             X);
+    return ARMRelocationFactory::OK;
+  }
+}
+
+// R_ARM_PREL31: (S + A) | T
+ARMRelocationFactory::Result prel31(Relocation& pReloc,
+                                    const MCLDInfo& pLDInfo,
+                                    ARMRelocationFactory& pParent)
+{
+  ARMRelocationFactory::DWord target = pReloc.target();
+  ARMRelocationFactory::DWord T = getThumbBit(pReloc);
+  ARMRelocationFactory::DWord A = helper_sign_extend(target, 31) +
+                                  pReloc.addend();
+  ARMRelocationFactory::Address S;
+
+  S = pReloc.symValue();
+  // if symbol has plt
+  if( pReloc.symInfo()->reserved() & 0x8u) {
+    S = helper_PLT(pReloc, pParent);
+    T = 0;  // PLT is not thumb.
+  }
+
+  ARMRelocationFactory::DWord X = (S + A) | T ;
+  pReloc.target() = helper_bit_select(target, X, 0x7fffffffU);
+  if(helper_check_signed_overflow(X, 31))
+    return ARMRelocationFactory::Overflow;
+  return ARMRelocationFactory::OK;
+}
+
+// R_ARM_TLS_GD32: GOT(S) + A - P
+// R_ARM_TLS_IE32: GOT(S) + A - P
+// R_ARM_TLS_LE32: S + A - tp
+ARMRelocationFactory::Result tls(Relocation& pReloc,
+                                 const MCLDInfo& pLDInfo,
+                                 ARMRelocationFactory& pParent)
+{
+  llvm::report_fatal_error("We don't support TLS relocation yet.");
+  return ARMRelocationFactory::Unsupport;
+}
+
+ARMRelocationFactory::Result unsupport(Relocation& pReloc,
+                                       const MCLDInfo& pLDInfo,
+                                       ARMRelocationFactory& pParent)
+{
+  return ARMRelocationFactory::Unsupport;
+}
diff --git a/lib/Target/ARM/ARMRelocationFactory.h b/lib/Target/ARM/ARMRelocationFactory.h
new file mode 100644
index 0000000..636dbee
--- /dev/null
+++ b/lib/Target/ARM/ARMRelocationFactory.h
@@ -0,0 +1,59 @@
+//===-  ARMRelocationFactory.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef ARM_RELOCATION_FACTORY_H
+#define ARM_RELOCATION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/Target/GOT.h>
+#include "ARMLDBackend.h"
+
+namespace mcld
+{
+
+/** \class ARMRelocationFactory
+ *  \brief ARMRelocationFactory creates and destroys the ARM relocations.
+ *
+ */
+class ARMRelocationFactory : public RelocationFactory
+{
+public:
+  /** \enum Reloc
+   *  \brief Reloc is the result of applying functions.
+   */
+  enum Result
+  {
+    OK,
+    Overflow,
+    BadReloc,
+    Unsupport
+  };
+
+public:
+  ARMRelocationFactory(size_t pNum, ARMGNULDBackend& pParent);
+  ~ARMRelocationFactory();
+
+  void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+
+  ARMGNULDBackend& getTarget()
+  { return m_Target; }
+
+  const ARMGNULDBackend& getTarget() const
+  { return m_Target; }
+
+private:
+  ARMGNULDBackend& m_Target;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/ARMRelocationFunctions.h b/lib/Target/ARM/ARMRelocationFunctions.h
new file mode 100644
index 0000000..10d27a4
--- /dev/null
+++ b/lib/Target/ARM/ARMRelocationFunctions.h
@@ -0,0 +1,169 @@
+//===- ARMRelocationFunction.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DECL_ARM_APPLY_RELOC_FUNC(Name) \
+static ARMRelocationFactory::Result Name    (Relocation& pEntry, \
+                                             const MCLDInfo& pLDInfo, \
+                                             ARMRelocationFactory& pParent);
+
+#define DECL_ARM_APPLY_RELOC_FUNCS \
+DECL_ARM_APPLY_RELOC_FUNC(none)             \
+DECL_ARM_APPLY_RELOC_FUNC(abs32)            \
+DECL_ARM_APPLY_RELOC_FUNC(rel32)            \
+DECL_ARM_APPLY_RELOC_FUNC(gotoff32)         \
+DECL_ARM_APPLY_RELOC_FUNC(base_prel)        \
+DECL_ARM_APPLY_RELOC_FUNC(got_brel)         \
+DECL_ARM_APPLY_RELOC_FUNC(call)             \
+DECL_ARM_APPLY_RELOC_FUNC(thm_call)         \
+DECL_ARM_APPLY_RELOC_FUNC(movw_prel_nc)     \
+DECL_ARM_APPLY_RELOC_FUNC(movw_abs_nc)      \
+DECL_ARM_APPLY_RELOC_FUNC(movt_abs)         \
+DECL_ARM_APPLY_RELOC_FUNC(movt_prel)        \
+DECL_ARM_APPLY_RELOC_FUNC(thm_movw_abs_nc)  \
+DECL_ARM_APPLY_RELOC_FUNC(thm_movw_prel_nc) \
+DECL_ARM_APPLY_RELOC_FUNC(thm_movt_abs)     \
+DECL_ARM_APPLY_RELOC_FUNC(thm_movt_prel)    \
+DECL_ARM_APPLY_RELOC_FUNC(prel31)           \
+DECL_ARM_APPLY_RELOC_FUNC(got_prel)         \
+DECL_ARM_APPLY_RELOC_FUNC(tls)              \
+DECL_ARM_APPLY_RELOC_FUNC(unsupport)
+
+
+#define DECL_ARM_APPLY_RELOC_FUNC_PTRS \
+  { &none,               0, "R_ARM_NONE"              },  \
+  { &unsupport,          1, "R_ARM_PC24"              },  \
+  { &abs32,              2, "R_ARM_ABS32"             },  \
+  { &rel32,              3, "R_ARM_REL32"             },  \
+  { &unsupport,          4, "R_ARM_LDR_PC_G0"         },  \
+  { &unsupport,          5, "R_ARM_ABS16"             },  \
+  { &unsupport,          6, "R_ARM_ABS12"             },  \
+  { &unsupport,          7, "R_ARM_THM_ABS5"          },  \
+  { &unsupport,          8, "R_ARM_ABS8"              },  \
+  { &unsupport,          9, "R_ARM_SBREL32"           },  \
+  { &thm_call,          10, "R_ARM_THM_CALL"          },  \
+  { &unsupport,         11, "R_ARM_THM_PC8"           },  \
+  { &unsupport,         12, "R_ARM_BREL_ADJ"          },  \
+  { &unsupport,         13, "R_ARM_TLS_DESC"          },  \
+  { &unsupport,         14, "R_ARM_THM_SWI8"          },  \
+  { &unsupport,         15, "R_ARM_XPC25"             },  \
+  { &unsupport,         16, "R_ARM_THM_XPC22"         },  \
+  { &unsupport,         17, "R_ARM_TLS_DTPMOD32"      },  \
+  { &unsupport,         18, "R_ARM_TLS_DTPOFF32"      },  \
+  { &unsupport,         19, "R_ARM_TLS_TPOFF32"       },  \
+  { &unsupport,         20, "R_ARM_COPY"              },  \
+  { &unsupport,         21, "R_ARM_GLOB_DAT"          },  \
+  { &unsupport,         22, "R_ARM_JUMP_SLOT"         },  \
+  { &unsupport,         23, "R_ARM_RELATIVE"          },  \
+  { &gotoff32,          24, "R_ARM_GOTOFF32"          },  \
+  { &base_prel,         25, "R_ARM_BASE_PREL"         },  \
+  { &got_brel,          26, "R_ARM_GOT_BREL"          },  \
+  { &call,              27, "R_ARM_PLT32"             },  \
+  { &call,              28, "R_ARM_CALL"              },  \
+  { &call,              29, "R_ARM_JUMP24"            },  \
+  { &unsupport,         30, "R_ARM_THM_JUMP24"        },  \
+  { &unsupport,         31, "R_ARM_BASE_ABS"          },  \
+  { &unsupport,         32, "R_ARM_ALU_PCREL_7_0"     },  \
+  { &unsupport,         33, "R_ARM_ALU_PCREL_15_8"    },  \
+  { &unsupport,         34, "R_ARM_ALU_PCREL_23_15"   },  \
+  { &unsupport,         35, "R_ARM_LDR_SBREL_11_0_NC" },  \
+  { &unsupport,         36, "R_ARM_ALU_SBREL_19_12_NC"},  \
+  { &unsupport,         37, "R_ARM_ALU_SBREL_27_20_CK"},  \
+  { &abs32,             38, "R_ARM_TARGET1"           },  \
+  { &unsupport,         39, "R_ARM_SBREL31"           },  \
+  { &unsupport,         40, "R_ARM_V4BX"              },  \
+  { &got_prel,          41, "R_ARM_TARGET2"           },  \
+  { &prel31,            42, "R_ARM_PREL31"            },  \
+  { &movw_abs_nc,       43, "R_ARM_MOVW_ABS_NC"       },  \
+  { &movt_abs,          44, "R_ARM_MOVT_ABS"          },  \
+  { &movw_prel_nc,      45, "R_ARM_MOVW_PREL_NC"      },  \
+  { &movt_prel,         46, "R_ARM_MOVT_PREL"         },  \
+  { &thm_movw_abs_nc,   47, "R_ARM_THM_MOVW_ABS_NC"   },  \
+  { &thm_movt_abs,      48, "R_ARM_THM_MOVT_ABS"      },  \
+  { &thm_movw_prel_nc,  49, "R_ARM_THM_MOVW_PREL_NC"  },  \
+  { &thm_movt_prel,     50, "R_ARM_THM_MOVT_PREL"     },  \
+  { &unsupport,         51, "R_ARM_THM_JUMP19"        },  \
+  { &unsupport,         52, "R_ARM_THM_JUMP6"         },  \
+  { &unsupport,         53, "R_ARM_THM_ALU_PREL_11_0" },  \
+  { &unsupport,         54, "R_ARM_THM_PC12"          },  \
+  { &unsupport,         55, "R_ARM_ABS32_NOI"         },  \
+  { &unsupport,         56, "R_ARM_REL32_NOI"         },  \
+  { &unsupport,         57, "R_ARM_ALU_PC_G0_NC"      },  \
+  { &unsupport,         58, "R_ARM_ALU_PC_G0"         },  \
+  { &unsupport,         59, "R_ARM_ALU_PC_G1_NC"      },  \
+  { &unsupport,         60, "R_ARM_ALU_PC_G1"         },  \
+  { &unsupport,         61, "R_ARM_ALU_PC_G2"         },  \
+  { &unsupport,         62, "R_ARM_LDR_PC_G1"         },  \
+  { &unsupport,         63, "R_ARM_LDR_PC_G2"         },  \
+  { &unsupport,         64, "R_ARM_LDRS_PC_G0"        },  \
+  { &unsupport,         65, "R_ARM_LDRS_PC_G1"        },  \
+  { &unsupport,         66, "R_ARM_LDRS_PC_G2"        },  \
+  { &unsupport,         67, "R_ARM_LDC_PC_G0"         },  \
+  { &unsupport,         68, "R_ARM_LDC_PC_G1"         },  \
+  { &unsupport,         69, "R_ARM_LDC_PC_G2"         },  \
+  { &unsupport,         70, "R_ARM_ALU_SB_G0_NC"      },  \
+  { &unsupport,         71, "R_ARM_ALU_SB_G0"         },  \
+  { &unsupport,         72, "R_ARM_ALU_SB_G1_NC"      },  \
+  { &unsupport,         73, "R_ARM_ALU_SB_G1"         },  \
+  { &unsupport,         74, "R_ARM_ALU_SB_G2"         },  \
+  { &unsupport,         75, "R_ARM_LDR_SB_G0"         },  \
+  { &unsupport,         76, "R_ARM_LDR_SB_G1"         },  \
+  { &unsupport,         77, "R_ARM_LDR_SB_G2"         },  \
+  { &unsupport,         78, "R_ARM_LDRS_SB_G0"        },  \
+  { &unsupport,         79, "R_ARM_LDRS_SB_G1"        },  \
+  { &unsupport,         80, "R_ARM_LDRS_SB_G2"        },  \
+  { &unsupport,         81, "R_ARM_LDC_SB_G0"         },  \
+  { &unsupport,         82, "R_ARM_LDC_SB_G1"         },  \
+  { &unsupport,         83, "R_ARM_LDC_SB_G2"         },  \
+  { &unsupport,         84, "R_ARM_MOVW_BREL_NC"      },  \
+  { &unsupport,         85, "R_ARM_MOVT_BREL"         },  \
+  { &unsupport,         86, "R_ARM_MOVW_BREL"         },  \
+  { &unsupport,         87, "R_ARM_THM_MOVW_BREL_NC"  },  \
+  { &unsupport,         88, "R_ARM_THM_MOVT_BREL"     },  \
+  { &unsupport,         89, "R_ARM_THM_MOVW_BREL"     },  \
+  { &unsupport,         90, "R_ARM_TLS_GOTDESC"       },  \
+  { &unsupport,         91, "R_ARM_TLS_CALL"          },  \
+  { &unsupport,         92, "R_ARM_TLS_DESCSEQ"       },  \
+  { &unsupport,         93, "R_ARM_THM_TLS_CALL"      },  \
+  { &unsupport,         94, "R_ARM_PLT32_ABS"         },  \
+  { &unsupport,         95, "R_ARM_GOT_ABS"           },  \
+  { &got_prel,          96, "R_ARM_GOT_PREL"          },  \
+  { &unsupport,         97, "R_ARM_GOT_PREL12"        },  \
+  { &unsupport,         98, "R_ARM_GOTOFF12"          },  \
+  { &unsupport,         99, "R_ARM_GOTRELAX"          },  \
+  { &unsupport,        100, "R_ARM_GNU_VTENTRY"       },  \
+  { &unsupport,        101, "R_ARM_GNU_VTINERIT"      },  \
+  { &unsupport,        102, "R_ARM_THM_JUMP11"        },  \
+  { &unsupport,        103, "R_ARM_THM_JUMP8"         },  \
+  { &tls,              104, "R_ARM_TLS_GD32"          },  \
+  { &unsupport,        105, "R_ARM_TLS_LDM32"         },  \
+  { &unsupport,        106, "R_ARM_TLS_LDO32"         },  \
+  { &tls,              107, "R_ARM_TLS_IE32"          },  \
+  { &tls,              108, "R_ARM_TLS_LE32"          },  \
+  { &unsupport,        109, "R_ARM_TLS_LDO12"         },  \
+  { &unsupport,        110, "R_ARM_TLS_LE12"          },  \
+  { &unsupport,        111, "R_ARM_TLS_IE12GP"        },  \
+  { &unsupport,        112, "R_ARM_PRIVATE_0"         },  \
+  { &unsupport,        113, "R_ARM_PRIVATE_1"         },  \
+  { &unsupport,        114, "R_ARM_PRIVATE_2"         },  \
+  { &unsupport,        115, "R_ARM_PRIVATE_3"         },  \
+  { &unsupport,        116, "R_ARM_PRIVATE_4"         },  \
+  { &unsupport,        117, "R_ARM_PRIVATE_5"         },  \
+  { &unsupport,        118, "R_ARM_PRIVATE_6"         },  \
+  { &unsupport,        119, "R_ARM_PRIVATE_7"         },  \
+  { &unsupport,        120, "R_ARM_PRIVATE_8"         },  \
+  { &unsupport,        121, "R_ARM_PRIVATE_9"         },  \
+  { &unsupport,        122, "R_ARM_PRIVATE_10"        },  \
+  { &unsupport,        123, "R_ARM_PRIVATE_11"        },  \
+  { &unsupport,        124, "R_ARM_PRIVATE_12"        },  \
+  { &unsupport,        125, "R_ARM_PRIVATE_13"        },  \
+  { &unsupport,        126, "R_ARM_PRIVATE_14"        },  \
+  { &unsupport,        127, "R_ARM_PRIVATE_15"        },  \
+  { &unsupport,        128, "R_ARM_ME_TOO"            },  \
+  { &unsupport,        129, "R_ARM_THM_TLS_DESCSEQ16" },  \
+  { &unsupport,        130, "R_ARM_THM_TLS_DESCSEQ32" }
diff --git a/lib/Target/ARM/ARMSectLinker.cpp b/lib/Target/ARM/ARMSectLinker.cpp
new file mode 100644
index 0000000..d686060
--- /dev/null
+++ b/lib/Target/ARM/ARMSectLinker.cpp
@@ -0,0 +1,47 @@
+//===- ARMSectLinker.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/ADT/Triple.h>
+#include <mcld/Support/TargetRegistry.h>
+#include "ARM.h"
+#include "ARMAndroidSectLinker.h"
+#include "ARMELFSectLinker.h"
+
+
+using namespace mcld;
+
+namespace mcld {
+//===----------------------------------------------------------------------===//
+// createARMSectLinker - the help function to create corresponding ARMSectLinker
+//
+SectLinker* createARMSectLinker(const std::string &pTriple,
+                                SectLinkerOption &pOption,
+                                mcld::TargetLDBackend &pLDBackend)
+{
+  Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker has not supported yet");
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker has not supported yet");
+  }
+
+  // For now, use Android SectLinker directly
+  return new ARMAndroidSectLinker(pOption,
+                                  pLDBackend);
+}
+
+} // namespace of mcld
+
+//==========================
+// ARMSectLinker
+extern "C" void LLVMInitializeARMSectLinker() {
+  // Register the linker frontend
+  mcld::TargetRegistry::RegisterSectLinker(TheARMTarget, createARMSectLinker);
+}
+
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
new file mode 100644
index 0000000..530a610
--- /dev/null
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -0,0 +1,33 @@
+//===- ARMTargetMachine.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "ARMTargetMachine.h"
+
+#include "mcld/Support/TargetRegistry.h"
+#include "mcld/MC/MCLDInfo.h"
+#include "ARM.h"
+
+extern "C" void LLVMInitializeARMLDTarget() {
+  // Register createTargetMachine function pointer to mcld::Target
+  mcld::RegisterTargetMachine<mcld::ARMBaseTargetMachine> X(mcld::TheARMTarget);
+}
+
+mcld::ARMBaseTargetMachine::ARMBaseTargetMachine(llvm::TargetMachine& pPM,
+                                                 const mcld::Target &pTarget,
+                                                 const std::string& pTriple)
+  : mcld::LLVMTargetMachine(pPM, pTarget, pTriple) {
+  // arg1 - the number of total attributes
+  // arg2 - the most possible number of input files
+  m_pLDInfo = new MCLDInfo(pTriple, 32, 64);
+}
+
+mcld::ARMBaseTargetMachine::~ARMBaseTargetMachine()
+{
+  delete m_pLDInfo;
+}
+
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
new file mode 100644
index 0000000..19f8aa2
--- /dev/null
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -0,0 +1,40 @@
+//===- ARMTargetMachine.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARM_TARGET_MACHINE_H
+#define MCLD_ARM_TARGET_MACHINE_H
+#include "mcld/Target/TargetMachine.h"
+#include "ARM.h"
+
+namespace mcld
+{
+
+class ARMBaseTargetMachine : public LLVMTargetMachine
+{
+protected:
+  MCLDInfo *m_pLDInfo;
+
+public:
+  ARMBaseTargetMachine(llvm::TargetMachine &pTM,
+                       const mcld::Target &pTarget,
+                       const std::string &pTriple);
+
+  virtual ~ARMBaseTargetMachine();
+
+  mcld::MCLDInfo& getLDInfo()
+  { return *m_pLDInfo; }
+
+  const mcld::MCLDInfo& getLDInfo() const
+  { return *m_pLDInfo; }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/ARM/Android.mk b/lib/Target/ARM/Android.mk
new file mode 100644
index 0000000..272e9f4
--- /dev/null
+++ b/lib/Target/ARM/Android.mk
@@ -0,0 +1,40 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_arm_target_SRC_FILES := \
+  ARMAndroidSectLinker.cpp  \
+  ARMELFDynamic.cpp \
+  ARMELFSectLinker.cpp  \
+  ARMGOT.cpp  \
+  ARMLDBackend.cpp  \
+  ARMPLT.cpp  \
+  ARMRelocationFactory.cpp  \
+  ARMSectLinker.cpp \
+  ARMTargetMachine.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_arm_target_SRC_FILES)
+LOCAL_MODULE:= libmcldARMTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),arm)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_arm_target_SRC_FILES)
+LOCAL_MODULE:= libmcldARMTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/ARM/README b/lib/Target/ARM/README
new file mode 100644
index 0000000..ea88bfe
--- /dev/null
+++ b/lib/Target/ARM/README
@@ -0,0 +1,2 @@
+ARMLDBackend stands like ARMAsmBackend. It's a backend of linker, 
+and all target-dependent behavior and data are here.
diff --git a/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp b/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp
new file mode 100644
index 0000000..7e6a41a
--- /dev/null
+++ b/lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp
@@ -0,0 +1,22 @@
+//===- ARMTargetInfo.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Support/TargetRegistry.h"
+
+namespace mcld {
+
+mcld::Target TheARMTarget;
+
+extern "C" void LLVMInitializeARMLDTargetInfo() {
+  // register into mcld::TargetRegistry
+  mcld::RegisterTarget X(TheARMTarget, "arm" );
+}
+
+} // namespace of mcld
+
diff --git a/lib/Target/ARM/TargetInfo/Android.mk b/lib/Target/ARM/TargetInfo/Android.mk
new file mode 100644
index 0000000..c4fffa3
--- /dev/null
+++ b/lib/Target/ARM/TargetInfo/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_arm_info_SRC_FILES := \
+  ARMTargetInfo.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_arm_info_SRC_FILES)
+LOCAL_MODULE:= libmcldARMInfo
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),arm)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_arm_info_SRC_FILES)
+LOCAL_MODULE:= libmcldARMInfo
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/Android.mk b/lib/Target/Android.mk
new file mode 100644
index 0000000..8e6e260
--- /dev/null
+++ b/lib/Target/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_target_SRC_FILES := \
+  AndroidSectLinker.cpp \
+  ELFDynamic.cpp  \
+  GNULDBackend.cpp  \
+  GOT.cpp \
+  OutputRelocSection.cpp  \
+  PLT.cpp \
+  Stub.cpp  \
+  Target.cpp  \
+  TargetLDBackend.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_target_SRC_FILES)
+LOCAL_MODULE:= libmcldTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_target_SRC_FILES)
+LOCAL_MODULE:= libmcldTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Target/AndroidSectLinker.cpp b/lib/Target/AndroidSectLinker.cpp
new file mode 100644
index 0000000..8f3acbf
--- /dev/null
+++ b/lib/Target/AndroidSectLinker.cpp
@@ -0,0 +1,45 @@
+//===- AndroidSectLinker.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/Target/AndroidSectLinker.h>
+
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/MC/MCLDDirectory.h>
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+//==========================
+// AndroidSectLinker
+
+AndroidSectLinker::AndroidSectLinker(SectLinkerOption &pOption,
+                                     TargetLDBackend &pLDBackend)
+  : SectLinker(pOption, pLDBackend) {
+}
+
+AndroidSectLinker::~AndroidSectLinker()
+{
+  // SectLinker will delete m_pLDBackend and m_pLDDriver;
+}
+
+void AndroidSectLinker::addTargetOptions(llvm::Module &pM,
+                                         SectLinkerOption &pOption)
+{
+  // -----  Set up General Options  ----- //
+  MCLDInfo &info = pOption.info();
+  MCLDDirectory search_path("=/system/lib");
+  search_path.setSysroot(info.options().sysroot());
+  if (exists(search_path.path()) && is_directory(search_path.path()))
+    info.options().directories().add(search_path);
+  else {
+    // FIXME: need a warning function
+    llvm::errs() << "WARNING: can not open search directory: `-L" << search_path.name() << "'.\n";
+  }
+}
+
diff --git a/lib/Target/DarwinLDBackend.cpp b/lib/Target/DarwinLDBackend.cpp
new file mode 100644
index 0000000..5bd55c3
--- /dev/null
+++ b/lib/Target/DarwinLDBackend.cpp
@@ -0,0 +1,15 @@
+//===- DarwinLDBackend.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <DarwinLDBackend.h>
+
+using namespace mcld;
+
+//==========================
+// DarwinLDBackend
+
diff --git a/lib/Target/ELFDynamic.cpp b/lib/Target/ELFDynamic.cpp
new file mode 100644
index 0000000..b863ab1
--- /dev/null
+++ b/lib/Target/ELFDynamic.cpp
@@ -0,0 +1,257 @@
+//===- ELFDynamic.cpp -------------    ------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/Host.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/Target/ELFDynamic.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/LD/ELFFileFormat.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/Support/MemoryRegion.h>
+
+using namespace mcld;
+using namespace elf_dynamic;
+
+//===----------------------------------------------------------------------===//
+// elf_dynamic::EntryIF
+EntryIF::EntryIF()
+{
+}
+
+EntryIF::~EntryIF()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// ELFDynamic
+ELFDynamic::ELFDynamic(const GNULDBackend& pParent)
+  : m_pEntryFactory(NULL), m_Idx(0) {
+  if (32 == pParent.bitclass() && pParent.isLittleEndian()) {
+    m_pEntryFactory = new Entry<32, true>();
+  }
+  // FIXME: support big-endian and 64-bit machine.
+}
+
+
+ELFDynamic::~ELFDynamic()
+{
+  if (NULL != m_pEntryFactory)
+    delete m_pEntryFactory;
+
+  EntryListType::iterator entry, entryEnd = m_EntryList.end();
+  for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) {
+    if (NULL != *entry)
+      delete (*entry);
+  }
+
+  entryEnd = m_NeedList.end();
+  for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) {
+    if (NULL != *entry)
+      delete (*entry);
+  }
+}
+
+size_t ELFDynamic::size() const
+{
+  return (m_NeedList.size() + m_EntryList.size());
+}
+
+size_t ELFDynamic::numOfBytes() const
+{
+  return size()*entrySize();
+}
+
+size_t ELFDynamic::entrySize() const
+{
+  return m_pEntryFactory->size();
+}
+
+void ELFDynamic::reserveOne(uint64_t pTag)
+{
+  assert(NULL != m_pEntryFactory);
+  m_EntryList.push_back(new elf_dynamic::Entry<32, true>());
+}
+
+void ELFDynamic::applyOne(uint64_t pTag, uint64_t pValue)
+{
+  assert(m_Idx < m_EntryList.size());
+  m_EntryList[m_Idx]->setValue(pTag, pValue);
+  ++m_Idx;
+}
+
+
+/// reserveEntries - reserve entries
+void ELFDynamic::reserveEntries(const MCLDInfo& pLDInfo,
+                                const ELFFileFormat& pFormat)
+{
+  if (pLDInfo.output().type() == Output::DynObj) {
+    reserveOne(llvm::ELF::DT_SONAME); // DT_SONAME
+
+    if (pLDInfo.options().Bsymbolic())
+      reserveOne(llvm::ELF::DT_SYMBOLIC); // DT_SYMBOLIC
+  }
+
+  if (pFormat.hasInit())
+    reserveOne(llvm::ELF::DT_INIT); // DT_INIT
+
+  if (pFormat.hasFini())
+    reserveOne(llvm::ELF::DT_FINI); // DT_FINI
+
+  if (pFormat.hasInitArray()) {
+    reserveOne(llvm::ELF::DT_INIT_ARRAY); // DT_INIT_ARRAY
+    reserveOne(llvm::ELF::DT_INIT_ARRAYSZ); // DT_INIT_ARRAYSZ
+  }
+
+  if (pFormat.hasFiniArray()) {
+    reserveOne(llvm::ELF::DT_FINI_ARRAY); // DT_FINI_ARRAY
+    reserveOne(llvm::ELF::DT_FINI_ARRAYSZ); // DT_FINI_ARRAYSZ
+  }
+
+  if (pFormat.hasHashTab())
+    reserveOne(llvm::ELF::DT_HASH); // DT_HASH
+
+  if (pFormat.hasDynSymTab()) {
+    reserveOne(llvm::ELF::DT_SYMTAB); // DT_SYMTAB
+    reserveOne(llvm::ELF::DT_SYMENT); // DT_SYMENT
+  }
+
+  if (pFormat.hasDynStrTab()) {
+    reserveOne(llvm::ELF::DT_STRTAB); // DT_STRTAB
+    reserveOne(llvm::ELF::DT_STRSZ); // DT_STRSZ
+  }
+
+  reserveTargetEntries(pFormat); // DT_PLTGOT
+
+  if (pFormat.hasRelPlt() || pFormat.hasRelaPlt())
+    reserveOne(llvm::ELF::DT_PLTREL); // DT_PLTREL
+
+  if (pFormat.hasPLT()) {
+    reserveOne(llvm::ELF::DT_JMPREL); // DT_JMPREL
+    reserveOne(llvm::ELF::DT_PLTRELSZ); // DT_PLTRELSZ
+  }
+
+  if (pFormat.hasRelDyn()) {
+    reserveOne(llvm::ELF::DT_REL); // DT_REL
+    reserveOne(llvm::ELF::DT_RELSZ); // DT_RELSZ
+    reserveOne(llvm::ELF::DT_RELENT); // DT_RELENT
+  }
+
+  if (pFormat.hasRelaDyn()) {
+    reserveOne(llvm::ELF::DT_RELA); // DT_RELA
+    reserveOne(llvm::ELF::DT_RELASZ); // DT_RELASZ
+    reserveOne(llvm::ELF::DT_RELAENT); // DT_RELAENT
+  }
+  reserveOne(llvm::ELF::DT_NULL); // for DT_NULL
+}
+
+/// applyEntries - apply entries
+void ELFDynamic::applyEntries(const MCLDInfo& pInfo,
+                              const ELFFileFormat& pFormat)
+{
+  if (pInfo.output().type() == Output::DynObj &&
+      pInfo.options().Bsymbolic()) {
+      applyOne(llvm::ELF::DT_SYMBOLIC, 0x0); // DT_SYMBOLIC
+  }
+
+  if (pFormat.hasInit())
+    applyOne(llvm::ELF::DT_INIT, pFormat.getInit().addr()); // DT_INIT
+
+  if (pFormat.hasFini())
+    applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr()); // DT_FINI
+
+  if (pFormat.hasInitArray()) {
+    // DT_INIT_ARRAY
+    applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr());
+
+    // DT_INIT_ARRAYSZ
+    applyOne(llvm::ELF::DT_INIT_ARRAYSZ, pFormat.getInitArray().size());
+  }
+
+  if (pFormat.hasFiniArray()) {
+    // DT_FINI_ARRAY
+    applyOne(llvm::ELF::DT_FINI_ARRAY, pFormat.getFiniArray().addr());
+
+    // DT_FINI_ARRAYSZ
+    applyOne(llvm::ELF::DT_FINI_ARRAYSZ, pFormat.getFiniArray().size());
+  }
+
+  if (pFormat.hasHashTab())
+    applyOne(llvm::ELF::DT_HASH, pFormat.getHashTab().addr()); // DT_HASH
+
+  if (pFormat.hasDynSymTab()) {
+    applyOne(llvm::ELF::DT_SYMTAB, pFormat.getDynSymTab().addr()); // DT_SYMTAB
+    applyOne(llvm::ELF::DT_SYMENT, symbolSize()); // DT_SYMENT
+  }
+
+  if (pFormat.hasDynStrTab()) {
+    applyOne(llvm::ELF::DT_STRTAB, pFormat.getDynStrTab().addr()); // DT_STRTAB
+    applyOne(llvm::ELF::DT_STRSZ, pFormat.getDynStrTab().size()); // DT_STRSZ
+  }
+
+  applyTargetEntries(pFormat); // DT_PLTGOT
+
+  if (pFormat.hasRelPlt())
+    applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_REL); // DT_PLTREL
+  else if (pFormat.hasRelaPlt())
+    applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_RELA); // DT_PLTREL
+
+  if (pFormat.hasRelPlt()) {
+    applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelPlt().addr()); // DT_JMPREL
+    applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelPlt().size()); // DT_PLTRELSZ
+  }
+
+  if (pFormat.hasRelDyn()) {
+    applyOne(llvm::ELF::DT_REL, pFormat.getRelDyn().addr()); // DT_REL
+    applyOne(llvm::ELF::DT_RELSZ, pFormat.getRelDyn().size()); // DT_RELSZ
+    applyOne(llvm::ELF::DT_RELENT, m_pEntryFactory->relSize()); // DT_RELENT
+  }
+
+  if (pFormat.hasRelaDyn()) {
+    applyOne(llvm::ELF::DT_RELA, pFormat.getRelaDyn().addr()); // DT_RELA
+    applyOne(llvm::ELF::DT_RELASZ, pFormat.getRelaDyn().size()); // DT_RELASZ
+    applyOne(llvm::ELF::DT_RELAENT, m_pEntryFactory->relaSize()); // DT_RELAENT
+  }
+
+  applyOne(llvm::ELF::DT_NULL, 0x0); // for DT_NULL
+}
+
+/// symbolSize
+size_t ELFDynamic::symbolSize() const
+{
+  return m_pEntryFactory->symbolSize();
+}
+
+/// reserveNeedEntry - reserve on DT_NEED entry.
+void ELFDynamic::reserveNeedEntry()
+{
+  m_NeedList.push_back(m_pEntryFactory->clone());
+}
+
+/// emit
+void ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const
+{
+  if (pRegion.size() < pSection.size()) {
+    llvm::report_fatal_error(llvm::Twine("the given memory is smaller") +
+                             llvm::Twine(" than the section's demaind.\n"));
+  }
+
+  uint8_t* address = (uint8_t*)pRegion.start();
+  EntryListType::const_iterator entry, entryEnd = m_NeedList.end();
+  for (entry = m_NeedList.begin(); entry != entryEnd; ++entry)
+    address += (*entry)->emit(address);
+
+  entryEnd = m_EntryList.end();
+  for (entry = m_EntryList.begin(); entry != entryEnd; ++entry)
+    address += (*entry)->emit(address);
+}
+
+void ELFDynamic::applySoname(uint64_t pStrTabIdx)
+{
+  applyOne(llvm::ELF::DT_SONAME, pStrTabIdx); // DT_SONAME
+}
+
diff --git a/lib/Target/GNULDBackend.cpp b/lib/Target/GNULDBackend.cpp
new file mode 100644
index 0000000..b82af73
--- /dev/null
+++ b/lib/Target/GNULDBackend.cpp
@@ -0,0 +1,1021 @@
+//===- GNULDBackend.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/Support/ELF.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLDInputTree.h>
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/LD/LDSymbol.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <string>
+#include <cstring>
+#include <cassert>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// GNULDBackend
+GNULDBackend::GNULDBackend()
+  : m_pArchiveReader(0),
+    m_pObjectReader(0),
+    m_pDynObjReader(0),
+    m_pObjectWriter(0),
+    m_pDynObjWriter(0),
+    m_pDynObjFileFormat(0),
+    m_pExecFileFormat(0),
+    m_ELFSegmentTable(9)// magic number
+{
+  m_pSymIndexMap = new HashTableType(1024);
+}
+
+GNULDBackend::~GNULDBackend()
+{
+  if (m_pArchiveReader)
+    delete m_pArchiveReader;
+  if (m_pObjectReader)
+    delete m_pObjectReader;
+  if (m_pDynObjReader)
+    delete m_pDynObjReader;
+  if (m_pObjectWriter)
+    delete m_pObjectWriter;
+  if (m_pDynObjWriter)
+    delete m_pDynObjWriter;
+  if (m_pDynObjFileFormat)
+    delete m_pDynObjFileFormat;
+  if (m_pExecFileFormat)
+    delete m_pExecFileFormat;
+  if(m_pSymIndexMap)
+    delete m_pSymIndexMap;
+}
+
+size_t GNULDBackend::sectionStartOffset() const
+{
+  // FIXME: use fixed offset, we need 10 segments by default
+  return sizeof(llvm::ELF::Elf64_Ehdr)+10*sizeof(llvm::ELF::Elf64_Phdr);
+}
+
+bool GNULDBackend::initArchiveReader(MCLinker&, MCLDInfo &pInfo)
+{
+  if (0 == m_pArchiveReader)
+  {
+    LDReader::Endian isLittleEndian = LDReader::LittleEndian;
+    m_pArchiveReader = new GNUArchiveReader(pInfo, isLittleEndian);
+  }
+  return true;
+}
+
+bool GNULDBackend::initObjectReader(MCLinker& pLinker)
+{
+  if (0 == m_pObjectReader)
+    m_pObjectReader = new ELFObjectReader(*this, pLinker);
+  return true;
+}
+
+bool GNULDBackend::initDynObjReader(MCLinker& pLinker)
+{
+  if (0 == m_pDynObjReader)
+    m_pDynObjReader = new ELFDynObjReader(*this, pLinker);
+  return true;
+}
+
+bool GNULDBackend::initObjectWriter(MCLinker&)
+{
+  // TODO
+  return true;
+}
+
+bool GNULDBackend::initDynObjWriter(MCLinker& pLinker)
+{
+  if (0 == m_pDynObjWriter)
+    m_pDynObjWriter = new ELFDynObjWriter(*this, pLinker);
+  return true;
+}
+
+bool GNULDBackend::initExecSections(MCLinker& pMCLinker)
+{
+  if (0 == m_pExecFileFormat)
+    m_pExecFileFormat = new ELFExecFileFormat(*this);
+
+  // initialize standard sections
+  m_pExecFileFormat->initStdSections(pMCLinker);
+  return true;
+}
+
+bool GNULDBackend::initDynObjSections(MCLinker& pMCLinker)
+{
+  if (0 == m_pDynObjFileFormat)
+    m_pDynObjFileFormat = new ELFDynObjFileFormat(*this);
+
+  // initialize standard sections
+  m_pDynObjFileFormat->initStdSections(pMCLinker);
+  return true;
+}
+
+bool GNULDBackend::initStandardSymbols(MCLinker& pLinker)
+{
+  return true;
+}
+
+GNUArchiveReader *GNULDBackend::getArchiveReader()
+{
+  assert(0 != m_pArchiveReader);
+  return m_pArchiveReader;
+}
+
+GNUArchiveReader *GNULDBackend::getArchiveReader() const
+{
+  assert(0 != m_pArchiveReader);
+  return m_pArchiveReader;
+}
+
+ELFObjectReader *GNULDBackend::getObjectReader()
+{
+  assert(0 != m_pObjectReader);
+  return m_pObjectReader;
+}
+
+ELFObjectReader *GNULDBackend::getObjectReader() const
+{
+  assert(0 != m_pObjectReader);
+  return m_pObjectReader;
+}
+
+ELFDynObjReader *GNULDBackend::getDynObjReader()
+{
+  assert(0 != m_pDynObjReader);
+  return m_pDynObjReader;
+}
+
+ELFDynObjReader *GNULDBackend::getDynObjReader() const
+{
+  assert(0 != m_pDynObjReader);
+  return m_pDynObjReader;
+}
+
+ELFObjectWriter *GNULDBackend::getObjectWriter()
+{
+  // TODO
+  return NULL;
+}
+
+ELFObjectWriter *GNULDBackend::getObjectWriter() const
+{
+  // TODO
+  return NULL;
+}
+
+ELFDynObjWriter *GNULDBackend::getDynObjWriter()
+{
+  assert(0 != m_pDynObjWriter);
+  return m_pDynObjWriter;
+}
+
+ELFDynObjWriter *GNULDBackend::getDynObjWriter() const
+{
+  assert(0 != m_pDynObjWriter);
+  return m_pDynObjWriter;
+}
+
+ELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat()
+{
+  assert(0 != m_pDynObjFileFormat);
+  return m_pDynObjFileFormat;
+}
+
+ELFDynObjFileFormat* GNULDBackend::getDynObjFileFormat() const
+{
+  assert(0 != m_pDynObjFileFormat);
+  return m_pDynObjFileFormat;
+}
+
+ELFExecFileFormat* GNULDBackend::getExecFileFormat()
+{
+  assert(0 != m_pExecFileFormat);
+  return m_pExecFileFormat;
+}
+
+ELFExecFileFormat* GNULDBackend::getExecFileFormat() const
+{
+  assert(0 != m_pExecFileFormat);
+  return m_pExecFileFormat;
+}
+
+/// sizeNamePools - compute the size of regular name pools
+/// In ELF executable files, regular name pools are .symtab, .strtab,
+/// .dynsym, .dynstr, and .hash
+void
+GNULDBackend::sizeNamePools(const Output& pOutput,
+                            const SymbolCategory& pSymbols,
+                            const MCLDInfo& pLDInfo)
+{
+  // size of string tables starts from 1 to hold the null character in their
+  // first byte
+  size_t symtab = 1;
+  size_t dynsym = 1;
+  // number of entries in symbol tables starts from 1 to hold the special entry
+  // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
+  size_t strtab = 1;
+  size_t dynstr = 1;
+  size_t hash   = 0;
+
+  // compute size of .symtab, .dynsym and .strtab
+  SymbolCategory::const_iterator symbol;
+  SymbolCategory::const_iterator symEnd = pSymbols.end();
+  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
+    size_t str_size = (*symbol)->nameSize() + 1;
+    if (isDynamicSymbol(**symbol, pOutput)) {
+      ++dynsym;
+      dynstr += str_size;
+    }
+    ++symtab;
+    strtab += str_size;
+  }
+
+  ELFFileFormat* file_format = NULL;
+  switch(pOutput.type()) {
+    // compute size of .dynstr and .hash
+    case Output::DynObj:
+      file_format = getDynObjFileFormat();
+      break;
+    case Output::Exec:
+      file_format = getExecFileFormat();
+      break;
+    case Output::Object:
+    default:
+      // TODO: not support yet
+      return;
+  }
+
+  switch(pOutput.type()) {
+    // compute size of .dynstr and .hash
+    case Output::DynObj:
+    case Output::Exec: {
+      // add DT_NEED strings into .dynstr and .dynamic
+      // Rules:
+      //   1. ignore --no-add-needed
+      //   2. force count in --no-as-needed
+      //   3. judge --as-needed
+      InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
+      for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
+        if (Input::DynObj == (*input)->type()) {
+          // --add-needed
+          if ((*input)->attribute()->isAddNeeded()) {
+            // --no-as-needed
+            if (!(*input)->attribute()->isAsNeeded()) {
+              dynstr += (*input)->name().size() + 1;
+              dynamic().reserveNeedEntry();
+            }
+            // --as-needed
+            else if ((*input)->isNeeded()) {
+              dynstr += (*input)->name().size() + 1;
+              dynamic().reserveNeedEntry();
+            }
+          }
+        }
+      } // for
+
+      // compute .hash
+      // Both Elf32_Word and Elf64_Word are 4 bytes
+      hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
+             sizeof(llvm::ELF::Elf32_Word);
+
+      // set size
+      dynstr += pOutput.name().size() + 1;
+      if (32 == bitclass())
+        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
+      else
+        file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
+      file_format->getDynStrTab().setSize(dynstr);
+      file_format->getHashTab().setSize(hash);
+
+    }
+    /* fall through */
+    case Output::Object: {
+      if (32 == bitclass())
+        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
+      else
+        file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
+      file_format->getStrTab().setSize(strtab);
+      break;
+    }
+  } // end of switch
+
+  // reserve fixed entries in the .dynamic section.
+  if (Output::DynObj == pOutput.type() || Output::Exec == pOutput.type()) {
+    // Because some entries in .dynamic section need information of .dynsym,
+    // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
+    // entries until we get the size of the sections mentioned above
+    dynamic().reserveEntries(pLDInfo, *file_format);
+    file_format->getDynamic().setSize(dynamic().numOfBytes());
+  }
+}
+
+/// emitRegNamePools - emit regular name pools - .symtab, .strtab
+///
+/// the size of these tables should be computed before layout
+/// layout should computes the start offset of these tables
+void GNULDBackend::emitRegNamePools(Output& pOutput,
+                                    SymbolCategory& pSymbols,
+                                    const Layout& pLayout,
+                                    const MCLDInfo& pLDInfo)
+{
+
+  assert(pOutput.hasMemArea());
+
+  bool sym_exist = false;
+  HashTableType::entry_type* entry = 0;
+
+  ELFFileFormat* file_format = NULL;
+  switch(pOutput.type()) {
+    // compute size of .dynstr and .hash
+    case Output::DynObj:
+      file_format = getDynObjFileFormat();
+      break;
+    case Output::Exec:
+      file_format = getExecFileFormat();
+      break;
+    case Output::Object:
+    default:
+      // add first symbol into m_pSymIndexMap
+      entry = m_pSymIndexMap->insert(NULL, sym_exist);
+      entry->setValue(0);
+
+      // TODO: not support yet
+      return;
+  }
+
+  LDSection& symtab_sect = file_format->getSymTab();
+  LDSection& strtab_sect = file_format->getStrTab();
+
+  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
+                                                           symtab_sect.size());
+  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
+                                                           strtab_sect.size());
+
+  // set up symtab_region
+  llvm::ELF::Elf32_Sym* symtab32 = NULL;
+  llvm::ELF::Elf64_Sym* symtab64 = NULL;
+  if (32 == bitclass())
+    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
+  else if (64 == bitclass())
+    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
+  else
+    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
+                             llvm::Twine(bitclass()) +
+                             llvm::Twine(".\n"));
+  // set up strtab_region
+  char* strtab = (char*)strtab_region->start();
+  strtab[0] = '\0';
+
+  // initialize the first ELF symbol
+  if (32 == bitclass()) {
+    symtab32[0].st_name  = 0;
+    symtab32[0].st_value = 0;
+    symtab32[0].st_size  = 0;
+    symtab32[0].st_info  = 0;
+    symtab32[0].st_other = 0;
+    symtab32[0].st_shndx = 0;
+  }
+  else { // must 64
+    symtab64[0].st_name  = 0;
+    symtab64[0].st_value = 0;
+    symtab64[0].st_size  = 0;
+    symtab64[0].st_info  = 0;
+    symtab64[0].st_other = 0;
+    symtab64[0].st_shndx = 0;
+  }
+
+  size_t symtabIdx = 1;
+  size_t strtabsize = 1;
+  // compute size of .symtab, .dynsym and .strtab
+  SymbolCategory::iterator symbol;
+  SymbolCategory::iterator symEnd = pSymbols.end();
+  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
+
+     // maintain output's symbol and index map if building .o file
+    if (Output::Object == pOutput.type()) {
+      entry = m_pSymIndexMap->insert(NULL, sym_exist);
+      entry->setValue(symtabIdx);
+    }
+
+    // FIXME: check the endian between host and target
+    // write out symbol
+    if (32 == bitclass()) {
+      symtab32[symtabIdx].st_name  = strtabsize;
+      symtab32[symtabIdx].st_value = getSymbolValue(**symbol);
+      symtab32[symtabIdx].st_size  = getSymbolSize(**symbol);
+      symtab32[symtabIdx].st_info  = getSymbolInfo(**symbol);
+      symtab32[symtabIdx].st_other = (*symbol)->visibility();
+      symtab32[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
+    }
+    else { // must 64
+      symtab64[symtabIdx].st_name  = strtabsize;
+      symtab64[symtabIdx].st_value = getSymbolValue(**symbol);
+      symtab64[symtabIdx].st_size  = getSymbolSize(**symbol);
+      symtab64[symtabIdx].st_info  = getSymbolInfo(**symbol);
+      symtab64[symtabIdx].st_other = (*symbol)->visibility();
+      symtab64[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
+    }
+    // write out string
+    strcpy((strtab + strtabsize), (*symbol)->name());
+
+    // write out
+    // sum up counters
+    ++symtabIdx;
+    strtabsize += (*symbol)->nameSize() + 1;
+  }
+}
+
+/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
+///
+/// the size of these tables should be computed before layout
+/// layout should computes the start offset of these tables
+void GNULDBackend::emitDynNamePools(Output& pOutput,
+                                    SymbolCategory& pSymbols,
+                                    const Layout& pLayout,
+                                    const MCLDInfo& pLDInfo)
+{
+  assert(pOutput.hasMemArea());
+  ELFFileFormat* file_format = NULL;
+
+  bool sym_exist = false;
+  HashTableType::entry_type* entry = 0;
+
+  switch(pOutput.type()) {
+    // compute size of .dynstr and .hash
+    case Output::DynObj:
+      file_format = getDynObjFileFormat();
+      break;
+    case Output::Exec:
+      file_format = getExecFileFormat();
+      break;
+    case Output::Object:
+    default:
+      // TODO: not support yet
+      return;
+  }
+
+  LDSection& symtab_sect = file_format->getDynSymTab();
+  LDSection& strtab_sect = file_format->getDynStrTab();
+  LDSection& hash_sect   = file_format->getHashTab();
+  LDSection& dyn_sect    = file_format->getDynamic();
+
+  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
+                                                           symtab_sect.size());
+  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
+                                                           strtab_sect.size());
+  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
+                                                         hash_sect.size());
+  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
+                                                        dyn_sect.size());
+  // set up symtab_region
+  llvm::ELF::Elf32_Sym* symtab32 = NULL;
+  llvm::ELF::Elf64_Sym* symtab64 = NULL;
+  if (32 == bitclass())
+    symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
+  else if (64 == bitclass())
+    symtab64 = (llvm::ELF::Elf64_Sym*)symtab_region->start();
+  else
+    llvm::report_fatal_error(llvm::Twine("unsupported bitclass ") +
+                             llvm::Twine(bitclass()) +
+                             llvm::Twine(".\n"));
+
+  // initialize the first ELF symbol
+  if (32 == bitclass()) {
+    symtab32[0].st_name  = 0;
+    symtab32[0].st_value = 0;
+    symtab32[0].st_size  = 0;
+    symtab32[0].st_info  = 0;
+    symtab32[0].st_other = 0;
+    symtab32[0].st_shndx = 0;
+  }
+  else { // must 64
+    symtab64[0].st_name  = 0;
+    symtab64[0].st_value = 0;
+    symtab64[0].st_size  = 0;
+    symtab64[0].st_info  = 0;
+    symtab64[0].st_other = 0;
+    symtab64[0].st_shndx = 0;
+  }
+  // set up strtab_region
+  char* strtab = (char*)strtab_region->start();
+  strtab[0] = '\0';
+
+  // add the first symbol into m_pSymIndexMap
+  entry = m_pSymIndexMap->insert(NULL, sym_exist);
+  entry->setValue(0);
+
+  size_t symtabIdx = 1;
+  size_t strtabsize = 1;
+
+  // emit of .dynsym, and .dynstr
+  SymbolCategory::iterator symbol;
+  SymbolCategory::iterator symEnd = pSymbols.end();
+  for (symbol = pSymbols.begin(); symbol != symEnd; ++symbol) {
+    if (!isDynamicSymbol(**symbol, pOutput))
+      continue;
+
+    // maintain output's symbol and index map
+    entry = m_pSymIndexMap->insert(*symbol, sym_exist);
+    entry->setValue(symtabIdx);
+
+    // FIXME: check the endian between host and target
+    // write out symbol
+    if (32 == bitclass()) {
+      symtab32[symtabIdx].st_name  = strtabsize;
+      symtab32[symtabIdx].st_value = (*symbol)->value();
+      symtab32[symtabIdx].st_size  = getSymbolSize(**symbol);
+      symtab32[symtabIdx].st_info  = getSymbolInfo(**symbol);
+      symtab32[symtabIdx].st_other = (*symbol)->visibility();
+      symtab32[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
+    }
+    else { // must 64
+      symtab64[symtabIdx].st_name  = strtabsize;
+      symtab64[symtabIdx].st_value = (*symbol)->value();
+      symtab64[symtabIdx].st_size  = getSymbolSize(**symbol);
+      symtab64[symtabIdx].st_info  = getSymbolInfo(**symbol);
+      symtab64[symtabIdx].st_other = (*symbol)->visibility();
+      symtab64[symtabIdx].st_shndx = getSymbolShndx(**symbol, pLayout);
+    }
+    // write out string
+    strcpy((strtab + strtabsize), (*symbol)->name());
+
+    // sum up counters
+    ++symtabIdx;
+    strtabsize += (*symbol)->nameSize() + 1;
+  }
+
+  // emit DT_NEED
+  // add DT_NEED strings into .dynstr
+  // Rules:
+  //   1. ignore --no-add-needed
+  //   2. force count in --no-as-needed
+  //   3. judge --as-needed
+  ELFDynamic::iterator dt_need = dynamic().needBegin();
+  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
+  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
+    if (Input::DynObj == (*input)->type()) {
+      // --add-needed
+      if ((*input)->attribute()->isAddNeeded()) {
+        // --no-as-needed
+        if (!(*input)->attribute()->isAsNeeded()) {
+          strcpy((strtab + strtabsize), (*input)->name().c_str());
+          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
+          strtabsize += (*input)->name().size() + 1;
+          ++dt_need;
+        }
+        // --as-needed
+        else if ((*input)->isNeeded()) {
+          strcpy((strtab + strtabsize), (*input)->name().c_str());
+          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
+          strtabsize += (*input)->name().size() + 1;
+          ++dt_need;
+        }
+      }
+    }
+  } // for
+
+  // emit soname
+  // initialize value of ELF .dynamic section
+  dynamic().applySoname(strtabsize);
+  dynamic().applyEntries(pLDInfo, *file_format);
+  dynamic().emit(dyn_sect, *dyn_region);
+
+  strcpy((strtab + strtabsize), pOutput.name().c_str());
+  strtabsize += pOutput.name().size() + 1;
+
+  // emit hash table
+  // FIXME: this verion only emit SVR4 hash section.
+  //        Please add GNU new hash section
+
+  // both 32 and 64 bits hash table use 32-bit entry
+  // set up hash_region
+  uint32_t* word_array = (uint32_t*)hash_region->start();
+  uint32_t& nbucket = word_array[0];
+  uint32_t& nchain  = word_array[1];
+
+  nbucket = getHashBucketCount(symtabIdx, false);
+  nchain  = symtabIdx;
+
+  uint32_t* bucket = (word_array + 2);
+  uint32_t* chain  = (bucket + nbucket);
+
+  // initialize bucket
+  bzero((void*)bucket, nbucket);
+
+  StringHash<ELF> hash_func;
+
+  if (32 == bitclass()) {
+    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
+      llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
+      size_t bucket_pos = hash_func(name) % nbucket;
+      chain[sym_idx] = bucket[bucket_pos];
+      bucket[bucket_pos] = sym_idx;
+    }
+  }
+  else if (64 == bitclass()) {
+    for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
+      llvm::StringRef name(strtab + symtab64[sym_idx].st_name);
+      size_t bucket_pos = hash_func(name) % nbucket;
+      chain[sym_idx] = bucket[bucket_pos];
+      bucket[bucket_pos] = sym_idx;
+    }
+  }
+}
+
+/// getSectionOrder
+unsigned int GNULDBackend::getSectionOrder(const Output& pOutput,
+                                           const LDSection& pSectHdr) const
+{
+  // NULL section should be the "1st" section
+  if (LDFileFormat::Null == pSectHdr.kind())
+    return 0;
+
+  // if the section is not ALLOC, lay it out until the last possible moment
+  if (0 == (pSectHdr.flag() & llvm::ELF::SHF_ALLOC))
+    return SHO_UNDEFINED;
+
+  bool is_write = (pSectHdr.flag() & llvm::ELF::SHF_WRITE) != 0;
+  bool is_exec = (pSectHdr.flag() & llvm::ELF::SHF_EXECINSTR) != 0;
+  ELFFileFormat* file_format = NULL;
+  switch (pOutput.type()) {
+    case Output::DynObj:
+      file_format = getDynObjFileFormat();
+      break;
+    case Output::Exec:
+      file_format = getExecFileFormat();
+      break;
+    case Output::Object:
+    default:
+      assert(0 && "Not support yet.\n");
+      break;
+  }
+
+  // TODO: need to take care other possible output sections
+  switch (pSectHdr.kind()) {
+    case LDFileFormat::Regular:
+      if (is_exec) {
+        if (&pSectHdr == &file_format->getInit())
+          return SHO_INIT;
+        if (&pSectHdr == &file_format->getFini())
+          return SHO_FINI;
+        return SHO_TEXT;
+      } else if (!is_write) {
+        return SHO_RO;
+      } else {
+        if (pSectHdr.type() == llvm::ELF::SHT_PREINIT_ARRAY ||
+            pSectHdr.type() == llvm::ELF::SHT_INIT_ARRAY ||
+            pSectHdr.type() == llvm::ELF::SHT_FINI_ARRAY ||
+            &pSectHdr == &file_format->getCtors() ||
+            &pSectHdr == &file_format->getDtors())
+          return SHO_RELRO;
+
+        return SHO_DATA;
+      }
+
+    case LDFileFormat::BSS:
+      return SHO_BSS;
+
+    case LDFileFormat::NamePool:
+      if (&pSectHdr == &file_format->getDynamic())
+        return SHO_RELRO;
+      return SHO_NAMEPOOL;
+
+    case LDFileFormat::Relocation:
+      if (&pSectHdr == &file_format->getRelPlt() ||
+          &pSectHdr == &file_format->getRelaPlt())
+        return SHO_REL_PLT;
+      return SHO_RELOCATION;
+
+    // get the order from target for target specific sections
+    case LDFileFormat::Target:
+      return getTargetSectionOrder(pOutput, pSectHdr);
+
+    // handle .interp
+    case LDFileFormat::Note:
+      return SHO_INTERP;
+
+    case LDFileFormat::Exception:
+      return SHO_EHFRAME;
+
+    case LDFileFormat::MetaData:
+    case LDFileFormat::Debug:
+    default:
+      return SHO_UNDEFINED;
+  }
+}
+
+/// getSymbolSize
+uint64_t GNULDBackend::getSymbolSize(const LDSymbol& pSymbol) const
+{
+  // @ref Google gold linker: symtab.cc: 2780
+  // undefined and dynamic symbols should have zero size.
+  if (pSymbol.isDyn() || pSymbol.desc() == ResolveInfo::Undefined)
+    return 0x0;
+  return pSymbol.resolveInfo()->size();
+}
+
+/// getSymbolInfo
+uint64_t GNULDBackend::getSymbolInfo(const LDSymbol& pSymbol) const
+{
+  // set binding
+  uint8_t bind = 0x0;
+  if (pSymbol.resolveInfo()->isLocal())
+    bind = llvm::ELF::STB_LOCAL;
+  else if (pSymbol.resolveInfo()->isGlobal())
+    bind = llvm::ELF::STB_GLOBAL;
+  else if (pSymbol.resolveInfo()->isWeak())
+    bind = llvm::ELF::STB_WEAK;
+  else if (pSymbol.resolveInfo()->isAbsolute()) {
+    // (Luba) Is a absolute but not global (weak or local) symbol meaningful?
+    bind = llvm::ELF::STB_GLOBAL;
+  }
+
+  if (pSymbol.visibility() == llvm::ELF::STV_INTERNAL ||
+      pSymbol.visibility() == llvm::ELF::STV_HIDDEN)
+    bind = llvm::ELF::STB_LOCAL;
+
+  return (pSymbol.resolveInfo()->type() | (bind << 4));
+}
+
+/// getSymbolValue - this function is called after layout()
+uint64_t GNULDBackend::getSymbolValue(const LDSymbol& pSymbol) const
+{
+  if (pSymbol.isDyn())
+    return 0x0;
+
+  return pSymbol.value();
+}
+
+/// getSymbolShndx - this function is called after layout()
+uint64_t
+GNULDBackend::getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const
+{
+  if (pSymbol.resolveInfo()->isAbsolute())
+    return llvm::ELF::SHN_ABS;
+  if (pSymbol.resolveInfo()->isCommon())
+    return llvm::ELF::SHN_COMMON;
+  if (pSymbol.resolveInfo()->isUndef() || pSymbol.isDyn())
+    return llvm::ELF::SHN_UNDEF;
+
+  if (pSymbol.resolveInfo()->isLocal()) {
+    switch (pSymbol.type()) {
+      case ResolveInfo::NoType:
+      case ResolveInfo::File:
+        return llvm::ELF::SHN_ABS;
+    }
+  }
+
+  assert(pSymbol.hasFragRef());
+  return pLayout.getOutputLDSection(*pSymbol.fragRef()->frag())->index();
+}
+
+/// getSymbolIdx - called by emitRelocation to get the ouput symbol table index
+size_t GNULDBackend::getSymbolIdx(LDSymbol* pSymbol) const
+{
+   HashTableType::iterator entry = m_pSymIndexMap->find(pSymbol);
+   return entry.getEntry()->value();
+}
+
+/// emitProgramHdrs - emit ELF program headers
+void GNULDBackend::emitProgramHdrs(Output& pOutput)
+{
+  assert(NULL != pOutput.context());
+  createProgramHdrs(*pOutput.context());
+
+  if (32 == bitclass())
+    writeELF32ProgramHdrs(pOutput);
+  else
+    writeELF64ProgramHdrs(pOutput);
+}
+
+/// createProgramHdrs - base on output sections to create the program headers
+void GNULDBackend::createProgramHdrs(LDContext& pContext)
+{
+  // make PT_PHDR
+  m_ELFSegmentTable.produce(llvm::ELF::PT_PHDR);
+
+  // make PT_INTERP
+  LDSection* interp = pContext.getSection(".interp");
+  if (NULL != interp) {
+    ELFSegment* interp_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_INTERP);
+    interp_seg->addSection(interp);
+    interp_seg->setAlign(bitclass() / 8);
+  }
+
+  uint32_t cur_seg_flag, prev_seg_flag = getSegmentFlag(0);
+  uint64_t padding = 0;
+  ELFSegment* load_seg = NULL;
+  // make possible PT_LOAD segments
+  LDContext::sect_iterator sect, sect_end = pContext.sectEnd();
+  for (sect = pContext.sectBegin(); sect != sect_end; ++sect) {
+    if (0 == ((*sect)->flag() & llvm::ELF::SHF_ALLOC) &&
+        LDFileFormat::Null != (*sect)->kind())
+      continue;
+
+    // FIXME: Now only separate writable and non-writable PT_LOAD
+    cur_seg_flag = getSegmentFlag((*sect)->flag());
+    if ((prev_seg_flag & llvm::ELF::PF_W) ^ (cur_seg_flag & llvm::ELF::PF_W) ||
+         LDFileFormat::Null == (*sect)->kind()) {
+      // create new PT_LOAD segment
+      load_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_LOAD);
+      load_seg->setAlign(pagesize());
+
+      // check if this segment needs padding
+      padding = 0;
+      if (((*sect)->offset() & (load_seg->align() - 1)) != 0)
+        padding = load_seg->align();
+    }
+
+    assert(NULL != load_seg);
+    load_seg->addSection(*sect);
+    load_seg->updateFlag(cur_seg_flag);
+
+    // FIXME: set section's vma
+    // need to handle start vma for user-defined one or for executable.
+    (*sect)->setAddr((*sect)->offset() + padding);
+
+    prev_seg_flag = cur_seg_flag;
+  }
+
+  // make PT_DYNAMIC
+  LDSection* dynamic = pContext.getSection(".dynamic");
+  if (NULL != dynamic) {
+    ELFSegment* dyn_seg = m_ELFSegmentTable.produce(llvm::ELF::PT_DYNAMIC);
+    dyn_seg->setFlag(llvm::ELF::PF_R | llvm::ELF::PF_W);
+    dyn_seg->addSection(dynamic);
+    dyn_seg->setAlign(bitclass() / 8);
+  }
+
+  // update segment info
+  uint64_t file_size = 0;
+  ELFSegmentFactory::iterator seg, seg_end = m_ELFSegmentTable.end();
+  for (seg = m_ELFSegmentTable.begin(); seg != seg_end; ++seg) {
+    ELFSegment& segment = *seg;
+
+    // update PT_PHDR
+    if (llvm::ELF::PT_PHDR == segment.type()) {
+      uint64_t offset, phdr_size;
+      if (32 == bitclass()) {
+        offset = sizeof(llvm::ELF::Elf32_Ehdr);
+        phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
+      }
+      else {
+        offset = sizeof(llvm::ELF::Elf64_Ehdr);
+        phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
+      }
+      segment.setOffset(offset);
+      segment.setVaddr(offset);
+      segment.setPaddr(segment.vaddr());
+      segment.setFilesz(numOfSegments() * phdr_size);
+      segment.setMemsz(numOfSegments() * phdr_size);
+      segment.setAlign(bitclass() / 8);
+      continue;
+    }
+
+    assert(NULL != segment.getFirstSection());
+    segment.setOffset(segment.getFirstSection()->offset());
+    segment.setVaddr(segment.getFirstSection()->addr());
+    segment.setPaddr(segment.vaddr());
+
+    const LDSection* last_sect = segment.getLastSection();
+    assert(NULL != last_sect);
+    file_size = last_sect->offset() - segment.offset();
+    if (LDFileFormat::BSS != last_sect->kind())
+      file_size += last_sect->size();
+    segment.setFilesz(file_size);
+
+    segment.setMemsz(last_sect->addr() - segment.vaddr() + last_sect->size());
+  }
+}
+
+/// writeELF32ProgramHdrs - write out the ELF32 program headers
+void GNULDBackend::writeELF32ProgramHdrs(Output& pOutput)
+{
+  assert(pOutput.hasMemArea());
+
+  uint64_t start_offset, phdr_size;
+
+  start_offset = sizeof(llvm::ELF::Elf32_Ehdr);
+  phdr_size = sizeof(llvm::ELF::Elf32_Phdr);
+  // Program header must start directly after ELF header
+  MemoryRegion *region = pOutput.memArea()->request(start_offset,
+                                                    numOfSegments()*phdr_size);
+
+  llvm::ELF::Elf32_Phdr* phdr = (llvm::ELF::Elf32_Phdr*)region->start();
+
+  size_t index = 0;
+  ELFSegmentFactory::iterator seg, segEnd = m_ELFSegmentTable.end();
+  for (seg = m_ELFSegmentTable.begin(); seg != segEnd; ++seg, ++index) {
+    phdr[index].p_type   = (*seg).type();
+    phdr[index].p_flags  = (*seg).flag();
+    phdr[index].p_offset = (*seg).offset();
+    phdr[index].p_vaddr  = (*seg).vaddr();
+    phdr[index].p_paddr  = (*seg).paddr();
+    phdr[index].p_filesz = (*seg).filesz();
+    phdr[index].p_memsz  = (*seg).memsz();
+    phdr[index].p_align  = (*seg).align();
+  }
+}
+
+/// writeELF64ProgramHdrs - write out the ELF64 program headers
+void GNULDBackend::writeELF64ProgramHdrs(Output& pOutput)
+{
+  assert(pOutput.hasMemArea());
+
+  uint64_t start_offset, phdr_size;
+
+  start_offset = sizeof(llvm::ELF::Elf64_Ehdr);
+  phdr_size = sizeof(llvm::ELF::Elf64_Phdr);
+  // Program header must start directly after ELF header
+  MemoryRegion *region = pOutput.memArea()->request(start_offset,
+                                                    numOfSegments() *phdr_size);
+  llvm::ELF::Elf64_Phdr* phdr = (llvm::ELF::Elf64_Phdr*)region->start();
+
+  size_t index = 0;
+  ELFSegmentFactory::iterator seg, segEnd = m_ELFSegmentTable.end();
+  for (seg = m_ELFSegmentTable.begin(); seg != segEnd; ++seg, ++index) {
+    phdr[index].p_type   = (*seg).type();
+    phdr[index].p_flags  = (*seg).flag();
+    phdr[index].p_offset = (*seg).offset();
+    phdr[index].p_vaddr  = (*seg).vaddr();
+    phdr[index].p_paddr  = (*seg).paddr();
+    phdr[index].p_filesz = (*seg).filesz();
+    phdr[index].p_memsz  = (*seg).memsz();
+    phdr[index].p_align  = (*seg).align();
+  }
+}
+
+/// preLayout - Backend can do any needed modification before layout
+void GNULDBackend::preLayout(const Output& pOutput,
+                             const MCLDInfo& pLDInfo,
+                             MCLinker& pLinker)
+{
+  // prelayout target first
+  doPreLayout(pOutput, pLDInfo, pLinker);
+}
+
+/// postLayout -Backend can do any needed modification after layout
+void GNULDBackend::postLayout(const Output& pOutput,
+                              const MCLDInfo& pInfo,
+                              MCLinker& pLinker)
+{
+  // post layout target first
+  doPostLayout(pOutput, pInfo, pLinker);
+}
+
+/// getHashBucketCount - calculate hash bucket count.
+/// @ref Google gold linker, dynobj.cc:791
+unsigned GNULDBackend::getHashBucketCount(unsigned pNumOfSymbols,
+                                          bool pIsGNUStyle)
+{
+  // @ref Google gold, dynobj.cc:loc 791
+  static const unsigned int buckets[] =
+  {
+    1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
+    16411, 32771, 65537, 131101, 262147
+  };
+  const unsigned buckets_count = sizeof buckets / sizeof buckets[0];
+
+  unsigned int result = 1;
+  for (unsigned i = 0; i < buckets_count; ++i) {
+    if (pNumOfSymbols < buckets[i])
+      break;
+    result = buckets[i];
+  }
+
+  if (pIsGNUStyle && result < 2)
+    result = 2;
+
+  return result;
+}
+
+/// isDynamicSymbol
+/// @ref Google gold linker: symtab.cc:311
+bool GNULDBackend::isDynamicSymbol(const LDSymbol& pSymbol,
+                                   const Output& pOutput)
+{
+  // If a local symbol is in the LDContext's symbol table, it's a real local
+  // symbol. We should not add it
+  if (pSymbol.binding() == ResolveInfo::Local)
+    return false;
+
+  // If we are building shared object, and the visibility is external, we
+  // need to add it.
+  if (Output::DynObj == pOutput.type())
+    if (pSymbol.resolveInfo()->visibility() == ResolveInfo::Default ||
+        pSymbol.resolveInfo()->visibility() == ResolveInfo::Protected)
+      return true;
+
+  return false;
+}
diff --git a/lib/Target/GOT.cpp b/lib/Target/GOT.cpp
new file mode 100644
index 0000000..a05b574
--- /dev/null
+++ b/lib/Target/GOT.cpp
@@ -0,0 +1,45 @@
+//===- GOT.cpp ------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Target/GOT.h>
+#include <cstring>
+#include <cstdlib>
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// GOTEntry
+GOTEntry::GOTEntry(uint64_t pContent, size_t pEntrySize,
+                   llvm::MCSectionData* pParent)
+  : MCTargetFragment(llvm::MCFragment::FT_Target, pParent),
+    f_Content(pContent), m_EntrySize(pEntrySize) {
+}
+
+GOTEntry::~GOTEntry()
+{
+}
+
+//===----------------------------------------------------------------------===//
+// GOT
+GOT::GOT(LDSection& pSection,
+         llvm::MCSectionData& pSectionData,
+         size_t pEntrySize)
+  : m_Section(pSection),
+    m_SectionData(pSectionData),
+    f_EntrySize(pEntrySize) {
+}
+
+GOT::~GOT()
+{
+}
+
+size_t GOT::getEntrySize() const
+{
+  return f_EntrySize;
+}
+
diff --git a/lib/Target/Mips/Android.mk b/lib/Target/Mips/Android.mk
new file mode 100644
index 0000000..cc5a211
--- /dev/null
+++ b/lib/Target/Mips/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_mips_target_SRC_FILES := \
+  MipsAndroidSectLinker.cpp \
+  MipsELFDynamic.cpp  \
+  MipsELFSectLinker.cpp \
+  MipsGOT.cpp \
+  MipsLDBackend.cpp \
+  MipsRelocationFactory.cpp \
+  MipsSectLinker.cpp  \
+  MipsTargetMachine.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mips_target_SRC_FILES)
+LOCAL_MODULE:= libmcldMipsTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),mips)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mips_target_SRC_FILES)
+LOCAL_MODULE:= libmcldMipsTarget
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/Mips/Mips.h b/lib/Target/Mips/Mips.h
new file mode 100644
index 0000000..a63be45
--- /dev/null
+++ b/lib/Target/Mips/Mips.h
@@ -0,0 +1,20 @@
+//===- Mips.h -------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MIPS_H
+#define MCLD_MIPS_H
+
+#include "mcld/Support/TargetRegistry.h"
+
+namespace mcld {
+
+extern mcld::Target TheMipselTarget;
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/Mips/MipsAndroidSectLinker.cpp b/lib/Target/Mips/MipsAndroidSectLinker.cpp
new file mode 100644
index 0000000..e697fbc
--- /dev/null
+++ b/lib/Target/Mips/MipsAndroidSectLinker.cpp
@@ -0,0 +1,33 @@
+//===- MipsAndroidSectLinker.cpp ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsAndroidSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+MipsAndroidSectLinker::MipsAndroidSectLinker(SectLinkerOption &pOption,
+                                             TargetLDBackend &pLDBackend)
+  : AndroidSectLinker(pOption,
+                      pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attibutes
+  info.attrFactory().constraint().disableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().unsetWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+}
+
+MipsAndroidSectLinker::~MipsAndroidSectLinker()
+{
+}
diff --git a/lib/Target/Mips/MipsAndroidSectLinker.h b/lib/Target/Mips/MipsAndroidSectLinker.h
new file mode 100644
index 0000000..ba216e4
--- /dev/null
+++ b/lib/Target/Mips/MipsAndroidSectLinker.h
@@ -0,0 +1,36 @@
+//===- MipsAndroidSectLinker.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_ANDROIDSECTLINKER_H
+#define MIPS_ANDROIDSECTLINKER_H
+
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Target/AndroidSectLinker.h"
+
+namespace mcld
+{
+
+/** \class MipsAndroidSectLinker
+ *  \brief MipsAndroidSectLinker sets up the environment for linking.
+ *
+ */
+class MipsAndroidSectLinker : public AndroidSectLinker
+{
+public:
+  MipsAndroidSectLinker(SectLinkerOption &pOption,
+                        mcld::TargetLDBackend &pLDBackend);
+
+  ~MipsAndroidSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/Mips/MipsELFDynamic.cpp b/lib/Target/Mips/MipsELFDynamic.cpp
new file mode 100644
index 0000000..cd692ac
--- /dev/null
+++ b/lib/Target/Mips/MipsELFDynamic.cpp
@@ -0,0 +1,90 @@
+//===- MipsELFDynamic.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/ELFFileFormat.h>
+#include <mcld/Target/GNULDBackend.h>
+#include "MipsELFDynamic.h"
+#include "MipsLDBackend.h"
+
+using namespace mcld;
+
+// MIPS mandatory dynamic section entries
+enum {
+  MIPS_RLD_VERSION  = 0x70000001,
+  MIPS_FLAGS        = 0x70000005,
+  MIPS_BASE_ADDRESS = 0x70000006,
+  MIPS_LOCAL_GOTNO  = 0x7000000a,
+  MIPS_SYMTABNO     = 0x70000011,
+  MIPS_GOTSYM       = 0x70000013,
+};
+
+MipsELFDynamic::MipsELFDynamic(const MipsGNULDBackend& pParent)
+  : ELFDynamic(pParent),
+    m_pParent(pParent)
+{
+}
+
+MipsELFDynamic::~MipsELFDynamic()
+{
+}
+
+void MipsELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat)
+{
+  // reservePLTGOT
+  if (pFormat.hasGOT())
+    reserveOne(llvm::ELF::DT_PLTGOT);
+
+  reserveOne(MIPS_RLD_VERSION);
+  reserveOne(MIPS_FLAGS);
+  reserveOne(MIPS_BASE_ADDRESS);
+  reserveOne(MIPS_LOCAL_GOTNO);
+  reserveOne(MIPS_SYMTABNO);
+  reserveOne(MIPS_GOTSYM);
+}
+
+void MipsELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
+{
+  // applyPLTGOT
+  if (pFormat.hasGOT())
+    applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr());
+
+  applyOne(MIPS_RLD_VERSION, 1);
+  applyOne(MIPS_FLAGS, 0);
+  applyOne(MIPS_BASE_ADDRESS, 0);
+  applyOne(MIPS_LOCAL_GOTNO, getLocalGotNum(pFormat));
+  applyOne(MIPS_SYMTABNO, getSymTabNum(pFormat));
+  applyOne(MIPS_GOTSYM, getGotSym(pFormat));
+}
+
+size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const
+{
+  if (!pFormat.hasDynSymTab())
+    return 0;
+
+  const LDSection& dynsym = pFormat.getDynSymTab();
+  return dynsym.size() / symbolSize();
+}
+
+size_t MipsELFDynamic::getGotSym(const ELFFileFormat& pFormat) const
+{
+  if (!pFormat.hasGOT())
+    return 0;
+
+  return getSymTabNum(pFormat) -
+         m_pParent.getGOT().getTotalNum() +
+         m_pParent.getGOT().getLocalNum();
+}
+
+size_t MipsELFDynamic::getLocalGotNum(const ELFFileFormat& pFormat) const
+{
+  if (!pFormat.hasGOT())
+    return 0;
+
+  return m_pParent.getGOT().getLocalNum();
+}
diff --git a/lib/Target/Mips/MipsELFDynamic.h b/lib/Target/Mips/MipsELFDynamic.h
new file mode 100644
index 0000000..118e4f9
--- /dev/null
+++ b/lib/Target/Mips/MipsELFDynamic.h
@@ -0,0 +1,41 @@
+//===- MipsELFDynamic.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_Mips_ELFDYNAMIC_SECTION_H
+#define MCLD_Mips_ELFDYNAMIC_SECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Target/ELFDynamic.h>
+
+namespace mcld {
+
+class MipsGNULDBackend;
+
+class MipsELFDynamic : public ELFDynamic
+{
+public:
+  MipsELFDynamic(const MipsGNULDBackend& pParent);
+  ~MipsELFDynamic();
+
+private:
+  const MipsGNULDBackend& m_pParent;
+
+private:
+  void reserveTargetEntries(const ELFFileFormat& pFormat);
+  void applyTargetEntries(const ELFFileFormat& pFormat);
+
+  size_t getSymTabNum(const ELFFileFormat& pFormat) const;
+  size_t getGotSym(const ELFFileFormat& pFormat) const;
+  size_t getLocalGotNum(const ELFFileFormat& pFormat) const;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/Mips/MipsELFSectLinker.cpp b/lib/Target/Mips/MipsELFSectLinker.cpp
new file mode 100644
index 0000000..aa41f36
--- /dev/null
+++ b/lib/Target/Mips/MipsELFSectLinker.cpp
@@ -0,0 +1,33 @@
+//===- MipsELFSectLinker.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsELFSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+MipsELFSectLinker::MipsELFSectLinker(SectLinkerOption &pOption,
+                                     TargetLDBackend &pLDBackend)
+  : SectLinker(pOption,
+               pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attibutes
+  info.attrFactory().constraint().enableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().setWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+}
+
+MipsELFSectLinker::~MipsELFSectLinker()
+{
+}
diff --git a/lib/Target/Mips/MipsELFSectLinker.h b/lib/Target/Mips/MipsELFSectLinker.h
new file mode 100644
index 0000000..82bec4c
--- /dev/null
+++ b/lib/Target/Mips/MipsELFSectLinker.h
@@ -0,0 +1,34 @@
+//===- MipsELFSectLinker.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_ELFSECTLINKER_H
+#define MIPS_ELFSECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/CodeGen/SectLinker.h>
+
+namespace mcld
+{
+
+/** \class MipsELFSectLinker
+ *  \brief MipsELFSectLinker sets up the environment for linking.
+ */
+class MipsELFSectLinker : public SectLinker
+{
+public:
+  MipsELFSectLinker(SectLinkerOption &pOption,
+                    mcld::TargetLDBackend &pLDBackend);
+
+  ~MipsELFSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/Mips/MipsGOT.cpp b/lib/Target/Mips/MipsGOT.cpp
new file mode 100644
index 0000000..f9d5bb4
--- /dev/null
+++ b/lib/Target/Mips/MipsGOT.cpp
@@ -0,0 +1,148 @@
+//===- MipsGOT.cpp --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/Support/MemoryRegion.h>
+#include "MipsGOT.h"
+
+namespace {
+  const size_t MipsGOTEntrySize = 4;
+  const size_t MipsGOT0Num = 1;
+}
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// MipsGOT
+MipsGOT::MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+  : GOT(pSection, pSectionData, MipsGOTEntrySize),
+    m_pLocalNum(0)
+{
+  // Create GOT0 entries.
+  for (size_t i = 0; i < MipsGOT0Num; ++i) {
+    GOTEntry* entry =
+      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
+
+    if (NULL == entry)
+      llvm::report_fatal_error("Allocating GOT0 entries failed!");
+
+    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
+  }
+
+  // Skip GOT0 entries.
+  iterator it = m_SectionData.begin();
+  iterator ie = m_SectionData.end();
+
+  for (size_t i = 1; i < MipsGOT0Num; ++i) {
+    if (it == ie)
+      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
+
+    ++it;
+  }
+
+  m_LocalGOTIterator = it;
+  m_GlobalGOTIterator = it;
+  m_pLocalNum = MipsGOT0Num;
+}
+
+MipsGOT::iterator MipsGOT::begin()
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+MipsGOT::iterator MipsGOT::end()
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+MipsGOT::const_iterator MipsGOT::begin() const
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+MipsGOT::const_iterator MipsGOT::end() const
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+uint64_t MipsGOT::emit(MemoryRegion& pRegion)
+{
+  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
+
+  size_t entry_size = getEntrySize();
+
+  uint64_t result = 0;
+  for (iterator it = begin(), ie = end();
+       it != ie; ++it, ++buffer) {
+    GOTEntry* got = &(llvm::cast<GOTEntry>((*it)));
+    *buffer = static_cast<uint32_t>(got->getContent());
+    result += entry_size;
+  }
+  return result;
+}
+
+void MipsGOT::reserveEntry(size_t pNum)
+{
+  for (size_t i = 0; i < pNum; ++i) {
+    GOTEntry* entry =
+      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
+
+    if (NULL == entry)
+      llvm::report_fatal_error("Allocating new GOTEntry failed");
+
+    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
+  }
+}
+
+void MipsGOT::reserveLocalEntry()
+{
+  reserveEntry(1);
+  ++m_pLocalNum;
+
+  // Move global entries iterator forward.
+  // We need to put global GOT entries after all local ones.
+  ++m_GlobalGOTIterator;
+}
+
+void MipsGOT::reserveGlobalEntry()
+{
+  reserveEntry(1);
+}
+
+GOTEntry* MipsGOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
+{
+  GOTEntry*& entry = m_GeneralGOTMap[&pInfo];
+
+  pExist = NULL != entry;
+
+  if (!pExist) {
+    iterator& it = pInfo.isLocal() ? m_LocalGOTIterator : m_GlobalGOTIterator;
+
+    ++it;
+
+    assert(it != m_SectionData.getFragmentList().end() &&
+           "The number of GOT Entries and ResolveInfo doesn't match");
+
+    entry = llvm::cast<GOTEntry>(&(*it));
+  }
+
+  return entry;
+}
+
+size_t MipsGOT::getTotalNum() const
+{
+  return m_SectionData.getFragmentList().size();
+}
+
+size_t MipsGOT::getLocalNum() const
+{
+  return m_pLocalNum;
+}
+
diff --git a/lib/Target/Mips/MipsGOT.h b/lib/Target/Mips/MipsGOT.h
new file mode 100644
index 0000000..dccc7ac
--- /dev/null
+++ b/lib/Target/Mips/MipsGOT.h
@@ -0,0 +1,67 @@
+//===- MipsGOT.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MIPS_GOT_H
+#define MCLD_MIPS_GOT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Target/GOT.h>
+
+namespace mcld
+{
+class LDSection;
+class MemoryRegion;
+
+/** \class MipsGOT
+ *  \brief Mips Global Offset Table.
+ */
+class MipsGOT : public GOT
+{
+private:
+  typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+public:
+  MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+
+  iterator begin();
+  iterator end();
+
+  const_iterator begin() const;
+  const_iterator end() const;
+
+  uint64_t emit(MemoryRegion& pRegion);
+
+  void reserveLocalEntry();
+  void reserveGlobalEntry();
+
+  GOTEntry* getEntry(const ResolveInfo& pInfo, bool& pExist);
+
+  size_t getTotalNum() const;
+  size_t getLocalNum() const;
+
+private:
+  SymbolIndexMapType m_GeneralGOTMap;
+  iterator m_LocalGOTIterator;  // last local GOT entries
+  iterator m_GlobalGOTIterator; // last global GOT entries
+  size_t m_pLocalNum;
+
+private:
+  // Use reserveLocalEntry()/reserveGlobalEntry() instead of this routine.
+  void reserveEntry(size_t pNum = 1);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/Mips/MipsLDBackend.cpp b/lib/Target/Mips/MipsLDBackend.cpp
new file mode 100644
index 0000000..c7a6b23
--- /dev/null
+++ b/lib/Target/Mips/MipsLDBackend.cpp
@@ -0,0 +1,894 @@
+//===- MipsLDBackend.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/Support/ELF.h>
+
+#include <mcld/LD/SectionMap.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Support/TargetRegistry.h>
+#include <mcld/Target/OutputRelocSection.h>
+
+#include "Mips.h"
+#include "MipsELFDynamic.h"
+#include "MipsLDBackend.h"
+#include "MipsRelocationFactory.h"
+
+enum {
+  // The original o32 abi.
+  E_MIPS_ABI_O32    = 0x00001000,
+  // O32 extended to work on 64 bit architectures.
+  E_MIPS_ABI_O64    = 0x00002000,
+  // EABI in 32 bit mode.
+  E_MIPS_ABI_EABI32 = 0x00003000,
+  // EABI in 64 bit mode.
+  E_MIPS_ABI_EABI64 = 0x00004000
+};
+
+namespace mcld {
+
+MipsGNULDBackend::MipsGNULDBackend()
+  : m_pRelocFactory(NULL),
+    m_pGOT(NULL),
+    m_pRelDyn(NULL),
+    m_pDynamic(NULL),
+    m_pGOTSymbol(NULL),
+    m_pGpDispSymbol(NULL)
+{
+}
+
+MipsGNULDBackend::~MipsGNULDBackend()
+{
+  if (NULL != m_pRelocFactory)
+    delete m_pRelocFactory;
+  if (NULL != m_pGOT)
+    delete m_pGOT;
+  if (NULL != m_pRelDyn)
+    delete m_pRelDyn;
+  if (NULL != m_pDynamic)
+    delete m_pDynamic;
+}
+
+bool MipsGNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
+{
+  // Nothing to do because we do not support
+  // any MIPS specific sections now.
+  return true;
+}
+
+void MipsGNULDBackend::initTargetSections(MCLinker& pLinker)
+{
+  // Nothing to do because we do not support
+  // any MIPS specific sections now.
+}
+
+void MipsGNULDBackend::initTargetSymbols(MCLinker& pLinker)
+{
+  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
+  // same name in input
+  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
+                   "_GLOBAL_OFFSET_TABLE_",
+                   false,
+                   ResolveInfo::Object,
+                   ResolveInfo::Define,
+                   ResolveInfo::Local,
+                   0x0,  // size
+                   0x0,  // value
+                   NULL, // FragRef
+                   ResolveInfo::Hidden);
+
+  m_pGpDispSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
+                   "_gp_disp",
+                   false,
+                   ResolveInfo::Section,
+                   ResolveInfo::Define,
+                   ResolveInfo::Absolute,
+                   0x0,  // size
+                   0x0,  // value
+                   NULL, // FragRef
+                   ResolveInfo::Default);
+
+  if (NULL != m_pGpDispSymbol) {
+    m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
+  }
+}
+
+bool MipsGNULDBackend::initRelocFactory(const MCLinker& pLinker)
+{
+  if (NULL == m_pRelocFactory) {
+    m_pRelocFactory = new MipsRelocationFactory(1024, *this);
+    m_pRelocFactory->setLayout(pLinker.getLayout());
+  }
+  return true;
+}
+
+RelocationFactory* MipsGNULDBackend::getRelocFactory()
+{
+  assert(NULL != m_pRelocFactory);
+  return m_pRelocFactory;
+}
+
+void MipsGNULDBackend::scanRelocation(Relocation& pReloc,
+                                      const LDSymbol& pInputSym,
+                                      MCLinker& pLinker,
+                                      const MCLDInfo& pLDInfo,
+                                      const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
+
+  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies
+  // that a .got section is needed.
+  if (NULL == m_pGOT && NULL != m_pGOTSymbol) {
+    if (rsym == m_pGOTSymbol->resolveInfo()) {
+      createGOT(pLinker, pOutput);
+    }
+  }
+
+  if (rsym->isLocal())
+    scanLocalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
+  else
+    scanGlobalReloc(pReloc, pInputSym, pLinker, pLDInfo, pOutput);
+}
+
+uint32_t MipsGNULDBackend::machine() const
+{
+  return llvm::ELF::EM_MIPS;
+}
+
+uint8_t MipsGNULDBackend::OSABI() const
+{
+  return llvm::ELF::ELFOSABI_NONE;
+}
+
+uint8_t MipsGNULDBackend::ABIVersion() const
+{
+  return 0;
+}
+
+uint64_t MipsGNULDBackend::flags() const
+{
+  // TODO: (simon) The correct flag's set depend on command line
+  // arguments and flags from input .o files.
+  return llvm::ELF::EF_MIPS_ARCH_32R2 |
+         llvm::ELF::EF_MIPS_NOREORDER |
+         llvm::ELF::EF_MIPS_PIC |
+         llvm::ELF::EF_MIPS_CPIC |
+         E_MIPS_ABI_O32;
+}
+
+bool MipsGNULDBackend::isLittleEndian() const
+{
+  // Now we support little endian (mipsel) target only.
+  return true;
+}
+
+unsigned int MipsGNULDBackend::bitclass() const
+{
+  return 32;
+}
+
+void MipsGNULDBackend::doPreLayout(const Output& pOutput,
+                                   const MCLDInfo& pInfo,
+                                   MCLinker& pLinker)
+{
+  // when building shared object, the .got section is must.
+  if (pOutput.type() == Output::DynObj && NULL == m_pGOT) {
+      createGOT(pLinker, pOutput);
+  }
+}
+
+void MipsGNULDBackend::doPostLayout(const Output& pOutput,
+                                    const MCLDInfo& pInfo,
+                                    MCLinker& pLinker)
+{
+  // emit program headers
+  if (pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
+    emitProgramHdrs(pLinker.getLDInfo().output());
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+MipsELFDynamic& MipsGNULDBackend::dynamic()
+{
+  if (NULL == m_pDynamic)
+    m_pDynamic = new MipsELFDynamic(*this);
+
+  return *m_pDynamic;
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+const MipsELFDynamic& MipsGNULDBackend::dynamic() const
+{
+  assert( NULL != m_pDynamic);
+  return *m_pDynamic;
+}
+
+uint64_t MipsGNULDBackend::emitSectionData(const Output& pOutput,
+                                           const LDSection& pSection,
+                                           const MCLDInfo& pInfo,
+                                           MemoryRegion& pRegion) const
+{
+  assert(pRegion.size() && "Size of MemoryRegion is zero!");
+
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  if (&pSection == &(file_format->getGOT())) {
+    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
+    uint64_t result = m_pGOT->emit(pRegion);
+    return result;
+  }
+
+  llvm::report_fatal_error(llvm::Twine("Unable to emit section `") +
+                           pSection.name() +
+                           llvm::Twine("'.\n"));
+  return 0;
+}
+/// isGOTSymbol - return true if the symbol is the GOT entry.
+bool MipsGNULDBackend::isGOTSymbol(const LDSymbol& pSymbol) const
+{
+  return std::find(m_LocalGOTSyms.begin(),
+                   m_LocalGOTSyms.end(), &pSymbol) != m_LocalGOTSyms.end() ||
+         std::find(m_GlobalGOTSyms.begin(),
+                   m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
+}
+
+/// emitDynamicSymbol - emit dynamic symbol.
+void MipsGNULDBackend::emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
+                                         Output& pOutput,
+                                         LDSymbol& pSymbol,
+                                         const Layout& pLayout,
+                                         char* strtab,
+                                         size_t strtabsize,
+                                         size_t symtabIdx)
+{
+  // maintain output's symbol and index map
+  bool sym_exist = false;
+  HashTableType::entry_type* entry = 0;
+  entry = m_pSymIndexMap->insert(&pSymbol, sym_exist);
+  entry->setValue(symtabIdx);
+
+  // FIXME: check the endian between host and target
+  // write out symbol
+  sym32.st_name  = strtabsize;
+  sym32.st_value = pSymbol.value();
+  sym32.st_size  = getSymbolSize(pSymbol);
+  sym32.st_info  = getSymbolInfo(pSymbol);
+  sym32.st_other = pSymbol.visibility();
+  sym32.st_shndx = getSymbolShndx(pSymbol, pLayout);
+  // write out string
+  strcpy((strtab + strtabsize), pSymbol.name());
+}
+
+/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
+///
+/// the size of these tables should be computed before layout
+/// layout should computes the start offset of these tables
+void MipsGNULDBackend::emitDynNamePools(Output& pOutput,
+                                        SymbolCategory& pSymbols,
+                                        const Layout& pLayout,
+                                        const MCLDInfo& pLDInfo)
+{
+  assert(pOutput.hasMemArea());
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& symtab_sect = file_format->getDynSymTab();
+  LDSection& strtab_sect = file_format->getDynStrTab();
+  LDSection& hash_sect   = file_format->getHashTab();
+  LDSection& dyn_sect    = file_format->getDynamic();
+
+  MemoryRegion* symtab_region = pOutput.memArea()->request(symtab_sect.offset(),
+                                                           symtab_sect.size());
+  MemoryRegion* strtab_region = pOutput.memArea()->request(strtab_sect.offset(),
+                                                           strtab_sect.size());
+  MemoryRegion* hash_region = pOutput.memArea()->request(hash_sect.offset(),
+                                                         hash_sect.size());
+  MemoryRegion* dyn_region = pOutput.memArea()->request(dyn_sect.offset(),
+                                                        dyn_sect.size());
+  // set up symtab_region
+  llvm::ELF::Elf32_Sym* symtab32 = NULL;
+  symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
+
+  symtab32[0].st_name  = 0;
+  symtab32[0].st_value = 0;
+  symtab32[0].st_size  = 0;
+  symtab32[0].st_info  = 0;
+  symtab32[0].st_other = 0;
+  symtab32[0].st_shndx = 0;
+
+  // set up strtab_region
+  char* strtab = (char*)strtab_region->start();
+  strtab[0] = '\0';
+
+  bool sym_exist = false;
+  HashTableType::entry_type* entry = 0;
+
+  // add index 0 symbol into SymIndexMap
+  entry = m_pSymIndexMap->insert(NULL, sym_exist);
+  entry->setValue(0);
+
+  size_t symtabIdx = 1;
+  size_t strtabsize = 1;
+
+  // emit of .dynsym, and .dynstr except GOT entries
+  for (SymbolCategory::iterator symbol = pSymbols.begin(),
+       sym_end = pSymbols.end(); symbol != sym_end; ++symbol) {
+    if (!isDynamicSymbol(**symbol, pOutput))
+      continue;
+
+    if (isGOTSymbol(**symbol))
+      continue;
+
+    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
+                      strtabsize, symtabIdx);
+
+    // sum up counters
+    ++symtabIdx;
+    strtabsize += (*symbol)->nameSize() + 1;
+  }
+
+  // emit global GOT
+  for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
+       symbol_end = m_GlobalGOTSyms.end();
+       symbol != symbol_end; ++symbol) {
+
+    emitDynamicSymbol(symtab32[symtabIdx], pOutput, **symbol, pLayout, strtab,
+                      strtabsize, symtabIdx);
+
+    // sum up counters
+    ++symtabIdx;
+    strtabsize += (*symbol)->nameSize() + 1;
+  }
+
+  // emit DT_NEED
+  // add DT_NEED strings into .dynstr
+  // Rules:
+  //   1. ignore --no-add-needed
+  //   2. force count in --no-as-needed
+  //   3. judge --as-needed
+  ELFDynamic::iterator dt_need = dynamic().needBegin();
+  InputTree::const_bfs_iterator input, inputEnd = pLDInfo.inputs().bfs_end();
+  for (input = pLDInfo.inputs().bfs_begin(); input != inputEnd; ++input) {
+    if (Input::DynObj == (*input)->type()) {
+      // --add-needed
+      if ((*input)->attribute()->isAddNeeded()) {
+        // --no-as-needed
+        if (!(*input)->attribute()->isAsNeeded()) {
+          strcpy((strtab + strtabsize), (*input)->name().c_str());
+          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
+          strtabsize += (*input)->name().size() + 1;
+          ++dt_need;
+        }
+        // --as-needed
+        else if ((*input)->isNeeded()) {
+          strcpy((strtab + strtabsize), (*input)->name().c_str());
+          (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
+          strtabsize += (*input)->name().size() + 1;
+          ++dt_need;
+        }
+      }
+    }
+  } // for
+
+  // emit soname
+  // initialize value of ELF .dynamic section
+  dynamic().applySoname(strtabsize);
+  dynamic().applyEntries(pLDInfo, *file_format);
+  dynamic().emit(dyn_sect, *dyn_region);
+
+  strcpy((strtab + strtabsize), pOutput.name().c_str());
+  strtabsize += pOutput.name().size() + 1;
+
+  // emit hash table
+  // FIXME: this verion only emit SVR4 hash section.
+  //        Please add GNU new hash section
+
+  // both 32 and 64 bits hash table use 32-bit entry
+  // set up hash_region
+  uint32_t* word_array = (uint32_t*)hash_region->start();
+  uint32_t& nbucket = word_array[0];
+  uint32_t& nchain  = word_array[1];
+
+  nbucket = getHashBucketCount(symtabIdx, false);
+  nchain  = symtabIdx;
+
+  uint32_t* bucket = (word_array + 2);
+  uint32_t* chain  = (bucket + nbucket);
+
+  // initialize bucket
+  bzero((void*)bucket, nbucket);
+
+  StringHash<ELF> hash_func;
+
+  for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
+    llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
+    size_t bucket_pos = hash_func(name) % nbucket;
+    chain[sym_idx] = bucket[bucket_pos];
+    bucket[bucket_pos] = sym_idx;
+  }
+
+}
+
+MipsGOT& MipsGNULDBackend::getGOT()
+{
+  assert(NULL != m_pGOT);
+  return *m_pGOT;
+}
+
+const MipsGOT& MipsGNULDBackend::getGOT() const
+{
+  assert(NULL != m_pGOT);
+  return *m_pGOT;
+}
+
+OutputRelocSection& MipsGNULDBackend::getRelDyn()
+{
+  assert(NULL != m_pRelDyn);
+  return *m_pRelDyn;
+}
+
+const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
+{
+  assert(NULL != m_pRelDyn);
+  return *m_pRelDyn;
+}
+
+unsigned int
+MipsGNULDBackend::getTargetSectionOrder(const Output& pOutput,
+                                        const LDSection& pSectHdr) const
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  if (&pSectHdr == &file_format->getGOT())
+    return SHO_DATA;
+
+  return SHO_UNDEFINED;
+}
+
+/// finalizeSymbol - finalize the symbol value
+/// If the symbol's reserved field is not zero, MCLinker will call back this
+/// function to ask the final value of the symbol
+bool MipsGNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
+{
+  if (&pSymbol == m_pGpDispSymbol) {
+    m_pGpDispSymbol->setValue(m_pGOT->getSection().addr() + 0x7FF0);
+    return true;
+  }
+  return false;
+}
+
+/// allocateCommonSymbols - allocate common symbols in the corresponding
+/// sections.
+/// @refer Google gold linker: common.cc: 214
+/// FIXME: Mips needs to allocate small common symbol
+bool
+MipsGNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
+{
+  // SymbolCategory contains all symbols that must emit to the output files.
+  // We are not like Google gold linker, we don't remember symbols before symbol
+  // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
+  // don't need to care about some symbols may be changed its category due to symbol
+  // resolution.
+  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
+
+  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
+    return true;
+
+  // addralign := max value of all common symbols
+  uint64_t addralign = 0x0;
+
+  // Due to the visibility, some common symbols may be forcefully local.
+  SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      if ((*com_sym)->value() > addralign)
+        addralign = (*com_sym)->value();
+    }
+  }
+
+  // global common symbols.
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    if ((*com_sym)->value() > addralign)
+      addralign = (*com_sym)->value();
+  }
+
+  // FIXME: If the order of common symbols is defined, then sort common symbols
+  // com_sym = symbol_list.commonBegin();
+  // std::sort(com_sym, com_end, some kind of order);
+
+  // get or create corresponding BSS LDSection
+  LDSection* bss_sect_hdr = NULL;
+  if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
+                                   ".tbss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+  else {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+
+  // get or create corresponding BSS MCSectionData
+  assert(NULL != bss_sect_hdr);
+  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
+
+  // allocate all common symbols
+  uint64_t offset = bss_sect_hdr->size();
+
+  // allocate all local common symbols
+  com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      alignAddress(offset, (*com_sym)->value());
+      // We have to reset the description of the symbol here. When doing
+      // incremental linking, the output relocatable object may have common
+      // symbols. Therefore, we can not treat common symbols as normal symbols
+      // when emitting the regular name pools. We must change the symbols'
+      // description here.
+      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
+      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+      offset += (*com_sym)->size();
+    }
+  }
+
+  // allocate all global common symbols
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    alignAddress(offset, (*com_sym)->value());
+
+    // We have to reset the description of the symbol here. When doing
+    // incremental linking, the output relocatable object may have common
+    // symbols. Therefore, we can not treat common symbols as normal symbols
+    // when emitting the regular name pools. We must change the symbols'
+    // description here.
+    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size(), &bss_section);
+    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+    offset += (*com_sym)->size();
+  }
+
+  bss_sect_hdr->setSize(offset);
+  symbol_list.changeCommonsToGlobal();
+  return true;
+}
+
+void MipsGNULDBackend::updateAddend(Relocation& pReloc,
+                                   const LDSymbol& pInputSym,
+                                   const Layout& pLayout) const
+{
+  // Update value keep in addend if we meet a section symbol
+  if(pReloc.symInfo()->type() == ResolveInfo::Section) {
+    pReloc.setAddend(pLayout.getOutputOffset(
+                     *pInputSym.fragRef()) + pReloc.addend());
+  }
+}
+
+void MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
+                                      const LDSymbol& pInputSym,
+                                      MCLinker& pLinker,
+                                      const MCLDInfo& pLDInfo,
+                                      const Output& pOutput)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  updateAddend(pReloc, pInputSym, pLinker.getLayout());
+
+  switch (pReloc.type()){
+    case llvm::ELF::R_MIPS_NONE:
+    case llvm::ELF::R_MIPS_16:
+      break;
+    case llvm::ELF::R_MIPS_32:
+      if (Output::DynObj == pOutput.type()) {
+        // TODO: (simon) The gold linker does not create an entry in .rel.dyn
+        // section if the symbol section flags contains SHF_EXECINSTR.
+        // 1. Find the reason of this condition.
+        // 2. Check this condition here.
+        if (NULL == m_pRelDyn)
+          createRelDyn(pLinker, pOutput);
+
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        rsym->setReserved(rsym->reserved() | ReserveRel);
+      }
+      break;
+    case llvm::ELF::R_MIPS_REL32:
+    case llvm::ELF::R_MIPS_26:
+    case llvm::ELF::R_MIPS_HI16:
+    case llvm::ELF::R_MIPS_LO16:
+    case llvm::ELF::R_MIPS_PC16:
+    case llvm::ELF::R_MIPS_SHIFT5:
+    case llvm::ELF::R_MIPS_SHIFT6:
+    case llvm::ELF::R_MIPS_64:
+    case llvm::ELF::R_MIPS_GOT_PAGE:
+    case llvm::ELF::R_MIPS_GOT_OFST:
+    case llvm::ELF::R_MIPS_SUB:
+    case llvm::ELF::R_MIPS_INSERT_A:
+    case llvm::ELF::R_MIPS_INSERT_B:
+    case llvm::ELF::R_MIPS_DELETE:
+    case llvm::ELF::R_MIPS_HIGHER:
+    case llvm::ELF::R_MIPS_HIGHEST:
+    case llvm::ELF::R_MIPS_SCN_DISP:
+    case llvm::ELF::R_MIPS_REL16:
+    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
+    case llvm::ELF::R_MIPS_PJUMP:
+    case llvm::ELF::R_MIPS_RELGOT:
+    case llvm::ELF::R_MIPS_JALR:
+    case llvm::ELF::R_MIPS_GLOB_DAT:
+    case llvm::ELF::R_MIPS_COPY:
+    case llvm::ELF::R_MIPS_JUMP_SLOT:
+      break;
+    case llvm::ELF::R_MIPS_GOT16:
+    case llvm::ELF::R_MIPS_CALL16:
+      if (NULL == m_pGOT)
+        createGOT(pLinker, pOutput);
+
+      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
+        m_pGOT->reserveLocalEntry();
+        rsym->setReserved(rsym->reserved() | ReserveGot);
+        m_LocalGOTSyms.push_back(rsym->outSymbol());
+      }
+      break;
+    case llvm::ELF::R_MIPS_GPREL32:
+    case llvm::ELF::R_MIPS_GPREL16:
+    case llvm::ELF::R_MIPS_LITERAL:
+      break;
+    case llvm::ELF::R_MIPS_GOT_DISP:
+    case llvm::ELF::R_MIPS_GOT_HI16:
+    case llvm::ELF::R_MIPS_CALL_HI16:
+    case llvm::ELF::R_MIPS_GOT_LO16:
+    case llvm::ELF::R_MIPS_CALL_LO16:
+      break;
+    case llvm::ELF::R_MIPS_TLS_DTPMOD32:
+    case llvm::ELF::R_MIPS_TLS_DTPREL32:
+    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
+    case llvm::ELF::R_MIPS_TLS_DTPREL64:
+    case llvm::ELF::R_MIPS_TLS_GD:
+    case llvm::ELF::R_MIPS_TLS_LDM:
+    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
+    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
+    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
+    case llvm::ELF::R_MIPS_TLS_TPREL32:
+    case llvm::ELF::R_MIPS_TLS_TPREL64:
+    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
+    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
+      break;
+    default:
+      llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
+                               llvm::Twine(pReloc.type()) +
+                               llvm::Twine("for the local symbol `") +
+                               pReloc.symInfo()->name() +
+                               llvm::Twine("'."));
+  }
+}
+
+void MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
+                                       const LDSymbol& pInputSym,
+                                       MCLinker& pLinker,
+                                       const MCLDInfo& pLDInfo,
+                                       const Output& pOutput)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  switch (pReloc.type()){
+    case llvm::ELF::R_MIPS_NONE:
+    case llvm::ELF::R_MIPS_INSERT_A:
+    case llvm::ELF::R_MIPS_INSERT_B:
+    case llvm::ELF::R_MIPS_DELETE:
+    case llvm::ELF::R_MIPS_TLS_DTPMOD64:
+    case llvm::ELF::R_MIPS_TLS_DTPREL64:
+    case llvm::ELF::R_MIPS_REL16:
+    case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
+    case llvm::ELF::R_MIPS_PJUMP:
+    case llvm::ELF::R_MIPS_RELGOT:
+    case llvm::ELF::R_MIPS_TLS_TPREL64:
+      break;
+    case llvm::ELF::R_MIPS_32:
+    case llvm::ELF::R_MIPS_64:
+    case llvm::ELF::R_MIPS_HI16:
+    case llvm::ELF::R_MIPS_LO16:
+      if (isSymbolNeedsDynRel(*rsym, pOutput)) {
+        if (NULL == m_pRelDyn)
+          createRelDyn(pLinker, pOutput);
+
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        rsym->setReserved(rsym->reserved() | ReserveRel);
+      }
+      break;
+    case llvm::ELF::R_MIPS_GOT16:
+    case llvm::ELF::R_MIPS_CALL16:
+    case llvm::ELF::R_MIPS_GOT_DISP:
+    case llvm::ELF::R_MIPS_GOT_HI16:
+    case llvm::ELF::R_MIPS_CALL_HI16:
+    case llvm::ELF::R_MIPS_GOT_LO16:
+    case llvm::ELF::R_MIPS_CALL_LO16:
+    case llvm::ELF::R_MIPS_GOT_PAGE:
+    case llvm::ELF::R_MIPS_GOT_OFST:
+      if (NULL == m_pGOT)
+        createGOT(pLinker, pOutput);
+
+      if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
+        m_pGOT->reserveGlobalEntry();
+        rsym->setReserved(rsym->reserved() | ReserveGot);
+        m_GlobalGOTSyms.push_back(rsym->outSymbol());
+      }
+      break;
+    case llvm::ELF::R_MIPS_LITERAL:
+    case llvm::ELF::R_MIPS_GPREL32:
+      llvm::report_fatal_error(llvm::Twine("Relocation ") +
+                               llvm::Twine(pReloc.type()) +
+                               llvm::Twine(" is not defined for the "
+                                           "global symbol `") +
+                               pReloc.symInfo()->name() +
+                               llvm::Twine("'."));
+      break;
+    case llvm::ELF::R_MIPS_GPREL16:
+      break;
+    case llvm::ELF::R_MIPS_26:
+    case llvm::ELF::R_MIPS_PC16:
+      break;
+    case llvm::ELF::R_MIPS_16:
+    case llvm::ELF::R_MIPS_SHIFT5:
+    case llvm::ELF::R_MIPS_SHIFT6:
+    case llvm::ELF::R_MIPS_SUB:
+    case llvm::ELF::R_MIPS_HIGHER:
+    case llvm::ELF::R_MIPS_HIGHEST:
+    case llvm::ELF::R_MIPS_SCN_DISP:
+      break;
+    case llvm::ELF::R_MIPS_TLS_DTPREL32:
+    case llvm::ELF::R_MIPS_TLS_GD:
+    case llvm::ELF::R_MIPS_TLS_LDM:
+    case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
+    case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
+    case llvm::ELF::R_MIPS_TLS_GOTTPREL:
+    case llvm::ELF::R_MIPS_TLS_TPREL32:
+    case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
+    case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
+      break;
+    case llvm::ELF::R_MIPS_REL32:
+      break;
+    case llvm::ELF::R_MIPS_JALR:
+      break;
+    case llvm::ELF::R_MIPS_COPY:
+    case llvm::ELF::R_MIPS_GLOB_DAT:
+    case llvm::ELF::R_MIPS_JUMP_SLOT:
+      llvm::report_fatal_error(llvm::Twine("Relocation ") +
+                               llvm::Twine(pReloc.type()) +
+                               llvm::Twine("for the global symbol `") +
+                               pReloc.symInfo()->name() +
+                               llvm::Twine("' should only be seen "
+                                           "by the dynamic linker"));
+      break;
+    default:
+      llvm::report_fatal_error(llvm::Twine("Unknown relocation ") +
+                               llvm::Twine(pReloc.type()) +
+                               llvm::Twine("for the global symbol `") +
+                               pReloc.symInfo()->name() +
+                               llvm::Twine("'."));
+  }
+}
+
+bool MipsGNULDBackend::isSymbolNeedsPLT(ResolveInfo& pSym,
+                                        const Output& pOutput) const
+{
+  return (Output::DynObj == pOutput.type() &&
+         ResolveInfo::Function == pSym.type() &&
+         (pSym.isDyn() || pSym.isUndef()));
+}
+
+bool MipsGNULDBackend::isSymbolNeedsDynRel(ResolveInfo& pSym,
+                                           const Output& pOutput) const
+{
+  if(pSym.isUndef() && Output::Exec == pOutput.type())
+    return false;
+  if(pSym.isAbsolute())
+    return false;
+  if(Output::DynObj == pOutput.type())
+    return true;
+  if(pSym.isDyn() || pSym.isUndef())
+    return true;
+
+  return false;
+}
+
+void MipsGNULDBackend::createGOT(MCLinker& pLinker, const Output& pOutput)
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& got = file_format->getGOT();
+  m_pGOT = new MipsGOT(got, pLinker.getOrCreateSectData(got));
+
+  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
+  if( m_pGOTSymbol != NULL ) {
+    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+  else {
+    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+}
+
+void MipsGNULDBackend::createRelDyn(MCLinker& pLinker, const Output& pOutput)
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  // get .rel.dyn LDSection and create MCSectionData
+  LDSection& reldyn = file_format->getRelDyn();
+  // create MCSectionData and ARMRelDynSection
+  m_pRelDyn = new OutputRelocSection(reldyn,
+                                     pLinker.getOrCreateSectData(reldyn),
+                                     8);
+}
+
+ELFFileFormat* MipsGNULDBackend::getOutputFormat(const Output& pOutput) const
+{
+  switch (pOutput.type()) {
+    case Output::DynObj:
+      return getDynObjFileFormat();
+    case Output::Exec:
+      return getExecFileFormat();
+    case Output::Object:
+      return NULL;
+    default:
+      llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
+                               llvm::Twine(pOutput.type()));
+      return NULL;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
+///
+static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
+                                            const std::string& pTriple)
+{
+  llvm::Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker is not supported yet");
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker is not supported yet");
+  }
+  return new MipsGNULDBackend();
+}
+
+} // namespace of mcld
+
+//=============================
+// Force static initialization.
+extern "C" void LLVMInitializeMipsLDBackend() {
+  // Register the linker backend
+  mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
+                                                mcld::createMipsLDBackend);
+}
diff --git a/lib/Target/Mips/MipsLDBackend.h b/lib/Target/Mips/MipsLDBackend.h
new file mode 100644
index 0000000..cd9e3cd
--- /dev/null
+++ b/lib/Target/Mips/MipsLDBackend.h
@@ -0,0 +1,200 @@
+//===- MipsLDBackend.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_LDBACKEND_H
+#define MIPS_LDBACKEND_H
+#include "mcld/Target/GNULDBackend.h"
+#include "MipsELFDynamic.h"
+#include "MipsGOT.h"
+
+namespace mcld {
+
+class MCLinker;
+class OutputRelocSection;
+class SectionMap;
+
+//===----------------------------------------------------------------------===//
+/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
+///
+class MipsGNULDBackend : public GNULDBackend
+{
+public:
+  enum ReservedEntryType {
+    None          = 0,  // no reserved entry
+    ReserveRel    = 1,  // reserve a dynamic relocation entry
+    ReserveGot    = 2,  // reserve a GOT entry
+    ReserveGpDisp = 8   // reserve _gp_disp symbol
+  };
+
+public:
+  MipsGNULDBackend();
+  ~MipsGNULDBackend();
+
+public:
+  /// initTargetSectionMap - initialize target dependent section mapping.
+  bool initTargetSectionMap(SectionMap& pSectionMap);
+
+  /// initTargetSections - initialize target dependent sections in output
+  void initTargetSections(MCLinker& pLinker);
+
+  /// initTargetSymbols - initialize target dependent symbols in output.
+  void initTargetSymbols(MCLinker& pLinker);
+
+  /// initRelocFactory - create and initialize RelocationFactory.
+  bool initRelocFactory(const MCLinker& pLinker);
+
+  /// getRelocFactory - return relocation factory.
+  RelocationFactory* getRelocFactory();
+
+  /// scanRelocation - determine the empty entries are needed or not and
+  /// create the empty entries if needed.
+  /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
+  void scanRelocation(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  uint32_t machine() const;
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  uint8_t OSABI() const;
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  uint8_t ABIVersion() const;
+
+  /// flags - the value of ElfXX_Ehdr::e_flags
+  uint64_t flags() const;
+
+  bool isLittleEndian() const;
+
+  unsigned int bitclass() const;
+
+  /// preLayout - Backend can do any needed modification before layout
+  void doPreLayout(const Output& pOutput,
+                   const MCLDInfo& pInfo,
+                   MCLinker& pLinker);
+
+  /// postLayout -Backend can do any needed modification after layout
+  void doPostLayout(const Output& pOutput,
+                    const MCLDInfo& pInfo,
+                    MCLinker& pLinker);
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  MipsELFDynamic& dynamic();
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  const MipsELFDynamic& dynamic() const;
+
+  /// emitSectionData - write out the section data into the memory region.
+  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
+  /// call back target backend to emit the data.
+  ///
+  /// Backends handle the target-special tables (plt, gp,...) by themselves.
+  /// Backend can put the data of the tables in MCSectionData directly
+  ///  - LDSection.getSectionData can get the section data.
+  /// Or, backend can put the data into special data structure
+  ///  - backend can maintain its own map<LDSection, table> to get the table
+  /// from given LDSection.
+  ///
+  /// @param pOutput - the output file
+  /// @param pSection - the given LDSection
+  /// @param pInfo - all options in the command line.
+  /// @param pRegion - the region to write out data
+  /// @return the size of the table in the file.
+  uint64_t emitSectionData(const Output& pOutput,
+                           const LDSection& pSection,
+                           const MCLDInfo& pInfo,
+                           MemoryRegion& pRegion) const;
+
+  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
+  virtual void emitDynNamePools(Output& pOutput,
+                                SymbolCategory& pSymbols,
+                                const Layout& pLayout,
+                                const MCLDInfo& pLDInfo);
+
+  MipsGOT& getGOT();
+  const MipsGOT& getGOT() const;
+
+  OutputRelocSection& getRelDyn();
+  const OutputRelocSection& getRelDyn() const;
+
+  /// getTargetSectionOrder - compute the layout order of ARM target sections
+  unsigned int getTargetSectionOrder(const Output& pOutput,
+                                     const LDSection& pSectHdr) const;
+
+  /// finalizeSymbol - finalize the symbol value
+  /// If the symbol's reserved field is not zero, MCLinker will call back this
+  /// function to ask the final value of the symbol
+  bool finalizeSymbol(LDSymbol& pSymbol) const;
+
+  /// allocateCommonSymbols - allocate common symbols in the corresponding
+  /// sections.
+  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
+
+private:
+  void scanLocalReloc(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  void scanGlobalReloc(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  bool isSymbolNeedsPLT(ResolveInfo& pSym, const Output& pOutput) const;
+  bool isSymbolNeedsDynRel(ResolveInfo& pSym, const Output& pOutput) const;
+
+  void createGOT(MCLinker& pLinker, const Output& pOutput);
+  void createRelDyn(MCLinker& pLinker, const Output& pOutput);
+
+  ELFFileFormat* getOutputFormat(const Output& pOutput) const;
+
+  /// updateAddend - update addend value of the relocation if the
+  /// the target symbol is a section symbol. Addend is the offset
+  /// in the section. This value should be updated after section
+  /// merged.
+  void updateAddend(Relocation& pReloc,
+                    const LDSymbol& pInputSym,
+                    const Layout& pLayout) const;
+
+private:
+  RelocationFactory* m_pRelocFactory;
+
+  MipsGOT* m_pGOT;                      // .got
+  OutputRelocSection* m_pRelDyn;        // .rel.dyn
+
+  MipsELFDynamic* m_pDynamic;
+  LDSymbol* m_pGOTSymbol;
+  LDSymbol* m_pGpDispSymbol;
+
+  std::vector<LDSymbol*> m_LocalGOTSyms;
+  std::vector<LDSymbol*> m_GlobalGOTSyms;
+
+private:
+  /// isGOTSymbol - return true if the symbol is the GOT entry.
+  bool isGOTSymbol(const LDSymbol& pSymbol) const;
+  /// emitDynamicSymbol - emit dynamic symbol.
+  void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
+                         Output& pOutput, 
+                         LDSymbol& pSymbol,
+                         const Layout& pLayout,
+                         char* strtab,
+                         size_t strtabsize,
+                         size_t symtabIdx);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/Mips/MipsRelocationFactory.cpp b/lib/Target/Mips/MipsRelocationFactory.cpp
new file mode 100644
index 0000000..e3a7793
--- /dev/null
+++ b/lib/Target/Mips/MipsRelocationFactory.cpp
@@ -0,0 +1,363 @@
+//===- MipsRelocationFactory.cpp  -----------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/Target/OutputRelocSection.h>
+
+#include "MipsRelocationFactory.h"
+#include "MipsRelocationFunctions.h"
+
+using namespace mcld;
+
+DECL_MIPS_APPLY_RELOC_FUNCS
+
+//==========================
+// MipsRelocationFactory
+MipsRelocationFactory::MipsRelocationFactory(size_t pNum,
+                                             MipsGNULDBackend& pParent)
+  : RelocationFactory(pNum),
+    m_Target(pParent),
+    m_AHL(0)
+{
+}
+
+void MipsRelocationFactory::applyRelocation(Relocation& pRelocation,
+                                            const MCLDInfo& pLDInfo)
+
+{
+  /// the prototype of applying function
+  typedef Result (*ApplyFunctionType)(Relocation&,
+                                      const MCLDInfo& pLDInfo,
+                                      MipsRelocationFactory&);
+
+  // the table entry of applying functions
+  struct ApplyFunctionTriple {
+    ApplyFunctionType func;
+    unsigned int type;
+    const char* name;
+  };
+
+  // declare the table of applying functions
+  static ApplyFunctionTriple apply_functions[] = {
+    DECL_MIPS_APPLY_RELOC_FUNC_PTRS
+  };
+
+  Relocation::Type type = pRelocation.type();
+
+  if (type >= sizeof(apply_functions) / sizeof(apply_functions[0])) {
+    llvm::report_fatal_error(llvm::Twine("Unknown relocation type. "
+                                         "To symbol `") +
+                             pRelocation.symInfo()->name() +
+                             llvm::Twine("'."));
+  }
+
+  // apply the relocation
+  Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
+
+  // check result
+  if (Overflow == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' causes overflow. on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+
+  if (BadReloc == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' encounters unexpected opcode. "
+                                         "on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+}
+
+//=========================================//
+// Relocation helper function              //
+//=========================================//
+
+static const char * const GP_DISP_NAME = "_gp_disp";
+
+// Get an relocation entry in .rel.dyn and set its type to R_MIPS_REL32,
+// its FragmentRef to pReloc->targetFrag() and its ResolveInfo
+// to pReloc->symInfo()
+static
+void helper_SetRelDynEntry(Relocation& pReloc,
+                   MipsRelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  MipsGNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  Relocation& rel_entry =
+    *ld_backend.getRelDyn().getEntry(*rsym, false, exist);
+
+  rel_entry.setType(llvm::ELF::R_MIPS_REL32);
+  rel_entry.targetRef() = pReloc.targetRef();
+  rel_entry.setSymInfo(0);
+}
+
+// Find next R_MIPS_LO16 relocation paired to pReloc.
+static
+Relocation* helper_FindLo16Reloc(Relocation& pReloc)
+{
+  Relocation* reloc = static_cast<Relocation*>(pReloc.getNextNode());
+  while (NULL != reloc)
+  {
+    if (llvm::ELF::R_MIPS_LO16 == reloc->type() &&
+        reloc->symInfo() == pReloc.symInfo())
+      return reloc;
+
+    reloc = static_cast<Relocation*>(reloc->getNextNode());
+  }
+  return NULL;
+}
+
+// Check the symbol is _gp_disp.
+static
+bool helper_isGpDisp(const Relocation& pReloc)
+{
+  const ResolveInfo* rsym = pReloc.symInfo();
+  return 0 == strcmp(GP_DISP_NAME, rsym->name());
+}
+
+static
+RelocationFactory::Address helper_GetGP(MipsRelocationFactory& pParent)
+{
+  return pParent.getTarget().getGOT().getSection().addr() + 0x7FF0;
+}
+
+static
+GOTEntry& helper_GetGOTEntry(Relocation& pReloc,
+                             MipsRelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  MipsGNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  GOTEntry& got_entry = *ld_backend.getGOT().getEntry(*rsym, exist);
+
+  if (exist)
+    return got_entry;
+
+  // If we first get this GOT entry, we should initialize it.
+  if (rsym->reserved() & MipsGNULDBackend::ReserveGot) {
+    got_entry.setContent(pReloc.symValue());
+  }
+  else {
+    llvm::report_fatal_error("No GOT entry reserved for GOT type relocation!");
+  }
+
+  return got_entry;
+}
+
+static
+RelocationFactory::Address helper_GetGOTOffset(Relocation& pReloc,
+                                               MipsRelocationFactory& pParent)
+{
+  GOTEntry& got_entry = helper_GetGOTEntry(pReloc, pParent);
+  return pParent.getLayout().getOutputOffset(got_entry) - 0x7FF0;
+}
+
+static
+int32_t helper_CalcAHL(const Relocation& pHiReloc, const Relocation& pLoReloc)
+{
+  assert((pHiReloc.type() == llvm::ELF::R_MIPS_HI16 ||
+          pHiReloc.type() == llvm::ELF::R_MIPS_GOT16) &&
+         pLoReloc.type() == llvm::ELF::R_MIPS_LO16 &&
+         "Incorrect type of relocation for AHL calculation");
+
+  // Note the addend is section symbol offset here
+  assert (pHiReloc.addend() == pLoReloc.addend());
+
+  int32_t AHI = pHiReloc.target();
+  int32_t ALO = pLoReloc.target();
+  int32_t AHL = ((AHI & 0xFFFF) << 16) + (int16_t)(ALO & 0xFFFF) + pLoReloc.addend();
+  return AHL;
+}
+
+static
+void helper_DynRel(Relocation& pReloc,
+                   MipsRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  MipsGNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  Relocation& rel_entry =
+    *ld_backend.getRelDyn().getEntry(*rsym, false, exist);
+
+  rel_entry.setType(llvm::ELF::R_MIPS_REL32);
+  rel_entry.targetRef() = pReloc.targetRef();
+  rel_entry.setSymInfo(rsym->isLocal() ? NULL : rsym);
+}
+
+//=========================================//
+// Relocation functions implementation     //
+//=========================================//
+
+// R_MIPS_NONE and those unsupported/deprecated relocation type
+static
+MipsRelocationFactory::Result none(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   MipsRelocationFactory& pParent)
+{
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_32: S + A
+static
+MipsRelocationFactory::Result abs32(Relocation& pReloc,
+                                    const MCLDInfo& pLDInfo,
+                                    MipsRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  if (rsym->reserved() & MipsGNULDBackend::ReserveRel) {
+    helper_DynRel(pReloc, pParent);
+  }
+
+  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  RelocationFactory::DWord S = pReloc.symValue();
+
+  pReloc.target() |= (S + A);
+
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_HI16:
+//   local/external: ((AHL + S) - (short)(AHL + S)) >> 16
+//   _gp_disp      : ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16
+static
+MipsRelocationFactory::Result hi16(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   MipsRelocationFactory& pParent)
+{
+  Relocation* lo_reloc = helper_FindLo16Reloc(pReloc);
+  assert(NULL != lo_reloc && "There is no paired R_MIPS_LO16 for R_MIPS_HI16");
+
+  int32_t AHL = helper_CalcAHL(pReloc, *lo_reloc);
+  int32_t res = 0;
+
+  pParent.setAHL(AHL);
+
+  if (helper_isGpDisp(pReloc)) {
+    int32_t P = pReloc.place(pParent.getLayout());
+    int32_t GP = helper_GetGP(pParent);
+    res = ((AHL + GP - P) - (int16_t)(AHL + GP - P)) >> 16;
+  }
+  else {
+    int32_t S = pReloc.symValue();
+    res = ((AHL + S) - (int16_t)(AHL + S)) >> 16;
+  }
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (res & 0xFFFF);
+
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_LO16:
+//   local/external: AHL + S
+//   _gp_disp      : AHL + GP - P + 4
+static
+MipsRelocationFactory::Result lo16(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   MipsRelocationFactory& pParent)
+{
+  int32_t AHL = pParent.getAHL();
+  int32_t res = 0;
+
+  if (helper_isGpDisp(pReloc)) {
+    int32_t P = pReloc.place(pParent.getLayout());
+    int32_t GP = helper_GetGP(pParent);
+    res = AHL + GP - P + 4;
+  }
+  else {
+    int32_t S = pReloc.symValue();
+    res = AHL + S;
+  }
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (res & 0xFFFF);
+
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_GOT16:
+//   local   : G (calculate AHL and put high 16 bit to GOT)
+//   external: G
+static
+MipsRelocationFactory::Result got16(Relocation& pReloc,
+                                    const MCLDInfo& pLDInfo,
+                                    MipsRelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  if (rsym->isLocal()) {
+    Relocation* lo_reloc = helper_FindLo16Reloc(pReloc);
+    assert(NULL != lo_reloc && "There is no paired R_MIPS_LO16 for R_MIPS_GOT16");
+
+    int32_t AHL = helper_CalcAHL(pReloc, *lo_reloc);
+    int32_t S = pReloc.symValue();
+
+    pParent.setAHL(AHL);
+
+    GOTEntry& got_entry = helper_GetGOTEntry(pReloc, pParent);
+
+    int32_t res = (AHL + S + 0x8000) & 0xFFFF0000;
+    got_entry.setContent(res);
+  }
+
+  RelocationFactory::Address G = helper_GetGOTOffset(pReloc, pParent);
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (G & 0xFFFF);
+
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_CALL16: G
+static
+MipsRelocationFactory::Result call16(Relocation& pReloc,
+                                     const MCLDInfo& pLDInfo,
+                                     MipsRelocationFactory& pParent)
+{
+  RelocationFactory::Address G = helper_GetGOTOffset(pReloc, pParent);
+
+  pReloc.target() &= 0xFFFF0000;
+  pReloc.target() |= (G & 0xFFFF);
+
+  return MipsRelocationFactory::OK;
+}
+
+// R_MIPS_GPREL32: A + S + GP0 - GP
+static
+MipsRelocationFactory::Result gprel32(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      MipsRelocationFactory& pParent)
+{
+  int32_t A = pReloc.target();
+  int32_t S = pReloc.symValue();
+  int32_t GP = helper_GetGP(pParent);
+
+  // llvm does not emits SHT_MIPS_REGINFO section.
+  // Assume that GP0 is zero.
+  pReloc.target() = (A + S - GP) & 0xFFFFFFFF;
+
+  return MipsRelocationFactory::OK;
+}
diff --git a/lib/Target/Mips/MipsRelocationFactory.h b/lib/Target/Mips/MipsRelocationFactory.h
new file mode 100644
index 0000000..8f3bf93
--- /dev/null
+++ b/lib/Target/Mips/MipsRelocationFactory.h
@@ -0,0 +1,64 @@
+//===- MipsRelocationFactory.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_RELOCATION_FACTORY_H
+#define MIPS_RELOCATION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/Support/GCFactory.h>
+#include "MipsLDBackend.h"
+
+namespace mcld
+{
+
+/** \class MipsRelocationFactory
+ *  \brief MipsRelocationFactory creates and destroys the Mips relocations.
+ */
+class MipsRelocationFactory : public RelocationFactory
+{
+public:
+  /** \enum Reloc
+   *  \brief Reloc is the result of applying functions.
+   */
+  enum Result
+  {
+    OK,
+    Overflow,
+    BadReloc
+  };
+
+public:
+  MipsRelocationFactory(size_t pNum, MipsGNULDBackend& pParent);
+
+  void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+
+  MipsGNULDBackend& getTarget()
+  { return m_Target; }
+
+  const MipsGNULDBackend& getTarget() const
+  { return m_Target; }
+
+  // Get last calculated AHL.
+  int32_t getAHL() const
+  { return m_AHL; }
+
+  // Set last calculated AHL.
+  void setAHL(int32_t pAHL)
+  { m_AHL = pAHL; }
+
+private:
+  MipsGNULDBackend& m_Target;
+  int32_t m_AHL;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/Mips/MipsRelocationFunctions.h b/lib/Target/Mips/MipsRelocationFunctions.h
new file mode 100644
index 0000000..4b60d10
--- /dev/null
+++ b/lib/Target/Mips/MipsRelocationFunctions.h
@@ -0,0 +1,76 @@
+//===- MipsRelocationFunction.h -------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DECL_MIPS_APPLY_RELOC_FUNC(Name) \
+static MipsRelocationFactory::Result Name(Relocation& pEntry, \
+                                          const MCLDInfo& pLDInfo, \
+                                          MipsRelocationFactory& pParent);
+
+#define DECL_MIPS_APPLY_RELOC_FUNCS \
+DECL_MIPS_APPLY_RELOC_FUNC(none) \
+DECL_MIPS_APPLY_RELOC_FUNC(abs32) \
+DECL_MIPS_APPLY_RELOC_FUNC(hi16) \
+DECL_MIPS_APPLY_RELOC_FUNC(lo16) \
+DECL_MIPS_APPLY_RELOC_FUNC(got16) \
+DECL_MIPS_APPLY_RELOC_FUNC(call16) \
+DECL_MIPS_APPLY_RELOC_FUNC(gprel32)
+
+#define DECL_MIPS_APPLY_RELOC_FUNC_PTRS \
+  { &none,     0, "R_MIPS_NONE"            }, \
+  { &none,     1, "R_MIPS_16"              }, \
+  { &abs32,    2, "R_MIPS_32"              }, \
+  { &none,     3, "R_MIPS_REL32"           }, \
+  { &none,     4, "R_MIPS_26"              }, \
+  { &hi16,     5, "R_MIPS_HI16"            }, \
+  { &lo16,     6, "R_MIPS_LO16"            }, \
+  { &none,     7, "R_MIPS_GPREL16"         }, \
+  { &none,     8, "R_MIPS_LITERAL"         }, \
+  { &got16,    9, "R_MIPS_GOT16"           }, \
+  { &none,    10, "R_MIPS_PC16"            }, \
+  { &call16,  11, "R_MIPS_CALL16"          }, \
+  { &gprel32, 12, "R_MIPS_GPREL32"         }, \
+  { &none,    13, "R_MIPS_UNUSED1"         }, \
+  { &none,    14, "R_MIPS_UNUSED2"         }, \
+  { &none,    15, "R_MIPS_UNUSED3"         }, \
+  { &none,    16, "R_MIPS_SHIFT5"          }, \
+  { &none,    17, "R_MIPS_SHIFT6"          }, \
+  { &none,    18, "R_MIPS_64"              }, \
+  { &none,    19, "R_MIPS_GOT_DISP"        }, \
+  { &none,    20, "R_MIPS_GOT_PAGE"        }, \
+  { &none,    21, "R_MIPS_GOT_OFST"        }, \
+  { &none,    22, "R_MIPS_GOT_HI16"        }, \
+  { &none,    23, "R_MIPS_GOT_LO16"        }, \
+  { &none,    24, "R_MIPS_SUB"             }, \
+  { &none,    25, "R_MIPS_INSERT_A"        }, \
+  { &none,    26, "R_MIPS_INSERT_B"        }, \
+  { &none,    27, "R_MIPS_DELETE"          }, \
+  { &none,    28, "R_MIPS_HIGHER"          }, \
+  { &none,    29, "R_MIPS_HIGHEST"         }, \
+  { &none,    30, "R_MIPS_CALL_HI16"       }, \
+  { &none,    31, "R_MIPS_CALL_LO16"       }, \
+  { &none,    32, "R_MIPS_SCN_DISP"        }, \
+  { &none,    33, "R_MIPS_REL16"           }, \
+  { &none,    34, "R_MIPS_ADD_IMMEDIATE"   }, \
+  { &none,    35, "R_MIPS_PJUMP"           }, \
+  { &none,    36, "R_MIPS_RELGOT"          }, \
+  { &none,    37, "R_MIPS_JALR"            }, \
+  { &none,    38, "R_MIPS_TLS_DTPMOD32"    }, \
+  { &none,    39, "R_MIPS_TLS_DTPREL32"    }, \
+  { &none,    40, "R_MIPS_TLS_DTPMOD64"    }, \
+  { &none,    41, "R_MIPS_TLS_DTPREL64"    }, \
+  { &none,    42, "R_MIPS_TLS_GD"          }, \
+  { &none,    43, "R_MIPS_TLS_LDM"         }, \
+  { &none,    44, "R_MIPS_TLS_DTPREL_HI16" }, \
+  { &none,    45, "R_MIPS_TLS_DTPREL_LO16" }, \
+  { &none,    46, "R_MIPS_TLS_GOTTPREL"    }, \
+  { &none,    47, "R_MIPS_TLS_TPREL32"     }, \
+  { &none,    48, "R_MIPS_TLS_TPREL64"     }, \
+  { &none,    49, "R_MIPS_TLS_TPREL_HI16"  }, \
+  { &none,    50, "R_MIPS_TLS_TPREL_LO16"  }, \
+  { &none,    51, "R_MIPS_GLOB_DAT"        }
diff --git a/lib/Target/Mips/MipsSectLinker.cpp b/lib/Target/Mips/MipsSectLinker.cpp
new file mode 100644
index 0000000..af543c9
--- /dev/null
+++ b/lib/Target/Mips/MipsSectLinker.cpp
@@ -0,0 +1,47 @@
+//===- MipsSectLinker.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/ADT/Triple.h>
+#include <mcld/Support/TargetRegistry.h>
+#include "Mips.h"
+#include "MipsAndroidSectLinker.h"
+
+using namespace mcld;
+
+namespace mcld {
+//===----------------------------------------------------------------------===//
+/// createMipsSectLinker - the help funtion to create
+/// corresponding MipsSectLinker
+///
+SectLinker* createMipsSectLinker(const std::string &pTriple,
+                                 SectLinkerOption &pOption,
+                                 mcld::TargetLDBackend &pLDBackend)
+{
+  llvm::Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker has not supported yet");
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker has not supported yet");
+  }
+
+  // For now, use Android SectLinker directly
+  return new MipsAndroidSectLinker(pOption,
+                                   pLDBackend);
+}
+
+} // namespace of mcld
+
+//==========================
+// MipsSectLinker
+extern "C" void LLVMInitializeMipsSectLinker() {
+  // Register the linker frontend
+  mcld::TargetRegistry::RegisterSectLinker(TheMipselTarget,
+                                           createMipsSectLinker);
+}
diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp
new file mode 100644
index 0000000..0987585
--- /dev/null
+++ b/lib/Target/Mips/MipsTargetMachine.cpp
@@ -0,0 +1,34 @@
+//===- MipsTargetMachine.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsTargetMachine.h"
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Support/TargetRegistry.h"
+#include "mcld/MC/MCLDInfo.h"
+#include "Mips.h"
+
+extern "C" void LLVMInitializeMipsLDTarget() {
+  // Register createTargetMachine function pointer to mcld::Target
+  mcld::RegisterTargetMachine<mcld::MipsBaseTargetMachine>
+        X(mcld::TheMipselTarget);
+}
+
+mcld::MipsBaseTargetMachine::MipsBaseTargetMachine(llvm::TargetMachine& pPM,
+                                                   const mcld::Target &pTarget,
+                                                   const std::string& pTriple)
+  : mcld::LLVMTargetMachine(pPM, pTarget, pTriple) {
+  // arg1 - the number of total attributes
+  // arg2 - the most possible number of input files
+  m_pLDInfo = new MCLDInfo(pTriple, 32, 64);
+}
+
+mcld::MipsBaseTargetMachine::~MipsBaseTargetMachine()
+{
+  delete m_pLDInfo;
+}
diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h
new file mode 100644
index 0000000..e9bd5da
--- /dev/null
+++ b/lib/Target/Mips/MipsTargetMachine.h
@@ -0,0 +1,38 @@
+//===- MipsTargetMachine.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MIPS_TARGET_MACHINE_H
+#define MIPS_TARGET_MACHINE_H
+#include "mcld/Target/TargetMachine.h"
+#include "Mips.h"
+
+namespace mcld
+{
+
+class MipsBaseTargetMachine : public LLVMTargetMachine
+{
+protected:
+  MCLDInfo *m_pLDInfo;
+
+public:
+  MipsBaseTargetMachine(llvm::TargetMachine &pTM,
+                        const mcld::Target &pTarget,
+                        const std::string &pTriple);
+
+  virtual ~MipsBaseTargetMachine();
+
+  mcld::MCLDInfo& getLDInfo()
+  { return *m_pLDInfo; }
+
+  const mcld::MCLDInfo& getLDInfo() const
+  { return *m_pLDInfo; }
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/Mips/TargetInfo/Android.mk b/lib/Target/Mips/TargetInfo/Android.mk
new file mode 100644
index 0000000..cf8ae38
--- /dev/null
+++ b/lib/Target/Mips/TargetInfo/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_mips_info_SRC_FILES := \
+  MipsTargetInfo.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mips_info_SRC_FILES)
+LOCAL_MODULE:= libmcldMipsInfo
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),mips)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_mips_info_SRC_FILES)
+LOCAL_MODULE:= libmcldMipsInfo
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp b/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
new file mode 100644
index 0000000..0889973
--- /dev/null
+++ b/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
@@ -0,0 +1,21 @@
+//===- MipsTargetInfo.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Support/TargetRegistry.h"
+
+namespace mcld {
+
+mcld::Target TheMipselTarget;
+
+extern "C" void LLVMInitializeMipsLDTargetInfo() {
+  // register into mcld::TargetRegistry
+  mcld::RegisterTarget X(TheMipselTarget, "mipsel");
+}
+
+} // namespace of mcld
diff --git a/lib/Target/OutputRelocSection.cpp b/lib/Target/OutputRelocSection.cpp
new file mode 100644
index 0000000..89b4f52
--- /dev/null
+++ b/lib/Target/OutputRelocSection.cpp
@@ -0,0 +1,84 @@
+//===- OutputRelocSection.cpp ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/LDSection.h>
+#include <mcld/Target/OutputRelocSection.h>
+
+using namespace mcld;
+
+//==========================
+// OutputRelocSection
+
+
+OutputRelocSection::OutputRelocSection(LDSection& pSection,
+                                       llvm::MCSectionData& pSectionData,
+                                       unsigned int pEntrySize)
+  : m_pSection(&pSection),
+    m_pSectionData(&pSectionData),
+    m_EntryBytes(pEntrySize),
+    m_isVisit(false),
+    m_ValidEntryIterator(){
+}
+
+OutputRelocSection::~OutputRelocSection()
+{
+}
+
+void OutputRelocSection::reserveEntry(RelocationFactory& pRelFactory,
+                                      size_t pNum)
+{
+  for(size_t i=0; i<pNum; i++) {
+    m_pSectionData->getFragmentList().push_back(pRelFactory.produceEmptyEntry());
+    // update section size
+    m_pSection->setSize(m_pSection->size() + m_EntryBytes);
+  }
+}
+
+Relocation* OutputRelocSection::getEntry(const ResolveInfo& pSymbol,
+                                         bool isForGOT,
+                                         bool& pExist)
+{
+  // first time visit this function, set m_ValidEntryIterator to
+  // Fragments.begin()
+  if(!m_isVisit) {
+    assert( !m_pSectionData->getFragmentList().empty() &&
+             "DynRelSection contains no entries.");
+    m_ValidEntryIterator = m_pSectionData->getFragmentList().begin();
+    m_isVisit = true;
+  }
+
+  assert(m_ValidEntryIterator != m_pSectionData->end() &&
+         "No empty relocation entry for the incoming symbol.");
+
+  // if this relocation is used to relocate GOT (.got or .got.plt),
+  // check if we've gotten an entry for this symbol before. If yes,
+  // return the found entry in map.
+  // Otherwise, this relocation is used to relocate general section
+  // (data or text section), return an empty entry directly.
+  Relocation* result;
+
+  if(isForGOT) {
+    // get or create entry in m_SymRelMap
+    Relocation *&Entry = m_SymRelMap[&pSymbol];
+    pExist = 1;
+
+    if(!Entry) {
+      pExist = 0;
+      Entry = llvm::cast<Relocation>(&(*m_ValidEntryIterator));
+      ++m_ValidEntryIterator;
+    }
+    result = Entry;
+  }
+  else {
+    pExist = 0;
+    result = llvm::cast<Relocation>(&(*m_ValidEntryIterator));
+    ++m_ValidEntryIterator;
+  }
+  return result;
+}
+
diff --git a/lib/Target/PLT.cpp b/lib/Target/PLT.cpp
new file mode 100644
index 0000000..a29dfd8
--- /dev/null
+++ b/lib/Target/PLT.cpp
@@ -0,0 +1,42 @@
+//===- PLT.cpp ------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Target/PLT.h>
+
+using namespace mcld;
+
+class GOT;
+
+//===--------------------------------------------------------------------===//
+// PLTEntry
+PLTEntry::PLTEntry(size_t pSize, llvm::MCSectionData* pParent)
+   : MCTargetFragment(llvm::MCFragment::FT_Target, pParent),
+     m_EntrySize(pSize), m_pContent(NULL)
+{
+}
+
+PLTEntry::~PLTEntry()
+{
+  if (m_pContent) {
+    free(m_pContent);
+    m_pContent = NULL;
+  }
+}
+
+//===--------------------------------------------------------------------===//
+// PLT
+PLT::PLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+  :m_Section(pSection),
+   m_SectionData(pSectionData)
+{
+}
+
+PLT::~PLT()
+{
+}
+
diff --git a/lib/Target/Stub.cpp b/lib/Target/Stub.cpp
new file mode 100644
index 0000000..4b59acf
--- /dev/null
+++ b/lib/Target/Stub.cpp
@@ -0,0 +1,15 @@
+//===- Stub.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Target/Stub.h"
+
+using namespace mcld;
+
+//==========================
+// Stub
+
diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp
new file mode 100644
index 0000000..58178ec
--- /dev/null
+++ b/lib/Target/Target.cpp
@@ -0,0 +1,25 @@
+//===- Target.cpp ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/TargetRegistry.h"
+#include "mcld/Target/TargetMachine.h"
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Target/TargetMachine.h>
+
+using namespace llvm;
+using namespace mcld;
+
+/* ** */
+mcld::Target::Target()
+  : TargetMachineCtorFn(0),
+    SectLinkerCtorFn(0),
+    TargetLDBackendCtorFn(0),
+    m_pT(0)
+{
+}
+
diff --git a/lib/Target/TargetLDBackend.cpp b/lib/Target/TargetLDBackend.cpp
new file mode 100644
index 0000000..1a8ab6b
--- /dev/null
+++ b/lib/Target/TargetLDBackend.cpp
@@ -0,0 +1,23 @@
+//===- TargetLDBackend.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/Relocation.h"
+#include "mcld/LD/Layout.h"
+#include "mcld/Target/TargetLDBackend.h"
+
+using namespace mcld;
+
+/* ** */
+TargetLDBackend::TargetLDBackend()
+{
+}
+
+TargetLDBackend::~TargetLDBackend()
+{
+}
+
diff --git a/lib/Target/X86/Android.mk b/lib/Target/X86/Android.mk
new file mode 100644
index 0000000..e9a051b
--- /dev/null
+++ b/lib/Target/X86/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_x86_target_SRC_FILES := \
+  X86AndroidSectLinker.cpp  \
+  X86ELFDynamic.cpp \
+  X86ELFSectLinker.cpp  \
+  X86GOT.cpp  \
+  X86GOTPLT.cpp  \
+  X86LDBackend.cpp  \
+  X86PLT.cpp  \
+  X86RelocationFactory.cpp  \
+  X86SectLinker.cpp \
+  X86TargetMachine.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_x86_target_SRC_FILES)
+LOCAL_MODULE:= libmcldX86Target
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),x86)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_x86_target_SRC_FILES)
+LOCAL_MODULE:= libmcldX86Target
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/X86/TargetInfo/Android.mk b/lib/Target/X86/TargetInfo/Android.mk
new file mode 100644
index 0000000..3664933
--- /dev/null
+++ b/lib/Target/X86/TargetInfo/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+mcld_x86_info_SRC_FILES := \
+  X86TargetInfo.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_x86_info_SRC_FILES)
+LOCAL_MODULE:= libmcldX86Info
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_HOST_BUILD_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifeq ($(TARGET_ARCH),x86)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(mcld_x86_info_SRC_FILES)
+LOCAL_MODULE:= libmcldX86Info
+
+LOCAL_MODULE_TAGS := optional
+
+include $(MCLD_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/lib/Target/X86/TargetInfo/X86TargetInfo.cpp b/lib/Target/X86/TargetInfo/X86TargetInfo.cpp
new file mode 100644
index 0000000..afe349e
--- /dev/null
+++ b/lib/Target/X86/TargetInfo/X86TargetInfo.cpp
@@ -0,0 +1,22 @@
+//===- X86TargetInfo.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Support/TargetRegistry.h"
+
+namespace mcld {
+
+mcld::Target TheX86Target;
+
+extern "C" void LLVMInitializeX86LDTargetInfo() {
+  // register into mcld::TargetRegistry
+  mcld::RegisterTarget X(TheX86Target, "x86");
+}
+
+} // namespace of mcld
+
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
new file mode 100644
index 0000000..2d07314
--- /dev/null
+++ b/lib/Target/X86/X86.h
@@ -0,0 +1,24 @@
+//===- X86.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_X86_H
+#define MCLD_X86_H
+#include <string>
+#include "mcld/Target/TargetMachine.h"
+
+namespace mcld {
+class TargetLDBackend;
+
+extern mcld::Target TheX86Target;
+
+TargetLDBackend *createX86LDBackend(const llvm::Target&, const std::string&);
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86AndroidSectLinker.cpp b/lib/Target/X86/X86AndroidSectLinker.cpp
new file mode 100644
index 0000000..91b466c
--- /dev/null
+++ b/lib/Target/X86/X86AndroidSectLinker.cpp
@@ -0,0 +1,35 @@
+//===- X86AndroidSectLinker.cpp -------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86AndroidSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+X86AndroidSectLinker::X86AndroidSectLinker(SectLinkerOption &pOption,
+                                           TargetLDBackend &pLDBackend)
+  : AndroidSectLinker(pOption,
+                      pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attibutes
+  info.attrFactory().constraint().disableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().unsetWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+
+}
+
+X86AndroidSectLinker::~X86AndroidSectLinker()
+{
+}
+
diff --git a/lib/Target/X86/X86AndroidSectLinker.h b/lib/Target/X86/X86AndroidSectLinker.h
new file mode 100644
index 0000000..b275aca
--- /dev/null
+++ b/lib/Target/X86/X86AndroidSectLinker.h
@@ -0,0 +1,38 @@
+//===- X86AndroidSectLinker.h ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86_ANDROIDSECTLINKER_H
+#define X86_ANDROIDSECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Target/AndroidSectLinker.h>
+
+namespace mcld
+{
+
+/** \class X86AndroidSectLinker
+ *  \brief X86AndroidSectLinker sets up the environment for linking.
+ *
+ *  \see
+ *  \author Anders Cheng <Anders.Cheng@mediatek.com>
+ */
+class X86AndroidSectLinker : public AndroidSectLinker
+{
+public:
+  X86AndroidSectLinker(SectLinkerOption &pOption,
+                       mcld::TargetLDBackend &pLDBackend);
+
+  ~X86AndroidSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86ELFDynamic.cpp b/lib/Target/X86/X86ELFDynamic.cpp
new file mode 100644
index 0000000..c32cfa8
--- /dev/null
+++ b/lib/Target/X86/X86ELFDynamic.cpp
@@ -0,0 +1,41 @@
+//===- X86ELFDynamic.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <mcld/LD/ELFFileFormat.h>
+#include "X86ELFDynamic.h"
+
+using namespace mcld;
+
+X86ELFDynamic::X86ELFDynamic(const GNULDBackend& pParent)
+  : ELFDynamic(pParent), m_HasGOTPLT(false)
+{
+}
+
+X86ELFDynamic::~X86ELFDynamic()
+{
+}
+
+void X86ELFDynamic::reserveTargetEntries(const ELFFileFormat& pFormat)
+{
+  // reservePLTGOT
+  if (m_HasGOTPLT ? pFormat.hasGOTPLT() : pFormat.hasGOT())
+    reserveOne(llvm::ELF::DT_PLTGOT);
+}
+
+void X86ELFDynamic::applyTargetEntries(const ELFFileFormat& pFormat)
+{
+  // applyPLTGOT
+  if (m_HasGOTPLT) {
+      if (pFormat.hasGOTPLT())
+	applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOTPLT().addr());
+  }
+  else if (pFormat.hasGOT())
+    applyOne(llvm::ELF::DT_PLTGOT, pFormat.getGOT().addr());
+}
+
diff --git a/lib/Target/X86/X86ELFDynamic.h b/lib/Target/X86/X86ELFDynamic.h
new file mode 100644
index 0000000..b9e70ce
--- /dev/null
+++ b/lib/Target/X86/X86ELFDynamic.h
@@ -0,0 +1,38 @@
+//===- X86ELFDynamic.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_X86_ELFDYNAMIC_SECTION_H
+#define MCLD_X86_ELFDYNAMIC_SECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Target/ELFDynamic.h>
+
+namespace mcld {
+
+class X86ELFDynamic : public ELFDynamic
+{
+public:
+  X86ELFDynamic(const GNULDBackend& pParent);
+  ~X86ELFDynamic();
+
+private:
+  void reserveTargetEntries(const ELFFileFormat& pFormat);
+  void applyTargetEntries(const ELFFileFormat& pFormat);
+
+private:
+  // True if we have .got.plt section, which will avoid GOT0 entries
+  // when PLT isn't used.  To support .got.plt section, we must combine
+  // .got section and .got.plt section into a single GOT.
+  bool m_HasGOTPLT;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/X86/X86ELFSectLinker.cpp b/lib/Target/X86/X86ELFSectLinker.cpp
new file mode 100644
index 0000000..009293c
--- /dev/null
+++ b/lib/Target/X86/X86ELFSectLinker.cpp
@@ -0,0 +1,34 @@
+//===- X86ELFSectLinker.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "X86ELFSectLinker.h"
+
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+using namespace mcld;
+
+X86ELFSectLinker::X86ELFSectLinker(SectLinkerOption &pOption,
+                                   TargetLDBackend &pLDBackend)
+  : SectLinker(pOption,
+               pLDBackend) {
+  MCLDInfo &info = pOption.info();
+  // set up target-dependent constraints of attibutes
+  info.attrFactory().constraint().enableWholeArchive();
+  info.attrFactory().constraint().disableAsNeeded();
+  info.attrFactory().constraint().setSharedSystem();
+
+  // set up the predefined attributes
+  info.attrFactory().predefined().setWholeArchive();
+  info.attrFactory().predefined().setDynamic();
+
+}
+
+X86ELFSectLinker::~X86ELFSectLinker()
+{
+}
+
diff --git a/lib/Target/X86/X86ELFSectLinker.h b/lib/Target/X86/X86ELFSectLinker.h
new file mode 100644
index 0000000..5e7abfd
--- /dev/null
+++ b/lib/Target/X86/X86ELFSectLinker.h
@@ -0,0 +1,36 @@
+//===- X86ELFSectLinker.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_ELFSECTLINKER_H
+#define X86_ELFSECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/CodeGen/SectLinker.h>
+
+namespace mcld
+{
+
+/** \class X86ELFSectLinker
+ *  \brief X86ELFSectLinker sets up the environment for linking.
+ *
+ *  \see
+ */
+class X86ELFSectLinker : public SectLinker
+{
+public:
+  X86ELFSectLinker(SectLinkerOption &pOption,
+                   mcld::TargetLDBackend &pLDBackend);
+
+  ~X86ELFSectLinker();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86GOT.cpp b/lib/Target/X86/X86GOT.cpp
new file mode 100644
index 0000000..2784989
--- /dev/null
+++ b/lib/Target/X86/X86GOT.cpp
@@ -0,0 +1,129 @@
+//===- impl.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "X86GOT.h"
+#include <mcld/LD/LDFileFormat.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <new>
+
+namespace {
+  const size_t X86GOTEntrySize = 4;
+}
+
+using namespace mcld;
+
+//===----------------------------------------------------------------------===//
+// X86GOT
+X86GOT::X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+             : GOT(pSection, pSectionData, X86GOTEntrySize),
+               m_GeneralGOTNum(0), m_GOTPLTNum(0), m_GeneralGOTIterator(),
+               m_GOTPLTIterator(), m_LastGOT0()
+{
+  GOTEntry* Entry = 0;
+
+  // Create GOT0 entries.
+  for (unsigned int i = 0; i < X86GOT0Num; i++) {
+    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
+                                        &m_SectionData);
+
+    if (!Entry)
+      llvm::report_fatal_error("Allocating GOT0 entries failed!");
+
+    m_Section.setSize(m_Section.size() + X86GOTEntrySize);
+  }
+
+  // Skip GOT0 entries.
+  iterator it = m_SectionData.begin();
+  iterator ie = m_SectionData.end();
+
+  for (unsigned int i = 1; i < X86GOT0Num; ++i) {
+    if (it == ie)
+      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
+
+    ++it;
+  }
+
+  m_LastGOT0 = it;
+  m_GeneralGOTIterator = it;
+  m_GOTPLTIterator = it;
+}
+
+X86GOT::~X86GOT()
+{
+}
+
+void X86GOT::reserveEntry(size_t pNum)
+{
+  GOTEntry* Entry = 0;
+
+  for (size_t i = 0; i < pNum; i++) {
+    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
+                                        &m_SectionData);
+
+    if (!Entry)
+      llvm::report_fatal_error("Allocating new memory for GOTEntry failed");
+
+    m_Section.setSize(m_Section.size() + X86GOTEntrySize);
+    ++m_GeneralGOTNum;
+  }
+}
+
+
+GOTEntry* X86GOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
+{
+  GOTEntry *&Entry = m_GeneralGOTMap[&pInfo];
+  pExist = 1;
+
+  if (!Entry) {
+    pExist = 0;
+
+    ++m_GeneralGOTIterator;
+    assert(m_GeneralGOTIterator != m_SectionData.getFragmentList().end()
+           && "The number of GOT Entries and ResolveInfo doesn't match!");
+
+    Entry = llvm::cast<GOTEntry>(&(*m_GeneralGOTIterator));
+  }
+
+  return Entry;
+}
+
+void X86GOT::applyGOT0(uint64_t pAddress)
+{
+  llvm::cast<GOTEntry>
+    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
+}
+
+X86GOT::iterator X86GOT::begin()
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+X86GOT::const_iterator X86GOT::begin() const
+{
+  return m_SectionData.getFragmentList().begin();
+}
+
+X86GOT::iterator X86GOT::end()
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+X86GOT::const_iterator X86GOT::end() const
+{
+  return m_SectionData.getFragmentList().end();
+}
+
+unsigned int X86GOT::getGOTPLTNum() const
+{ return m_GOTPLTNum; }
+
+X86GOT::iterator X86GOT::getLastGOT0()
+{ return m_LastGOT0; }
+
+const X86GOT::iterator X86GOT::getLastGOT0() const
+{ return m_LastGOT0; }
+
diff --git a/lib/Target/X86/X86GOT.h b/lib/Target/X86/X86GOT.h
new file mode 100644
index 0000000..018aa24
--- /dev/null
+++ b/lib/Target/X86/X86GOT.h
@@ -0,0 +1,91 @@
+//===- X86GOT.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_X86_GOT_H
+#define MCLD_X86_GOT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "X86PLT.h"
+#include <mcld/Target/GOT.h>
+
+namespace mcld
+{
+class LDSection;
+
+/** \class X86GOT
+ *  \brief X86 Global Offset Table.
+ */
+
+const unsigned int X86GOT0Num = 3;
+
+class X86GOT : public GOT
+{
+  friend void mcld::X86PLT::reserveEntry(size_t pNum);
+
+  friend mcld::PLTEntry* mcld::X86PLT::getPLTEntry(
+         const mcld::ResolveInfo& pSymbol,bool& pExist);
+
+  friend mcld::GOTEntry* mcld::X86PLT::getGOTPLTEntry(
+         const mcld::ResolveInfo& pSymbol,bool& pExist);
+
+  typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+public:
+  X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+
+  ~X86GOT();
+
+  //Reserve general GOT entries.
+  void reserveEntry(size_t pNum = 1);
+
+  GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist);
+
+  void applyGOT0(uint64_t pAddress);
+
+  iterator begin();
+
+  const_iterator begin() const;
+
+  iterator end();
+
+  const_iterator end() const;
+
+  unsigned int getGOTPLTNum() const;
+
+  iterator getLastGOT0();
+
+  const iterator getLastGOT0() const;
+
+private:
+
+  unsigned int m_GeneralGOTNum;
+  unsigned int m_GOTPLTNum;
+
+  // Used by getGeneralGOTEntry()
+  iterator m_GeneralGOTIterator;
+
+  // Used by getGOTPLTEntry()
+  iterator m_GOTPLTIterator;
+
+  // The last GOT0 entry
+  iterator m_LastGOT0;
+
+  SymbolIndexMapType m_GOTPLTMap;
+  SymbolIndexMapType m_GeneralGOTMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86GOTPLT.cpp b/lib/Target/X86/X86GOTPLT.cpp
new file mode 100644
index 0000000..55596e3
--- /dev/null
+++ b/lib/Target/X86/X86GOTPLT.cpp
@@ -0,0 +1,113 @@
+//===- X86GOTPLT.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "X86GOTPLT.h"
+#include "mcld/LD/LDFileFormat.h"
+#include <llvm/Support/ErrorHandling.h>
+#include <new>
+
+namespace {
+  const uint64_t X86GOTPLTEntrySize = 4;
+}
+
+namespace mcld {
+
+//===----------------------------------------------------------------------===//
+// X86GOTPLT
+X86GOTPLT::X86GOTPLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
+  : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator()
+{
+  GOTEntry* Entry = 0;
+
+  // Create GOT0 entries.
+  for (int i = 0; i < 3; i++) {
+    Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize,
+                                        &m_SectionData);
+
+    if (!Entry)
+      llvm::report_fatal_error("Allocating GOT0 entries failed!");
+
+    m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize);
+  }
+
+  // Skip GOT0 entries.
+  iterator it = m_SectionData.begin();
+  iterator ie = m_SectionData.end();
+
+  for (size_t i = 1; i < X86GOT0Num; ++i) {
+    if (it == ie)
+      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
+
+    ++it;
+  }
+
+  m_GOTPLTIterator = it;
+}
+
+X86GOTPLT::~X86GOTPLT()
+{
+}
+
+X86GOTPLT::iterator X86GOTPLT::begin()
+{
+  return m_SectionData.begin();
+}
+
+X86GOTPLT::const_iterator X86GOTPLT::begin() const
+{
+  return m_SectionData.begin();
+}
+
+X86GOTPLT::iterator X86GOTPLT::end()
+{
+  return m_SectionData.end();
+}
+
+X86GOTPLT::const_iterator X86GOTPLT::end() const
+{
+  return m_SectionData.end();
+}
+
+void X86GOTPLT::applyGOT0(const uint64_t pAddress)
+{
+  llvm::cast<GOTEntry>
+    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
+}
+
+void X86GOTPLT::reserveGOTPLTEntry()
+{
+    GOTEntry* got_entry = 0;
+
+    got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData()));
+
+    if (!got_entry)
+      llvm::report_fatal_error("Allocating new memory for GOT failed!");
+
+    m_Section.setSize(m_Section.size() + getEntrySize());
+}
+
+void X86GOTPLT::applyAllGOTPLT(const uint64_t pPLTBase)
+{
+  iterator gotplt_it = begin();
+  iterator gotplt_ie = end();
+
+  for (; gotplt_it != gotplt_ie; ++gotplt_it)
+    llvm::cast<GOTEntry>(*gotplt_it).setContent(pPLTBase);
+}
+
+GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
+{
+  return m_GOTPLTMap[&pSymbol];
+}
+
+X86GOTPLT::iterator X86GOTPLT::getNextGOTPLTEntry()
+{
+  return ++m_GOTPLTIterator;
+}
+
+} //end mcld namespace
diff --git a/lib/Target/X86/X86GOTPLT.h b/lib/Target/X86/X86GOTPLT.h
new file mode 100644
index 0000000..9882cc4
--- /dev/null
+++ b/lib/Target/X86/X86GOTPLT.h
@@ -0,0 +1,70 @@
+//===- X86GOTPLT.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_X86_GOTPLT_H
+#define MCLD_X86_GOTPLT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Target/GOT.h"
+
+namespace mcld
+{
+class LDSection;
+
+/** \class X86GOTPLT
+ *  \brief X86 .got.plt section.
+ */
+
+const unsigned int X86GOT0Num = 3;
+
+class X86GOTPLT : public GOT
+{
+  typedef llvm::DenseMap<const ResolveInfo*, GOTEntry*> SymbolIndexMapType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+public:
+  X86GOTPLT(LDSection &pSection, llvm::MCSectionData& pSectionData);
+
+  ~X86GOTPLT();
+
+  iterator begin();
+
+  const_iterator begin() const;
+
+  iterator end();
+
+  const_iterator end() const;
+
+// For GOT0
+public:
+  void applyGOT0(const uint64_t pAddress);
+
+// For GOTPLT
+public:
+  void reserveGOTPLTEntry();
+
+  void applyAllGOTPLT(const uint64_t pPLTBase);
+
+  GOTEntry*& lookupGOTPLTMap(const ResolveInfo& pSymbol);
+
+  iterator getNextGOTPLTEntry();
+
+private:
+  iterator m_GOTPLTIterator;
+  SymbolIndexMapType m_GOTPLTMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp
new file mode 100644
index 0000000..354cd51
--- /dev/null
+++ b/lib/Target/X86/X86LDBackend.cpp
@@ -0,0 +1,752 @@
+//===- X86LDBackend.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86ELFDynamic.h"
+#include "X86LDBackend.h"
+#include "X86RelocationFactory.h"
+
+#include <llvm/ADT/Triple.h>
+#include <mcld/Support/MemoryRegion.h>
+#include <mcld/Support/TargetRegistry.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/LD/SectionMap.h>
+#include <mcld/MC/MCRegionFragment.h>
+
+#include <cstring>
+
+using namespace mcld;
+
+X86GNULDBackend::X86GNULDBackend()
+  : m_pRelocFactory(NULL),
+    m_pGOT(NULL),
+    m_pPLT(NULL),
+    m_pRelDyn(NULL),
+    m_pRelPLT(NULL),
+    m_pDynamic(NULL) {
+}
+
+X86GNULDBackend::~X86GNULDBackend()
+{
+  if (NULL != m_pRelocFactory)
+    delete m_pRelocFactory;
+  if (NULL != m_pGOT)
+    delete m_pGOT;
+  if (NULL != m_pPLT)
+    delete m_pPLT;
+  if (NULL !=m_pRelDyn)
+    delete m_pRelDyn;
+  if (NULL != m_pRelPLT)
+    delete m_pRelPLT;
+  if (NULL != m_pDynamic)
+    delete m_pDynamic;
+}
+
+RelocationFactory* X86GNULDBackend::getRelocFactory()
+{
+  assert(NULL != m_pRelocFactory);
+  return m_pRelocFactory;
+}
+
+bool X86GNULDBackend::initRelocFactory(const MCLinker& pLinker)
+{
+  if (NULL == m_pRelocFactory) {
+    m_pRelocFactory = new X86RelocationFactory(1024, *this);
+    m_pRelocFactory->setLayout(pLinker.getLayout());
+  }
+  return true;
+}
+
+void X86GNULDBackend::doPreLayout(const Output& pOutput,
+                                  const MCLDInfo& pInfo,
+                                  MCLinker& pLinker)
+{
+  // when building shared object, the .got section is needed
+  if(pOutput.type() == Output::DynObj && (NULL == m_pGOT))
+      createX86GOT(pLinker, pOutput);
+}
+
+void X86GNULDBackend::doPostLayout(const Output& pOutput,
+                                   const MCLDInfo& pInfo,
+                                   MCLinker& pLinker)
+{
+  // emit program headers
+  if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec)
+    emitProgramHdrs(pLinker.getLDInfo().output());
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+X86ELFDynamic& X86GNULDBackend::dynamic()
+{
+  if (NULL == m_pDynamic)
+    m_pDynamic = new X86ELFDynamic(*this);
+
+  return *m_pDynamic;
+}
+
+/// dynamic - the dynamic section of the target machine.
+/// Use co-variant return type to return its own dynamic section.
+const X86ELFDynamic& X86GNULDBackend::dynamic() const
+{
+  assert( NULL != m_pDynamic);
+  return *m_pDynamic;
+}
+
+void X86GNULDBackend::createX86GOT(MCLinker& pLinker, const Output& pOutput)
+{
+  // get .got LDSection and create MCSectionData
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& got = file_format->getGOT();
+  m_pGOT = new X86GOT(got, pLinker.getOrCreateSectData(got));
+
+  // define symbol _GLOBAL_OFFSET_TABLE_ when .got create
+  if( m_pGOTSymbol != NULL ) {
+    pLinker.defineSymbol<MCLinker::Force, MCLinker::Unresolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+  else {
+    m_pGOTSymbol = pLinker.defineSymbol<MCLinker::Force, MCLinker::Resolve>(
+                     "_GLOBAL_OFFSET_TABLE_",
+                     false,
+                     ResolveInfo::Object,
+                     ResolveInfo::Define,
+                     ResolveInfo::Local,
+                     0x0, // size
+                     0x0, // value
+                     pLinker.getLayout().getFragmentRef(*(m_pGOT->begin()), 0x0),
+                     ResolveInfo::Hidden);
+  }
+}
+
+void X86GNULDBackend::createX86PLTandRelPLT(MCLinker& pLinker,
+                                            const Output& pOutput)
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& plt = file_format->getPLT();
+  LDSection& relplt = file_format->getRelPlt();
+  // create MCSectionData and X86PLT
+  m_pPLT = new X86PLT(plt, pLinker.getOrCreateSectData(plt), *m_pGOT, pOutput);
+
+  // set info of .rel.plt to .plt
+  relplt.setLink(&plt);
+  // create MCSectionData and X86RelDynSection
+  m_pRelPLT = new OutputRelocSection(relplt,
+                                     pLinker.getOrCreateSectData(relplt),
+                                     8);
+}
+
+void X86GNULDBackend::createX86RelDyn(MCLinker& pLinker,
+                                      const Output& pOutput)
+{
+  // get .rel.dyn LDSection and create MCSectionData
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  LDSection& reldyn = file_format->getRelDyn();
+  // create MCSectionData and X86RelDynSection
+  m_pRelDyn = new OutputRelocSection(reldyn,
+                                     pLinker.getOrCreateSectData(reldyn),
+                                     8);
+}
+
+ELFFileFormat* X86GNULDBackend::getOutputFormat(const Output& pOutput) const
+{
+  switch (pOutput.type()) {
+    case Output::DynObj:
+      return getDynObjFileFormat();
+    case Output::Exec:
+      return getExecFileFormat();
+    // FIXME: We do not support building .o now
+    case Output::Object:
+    default:
+      llvm::report_fatal_error(llvm::Twine("Unsupported output file format: ") +
+                               llvm::Twine(pOutput.type()));
+      return NULL;
+  }
+}
+
+bool X86GNULDBackend::isSymbolNeedsPLT(const ResolveInfo& pSym,
+                                       const MCLDInfo& pLDInfo,
+                                       const Output& pOutput) const
+{
+  return((Output::DynObj == pOutput.type())
+         &&(ResolveInfo::Function == pSym.type())
+         &&(pSym.isDyn() || pSym.isUndef() ||
+            isSymbolPreemptible(pSym, pLDInfo, pOutput))
+        );
+}
+
+bool X86GNULDBackend::isSymbolNeedsDynRel(const ResolveInfo& pSym,
+                                          const Output& pOutput,
+                                          bool isAbsReloc) const
+{
+  if(pSym.isUndef() && (pOutput.type()==Output::Exec))
+    return false;
+  if(pSym.isAbsolute())
+    return false;
+  if(pOutput.type()==Output::DynObj && isAbsReloc)
+    return true;
+  if(pSym.isDyn() || pSym.isUndef())
+    return true;
+
+  return false;
+}
+
+bool X86GNULDBackend::isSymbolPreemptible(const ResolveInfo& pSym,
+                                         const MCLDInfo& pLDInfo,
+                                         const Output& pOutput) const
+{
+  if(pSym.other() != ResolveInfo::Default)
+    return false;
+
+  if(pOutput.type() != Output::DynObj)
+    return false;
+
+  if(pLDInfo.options().Bsymbolic())
+    return false;
+
+  return true;
+}
+
+void X86GNULDBackend::updateAddend(Relocation& pReloc,
+                                   const LDSymbol& pInputSym,
+                                   const Layout& pLayout) const
+{
+  // Update value keep in addend if we meet a section symbol
+  if(pReloc.symInfo()->type() == ResolveInfo::Section) {
+    pReloc.setAddend(pLayout.getOutputOffset(
+                     *pInputSym.fragRef()) + pReloc.addend());
+  }
+}
+
+void X86GNULDBackend::scanLocalReloc(Relocation& pReloc,
+                                     const LDSymbol& pInputSym,
+                                     MCLinker& pLinker,
+                                     const MCLDInfo& pLDInfo,
+                                     const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  updateAddend(pReloc, pInputSym, pLinker.getLayout());
+
+  switch(pReloc.type()){
+
+    case llvm::ELF::R_386_32:
+      // If buiding PIC object (shared library or PIC executable),
+      // a dynamic relocations with RELATIVE type to this location is needed.
+      // Reserve an entry in .rel.dyn
+      if(Output::DynObj == pOutput.type()) {
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createX86RelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | ReserveRel);
+      }
+      return;
+
+    case llvm::ELF::R_386_GOTOFF:
+    case llvm::ELF::R_386_GOTPC:
+      // A GOT section is needed
+      if(NULL == m_pGOT)
+        createX86GOT(pLinker, pOutput);
+      return;
+
+    case llvm::ELF::R_386_PC32:
+      return;
+
+    default:
+      llvm::report_fatal_error(llvm::Twine("unexpected reloc ") +
+                               llvm::Twine((int) pReloc.type()) +
+                               llvm::Twine(" in object file"));
+      break;
+  } // end switch
+}
+
+void X86GNULDBackend::scanGlobalReloc(Relocation& pReloc,
+                                      const LDSymbol& pInputSym,
+                                      MCLinker& pLinker,
+                                      const MCLDInfo& pLDInfo,
+                                      const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+
+  switch(pReloc.type()) {
+    case llvm::ELF::R_386_32:
+      // Absolute relocation type, symbol may needs PLT entry or
+      // dynamic relocation entry
+      if(isSymbolNeedsPLT(*rsym, pLDInfo, pOutput)) {
+        // create plt for this symbol if it does not have one
+        if(!(rsym->reserved() & ReservePLT)){
+          // Create .got section if it dosen't exist
+          if(NULL == m_pGOT)
+             createX86GOT(pLinker, pOutput);
+          // create .plt and .rel.plt if not exist
+          if(NULL == m_pPLT)
+            createX86PLTandRelPLT(pLinker, pOutput);
+          // Symbol needs PLT entry, we need to reserve a PLT entry
+          // and the corresponding GOT and dynamic relocation entry
+          // in .got and .rel.plt. (GOT entry will be reserved simultaneously
+          // when calling X86PLT->reserveEntry())
+          m_pPLT->reserveEntry();
+          m_pRelPLT->reserveEntry(*m_pRelocFactory);
+          // set PLT bit
+          rsym->setReserved(rsym->reserved() | ReservePLT);
+        }
+      }
+
+      if(isSymbolNeedsDynRel(*rsym, pOutput, true)) {
+        // symbol needs dynamic relocation entry, reserve an entry in .rel.dyn
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createX86RelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set Rel bit
+        rsym->setReserved(rsym->reserved() | ReserveRel);
+      }
+      return;
+
+    case llvm::ELF::R_386_GOTOFF:
+    case llvm::ELF::R_386_GOTPC: {
+      // A GOT section is needed
+      if(NULL == m_pGOT)
+        createX86GOT(pLinker, pOutput);
+      return;
+    }
+
+    case llvm::ELF::R_386_PLT32:
+      // A PLT entry is needed when building shared library
+
+      // return if we already create plt for this symbol
+      if(rsym->reserved() & ReservePLT)
+        return;
+
+      // if symbol is defined in the ouput file and it's not
+      // preemptible, no need plt
+      if(rsym->isDefine() && !rsym->isDyn() &&
+         !isSymbolPreemptible(*rsym, pLDInfo, pOutput)) {
+        return;
+      }
+
+      // Create .got section if it dosen't exist
+      if(NULL == m_pGOT)
+         createX86GOT(pLinker, pOutput);
+      // create .plt and .rel.plt if not exist
+      if(NULL == m_pPLT)
+         createX86PLTandRelPLT(pLinker, pOutput);
+      // Symbol needs PLT entry, we need to reserve a PLT entry
+      // and the corresponding GOT and dynamic relocation entry
+      // in .got and .rel.plt. (GOT entry will be reserved simultaneously
+      // when calling X86PLT->reserveEntry())
+      m_pPLT->reserveEntry();
+      m_pRelPLT->reserveEntry(*m_pRelocFactory);
+      // set PLT bit
+      rsym->setReserved(rsym->reserved() | ReservePLT);
+      return;
+
+    case llvm::ELF::R_386_GOT32:
+      // Symbol needs GOT entry, reserve entry in .got
+      // return if we already create GOT for this symbol
+      if(rsym->reserved() & (ReserveGOT | GOTRel))
+        return;
+      if(NULL == m_pGOT)
+        createX86GOT(pLinker, pOutput);
+      m_pGOT->reserveEntry();
+      // If building shared object or the symbol is undefined, a dynamic
+      // relocation is needed to relocate this GOT entry. Reserve an
+      // entry in .rel.dyn
+      if(Output::DynObj == pOutput.type() || rsym->isUndef() || rsym->isDyn()) {
+        // create .rel.dyn section if not exist
+        if(NULL == m_pRelDyn)
+          createX86RelDyn(pLinker, pOutput);
+        m_pRelDyn->reserveEntry(*m_pRelocFactory);
+        // set GOTRel bit
+        rsym->setReserved(rsym->reserved() | GOTRel);
+        return;
+      }
+      // set GOT bit
+      rsym->setReserved(rsym->reserved() | ReserveGOT);
+      return;
+
+    case llvm::ELF::R_386_PC32:
+      // We allow R_386_PC32 only if it isn't preemptible.  Otherwise
+      // we will generate writable text section in output.
+      if (!isSymbolPreemptible(*rsym, pLDInfo, pOutput))
+	return;
+
+    default: {
+      llvm::report_fatal_error(llvm::Twine("Unexpected reloc ") +
+                               llvm::Twine((int) pReloc.type()) +
+                               llvm::Twine(" in object file"));
+      break;
+    }
+  } // end switch
+}
+
+void X86GNULDBackend::scanRelocation(Relocation& pReloc,
+                                     const LDSymbol& pInputSym,
+                                     MCLinker& pLinker,
+                                     const MCLDInfo& pLDInfo,
+                                     const Output& pOutput)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
+
+  // Scan relocation type to determine if an GOT/PLT/Dynamic Relocation
+  // entries should be created.
+  // FIXME: Below judgements concern only .so is generated as output
+  // FIXME: Below judgements concren nothing about TLS related relocation
+
+  // A refernece to symbol _GLOBAL_OFFSET_TABLE_ implies that a .got section
+  // is needed
+  if(NULL == m_pGOT && NULL != m_pGOTSymbol) {
+    if(rsym == m_pGOTSymbol->resolveInfo()) {
+      createX86GOT(pLinker, pOutput);
+    }
+  }
+
+  // rsym is local
+  if(rsym->isLocal())
+    scanLocalReloc(pReloc, pInputSym,  pLinker, pLDInfo, pOutput);
+
+  // rsym is external
+  else
+    scanGlobalReloc(pReloc, pInputSym ,pLinker, pLDInfo, pOutput);
+
+}
+
+uint64_t X86GNULDBackend::emitSectionData(const Output& pOutput,
+                                          const LDSection& pSection,
+                                          const MCLDInfo& pInfo,
+                                          MemoryRegion& pRegion) const
+{
+  assert(pRegion.size() && "Size of MemoryRegion is zero!");
+
+  ELFFileFormat* FileFormat = getOutputFormat(pOutput);
+  assert(FileFormat &&
+         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");
+
+  unsigned int EntrySize = 0;
+  uint64_t RegionSize = 0;
+
+  if (&pSection == &(FileFormat->getPLT())) {
+    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
+
+    unsigned char* buffer = pRegion.getBuffer();
+
+    m_pPLT->applyPLT0();
+    m_pPLT->applyPLT1();
+
+    X86PLT::iterator it = m_pPLT->begin();
+    unsigned int plt0_size = llvm::cast<X86PLT0>((*it)).getEntrySize();
+
+    memcpy(buffer, llvm::cast<X86PLT0>((*it)).getContent(), plt0_size);
+    RegionSize += plt0_size;
+    ++it;
+
+    X86PLT1* plt1 = 0;
+    X86PLT::iterator ie = m_pPLT->end();
+    while (it != ie) {
+      plt1 = &(llvm::cast<X86PLT1>(*it));
+      EntrySize = plt1->getEntrySize();
+      memcpy(buffer + RegionSize, plt1->getContent(), EntrySize);
+      RegionSize += EntrySize;
+      ++it;
+    }
+  }
+
+  else if (&pSection == &(FileFormat->getGOT())) {
+    assert(m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
+
+    m_pGOT->applyGOT0(FileFormat->getDynamic().addr());
+
+    uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
+
+    GOTEntry* got = 0;
+    EntrySize = m_pGOT->getEntrySize();
+
+    for (X86GOT::iterator it = m_pGOT->begin(),
+         ie = m_pGOT->end(); it != ie; ++it, ++buffer) {
+      got = &(llvm::cast<GOTEntry>((*it)));
+      *buffer = static_cast<uint32_t>(got->getContent());
+      RegionSize += EntrySize;
+    }
+  }
+
+  else
+    llvm::report_fatal_error("unsupported section name "
+                             + pSection.name() + " !");
+
+  return RegionSize;
+}
+uint32_t X86GNULDBackend::machine() const
+{
+  return llvm::ELF::EM_386;
+}
+
+X86GOT& X86GNULDBackend::getGOT()
+{
+  assert(NULL != m_pGOT);
+  return *m_pGOT;
+}
+
+const X86GOT& X86GNULDBackend::getGOT() const
+{
+  assert(NULL != m_pGOT);
+  return *m_pGOT;
+}
+
+X86PLT& X86GNULDBackend::getPLT()
+{
+  assert(NULL != m_pPLT && "PLT section not exist");
+  return *m_pPLT;
+}
+
+const X86PLT& X86GNULDBackend::getPLT() const
+{
+  assert(NULL != m_pPLT && "PLT section not exist");
+  return *m_pPLT;
+}
+
+OutputRelocSection& X86GNULDBackend::getRelDyn()
+{
+  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
+  return *m_pRelDyn;
+}
+
+const OutputRelocSection& X86GNULDBackend::getRelDyn() const
+{
+  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
+  return *m_pRelDyn;
+}
+
+OutputRelocSection& X86GNULDBackend::getRelPLT()
+{
+  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
+  return *m_pRelPLT;
+}
+
+const OutputRelocSection& X86GNULDBackend::getRelPLT() const
+{
+  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
+  return *m_pRelPLT;
+}
+
+unsigned int
+X86GNULDBackend::getTargetSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const
+{
+  ELFFileFormat* file_format = getOutputFormat(pOutput);
+
+  // FIXME: if command line option, "-z now", is given, we can let the order of
+  // .got and .got.plt be the same as RELRO sections
+  if (&pSectHdr == &file_format->getGOT())
+    return SHO_RELRO_LAST;
+
+  if (&pSectHdr == &file_format->getGOTPLT())
+    return SHO_NON_RELRO_FIRST;
+
+  if (&pSectHdr == &file_format->getPLT())
+    return SHO_PLT;
+
+  return SHO_UNDEFINED;
+}
+
+unsigned int X86GNULDBackend::bitclass() const
+{
+  return 32;
+}
+
+bool X86GNULDBackend::initTargetSectionMap(SectionMap& pSectionMap)
+{
+  return true;
+}
+
+void X86GNULDBackend::initTargetSections(MCLinker& pLinker)
+{
+}
+
+void X86GNULDBackend::initTargetSymbols(MCLinker& pLinker)
+{
+  // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
+  // same name in input
+  m_pGOTSymbol = pLinker.defineSymbol<MCLinker::AsRefered, MCLinker::Resolve>(
+                   "_GLOBAL_OFFSET_TABLE_",
+                   false,
+                   ResolveInfo::Object,
+                   ResolveInfo::Define,
+                   ResolveInfo::Local,
+                   0x0,  // size
+                   0x0,  // value
+                   NULL, // FragRef
+                   ResolveInfo::Hidden);
+}
+
+/// finalizeSymbol - finalize the symbol value
+/// If the symbol's reserved field is not zero, MCLinker will call back this
+/// function to ask the final value of the symbol
+bool X86GNULDBackend::finalizeSymbol(LDSymbol& pSymbol) const
+{
+  return false;
+}
+
+/// allocateCommonSymbols - allocate common symbols in the corresponding
+/// sections.
+/// @refer Google gold linker: common.cc: 214
+bool
+X86GNULDBackend::allocateCommonSymbols(const MCLDInfo& pInfo, MCLinker& pLinker) const
+{
+  // SymbolCategory contains all symbols that must emit to the output files.
+  // We are not like Google gold linker, we don't remember symbols before symbol
+  // resolution. All symbols in SymbolCategory are already resolved. Therefore, we
+  // don't need to care about some symbols may be changed its category due to symbol
+  // resolution.
+  SymbolCategory& symbol_list = pLinker.getOutputSymbols();
+
+  if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
+    return true;
+
+  // addralign := max value of all common symbols
+  uint64_t addralign = 0x0;
+
+  // Due to the visibility, some common symbols may be forcefully local.
+  SymbolCategory::iterator com_sym, com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      if ((*com_sym)->value() > addralign)
+        addralign = (*com_sym)->value();
+    }
+  }
+
+  // global common symbols.
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    if ((*com_sym)->value() > addralign)
+      addralign = (*com_sym)->value();
+  }
+
+  // FIXME: If the order of common symbols is defined, then sort common symbols
+  // com_sym = symbol_list.commonBegin();
+  // std::sort(com_sym, com_end, some kind of order);
+
+  // get or create corresponding BSS LDSection
+  LDSection* bss_sect_hdr = NULL;
+  if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(
+                                   ".tbss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+  else {
+    bss_sect_hdr = &pLinker.getOrCreateOutputSectHdr(".bss",
+                                   LDFileFormat::BSS,
+                                   llvm::ELF::SHT_NOBITS,
+                                   llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC);
+  }
+
+  // get or create corresponding BSS MCSectionData
+  assert(NULL != bss_sect_hdr);
+  llvm::MCSectionData& bss_section = pLinker.getOrCreateSectData(*bss_sect_hdr);
+
+  // allocate all common symbols
+  uint64_t offset = bss_sect_hdr->size();
+
+  // allocate all local common symbols
+  com_end = symbol_list.localEnd();
+  for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
+    if (ResolveInfo::Common == (*com_sym)->desc()) {
+      // We have to reset the description of the symbol here. When doing
+      // incremental linking, the output relocatable object may have common
+      // symbols. Therefore, we can not treat common symbols as normal symbols
+      // when emitting the regular name pools. We must change the symbols'
+      // description here.
+      (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+      llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
+      (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+      uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                         bss_section,
+                                                         (*com_sym)->value());
+      offset += size;
+    }
+  }
+
+  // allocate all global common symbols
+  com_end = symbol_list.commonEnd();
+  for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
+    // We have to reset the description of the symbol here. When doing
+    // incremental linking, the output relocatable object may have common
+    // symbols. Therefore, we can not treat common symbols as normal symbols
+    // when emitting the regular name pools. We must change the symbols'
+    // description here.
+    (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
+    llvm::MCFragment* frag = new llvm::MCFillFragment(0x0, 1, (*com_sym)->size());
+    (*com_sym)->setFragmentRef(new MCFragmentRef(*frag, 0));
+    uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                       bss_section,
+                                                       (*com_sym)->value());
+    offset += size;
+  }
+
+  bss_sect_hdr->setSize(offset);
+  symbol_list.changeCommonsToGlobal();
+  return true;
+}
+
+namespace mcld {
+
+//===----------------------------------------------------------------------===//
+/// createX86LDBackend - the help funtion to create corresponding X86LDBackend
+///
+TargetLDBackend* createX86LDBackend(const llvm::Target& pTarget,
+                                    const std::string& pTriple)
+{
+  Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker is not supported yet");
+    /**
+    return new X86MachOLDBackend(createX86MachOArchiveReader,
+                               createX86MachOObjectReader,
+                               createX86MachOObjectWriter);
+    **/
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker is not supported yet");
+    /**
+    return new X86COFFLDBackend(createX86COFFArchiveReader,
+                               createX86COFFObjectReader,
+                               createX86COFFObjectWriter);
+    **/
+  }
+  return new X86GNULDBackend();
+}
+
+} // namespace of mcld
+
+//=============================
+// Force static initialization.
+extern "C" void LLVMInitializeX86LDBackend() {
+  // Register the linker backend
+  mcld::TargetRegistry::RegisterTargetLDBackend(TheX86Target, createX86LDBackend);
+}
diff --git a/lib/Target/X86/X86LDBackend.h b/lib/Target/X86/X86LDBackend.h
new file mode 100644
index 0000000..d9a4d56
--- /dev/null
+++ b/lib/Target/X86/X86LDBackend.h
@@ -0,0 +1,257 @@
+//===- X86LDBackend.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_LDBACKEND_H
+#define X86_LDBACKEND_H
+
+#include "X86ELFDynamic.h"
+#include "X86GOT.h"
+#include "X86PLT.h"
+#include <mcld/LD/LDSection.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Target/OutputRelocSection.h>
+
+namespace mcld {
+
+//===----------------------------------------------------------------------===//
+/// X86GNULDBackend - linker backend of X86 target of GNU ELF format
+///
+class X86GNULDBackend : public GNULDBackend
+{
+public:
+  /** \enum ReservedEntryType
+   *  \brief The reserved entry type of reserved space in ResolveInfo.
+   *
+   *  This is used for sacnRelocation to record what kinds of entries are
+   *  reserved for this resolved symbol
+   *
+   *  In X86, there are three kinds of entries, GOT, PLT, and dynamic reloction.
+   *  GOT may needs a corresponding relocation to relocate itself, so we
+   *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
+   *  symbol, there might be two kinds of entries reserved for different location.
+   *  For example, reference to the same symbol, one may use GOT and the other may
+   *  use dynamic relocation.
+   *
+   *  bit:  3       2      1     0
+   *   | PLT | GOTRel | GOT | Rel |
+   *
+   *  value    Name         - Description
+   *
+   *  0000     None         - no reserved entry
+   *  0001     ReserveRel   - reserve an dynamic relocation entry
+   *  0010     ReserveGOT   - reserve an GOT entry
+   *  0011     GOTandRel    - For different relocation, we've reserved GOT and
+   *                          Rel for different location.
+   *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
+   *                          relocation entry which relocate this GOT entry
+   *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
+   *                          and relocation entry for different location.
+   *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
+   *                          Dynamic relocation entries
+   *  1001     PLTandRel    - For different relocation, we've reserved PLT and
+   *                          Rel for different location.
+   */
+  enum ReservedEntryType {
+    None         = 0,
+    ReserveRel   = 1,
+    ReserveGOT   = 2,
+    GOTandRel    = 3,
+    GOTRel       = 4,
+    GOTRelandRel = 5,
+    ReservePLT   = 8,
+    PLTandRel    = 9
+  };
+
+  X86GNULDBackend();
+
+  ~X86GNULDBackend();
+
+  RelocationFactory* getRelocFactory();
+
+  uint32_t machine() const;
+
+  bool isLittleEndian() const
+  { return true; }
+
+  X86GOT& getGOT();
+
+  const X86GOT& getGOT() const;
+
+  X86PLT& getPLT();
+
+  const X86PLT& getPLT() const;
+
+  unsigned int bitclass() const;
+
+  /// preLayout - Backend can do any needed modification before layout
+  void doPreLayout(const Output& pOutput,
+                   const MCLDInfo& pInfo,
+                   MCLinker& pLinker);
+
+  /// postLayout -Backend can do any needed modification after layout
+  void doPostLayout(const Output& pOutput,
+                    const MCLDInfo& pInfo,
+                    MCLinker& pLinker);
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  X86ELFDynamic& dynamic();
+
+  /// dynamic - the dynamic section of the target machine.
+  /// Use co-variant return type to return its own dynamic section.
+  const X86ELFDynamic& dynamic() const;
+
+  /// emitSectionData - write out the section data into the memory region.
+  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
+  /// call back target backend to emit the data.
+  ///
+  /// Backends handle the target-special tables (plt, gp,...) by themselves.
+  /// Backend can put the data of the tables in MCSectionData directly
+  ///  - LDSection.getSectionData can get the section data.
+  /// Or, backend can put the data into special data structure
+  ///  - backend can maintain its own map<LDSection, table> to get the table
+  /// from given LDSection.
+  ///
+  /// @param pOutput - the output file
+  /// @param pSection - the given LDSection
+  /// @param pInfo - all options in the command line.
+  /// @param pRegion - the region to write out data
+  /// @return the size of the table in the file.
+  uint64_t emitSectionData(const Output& pOutput,
+                           const LDSection& pSection,
+                           const MCLDInfo& pInfo,
+                           MemoryRegion& pRegion) const;
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  /// FIXME
+  uint8_t OSABI() const
+  { return llvm::ELF::ELFOSABI_NONE; }
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  /// FIXME
+  uint8_t ABIVersion() const
+  { return 0x0; }
+
+  /// flags - the value of ElfXX_Ehdr::e_flags
+  /// FIXME
+  uint64_t flags() const
+  { return 0x0; }
+
+  /// initTargetSectionMap - initialize target dependent section mapping
+  bool initTargetSectionMap(SectionMap& pSectionMap);
+
+  // initRelocFactory - create and initialize RelocationFactory
+  bool initRelocFactory(const MCLinker& pLinker);
+
+  void initTargetSections(MCLinker& pLinker);
+
+  void initTargetSymbols(MCLinker& pLinker);
+
+  /// scanRelocation - determine the empty entries are needed or not and create
+  /// the empty entries if needed.
+  /// For X86, following entries are check to create:
+  /// - GOT entry (for .got and .got.plt sections)
+  /// - PLT entry (for .plt section)
+  /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
+  void scanRelocation(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  OutputRelocSection& getRelDyn();
+
+  const OutputRelocSection& getRelDyn() const;
+
+  OutputRelocSection& getRelPLT();
+
+  const OutputRelocSection& getRelPLT() const;
+
+  /// getTargetSectionOrder - compute the layout order of X86 target sections
+  unsigned int getTargetSectionOrder(const Output& pOutput,
+                                     const LDSection& pSectHdr) const;
+
+  /// finalizeSymbol - finalize the symbol value
+  /// If the symbol's reserved field is not zero, MCLinker will call back this
+  /// function to ask the final value of the symbol
+  bool finalizeSymbol(LDSymbol& pSymbol) const;
+
+  /// allocateCommonSymbols - allocate common symbols in the corresponding
+  /// sections.
+  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
+
+public:
+  bool isSymbolPreemptible(const ResolveInfo& pSym,
+                           const MCLDInfo& pLDInfo,
+                           const Output& pOutput) const;
+
+private:
+  void scanLocalReloc(Relocation& pReloc,
+                      const LDSymbol& pInputSym,
+                      MCLinker& pLinker,
+                      const MCLDInfo& pLDInfo,
+                      const Output& pOutput);
+
+  void scanGlobalReloc(Relocation& pReloc,
+                       const LDSymbol& pInputSym,
+                       MCLinker& pLinker,
+                       const MCLDInfo& pLDInfo,
+                       const Output& pOutput);
+
+  bool isSymbolNeedsPLT(const ResolveInfo& pSym,
+                        const MCLDInfo& pLDInfo,
+                        const Output& pOutput) const;
+
+  bool isSymbolNeedsDynRel(const ResolveInfo& pSym,
+                           const Output& pOutput,
+                           bool isAbsReloc) const;
+
+  void updateAddend(Relocation& pReloc,
+                    const LDSymbol& pInputSym,
+                    const Layout& pLayout) const;
+
+  void createX86GOT(MCLinker& pLinker, const Output& pOutput);
+  void createX86PLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
+  void createX86RelDyn(MCLinker& pLinker, const Output& pOutput);
+
+  ELFFileFormat* getOutputFormat(const Output& pOutput) const;
+
+private:
+  RelocationFactory* m_pRelocFactory;
+  X86GOT* m_pGOT;
+  X86PLT* m_pPLT;
+  /// m_RelDyn - dynamic relocation table of .rel.dyn
+  OutputRelocSection* m_pRelDyn;
+  /// m_RelPLT - dynamic relocation table of .rel.plt
+  OutputRelocSection* m_pRelPLT;
+
+  X86ELFDynamic* m_pDynamic;
+  LDSymbol* m_pGOTSymbol;
+};
+
+//===----------------------------------------------------------------------===//
+/// X86MachOLDBackend - linker backend of X86 target of MachO format
+///
+/**
+class X86MachOLDBackend : public DarwinX86LDBackend
+{
+public:
+  X86MachOLDBackend();
+  ~X86MachOLDBackend();
+
+private:
+  MCMachOTargetArchiveReader *createTargetArchiveReader() const;
+  MCMachOTargetObjectReader *createTargetObjectReader() const;
+  MCMachOTargetObjectWriter *createTargetObjectWriter() const;
+
+};
+**/
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86PLT.cpp b/lib/Target/X86/X86PLT.cpp
new file mode 100644
index 0000000..c5e05f9
--- /dev/null
+++ b/lib/Target/X86/X86PLT.cpp
@@ -0,0 +1,279 @@
+//===- X86PLT.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "X86GOT.h"
+#include "X86PLT.h"
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <new>
+
+namespace {
+
+const uint8_t x86_dyn_plt0[] = {
+  0xff, 0xb3, 0x04, 0, 0, 0,		// pushl  0x4(%ebx)
+  0xff, 0xa3, 0x08, 0, 0, 0,		// jmp    *0x8(%ebx)
+  0xf, 0x1f, 0x4, 0			// nopl   0(%eax)
+};
+
+const uint8_t x86_dyn_plt1[] = {
+  0xff, 0xa3, 0, 0, 0, 0,		// jmp    *sym@GOT(%ebx)
+  0x68, 0, 0, 0, 0,			// pushl  $offset
+  0xe9, 0, 0, 0, 0			// jmp    plt0
+};
+
+const uint8_t x86_exec_plt0[] = {
+  0xff, 0x35, 0, 0, 0, 0,		// pushl  .got + 4
+  0xff, 0x25, 0, 0, 0, 0,		// jmp    *(.got + 8)
+  0xf, 0x1f, 0x4, 0			// nopl   0(%eax)
+};
+
+const uint8_t x86_exec_plt1[] = {
+  0xff, 0x25, 0, 0, 0, 0,		// jmp    *(sym in .got)
+  0x68, 0, 0, 0, 0,			// pushl  $offset
+  0xe9, 0, 0, 0, 0			// jmp    plt0
+};
+
+}
+
+namespace mcld {
+
+X86PLT0::X86PLT0(llvm::MCSectionData* pParent, unsigned int pSize)
+  : PLTEntry(pSize, pParent) { }
+
+X86PLT1::X86PLT1(llvm::MCSectionData* pParent, unsigned int pSize)
+  : PLTEntry(pSize, pParent) { }
+
+//===----------------------------------------------------------------------===//
+// X86PLT
+
+X86PLT::X86PLT(LDSection& pSection,
+               llvm::MCSectionData& pSectionData,
+               X86GOT &pGOTPLT,
+	       const Output& pOutput)
+  : PLT(pSection, pSectionData), m_GOT(pGOTPLT), m_PLTEntryIterator()
+{
+  assert (Output::DynObj == pOutput.type() || Output::Exec == pOutput.type());
+  if (Output::DynObj == pOutput.type()) {
+      m_PLT0 = x86_dyn_plt0;
+      m_PLT1 = x86_dyn_plt1;
+      m_PLT0Size = sizeof (x86_dyn_plt0);
+      m_PLT1Size = sizeof (x86_dyn_plt1);
+  }
+  else {
+      m_PLT0 = x86_exec_plt0;
+      m_PLT1 = x86_exec_plt1;
+      m_PLT0Size = sizeof (x86_exec_plt0);
+      m_PLT1Size = sizeof (x86_exec_plt1);
+  }
+  X86PLT0* plt0_entry = new X86PLT0(&m_SectionData, m_PLT0Size);
+
+  m_Section.setSize(m_Section.size() + plt0_entry->getEntrySize());
+
+  m_PLTEntryIterator = pSectionData.begin();
+}
+
+X86PLT::~X86PLT()
+{
+}
+
+void X86PLT::reserveEntry(size_t pNum)
+{
+  X86PLT1* plt1_entry = 0;
+  GOTEntry* got_entry = 0;
+
+  for (size_t i = 0; i < pNum; ++i) {
+    plt1_entry = new (std::nothrow) X86PLT1(&m_SectionData, m_PLT1Size);
+
+    if (!plt1_entry)
+      llvm::report_fatal_error("Allocating new memory for X86PLT1 failed!");
+
+    m_Section.setSize(m_Section.size() + plt1_entry->getEntrySize());
+
+    got_entry= new (std::nothrow) GOTEntry(0, m_GOT.getEntrySize(),
+                                           &(m_GOT.m_SectionData));
+
+    if (!got_entry)
+      llvm::report_fatal_error("Allocating new memory for GOT failed!");
+
+    m_GOT.m_Section.setSize(m_GOT.m_Section.size() + m_GOT.f_EntrySize);
+
+    ++(m_GOT.m_GOTPLTNum);
+    ++(m_GOT.m_GeneralGOTIterator);
+  }
+}
+
+PLTEntry* X86PLT::getPLTEntry(const ResolveInfo& pSymbol, bool& pExist)
+{
+   X86PLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol];
+
+   pExist = 1;
+
+   if (!PLTEntry) {
+     GOTEntry *&GOTPLTEntry = m_GOT.m_GOTPLTMap[&pSymbol];
+     assert(!GOTPLTEntry && "PLT entry and got.plt entry doesn't match!");
+
+     pExist = 0;
+
+     // This will skip PLT0.
+     ++m_PLTEntryIterator;
+     assert(m_PLTEntryIterator != m_SectionData.end() &&
+            "The number of PLT Entries and ResolveInfo doesn't match");
+     ++(m_GOT.m_GOTPLTIterator);
+
+     PLTEntry = llvm::cast<X86PLT1>(&(*m_PLTEntryIterator));
+     GOTPLTEntry = llvm::cast<GOTEntry>(&(*(m_GOT.m_GOTPLTIterator)));
+   }
+
+   return PLTEntry;
+}
+
+GOTEntry* X86PLT::getGOTPLTEntry(const ResolveInfo& pSymbol, bool& pExist)
+{
+   GOTEntry *&GOTPLTEntry = m_GOT.m_GOTPLTMap[&pSymbol];
+
+   pExist = 1;
+
+   if (!GOTPLTEntry) {
+     X86PLT1 *&PLTEntry = m_PLTEntryMap[&pSymbol];
+     assert(!PLTEntry && "PLT entry and got.plt entry doesn't match!");
+
+     pExist = 0;
+
+     // This will skip PLT0.
+     ++m_PLTEntryIterator;
+     assert(m_PLTEntryIterator != m_SectionData.end() &&
+            "The number of PLT Entries and ResolveInfo doesn't match");
+     ++(m_GOT.m_GOTPLTIterator);
+
+     PLTEntry = llvm::cast<X86PLT1>(&(*m_PLTEntryIterator));
+     GOTPLTEntry = llvm::cast<GOTEntry>(&(*(m_GOT.m_GOTPLTIterator)));
+   }
+
+   return GOTPLTEntry;
+}
+
+X86PLT0* X86PLT::getPLT0() const {
+
+  iterator first = m_SectionData.getFragmentList().begin();
+  iterator end = m_SectionData.getFragmentList().end();
+
+  assert(first!=end && "FragmentList is empty, getPLT0 failed!");
+
+  X86PLT0* plt0 = &(llvm::cast<X86PLT0>(*first));
+
+  return plt0;
+}
+
+// FIXME: It only works on little endian machine.
+void X86PLT::applyPLT0() {
+
+  iterator first = m_SectionData.getFragmentList().begin();
+  iterator end = m_SectionData.getFragmentList().end();
+
+  assert(first!=end && "FragmentList is empty, applyPLT0 failed!");
+
+  X86PLT0* plt0 = &(llvm::cast<X86PLT0>(*first));
+
+  unsigned char* data = 0;
+  data = static_cast<unsigned char*>(malloc(plt0->getEntrySize()));
+
+  if (!data)
+    llvm::report_fatal_error("Allocating new memory for plt0 failed!");
+
+  memcpy(data, m_PLT0, plt0->getEntrySize());
+
+  if (m_PLT0 == x86_exec_plt0) {
+    uint64_t got_base = m_GOT.getSection().addr();
+    assert(got_base && ".got base address is NULL!");
+    uint32_t *offset = reinterpret_cast<uint32_t*>(data + 2);
+    *offset = got_base + 4;
+    offset = reinterpret_cast<uint32_t*>(data + 8);
+    *offset = got_base + 8;
+  }
+
+  plt0->setContent(data);
+}
+
+// FIXME: It only works on little endian machine.
+void X86PLT::applyPLT1() {
+
+  uint64_t plt_base = m_Section.addr();
+  assert(plt_base && ".plt base address is NULL!");
+
+  uint64_t got_base = m_GOT.getSection().addr();
+  assert(got_base && ".got base address is NULL!");
+
+  X86PLT::iterator it = m_SectionData.begin();
+  X86PLT::iterator ie = m_SectionData.end();
+  assert(it!=ie && "FragmentList is empty, applyPLT1 failed!");
+
+  uint64_t GOTEntrySize = m_GOT.getEntrySize();
+
+  // Skip GOT0
+  uint64_t GOTEntryOffset = GOTEntrySize * X86GOT0Num;
+
+  //skip PLT0
+  uint64_t PLTEntryOffset = m_PLT0Size;
+  ++it;
+
+  X86PLT1* plt1 = 0;
+
+  uint64_t PLTRelOffset = 0;
+
+  while (it != ie) {
+    plt1 = &(llvm::cast<X86PLT1>(*it));
+    unsigned char *data;
+    data = static_cast<unsigned char*>(malloc(plt1->getEntrySize()));
+
+    if (!data)
+      llvm::report_fatal_error("Allocating new memory for plt1 failed!");
+
+    memcpy(data, m_PLT1, plt1->getEntrySize());
+
+    uint32_t* offset;
+
+    offset = reinterpret_cast<uint32_t*>(data + 2);
+    *offset = GOTEntryOffset;
+    GOTEntryOffset += GOTEntrySize;
+
+    offset = reinterpret_cast<uint32_t*>(data + 7);
+    *offset = PLTRelOffset;
+    PLTRelOffset += sizeof (llvm::ELF::Elf32_Rel);
+
+    offset = reinterpret_cast<uint32_t*>(data + 12);
+    *offset = -(PLTEntryOffset + 12 + 4);
+    PLTEntryOffset += m_PLT1Size;
+
+    plt1->setContent(data);
+    ++it;
+  }
+
+  unsigned int GOTPLTNum = m_GOT.getGOTPLTNum();
+
+  if (GOTPLTNum != 0) {
+    X86GOT::iterator gotplt_it = m_GOT.getLastGOT0();
+    X86GOT::iterator list_ie = m_GOT.getSectionData().getFragmentList().end();
+
+    ++gotplt_it;
+    uint64_t PLTEntryAddress = plt_base + m_PLT0Size;
+    for (unsigned int i = 0; i < GOTPLTNum; ++i) {
+      if (gotplt_it == list_ie)
+        llvm::report_fatal_error(
+          "The number of got.plt entries is inconsistent!");
+
+      llvm::cast<GOTEntry>(*gotplt_it).setContent(PLTEntryAddress + 6);
+      PLTEntryAddress += m_PLT1Size;
+      ++gotplt_it;
+    }
+  }
+}
+
+} // end namespace mcld
+
diff --git a/lib/Target/X86/X86PLT.h b/lib/Target/X86/X86PLT.h
new file mode 100644
index 0000000..dd72f52
--- /dev/null
+++ b/lib/Target/X86/X86PLT.h
@@ -0,0 +1,91 @@
+//===- X86PLT.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_PLT_H
+#define X86_PLT_H
+
+#include <mcld/Target/PLT.h>
+
+namespace mcld {
+
+class X86GOT;
+class GOTEntry;
+class Output;
+
+class X86PLT0 : public PLTEntry {
+public:
+  X86PLT0(llvm::MCSectionData* pParent, unsigned int pSize);
+};
+
+class X86PLT1 : public PLTEntry {
+public:
+  X86PLT1(llvm::MCSectionData* pParent, unsigned int pSize);
+};
+
+/** \class X86PLT
+ *  \brief X86 Procedure Linkage Table
+ */
+class X86PLT : public PLT
+{
+  typedef llvm::DenseMap<const ResolveInfo*, X86PLT1*> SymbolIndexType;
+
+public:
+  typedef llvm::MCSectionData::iterator iterator;
+  typedef llvm::MCSectionData::const_iterator const_iterator;
+
+public:
+  X86PLT(LDSection& pSection,
+         llvm::MCSectionData& pSectionData,
+         X86GOT& pGOTPLT,
+	 const Output& pOutput);
+  ~X86PLT();
+
+// Override virtual function.
+public:
+
+  // reserveEntry is X86GOT friend function.
+  void reserveEntry(size_t pNum = 1) ;
+
+  PLTEntry* getPLTEntry(const ResolveInfo& pSymbol, bool& pExist) ;
+
+  GOTEntry* getGOTPLTEntry(const ResolveInfo& pSymbol, bool& pExist);
+
+public:
+
+  iterator begin() { return m_SectionData.begin(); }
+
+  const_iterator begin() const { return m_SectionData.begin(); }
+
+  iterator end() { return m_SectionData.end(); }
+
+  const_iterator end() const { return m_SectionData.end(); }
+
+  X86PLT0* getPLT0() const;
+
+  void applyPLT0();
+
+  void applyPLT1();
+
+private:
+  X86GOT& m_GOT;
+
+  // Used by getEntry() for mapping a ResolveInfo
+  // instance to a PLT1 Entry.
+  iterator m_PLTEntryIterator;
+
+  SymbolIndexType m_PLTEntryMap;
+
+  const uint8_t *m_PLT0;
+  const uint8_t *m_PLT1;
+  unsigned int m_PLT0Size;
+  unsigned int m_PLT1Size;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/lib/Target/X86/X86RelocationFactory.cpp b/lib/Target/X86/X86RelocationFactory.cpp
new file mode 100644
index 0000000..15b9a6b
--- /dev/null
+++ b/lib/Target/X86/X86RelocationFactory.cpp
@@ -0,0 +1,361 @@
+//===- X86RelocationFactory.cpp -------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <llvm/ADT/Twine.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/DataTypes.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/LD/Layout.h>
+
+#include "X86RelocationFactory.h"
+#include "X86RelocationFunctions.h"
+
+using namespace mcld;
+
+DECL_X86_APPLY_RELOC_FUNCS
+
+//===--------------------------------------------------------------------===//
+// X86RelocationFactory
+X86RelocationFactory::X86RelocationFactory(size_t pNum,
+                                           X86GNULDBackend& pParent)
+  : RelocationFactory(pNum),
+    m_Target(pParent) {
+}
+
+X86RelocationFactory::~X86RelocationFactory()
+{
+}
+
+void X86RelocationFactory::applyRelocation(Relocation& pRelocation,
+                                           const MCLDInfo& pLDInfo)
+{
+  Relocation::Type type = pRelocation.type();
+
+  /// the prototype of applying function
+  typedef Result (*ApplyFunctionType)(Relocation& pReloc,
+				      const MCLDInfo& pLDInfo,
+                                      X86RelocationFactory& pParent);
+
+  // the table entry of applying functions
+  struct ApplyFunctionTriple {
+    ApplyFunctionType func;
+    unsigned int type;
+    const char* name;
+  };
+
+  // declare the table of applying functions
+  static ApplyFunctionTriple apply_functions[] = {
+    DECL_X86_APPLY_RELOC_FUNC_PTRS
+  };
+
+  if (type >= sizeof (apply_functions) / sizeof (apply_functions[0]) ) {
+    llvm::report_fatal_error(llvm::Twine("Unknown relocation type ") +
+			     llvm::Twine((int) type) +
+			     llvm::Twine(" to symbol `") +
+                             pRelocation.symInfo()->name() +
+                             llvm::Twine("'."));
+    return;
+  }
+
+  // apply the relocation
+  Result result = apply_functions[type].func(pRelocation, pLDInfo, *this);
+
+  // check result
+  if (Overflow == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' causes overflow. on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+
+  if (BadReloc == result) {
+    llvm::report_fatal_error(llvm::Twine("Applying relocation `") +
+                             llvm::Twine(apply_functions[type].name) +
+                             llvm::Twine("' encounters unexpected opcode. "
+                                         "on symbol: `") +
+                             llvm::Twine(pRelocation.symInfo()->name()) +
+                             llvm::Twine("'."));
+    return;
+  }
+}
+
+
+
+// non-member functions
+
+//=========================================//
+// Relocation helper function              //
+//=========================================//
+
+// Check if symbol can use relocation R_386_RELATIVE
+static bool
+helper_use_relative_reloc(const ResolveInfo& pSym,
+                          const MCLDInfo& pLDInfo,
+                          const X86RelocationFactory& pFactory)
+
+{
+  // if symbol is dynamic or undefine or preemptible
+  if(pSym.isDyn() ||
+     pSym.isUndef() ||
+     pFactory.getTarget().isSymbolPreemptible(pSym, pLDInfo, pLDInfo.output()))
+    return false;
+  return true;
+}
+
+static
+GOTEntry& helper_get_GOT_and_init(Relocation& pReloc,
+                                  const MCLDInfo& pLDInfo,
+                                  X86RelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  X86GNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  GOTEntry& got_entry = *ld_backend.getGOT().getEntry(*rsym, exist);
+  if (!exist) {
+    // If we first get this GOT entry, we should initialize it.
+    if (rsym->reserved() & X86GNULDBackend::ReserveGOT) {
+      // No corresponding dynamic relocation, initialize to the symbol value.
+      got_entry.setContent(pReloc.symValue());
+    }
+    else if (rsym->reserved() & X86GNULDBackend::GOTRel) {
+      // Initialize corresponding dynamic relocation.
+      Relocation& rel_entry =
+        *ld_backend.getRelDyn().getEntry(*rsym, true, exist);
+      assert(!exist && "GOT entry not exist, but DynRel entry exist!");
+      if(helper_use_relative_reloc(*rsym, pLDInfo, pParent)) {
+        // Initialize got entry to target symbol address
+        got_entry.setContent(pReloc.symValue());
+        rel_entry.setType(llvm::ELF::R_386_RELATIVE);
+        rel_entry.setSymInfo(0);
+      }
+      else {
+        got_entry.setContent(0);
+        rel_entry.setType(llvm::ELF::R_386_GLOB_DAT);
+        rel_entry.setSymInfo(rsym);
+      }
+      rel_entry.targetRef().assign(got_entry);
+    }
+    else {
+      llvm::report_fatal_error("No GOT entry reserved for GOT type relocation!");
+    }
+  }
+  return got_entry;
+}
+
+
+static
+X86RelocationFactory::Address helper_GOT_ORG(X86RelocationFactory& pParent)
+{
+  return pParent.getTarget().getGOT().getSection().addr();
+}
+
+
+static
+X86RelocationFactory::Address helper_GOT(Relocation& pReloc,
+                                         const MCLDInfo& pLDInfo,
+                                         X86RelocationFactory& pParent)
+{
+  GOTEntry& got_entry = helper_get_GOT_and_init(pReloc, pLDInfo,  pParent);
+  return helper_GOT_ORG(pParent) + pParent.getLayout().getOutputOffset(got_entry);
+}
+
+
+static
+PLTEntry& helper_get_PLT_and_init(Relocation& pReloc,
+                                  X86RelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  X86GNULDBackend& ld_backend = pParent.getTarget();
+
+  bool exist;
+  PLTEntry& plt_entry = *ld_backend.getPLT().getPLTEntry(*rsym, exist);
+  if (!exist) {
+    // If we first get this PLT entry, we should initialize it.
+    if (rsym->reserved() & X86GNULDBackend::ReservePLT) {
+      GOTEntry& gotplt_entry =
+        *ld_backend.getPLT().getGOTPLTEntry(*rsym, exist);
+      // Initialize corresponding dynamic relocation.
+      Relocation& rel_entry =
+        *ld_backend.getRelPLT().getEntry(*rsym, true, exist);
+      assert(!exist && "PLT entry not exist, but DynRel entry exist!");
+      rel_entry.setType(llvm::ELF::R_386_JUMP_SLOT);
+      rel_entry.targetRef().assign(gotplt_entry);
+      rel_entry.setSymInfo(rsym);
+    }
+    else {
+      llvm::report_fatal_error("No PLT entry reserved for PLT type relocation!");
+    }
+  }
+  return plt_entry;
+}
+
+
+
+static
+X86RelocationFactory::Address helper_PLT_ORG(X86RelocationFactory& pParent)
+{
+  return pParent.getTarget().getPLT().getSection().addr();
+}
+
+
+static
+X86RelocationFactory::Address helper_PLT(Relocation& pReloc,
+                                         X86RelocationFactory& pParent)
+{
+  PLTEntry& plt_entry = helper_get_PLT_and_init(pReloc, pParent);
+  return helper_PLT_ORG(pParent) + pParent.getLayout().getOutputOffset(plt_entry);
+}
+
+// Get an relocation entry in .rel.dyn and set its type to pType,
+// its FragmentRef to pReloc->targetFrag() and its ResolveInfo to pReloc->symInfo()
+static
+void helper_DynRel(Relocation& pReloc,
+                   X86RelocationFactory::Type pType,
+                   X86RelocationFactory& pParent)
+{
+  // rsym - The relocation target symbol
+  ResolveInfo* rsym = pReloc.symInfo();
+  X86GNULDBackend& ld_backend = pParent.getTarget();
+  bool exist;
+
+  Relocation& rel_entry =
+    *ld_backend.getRelDyn().getEntry(*rsym, false, exist);
+  rel_entry.setType(pType);
+  rel_entry.targetRef() = pReloc.targetRef();
+
+  if(pType == llvm::ELF::R_386_RELATIVE)
+    rel_entry.setSymInfo(0);
+  else
+    rel_entry.setSymInfo(rsym);
+}
+
+
+//=========================================//
+// Each relocation function implementation //
+//=========================================//
+
+// R_386_NONE
+X86RelocationFactory::Result none(Relocation& pReloc,
+                                  const MCLDInfo& pLDInfo,
+                                  X86RelocationFactory& pParent)
+{
+  return X86RelocationFactory::OK;
+}
+
+// R_386_32: S + A
+X86RelocationFactory::Result abs32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   X86RelocationFactory& pParent)
+{
+  ResolveInfo* rsym = pReloc.symInfo();
+  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  RelocationFactory::DWord S = pReloc.symValue();
+
+  if(rsym->isLocal() && (rsym->reserved() & X86GNULDBackend::ReserveRel)) {
+    helper_DynRel(pReloc, llvm::ELF::R_386_RELATIVE, pParent);
+    pReloc.target() = S + A;
+    return X86RelocationFactory::OK;
+  }
+  else if(!rsym->isLocal()) {
+    if(rsym->reserved() & X86GNULDBackend::ReservePLT) {
+      S = helper_PLT(pReloc, pParent);
+      pReloc.target() = S + A;
+    }
+    if(rsym->reserved() & X86GNULDBackend::ReserveRel) {
+      if(helper_use_relative_reloc(*rsym, pLDInfo, pParent) ) {
+        helper_DynRel(pReloc, llvm::ELF::R_386_RELATIVE, pParent);
+      }
+      else {
+        helper_DynRel(pReloc, pReloc.type(), pParent);
+        return X86RelocationFactory::OK;
+      }
+    }
+  }
+
+  // perform static relocation
+  pReloc.target() = S + A;
+  return X86RelocationFactory::OK;
+}
+
+// R_386_PC32: S + A - P
+X86RelocationFactory::Result rel32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   X86RelocationFactory& pParent)
+{
+  // perform static relocation
+  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  pReloc.target() = pReloc.symValue() + A
+      - pReloc.place(pParent.getLayout());
+  return X86RelocationFactory::OK;
+}
+
+// R_386_GOTOFF: S + A - GOT_ORG
+X86RelocationFactory::Result gotoff32(Relocation& pReloc,
+                                      const MCLDInfo& pLDInfo,
+                                      X86RelocationFactory& pParent)
+{
+  RelocationFactory::DWord A = pReloc.target() + pReloc.addend();
+  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  X86RelocationFactory::Address S = pReloc.symValue();
+
+  pReloc.target() = S + A - GOT_ORG;
+  return X86RelocationFactory::OK;
+}
+
+// R_386_GOTPC: GOT_ORG + A - P
+X86RelocationFactory::Result gotpc32(Relocation& pReloc,
+                                     const MCLDInfo& pLDInfo,
+                                     X86RelocationFactory& pParent)
+{
+  RelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
+  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  // Apply relocation.
+  pReloc.target() = GOT_ORG + A - pReloc.place(pParent.getLayout());
+  return X86RelocationFactory::OK;
+}
+
+// R_386_GOT32: GOT(S) + A - GOT_ORG
+X86RelocationFactory::Result got32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   X86RelocationFactory& pParent)
+{
+  if(!(pReloc.symInfo()->reserved()
+       & (X86GNULDBackend::ReserveGOT |X86GNULDBackend::GOTRel))) {
+    return X86RelocationFactory::BadReloc;
+  }
+  X86RelocationFactory::Address GOT_S   = helper_GOT(pReloc, pLDInfo, pParent);
+  RelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
+  X86RelocationFactory::Address GOT_ORG = helper_GOT_ORG(pParent);
+  // Apply relocation.
+  pReloc.target() = GOT_S + A - GOT_ORG;
+  return X86RelocationFactory::OK;
+}
+
+// R_386_PLT32: PLT(S) + A - P
+X86RelocationFactory::Result plt32(Relocation& pReloc,
+                                   const MCLDInfo& pLDInfo,
+                                   X86RelocationFactory& pParent)
+{
+  // PLT_S depends on if there is a PLT entry.
+  X86RelocationFactory::Address PLT_S;
+  if((pReloc.symInfo()->reserved() & X86GNULDBackend::ReservePLT))
+    PLT_S = helper_PLT(pReloc, pParent);
+  else
+    PLT_S = pReloc.symValue();
+  RelocationFactory::DWord   A       = pReloc.target() + pReloc.addend();
+  X86RelocationFactory::Address P = pReloc.place(pParent.getLayout());
+  pReloc.target() = PLT_S + A - P;
+  return X86RelocationFactory::OK;
+}
diff --git a/lib/Target/X86/X86RelocationFactory.h b/lib/Target/X86/X86RelocationFactory.h
new file mode 100644
index 0000000..6a6c372
--- /dev/null
+++ b/lib/Target/X86/X86RelocationFactory.h
@@ -0,0 +1,58 @@
+//===-  X86RelocationFactory.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef X86_RELOCATION_FACTORY_H
+#define X86_RELOCATION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/RelocationFactory.h>
+#include <mcld/Target/GOT.h>
+#include "X86LDBackend.h"
+
+namespace mcld
+{
+
+/** \class X86RelocationFactory
+ *  \brief X86RelocationFactory creates and destroys the X86 relocations.
+ *
+ */
+class X86RelocationFactory : public RelocationFactory
+{
+public:
+  /** \enum Reloc
+   *  \brief Reloc is the result of applying functions.
+   */
+  enum Result
+  {
+    OK,
+    Overflow,
+    BadReloc
+  };
+
+public:
+  X86RelocationFactory(size_t pNum, X86GNULDBackend& pParent);
+  ~X86RelocationFactory();
+
+  void applyRelocation(Relocation& pRelocation, const MCLDInfo& pLDInfo);
+
+  X86GNULDBackend& getTarget()
+  { return m_Target; }
+
+  const X86GNULDBackend& getTarget() const
+  { return m_Target; }
+
+private:
+  X86GNULDBackend& m_Target;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/lib/Target/X86/X86RelocationFunctions.h b/lib/Target/X86/X86RelocationFunctions.h
new file mode 100644
index 0000000..46d4f34
--- /dev/null
+++ b/lib/Target/X86/X86RelocationFunctions.h
@@ -0,0 +1,36 @@
+//===- X86RelocationFunction.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DECL_X86_APPLY_RELOC_FUNC(Name) \
+static X86RelocationFactory::Result Name    (Relocation& pEntry, \
+					     const MCLDInfo& pLDInfo, \
+					     X86RelocationFactory& pParent);
+
+#define DECL_X86_APPLY_RELOC_FUNCS \
+DECL_X86_APPLY_RELOC_FUNC(none)             \
+DECL_X86_APPLY_RELOC_FUNC(abs32)            \
+DECL_X86_APPLY_RELOC_FUNC(rel32)            \
+DECL_X86_APPLY_RELOC_FUNC(plt32)            \
+DECL_X86_APPLY_RELOC_FUNC(got32)            \
+DECL_X86_APPLY_RELOC_FUNC(gotoff32)	    \
+DECL_X86_APPLY_RELOC_FUNC(gotpc32)
+
+
+#define DECL_X86_APPLY_RELOC_FUNC_PTRS \
+  { &none,               0, "R_386_NONE"              },  \
+  { &abs32,              1, "R_386_32"                },  \
+  { &rel32,              2, "R_386_PC32"              },  \
+  { &got32,              3, "R_386_GOT32"             },  \
+  { &plt32,              4, "R_386_PLT32"             },  \
+  { &none,               5, "R_386_COPY"              },  \
+  { &none,               6, "R_386_GLOB_DAT"          },  \
+  { &none,               7, "R_386_JMP_SLOT"          },  \
+  { &none,               8, "R_386_RELATIVE"          },  \
+  { &gotoff32,           9, "R_386_GOTOFF"            },  \
+  { &gotpc32,           10, "R_386_GOTPC"             }
diff --git a/lib/Target/X86/X86SectLinker.cpp b/lib/Target/X86/X86SectLinker.cpp
new file mode 100644
index 0000000..793b97b
--- /dev/null
+++ b/lib/Target/X86/X86SectLinker.cpp
@@ -0,0 +1,47 @@
+//===- X86SectLinker.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <llvm/ADT/Triple.h>
+#include <mcld/Support/TargetRegistry.h>
+
+#include "X86.h"
+#include "X86AndroidSectLinker.h"
+#include "X86ELFSectLinker.h"
+
+using namespace mcld;
+
+namespace mcld {
+//===----------------------------------------------------------------------===//
+/// createX86SectLinker - the help funtion to create corresponding X86SectLinker
+///
+SectLinker* createX86SectLinker(const std::string &pTriple,
+                                SectLinkerOption &pOption,
+                                mcld::TargetLDBackend &pLDBackend)
+{
+  Triple theTriple(pTriple);
+  if (theTriple.isOSDarwin()) {
+    assert(0 && "MachO linker has not supported yet");
+  }
+  if (theTriple.isOSWindows()) {
+    assert(0 && "COFF linker has not supported yet");
+  }
+
+  // For now, use Android SectLinker directly
+  return new X86AndroidSectLinker(pOption,
+                                  pLDBackend);
+}
+
+} // namespace of mcld
+
+//==========================
+// X86SectLinker
+extern "C" void LLVMInitializeX86SectLinker() {
+  // Register the linker frontend
+  mcld::TargetRegistry::RegisterSectLinker(TheX86Target, createX86SectLinker);
+}
+
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
new file mode 100644
index 0000000..b036137
--- /dev/null
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -0,0 +1,34 @@
+//===- X86TargetMachine.cpp -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "X86TargetMachine.h"
+
+#include "mcld/Target/TargetMachine.h"
+#include "mcld/Support/TargetRegistry.h"
+#include "mcld/MC/MCLDInfo.h"
+#include "X86.h"
+
+extern "C" void LLVMInitializeX86LDTarget() {
+  // Register createTargetMachine function pointer to mcld::Target
+  mcld::RegisterTargetMachine<mcld::X86TargetMachine> X(mcld::TheX86Target);
+}
+
+mcld::X86TargetMachine::X86TargetMachine(llvm::TargetMachine& pPM,
+                                         const mcld::Target &pTarget,
+                                         const std::string& pTriple)
+  : mcld::LLVMTargetMachine(pPM, pTarget, pTriple) {
+  // arg1 - the number of total attributes
+  // arg2 - the most possible number of input files
+  m_pLDInfo = new MCLDInfo(pTriple, 32, 64);
+}
+
+mcld::X86TargetMachine::~X86TargetMachine()
+{
+  delete m_pLDInfo;
+}
+
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
new file mode 100644
index 0000000..3ba9e59
--- /dev/null
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -0,0 +1,40 @@
+//===- X86TargetMachine.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_X86_TARGET_MACHINE_H
+#define MCLD_X86_TARGET_MACHINE_H
+#include "mcld/Target/TargetMachine.h"
+#include "X86.h"
+
+namespace mcld
+{
+
+class X86TargetMachine : public LLVMTargetMachine
+{
+protected:
+  MCLDInfo *m_pLDInfo;
+
+public:
+  X86TargetMachine(llvm::TargetMachine &pTM,
+                       const mcld::Target &pTarget,
+                       const std::string &pTriple);
+
+  virtual ~X86TargetMachine();
+
+  mcld::MCLDInfo& getLDInfo()
+  { return *m_pLDInfo; }
+
+  const mcld::MCLDInfo& getLDInfo() const
+  { return *m_pLDInfo; }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/m4/gtest.m4 b/m4/gtest.m4
new file mode 100644
index 0000000..6598ba7
--- /dev/null
+++ b/m4/gtest.m4
@@ -0,0 +1,74 @@
+dnl GTEST_LIB_CHECK([minimum version [,
+dnl                  action if found [,action if not found]]])
+dnl
+dnl Check for the presence of the Google Test library, optionally at a minimum
+dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines
+dnl standard variables for substitution including GTEST_CPPFLAGS,
+dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines
+dnl GTEST_VERSION as the version of Google Test found. Finally, it provides
+dnl optional custom action slots in the event GTEST is found or not.
+AC_DEFUN([GTEST_LIB_CHECK],
+[
+dnl Provide a flag to enable or disable Google Test usage.
+AC_ARG_ENABLE([gtest],
+  [AS_HELP_STRING([--enable-gtest],
+                  [Enable tests using the Google C++ Testing Framework.
+                  (Default is enabled.)])],
+  [],
+  [enable_gtest=])
+AC_ARG_VAR([GTEST_CONFIG],
+           [The exact path of Google Test's 'gtest-config' script.])
+AC_ARG_VAR([GTEST_CPPFLAGS],
+           [C-like preprocessor flags for Google Test.])
+AC_ARG_VAR([GTEST_CXXFLAGS],
+           [C++ compile flags for Google Test.])
+AC_ARG_VAR([GTEST_LDFLAGS],
+           [Linker path and option flags for Google Test.])
+AC_ARG_VAR([GTEST_LIBS],
+           [Library linking flags for Google Test.])
+AC_ARG_VAR([GTEST_VERSION],
+           [The version of Google Test available.])
+HAVE_GTEST="no"
+AS_IF([test "x${enable_gtest}" != "xno"],
+  [AC_MSG_CHECKING([for 'gtest-config'])
+   AS_IF([test "x${enable_gtest}" != "xyes"],
+     [AS_IF([test -x "${enable_gtest}/scripts/gtest-config"],
+        [GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"],
+        [GTEST_CONFIG="${enable_gtest}/bin/gtest-config"])
+      AS_IF([test -x "${GTEST_CONFIG}"], [],
+        [AC_MSG_RESULT([no])
+         AC_MSG_ERROR([dnl
+Unable to locate either a built or installed Google Test.
+The specific location '${enable_gtest}' was provided for a built or installed
+Google Test, but no 'gtest-config' script could be found at this location.])
+         ])],
+     [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
+   AS_IF([test -x "${GTEST_CONFIG}"],
+     [AC_MSG_RESULT([${GTEST_CONFIG}])
+      m4_ifval([$1],
+        [_gtest_min_version="--min-version=$1"
+         AC_MSG_CHECKING([for Google Test at least version >= $1])],
+        [_gtest_min_version="--min-version=0"
+         AC_MSG_CHECKING([for Google Test])])
+      AS_IF([${GTEST_CONFIG} ${_gtest_min_version}],
+        [AC_MSG_RESULT([yes])
+         HAVE_GTEST='yes'],
+        [AC_MSG_RESULT([no])])],
+     [AC_MSG_RESULT([no])])
+   AS_IF([test "x${HAVE_GTEST}" = "xyes"],
+     [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
+      GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
+      GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
+      GTEST_LIBS=`${GTEST_CONFIG} --libs`
+      GTEST_VERSION=`${GTEST_CONFIG} --version`
+      AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])],
+     [AS_IF([test "x${enable_gtest}" = "xyes"],
+        [AC_MSG_ERROR([dnl
+Google Test was enabled, but no viable version could be found.])
+         ])])])
+AC_SUBST([HAVE_GTEST])
+AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"])
+AS_IF([test "x$HAVE_GTEST" = "xyes"],
+  [m4_ifval([$2], [$2])],
+  [m4_ifval([$3], [$3])])
+])
diff --git a/m4/llvm-target.m4 b/m4/llvm-target.m4
new file mode 100644
index 0000000..0dbcd51
--- /dev/null
+++ b/m4/llvm-target.m4
@@ -0,0 +1,65 @@
+dnl
+dnl @synopsis ENUM_LLVM_TARGETS
+dnl
+dnl @summary enumlate LLVM Targets, set up variables:
+dnl   LLVM_ENUM_TARGETS
+dnl   LLVM_ENUM_LINKERS
+dnl
+dnl Luba Tang <lubatang@mediatek.com>
+
+AC_DEFUN([ENUM_LLVM_TARGETS],
+[dnl
+	dnl from ${LLVM}/autoconf/configure.ac
+	dnl Allow specific targets to be specified for building (or not)
+	TARGETS_TO_BUILD="";
+
+	AC_ARG_ENABLE([targets],
+		[AS_HELP_STRING([--enable-targets],
+			        [Build specific host targets: all or target1,target2,... Valid targets are:
+	     host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
+	     xcore, msp430, systemz, blackfin, ptx, cbe, and cpp (default=all)])],
+		[],
+		[enableval=all])
+
+	case "$enableval" in
+	  all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze PTX" ;;
+	  *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
+	      case "$a_target" in
+		x86)      TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
+		x86_64)   TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
+		sparc)    TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
+		powerpc)  TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
+		alpha)    TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
+		arm)      TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
+		mips)     TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
+		spu)      TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
+		xcore)    TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
+		msp430)   TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
+		systemz)  TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
+		blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
+		cbe)      TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
+		cpp)      TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
+		mblaze)   TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
+		ptx)      TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
+		*) AC_MSG_ERROR([Unrecognized target $a_target]) ;;
+	      esac
+	  done
+	  ;;
+	esac
+	AC_SUBST(TARGETS_TO_BUILD,$TARGETS_TO_BUILD)
+
+	dnl Build the LLVM_TARGET and LLVM_... macros for Targets.def and the individual
+	dnl target feature def files.
+	LLVM_ENUM_TARGETS=""
+	LLVM_ENUM_LINKERS=""
+	for target_to_build in $TARGETS_TO_BUILD; do
+	  if test -d ${srcdir}/lib/Target/${target_to_build} ; then
+	    LLVM_ENUM_TARGETS="LLVM_TARGET($target_to_build) $LLVM_ENUM_TARGETS"
+	  fi
+	  if test -f ${srcdir}/lib/Target/${target_to_build}/*LDBackend.cpp ; then
+	    LLVM_ENUM_LINKERS="LLVM_LINKER($target_to_build) $LLVM_ENUM_LINKERS";
+	  fi
+	done
+	AC_SUBST(LLVM_ENUM_TARGETS)
+	AC_SUBST(LLVM_ENUM_LINKERS)
+])
diff --git a/m4/llvm.m4 b/m4/llvm.m4
new file mode 100644
index 0000000..018a7ce
--- /dev/null
+++ b/m4/llvm.m4
@@ -0,0 +1,140 @@
+dnl
+dnl @synopsis CHECK_LLVM([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl
+dnl @summary check LLVM, set up variables:
+dnl   LLVM_CFLAGS="`${LLVM_CONFIG_BIN} --cflags`"
+dnl   LLVM_CPPFLAGS="`${LLVM_CONFIG_BIN} --cxxflags`"
+dnl   LLVM_LDFLAGS="`${LLVM_CONFIG_BIN} --ldflags --libs`"
+dnl
+dnl Luba Tang <lubatang@gmail.com>
+
+
+AC_DEFUN([CHECK_LLVM],
+[dnl
+
+	AC_ARG_WITH(
+		[llvm-config],
+		[AS_HELP_STRING([--with-llvm-config[[=PATH]]], 
+			[path to llvm-config (by default, searching in $PATH)])],
+		[llvm_config_path="${withval}"],
+		[llvm_config_path="/usr/"])
+
+	#Set up ${LLVM_CONFIG_BIN}
+	AC_MSG_CHECKING(for llvm-config)
+
+	if test -x "${llvm_config_path}" -a ! -d "${llvm_config_path}"; then
+		LLVM_CONFIG_BIN=${llvm_config_path}
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		llvm_config_path=${PATH}
+		if test -d "${LLVM_BINDIR}"; then
+			llvm_config_path="${llvm_config_path}:${LLVM_BINDIR}"
+		fi
+		AC_PATH_PROG(LLVM_CONFIG_BIN, llvm-config, [no], ${llvm_config_path})
+		if test "${LLVM_CONFIG_BIN}" = "no"; then
+			ifelse([$3], , , [$3])
+			AC_MSG_NOTICE([*** The 'llvm-config' is not found!])
+			AC_MSG_ERROR([*** Please use  --with-llvm-config option with the full path of 'llvm-config'.])
+		fi
+	fi
+
+	dnl Use llvm-config to do:
+	dnl   1. is the minimum version correct?
+	dnl   2. the includedir
+	dnl   3. the flags - cflags, cxxflags, cppflags, ldflags
+	dnl   4. the libs
+	AC_MSG_CHECKING(for llvm - version >= $1)
+	cur_version="`${LLVM_CONFIG_BIN} --version`";
+	tool_major="`${LLVM_CONFIG_BIN} --version | sed 's/svn//' | sed 's/\([[0-9]]*\).\([[0-9]]*\)/\1/'`"
+	tool_minor="`${LLVM_CONFIG_BIN} --version | sed 's/svn//'| sed 's/\([[0-9]]*\).\([[0-9]]*\)/\2/'`"
+
+	require_major="`echo $1 | sed 's/svn//' | sed 's/\([[0-9]]*\).\([[0-9]]*\)/\1/'`"
+	require_minor="`echo $1 | sed 's/svn//' | sed 's/\([[0-9]]*\).\([[0-9]]*\)/\2/'`"
+
+	if test "${tool_major}" -lt "${require_major}"; then
+		AC_MSG_RESULT([no])
+		AC_MSG_ERROR([*** The version of LLVM is too low! (${cur_version}<$1)]) 
+	elif test "${tool_major}" -eq "${require_major}"; then
+		if test "${tool_minor}" -lt "${require_minor}"; then
+			AC_MSG_RESULT([no])
+			AC_MSG_ERROR([*** The version of LLVM is too low! (${cur_version}<$1)]) 
+		fi
+	fi
+	AC_MSG_RESULT([yes]) 
+
+	LLVM_CFLAGS="`${LLVM_CONFIG_BIN} --cflags`"
+	LLVM_CPPFLAGS="`${LLVM_CONFIG_BIN} --cxxflags`"
+	LLVM_LDFLAGS="`${LLVM_CONFIG_BIN} --libs`"
+	LLVM_LDFLAGS="${LLVM_LDFLAGS} `${LLVM_CONFIG_BIN} --ldflags`"
+	LLVM_LDFLAGS="`echo ${LLVM_LDFLAGS} | sed 's/\n//g'`"
+	LLVM_LDFLAGS="`echo ${LLVM_LDFLAGS} | sed 's/-lgtest_main -lgtest//g'`"
+	LLVM_VERSION=${tool_major}
+	
+	AC_SUBST(LLVM_CFLAGS)
+	AC_SUBST(LLVM_CPPFLAGS)
+	AC_SUBST(LLVM_LDFLAGS)
+	AC_SUBST(LLVM_VERSION)
+	ifelse([$2], , , [$2])
+
+	AC_CACHE_CHECK([type of operating system we're going to host on],
+        		[llvm_cv_platform_type],
+			[case $host in
+			*-*-aix*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-irix*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-cygwin*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-darwin*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-minix*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-freebsd*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-openbsd*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-netbsd*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-dragonfly*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-hpux*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-interix*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-linux*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-solaris*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-auroraux*)
+				llvm_cv_platform_type="Unix" ;;
+			*-*-win32*)
+				llvm_cv_platform_type="Win32" ;;
+			*-*-mingw*)
+				llvm_cv_platform_type="Win32" ;;
+			*-*-haiku*)
+				llvm_cv_platform_type="Unix" ;;
+			*-unknown-eabi*)
+				llvm_cv_platform_type="Unix" ;;
+			*-unknown-elf*)
+				llvm_cv_platform_type="Unix" ;;
+			*)
+				llvm_cv_platform_type="Unknown" ;;
+			esac])
+
+	dnl Set the "LLVM_ON_*" variables based on llvm_cv_llvm_cv_platform_type
+	dnl This is used by lib/Support to determine the basic kind of implementation
+	dnl to use.
+	case $llvm_cv_platform_type in
+	Unix)
+		AC_DEFINE([LLVM_ON_UNIX],[1],[Define if this is Unixish platform])
+		AC_SUBST(LLVM_ON_UNIX,[1])
+		AC_SUBST(LLVM_ON_WIN32,[0])
+	;;
+	Win32)
+		AC_DEFINE([LLVM_ON_WIN32],[1],[Define if this is Win32ish platform])
+		AC_SUBST(LLVM_ON_UNIX,[0])
+		AC_SUBST(LLVM_ON_WIN32,[1])
+	;;
+	esac
+])
diff --git a/mcld-device-build.mk b/mcld-device-build.mk
new file mode 100644
index 0000000..9f445b3
--- /dev/null
+++ b/mcld-device-build.mk
@@ -0,0 +1,37 @@
+include $(LLVM_DEVICE_BUILD_MK)
+
+# The three inline options together reduce libbcc.so almost 1MB.
+# We move them from global build/core/combo/TARGET_linux-arm.mk
+# to here.
+LOCAL_CFLAGS := -DANDROID_TARGET_BUILD \
+		-finline-limit=64 \
+		-finline-functions \
+		-fno-inline-functions-called-once \
+		$(LOCAL_CFLAGS)
+
+LOCAL_CPPFLAGS :=	\
+	$(LOCAL_CPPFLAGS)	\
+  -Wformat  \
+  -Werror=format-security \
+  -Werror=return-type \
+  -Werror=non-virtual-dtor  \
+  -Werror=address \
+  -Werror=sequence-point  \
+	-Woverloaded-virtual	\
+	-Wno-sign-promo
+
+ifeq ($(MCLD_ENABLE_ASSERTION),true)
+  LOCAL_CPPFLAGS += \
+    -D_DEBUG  \
+    -UNDEBUG
+endif
+
+# Make sure bionic is first so we can include system headers.
+LOCAL_C_INCLUDES :=	\
+	bionic \
+	external/stlport/stlport \
+  $(MCLD_ROOT_PATH)/include \
+	$(LLVM_ROOT_PATH)	\
+	$(LLVM_ROOT_PATH)/include	\
+	$(LLVM_ROOT_PATH)/device/include	\
+	$(LOCAL_C_INCLUDES)
diff --git a/mcld-host-build.mk b/mcld-host-build.mk
new file mode 100644
index 0000000..2bedf07
--- /dev/null
+++ b/mcld-host-build.mk
@@ -0,0 +1,27 @@
+include $(LLVM_HOST_BUILD_MK)
+
+LOCAL_CPPFLAGS :=	\
+	$(LOCAL_CPPFLAGS)	\
+  -Wformat  \
+  -Werror=format-security \
+  -Werror=return-type \
+  -Werror=non-virtual-dtor  \
+  -Werror=address \
+  -Werror=sequence-point  \
+	-Woverloaded-virtual	\
+	-Wno-sign-promo
+
+ifeq ($(MCLD_ENABLE_ASSERTION),true)
+  LOCAL_CPPFLAGS += \
+    -D_DEBUG  \
+    -UNDEBUG
+endif
+
+LOCAL_C_INCLUDES :=	\
+  $(MCLD_ROOT_PATH)/include \
+	$(LLVM_ROOT_PATH)	\
+	$(LLVM_ROOT_PATH)/include	\
+	$(LLVM_ROOT_PATH)/host/include	\
+	$(LOCAL_C_INCLUDES)
+
+LOCAL_IS_HOST_MODULE := true
diff --git a/mcld.mk b/mcld.mk
new file mode 100644
index 0000000..3fa71f9
--- /dev/null
+++ b/mcld.mk
@@ -0,0 +1,12 @@
+ifeq ($(MCLD_ROOT_PATH),)
+$(error Must set variable MCLD_ROOT_PATH before including this! $(LOCAL_PATH))
+endif
+
+MCLD_HOST_BUILD_MK := $(MCLD_ROOT_PATH)/mcld-host-build.mk
+MCLD_DEVICE_BUILD_MK := $(MCLD_ROOT_PATH)/mcld-device-build.mk
+
+ifeq ($(LLVM_ROOT_PATH),)
+$(error Must set variable LLVM_ROOT_PATH before including this! $(LOCAL_PATH))
+endif
+
+include $(LLVM_ROOT_PATH)/llvm.mk
diff --git a/optimized/Makefile.am b/optimized/Makefile.am
new file mode 100644
index 0000000..62f2ed9
--- /dev/null
+++ b/optimized/Makefile.am
@@ -0,0 +1,233 @@
+BUILDTOP=..
+TOPLEVEL=${srcdir}/..
+TOOLDIR=${TOPLEVEL}/tools/llvm-mcld
+LIBDIR=${TOPLEVEL}/lib
+INCDIR=${TOPLEVEL}/include/mcld
+UNITTEST=${TOPLEVEL}/unittests
+
+ANDROID_CPPFLAGS=-Wformat -Werror=format-security -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
+
+bin_PROGRAMS = llvm-mcld
+
+llvm_mcld_CPPFLAGS = -O2 -DTOPDIR=\"${abs_top_srcdir}\" -DLLVM_VERSION=${LLVM_VERSION} -I$(TOPLEVEL)/include -I$(BUILDTOP)/include ${LLVM_CPPFLAGS} ${ANDROID_CPPFLAGS}
+llvm_mcld_LDADD = ${LLVM_LDFLAGS}
+
+NORMAL_SOURCE = ${TOOLDIR}/llvm-mcld.cpp \
+	${INCDIR}/ADT/Uncopyable.h \
+	${INCDIR}/ADT/TypeTraits.h \
+	${INCDIR}/ADT/TreeBase.h \
+	${INCDIR}/ADT/Allocators.h \
+	${INCDIR}/ADT/TreeAllocator.h \
+	${INCDIR}/ADT/BinTree.h \
+	${INCDIR}/Support/Path.h \
+	${LIBDIR}/Support/Path.cpp \
+	${INCDIR}/Support/RealPath.h \
+	${LIBDIR}/Support/RealPath.cpp \
+	${INCDIR}/Support/Directory.h \
+	${LIBDIR}/Support/Directory.cpp \
+	${INCDIR}/Support/FileSytem.h \
+	${LIBDIR}/Support/FileSystem.cpp \
+	${INCDIR}/Support/LEB128.h \
+	${LIBDIR}/Support/LEB128.cpp \
+	${INCDIR}/Support/MemoryArea.h \
+	${LIBDIR}/Support/MemoryArea.cpp \
+	${INCDIR}/Support/MemoryRegion.h \
+	${LIBDIR}/Support/MemoryRegion.cpp \
+	${INCDIR}/Support/RegionFactory.h \
+	${LIBDIR}/Support/RegionFactory.cpp \
+	${INCDIR}/Support/MemoryAreaFactory.h \
+	${LIBDIR}/Support/MemoryAreaFactory.cpp \
+	${INCDIR}/Support/CommandLine.h \
+	${LIBDIR}/Support/CommandLine.cpp \
+	${INCDIR}/Support/GCFactory.h \
+	${INCDIR}/Support/UniqueGCFactory.h \
+	${INCDIR}/Support/PositionDependentOption.h \
+	${INCDIR}/Support/DerivedPositionDependentOptions.h \
+	${LIBDIR}/CodeGen/LLVMTargetMachine.cpp \
+	${INCDIR}/CodeGen/SectLinker.h \
+	${LIBDIR}/CodeGen/SectLinker.cpp \
+	${INCDIR}/CodeGen/SectLinkerOption.h \
+	${LIBDIR}/CodeGen/SectLinkerOption.cpp \
+	${INCDIR}/Target/PLT.h\
+	${LIBDIR}/Target/PLT.cpp\
+	${INCDIR}/Target/GOT.h \
+	${LIBDIR}/Target/GOT.cpp \
+	${INCDIR}/Target/TargetMachine.h \
+	${INCDIR}/Target/TargetRegistry.h \
+	${LIBDIR}/Support/TargetRegistry.cpp \
+	${LIBDIR}/Target/Target.cpp \
+	${INCDIR}/Target/TargetSelect.h \
+	${INCDIR}/Target/TargetLDBackend.h \
+	${LIBDIR}/Target/TargetLDBackend.cpp \
+	${INCDIR}/Target/GNULDBackend.h \
+	${LIBDIR}/Target/GNULDBackend.cpp \
+	${INCDIR}/Target/AndroidSectLinker.h \
+	${LIBDIR}/Target/AndroidSectLinker.cpp \
+	${INCDIR}/Target/ELFDynamic.h \
+	${LIBDIR}/Target/ELFDynamic.cpp \
+	${INCDIR}/Target/OutputRelocSection.h \
+	${LIBDIR}/Target/OutputRelocSection.cpp \
+	${LIBDIR}/Target/ARM/ARMELFDynamic.h \
+	${LIBDIR}/Target/ARM/ARMELFDynamic.cpp \
+	${LIBDIR}/Target/ARM/ARMLDBackend.h \
+	${LIBDIR}/Target/ARM/ARMLDBackend.cpp \
+	${LIBDIR}/Target/ARM/ARMGOT.h \
+	${LIBDIR}/Target/ARM/ARMGOT.cpp \
+	${LIBDIR}/Target/ARM/ARMPLT.h \
+	${LIBDIR}/Target/ARM/ARMPLT.cpp \
+	${LIBDIR}/Target/ARM/ARMTargetMachine.h \
+	${LIBDIR}/Target/ARM/ARMTargetMachine.cpp \
+	${LIBDIR}/Target/ARM/ARMRelocationFactory.h \
+	${LIBDIR}/Target/ARM/ARMRelocationFactory.cpp \
+	${LIBDIR}/Target/ARM/ARMSectLinker.cpp \
+	${LIBDIR}/Target/ARM/ARMELFSectLinker.h \
+	${LIBDIR}/Target/ARM/ARMELFSectLinker.cpp \
+	${LIBDIR}/Target/ARM/ARMAndroidSectLinker.h \
+	${LIBDIR}/Target/ARM/ARMAndroidSectLinker.cpp \
+	${LIBDIR}/Target/ARM/TargetInfo/ARMTargetInfo.cpp \
+	${LIBDIR}/Target/Mips/MipsELFDynamic.h \
+	${LIBDIR}/Target/Mips/MipsELFDynamic.cpp \
+	${LIBDIR}/Target/Mips/MipsLDBackend.h \
+	${LIBDIR}/Target/Mips/MipsLDBackend.cpp \
+	${LIBDIR}/Target/Mips/MipsGOT.h \
+	${LIBDIR}/Target/Mips/MipsGOT.cpp \
+	${LIBDIR}/Target/Mips/MipsTargetMachine.h \
+	${LIBDIR}/Target/Mips/MipsTargetMachine.cpp \
+	${LIBDIR}/Target/Mips/MipsRelocationFactory.h \
+	${LIBDIR}/Target/Mips/MipsRelocationFactory.cpp \
+	${LIBDIR}/Target/Mips/MipsSectLinker.cpp \
+	${LIBDIR}/Target/Mips/MipsELFSectLinker.h \
+	${LIBDIR}/Target/Mips/MipsELFSectLinker.cpp \
+	${LIBDIR}/Target/Mips/MipsAndroidSectLinker.h \
+	${LIBDIR}/Target/Mips/MipsAndroidSectLinker.cpp \
+	${LIBDIR}/Target/Mips/TargetInfo/MipsTargetInfo.cpp \
+	${LIBDIR}/Target/X86/X86ELFDynamic.h \
+	${LIBDIR}/Target/X86/X86ELFDynamic.cpp \
+	${LIBDIR}/Target/X86/X86LDBackend.h \
+	${LIBDIR}/Target/X86/X86LDBackend.cpp \
+	${LIBDIR}/Target/X86/X86GOT.h \
+	${LIBDIR}/Target/X86/X86GOT.cpp \
+	${LIBDIR}/Target/X86/X86GOTPLT.h \
+	${LIBDIR}/Target/X86/X86GOTPLT.cpp \
+	${LIBDIR}/Target/X86/X86PLT.h \
+	${LIBDIR}/Target/X86/X86PLT.cpp \
+	${LIBDIR}/Target/X86/X86TargetMachine.h \
+	${LIBDIR}/Target/X86/X86TargetMachine.cpp \
+	${LIBDIR}/Target/X86/X86RelocationFactory.h \
+	${LIBDIR}/Target/X86/X86RelocationFactory.cpp \
+	${LIBDIR}/Target/X86/X86SectLinker.cpp \
+	${LIBDIR}/Target/X86/X86ELFSectLinker.h \
+	${LIBDIR}/Target/X86/X86ELFSectLinker.cpp \
+	${LIBDIR}/Target/X86/X86AndroidSectLinker.h \
+	${LIBDIR}/Target/X86/X86AndroidSectLinker.cpp \
+	${LIBDIR}/Target/X86/TargetInfo/X86TargetInfo.cpp \
+	${INCDIR}/MC/MCLDDriver.h \
+	${LIBDIR}/MC/MCLDDriver.cpp \
+	${INCDIR}/MC/SymbolCategory.h \
+	${LIBDIR}/MC/SymbolCategory.cpp \
+	${INCDIR}/MC/MCLinker.h \
+	${LIBDIR}/MC/MCLinker.cpp \
+	${INCDIR}/MC/MCBitcodeInterceptor.h \
+	${LIBDIR}/MC/MCBitcodeInterceptor.cpp \
+	${INCDIR}/MC/MCLDFile.h \
+	${LIBDIR}/MC/MCLDFile.cpp \
+	${INCDIR}/MC/MCLDInput.h \
+	${LIBDIR}/MC/MCLDInput.cpp \
+	${INCDIR}/MC/MCLDOutput.h \
+	${LIBDIR}/MC/MCLDOutput.cpp \
+	${INCDIR}/MC/InputFactory.h \
+	${LIBDIR}/MC/InputFactory.cpp \
+	${INCDIR}/MC/MCLDOptions.h \
+	${LIBDIR}/MC/MCLDOptions.cpp \
+	${INCDIR}/MC/MCLDInfo.h \
+	${LIBDIR}/MC/MCLDInfo.cpp \
+	${INCDIR}/MC/ContextFactory.h \
+	${LIBDIR}/MC/ContextFactory.cpp \
+	${INCDIR}/MC/SearchDirs.h \
+	${LIBDIR}/MC/SearchDirs.cpp \
+	${INCDIR}/MC/MCLDDirectory.h \
+	${LIBDIR}/MC/MCLDDirectory.cpp \
+	${INCDIR}/MC/MCLDAttribute.h \
+	${LIBDIR}/MC/MCLDAttribute.cpp \
+	${INCDIR}/MC/AttributeFactory.h \
+	${LIBDIR}/MC/AttributeFactory.cpp \
+	${INCDIR}/MC/MCLDInputTree.h \
+	${LIBDIR}/MC/MCLDInputTree.cpp \
+	${INCDIR}/MC/MCRegionFragment.h \
+	${LIBDIR}/MC/MCRegionFragment.cpp \
+	${INCDIR}/MC/MCTargetFragment.h \
+	${INCDIR}/MC/MCFragmentRef.h \
+	${LIBDIR}/MC/MCFragmentRef.cpp \
+	${INCDIR}/LD/LDContext.h \
+	${LIBDIR}/LD/LDContext.cpp \
+	${INCDIR}/LD/LDSection.h \
+	${LIBDIR}/LD/LDSection.cpp \
+	${INCDIR}/LD/ResolveInfo.h \
+	${LIBDIR}/LD/ResolveInfo.cpp \
+	${INCDIR}/LD/ResolveInfoFactory.h \
+	${LIBDIR}/LD/ResolveInfoFactory.cpp \
+	${INCDIR}/LD/Resolver.h \
+	${LIBDIR}/LD/Resolver.cpp \
+	${INCDIR}/LD/LDSymbol.h \
+	${LIBDIR}/LD/LDSymbol.cpp \
+	${INCDIR}/LD/Layout.h \
+	${LIBDIR}/LD/Layout.cpp\
+	${INCDIR}/LD/Relocation.h \
+	${LIBDIR}/LD/Relocation.cpp \
+	${INCDIR}/LD/RelocationFactory.h \
+	${LIBDIR}/LD/RelocationFactory.cpp \
+	${INCDIR}/LD/StaticResolver.h \
+	${LIBDIR}/LD/StaticResolver.cpp \
+	${INCDIR}/LD/StrSymPool.h \
+	${LIBDIR}/LD/StrSymPool.cpp \
+	${INCDIR}/LD/LDReader.h \
+	${LIBDIR}/LD/LDReader.cpp \
+	${INCDIR}/LD/LDWriter.h \
+	${LIBDIR}/LD/LDWriter.cpp \
+	${INCDIR}/LD/ArchiveReader.h \
+	${LIBDIR}/LD/ArchiveReader.cpp \
+	${INCDIR}/LD/ObjectReader.h \
+	${INCDIR}/LD/DynObjReader.h \
+	${LIBDIR}/LD/DynObjReader.cpp \
+	${INCDIR}/LD/ObjectWriter.h \
+	${LIBDIR}/LD/ObjectWriter.cpp \
+	${INCDIR}/LD/DynObjWriter.h \
+	${LIBDIR}/LD/DynObjWriter.cpp \
+	${INCDIR}/LD/ELFReader.h \
+	${LIBDIR}/LD/ELFReader.cpp \
+	${INCDIR}/LD/ELFWriter.h \
+	${LIBDIR}/LD/ELFWriter.cpp \
+	${INCDIR}/LD/GNUArchiveReader.h \
+	${LIBDIR}/LD/GNUArchiveReader.cpp \
+	${INCDIR}/LD/BSDArchiveReader.h \
+	${LIBDIR}/LD/BSDArchiveReader.cpp \
+	${INCDIR}/LD/ELFObjectReader.h \
+	${LIBDIR}/LD/ELFObjectReader.cpp \
+	${INCDIR}/LD/ELFDynObjReader.h \
+	${LIBDIR}/LD/ELFDynObjReader.cpp \
+	${INCDIR}/LD/ELFObjectWriter.h \
+	${LIBDIR}/LD/ELFObjectWriter.cpp \
+	${INCDIR}/LD/ELFDynObjWriter.h \
+	${LIBDIR}/LD/ELFDynObjWriter.cpp \
+	${INCDIR}/LD/LDFileFormat.h \
+	${LIBDIR}/LD/LDFileFormat.cpp \
+	${INCDIR}/LD/ELFFileFormat.h \
+	${LIBDIR}/LD/ELFFileFormat.cpp \
+	${INCDIR}/LD/ELFDynObjFileFormat.h \
+	${LIBDIR}/LD/ELFDynObjFileFormat.cpp \
+	${INCDIR}/LD/ELFExecFileFormat.h \
+	${LIBDIR}/LD/ELFExecFileFormat.cpp \
+	${INCDIR}/LD/LDSectionFactory.h \
+	${LIBDIR}/LD/LDSectionFactory.cpp \
+	${INCDIR}/LD/SectionMap.h \
+	${LIBDIR}/LD/SectionMap.cpp \
+	${INCDIR}/LD/SectionMerger.h \
+	${LIBDIR}/LD/SectionMerger.cpp \
+	${INCDIR}/LD/ELFSegment.h \
+	${LIBDIR}/LD/ELFSegment.cpp \
+	${INCDIR}/LD/ELFSegmentFactory.h \
+	${LIBDIR}/LD/ELFSegmentFactory.cpp
+
+SOURCE = ${NORMAL_SOURCE}
+
+llvm_mcld_SOURCES = ${SOURCE}
diff --git a/patch/LLVM.patch b/patch/LLVM.patch
new file mode 100644
index 0000000..bf84562
--- /dev/null
+++ b/patch/LLVM.patch
@@ -0,0 +1,161 @@
+Index: include/llvm/MC/MCAssembler.h
+===================================================================
+--- include/llvm/MC/MCAssembler.h	(revision 152063)
++++ include/llvm/MC/MCAssembler.h	(working copy)
+@@ -21,6 +21,10 @@
+ #include "llvm/Support/DataTypes.h"
+ #include <vector> // FIXME: Shouldn't be needed.
+ 
++namespace mcld {
++class Layout;
++}
++
+ namespace llvm {
+ class raw_ostream;
+ class MCAsmLayout;
+@@ -40,6 +44,7 @@
+ 
+ class MCFragment : public ilist_node<MCFragment> {
+   friend class MCAsmLayout;
++  friend class mcld::Layout;
+ 
+   MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
+   void operator=(const MCFragment&); // DO NOT IMPLEMENT
+@@ -53,10 +58,13 @@
+     FT_Org,
+     FT_Dwarf,
+     FT_DwarfFrame,
+-    FT_LEB
++    FT_LEB,
++    FT_Region,
++    FT_Reloc,
++    FT_Target
+   };
+ 
+-private:
++protected:
+   FragmentType Kind;
+ 
+   /// Parent - The data for the section this fragment is in.
+@@ -453,7 +461,7 @@
+   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+   typedef FragmentListType::reverse_iterator reverse_iterator;
+ 
+-private:
++protected:
+   FragmentListType Fragments;
+   const MCSection *Section;
+ 
+@@ -481,6 +489,7 @@
+   // Only for use as sentinel.
+   MCSectionData();
+   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
++  virtual ~MCSectionData() {}
+ 
+   const MCSection &getSection() const { return *Section; }
+ 
+@@ -679,7 +688,7 @@
+ 
+   MCCodeEmitter &Emitter;
+ 
+-  MCObjectWriter &Writer;
++  MCObjectWriter *m_pWriter;
+ 
+   raw_ostream &OS;
+ 
+@@ -807,8 +816,10 @@
+ 
+   MCCodeEmitter &getEmitter() const { return Emitter; }
+ 
+-  MCObjectWriter &getWriter() const { return Writer; }
++  MCObjectWriter &getWriter() const { return *m_pWriter; }
+ 
++  void setWriter(MCObjectWriter &pObjectWriter);
++
+   /// Finish - Do final processing and write the object to the output stream.
+   /// \arg Writer is used for custom object writer (as the MCJIT does),
+   /// if not specified it is automatically created from backend.
+Index: include/llvm/MC/MCSection.h
+===================================================================
+--- include/llvm/MC/MCSection.h	(revision 152063)
++++ include/llvm/MC/MCSection.h	(working copy)
+@@ -31,7 +31,8 @@
+     enum SectionVariant {
+       SV_COFF = 0,
+       SV_ELF,
+-      SV_MachO
++      SV_MachO,
++      SV_LDContext
+     };
+ 
+   private:
+Index: include/llvm/Support/ELF.h
+===================================================================
+--- include/llvm/Support/ELF.h	(revision 152063)
++++ include/llvm/Support/ELF.h	(working copy)
+@@ -736,6 +736,13 @@
+   SHT_LOOS          = 0x60000000, // Lowest operating system-specific type.
+   SHT_HIOS          = 0x6fffffff, // Highest operating system-specific type.
+   SHT_LOPROC        = 0x70000000, // Lowest processor architecture-specific type.
++
++  SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
++  SHT_GNU_HASH       = 0x6ffffff6, // GNU style dynamic hash table.
++  SHT_GNU_verdef     = 0x6ffffffd, // Versions defined by file.
++  SHT_GNU_verneed    = 0x6ffffffe, // Versions needed by file.
++  SHT_GNU_versym     = 0x6fffffff, // Symbol versions.
++
+   // Fixme: All this is duplicated in MCSectionELF. Why??
+   // Exception Index table
+   SHT_ARM_EXIDX           = 0x70000001U,
+Index: include/llvm/Support/CommandLine.h
+===================================================================
+--- include/llvm/Support/CommandLine.h	(revision 152063)
++++ include/llvm/Support/CommandLine.h	(working copy)
+@@ -337,7 +337,11 @@
+ 
+   bool hasValue() const { return false; }
+ 
+-  const DataType &getValue() const { llvm_unreachable("no default value"); }
++  const DataType &getValue() const {
++    assert(false && "no default value");
++    DataType *p = 0;
++    return *p;
++  }
+ 
+   // Some options may take their value from a different data type.
+   template<class DT>
+Index: lib/MC/MCAssembler.cpp
+===================================================================
+--- lib/MC/MCAssembler.cpp	(revision 152063)
++++ lib/MC/MCAssembler.cpp	(working copy)
+@@ -157,7 +157,8 @@
+ }
+ 
+ MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
+-  : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0))
++  : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)),
++    LayoutOrder(~(0U))
+ {
+   if (Parent)
+     Parent->getFragmentList().push_back(this);
+@@ -197,7 +198,7 @@
+ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
+                          MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
+                          raw_ostream &OS_)
+-  : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
++  : Context(Context_), Backend(Backend_), Emitter(Emitter_), m_pWriter(&Writer_),
+     OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false)
+ {
+ }
+@@ -205,6 +206,11 @@
+ MCAssembler::~MCAssembler() {
+ }
+ 
++void MCAssembler::setWriter(MCObjectWriter &pObjectWriter) {
++  delete m_pWriter;
++  m_pWriter = &pObjectWriter;
++}
++
+ bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
+   // Non-temporary labels should always be visible to the linker.
+   if (!Symbol.isTemporary())
diff --git a/patch/README b/patch/README
new file mode 100644
index 0000000..04ac2b3
--- /dev/null
+++ b/patch/README
@@ -0,0 +1,24 @@
+
+------------------------------------------------------------
+For building MCLinker, it needs to build LLVM first.
+
+Before building LLVM,
+the patch "${MCLINKER_SRC}/patch/LLVM.patch" should be applied first.
+
+Following the steps below to apply the patch:
+1. cd $(LLVM_ROOT)
+2. patch -p0 < ${MCLINKER_SRC}/patch/LLVM.patch
+
+This patch is for LLVM trunk@152063.
+
+
+------------------------------------------------------------
+commit c3384c93c0e4c50da4ad093f08997507f9281c75
+Author: Jim Grosbach <grosbach@apple.com>
+Date:   Mon Mar 5 21:43:40 2012 +0000
+
+    ARM Refactor VLD/VST spaced pair instructions.
+
+    Use the new composite physical registers.
+
+    git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152063
diff --git a/scripts/bin/add_class b/scripts/bin/add_class
new file mode 100755
index 0000000..5526e64
--- /dev/null
+++ b/scripts/bin/add_class
@@ -0,0 +1,150 @@
+#!/bin/bash
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+############################
+# Design Pattern - Builder, using BASH
+# 0. watch configuration
+# 1. ask name
+# 2. ask email
+#  i. write back to configuration
+# 3. ask file type
+#  i. ask deployment
+# 4. ask file name
+# 5. copy templates
+# 6. replace the keywords
+
+############################
+# Variable Dictionary
+MCLINKER_CONFIG_DIR=$HOME/.bold
+AUTHOR=
+EMAIL=
+CLASS_NAME=
+BRIEF=
+FILE_TYPE=
+
+# 0. watch configuration
+if [ -d "${MCLINKER_CONFIG_DIR}" ]; then
+	if [ -f "${MCLINKER_CONFIG_DIR}/config" ]; then
+		source ${MCLINKER_CONFIG_DIR}/config
+	fi
+else
+	mkdir ${MCLINKER_CONFIG_DIR}
+fi
+
+# 1. ask name
+#  i. write back to configuration
+if [ -z "${AUTHOR}" ]; then
+	echo -n "name? ";
+	read AUTHOR
+	echo "AUTHOR=\"${AUTHOR}\"" >> ${MCLINKER_CONFIG_DIR}/config
+fi
+
+# 2. ask email
+#  i. write back to configuration
+if [ -z "${EMAIL}" ]; then
+	echo -n "e-mail? ";
+	read EMAIL
+	echo "EMAIL=\"${EMAIL}\"" >> ${MCLINKER_CONFIG_DIR}/config
+fi
+
+# 3. ask file type
+echo "What type of files you want to create?";
+echo " 1) normal source code"
+echo " 2) test case"
+
+while [ -z "${FILE_TYPE}" ]; do
+	echo -n "your choice? ";
+	read FILE_TYPE
+
+	case "$FILE_TYPE" in
+	1 ) source ${MCLINKERTOP}/scripts/normal_files.sh;
+		FILE_TYPE="normal";
+		;;
+	2 ) source ${MCLINKERTOP}/scripts/test_files.sh;
+		FILE_TYPE="testcase";
+		;;
+	* ) FILE_TYPE="" ;;
+	esac
+done
+
+# 3.i ask deployment
+if [ "${FILE_TYPE}" = "normal" ]; then
+	echo "Where you what to deploy?";
+	echo " 1) ADT"
+	echo " 2) MC"
+	echo " 3) Target"
+	echo " 4) CodeGen"
+	echo " 5) Support"
+	echo " 6) LD"
+
+	while [ -z "${DEPLOYMENT}" ]; do
+		echo -n "your choice? ";
+		read DEPLOYMENT
+
+		case "${DEPLOYMENT}" in
+		1 ) DEPLOYMENT="ADT";;
+		2 ) DEPLOYMENT="MC";;
+		3 ) DEPLOYMENT="Target";;
+		4 ) DEPLOYMENT="CodeGen";;
+		5 ) DEPLOYMENT="Support";;
+		6 ) DEPLOYMENT="LD";;
+		* ) DEPLOYMENT="";;
+		esac
+	done
+fi
+
+# 3.ii ask Target
+if [ "${DEPLOYMENT}" = "Target" ]; then
+	echo "What is your Target?";
+	echo " 1) Target"
+	echo " 2) Target/ARM"
+	echo " 3) Target/X86"
+	echo " 4) Target/Mips"
+
+	while [ -z "${TARGET}" ]; do
+		echo -n "your choice? ";
+		read TARGET
+		case "${TARGET}" in
+		1 ) TARGET=".";;
+		2 ) TARGET="ARM"
+		    source ${MCLINKERTOP}/scripts/target_files.sh;
+			;;
+		3 ) TARGET="X86"
+		    source ${MCLINKERTOP}/scripts/target_files.sh;
+			;;
+		4 ) TARGET="Mips"
+		    source ${MCLINKERTOP}/scripts/target_files.sh;
+			;;
+		* ) TARGET="";;
+		esac
+	done
+	DEPLOYMENT="${DEPLOYMENT}/${TARGET}"
+fi
+
+# 4. ask file name
+ask_filename
+read CLASS_NAME
+
+ask_brief ${CLASS_NAME}
+read BRIEF
+
+# 5. copy the templates
+TARGET_FILE=$(copy_template_header ${CLASS_NAME} ${DEPLOYMENT})
+
+# 6. replace the keywords
+replace_author  ${TARGET_FILE} ${AUTHOR}
+repalce_email ${TARGET_FILE} ${EMAIL} 
+replace_class ${TARGET_FILE} ${CLASS_NAME} 
+replace_brief ${TARGET_FILE} ${BRIEF}
+
+# 5. copy the templates
+TARGET_FILE=$(copy_template_impl ${CLASS_NAME} ${DEPLOYMENT})
+
+# 6. replace the keywords
+replace_author  ${TARGET_FILE} ${AUTHOR}
+repalce_email ${TARGET_FILE} ${EMAIL} 
+replace_class ${TARGET_FILE} ${CLASS_NAME} 
+replace_brief ${TARGET_FILE} ${BRIEF}
diff --git a/scripts/envsetup.sh b/scripts/envsetup.sh
new file mode 100755
index 0000000..51a7bdb
--- /dev/null
+++ b/scripts/envsetup.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+function gettop() 
+{
+	local TOPFILE=tools/llvm-mcld/llvm-mcld.cpp
+	if [ -n "${MCLINKERTOP}" -a -f "${MCLINKERTOP}/${TOPFILE}" ]; then
+		echo ${MCLINKERTOP}
+	else
+		if [ -f "${TOPFILE}" ]; then
+			echo `pwd`;
+		else
+			local HERE=$PWD
+			T=
+			while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
+				cd .. > /dev/null
+				T=`PWD= pwd`
+			done
+			cd $HERE > /dev/null
+			if [ -f "${T}/${TOPFILE}" ]; then
+				echo ${T}
+			fi
+		fi
+	fi
+	
+}
+
+function wc_pndk()
+{
+	local H=`find ${MCLINKERTOP} | grep '\.h'`
+	local C=`find ${MCLINKERTOP} | grep '\.cpp'`
+	wc ${C} ${H}
+}
+
+#############################
+#  Variable Dictionary
+export MCLINKERTOP=$(gettop)
+export PATH="${MCLINKERTOP}/scripts/bin:$PATH"
+if [ -x "${MCLINKERTOP}/debug/llvm-mcld" ]; then
+	ln -sf ${MCLINKERTOP}/debug/llvm-mcld ${MCLINKERTOP}/scripts/bin/MCLinker
+fi
+
+alias mk="make -C ${MCLINKERTOP}"
+
+SERVER=`grep mtksgt01 /etc/hosts`
+if [ ! -z "${SERVER}" ]; then
+	export PATH="/mtkoss/git/1.7.6-rhel-5.5/x86_64/bin:$PATH";
+fi
diff --git a/scripts/normal_files.sh b/scripts/normal_files.sh
new file mode 100644
index 0000000..aa50941
--- /dev/null
+++ b/scripts/normal_files.sh
@@ -0,0 +1,144 @@
+#!/bin/bash
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+function ask_filename
+{
+	echo -n "What is the class name? ";
+}
+
+function ask_brief
+{
+	CLASS_NAME=$1
+	echo "Please brief the class ${CLASS_NAME}: "
+}
+
+function copy_template_header
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/include/mcld/${DEPLOYMENT}/${NAME}.h";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/header.h";
+	mkdir -p ${MCLINKERTOP}/include/mcld/${DEPLOYMENT}
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	# replace the template name by target flie name and adjust the padding of '-'
+	local header_str="header";
+	PADDING_LEN=`expr ${#header_str} - ${#NAME}`;
+	ABS_PADDING_LEN=${PADDING_LEN};
+	PADDING="";
+
+	if [ "${PADDING_LEN}" -lt "0" ]; then
+		ABS_PADDING_LEN=`expr ${ABS_PADDING_LEN} \* -1`;
+	fi
+	for (( i=0; i < ${ABS_PADDING_LEN}; i = i + 1 )); do
+		PADDING="${PADDING}-";
+	done
+
+	if [ "${PADDING_LEN}" -gt "0" ]; then # replace and add padding
+		sed -e "s/header.h /${NAME}.h ${PADDING}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	elif [ "${PADDING_LEN}" -lt "0" ]; then # replace and strip padding
+		sed -e "s/header.h ${PADDING}/${NAME}.h /g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	else # replace directly
+		sed -e "s/header/${NAME}/g" ${TARGET_FILE} >  ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	fi
+
+	echo "${TARGET_FILE}";
+}
+
+function copy_template_impl
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/lib/${DEPLOYMENT}/${NAME}.cpp";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/impl.cpp";
+	mkdir -p ${MCLINKERTOP}/lib/${DEPLOYMENT}
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	# replace the template name by target flie name and adjust the padding of '-'
+	local impl_str="impl";
+	PADDING_LEN=`expr ${#impl_str} - ${#NAME}`;
+	ABS_PADDING_LEN=${PADDING_LEN};
+	PADDING="";
+	if [ "${PADDING_LEN}" -lt "0" ]; then
+		ABS_PADDING_LEN=`expr ${ABS_PADDING_LEN} \* -1`;
+	fi
+
+	for (( i = 0; i < ${ABS_PADDING_LEN}; i = i + 1 )); do
+		PADDING="${PADDING}-";
+	done
+
+	if [ "${PADDING_LEN}" -gt "0" ]; then # replace and add padding
+		sed -e "s/impl.cpp /${NAME}.cpp ${PADDING}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	elif [ "${PADDING_LEN}" -lt "0" ]; then # replace and strip padding
+		sed -e "s/impl.cpp ${PADDING}/${NAME}.cpp /g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	else # replace directly
+		sed -e "s/impl/${NAME}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	fi
+
+	echo "${TARGET_FILE}";
+}
+
+function replace_author
+{
+	local TARGET_FILE=$1
+	shift
+	local AUTHOR=$*
+
+	sed -e "s/\${AUTHOR}/${AUTHOR}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+}
+
+function repalce_email
+{
+	local TARGET_FILE=$1
+	local EMAIL=$2
+	sed -e "s/\${EMAIL}/${EMAIL}/g" ${TARGET_FILE}  > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+
+	# adjust the length of header
+	NEW_SPACE=`grep '>                                                    *' ${TARGET_FILE} | wc -c`
+	NEW_SPACE=`expr 79 - ${NEW_SPACE}`
+	ADDEND=">";
+	if [ "${NEW_SPACE}" -gt "0" ]; then # add space
+		for (( i=0; i<${NEW_SPACE}; i=i+1 )); do
+			ADDEND="${ADDEND} ";
+		done
+		sed -e "s/${EMAIL}>/${EMAIL}${ADDEND}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	elif [ "${NEW_SPACE}" -lt "0" ]; then # strip space
+		for (( i=${NEW_SPACE}; i<0; i=i+1 )); do
+			ADDEND="${ADDEND} ";
+		done
+		sed -e "s/${EMAIL}${ADDEND}/${EMAIL}>/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	fi
+}
+
+function replace_class
+{
+	local TARGET_FILE=$1
+	local CLASS_NAME=$2
+	local UPCLASS_NAME=`echo ${CLASS_NAME} | tr [:lower:] [:upper:]`
+
+	sed -e "s/\${class_name}/${CLASS_NAME}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	sed -e "s/\${CLASS_NAME}/${UPCLASS_NAME}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+}
+
+function replace_brief
+{
+	local TARGET_FILE=$1
+	shift
+	local BRIEF=$*
+	sed -e "s/\${brief}/${BRIEF}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+}
+
diff --git a/scripts/target_files.sh b/scripts/target_files.sh
new file mode 100644
index 0000000..21fbeba
--- /dev/null
+++ b/scripts/target_files.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+function copy_template_header
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/lib/${DEPLOYMENT}/${NAME}.h";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/header.h";
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	echo "${TARGET_FILE}";
+}
+
+function copy_template_impl
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/lib/${DEPLOYMENT}/${NAME}.cpp";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/impl.cpp";
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	echo "${TARGET_FILE}";
+}
+
diff --git a/scripts/test_files.sh b/scripts/test_files.sh
new file mode 100644
index 0000000..2e609ba
--- /dev/null
+++ b/scripts/test_files.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+#                     The MCLinker project
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+
+function ask_filename
+{
+	echo -n "What is the class you what to test for? ";
+}
+
+function ask_brief
+{
+	CLASS_NAME=$1
+	echo "Please brief the testcase (optional):"
+}
+
+function copy_template_header
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/unittests/${NAME}Test.h";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/headerTest.h";
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	echo "${TARGET_FILE}";
+}
+
+function copy_template_impl
+{
+	local NAME=$1
+	local DEPLOYMENT=$2
+	local TARGET_FILE="${MCLINKERTOP}/unittests/${NAME}Test.cpp";
+	local SOURCE_FILE="${MCLINKERTOP}/templates/implTest.cpp";
+	cp ${SOURCE_FILE} ${TARGET_FILE}
+	echo "${TARGET_FILE}";
+}
+
+function replace_author
+{
+	local TARGET_FILE=$1
+	shift
+	local AUTHOR=$*
+
+	sed "s/\${AUTHOR}/${AUTHOR}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+}
+
+function repalce_email
+{
+	local TARGET_FILE=$1
+	local EMAIL=$2
+	sed "s/\${EMAIL}/${EMAIL}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+
+	# adjust the length of header
+	NEW_SPACE=`grep '>                                                    *' ${TARGET_FILE}.tmp | wc -c`
+	NEW_SPACE=`expr 79 - ${NEW_SPACE}`
+	ADDEND=">";
+	if [ "${NEW_SPACE}" -gt "0" ]; then # add space
+		for (( i=0; i<${NEW_SPACE}; i=i+1 )); do
+			ADDEND="${ADDEND} ";
+		done
+		sed "s/${EMAIL}>/${EMAIL}${ADDEND}/" ${TARGET_FILE}.tmp > ${TARGET_FILE}
+	elif [ "${NEW_SPACE}" -lt "0" ]; then # strip space
+		for (( i=${NEW_SPACE}; i<0; i=i+1 )); do
+			ADDEND="${ADDEND} ";
+		done
+		sed "s/${EMAIL}${ADDEND}/${EMAIL}>/g" ${TARGET_FILE}.tmp > ${TARGET_FILE}
+
+	else #do nothing
+		mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+	fi
+
+	rm ${TARGET_FILE}.tmp
+	local EMAIL=$2
+}
+
+function replace_class
+{
+	local TARGET_FILE=$1
+	local CLASS_NAME=$2
+	local UPCLASS_NAME=`echo ${CLASS_NAME} | tr [:lower:] [:upper:]`
+
+	sed "s/\${class_name}/${CLASS_NAME}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	sed "s/\${CLASS_NAME}/${UPCLASS_NAME}/g" ${TARGET_FILE}.tmp > ${TARGET_FILE}
+	rm ${TARGET_FILE}.tmp
+}
+
+function replace_brief
+{
+	local TARGET_FILE=$1
+	shift
+	local BRIEF=$*
+	sed "s/\${brief}/${BRIEF}/g" ${TARGET_FILE} > ${TARGET_FILE}.tmp
+	mv ${TARGET_FILE}.tmp ${TARGET_FILE}
+}
+
diff --git a/templates/header.h b/templates/header.h
new file mode 100644
index 0000000..2b9acf7
--- /dev/null
+++ b/templates/header.h
@@ -0,0 +1,29 @@
+//===- header.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_${CLASS_NAME}_H
+#define MCLD_${CLASS_NAME}_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class ${class_name}
+ *  \brief ${brief}
+ */
+class ${class_name}
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/templates/headerTest.h b/templates/headerTest.h
new file mode 100644
index 0000000..be55559
--- /dev/null
+++ b/templates/headerTest.h
@@ -0,0 +1,50 @@
+//===- headerTest.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_${CLASS_NAME}_TEST_H
+#define MCLD_${CLASS_NAME}_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class ${class_name};
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class ${class_name}Test
+ *  \brief ${brief}
+ *
+ *  \see ${class_name} 
+ */
+class ${class_name}Test : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	${class_name}Test();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~${class_name}Test();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::${class_name}* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/templates/impl.cpp b/templates/impl.cpp
new file mode 100644
index 0000000..a3d0df2
--- /dev/null
+++ b/templates/impl.cpp
@@ -0,0 +1,15 @@
+//===- impl.cpp -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <${class_name}.h>
+
+using namespace mcld;
+
+//==========================
+// ${class_name}
+
diff --git a/templates/implTest.cpp b/templates/implTest.cpp
new file mode 100644
index 0000000..55ba332
--- /dev/null
+++ b/templates/implTest.cpp
@@ -0,0 +1,48 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <${class_name}.h>
+#include "${class_name}Test.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+${class_name}Test::${class_name}Test()
+{
+	// create testee. modify it if need
+	m_pTestee = new ${class_name}();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+${class_name}Test::~${class_name}Test()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void ${class_name}Test::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void ${class_name}Test::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+/** 
+TEST_F( ${class_name}Test, name of  the testcase for ${class_name} ) {
+	Write you exercise here
+}
+**/
+
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
new file mode 100644
index 0000000..835bb59
--- /dev/null
+++ b/tools/llvm-mcld/llvm-mcld.cpp
@@ -0,0 +1,908 @@
+//===- llvm-mcld.cpp ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Target/TargetMachine.h>
+#include <mcld/Support/TargetSelect.h>
+#include <mcld/Support/TargetRegistry.h>
+#include <mcld/Support/CommandLine.h>
+#include <mcld/Support/DerivedPositionDependentOptions.h>
+#include <mcld/Support/RealPath.h>
+#include <mcld/CodeGen/SectLinkerOption.h>
+
+#include <llvm/Module.h>
+#include <llvm/PassManager.h>
+#include <llvm/Pass.h>
+#include <llvm/ADT/Triple.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/MC/SubtargetFeature.h>
+#include <llvm/Support/CommandLine.h>
+#include <llvm/Support/Debug.h>
+#include <llvm/Support/FormattedStream.h>
+#include <llvm/Support/Host.h>
+#include <llvm/Support/IRReader.h>
+#include <llvm/Support/ManagedStatic.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/TargetSelect.h>
+#include <llvm/Support/ToolOutputFile.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Target/TargetMachine.h>
+
+using namespace llvm;
+
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+
+static cl::opt<bool>
+UnitTest("unittest",  cl::desc("do unit test") );
+
+int unit_test( int argc, char* argv[] )
+{
+  testing::InitGoogleTest( &argc, argv );
+  return RUN_ALL_TESTS();
+}
+
+#endif
+
+
+// General options for llc.  Other pass-specific options are specified
+// within the corresponding llc passes, and target-specific options
+// and back-end code generation options are specified with the target machine.
+//
+static cl::opt<std::string>
+InputFilename("dB",
+              cl::desc("set default bitcode"),
+              cl::value_desc("bitcode"));
+
+static cl::opt<std::string>
+OutputFilename("o",
+               cl::desc("Output filename"),
+               cl::value_desc("filename"));
+
+// Determine optimization level.
+static cl::opt<char>
+OptLevel("O",
+         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+                  "(default = '-O2')"),
+         cl::Prefix,
+         cl::ZeroOrMore,
+         cl::init(' '));
+
+static cl::opt<std::string>
+TargetTriple("mtriple", cl::desc("Override target triple for module"));
+
+static cl::opt<std::string>
+MArch("march", cl::desc("Architecture to generate code for (see --version)"));
+
+static cl::opt<std::string>
+MCPU("mcpu",
+  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+  cl::value_desc("cpu-name"),
+  cl::init(""));
+
+static cl::list<std::string>
+MAttrs("mattr",
+  cl::CommaSeparated,
+  cl::desc("Target specific attributes (-mattr=help for details)"),
+  cl::value_desc("a1,+a2,-a3,..."));
+
+static cl::opt<Reloc::Model>
+RelocModel("relocation-model",
+             cl::desc("Choose relocation model"),
+             cl::init(Reloc::Default),
+             cl::values(
+            clEnumValN(Reloc::Default, "default",
+                       "Target default relocation model"),
+            clEnumValN(Reloc::Static, "static",
+                       "Non-relocatable code"),
+            clEnumValN(Reloc::PIC_, "pic",
+                       "Fully relocatable, position independent code"),
+            clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
+                       "Relocatable external references, non-relocatable code"),
+            clEnumValEnd));
+
+static cl::opt<llvm::CodeModel::Model>
+CMModel("code-model",
+        cl::desc("Choose code model"),
+        cl::init(CodeModel::Default),
+        cl::values(clEnumValN(CodeModel::Default, "default",
+                              "Target default code model"),
+                   clEnumValN(CodeModel::Small, "small",
+                              "Small code model"),
+                   clEnumValN(CodeModel::Kernel, "kernel",
+                              "Kernel code model"),
+                   clEnumValN(CodeModel::Medium, "medium",
+                              "Medium code model"),
+                   clEnumValN(CodeModel::Large, "large",
+                              "Large code model"),
+                   clEnumValEnd));
+
+cl::opt<mcld::CodeGenFileType>
+FileType("filetype", cl::init(mcld::CGFT_EXEFile),
+  cl::desc("Choose a file type (not all types are supported by all targets):"),
+  cl::values(
+       clEnumValN(mcld::CGFT_ASMFile, "asm",
+                  "Emit an assembly ('.s') file"),
+       clEnumValN(mcld::CGFT_OBJFile, "obj",
+                  "Emit a relocatable object ('.o') file"),
+       clEnumValN(mcld::CGFT_ARCFile, "arc",
+                  "Emit an archive ('.a') file"),
+       clEnumValN(mcld::CGFT_DSOFile, "dso",
+                  "Emit an dynamic shared object ('.so') file"),
+       clEnumValN(mcld::CGFT_EXEFile, "exe",
+                  "Emit a executable ('.exe') file"),
+       clEnumValN(mcld::CGFT_NULLFile, "null",
+                  "Emit nothing, for performance testing"),
+       clEnumValEnd));
+
+cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
+                       cl::desc("Do not verify input module"));
+
+static cl::opt<bool>
+EnableFPMAD("enable-fp-mad",
+  cl::desc("Enable less precise MAD instructions to be generated"),
+  cl::init(false));
+
+static cl::opt<bool>
+PrintCode("print-machineinstrs",
+  cl::desc("Print generated machine code"),
+  cl::init(false));
+
+static cl::opt<bool>
+DisableFPElim("disable-fp-elim",
+  cl::desc("Disable frame pointer elimination optimization"),
+  cl::init(false));
+
+static cl::opt<bool>
+DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
+  cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
+  cl::init(false));
+
+static cl::opt<bool>
+DisableExcessPrecision("disable-excess-fp-precision",
+  cl::desc("Disable optimizations that may increase FP precision"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableUnsafeFPMath("enable-unsafe-fp-math",
+  cl::desc("Enable optimizations that may decrease FP precision"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableNoInfsFPMath("enable-no-infs-fp-math",
+  cl::desc("Enable FP math optimizations that assume no +-Infs"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableNoNaNsFPMath("enable-no-nans-fp-math",
+  cl::desc("Enable FP math optimizations that assume no NaNs"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
+  cl::Hidden,
+  cl::desc("Force codegen to assume rounding mode can change dynamically"),
+  cl::init(false));
+
+static cl::opt<bool>
+GenerateSoftFloatCalls("soft-float",
+  cl::desc("Generate software floating point library calls"),
+  cl::init(false));
+
+static cl::opt<llvm::FloatABI::ABIType>
+FloatABIForCalls("float-abi",
+  cl::desc("Choose float ABI type"),
+  cl::init(FloatABI::Default),
+  cl::values(
+    clEnumValN(FloatABI::Default, "default",
+               "Target default float ABI type"),
+    clEnumValN(FloatABI::Soft, "soft",
+               "Soft float ABI (implied by -soft-float)"),
+    clEnumValN(FloatABI::Hard, "hard",
+               "Hard float ABI (uses FP registers)"),
+    clEnumValEnd));
+
+static cl::opt<bool>
+DontPlaceZerosInBSS("nozero-initialized-in-bss",
+  cl::desc("Don't place zero-initialized symbols into bss section"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableJITExceptionHandling("jit-enable-eh",
+  cl::desc("Emit exception handling information"),
+  cl::init(false));
+
+// In debug builds, make this default to true.
+#ifdef NDEBUG
+#define EMIT_DEBUG false
+#else
+#define EMIT_DEBUG true
+#endif
+static cl::opt<bool>
+EmitJitDebugInfo("jit-emit-debug",
+  cl::desc("Emit debug information to debugger"),
+  cl::init(EMIT_DEBUG));
+#undef EMIT_DEBUG
+
+static cl::opt<bool>
+EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
+  cl::Hidden,
+  cl::desc("Emit debug info objfiles to disk"),
+  cl::init(false));
+
+static cl::opt<bool>
+EnableGuaranteedTailCallOpt("tailcallopt",
+  cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
+  cl::init(false));
+
+static cl::opt<unsigned>
+OverrideStackAlignment("stack-alignment",
+  cl::desc("Override default stack alignment"),
+  cl::init(0));
+
+static cl::opt<bool>
+EnableRealignStack("realign-stack",
+  cl::desc("Realign stack if needed"),
+  cl::init(true));
+
+static cl::opt<bool>
+DisableSwitchTables(cl::Hidden, "disable-jump-tables",
+  cl::desc("Do not generate jump tables."),
+  cl::init(false));
+
+static cl::opt<std::string>
+TrapFuncName("trap-func", cl::Hidden,
+  cl::desc("Emit a call to trap function rather than a trap instruction"),
+  cl::init(""));
+
+static cl::opt<bool>
+SegmentedStacks("segmented-stacks",
+  cl::desc("Use segmented stacks if possible."),
+  cl::init(false));
+
+//===----------------------------------------------------------------------===//
+// Command Line Options
+// There are four kinds of command line options:
+//   1. input, (may be a file, such as -m and /tmp/XXXX.o.)
+//   2. attribute of inputs, (describing the attributes of inputs, such as
+//      --as-needed and --whole-archive. usually be positional.)
+//   3. scripting options, (represent a subset of link scripting language, such
+//      as --defsym.)
+//   4. and general options. (the rest of options)
+//===----------------------------------------------------------------------===//
+// General Options
+static cl::opt<mcld::sys::fs::Path, false, llvm::cl::parser<mcld::sys::fs::Path> >
+ArgSysRoot("sysroot",
+           cl::desc("Use directory as the location of the sysroot, overriding the configure-time default."),
+           cl::value_desc("directory"),
+           cl::ValueRequired);
+
+static cl::list<mcld::MCLDDirectory, bool, llvm::cl::parser<mcld::MCLDDirectory> >
+ArgSearchDirList("L",
+                 cl::ZeroOrMore,
+                 cl::desc("Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts."),
+                 cl::value_desc("searchdir"),
+                 cl::Prefix);
+
+static cl::alias
+ArgSearchDirListAlias("library-path",
+                      cl::desc("alias for -L"),
+                      cl::aliasopt(ArgSearchDirList));
+
+static cl::opt<bool>
+ArgTrace("t",
+         cl::desc("Print the names of the input files as ld processes them."));
+
+static cl::alias
+ArgTraceAlias("trace",
+              cl::desc("alias for -t"),
+              cl::aliasopt(ArgTrace));
+
+static cl::opt<bool>
+ArgVerbose("V",
+          cl::desc("Display the version number for ld and list the linker emulations supported."));
+
+static cl::alias
+ArgVerboseAlias("verbose",
+                cl::desc("alias for -V"),
+                cl::aliasopt(ArgVerbose));
+
+static cl::opt<std::string>
+ArgEntry("e",
+         cl::desc("Use entry as the explicit symbol for beginning execution of your program."),
+         cl::value_desc("entry"),
+         cl::ValueRequired);
+
+static cl::alias
+ArgEntryAlias("entry",
+              cl::desc("alias for -e"),
+              cl::aliasopt(ArgEntry));
+
+static cl::opt<bool>
+ArgBsymbolic("Bsymbolic",
+             cl::desc("Bind references within the shared library."),
+             cl::init(false));
+
+static cl::opt<std::string>
+ArgSOName("soname",
+          cl::desc("Set internal name of shared library"),
+          cl::value_desc("name"));
+
+//===----------------------------------------------------------------------===//
+// Inputs
+static cl::list<mcld::sys::fs::Path>
+ArgInputObjectFiles(cl::Positional,
+                    cl::desc("[input object files]"),
+                    cl::ZeroOrMore);
+
+static cl::list<std::string>
+ArgNameSpecList("l",
+            cl::ZeroOrMore,
+            cl::desc("Add the archive or object file specified by namespec to the list of files to link."),
+            cl::value_desc("namespec"),
+            cl::Prefix);
+
+static cl::alias
+ArgNameSpecListAlias("library",
+                 cl::desc("alias for -l"),
+                 cl::aliasopt(ArgNameSpecList));
+
+static cl::list<bool>
+ArgStartGroupList("start-group",
+                  cl::ValueDisallowed,
+                  cl::desc("start to record a group of archives"));
+
+static cl::alias
+ArgStartGroupListAlias("(",
+                       cl::desc("alias for --start-group"),
+                       cl::aliasopt(ArgStartGroupList));
+
+static cl::list<bool>
+ArgEndGroupList("end-group",
+                cl::ValueDisallowed,
+                cl::desc("stop recording a group of archives"));
+
+static cl::alias
+ArgEndGroupListAlias(")",
+                     cl::desc("alias for --end-group"),
+                     cl::aliasopt(ArgEndGroupList));
+
+//===----------------------------------------------------------------------===//
+// Attributes of Inputs
+static cl::list<bool>
+ArgWholeArchiveList("whole-archive",
+                    cl::ValueDisallowed,
+                    cl::desc("For each archive mentioned on the command line after the --whole-archive option, include all object files in the archive."));
+
+static cl::list<bool>
+ArgNoWholeArchiveList("no-whole-archive",
+                    cl::ValueDisallowed,
+                    cl::desc("Turn off the effect of the --whole-archive option for subsequent archive files."));
+
+static cl::list<bool>
+ArgAsNeededList("as-needed",
+                cl::ValueDisallowed,
+                cl::desc("This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option."));
+
+static cl::list<bool>
+ArgNoAsNeededList("no-as-needed",
+                cl::ValueDisallowed,
+                cl::desc("Turn off the effect of the --as-needed option for subsequent dynamic libraries"));
+
+static cl::list<bool>
+ArgAddNeededList("add-needed",
+                cl::ValueDisallowed,
+                cl::desc("--add-needed causes DT_NEEDED tags are always emitted for those libraries from DT_NEEDED tags. This is the default behavior."));
+
+static cl::list<bool>
+ArgNoAddNeededList("no-add-needed",
+                cl::ValueDisallowed,
+                cl::desc("--no-add-needed causes DT_NEEDED tags will never be emitted for those libraries from DT_NEEDED tags"));
+
+static cl::list<bool>
+ArgBDynamicList("Bdynamic",
+                cl::ValueDisallowed,
+                cl::desc("Link against dynamic library"));
+
+static cl::alias
+ArgBDynamicListAlias1("dy",
+                     cl::desc("alias for --Bdynamic"),
+                     cl::aliasopt(ArgBDynamicList));
+
+static cl::alias
+ArgBDynamicListAlias2("call_shared",
+                     cl::desc("alias for --Bdynamic"),
+                     cl::aliasopt(ArgBDynamicList));
+
+static cl::list<bool>
+ArgBStaticList("Bstatic",
+                cl::ValueDisallowed,
+                cl::desc("Link against static library"));
+
+static cl::alias
+ArgBStaticListAlias1("dn",
+                     cl::desc("alias for --Bstatic"),
+                     cl::aliasopt(ArgBStaticList));
+
+static cl::alias
+ArgBStaticListAlias2("static",
+                     cl::desc("alias for --Bstatic"),
+                     cl::aliasopt(ArgBStaticList));
+
+static cl::alias
+ArgBStaticListAlias3("non_shared",
+                     cl::desc("alias for --Bstatic"),
+                     cl::aliasopt(ArgBStaticList));
+
+//===----------------------------------------------------------------------===//
+// Scripting Options
+
+
+//===----------------------------------------------------------------------===//
+/// non-member functions
+
+// GetFileNameRoot - Helper function to get the basename of a filename.
+static inline void
+GetFileNameRoot(const std::string &pInputFilename, std::string& pFileNameRoot)
+{
+  std::string outputFilename;
+  /* *** */
+  const std::string& IFN = pInputFilename;
+  int Len = IFN.length();
+  if ((Len > 2) &&
+      IFN[Len-3] == '.' &&
+      ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') ||
+       (IFN[Len-2] == 'l' && IFN[Len-1] == 'l')))
+    pFileNameRoot = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
+  else
+    pFileNameRoot = std::string(IFN);
+}
+
+static tool_output_file *GetOutputStream(const char* pTargetName,
+                          Triple::OSType pOSType,
+                          mcld::CodeGenFileType pFileType,
+                          const std::string& pInputFilename,
+                          std::string& pOutputFilename)
+{
+  // If we don't yet have an output filename, make one.
+  if (pOutputFilename.empty()) {
+    if (pInputFilename == "-")
+      pOutputFilename = "-";
+    else {
+      GetFileNameRoot(pInputFilename, pOutputFilename);
+
+      switch (pFileType) {
+      case mcld::CGFT_ASMFile:
+        if (pTargetName[0] == 'c') {
+          if (pTargetName[1] == 0)
+            pOutputFilename += ".cbe.c";
+          else if (pTargetName[1] == 'p' && pTargetName[2] == 'p')
+            pOutputFilename += ".cpp";
+          else
+            pOutputFilename += ".s";
+        }
+        else
+          pOutputFilename += ".s";
+        break;
+      case mcld::CGFT_OBJFile:
+        if (pOSType == Triple::Win32)
+          pOutputFilename += ".obj";
+        else
+          pOutputFilename += ".o";
+        break;
+      case mcld::CGFT_DSOFile:
+        if (pOSType == Triple::Win32)
+         pOutputFilename += ".dll";
+        else
+         pOutputFilename += ".so";
+        break;
+      case mcld::CGFT_ARCFile:
+         pOutputFilename += ".a";
+        break;
+      case mcld::CGFT_EXEFile:
+      case mcld::CGFT_NULLFile:
+        // do nothing
+        break;
+      default:
+        assert(0 && "Unknown file type");
+      }
+    }
+  }
+
+  // Decide if we need "binary" output.
+  bool Binary = false;
+  switch (pFileType) {
+  default: assert(0 && "Unknown file type");
+  case mcld::CGFT_ASMFile:
+    break;
+  case mcld::CGFT_ARCFile:
+  case mcld::CGFT_OBJFile:
+  case mcld::CGFT_DSOFile:
+  case mcld::CGFT_EXEFile:
+  case mcld::CGFT_NULLFile:
+    Binary = true;
+    break;
+  }
+
+  // Open the file.
+  std::string error;
+  unsigned OpenFlags = 0;
+  if (Binary) OpenFlags |= raw_fd_ostream::F_Binary;
+  tool_output_file *FDOut = new tool_output_file(pOutputFilename.c_str(), error,
+                                                 OpenFlags);
+  if (!error.empty()) {
+    errs() << error << '\n';
+    delete FDOut;
+    return 0;
+  }
+
+  return FDOut;
+}
+
+static bool ProcessLinkerInputsFromCommand(mcld::SectLinkerOption &pOption) {
+  // -----  Set up General Options  ----- //
+  // set up soname
+  pOption.info().output().setSOName(ArgSOName);
+
+  // set up sysroot
+  if (!ArgSysRoot.empty()) {
+    if (exists(ArgSysRoot) && is_directory(ArgSysRoot))
+      pOption.info().options().setSysroot(ArgSysRoot);
+  }
+
+  // add all search directories
+  cl::list<mcld::MCLDDirectory>::iterator sd;
+  cl::list<mcld::MCLDDirectory>::iterator sdEnd = ArgSearchDirList.end();
+  for (sd=ArgSearchDirList.begin(); sd!=sdEnd; ++sd) {
+    if (sd->isInSysroot())
+      sd->setSysroot(pOption.info().options().sysroot());
+    if (exists(sd->path()) && is_directory(sd->path())) {
+      pOption.info().options().directories().add(*sd);
+    }
+    else {
+      // FIXME: need a warning function
+      errs() << "WARNING: can not open search directory `-L"
+             << sd->name()
+             << "'.\n";
+    }
+  }
+
+  pOption.info().options().setTrace(ArgTrace);
+  pOption.info().options().setVerbose(ArgVerbose);
+  pOption.info().options().setEntry(ArgEntry);
+  pOption.info().options().setBsymbolic(ArgBsymbolic);
+
+  // -----  Set up Inputs  ----- //
+  // add all start-group
+  cl::list<bool>::iterator sg;
+  cl::list<bool>::iterator sgEnd = ArgStartGroupList.end();
+  for (sg=ArgStartGroupList.begin(); sg!=sgEnd; ++sg) {
+    // calculate position
+    pOption.appendOption(new mcld::StartGroupOption(
+                                    ArgStartGroupList.getPosition(sg-ArgStartGroupList.begin())));
+  }
+
+  // add all end-group
+  cl::list<bool>::iterator eg;
+  cl::list<bool>::iterator egEnd = ArgEndGroupList.end();
+  for (eg=ArgEndGroupList.begin(); eg!=egEnd; ++eg) {
+    // calculate position
+    pOption.appendOption(new mcld::EndGroupOption(
+                                    ArgEndGroupList.getPosition(eg-ArgEndGroupList.begin())));
+  }
+
+  // add all namespecs
+  cl::list<std::string>::iterator ns;
+  cl::list<std::string>::iterator nsEnd = ArgNameSpecList.end();
+  for (ns=ArgNameSpecList.begin(); ns!=nsEnd; ++ns) {
+    // calculate position
+    pOption.appendOption(new mcld::NamespecOption(
+                                    ArgNameSpecList.getPosition(ns-ArgNameSpecList.begin()),
+                                    *ns));
+  }
+
+  // add all object files
+  cl::list<mcld::sys::fs::Path>::iterator obj;
+  cl::list<mcld::sys::fs::Path>::iterator objEnd = ArgInputObjectFiles.end();
+  for (obj=ArgInputObjectFiles.begin(); obj!=objEnd; ++obj) {
+    // calculate position
+    pOption.appendOption(new mcld::InputFileOption(
+                                    ArgInputObjectFiles.getPosition(obj-ArgInputObjectFiles.begin()),
+                                    *obj));
+  }
+
+  // -----  Set up Attributes of Inputs  ----- //
+  // --whole-archive
+  cl::list<bool>::iterator attr = ArgWholeArchiveList.begin();
+  cl::list<bool>::iterator attrEnd = ArgWholeArchiveList.end();
+  for (; attr!=attrEnd; ++attr) {
+    pOption.appendOption(new mcld::WholeArchiveOption(
+                                    ArgWholeArchiveList.getPosition(attr-ArgWholeArchiveList.begin())));
+  }
+
+  // --no-whole-archive
+  attr = ArgNoWholeArchiveList.begin();
+  attrEnd = ArgNoWholeArchiveList.end();
+  for (; attr!=attrEnd; ++attr) {
+    pOption.appendOption(new mcld::NoWholeArchiveOption(
+                                    ArgNoWholeArchiveList.getPosition(attr-ArgNoWholeArchiveList.begin())));
+  }
+
+  // --as-needed
+  attr = ArgAsNeededList.begin();
+  attrEnd = ArgAsNeededList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::AsNeededOption(
+                                    ArgAsNeededList.getPosition(attr-ArgAsNeededList.begin())));
+    ++attr;
+  }
+
+  // --no-as-needed
+  attr = ArgNoAsNeededList.begin();
+  attrEnd = ArgNoAsNeededList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::NoAsNeededOption(
+                                    ArgNoAsNeededList.getPosition(attr-ArgNoAsNeededList.begin())));
+    ++attr;
+  }
+
+  // --add-needed
+  attr = ArgAddNeededList.begin();
+  attrEnd = ArgAddNeededList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::AddNeededOption(
+                                    ArgAddNeededList.getPosition(attr-ArgAddNeededList.begin())));
+    ++attr;
+  }
+
+  // --no-add-needed
+  attr = ArgNoAddNeededList.begin();
+  attrEnd = ArgNoAddNeededList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::NoAddNeededOption(
+                                    ArgNoAddNeededList.getPosition(attr-ArgNoAddNeededList.begin())));
+    ++attr;
+  }
+
+  // -Bdynamic
+  attr = ArgBDynamicList.begin();
+  attrEnd = ArgBDynamicList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::BDynamicOption(
+                                    ArgBDynamicList.getPosition(attr-ArgBDynamicList.begin())));
+  }
+
+  // -Bstatic
+  attr = ArgBStaticList.begin();
+  attrEnd = ArgBStaticList.end();
+  while(attr != attrEnd) {
+    pOption.appendOption(new mcld::BStaticOption(
+                                    ArgBStaticList.getPosition(attr-ArgBStaticList.begin())));
+    ++attr;
+  }
+
+  // -----  Set up Scripting Options  ----- //
+
+  return false;
+}
+
+int main( int argc, char* argv[] )
+{
+
+  LLVMContext &Context = getGlobalContext();
+  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
+  // Initialize targets first, so that --version shows registered targets.
+  InitializeAllTargets();
+  InitializeAllAsmPrinters();
+  InitializeAllAsmParsers();
+  InitializeAllTargetMCs();
+  mcld::InitializeAllTargets();
+  mcld::InitializeAllLinkers();
+  cl::ParseCommandLineOptions(argc, argv, "llvm MCLinker\n");
+
+#ifdef ENABLE_UNITTEST
+  if (UnitTest) {
+    return unit_test( argc, argv );
+  }
+#endif
+
+  // Load the module to be compiled...
+  std::auto_ptr<Module> M;
+
+  if (InputFilename.empty() && (FileType != mcld::CGFT_DSOFile)) {
+    // Read from stdin
+    InputFilename = "-";
+  }
+
+  if (!InputFilename.empty()) {
+    SMDiagnostic Err;
+    M.reset(ParseIRFile(InputFilename, Err, Context));
+
+    if (M.get() == 0) {
+      Err.print(argv[0], errs());
+      errs() << "** Failed to to the given bitcode/llvm asm file '"
+             << InputFilename << "'. **\n";
+      return 1;
+    }
+  } else {
+    // If here, output must be dynamic shared object (mcld::CGFT_DSOFile).
+
+    // Create an empty Module
+    M.reset(new Module("Empty Module", Context));
+  }
+  Module &mod = *M.get();
+
+  // If we are supposed to override the target triple, do so now.
+  Triple TheTriple;
+  if (!TargetTriple.empty()) {
+    TheTriple.setTriple(TargetTriple);
+    mod.setTargetTriple(TargetTriple);
+  }
+
+  // User doesn't specify the triple from command.
+  if (TheTriple.getTriple().empty()) {
+    // Try to get one from the input Module.
+    const std::string &TripleStr = mod.getTargetTriple();
+
+    if (TripleStr.empty())
+      TheTriple.setTriple(sys::getDefaultTargetTriple());
+    else
+      TheTriple.setTriple(TripleStr);
+  }
+
+  // Allocate target machine.  First, check whether the user has explicitly
+  // specified an architecture to compile for. If so we have to look it up by
+  // name, because it might be a backend that has no mapping to a target triple.
+  const mcld::Target *TheTarget = 0;
+  if (!MArch.empty()) {
+    for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(),
+           ie = mcld::TargetRegistry::end(); it != ie; ++it) {
+      if (MArch == (*it)->get()->getName()) {
+        TheTarget = *it;
+        break;
+      }
+    }
+
+    if (!TheTarget) {
+      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
+      return 1;
+    }
+
+    // Adjust the triple to match (if known), otherwise stick with the
+    // module/host triple.
+    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
+    if (Type != Triple::UnknownArch)
+      TheTriple.setArch(Type);
+  }
+  else {
+    std::string Err;
+    TheTarget = mcld::TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
+    if (TheTarget == 0) {
+      errs() << argv[0] << ": error auto-selecting target for module '"
+             << Err << "'.  Please use the -march option to explicitly "
+             << "pick a target.\n";
+      return 1;
+    }
+  }
+
+  // Package up features to be passed to target/subtarget
+  std::string FeaturesStr;
+  if (MAttrs.size()) {
+    SubtargetFeatures Features;
+    for (unsigned i = 0; i != MAttrs.size(); ++i)
+      Features.AddFeature(MAttrs[i]);
+    FeaturesStr = Features.getString();
+  }
+
+  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
+  switch (OptLevel) {
+  default:
+    errs() << argv[0] << ": invalid optimization level.\n";
+    return 1;
+  case ' ': break;
+  case '0': OLvl = CodeGenOpt::None; break;
+  case '1': OLvl = CodeGenOpt::Less; break;
+  case '2': OLvl = CodeGenOpt::Default; break;
+  case '3': OLvl = CodeGenOpt::Aggressive; break;
+  }
+
+  TargetOptions Options;
+  Options.LessPreciseFPMADOption = EnableFPMAD;
+  Options.PrintMachineCode = PrintCode;
+  Options.NoFramePointerElim = DisableFPElim;
+  Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
+  Options.NoExcessFPPrecision = DisableExcessPrecision;
+  Options.UnsafeFPMath = EnableUnsafeFPMath;
+  Options.NoInfsFPMath = EnableNoInfsFPMath;
+  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+  Options.HonorSignDependentRoundingFPMathOption =
+      EnableHonorSignDependentRoundingFPMath;
+  Options.UseSoftFloat = GenerateSoftFloatCalls;
+  if (FloatABIForCalls != FloatABI::Default)
+    Options.FloatABIType = FloatABIForCalls;
+  Options.NoZerosInBSS = DontPlaceZerosInBSS;
+  Options.JITExceptionHandling = EnableJITExceptionHandling;
+  Options.JITEmitDebugInfo = EmitJitDebugInfo;
+  Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
+  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+  Options.StackAlignmentOverride = OverrideStackAlignment;
+  Options.RealignStack = EnableRealignStack;
+  Options.DisableJumpTables = DisableSwitchTables;
+  Options.TrapFuncName = TrapFuncName;
+  Options.EnableSegmentedStacks = SegmentedStacks;
+
+  std::auto_ptr<mcld::LLVMTargetMachine> target_machine(
+          TheTarget->createTargetMachine(TheTriple.getTriple(),
+                                         MCPU, FeaturesStr, Options,
+                                         RelocModel, CMModel, OLvl));
+  assert(target_machine.get() && "Could not allocate target machine!");
+  mcld::LLVMTargetMachine &TheTargetMachine = *target_machine.get();
+
+  TheTargetMachine.getTM().setMCUseLoc(false);
+  TheTargetMachine.getTM().setMCUseCFI(false);
+
+  // Figure out where we are going to send the output...
+  OwningPtr<tool_output_file>
+  Out(GetOutputStream(TheTarget->get()->getName(),
+                      TheTriple.getOS(),
+                      FileType,
+                      InputFilename,
+                      OutputFilename));
+  if (!Out) return 1;
+
+  // Build up all of the passes that we want to do to the module.
+  PassManager PM;
+
+  // Add the target data from the target machine, if it exists, or the module.
+  if (const TargetData *TD = TheTargetMachine.getTM().getTargetData())
+    PM.add(new TargetData(*TD));
+  else
+    PM.add(new TargetData(&mod));
+
+  // Override default to generate verbose assembly.
+  TheTargetMachine.getTM().setAsmVerbosityDefault(true);
+
+  // Process the linker input from the command line
+  mcld::SectLinkerOption *LinkerOpt =
+      new mcld::SectLinkerOption(TheTargetMachine.getLDInfo());
+
+  if (ProcessLinkerInputsFromCommand(*LinkerOpt)) {
+    errs() << argv[0] << ": failed to process inputs from command line!\n";
+    return 1;
+  }
+
+  {
+    formatted_raw_ostream FOS(Out->os());
+
+    // Ask the target to add backend passes as necessary.
+    if( TheTargetMachine.addPassesToEmitFile(PM,
+                                             FOS,
+                                             OutputFilename,
+                                             FileType,
+                                             OLvl,
+                                             LinkerOpt,
+                                             NoVerify)) {
+      errs() << argv[0] << ": target does not support generation of this"
+             << " file type!\n";
+      return 1;
+    }
+
+    // Before executing passes, print the final values of the LLVM options.
+    cl::PrintOptionValues();
+
+    PM.run(mod);
+  }
+
+  // Declare success.
+  Out->keep();
+
+  // clean up
+  delete LinkerOpt;
+
+  return 0;
+}
+
diff --git a/unittests/BinTreeTest.cpp b/unittests/BinTreeTest.cpp
new file mode 100644
index 0000000..bce4b24
--- /dev/null
+++ b/unittests/BinTreeTest.cpp
@@ -0,0 +1,275 @@
+//===- BinTreeTest.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "BinTreeTest.h"
+
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/MC/MCLDInputTree.h"
+#include <string>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+BinTreeTest::BinTreeTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new BinaryTree<int>();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+BinTreeTest::~BinTreeTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void BinTreeTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void BinTreeTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+
+/// General 
+TEST_F( BinTreeTest,Two_non_null_tree_merge) 
+{
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,0);
+  --pos;
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,1);
+  m_pTestee->join<TreeIteratorBase::Leftward>(pos,1);
+  --pos;
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,2);
+  m_pTestee->join<TreeIteratorBase::Leftward>(pos,2);
+
+  BinaryTree<int> *mergeTree = new BinaryTree<int>;
+  BinaryTree<int>::iterator pos2 = mergeTree->root();
+  mergeTree->join<TreeIteratorBase::Rightward>(pos2,1);
+  --pos2;
+  mergeTree->join<TreeIteratorBase::Rightward>(pos2,1);
+  mergeTree->join<TreeIteratorBase::Leftward>(pos2,1);
+
+  m_pTestee->merge<TreeIteratorBase::Rightward>(pos,*mergeTree); 
+  delete mergeTree;
+  EXPECT_TRUE(m_pTestee->size()==8);
+}
+
+/// ---- TEST - 2 ----
+TEST_F( BinTreeTest, A_null_tree_merge_a_non_null_tree) 
+{ 
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+ 
+  BinaryTree<int> *mergeTree = new BinaryTree<int>;
+  mergeTree->join<TreeIteratorBase::Rightward>(pos,0);
+  --pos;
+  mergeTree->join<TreeIteratorBase::Rightward>(pos,1);
+  mergeTree->join<TreeIteratorBase::Leftward>(pos,1);
+  --pos;
+  mergeTree->join<TreeIteratorBase::Rightward>(pos,2);
+  mergeTree->join<TreeIteratorBase::Leftward>(pos,2);
+
+  m_pTestee->merge<TreeIteratorBase::Rightward>(pos,*mergeTree); 
+
+  delete mergeTree;
+  EXPECT_TRUE(m_pTestee->size()==5);
+}
+
+TEST_F( BinTreeTest, A_non_null_tree_merge_a_null_tree) 
+{ 
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,0);
+  --pos;
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,1);
+  m_pTestee->join<TreeIteratorBase::Leftward>(pos,1);
+  --pos;
+  m_pTestee->join<TreeIteratorBase::Rightward>(pos,2);
+  m_pTestee->join<TreeIteratorBase::Leftward>(pos,2);
+  
+  BinaryTree<int> *mergeTree = new BinaryTree<int>;
+  BinaryTree<int>::iterator pos2 = mergeTree->root(); 
+  mergeTree->merge<TreeIteratorBase::Rightward>(pos2,*m_pTestee); 
+
+  //delete m_pTestee;
+  EXPECT_TRUE(mergeTree->size()==5);
+  delete mergeTree;
+}
+
+TEST_F( BinTreeTest, Two_null_tree_merge) 
+{ 
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+ 
+  BinaryTree<int> *mergeTree = new BinaryTree<int>;
+  BinaryTree<int>::iterator pos2 = mergeTree->root(); 
+
+  mergeTree->merge<TreeIteratorBase::Rightward>(pos2,*m_pTestee); 
+
+  //delete m_pTestee;
+  EXPECT_TRUE(mergeTree->size()==0);
+  delete mergeTree;
+}
+
+TEST_F( BinTreeTest, DFSIterator_BasicTraversal)
+{
+  int a = 111;
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  
+  m_pTestee->join<InputTree::Inclusive>(pos,a);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,10);
+  m_pTestee->join<InputTree::Inclusive>(pos,9);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,8);
+  m_pTestee->join<InputTree::Inclusive>(pos,7);
+  
+  BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin(); 
+  BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end(); 
+
+  ASSERT_EQ(111, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(9, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(7, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(8, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(10, **dfs_it);
+  ++dfs_it;
+  ASSERT_TRUE( dfs_it ==  dfs_end);
+  BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin(); 
+  BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end(); 
+}
+
+TEST_F( BinTreeTest, DFSIterator_RightMostTree)
+{
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<InputTree::Inclusive>(pos,0);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,1);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,2);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,3);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,4);
+  
+  BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin(); 
+  BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end(); 
+
+  ASSERT_EQ(0, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(1, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(2, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(3, **dfs_it);
+  ++dfs_it;
+  ASSERT_EQ(4, **dfs_it);
+  ++dfs_it;
+  ASSERT_TRUE( dfs_it ==  dfs_end);
+}
+
+
+TEST_F( BinTreeTest, DFSIterator_SingleNode)
+{
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<InputTree::Inclusive>(pos,0);
+  BinaryTree<int>::dfs_iterator dfs_it = m_pTestee->dfs_begin(); 
+  BinaryTree<int>::dfs_iterator dfs_end = m_pTestee->dfs_end(); 
+  int counter = 0;
+  while( dfs_it != dfs_end ) {
+    ++counter;
+    ++dfs_it;
+  }
+  ASSERT_EQ(1, counter);
+}
+
+TEST_F( BinTreeTest, BFSIterator_BasicTraversal)
+{
+  int a = 111;
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  
+  m_pTestee->join<InputTree::Inclusive>(pos,a);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,10);
+  m_pTestee->join<InputTree::Inclusive>(pos,9);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,8);
+  m_pTestee->join<InputTree::Inclusive>(pos,7);
+  
+  BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin(); 
+  BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end(); 
+
+  ASSERT_EQ(111, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(10, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(9, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(8, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(7, **bfs_it);
+  ++bfs_it;
+  ASSERT_TRUE(bfs_it ==  bfs_end);
+  bfs_it = m_pTestee->bfs_begin(); 
+  bfs_end = m_pTestee->bfs_end(); 
+}
+
+TEST_F( BinTreeTest, BFSIterator_RightMostTree)
+{
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<InputTree::Inclusive>(pos,0);
+  pos.move<InputTree::Inclusive>();
+  m_pTestee->join<InputTree::Positional>(pos,1);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,2);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,3);
+  pos.move<InputTree::Positional>();
+  m_pTestee->join<InputTree::Positional>(pos,4);
+  
+  BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin(); 
+  BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end(); 
+
+  ASSERT_EQ(0, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(1, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(2, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(3, **bfs_it);
+  ++bfs_it;
+  ASSERT_EQ(4, **bfs_it);
+  ++bfs_it;
+  ASSERT_TRUE( bfs_it ==  bfs_end);
+}
+
+
+TEST_F( BinTreeTest, BFSIterator_SingleNode)
+{
+  BinaryTree<int>::iterator pos = m_pTestee->root();
+  m_pTestee->join<InputTree::Inclusive>(pos,0);
+  BinaryTree<int>::bfs_iterator bfs_it = m_pTestee->bfs_begin(); 
+  BinaryTree<int>::bfs_iterator bfs_end = m_pTestee->bfs_end(); 
+  int counter = 0;
+  while( bfs_it != bfs_end ) {
+    ++counter;
+    ++bfs_it;
+  }
+  ASSERT_EQ(1, counter);
+}
+
+
diff --git a/unittests/BinTreeTest.h b/unittests/BinTreeTest.h
new file mode 100644
index 0000000..3e8fab4
--- /dev/null
+++ b/unittests/BinTreeTest.h
@@ -0,0 +1,52 @@
+//===- BinTreeTest.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef BINTREE_TEST_H
+#define BINTREE_TEST_H
+
+#include "mcld/ADT/BinTree.h"
+
+#include <gtest.h>
+
+namespace mcld
+{
+class BinTree;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class BinTreeTest
+ *  \brief Make sure the interface of BinTree , such as insert , traversal , etc..
+ *
+ *  \see BinTree 
+ */
+class BinTreeTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	BinTreeTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~BinTreeTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::BinaryTree<int>* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/DirIteratorTest.cpp b/unittests/DirIteratorTest.cpp
new file mode 100644
index 0000000..f319172
--- /dev/null
+++ b/unittests/DirIteratorTest.cpp
@@ -0,0 +1,64 @@
+//===- DirIteratorTest.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/Directory.h"
+#include "DirIteratorTest.h"
+#include "errno.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+DirIteratorTest::DirIteratorTest()
+{
+  //FIXME:Some bugs modifies the global value "errno" to non-zero.
+  //      This makes readir() failed when daily build system runs unittest
+  //      Remove this after fixing those bugs
+  errno = 0;
+
+  // create testee. modify it if need
+  m_pDir = new mcld::sys::fs::Directory(".");
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+DirIteratorTest::~DirIteratorTest()
+{
+  delete m_pDir;
+}
+
+// SetUp() will be called immediately before each test.
+void DirIteratorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void DirIteratorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( DirIteratorTest, open_dir ) {
+	ASSERT_TRUE( m_pDir->isGood() );
+
+  Directory::iterator entry = m_pDir->begin();
+  Directory::iterator enEnd = m_pDir->end();
+
+  size_t size = 0;
+  while( entry!=enEnd ) {
+    if (0 != entry.path())
+      size = entry.path()->native().size();
+
+    ++entry;
+  }
+}
+
+
diff --git a/unittests/DirIteratorTest.h b/unittests/DirIteratorTest.h
new file mode 100644
index 0000000..1f6e616
--- /dev/null
+++ b/unittests/DirIteratorTest.h
@@ -0,0 +1,52 @@
+//===- DirIteratorTest.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DIR_ITERATOR_TEST_H
+#define MCLD_DIR_ITERATOR_TEST_H
+
+#include <gtest.h>
+
+namespace mcld {
+namespace sys {
+namespace fs {
+class Directory;
+class DirIterator;
+}
+}
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class DirIteratorTest
+ *  \brief 
+ *
+ *  \see DirIterator 
+ */
+class DirIteratorTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	DirIteratorTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~DirIteratorTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+protected:
+	mcld::sys::fs::Directory *m_pDir;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/FactoriesTest.cpp b/unittests/FactoriesTest.cpp
new file mode 100644
index 0000000..9301fb9
--- /dev/null
+++ b/unittests/FactoriesTest.cpp
@@ -0,0 +1,220 @@
+//===- FactoriesTest.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <cstdlib>
+#include "FactoriesTest.h"
+#include <string>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+FactoriesTest::FactoriesTest()
+{
+	m_pNodeAlloc = new NodeAlloc();
+	m_pFileAlloc = new FileAlloc();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+FactoriesTest::~FactoriesTest()
+{
+	delete m_pNodeAlloc;
+	delete m_pFileAlloc;
+}
+
+// SetUp() will be called immediately before each test.
+void FactoriesTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void FactoriesTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( FactoriesTest, node_produce ) {
+	NodeAlloc::NodeType* node = m_pNodeAlloc->produce();
+	ASSERT_EQ(1, m_pNodeAlloc->size());
+	ASSERT_FALSE(m_pNodeAlloc->empty());
+	node = m_pNodeAlloc->produce();
+	ASSERT_EQ(2, m_pNodeAlloc->size());
+	ASSERT_FALSE(m_pNodeAlloc->empty());
+	node = m_pNodeAlloc->produce();
+	ASSERT_EQ(3, m_pNodeAlloc->size());
+	ASSERT_FALSE(m_pNodeAlloc->empty());
+}
+
+TEST_F( FactoriesTest, node_iterate ) {
+	NodeAlloc::NodeType* node = 0;
+	for (int i=0 ; i<100; ++i) {
+		node = m_pNodeAlloc->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = i;
+	}
+
+	int counter = 0;
+	NodeAlloc::iterator data = m_pNodeAlloc->begin();
+	NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+	for (; data!=dEnd; ++data) {
+		ASSERT_EQ(counter, *(*data).data );
+		free((*data).data);
+		(*data).data = 0;
+		++counter;
+	}
+}
+
+TEST_F( FactoriesTest, node_delegate_empty ) {
+	NodeAlloc::NodeType* node = 0;
+	for (int i=0 ; i<100; ++i) {
+		node = m_pNodeAlloc->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = i;
+	}
+	NodeAlloc* delegatee = new NodeAlloc();
+	m_pNodeAlloc->delegate(*delegatee);
+	ASSERT_EQ(100, m_pNodeAlloc->size());
+	int counter = 0;
+	NodeAlloc::iterator data = m_pNodeAlloc->begin();
+	NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+	for (; data!=dEnd; ++data) {
+		ASSERT_EQ(counter, *(*data).data );
+		free((*data).data);
+		(*data).data = 0;
+		++counter;
+	}
+	delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_empty_delegate ) {
+	NodeAlloc::NodeType* node = 0;
+	NodeAlloc* delegatee = new NodeAlloc();
+	for (int i=0 ; i<100; ++i) {
+		node = delegatee->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = i;
+	}
+	m_pNodeAlloc->delegate(*delegatee);
+	ASSERT_EQ(100, m_pNodeAlloc->size());
+	int counter = 0;
+	NodeAlloc::iterator data = m_pNodeAlloc->begin();
+	NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+	for (; data!=dEnd; ++data) {
+		ASSERT_EQ(counter, *(*data).data );
+		free((*data).data);
+		(*data).data = 0;
+		++counter;
+	}
+	ASSERT_EQ(0, delegatee->size());
+	ASSERT_TRUE(delegatee->empty());
+	delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_delegate ) {
+	NodeAlloc::NodeType* node = 0;
+	NodeAlloc* delegatee = new NodeAlloc();
+	int counter = 0;
+	// produce agent
+	for (int i=0 ; i<100; ++i) {
+		node = m_pNodeAlloc->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = counter;
+		++counter;
+	}
+
+	// produce delegatee
+	for (int i=0 ; i<100; ++i) {
+		node = delegatee->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = counter;
+		++counter;
+	}
+
+	m_pNodeAlloc->delegate(*delegatee);
+	ASSERT_EQ(200, m_pNodeAlloc->size());
+	ASSERT_FALSE(m_pNodeAlloc->empty());
+	NodeAlloc::iterator data = m_pNodeAlloc->begin();
+	NodeAlloc::iterator dEnd = m_pNodeAlloc->end();
+	for ( counter = 0; data!=dEnd; ++data) {
+		ASSERT_EQ(counter, *(*data).data );
+		free((*data).data);
+		(*data).data = 0;
+		++counter;
+	}
+	ASSERT_EQ(0, delegatee->size());
+	ASSERT_TRUE(delegatee->empty());
+	delete delegatee;
+}
+
+TEST_F( FactoriesTest, node_delegate_self ) {
+	NodeAlloc::NodeType* node = 0;
+	for (int i=0 ; i<100; ++i) {
+		node = m_pNodeAlloc->produce();
+		node->data = (int*)malloc(sizeof(int));
+		*(node->data) = i;
+	}
+	ASSERT_EQ(100, m_pNodeAlloc->size());
+	m_pNodeAlloc->delegate(*m_pNodeAlloc);
+	ASSERT_EQ(100, m_pNodeAlloc->size());
+	ASSERT_FALSE(m_pNodeAlloc->empty());
+}
+
+TEST_F( FactoriesTest, file_produce ) {
+	int counter = 0;
+	for (counter=1; counter<1000; ++counter) {
+		MCLDFile* file = m_pFileAlloc->produce();
+		ASSERT_EQ(counter, m_pFileAlloc->size());
+		ASSERT_FALSE(m_pFileAlloc->empty());
+	}
+}
+
+TEST_F( FactoriesTest, file_produce_by_params ) {
+	int counter = 0;
+	for (counter=1; counter<1000; ++counter) {
+		char name[100];
+		sprintf(name, "file %d", counter);
+		char path_name[100];
+		sprintf(path_name, "/proj/mtk%d", counter);
+		MCLDFile* file = m_pFileAlloc->produce( string(name),
+							sys::fs::Path(string(path_name)),
+							MCLDFile::Archive);
+		ASSERT_EQ(counter, m_pFileAlloc->size());
+		ASSERT_FALSE(m_pFileAlloc->empty());
+		ASSERT_TRUE(file->isRecognized());
+		ASSERT_STREQ(name, file->name().data());
+	}
+}
+
+TEST_F( FactoriesTest, file_iterate ) {
+	int counter = 0;
+	for (counter=1; counter<1000; ++counter) {
+		char name[100];
+		sprintf(name, "file %d", counter);
+		char path_name[100];
+		sprintf(path_name, "/proj/mtk%d", counter);
+		MCLDFile* file = m_pFileAlloc->produce( string(name),
+							sys::fs::Path(string(path_name)),
+							MCLDFile::Archive);
+	}
+
+	ASSERT_EQ(counter-1, m_pFileAlloc->size());
+	ASSERT_FALSE(m_pFileAlloc->empty());
+
+	MCLDFileFactory::iterator file = m_pFileAlloc->begin();
+	MCLDFileFactory::iterator fEnd = m_pFileAlloc->end();
+
+	while (file!=fEnd) {
+		ASSERT_TRUE((*file).isRecognized());
+		ASSERT_FALSE((*file).name().empty());
+		++file;
+	}
+}
+
diff --git a/unittests/FactoriesTest.h b/unittests/FactoriesTest.h
new file mode 100644
index 0000000..ee7badf
--- /dev/null
+++ b/unittests/FactoriesTest.h
@@ -0,0 +1,49 @@
+//===- FactoriesTest.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef FACTORIES_TEST_H
+#define FACTORIES_TEST_H
+#include <gtest.h>
+#include "mcld/ADT/TreeAllocator.h"
+#include "mcld/MC/MCLDFile.h"
+
+namespace mcldtest
+{
+
+/** \class FactoriesTest
+ *  \brief Test cases for factories - NodeFactory and MCLDFileFactory.
+ *
+ *  \see Factories 
+ */
+class FactoriesTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	FactoriesTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~FactoriesTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	typedef mcld::NodeFactory<int> NodeAlloc;
+	typedef mcld::MCLDFileFactory FileAlloc;
+protected:
+	NodeAlloc* m_pNodeAlloc;
+	FileAlloc *m_pFileAlloc;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/GCFactoryListTraitsTest.cpp b/unittests/GCFactoryListTraitsTest.cpp
new file mode 100644
index 0000000..e99d42c
--- /dev/null
+++ b/unittests/GCFactoryListTraitsTest.cpp
@@ -0,0 +1,123 @@
+//===- GCFactoryListTraitsTest.cpp ----------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "GCFactoryListTraitsTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+GCFactoryListTraitsTest::GCFactoryListTraitsTest()
+{
+  // Allocate the nodes.
+  m_pNodesAlloc = new Node* [10];
+#define ALLOCATE_NODE(i) m_pNodesAlloc[(i)] = m_NodeFactory.produce(i);
+  ALLOCATE_NODE(0);
+  ALLOCATE_NODE(1);
+  ALLOCATE_NODE(2);
+  ALLOCATE_NODE(3);
+  ALLOCATE_NODE(4);
+  ALLOCATE_NODE(5);
+  ALLOCATE_NODE(6);
+  ALLOCATE_NODE(7);
+  ALLOCATE_NODE(8);
+  ALLOCATE_NODE(9);
+#undef ALLOCATE_NODE
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+GCFactoryListTraitsTest::~GCFactoryListTraitsTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void GCFactoryListTraitsTest::SetUp()
+{
+  // Reset the node value and (re)insert into the iplist.
+  for (unsigned i = 0; i < 10; i++) {
+    m_pNodesAlloc[i]->setValue(m_pNodesAlloc[i]->getInitialValue());
+    m_pNodeList.push_back(m_pNodesAlloc[i]);
+  }
+}
+
+// TearDown() will be called immediately after each test.
+void GCFactoryListTraitsTest::TearDown()
+{
+  // Erasing of llvm::iplist won't destroy the allocation of the nodes managed
+  // by the GCFactory (i.e., NodeFactory.)
+  m_pNodeList.clear();
+}
+
+//==========================================================================//
+// Testcases
+//
+
+#define CHECK_NODE_VALUE(v_) do {  \
+  ASSERT_EQ(v_, it->getValue()); \
+  it++; \
+} while (false)
+
+#define CHECK_LIST_VALUE(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) do {  \
+  llvm::iplist<Node>::const_iterator it = m_pNodeList.begin();  \
+  CHECK_NODE_VALUE(v1);   \
+  CHECK_NODE_VALUE(v2);   \
+  CHECK_NODE_VALUE(v3);   \
+  CHECK_NODE_VALUE(v4);   \
+  CHECK_NODE_VALUE(v5);   \
+  CHECK_NODE_VALUE(v6);   \
+  CHECK_NODE_VALUE(v7);   \
+  CHECK_NODE_VALUE(v8);   \
+  CHECK_NODE_VALUE(v9);   \
+  CHECK_NODE_VALUE(v10);  \
+} while (false)
+
+TEST_F( GCFactoryListTraitsTest, Basic) {
+  ASSERT_EQ(10, m_pNodeList.size());
+  CHECK_LIST_VALUE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+}
+
+TEST_F( GCFactoryListTraitsTest, BasicAgain) {
+  ASSERT_EQ(10, m_pNodeList.size());
+  CHECK_LIST_VALUE(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+}
+
+TEST_F( GCFactoryListTraitsTest, Clear) {
+  m_pNodeList.clear();
+  ASSERT_EQ(0, m_pNodeList.size());
+}
+
+TEST_F( GCFactoryListTraitsTest, PushThenPop) {
+  Node *NewNode = m_NodeFactory.produce(11);
+  m_pNodeList.push_back(NewNode);
+  ASSERT_EQ(11, m_pNodeList.size());
+  m_pNodeList.pop_back();
+  ASSERT_EQ(10, m_pNodeList.size());
+}
+
+TEST_F( GCFactoryListTraitsTest, CodeIterator) {
+  // to test whether there's compilation error for const template
+  for (llvm::iplist<Node>::const_iterator I = m_pNodeList.begin(),
+          E = m_pNodeList.end(); I != E; I++)
+    I->getValue();
+}
+
+TEST_F( GCFactoryListTraitsTest, Empty) {
+  ASSERT_FALSE(m_pNodeList.empty());
+  m_pNodeList.clear();
+  ASSERT_TRUE(m_pNodeList.empty());
+}
+
+TEST_F( GCFactoryListTraitsTest, EraseAndSize) {
+  ASSERT_FALSE(m_pNodeList.empty());
+  m_pNodeList.erase(m_pNodeList.begin());
+  m_pNodeList.erase(m_pNodeList.begin());
+  ASSERT_TRUE(m_pNodeList.size() == 8);
+}
+
+#undef CHECK_LIST_VALUE
+#undef CHECK_NODE_VALUE
diff --git a/unittests/GCFactoryListTraitsTest.h b/unittests/GCFactoryListTraitsTest.h
new file mode 100644
index 0000000..7067907
--- /dev/null
+++ b/unittests/GCFactoryListTraitsTest.h
@@ -0,0 +1,98 @@
+//===- GCFactoryListTraitsTest.h ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_LIST_TRAITS_TEST_H
+#define MCLD_GC_FACTORY_LIST_TRAITS_TEST_H
+
+#include <gtest.h>
+
+#include <mcld/Support/GCFactoryListTraits.h>
+
+#include <llvm/ADT/ilist_node.h>
+
+#include <mcld/Support/GCFactory.h>
+
+namespace mcldtest
+{
+
+/** \class GCFactoryListTraitsTest
+ *  \brief
+ *
+ *  \see GCFactoryListTraits
+ */
+class GCFactoryListTraitsTest : public ::testing::Test
+{
+public:
+  /** \class GCFactoryListTraitsTest
+  *   \brief Node used in the test
+  *
+  */
+  class NodeFactory;
+
+  class Node : public llvm::ilist_node<Node>
+  {
+    friend class NodeFactory;
+  private:
+    unsigned m_Init;
+    unsigned m_Value;
+
+  private:
+    Node(unsigned pInit) : m_Init(pInit), m_Value(pInit) { }
+
+  public:
+    unsigned getInitialValue() const {
+      return m_Init;
+    }
+
+    inline unsigned getValue() const
+    { return m_Value; }
+
+    inline void setValue(unsigned pValue)
+    { m_Value = pValue; }
+  };
+
+  class NodeFactory : public mcld::GCFactory<Node, 0> {
+  public:
+    NodeFactory() : mcld::GCFactory<Node, 0>(16) { }
+
+    Node *produce(unsigned pInit) {
+      Node *result = allocate();
+      new (result) Node(pInit);
+      return result;
+    }
+  };
+
+	// Constructor can do set-up work for all test here.
+	GCFactoryListTraitsTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~GCFactoryListTraitsTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+  const llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > &getNodeList() const
+  { return m_pNodeList; }
+
+  llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > &getNodeList()
+  { return m_pNodeList; }
+
+protected:
+  NodeFactory m_NodeFactory;
+  Node **m_pNodesAlloc;
+
+  llvm::iplist<Node, mcld::GCFactoryListTraits<Node> > m_pNodeList;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/HashTableTest.cpp b/unittests/HashTableTest.cpp
new file mode 100644
index 0000000..4106641
--- /dev/null
+++ b/unittests/HashTableTest.cpp
@@ -0,0 +1,327 @@
+//===- HashTableTest.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HashTableTest.h"
+#include "mcld/ADT/HashEntry.h"
+#include "mcld/ADT/HashTable.h"
+#include <cstdlib>
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+HashTableTest::HashTableTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+HashTableTest::~HashTableTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void HashTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void HashTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+struct IntCompare
+{
+  bool operator()(int X, int Y) const
+  { return (X==Y); }
+};
+
+struct PtrCompare
+{
+  bool operator()(const int* X, const int* Y) const
+  { return (X==Y); }
+};
+
+struct PtrHash
+{
+  size_t operator()(const int* pKey) const
+  {
+    return (unsigned((uintptr_t)pKey) >> 4) ^
+           (unsigned((uintptr_t)pKey) >> 9);
+  }
+};
+
+struct IntHash
+{
+  size_t operator()(int pKey) const
+  { return pKey; }
+};
+
+struct IntMod3Hash
+{
+  size_t operator()(int pKey) const
+  { return pKey % 3; }
+};
+
+TEST_F( HashTableTest, ptr_entry ) {
+  int A = 1;
+  int* pA = &A;
+
+  typedef HashEntry<int*, int, PtrCompare> HashEntryType;
+  typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(0);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+
+  entry = hashTable->insert(pA, exist);
+
+  EXPECT_FALSE(hashTable->empty());
+
+  HashTableTy::iterator iter;
+  iter = hashTable->find(NULL);
+  EXPECT_TRUE(iter==hashTable->end());
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, constructor ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > hashTable(16);
+  EXPECT_EQ(17, hashTable.numOfBuckets());
+  EXPECT_TRUE(hashTable.empty());
+  EXPECT_EQ(0, hashTable.numOfEntries());
+}
+
+TEST_F( HashTableTest, allocattion ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(22);
+
+  bool exist;
+  int key = 100;
+  HashTableTy::entry_type* val = hashTable->insert(key, exist);
+  val->setValue(999);
+  EXPECT_FALSE(hashTable->empty());
+  EXPECT_FALSE(exist);
+  EXPECT_FALSE(NULL == val);
+  HashTableTy::iterator entry = hashTable->find(key);
+  EXPECT_EQ(999, entry.getEntry()->value());
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, alloc100 ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(22);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<100; ++key) {
+    entry = hashTable->insert(key, exist);
+    EXPECT_FALSE(hashTable->empty());
+    EXPECT_FALSE(exist);
+    EXPECT_FALSE(NULL == entry);
+    EXPECT_EQ(key, entry->key());
+    entry->setValue(key+10);
+  }
+
+  EXPECT_FALSE(hashTable->empty());
+  EXPECT_EQ(100, hashTable->numOfEntries());
+  EXPECT_EQ(197, hashTable->numOfBuckets());
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, erase100 ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(0);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<100; ++key)
+    entry = hashTable->insert(key, exist);
+
+  EXPECT_FALSE(hashTable->empty());
+
+  int count;
+  HashTableTy::iterator iter;
+  for (unsigned int key=0; key<100; ++key) {
+    count = hashTable->erase(key);
+    EXPECT_EQ(1, count);
+    iter = hashTable->find(key);
+    EXPECT_TRUE(iter == hashTable->end());
+  }
+
+  EXPECT_TRUE(hashTable->empty());
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, clear) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(22);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<100; ++key) {
+    entry = hashTable->insert(key, exist);
+  }
+
+  hashTable->clear();
+
+  int count;
+  HashTableTy::iterator iter;
+  for (unsigned int key=0; key<100; ++key) {
+    iter = hashTable->find(key);
+    EXPECT_TRUE(iter == hashTable->end());
+  }
+
+  EXPECT_TRUE(hashTable->empty());
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, tombstone ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntMod3Hash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy();
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<100; ++key) {
+    entry = hashTable->insert(key, exist);
+  }
+  EXPECT_FALSE(hashTable->empty());
+
+  int count;
+  HashTableTy::iterator iter;
+  for (unsigned int key=0; key<20; ++key) {
+    count = hashTable->erase(key);
+    EXPECT_EQ(1, count);
+    iter = hashTable->find(key);
+    EXPECT_TRUE(iter == hashTable->end());
+  }
+  EXPECT_EQ(80, hashTable->numOfEntries());
+
+  for (unsigned int key=20; key<100; ++key) {
+    iter = hashTable->find(key);
+    EXPECT_TRUE(iter != hashTable->end());
+  }
+
+  for (unsigned int key=0; key<20; ++key) {
+    entry = hashTable->insert(key, exist);
+  }
+  EXPECT_EQ(100, hashTable->numOfEntries());
+  EXPECT_EQ(197, hashTable->numOfBuckets());
+
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, rehash_test ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(0);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<400000; ++key) {
+    entry = hashTable->insert(key, exist);
+    entry->setValue(key+10);
+  }
+
+  HashTableTy::iterator iter;
+  for (unsigned int key=0; key<400000; ++key) {
+    iter = hashTable->find(key);
+    EXPECT_EQ((key+10), iter.getEntry()->value());
+  }
+
+  delete hashTable;
+}
+
+TEST_F( HashTableTest, bucket_iterator ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy(0);
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<400000; ++key) {
+    entry = hashTable->insert(key, exist);
+    entry->setValue(key+10);
+  }
+
+  HashTableTy::iterator iter, iEnd = hashTable->end();
+  unsigned int counter = 0;
+  for (iter = hashTable->begin(); iter != iEnd; ++iter) {
+    EXPECT_EQ(iter.getEntry()->key()+10, iter.getEntry()->value());
+    ++counter;
+  }
+  EXPECT_EQ(400000, counter);
+  delete hashTable;
+}
+
+
+TEST_F( HashTableTest, chain_iterator_single ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, IntHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy();
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<16; ++key) {
+    entry = hashTable->insert(key*37, exist);
+    entry->setValue(key+10);
+  }
+  for (unsigned int key=0; key<16; ++key) {
+    unsigned int counter = 0;
+    HashTableTy::chain_iterator iter, iEnd = hashTable->end(key*37);
+    for (iter = hashTable->begin(key*37); iter != iEnd; ++iter) {
+      EXPECT_EQ(key+10, iter.getEntry()->value());
+      ++counter;
+    }
+    EXPECT_EQ(1, counter);
+  }
+  delete hashTable;
+}
+
+struct FixHash
+{
+  size_t operator()(int pKey) const {
+    return 10;
+  }
+};
+
+
+TEST_F( HashTableTest, chain_iterator_list ) {
+  typedef HashEntry<int, int, IntCompare> HashEntryType;
+  typedef HashTable<HashEntryType, FixHash, EntryFactory<HashEntryType> > HashTableTy;
+  HashTableTy *hashTable = new HashTableTy();
+
+  bool exist;
+  HashTableTy::entry_type* entry = 0;
+  for (unsigned int key=0; key<16; ++key) {
+    entry = hashTable->insert(key, exist);
+    ASSERT_FALSE(exist);
+    entry->setValue(key);
+  }
+  ASSERT_EQ(16, hashTable->numOfEntries());
+  ASSERT_EQ(37, hashTable->numOfBuckets());
+
+  unsigned int key = 0;
+  unsigned int count = 0;
+  HashTableTy::chain_iterator iter, iEnd = hashTable->end(key);
+  for (iter = hashTable->begin(key); iter != iEnd; ++iter) {
+    count++;
+  }
+  ASSERT_EQ(16, count);
+  delete hashTable;
+}
diff --git a/unittests/HashTableTest.h b/unittests/HashTableTest.h
new file mode 100644
index 0000000..4bf2c50
--- /dev/null
+++ b/unittests/HashTableTest.h
@@ -0,0 +1,42 @@
+//===- HashTableTest.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_TABLE_TEST_H
+#define MCLD_HASH_TABLE_TEST_H
+
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class HashTableTest
+ *  \brief Testcase for HashTable
+ *
+ *  \see HashTable 
+ */
+class HashTableTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	HashTableTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~HashTableTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/InputTreeTest.cpp b/unittests/InputTreeTest.cpp
new file mode 100644
index 0000000..060eaad
--- /dev/null
+++ b/unittests/InputTreeTest.cpp
@@ -0,0 +1,143 @@
+//===- InputTreeTest.cpp --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/MCLDInputTree.h"
+#include "mcld/MC/MCLDInfo.h"
+#include <InputTreeTest.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+InputTreeTest::InputTreeTest()
+{
+	// create testee. modify it if need
+	m_pAttr = new mcld::AttributeFactory(2);
+        m_pAlloc = new mcld::InputFactory(10, *m_pAttr);
+	m_pTestee = new InputTree(*m_pAlloc);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+InputTreeTest::~InputTreeTest()
+{
+	delete m_pTestee;
+	delete m_pAlloc;
+	delete m_pAttr;
+}
+
+// SetUp() will be called immediately before each test.
+void InputTreeTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void InputTreeTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( InputTreeTest, Basic_operation ) {
+  InputTree::iterator node = m_pTestee->root();
+  m_pTestee->insert<InputTree::Inclusive>(node, "FileSpec", "path1");
+
+  InputTree::const_iterator const_node = node;
+
+  ASSERT_TRUE(isGroup(node));
+  ASSERT_TRUE(isGroup(const_node));
+  ASSERT_TRUE(m_pTestee->hasInput());
+  ASSERT_EQ(1, m_pTestee->numOfInputs());
+
+  --node;
+
+  m_pTestee->enterGroup(node, InputTree::Downward);
+
+  InputTree::const_iterator const_node2 = node;
+
+  ASSERT_FALSE(node.isRoot());
+
+  ASSERT_FALSE(isGroup(node));
+  ASSERT_FALSE(isGroup(const_node2));
+  ASSERT_TRUE(m_pTestee->hasInput());
+  ASSERT_FALSE(m_pTestee->numOfInputs()==0);
+
+  ASSERT_TRUE(m_pTestee->size()==2);
+}
+
+TEST_F( InputTreeTest, forLoop_TEST ) {
+  InputTree::iterator node = m_pTestee->root();
+
+  
+  m_pTestee->insert<InputTree::Inclusive>(node, "FileSpec", "path1");
+  InputTree::const_iterator const_node = node;
+  --node;
+
+  for(int i=0 ; i<100 ; ++i) 
+  {
+    m_pTestee->insert<InputTree::Inclusive>(node,"FileSpec", "path1");
+    ++node;
+  }
+
+  m_pTestee->enterGroup(node, InputTree::Downward);
+  --node;
+
+  ASSERT_FALSE(node.isRoot());
+  ASSERT_TRUE(isGroup(node));
+  ASSERT_TRUE(m_pTestee->hasInput());
+  ASSERT_FALSE(m_pTestee->numOfInputs()==100);
+
+  ASSERT_TRUE(m_pTestee->size()==102);
+}
+
+TEST_F( InputTreeTest, Nesting_Case ) {
+  InputTree::iterator node = m_pTestee->root(); 
+
+  for(int i=0 ; i<50 ; ++i) 
+  {
+    m_pTestee->enterGroup(node, InputTree::Downward);
+    --node;
+
+    m_pTestee->insert(node, InputTree::Afterward, "FileSpec", "path1");
+    ++node;
+  }
+  
+  ASSERT_FALSE(node.isRoot());
+  ASSERT_FALSE(isGroup(node));
+  ASSERT_TRUE(m_pTestee->hasInput());
+  ASSERT_TRUE(m_pTestee->numOfInputs()==50);
+  ASSERT_TRUE(m_pTestee->size()==100);
+}
+
+TEST_F( InputTreeTest, DFSIterator_BasicTraversal)
+{
+  
+  InputTree::iterator node = m_pTestee->root(); 
+  m_pTestee->insert<InputTree::Inclusive>(node, "111", "/");
+  node.move<InputTree::Inclusive>();
+
+  m_pTestee->insert<InputTree::Positional>(node, "10", "/");
+  m_pTestee->enterGroup<InputTree::Inclusive>(node);
+  node.move<InputTree::Inclusive>();
+  m_pTestee->insert<InputTree::Inclusive>(node, "7", "/");
+  m_pTestee->insert<InputTree::Positional>(node, "8", "/");
+
+  InputTree::dfs_iterator dfs_it = m_pTestee->dfs_begin(); 
+  InputTree::dfs_iterator dfs_end = m_pTestee->dfs_end(); 
+  ASSERT_STREQ("111", (*dfs_it)->name().c_str());
+  ++dfs_it;
+  ASSERT_STREQ("7", (**dfs_it).name().c_str());
+  ++dfs_it;
+  ASSERT_STREQ("8", (**dfs_it).name().c_str());
+  ++dfs_it;
+  ASSERT_STREQ("10", (**dfs_it).name().c_str());
+  ++dfs_it;
+  ASSERT_TRUE(dfs_it ==  dfs_end);
+}
+
diff --git a/unittests/InputTreeTest.h b/unittests/InputTreeTest.h
new file mode 100644
index 0000000..2ffef9c
--- /dev/null
+++ b/unittests/InputTreeTest.h
@@ -0,0 +1,54 @@
+//===- InputTreeTest.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INPUTTREE_TEST_H
+#define INPUTTREE_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class InputTree;
+class InputFactory;
+class AttributeFactory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class InputTreeTest
+ *  \brief 
+ *
+ *  \see InputTree 
+ */
+class InputTreeTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	InputTreeTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~InputTreeTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::AttributeFactory *m_pAttr;
+	mcld::InputFactory *m_pAlloc;
+	mcld::InputTree* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LDSymbolTest.cpp b/unittests/LDSymbolTest.cpp
new file mode 100644
index 0000000..c414fa0
--- /dev/null
+++ b/unittests/LDSymbolTest.cpp
@@ -0,0 +1,42 @@
+//===- LDSymbolTest.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/LD/LDSymbol.h"
+#include "LDSymbolTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LDSymbolTest::LDSymbolTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LDSymbolTest::~LDSymbolTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void LDSymbolTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LDSymbolTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( LDSymbolTest, produce ) {
+}
+
diff --git a/unittests/LDSymbolTest.h b/unittests/LDSymbolTest.h
new file mode 100644
index 0000000..43d6b8a
--- /dev/null
+++ b/unittests/LDSymbolTest.h
@@ -0,0 +1,46 @@
+//===- LDSymbolTest.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LDSYMBOL_TEST_H
+#define LDSYMBOL_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class LDSymbol;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class LDSymbolTest
+ */
+class LDSymbolTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  LDSymbolTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~LDSymbolTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LEB128Test.cpp b/unittests/LEB128Test.cpp
new file mode 100644
index 0000000..1f1467f
--- /dev/null
+++ b/unittests/LEB128Test.cpp
@@ -0,0 +1,531 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Support/LEB128.h>
+#include "LEB128Test.h"
+
+#include <ctime>
+#include <cstdlib>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LEB128Test::LEB128Test()
+{
+	// Initialize the seed for random number generator using during the tests.
+  ::srandom(::time(NULL));
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LEB128Test::~LEB128Test()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void LEB128Test::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LEB128Test::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( LEB128Test, EncodeULEB_Example_from_Dwarf3_Figure22_Using_32bits) {
+  leb128::ByteType buffer[2];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 2);
+  ASSERT_EQ(buffer[0], 2);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 127);
+  ASSERT_EQ(buffer[0], 127);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 128);
+  ASSERT_EQ(buffer[0], 0 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 129);
+  ASSERT_EQ(buffer[0], 1 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 130);
+  ASSERT_EQ(buffer[0], 2 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 12857);
+  ASSERT_EQ(buffer[0], 57 + 0x80);
+  ASSERT_EQ(buffer[1], 100);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, EncodeULEB_Example_from_Dwarf3_Figure22_Using_64bits) {
+  leb128::ByteType buffer[2];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 2);
+  ASSERT_EQ(buffer[0], 2);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 127);
+  ASSERT_EQ(buffer[0], 127);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 128);
+  ASSERT_EQ(buffer[0], 0 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 129);
+  ASSERT_EQ(buffer[0], 1 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 130);
+  ASSERT_EQ(buffer[0], 2 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 12857);
+  ASSERT_EQ(buffer[0], 57 + 0x80);
+  ASSERT_EQ(buffer[1], 100);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, EncodeSLEB_Example_from_Dwarf3_Figure22) {
+  leb128::ByteType buffer[2];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 2);
+  ASSERT_EQ(buffer[0], 2);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, -2);
+  ASSERT_EQ(buffer[0], 0x7e);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 127);
+  ASSERT_EQ(buffer[0], 127 + 0x80);
+  ASSERT_EQ(buffer[1], 0);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, -127);
+  ASSERT_EQ(buffer[0], 1 + 0x80);
+  ASSERT_EQ(buffer[1], 0x7f);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 128);
+  ASSERT_EQ(buffer[0], 0 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, -128);
+  ASSERT_EQ(buffer[0], 0 + 0x80);
+  ASSERT_EQ(buffer[1], 0x7f);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 129);
+  ASSERT_EQ(buffer[0], 1 + 0x80);
+  ASSERT_EQ(buffer[1], 1);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, -129);
+  ASSERT_EQ(buffer[0], 0x7f + 0x80);
+  ASSERT_EQ(buffer[1], 0x7e);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, DecodeULEB_Example_from_Dwarf3_Figure22) {
+  leb128::ByteType buffer[2];
+  size_t size;
+
+  buffer[0] = 2;
+  buffer[1] = 0;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 2);
+  ASSERT_EQ(size, 1);
+
+  buffer[0] = 127;
+  buffer[1] = 0;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 127);
+  ASSERT_EQ(size, 1);
+
+  buffer[0] = 0 + 0x80;
+  buffer[1] = 1;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 128);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 1 + 0x80;
+  buffer[1] = 1;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 129);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 2 + 0x80;
+  buffer[1] = 1;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 130);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 57 + 0x80;
+  buffer[1] = 100;
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 12857);
+  ASSERT_EQ(size, 2);
+
+}
+
+TEST_F( LEB128Test, DecodeSLEB_Example_from_Dwarf3_Figure22) {
+  leb128::ByteType buffer[2];
+  size_t size;
+
+  buffer[0] = 2;
+  buffer[1] = 0;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 2);
+  ASSERT_EQ(size, 1);
+
+  buffer[0] = 0x7e;
+  buffer[1] = 0;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -2);
+  ASSERT_EQ(size, 1);
+
+  buffer[0] = 127 + 0x80;
+  buffer[1] = 0;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 127);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 1 + 0x80;
+  buffer[1] = 0x7f;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -127);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 0 + 0x80;
+  buffer[1] = 1;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 128);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 0 + 0x80;
+  buffer[1] = 0x7f;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -128);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 1 + 0x80;
+  buffer[1] = 1;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), 129);
+  ASSERT_EQ(size, 2);
+
+  buffer[0] = 0x7f + 0x80;
+  buffer[1] = 0x7e;
+  ASSERT_EQ(leb128::decode<int64_t>(buffer, size), -129);
+  ASSERT_EQ(size, 2);
+}
+
+TEST_F( LEB128Test, DecodeULEB_Tests_Found_in_Android_dalvik_dx) {
+  leb128::ByteType content[2];
+  const leb128::ByteType *p;
+
+  content[0] = 0;
+  p = content;
+  ASSERT_EQ(leb128::decode<uint64_t>(p), 0);
+  ASSERT_EQ(p, content + 1);
+
+  content[0] = 1;
+  p = content;
+  ASSERT_EQ(leb128::decode<uint64_t>(p), 1);
+  ASSERT_EQ(p, content + 1);
+
+  content[0] = 0x80;
+  content[1] = 0x7f;
+  p = content;
+  ASSERT_EQ(leb128::decode<uint64_t>(p), 16256);
+  ASSERT_EQ(p, content + 2);
+}
+
+TEST_F( LEB128Test, EncodeULEB_Tests_Found_in_Android_dalvik_dx) {
+  leb128::ByteType buffer[5];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 0);
+  ASSERT_EQ(buffer[0], 0);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 0);
+  ASSERT_EQ(buffer[0], 0);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 1);
+  ASSERT_EQ(buffer[0], 1);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 1);
+  ASSERT_EQ(buffer[0], 1);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 16256);
+  ASSERT_EQ(buffer[0], 0x80);
+  ASSERT_EQ(buffer[1], 0x7f);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 16256);
+  ASSERT_EQ(buffer[0], 0x80);
+  ASSERT_EQ(buffer[1], 0x7f);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 0x3b4);
+  ASSERT_EQ(buffer[0], 0xb4);
+  ASSERT_EQ(buffer[1], 0x07);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 0x3b4);
+  ASSERT_EQ(buffer[0], 0xb4);
+  ASSERT_EQ(buffer[1], 0x07);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 0x40c);
+  ASSERT_EQ(buffer[0], 0x8c);
+  ASSERT_EQ(buffer[1], 0x08);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 0x40c);
+  ASSERT_EQ(buffer[0], 0x8c);
+  ASSERT_EQ(buffer[1], 0x08);
+  ASSERT_EQ(result, buffer + 2);
+  ASSERT_EQ(size, 2);
+
+  result = buffer;
+  size = leb128::encode<uint32_t>(result, 0xffffffff);
+  ASSERT_EQ(buffer[0], 0xff);
+  ASSERT_EQ(buffer[1], 0xff);
+  ASSERT_EQ(buffer[2], 0xff);
+  ASSERT_EQ(buffer[3], 0xff);
+  ASSERT_EQ(buffer[4], 0xf);
+  ASSERT_EQ(result, buffer + 5);
+  ASSERT_EQ(size, 5);
+
+  result = buffer;
+  size = leb128::encode<uint64_t>(result, 0xffffffff);
+  ASSERT_EQ(buffer[0], 0xff);
+  ASSERT_EQ(buffer[1], 0xff);
+  ASSERT_EQ(buffer[2], 0xff);
+  ASSERT_EQ(buffer[3], 0xff);
+  ASSERT_EQ(buffer[4], 0xf);
+  ASSERT_EQ(result, buffer + 5);
+  ASSERT_EQ(size, 5);
+}
+
+TEST_F( LEB128Test, DecodeSLEB_Tests_Found_in_Android_dalvik_dx) {
+  leb128::ByteType content[2];
+  const leb128::ByteType *p;
+
+  content[0] = 0;
+  p = content;
+  ASSERT_EQ(leb128::decode<int64_t>(p), 0);
+  ASSERT_EQ(p, content + 1);
+
+  content[0] = 1;
+  p = content;
+  ASSERT_EQ(leb128::decode<int64_t>(p), 1);
+  ASSERT_EQ(p, content + 1);
+
+  content[0] = 0x7f;
+  p = content;
+  ASSERT_EQ(leb128::decode<int64_t>(p), -1);
+  ASSERT_EQ(p, content + 1);
+
+  content[0] = 0x3c;
+  p = content;
+  ASSERT_EQ(leb128::decode<int64_t>(p), 0x3c);
+  ASSERT_EQ(p, content + 1);
+}
+
+TEST_F( LEB128Test, EncodeSLEB_Tests_Found_in_Android_dalvik_dx) {
+  leb128::ByteType buffer[5];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 0);
+  ASSERT_EQ(buffer[0], 0);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int64_t>(result, 0);
+  ASSERT_EQ(buffer[0], 0);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, 1);
+  ASSERT_EQ(buffer[0], 1);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int64_t>(result, 1);
+  ASSERT_EQ(buffer[0], 1);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int32_t>(result, -1);
+  ASSERT_EQ(buffer[0], 0x7f);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+
+  result = buffer;
+  size = leb128::encode<int64_t>(result, -1);
+  ASSERT_EQ(buffer[0], 0x7f);
+  ASSERT_EQ(result, buffer + 1);
+  ASSERT_EQ(size, 1);
+}
+
+TEST_F( LEB128Test, Random_Regression_Test) {
+  leb128::ByteType buffer[5];
+
+  for (int i = 0; i < 20; i++) {
+    long int value = random();
+    uint64_t value2 = value * value;
+    leb128::ByteType *result;
+    size_t encode_size, decode_size;
+
+    // Test encode<uint32_t> and decode<uint64_t> on value
+    result = buffer;
+    encode_size = leb128::encode<uint32_t>(result, value);
+    ASSERT_EQ(result, buffer + encode_size);
+    ASSERT_EQ(leb128::decode<uint64_t>(buffer, decode_size), value);
+    ASSERT_EQ(encode_size, decode_size);
+
+    // Test encode<uint64_t> and decode<uint64_t> on (value * value)
+    result = buffer;
+    encode_size = leb128::encode<uint64_t>(result, value2);
+    ASSERT_EQ(result, buffer + encode_size);
+    ASSERT_EQ(leb128::decode<uint64_t>(buffer, decode_size), value2);
+    ASSERT_EQ(encode_size, decode_size);
+
+    // Test encode<uint64_t> and decode<uint64_t> on (value * value)
+    result = buffer;
+    encode_size = leb128::encode<int64_t>(result, value2);
+    ASSERT_EQ(result, buffer + encode_size);
+    ASSERT_EQ(leb128::decode<int64_t>(buffer, decode_size), value2);
+    ASSERT_EQ(encode_size, decode_size);
+
+    // Test encode<uint64_t> and decode<uint64_t> on -(value * value)
+    result = buffer;
+    encode_size = leb128::encode<int64_t>(result, -value2);
+    ASSERT_EQ(result, buffer + encode_size);
+    ASSERT_EQ(leb128::decode<int64_t>(buffer, decode_size), -value2);
+    ASSERT_EQ(encode_size, decode_size);
+  }
+}
+
+TEST_F( LEB128Test, Other_Test) {
+  leb128::ByteType buffer[5];
+  leb128::ByteType *result;
+  size_t size;
+
+  result = buffer;
+  leb128::encode<uint64_t>(result, 154452);
+  ASSERT_EQ(result, buffer + 3);
+  ASSERT_EQ(buffer[0], 0xd4);
+  ASSERT_EQ(buffer[1], 0xb6);
+  ASSERT_EQ(buffer[2], 0x9);
+
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 154452);
+  ASSERT_EQ(size, 3);
+}
+
+TEST_F( LEB128Test, Type_Conversion_Test) {
+  char buffer[5];
+  char *result;
+  size_t size;
+
+  result = buffer;
+  leb128::encode<uint64_t>(result, 154452);
+  ASSERT_EQ(result, buffer + 3);
+  ASSERT_EQ(buffer[0], '\xd4');
+  ASSERT_EQ(buffer[1], '\xb6');
+  ASSERT_EQ(buffer[2], '\x09');
+
+  ASSERT_EQ(leb128::decode<uint64_t>(buffer, size), 154452);
+  ASSERT_EQ(size, 3);
+
+  const char *p = buffer;
+  ASSERT_EQ(leb128::decode<uint64_t>(p), 154452);
+  ASSERT_EQ(p, buffer + 3);
+}
diff --git a/unittests/LEB128Test.h b/unittests/LEB128Test.h
new file mode 100644
index 0000000..f0a87e3
--- /dev/null
+++ b/unittests/LEB128Test.h
@@ -0,0 +1,41 @@
+//===- LEB128Test.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LEB128_TEST_H
+#define MCLD_LEB128_TEST_H
+
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class LEB128Test
+ *  \brief
+ *
+ *  \see LEB
+ */
+class LEB128Test : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	LEB128Test();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~LEB128Test();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/LinearAllocatorTest.cpp b/unittests/LinearAllocatorTest.cpp
new file mode 100644
index 0000000..9100160
--- /dev/null
+++ b/unittests/LinearAllocatorTest.cpp
@@ -0,0 +1,139 @@
+//===- LinearAllocatorTest.cpp --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "LinearAllocatorTest.h"
+#include "mcld/Support/Allocators.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+LinearAllocatorTest::LinearAllocatorTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new LinearAllocator<Data, CHUNK_SIZE>();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+LinearAllocatorTest::~LinearAllocatorTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void LinearAllocatorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void LinearAllocatorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( LinearAllocatorTest, allocateN ) {
+	Data* pointer = m_pTestee->allocate(10);
+	ASSERT_FALSE(0 == pointer);
+	ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+	ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, allocate ) {
+	Data* pointer = m_pTestee->allocate();
+	ASSERT_FALSE(0 == pointer);
+	ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+	ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, allocateOver ) {
+	Data* pointer = m_pTestee->allocate(CHUNK_SIZE+1);
+	ASSERT_TRUE(0 == pointer);
+	ASSERT_EQ(0, m_pTestee->max_size());
+	ASSERT_TRUE(m_pTestee->empty());
+}
+
+TEST_F( LinearAllocatorTest, alloc_construct ) {
+	Data* pointer = m_pTestee->allocate();
+	m_pTestee->construct(pointer);
+	ASSERT_EQ(1, pointer->one);
+	ASSERT_EQ(2, pointer->two);
+	ASSERT_EQ(3, pointer->three);
+	ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, alloc_constructCopy ) {
+	Data* pointer = m_pTestee->allocate();
+	Data data(7, 7, 7, 7);
+	m_pTestee->construct(pointer, data);
+	
+	ASSERT_EQ(7, pointer->one);
+	ASSERT_EQ(7, pointer->two);
+	ASSERT_EQ(7, pointer->three);
+	ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, allocN_construct ) {
+	Data* pointer = m_pTestee->allocate(10);
+	m_pTestee->construct(pointer);
+	ASSERT_EQ(1, pointer->one);
+	ASSERT_EQ(2, pointer->two);
+	ASSERT_EQ(3, pointer->three);
+	ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, allocN_constructCopy ) {
+	Data* pointer = m_pTestee->allocate(10);
+	Data data(7, 7, 7, 7);
+	m_pTestee->construct(pointer, data);
+	
+	ASSERT_EQ(7, pointer->one);
+	ASSERT_EQ(7, pointer->two);
+	ASSERT_EQ(7, pointer->three);
+	ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F( LinearAllocatorTest, multi_alloc_ctor_iterate ) {
+	for (int i=0; i<101; ++i) {
+		Data* pointer = m_pTestee->allocate();
+		m_pTestee->construct(pointer);
+		pointer->one = i;
+	}
+/**
+	Alloc::iterator data, dEnd = m_pTestee->end();
+	int counter = 0;
+	for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+		ASSERT_EQ(counter, (*data).one);
+		++counter;
+	}
+**/
+}
+
+TEST_F( LinearAllocatorTest, multi_allocN_ctor_iterate ) {
+	int counter = 0;
+	for (int i=0; i<10000; ++i) {
+		Data* pointer = m_pTestee->allocate(10);
+		for (int j=0; j<10; ++j) {
+			m_pTestee->construct(pointer);
+			pointer->one = counter;
+			++pointer;
+			++counter;
+		}
+	}
+/**
+	Alloc::iterator data, dEnd = m_pTestee->end();
+	counter = 0;
+	for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+		ASSERT_EQ(counter, (*data).one);
+		++counter;
+	}
+**/
+}
+
diff --git a/unittests/LinearAllocatorTest.h b/unittests/LinearAllocatorTest.h
new file mode 100644
index 0000000..9e9b2ab
--- /dev/null
+++ b/unittests/LinearAllocatorTest.h
@@ -0,0 +1,75 @@
+//===- LinearAllocatorTest.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LINEAR_ALLOCATOR_TEST_H
+#define LINEAR_ALLOCATOR_TEST_H
+
+#include <gtest.h>
+#include "mcld/Support/Allocators.h"
+
+namespace mcldtest
+{
+
+/** \class LinearAllocatorTest
+ *  \brief The testcase for LinearAllocator
+ *
+ *  \see LinearAllocator 
+ */
+class LinearAllocatorTest : public ::testing::Test
+{
+public:
+	struct Data {
+		Data()
+		: one(1), two(2), three(3), four(4)
+		{ }
+
+		Data( unsigned int pOne, unsigned int pTwo, unsigned char pThree, unsigned char pFour)
+		{
+			one = pOne;
+			two = pTwo;
+			three = pThree;
+			four = pFour;
+		}
+
+		~Data()
+		{
+			one = -1;
+			two = -2;
+			three = -3;
+			four = -4;
+		}
+
+		unsigned int one;
+		unsigned int two;
+		unsigned char three;
+		unsigned char four;
+	};
+public:
+	// Constructor can do set-up work for all test here.
+	LinearAllocatorTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~LinearAllocatorTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	enum { CHUNK_SIZE = 32 };
+	typedef mcld::LinearAllocator<Data, CHUNK_SIZE> Alloc;
+protected:
+	Alloc* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MCFragmentRefTest.cpp b/unittests/MCFragmentRefTest.cpp
new file mode 100644
index 0000000..556fbdd
--- /dev/null
+++ b/unittests/MCFragmentRefTest.cpp
@@ -0,0 +1,70 @@
+//===- MCFragmentRefTest --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mcld/MC/MCFragmentRef.h"
+#include "mcld/MC/MCRegionFragment.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+#include "MCFragmentRefTest.h"
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcld::sys::fs::detail;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+MCFragmentRefTest::MCFragmentRefTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MCFragmentRefTest::~MCFragmentRefTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MCFragmentRefTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MCFragmentRefTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( MCFragmentRefTest, ) {
+  Path path(TOPDIR);
+  path.append("unittests/test3.txt");
+  MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+  MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+  MemoryRegion* region = area->request(0, 4096);
+  MCRegionFragment *frag = new MCRegionFragment(*region);
+  MCFragmentRef *ref = new MCFragmentRef(*frag);
+
+  ASSERT_EQ('H', region->getBuffer()[0]);
+  ASSERT_EQ(4096, region->size());
+  ASSERT_EQ('H', frag->getRegion().getBuffer()[0]);
+  ASSERT_EQ(4096, frag->getRegion().size());
+  ASSERT_EQ(frag, ref->frag());
+  ASSERT_EQ('H', static_cast<MCRegionFragment*>(ref->frag())->getRegion().getBuffer()[0]);
+  ASSERT_EQ(4096, static_cast<MCRegionFragment*>(ref->frag())->getRegion().size());
+  ASSERT_EQ('H', ref->deref()[0]);
+
+  ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+  ASSERT_TRUE(MCRegionFragment::classof(frag));
+
+  delete ref;
+  delete frag;
+  delete areaFactory;
+}
+
diff --git a/unittests/MCFragmentRefTest.h b/unittests/MCFragmentRefTest.h
new file mode 100644
index 0000000..c0b23f3
--- /dev/null
+++ b/unittests/MCFragmentRefTest.h
@@ -0,0 +1,48 @@
+//===- MCFragmentRefTest.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_MCFRAGMENT_REF_TEST_H
+#define MCLD_MCFRAGMENT_REF_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MCFragmentRef;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MCFragmentRefTest
+ *  \brief Reference Test
+ *
+ *  \see MCFragmentRef 
+ */
+class MCFragmentRefTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  MCFragmentRefTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~MCFragmentRefTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MCRegionFragmentTest.cpp b/unittests/MCRegionFragmentTest.cpp
new file mode 100644
index 0000000..842ddf9
--- /dev/null
+++ b/unittests/MCRegionFragmentTest.cpp
@@ -0,0 +1,74 @@
+//===- MCRegionFragmentTest.cpp - MCRegionFragment implementation ---------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCRegionFragmentTest.h"
+
+#include "mcld/MC/MCRegionFragment.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+
+using namespace mcld;
+using namespace mcldtest;
+using namespace mcld::sys::fs;
+
+
+// Constructor can do set-up work for all test here.
+MCRegionFragmentTest::MCRegionFragmentTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MCRegionFragmentTest::~MCRegionFragmentTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MCRegionFragmentTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MCRegionFragmentTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( MCRegionFragmentTest, classof_explicit ) {
+  Path path(TOPDIR);
+  path.append("unittests/test3.txt");
+  MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+  MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+  MemoryRegion* region = area->request(0, 4096);
+  MCRegionFragment *frag = new MCRegionFragment(*region);
+
+  ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+  ASSERT_TRUE(MCRegionFragment::classof(frag));
+  delete frag;
+  delete areaFactory;
+}
+
+TEST_F( MCRegionFragmentTest, classof_implicit ) {
+  Path path(TOPDIR);
+  path.append("unittests/test3.txt");
+  MemoryAreaFactory* areaFactory = new MemoryAreaFactory(1);
+  MemoryArea* area = areaFactory->produce(path, MemoryArea::ReadWrite);
+
+  MemoryRegion* region = area->request(0, 4096);
+  llvm::MCFragment *frag = new MCRegionFragment(*region);
+
+  ASSERT_FALSE(llvm::MCDataFragment::classof(frag));
+  ASSERT_TRUE(MCRegionFragment::classof(frag));
+  delete frag;
+  delete areaFactory;
+}
+
diff --git a/unittests/MCRegionFragmentTest.h b/unittests/MCRegionFragmentTest.h
new file mode 100644
index 0000000..15434fd
--- /dev/null
+++ b/unittests/MCRegionFragmentTest.h
@@ -0,0 +1,51 @@
+//===- MCRegionFragment.h - unittest for MCRegionFragment -----------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCREGIONFRAGMENT_TEST_H
+#define MCREGIONFRAGMENT_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MCRegionFragment;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MCRegionFragmentTest
+ *  \brief The testcase of MCRegionFragment.
+ *
+ *  \see MCRegionFragment 
+ */
+class MCRegionFragmentTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	MCRegionFragmentTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~MCRegionFragmentTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::MCRegionFragment* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/MemoryAreaTest.cpp b/unittests/MemoryAreaTest.cpp
new file mode 100644
index 0000000..a2e631a
--- /dev/null
+++ b/unittests/MemoryAreaTest.cpp
@@ -0,0 +1,148 @@
+//===- MemoryAreaTest.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/MemoryRegion.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "mcld/Support/Path.h"
+
+#include "MemoryAreaTest.h"
+#include <fcntl.h>
+#include <cstdio>
+
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+MemoryAreaTest::MemoryAreaTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+MemoryAreaTest::~MemoryAreaTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void MemoryAreaTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void MemoryAreaTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( MemoryAreaTest, read_by_malloc )
+{
+	Path path(TOPDIR);
+	path.append("unittests/test3.txt");
+	MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1);
+	MemoryArea* area = AreaFactory->produce(path, O_RDONLY);
+	MemoryRegion* region = area->request(3, 2);
+	ASSERT_EQ('L', region->getBuffer()[0]);
+	ASSERT_EQ('O', region->getBuffer()[1]);
+	delete AreaFactory;
+}
+
+TEST_F( MemoryAreaTest, write_by_malloc )
+{
+	Path path(TOPDIR);
+	path.append("unittests/test2.txt");
+	MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1);
+	MemoryArea* area = AreaFactory->produce(path, O_RDWR);
+        ASSERT_TRUE(area->isMapped());
+        ASSERT_TRUE(area->isGood());
+	MemoryRegion* region = area->request(3, 4);
+	region->getBuffer()[0] = 'L';
+	region->getBuffer()[1] = 'i';
+	region->getBuffer()[2] = 'n';
+	region->getBuffer()[3] = 'k';
+        area->sync();
+	area->unmap();
+        area->map(path, O_RDONLY);
+        ASSERT_TRUE(area->isMapped());
+        ASSERT_TRUE(area->isGood());
+        region = area->request(5, 2);
+        ASSERT_EQ('n', region->getBuffer()[0]);
+        ASSERT_EQ('k', region->getBuffer()[1]);
+	delete AreaFactory;
+}
+
+TEST_F( MemoryAreaTest, read_one_page )
+{
+        Path path(TOPDIR) ;
+	path.append("unittests/test3.txt") ;
+	MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+	MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+	ASSERT_TRUE(area->isMapped()) ;
+	ASSERT_TRUE(area->isGood()) ;
+	MemoryRegion* region = area->request(0, 4096) ;
+	ASSERT_EQ('H', region->getBuffer()[0]);
+	ASSERT_EQ('E', region->getBuffer()[1]);
+	delete AreaFactory ;
+}
+
+TEST_F( MemoryAreaTest, write_one_page )
+{
+        Path path(TOPDIR) ;
+	path.append("unittests/test2.txt") ;
+        MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+	MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+	ASSERT_TRUE(area->isMapped()) ;
+	ASSERT_TRUE(area->isGood()) ;
+	MemoryRegion* region = area->request(0, 4096) ;
+	region->getBuffer()[4000] = 'K' ;
+	region->getBuffer()[4001] = 'R' ;
+	area->sync() ;
+	area->unmap() ;
+	area->map(path, O_RDONLY) ;
+	region = area->request(4000, 4) ;
+	ASSERT_EQ('K', region->getBuffer()[0]);
+	ASSERT_EQ('R', region->getBuffer()[1]);
+	region->getBuffer()[0] = 'O' ;
+	region->getBuffer()[1] = 'H' ;
+        area->sync() ;
+	delete AreaFactory ;
+}
+
+TEST_F( MemoryAreaTest, write_sync )
+{
+        Path path(TOPDIR) ;
+	path.append("unittests/test2.txt") ;
+	MemoryAreaFactory *AreaFactory = new MemoryAreaFactory(1) ;
+	MemoryArea* area = AreaFactory->produce(path, O_RDWR) ;
+	ASSERT_TRUE(area->isMapped()) ;
+	ASSERT_TRUE(area->isGood()) ;
+	MemoryRegion* region1 = area->request(0, 4096) ;
+	MemoryRegion* region2 = area->request(512, 1024) ;
+	region1->getBuffer()[1000] = 'L' ;
+	region1->getBuffer()[1001] = 'L' ;
+	region2->getBuffer()[488] = 'V' ;
+	region2->getBuffer()[489] = 'M' ;
+	area->sync() ;
+	area->unmap();
+	area->map(path, O_RDWR) ;
+	region1 = area->request(0, 1024) ;
+	EXPECT_EQ('V', region1->getBuffer()[1000]) ;
+	EXPECT_EQ('M', region1->getBuffer()[1001]) ;
+	region1->getBuffer()[1000] = '@' ;
+	region1->getBuffer()[1001] = '@' ;
+	area->sync();
+	delete AreaFactory ;
+}
+
+
diff --git a/unittests/MemoryAreaTest.h b/unittests/MemoryAreaTest.h
new file mode 100644
index 0000000..86a5da0
--- /dev/null
+++ b/unittests/MemoryAreaTest.h
@@ -0,0 +1,50 @@
+//===- MemoryAreaTest.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MEMORYAREA_TEST_H
+#define MEMORYAREA_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class MemoryArea;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class MemoryAreaTest
+ *  \brief 
+ *
+ *  \see MemoryArea 
+ */
+class MemoryAreaTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	MemoryAreaTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~MemoryAreaTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::MemoryArea* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/PathSetTest.cpp b/unittests/PathSetTest.cpp
new file mode 100644
index 0000000..d735e9c
--- /dev/null
+++ b/unittests/PathSetTest.cpp
@@ -0,0 +1,45 @@
+//===- PathSetTest.cpp ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/PathSet.h"
+#include "PathSetTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+PathSetTest::PathSetTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new PathSet();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+PathSetTest::~PathSetTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void PathSetTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void PathSetTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( PathSetTest, ) {
+}
+
diff --git a/unittests/PathSetTest.h b/unittests/PathSetTest.h
new file mode 100644
index 0000000..d64b2a8
--- /dev/null
+++ b/unittests/PathSetTest.h
@@ -0,0 +1,50 @@
+//===- PathSetTest.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PATHSET_TEST_H
+#define PATHSET_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class PathSet;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class PathSetTest
+ *  \brief The testcase of PathSet
+ *
+ *  \see PathSet 
+ */
+class PathSetTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	PathSetTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~PathSetTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::PathSet* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/PathTest.cpp b/unittests/PathTest.cpp
new file mode 100644
index 0000000..8906d02
--- /dev/null
+++ b/unittests/PathTest.cpp
@@ -0,0 +1,140 @@
+//===- PathTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "PathTest.h"
+#include "mcld/Support/FileSystem.h"
+#include <string>
+
+//
+using namespace mcld;
+using namespace mcld::sys::fs;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+PathTest::PathTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new Path();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+PathTest::~PathTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void PathTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void PathTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( PathTest, should_exist ) {
+  const std::string root = "/etc/hosts";
+  m_pTestee->assign(root);
+  EXPECT_TRUE(exists(*m_pTestee));
+
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_TRUE(exists(*m_pTestee));
+}
+
+TEST_F( PathTest, should_not_exist ) {
+  const std::string root = "/luck";
+  m_pTestee->assign(root);
+  EXPECT_FALSE(exists(*m_pTestee));
+
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_FALSE(exists(*m_pTestee));
+}
+
+TEST_F( PathTest, should_is_directory ) {
+//  const std::string root = "/proj/mtk03931/temp/pndk-luba/../";
+  const std::string root = "../././..";
+  m_pTestee->assign(root);
+  EXPECT_TRUE(exists(*m_pTestee));
+  EXPECT_TRUE(is_directory(*m_pTestee));
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_TRUE(exists(*m_pTestee));
+  EXPECT_TRUE(is_directory(*m_pTestee));
+}
+
+TEST_F( PathTest, should_not_is_directory ) {
+  const std::string root = "/luck";
+  m_pTestee->assign(root);
+  EXPECT_FALSE(exists(*m_pTestee));
+  EXPECT_FALSE(is_directory(*m_pTestee));
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_FALSE(exists(*m_pTestee));
+  EXPECT_FALSE(is_directory(*m_pTestee));
+}
+
+TEST_F( PathTest, should_equal ) {
+  const std::string root = "aaa/bbb/../../ccc/";
+  m_pTestee->assign(root);
+
+  Path* p2 = new Path("ccc///////");
+
+  EXPECT_TRUE(*m_pTestee==*p2);
+
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_TRUE(*m_pTestee==*m_pTestee);
+  delete p2;
+}
+
+TEST_F( PathTest, should_not_equal ) {
+  const std::string root = "aa/";
+  Path* p2=new Path("aaa//");
+//  p2->assign(root);
+  m_pTestee->assign(root);
+  EXPECT_TRUE(*m_pTestee!=*p2);
+
+  delete m_pTestee;
+  m_pTestee = new Path(root);
+  EXPECT_TRUE(*m_pTestee!=*p2);
+  delete p2;
+}
+
+TEST_F( PathTest, append_success ) {
+
+  const std::string root = "aa/";
+  m_pTestee->assign(root);
+  m_pTestee->append("aaa");
+  std::string a("aa/aaa");
+  EXPECT_TRUE(m_pTestee->native()=="aa/aaa");
+  delete m_pTestee;
+  m_pTestee = new Path("aa/");
+  m_pTestee->append("/aaa");
+  EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+  delete m_pTestee;
+  m_pTestee = new Path("aa");
+  m_pTestee->append("/aaa");
+  EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+  delete m_pTestee;
+  m_pTestee = new Path("aa");
+  m_pTestee->append("aaa");
+  EXPECT_TRUE(m_pTestee->string()=="aa/aaa");
+}
+
+TEST_F( PathTest, should_become_generic_string ) {
+  m_pTestee->assign("/etc/../dev/../usr//lib//");
+  EXPECT_STREQ("/usr/lib/", m_pTestee->generic_string().c_str());
+}
+
diff --git a/unittests/PathTest.h b/unittests/PathTest.h
new file mode 100644
index 0000000..968ce0e
--- /dev/null
+++ b/unittests/PathTest.h
@@ -0,0 +1,45 @@
+//===- PathTest.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PATH_TEST_H
+#define PATH_TEST_H
+
+#include "mcld/Support/Path.h"
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class PathTest
+ *  \brief a testcase for mcld::Path and its non-member funtions.
+ *
+ *  \see Path 
+ */
+class PathTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	PathTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~PathTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::sys::fs::Path* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/RTLinearAllocatorTest.cpp b/unittests/RTLinearAllocatorTest.cpp
new file mode 100644
index 0000000..9ef31e5
--- /dev/null
+++ b/unittests/RTLinearAllocatorTest.cpp
@@ -0,0 +1,140 @@
+//===- RTLinearAllocatorTest.cpp ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/Support/Allocators.h"
+#include <RTLinearAllocatorTest.h>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+RTLinearAllocatorTest::RTLinearAllocatorTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new LinearAllocator<Data, 0>(CHUNK_SIZE);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+RTLinearAllocatorTest::~RTLinearAllocatorTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void RTLinearAllocatorTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void RTLinearAllocatorTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F(RTLinearAllocatorTest, AllocateN) {
+	Data* pointer = m_pTestee->allocate(10);
+	ASSERT_FALSE(0 == pointer);
+	ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+	ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, allocate ) {
+	Data* pointer = m_pTestee->allocate();
+	ASSERT_FALSE(0 == pointer);
+	ASSERT_EQ(CHUNK_SIZE, m_pTestee->max_size());
+	ASSERT_FALSE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, allocateOver ) {
+	Data* pointer = m_pTestee->allocate(CHUNK_SIZE+1);
+	ASSERT_TRUE(0 == pointer);
+	ASSERT_EQ(0, m_pTestee->max_size());
+	ASSERT_TRUE(m_pTestee->empty());
+}
+
+TEST_F(RTLinearAllocatorTest, alloc_construct ) {
+	Data* pointer = m_pTestee->allocate();
+	m_pTestee->construct(pointer);
+	ASSERT_EQ(1, pointer->one);
+	ASSERT_EQ(2, pointer->two);
+	ASSERT_EQ(3, pointer->three);
+	ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, alloc_constructCopy ) {
+	Data* pointer = m_pTestee->allocate();
+	Data data(7, 7, 7, 7);
+	m_pTestee->construct(pointer, data);
+
+	ASSERT_EQ(7, pointer->one);
+	ASSERT_EQ(7, pointer->two);
+	ASSERT_EQ(7, pointer->three);
+	ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, allocN_construct ) {
+	Data* pointer = m_pTestee->allocate(10);
+	m_pTestee->construct(pointer);
+	ASSERT_EQ(1, pointer->one);
+	ASSERT_EQ(2, pointer->two);
+	ASSERT_EQ(3, pointer->three);
+	ASSERT_EQ(4, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, allocN_constructCopy ) {
+	Data* pointer = m_pTestee->allocate(10);
+	Data data(7, 7, 7, 7);
+	m_pTestee->construct(pointer, data);
+	
+	ASSERT_EQ(7, pointer->one);
+	ASSERT_EQ(7, pointer->two);
+	ASSERT_EQ(7, pointer->three);
+	ASSERT_EQ(7, pointer->four);
+}
+
+TEST_F(RTLinearAllocatorTest, multi_alloc_ctor_iterate ) {
+	for (int i=0; i<101; ++i) {
+		Data* pointer = m_pTestee->allocate();
+		m_pTestee->construct(pointer);
+		pointer->one = i;
+	}
+/**
+	Alloc::iterator data, dEnd = m_pTestee->end();
+	int counter = 0;
+	for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+		ASSERT_EQ(counter, (*data).one);
+		++counter;
+	}
+**/
+}
+
+TEST_F(RTLinearAllocatorTest, multi_allocN_ctor_iterate ) {
+	int counter = 0;
+	for (int i=0; i<10000; ++i) {
+		Data* pointer = m_pTestee->allocate(10);
+		for (int j=0; j<10; ++j) {
+			m_pTestee->construct(pointer);
+			pointer->one = counter;
+			++pointer;
+			++counter;
+		}
+	}
+/**
+	Alloc::iterator data, dEnd = m_pTestee->end();
+	counter = 0;
+	for (data=m_pTestee->begin(); data!=dEnd; ++data) {
+		ASSERT_EQ(counter, (*data).one);
+		++counter;
+	}
+**/
+}
+
diff --git a/unittests/RTLinearAllocatorTest.h b/unittests/RTLinearAllocatorTest.h
new file mode 100644
index 0000000..d58442a
--- /dev/null
+++ b/unittests/RTLinearAllocatorTest.h
@@ -0,0 +1,74 @@
+//===- RTLinearAllocatorTest.h --------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef RTLINEARALLOCATOR_TEST_H
+#define RTLINEARALLOCATOR_TEST_H
+
+#include <gtest.h>
+#include "mcld/Support/Allocators.h"
+
+namespace mcldtest
+{
+
+/** \class RTLinearAllocatorTest
+ *  \brief 
+ *
+ *  \see RTLinearAllocator 
+ */
+class RTLinearAllocatorTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	RTLinearAllocatorTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~RTLinearAllocatorTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+public:
+	struct Data {
+		Data()
+		: one(1), two(2), three(3), four(4)
+		{ }
+
+		Data( unsigned int pOne, unsigned int pTwo, unsigned char pThree, unsigned char pFour)
+		{
+			one = pOne;
+			two = pTwo;
+			three = pThree;
+			four = pFour;
+		}
+
+		~Data()
+		{
+			one = -1;
+			two = -2;
+			three = -3;
+			four = -4;
+		}
+
+		unsigned int one;
+		unsigned int two;
+		unsigned char three;
+		unsigned char four;
+  };
+  enum {  CHUNK_SIZE = 32  };
+
+protected:
+	mcld::LinearAllocator<Data,0>* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StaticResolverTest.cpp b/unittests/StaticResolverTest.cpp
new file mode 100644
index 0000000..f9dfdf4
--- /dev/null
+++ b/unittests/StaticResolverTest.cpp
@@ -0,0 +1,436 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/LD/StaticResolver.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+#include "StaticResolverTest.h"
+
+#include <iostream>
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+// Constructor can do set-up work for all test here.
+StaticResolverTest::StaticResolverTest()
+{
+  // create testee. modify it if need
+  m_pResolver = new StaticResolver();
+  m_pFactory = new ResolveInfoFactory();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StaticResolverTest::~StaticResolverTest()
+{
+  delete m_pResolver;
+  delete m_pFactory;
+}
+
+// SetUp() will be called immediately before each test.
+void StaticResolverTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StaticResolverTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( StaticResolverTest, MDEF ) {
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  new_sym->setDesc(ResolveInfo::Define);
+  old_sym->setDesc(ResolveInfo::Define);
+  ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+  ASSERT_TRUE( mcld::ResolveInfo::define_flag == new_sym->info());
+  ASSERT_TRUE( mcld::ResolveInfo::define_flag == old_sym->info());
+  bool override = true;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Abort, result);
+  ASSERT_FALSE( override );
+  ASSERT_STREQ( "multiple definitions of `abc'.", m_pResolver->mesg().c_str() );
+}
+
+TEST_F( StaticResolverTest, DynDefAfterDynUndef ) {
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setBinding(ResolveInfo::Global);
+  old_sym->setBinding(ResolveInfo::Global);
+  new_sym->setDesc(ResolveInfo::Undefined);
+  old_sym->setDesc(ResolveInfo::Define);
+  new_sym->setSource(true);
+  old_sym->setSource(true);
+
+  new_sym->setSize(0);
+
+  old_sym->setSize(1);
+
+  ASSERT_EQ( mcld::ResolveInfo::Global,    new_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Global,    old_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Undefined, new_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Define,    old_sym->desc());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_FALSE( override );
+  ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynDefAfterDynDef ) {
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setBinding(ResolveInfo::Global);
+  old_sym->setBinding(ResolveInfo::Global);
+  new_sym->setDesc(ResolveInfo::Define);
+  old_sym->setDesc(ResolveInfo::Define);
+  new_sym->setSource(true);
+  old_sym->setSource(true);
+
+  new_sym->setSize(0);
+
+  old_sym->setSize(1);
+
+  ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Global, old_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_FALSE( override );
+  ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynUndefAfterDynUndef ) {
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setBinding(ResolveInfo::Global);
+  old_sym->setBinding(ResolveInfo::Global);
+  new_sym->setDesc(ResolveInfo::Undefined);
+  old_sym->setDesc(ResolveInfo::Undefined);
+  new_sym->setSource(true);
+  old_sym->setSource(true);
+
+  new_sym->setSize(0);
+
+  old_sym->setSize(1);
+
+  ASSERT_EQ( mcld::ResolveInfo::Global,    new_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Global,    old_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Undefined, new_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Undefined, old_sym->desc());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_FALSE( override );
+  ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideWeakByGlobal )
+{
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setBinding(ResolveInfo::Global);
+  old_sym->setBinding(ResolveInfo::Weak);
+  new_sym->setSize(0);
+  old_sym->setSize(1);
+
+  ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Weak, old_sym->binding());
+
+  ASSERT_TRUE( mcld::ResolveInfo::global_flag == new_sym->info());
+  ASSERT_TRUE( mcld::ResolveInfo::weak_flag == old_sym->info());
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_TRUE( override );
+  ASSERT_EQ(0, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, DynWeakAfterDynDef ) {
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  old_sym->setBinding(ResolveInfo::Weak);
+  new_sym->setBinding(ResolveInfo::Global);
+
+  new_sym->setSource(true);
+  old_sym->setSource(true);
+
+  old_sym->setDesc(ResolveInfo::Define);
+  new_sym->setDesc(ResolveInfo::Define);
+
+  new_sym->setSize(0);
+
+  old_sym->setSize(1);
+
+  ASSERT_EQ( mcld::ResolveInfo::Weak,   old_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Global, new_sym->binding());
+  ASSERT_EQ( mcld::ResolveInfo::Define, old_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Define, new_sym->desc());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_FALSE( override );
+  ASSERT_EQ(1, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, MarkByBiggerCommon )
+{
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setDesc(ResolveInfo::Common);
+  old_sym->setDesc(ResolveInfo::Common);
+  new_sym->setSize(999);
+  old_sym->setSize(0);
+
+  ASSERT_EQ( mcld::ResolveInfo::Common, new_sym->desc());
+  ASSERT_EQ( mcld::ResolveInfo::Common, old_sym->desc());
+
+  ASSERT_TRUE( mcld::ResolveInfo::common_flag == new_sym->info());
+  ASSERT_TRUE( mcld::ResolveInfo::common_flag == old_sym->info());
+  bool override = true;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_FALSE( override );
+  ASSERT_EQ(999, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideByBiggerCommon )
+{
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  new_sym->setDesc(ResolveInfo::Common);
+  old_sym->setDesc(ResolveInfo::Common);
+  old_sym->setBinding(ResolveInfo::Weak);
+  new_sym->setSize(999);
+  old_sym->setSize(0);
+
+  ASSERT_EQ( ResolveInfo::Common, new_sym->desc());
+  ASSERT_EQ( ResolveInfo::Common, old_sym->desc());
+  ASSERT_EQ( ResolveInfo::Weak, old_sym->binding());
+
+  ASSERT_TRUE( ResolveInfo::common_flag == new_sym->info());
+  ASSERT_TRUE( (ResolveInfo::weak_flag | ResolveInfo::common_flag) == old_sym->info());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ( Resolver::Success, result);
+  ASSERT_TRUE( override );
+  ASSERT_EQ(999, old_sym->size());
+}
+
+TEST_F( StaticResolverTest, OverrideCommonByDefine)
+{
+  ResolveInfo* old_sym = m_pFactory->produce("abc");
+  ResolveInfo* new_sym = m_pFactory->produce("abc");
+  
+  old_sym->setDesc(ResolveInfo::Common);
+  old_sym->setSize(0);
+
+  new_sym->setDesc(ResolveInfo::Define);
+  new_sym->setSize(999);
+
+  ASSERT_EQ( ResolveInfo::Define, new_sym->desc());
+  ASSERT_EQ( ResolveInfo::Common, old_sym->desc());
+
+  ASSERT_TRUE( ResolveInfo::define_flag == new_sym->info());
+  ASSERT_TRUE( ResolveInfo::common_flag == old_sym->info());
+
+  bool override = false;
+  unsigned int result = m_pResolver->resolve(*old_sym, *new_sym, override);
+  ASSERT_EQ(Resolver::Warning, result);
+  ASSERT_TRUE( override );
+  ASSERT_EQ(999, old_sym->size());
+  
+  ASSERT_STREQ("definition of 'abc' is overriding common.", m_pResolver->mesg().c_str() );
+
+}
+
+TEST_F( StaticResolverTest, SetUpDesc)
+{
+  ResolveInfo* sym = m_pFactory->produce("abc");
+  
+  sym->setIsSymbol(true);
+
+//  ASSERT_FALSE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setIsSymbol(false);
+  ASSERT_FALSE( sym->isSymbol() );
+//  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setDesc(ResolveInfo::Define);
+  ASSERT_FALSE( sym->isSymbol() );
+//  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_TRUE( sym->isDefine() );
+  ASSERT_FALSE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( ResolveInfo::Define, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setDesc(ResolveInfo::Common);
+  ASSERT_FALSE( sym->isSymbol() );
+//  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_FALSE( sym->isUndef() );
+  ASSERT_TRUE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( ResolveInfo::Common, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setDesc(ResolveInfo::Indirect);
+  ASSERT_FALSE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_FALSE( sym->isUndef() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_TRUE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( ResolveInfo::Indirect, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setDesc(ResolveInfo::Undefined);
+  ASSERT_FALSE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+}
+
+TEST_F( StaticResolverTest, SetUpBinding)
+{
+  ResolveInfo* sym = m_pFactory->produce("abc");
+  
+  sym->setIsSymbol(true);
+
+//  ASSERT_FALSE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( 0, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setBinding(ResolveInfo::Global);
+  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_TRUE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( ResolveInfo::Global, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setBinding(ResolveInfo::Weak);
+  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_FALSE( sym->isGlobal() );
+  ASSERT_TRUE( sym->isWeak() );
+  ASSERT_FALSE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( ResolveInfo::Weak, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+
+  sym->setBinding(ResolveInfo::Local);
+  ASSERT_TRUE( sym->isSymbol() );
+  ASSERT_FALSE( sym->isGlobal() );
+  ASSERT_FALSE( sym->isWeak() );
+  ASSERT_TRUE( sym->isLocal() );
+  ASSERT_FALSE( sym->isDyn() );
+  ASSERT_FALSE( sym->isDefine() );
+  ASSERT_TRUE( sym->isUndef() );
+  ASSERT_FALSE( sym->isCommon() );
+  ASSERT_FALSE( sym->isIndirect() );
+  ASSERT_EQ( ResolveInfo::NoType, sym->type());
+  ASSERT_EQ( 0, sym->desc() );
+  ASSERT_EQ( ResolveInfo::Local, sym->binding() );
+  ASSERT_EQ( 0, sym->other() );
+}
+
diff --git a/unittests/StaticResolverTest.h b/unittests/StaticResolverTest.h
new file mode 100644
index 0000000..8b8ba31
--- /dev/null
+++ b/unittests/StaticResolverTest.h
@@ -0,0 +1,52 @@
+//===- headerTest.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STATICRESOLVER_TEST_H
+#define STATICRESOLVER_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StaticResolver;
+class ResolveInfoFactory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StaticResolverTest
+ *  \brief The testcases for static resolver
+ *
+ *  \see StaticResolver 
+ */
+class StaticResolverTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	StaticResolverTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~StaticResolverTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::StaticResolver* m_pResolver;
+	mcld::ResolveInfoFactory* m_pFactory;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StrSymPoolTest.cpp b/unittests/StrSymPoolTest.cpp
new file mode 100644
index 0000000..a4ef558
--- /dev/null
+++ b/unittests/StrSymPoolTest.cpp
@@ -0,0 +1,259 @@
+//===- StrSymPoolTest.cpp -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/StrSymPool.h"
+#include "StrSymPoolTest.h"
+#include <string>
+#include <cstdio>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+StrSymPoolTest::StrSymPoolTest()
+{
+	// create testee. modify it if need
+  Resolver resolver;
+	m_pTestee = new StrSymPool(1, 1, resolver);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StrSymPoolTest::~StrSymPoolTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void StrSymPoolTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StrSymPoolTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+
+TEST_F( StrSymPoolTest, insertString ) {
+  const char *s1 = "Hello MCLinker";
+  const char *result1 = m_pTestee->insertString(s1);
+  EXPECT_NE(s1, result1);
+  EXPECT_STREQ(s1, result1);
+}
+
+TEST_F( StrSymPoolTest, insertSameString ) {
+  const char *s1 = "Hello MCLinker";
+  std::string s2(s1);
+  const char *result1 = m_pTestee->insertString(s1);
+  const char *result2 = m_pTestee->insertString(s2.c_str());
+  EXPECT_STREQ(s1, result1);
+  EXPECT_STREQ(s2.c_str(), result2);
+  EXPECT_EQ(result1, result2);
+}
+
+TEST_F( StrSymPoolTest, insert_local_defined_Symbol ) {
+  const char *name = "Hello MCLinker";
+  bool isDyn = false;
+  LDSymbol::Type type = LDSymbol::Defined;
+  LDSymbol::Binding binding = LDSymbol::Local;
+  const llvm::MCSectionData *section = 0;
+  uint64_t value = 0;
+  uint64_t size = 0;
+  uint8_t other = 0;
+
+  LDSymbol *sym =  m_pTestee->insertSymbol(name,
+                                           isDyn,
+                                           type,
+                                           binding,
+                                           section,
+                                           value,
+                                           size,
+                                           other);
+  EXPECT_NE(name, sym->name());
+  EXPECT_STREQ(name, sym->name());
+  EXPECT_EQ(isDyn, sym->isDyn());
+  EXPECT_EQ(type, sym->type());
+  EXPECT_EQ(binding, sym->binding());
+  EXPECT_EQ(section, sym->section());
+  EXPECT_EQ(value, sym->value());
+  EXPECT_EQ(size, sym->size());
+  EXPECT_EQ(other, sym->other());
+
+  LDSymbol *sym2 =  m_pTestee->insertSymbol(name,
+                                            isDyn,
+                                            type,
+                                            binding,
+                                            section,
+                                            value,
+                                            size,
+                                            other);
+  EXPECT_NE(name, sym2->name());
+  EXPECT_STREQ(name, sym2->name());
+  EXPECT_EQ(isDyn, sym2->isDyn());
+  EXPECT_EQ(type, sym2->type());
+  EXPECT_EQ(binding, sym2->binding());
+  EXPECT_EQ(section, sym2->section());
+  EXPECT_EQ(value, sym2->value());
+  EXPECT_EQ(size, sym2->size());
+  EXPECT_EQ(other, sym2->other());
+
+
+  EXPECT_NE(sym, sym2);
+}
+
+TEST_F( StrSymPoolTest, insert_global_reference_Symbol ) {
+  const char *name = "Hello MCLinker";
+  bool isDyn = false;
+  LDSymbol::Type type = LDSymbol::Reference;
+  LDSymbol::Binding binding = LDSymbol::Global;
+  const llvm::MCSectionData *section = 0;
+  uint64_t value = 0;
+  uint64_t size = 0;
+  uint8_t other = 0;
+
+  LDSymbol *sym =  m_pTestee->insertSymbol(name,
+                                           isDyn,
+                                           type,
+                                           binding,
+                                           section,
+                                           value,
+                                           size,
+                                           other);
+  EXPECT_NE(name, sym->name());
+  EXPECT_STREQ(name, sym->name());
+  EXPECT_EQ(isDyn, sym->isDyn());
+  EXPECT_EQ(type, sym->type());
+  EXPECT_EQ(binding, sym->binding());
+  EXPECT_EQ(section, sym->section());
+  EXPECT_EQ(value, sym->value());
+  EXPECT_EQ(size, sym->size());
+  EXPECT_EQ(other, sym->other());
+
+
+  LDSymbol *sym2 =  m_pTestee->insertSymbol(name,
+                                            isDyn,
+                                            type,
+                                            binding,
+                                            section,
+                                            value,
+                                            size,
+                                            other);
+
+
+  EXPECT_EQ(sym, sym2);
+
+
+  LDSymbol *sym3 =  m_pTestee->insertSymbol("Different symbol",
+                                            isDyn,
+                                            type,
+                                            binding,
+                                            section,
+                                            value,
+                                            size,
+                                            other);
+
+  EXPECT_NE(sym, sym3);
+}
+
+
+TEST_F( StrSymPoolTest, insertSymbol_after_insert_same_string ) {
+  const char *name = "Hello MCLinker";
+  bool isDyn = false;
+  LDSymbol::Type type = LDSymbol::Defined;
+  LDSymbol::Binding binding = LDSymbol::Global;
+  const llvm::MCSectionData *section = 0;
+  uint64_t value = 0;
+  uint64_t size = 0;
+  uint8_t other = 0;
+
+  const char *result1 =  m_pTestee->insertString(name);
+  LDSymbol *sym =  m_pTestee->insertSymbol(name,
+                                           isDyn,
+                                           type,
+                                           binding,
+                                           section,
+                                           value,
+                                           size,
+                                           other);
+
+  EXPECT_STREQ(name, sym->name());
+  EXPECT_EQ(result1, sym->name());
+
+  char s[16];
+  strcpy(s, result1);
+  const char *result2 = m_pTestee->insertString(result1);
+  const char *result3 = m_pTestee->insertString(s);
+
+  EXPECT_EQ(result1, result2);
+  EXPECT_EQ(result1, result3);
+}
+
+
+TEST_F( StrSymPoolTest, insert_16384_weak_reference_symbols ) {
+  char name[16];
+  bool isDyn = false;
+  LDSymbol::Type type = LDSymbol::Reference;
+  LDSymbol::Binding binding = LDSymbol::Weak;
+  const llvm::MCSectionData *section = 0;
+  uint64_t value = 0;
+  uint64_t size = 0;
+  uint8_t other = 0;
+  strcpy(name, "Hello MCLinker");
+  LDSymbol *syms[128][128];
+  for(int i=0; i<128 ;++i) {
+    name[0] = i;
+    for(int j=0; j<128 ;++j) {
+      name[1] = j;
+      syms[i][j] =  m_pTestee->insertSymbol(name,
+                                            isDyn,
+                                            type,
+                                            binding,
+                                            section,
+                                            value,
+                                            size,
+                                            other);
+
+      ASSERT_STREQ(name, syms[i][j]->name());
+    }
+  }
+  for(int i=127; i>=0 ;--i) {
+    name[0] = i;
+    for(int j=0; j<128 ;++j) {
+      name[1] = j;
+      LDSymbol *sym =  m_pTestee->insertSymbol(name,
+                                               isDyn,
+                                               type,
+                                               binding,
+                                               section,
+                                               value,
+                                               size,
+                                               other);
+      ASSERT_EQ(sym, syms[i][j]);
+    }
+  }
+  for(int i=0; i<128 ;++i) {
+    name[0] = i;
+    for(int j=0; j<128 ;++j) {
+      name[1] = j;
+      LDSymbol *sym =  m_pTestee->insertSymbol(name,
+                                               isDyn,
+                                               type,
+                                               binding,
+                                               section,
+                                               value,
+                                               size,
+                                               other);
+      ASSERT_EQ(sym, syms[i][j]);
+    }
+  }
+}
diff --git a/unittests/StrSymPoolTest.h b/unittests/StrSymPoolTest.h
new file mode 100644
index 0000000..041fafa
--- /dev/null
+++ b/unittests/StrSymPoolTest.h
@@ -0,0 +1,50 @@
+//===- StrSymPoolTest.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STRSYMPOOL_TEST_H
+#define STRSYMPOOL_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StrSymPool;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StrSymPoolTest
+ *  \brief 
+ *
+ *  \see StrSymPool 
+ */
+class StrSymPoolTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	StrSymPoolTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~StrSymPoolTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+
+protected:
+	mcld::StrSymPool* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/StringTableTest.cpp b/unittests/StringTableTest.cpp
new file mode 100644
index 0000000..59a8e7b
--- /dev/null
+++ b/unittests/StringTableTest.cpp
@@ -0,0 +1,77 @@
+//===- StringTableTest.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "StringTableTest.h"
+#include "mcld/LD/StringTable.h"
+#include <cstring>
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+StringTableTest::StringTableTest()
+{
+  // create testee. modify it if need
+  Resolver* R = new Resolver();
+  StrSymPool* Pool = new StrSymPool(1, 1, *R);
+  m_pTestee = new StringTable(*Pool);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+StringTableTest::~StringTableTest()
+{
+  delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void StringTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void StringTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F(StringTableTest, different_string_size) {
+  int size = 127-32;
+  for (int i = 32; i < 127; ++i) {
+    char c[2];
+    c[0] = i;
+    c[1] = '\0';
+    ASSERT_NE(m_pTestee->insert(c), c);
+  }
+  ASSERT_EQ(m_pTestee->size(), size);
+}
+
+TEST_F(StringTableTest, traverse_begin_to_end) {
+  m_pTestee->insert("Hello");
+  m_pTestee->insert("World");
+  m_pTestee->insert("Media");
+  m_pTestee->insert("Tek");
+  StringTable::iterator it = m_pTestee->begin();
+  ASSERT_STREQ(*it, "Hello");
+  ++it;
+  ASSERT_STREQ(*it, "World");
+  ++it;
+  ASSERT_STREQ(*it, "Media");
+  ++it;
+  ASSERT_STREQ(*it, "Tek");
+  ++it;
+  ASSERT_EQ(it, m_pTestee->end());
+}
+
+TEST_F(StringTableTest, null_string) {
+  m_pTestee->insert("");
+  ASSERT_STREQ(*(m_pTestee->begin()), "");
+  ASSERT_EQ(m_pTestee->size(), 1);
+}
diff --git a/unittests/StringTableTest.h b/unittests/StringTableTest.h
new file mode 100644
index 0000000..0b397e8
--- /dev/null
+++ b/unittests/StringTableTest.h
@@ -0,0 +1,50 @@
+//===- StringTableTest.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef STRINGTABLE_TEST_H
+#define STRINGTABLE_TEST_H
+
+#include <gtest.h>
+
+namespace mcld
+{
+class StringTable;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class StringTableTest
+ *  \brief 
+ *
+ *  \see StringTable 
+ */
+class StringTableTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  StringTableTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~StringTableTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+
+protected:
+  mcld::StringTable* m_pTestee;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/SymbolCategoryTest.cpp b/unittests/SymbolCategoryTest.cpp
new file mode 100644
index 0000000..4233c3e
--- /dev/null
+++ b/unittests/SymbolCategoryTest.cpp
@@ -0,0 +1,94 @@
+//===- implTest.cpp -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDSymbol.h>
+#include <iostream>
+#include "SymbolCategoryTest.h"
+
+using namespace std;
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+SymbolCategoryTest::SymbolCategoryTest()
+{
+	// create testee. modify it if need
+	m_pTestee = new SymbolCategory();
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SymbolCategoryTest::~SymbolCategoryTest()
+{
+	delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void SymbolCategoryTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SymbolCategoryTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F(SymbolCategoryTest, upward_test) {
+  ResolveInfo* a = m_InfoFactory.produce("a");
+  ResolveInfo* b = m_InfoFactory.produce("b");
+  ResolveInfo* c = m_InfoFactory.produce("c");
+  ResolveInfo* d = m_InfoFactory.produce("d");
+  ResolveInfo* e = m_InfoFactory.produce("e");
+  e->setBinding(ResolveInfo::Global);
+  d->setBinding(ResolveInfo::Weak);
+  c->setDesc(ResolveInfo::Common);
+  c->setBinding(ResolveInfo::Global);
+  b->setBinding(ResolveInfo::Local);
+  a->setType(ResolveInfo::File);
+  
+  LDSymbol aa;
+  LDSymbol bb;
+  LDSymbol cc;
+  LDSymbol dd;
+  LDSymbol ee;
+
+  aa.setResolveInfo(*a);
+  bb.setResolveInfo(*b);
+  cc.setResolveInfo(*c);
+  dd.setResolveInfo(*d);
+  ee.setResolveInfo(*e);
+
+  m_pTestee->add(ee);
+  m_pTestee->add(dd);
+  m_pTestee->add(cc);
+  m_pTestee->add(bb);
+  m_pTestee->add(aa);
+
+  SymbolCategory::iterator sym = m_pTestee->begin();
+  ASSERT_STREQ("a", (*sym)->name());
+  ++sym;
+  ASSERT_STREQ("b", (*sym)->name());
+  ++sym;
+  ASSERT_STREQ("c", (*sym)->name());
+  ++sym;
+  ASSERT_STREQ("d", (*sym)->name());
+  ++sym;
+  ASSERT_STREQ("e", (*sym)->name());
+
+  ASSERT_EQ(2, m_pTestee->numOfLocals());
+  ASSERT_EQ(1, m_pTestee->numOfCommons());
+  ASSERT_EQ(2, m_pTestee->numOfRegulars());
+  ASSERT_EQ(5, m_pTestee->numOfSymbols());
+}
+
diff --git a/unittests/SymbolCategoryTest.h b/unittests/SymbolCategoryTest.h
new file mode 100644
index 0000000..f721368
--- /dev/null
+++ b/unittests/SymbolCategoryTest.h
@@ -0,0 +1,52 @@
+//===- headerTest.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOLCATEGORY_TEST_H
+#define MCLD_SYMBOLCATEGORY_TEST_H
+#include <mcld/LD/ResolveInfoFactory.h>
+
+#include <gtest.h>
+
+namespace mcld
+{
+class SymbolCategory;
+
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class SymbolCategoryTest
+ *  \brief The testcases of symbol category.
+ *
+ *  \see SymbolCategory 
+ */
+class SymbolCategoryTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  SymbolCategoryTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~SymbolCategoryTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+
+protected:
+  mcld::SymbolCategory* m_pTestee;
+  mcld::ResolveInfoFactory m_InfoFactory;
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/SymbolTableTest.cpp b/unittests/SymbolTableTest.cpp
new file mode 100644
index 0000000..5b665f0
--- /dev/null
+++ b/unittests/SymbolTableTest.cpp
@@ -0,0 +1,45 @@
+//===- SymbolTableTest.cpp ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/LD/SymbolTable.h"
+#include "SymbolTableTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+SymbolTableTest::SymbolTableTest()
+{
+  // create testee. modify it if need
+  m_pTestee = new SymbolTable<>(m_StrTable);
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+SymbolTableTest::~SymbolTableTest()
+{
+  delete m_pTestee;
+}
+
+// SetUp() will be called immediately before each test.
+void SymbolTableTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void SymbolTableTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+TEST_F(SymbolTableTest, init) {
+  mcld::SymbolTable<>::iterator it;
+  it = m_pTestee->begin();
+  ASSERT_EQ(it, m_pTestee->end());
+}
diff --git a/unittests/SymbolTableTest.h b/unittests/SymbolTableTest.h
new file mode 100644
index 0000000..9076ac9
--- /dev/null
+++ b/unittests/SymbolTableTest.h
@@ -0,0 +1,50 @@
+//===- SymbolTableTest.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_SYMBOLTABLE_TEST_H
+#define LD_SYMBOLTABLE_TEST_H
+#include "mcld/LD/StringTable.h"
+#include <gtest.h>
+
+namespace mcld
+{
+  template <template <class> class, class>
+  class SymbolTable;
+} // namespace for mcld
+
+namespace mcldtest
+{
+
+/** \class SymbolTableTest
+ *  \brief 
+ *
+ *  \see SymbolTable 
+ */
+class SymbolTableTest : public ::testing::Test
+{
+public:
+  // Constructor can do set-up work for all test here.
+  SymbolTableTest();
+
+  // Destructor can do clean-up work that doesn't throw exceptions here.
+  virtual ~SymbolTableTest();
+
+  // SetUp() will be called immediately before each test.
+  virtual void SetUp();
+
+  // TearDown() will be called immediately after each test.
+  virtual void TearDown();
+
+protected:
+  mcld::SymbolTable<>* m_pTestee;
+  mcld::StringTable m_StrTable;
+};
+
+} // namespace of mcldtest
+
+#endif
diff --git a/unittests/TargetMachineTest.cpp b/unittests/TargetMachineTest.cpp
new file mode 100644
index 0000000..6258906
--- /dev/null
+++ b/unittests/TargetMachineTest.cpp
@@ -0,0 +1,42 @@
+//===- TargetMachineTest.cpp ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <TargetMachineTest.h>
+
+using namespace mcld;
+using namespace mcldTEST;
+
+
+// Constructor can do set-up work for all test here.
+TargetMachineTest::TargetMachineTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+TargetMachineTest::~TargetMachineTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void TargetMachineTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void TargetMachineTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+
+TEST_F( TargetMachineTest, addPassesToEmitFile ) {
+	mcld::addPassesToEmitFile();
+}
+
diff --git a/unittests/TargetMachineTest.h b/unittests/TargetMachineTest.h
new file mode 100644
index 0000000..3f77da7
--- /dev/null
+++ b/unittests/TargetMachineTest.h
@@ -0,0 +1,41 @@
+//===- TargetMachineTest.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGETMACHINE_TEST_H
+#define TARGETMACHINE_TEST_H
+#include "mcld/Target/TargetMachine.h"
+#include <gtest.h>
+
+namespace mcldTEST
+{
+
+/** \class TargetMachineTest
+ *  \brief 
+ *
+ *  \see TargetMachine 
+ */
+class TargetMachineTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	TargetMachineTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~TargetMachineTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+};
+
+} // namespace of BOLDTEST
+
+#endif
+
diff --git a/unittests/UniqueGCFactoryBaseTest.cpp b/unittests/UniqueGCFactoryBaseTest.cpp
new file mode 100644
index 0000000..08f82ba
--- /dev/null
+++ b/unittests/UniqueGCFactoryBaseTest.cpp
@@ -0,0 +1,87 @@
+//===- UniqueGCFactoryBaseTest.cpp ----------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "mcld/MC/ContextFactory.h"
+#include "mcld/Support/MemoryAreaFactory.h"
+#include "UniqueGCFactoryBaseTest.h"
+
+using namespace mcld;
+using namespace mcldtest;
+
+
+// Constructor can do set-up work for all test here.
+UniqueGCFactoryBaseTest::UniqueGCFactoryBaseTest()
+{
+}
+
+// Destructor can do clean-up work that doesn't throw exceptions here.
+UniqueGCFactoryBaseTest::~UniqueGCFactoryBaseTest()
+{
+}
+
+// SetUp() will be called immediately before each test.
+void UniqueGCFactoryBaseTest::SetUp()
+{
+}
+
+// TearDown() will be called immediately after each test.
+void UniqueGCFactoryBaseTest::TearDown()
+{
+}
+
+//==========================================================================//
+// Testcases
+//
+TEST_F( UniqueGCFactoryBaseTest, number_constructor ) {
+	ContextFactory *contextFactory = new ContextFactory(10); 
+	contextFactory->produce("/");
+	contextFactory->produce("ab/c");
+	ASSERT_EQ( 2, contextFactory->size());
+	delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, unique_produce ) {
+	ContextFactory *contextFactory = new ContextFactory(10); 
+	LDContext* context1 = contextFactory->produce("/");
+	contextFactory->produce("ab/c");
+	ASSERT_EQ( 2, contextFactory->size());
+	LDContext* context2 = contextFactory->produce("/");
+	ASSERT_EQ( context1, context2 );
+	delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, unique_produce2 ) {
+	ContextFactory *contextFactory = new ContextFactory(10); 
+	LDContext* context1 = contextFactory->produce("abc/def");
+	contextFactory->produce("ab/c");
+	ASSERT_EQ( 2, contextFactory->size());
+	LDContext* context2 = contextFactory->produce("ttt/../abc/def");
+	ASSERT_EQ( context1, context2 );
+	delete contextFactory;
+}
+
+TEST_F( UniqueGCFactoryBaseTest, iterator )
+{
+	MemoryAreaFactory* memFactory = new MemoryAreaFactory(10);
+	MemoryArea* area1 = memFactory->produce("/home/luba", O_RDONLY);
+	MemoryArea* area2 = memFactory->produce("/home/jush", O_RDONLY);
+	ASSERT_NE( area1, area2);
+	MemoryArea* area3 = memFactory->produce("/home/jush/../luba", O_RDONLY);
+	ASSERT_EQ( area1, area3);
+	ASSERT_FALSE( memFactory->empty());
+	ASSERT_EQ( 2, memFactory->size());
+	MemoryAreaFactory::iterator aIter = memFactory->begin();
+	ASSERT_EQ( area1, &(*aIter));
+	++aIter;
+	ASSERT_EQ( area2, &(*aIter));
+	++aIter;
+	MemoryAreaFactory::iterator aEnd = memFactory->end();
+	ASSERT_TRUE( aEnd == aIter);
+	delete memFactory;
+}
+
diff --git a/unittests/UniqueGCFactoryBaseTest.h b/unittests/UniqueGCFactoryBaseTest.h
new file mode 100644
index 0000000..a1558e7
--- /dev/null
+++ b/unittests/UniqueGCFactoryBaseTest.h
@@ -0,0 +1,42 @@
+//===- UniqueGCFactoryBaseTest.h ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UNIQUE_GCFACTORYBASE_TEST_H
+#define UNIQUE_GCFACTORYBASE_TEST_H
+
+#include "mcld/Support/UniqueGCFactory.h"
+#include <gtest.h>
+
+namespace mcldtest
+{
+
+/** \class UniqueGCFactoryBaseTest
+ *  - check the unique of key.
+ *  - make sure the key associates with the same storage of value.
+ *  - check if all functions in the GCFactoryBase are available.
+ */
+class UniqueGCFactoryBaseTest : public ::testing::Test
+{
+public:
+	// Constructor can do set-up work for all test here.
+	UniqueGCFactoryBaseTest();
+
+	// Destructor can do clean-up work that doesn't throw exceptions here.
+	virtual ~UniqueGCFactoryBaseTest();
+
+	// SetUp() will be called immediately before each test.
+	virtual void SetUp();
+
+	// TearDown() will be called immediately after each test.
+	virtual void TearDown();
+};
+
+} // namespace of mcldtest
+
+#endif
+
diff --git a/unittests/test.txt b/unittests/test.txt
new file mode 100644
index 0000000..5b5a6a9
--- /dev/null
+++ b/unittests/test.txt
@@ -0,0 +1 @@
+This is a text for testing
diff --git a/unittests/test2.txt b/unittests/test2.txt
new file mode 100644
index 0000000..f1e9c6a
--- /dev/null
+++ b/unittests/test2.txt
Binary files differ
diff --git a/unittests/test3.txt b/unittests/test3.txt
new file mode 100644
index 0000000..2689bfd
--- /dev/null
+++ b/unittests/test3.txt
@@ -0,0 +1,296 @@
+HELLOopyright (C@@1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+#   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# This Makefile contains release scripts for gdb, binutils, and other
+# packages which live in src.  It used to be part of the top level Makefile,
+# but th@@ turned out to be very messy and hard to maintain.
+
+# This stuff really ought to be cleaned up and turned into something other
+# than a Makefile.  As it is it's heavily recursive.
+
+# This is the name of this script (!).  Needed due to horrible recursion.
+SELF = src-release
+
+SHELL = /bin/sh
+
+BZIPPROG = bzip2
+MD5PROG = md5sum
+
+# (Default to avoid splitting info files by setting the threshold high.)
+MAKEINFOFLAGS = --split-size=5000000
+
+# pwd command to use.  Allow user to override default by setting PWDCMD in
+# the environment to account for automounters.  The make variable must not
+# be called PWDCMD, otherwise the value set here is passed to make
+# subprocesses and overrides the setting from the user's environment.
+PWD = $${PWDCMD-pwd}
+
+#
+# Support for building net releases
+
+# Files in devo used in any net release.
+DEVO_SUPPORT= README Makefile.in configure configure.ac \
+	config.guess config.sub config move-if-change \
+	COPYING COPYING.LIB install-sh config-ml.in symlink-tree \
+	mkinstalldirs ltmain.sh missing ylwrap \
+	libtool.m4 ltsugar.m4 ltversion.m4 ltoptions.m4 \
+	Makefile.def Makefile.tpl src-release config.rpath \
+	ChangeLog MAINTAINERS README-maintainer-mode \
+	lt~obsolete.m4 ltgcc.m4 depcomp mkdep compile \
+	COPYING3 COPYING3.LIB
+
+# Files in devo/etc used in any net release.
+ETC_SUPPORT= Makefile.in configure configure.in standards.texi \
+	make-stds.texi standards.info* configure.texi configure.info* \
+	ChangeLog configbuild.* configdev.* fdl.texi texi2pod.pl gnu-oids.texi
+
+
+# When you use `make setup-dirs' or `make taz' you should always redefine
+# this macro.
+SUPPORT_FILES = list-of-support-files-for-tool-in-question
+
+# NOTE: No double quotes in the below.  It is used within shell script
+# as VER="$(VER)"
+VER = `	if grep 'AM_INIT_AUTOMAKE.*BFD_VERSION' $(TOOL)/configure.in >/dev/null 2>&1; then \
+	  sed < bfd/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \
+	elif grep AM_INIT_AUTOMAKE $(TOOL)/configure.in >/dev/null 2>&1; then \
+	  sed < $(TOOL)/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'; \
+	elif test -f $(TOOL)/version.in; then \
+	  head -1 $(TOOL)/version.in; \
+	elif grep VERSION $(TOOL)/Makefile.in > /dev/null 2>&1; then \
+	  sed < $(TOOL)/Makefile.in -n 's/^VERSION *= *//p'; \
+	else \
+	  echo VERSION; \
+	fi`
+PACKAGE = $(TOOL)
+
+.PHONY: taz
+taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+	$(MAKE) -f $(SELF) do-proto-toplev \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-md5sum \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-tar \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-bz2 \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: gdb-tar
+gdb-tar: $(DEVO_SUPPORT)OH(SUPPORT_FILES) texinfo/texinfo.tex
+	$(MAKE) -f $(SELF) do-proto-toplev \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-md5sum \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-djunpack \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-tar \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: gdb-taz
+gdb-taz: gdb-tar $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+	$(MAKE) -f $(SELF) gdb-tar \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+	$(MAKE) -f $(SELF) do-bz2 \
+		TOOL=$(TOOL) PACKAGE="$(PACKAGE)" VER="$(VER)" \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(SUPPORT_FILES)"
+
+.PHONY: do-proto-toplev
+do-proto-toplev: $(DEVO_SUPPORT) $(SUPPORT_FILES) texinfo/texinfo.tex
+	echo "==> Making $(PACKAGE)-$(VER)/"
+	# Take out texinfo from a few places.
+	sed -e '/^all\.normal: /s/\all-texinfo //' \
+	    -e '/^	install-texinfo /d' \
+	<Makefile.in >tmp
+	mv -f tmp Makefile.in
+	#
+	./configure i686-pc-linux-gnu
+	$(MAKE) configure-host configure-target \
+	    ALL_GCC="" ALL_GCC_C="" ALL_GCC_CXX="" \
+	    CC_FOR_TARGET="$(CC)" CXX_FOR_TARGET="$(CXX)"
+	# Make links, and run "make diststuff" or "make info" when needed.
+	rm -rf proto-toplev ; mkdir proto-toplev
+	set -e ; dirs="$(DEVO_SUPPORT) $(SUPPORT_FILES) $(TOOL)" ; \
+	for d in $$dirs ; do \
+	  if [ -d $$d ]; then \
+	    if [ ! -f $$d/Makefile ] ; then true ; \
+	    elif grep '^diststuff:' $$d/Makefile >/dev/null ; then \
+		(cd $$d ; $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" \
+			  diststuff ) || exit 1 ; \
+	    elif grep '^info:' $$d/Makefile >/dev/null ; then \
+		(cd $$d ; $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" \
+			  info ) || exit 1 ; \
+	    fi ; \
+	    if [ -d $$d/proto-$$d.dir ]; then \
+	      ln -s ../$$d/proto-$$d.dir proto-toplev/$$d ; \
+	    else \
+	      ln -s ../$$d proto-toplev/$$d ; \
+	    fi ; \
+	  else ln -s ../$$d proto-toplev/$$d ; fi ; \
+	done
+	cd etc && $(MAKE) MAKEINFOFLAGS="$(MAKEINFOFLAGS)" info
+	$(MAKE) distclean
+	# Kludge for pr gdb/857.  intl/Makefile.in lacks a couple
+	# of files in the distclean rule.  Zack W is planning to make
+	# the gcc version of intl/ the master version and then push
+	# that version to src soon.  See:
+	#   http://sources.redhat.com/ml/binutils/2003-07/msg00032.html
+	# After the src version of intl/ is upgraded, we can look at
+	# moving this logic into intl/Makefile.in distclean rule
+	# if it is still needed.  -- chastain 2003-09-12
+	rm -f intl/config.cache
+	rm -f intl/config.status
+	rm -f intl/config.h
+	rm -f intl/stamp-h
+	#
+	mkdir proto-toplev/etc
+	(cd proto-toplev/etc; \
+	 for i in $(ETC_SUPPORT); do \
+		ln -s ../../etc/$$i . ; \
+	 done)
+	#
+	# Take out texinfo from configurable dirs
+	rm proto-toplev/configure.ac
+	sed -e '/^host_tools=/s/texinfo //' \
+	    <configure.ac >proto-toplev/configure.ac
+	#
+	mkdir proto-toplev/texinfo
+	ln -s ../../texinfo/texinfo.tex		proto-toplev/texinfo/
+	if test -r texinfo/util/tex3patch ; then \
+	  mkdir proto-toplev/texinfo/util && \
+	  ln -s ../../../texinfo/util/tex3patch	proto-toplev/texinfo/util ; \
+	else true; fi
+	chmod -R og=u . || chmod og=u `find . -print`
+	#
+	# Create .gmo files from .po files.
+	for f in `find . -name '*.po' -type f -print`; do \
+	     msgfmt -o `echo $$f | sed -e 's/\.po$$/.gmo/'` $$f ; \
+	done
+	#
+	-rm -f $(PACKAGE)-$(VER)
+	ln -s proto-toplev $(PACKAGE)-$(VER)
+
+CVS_NAMES= \( -name CVS -o -name '.cvsignore' \)
+
+.PHONY: do-tar
+do-tar:
+	echo "==> Making $(PACKAGE)-$(VER).tar"
+	-rm -f $(PACKAGE)-$(VER).tar
+	find $(PACKAGE)-$(VER) -follow $(CVS_NAMES) -prune \
+			-o -type f -print \
+		| tar cTfh - $(PACKAGE)-$(VER).tar
+
+.PHONY: do-bz2
+do-bz2:
+	echo "==> Bzipping $(PACKAGE)-$(VER).tar.bz2"
+	-rm -f $(PACKAGE)-$(VER).tar.bz2
+	$(BZIPPROG) -v -9 $(PACKAGE)-$(VER).tar
+
+.PHONY: do-md5sum
+do-md5sum:
+	echo "==> Adding md5 checksum to top-level directory"
+	cd proto-toplev && find * -follow $(CVS_NAMES) -prune \
+			-o -type f -print \
+		| xargs $(MD5PROG) > ../md5.new
+	-rm -f proto-toplev/md5.sum
+	mv md5.new proto-toplev/md5.sum
+
+.PHONY: do-djunpack
+do-djunpack:
+	echo "==> Adding updated djunpack.bat to top-level directory"
+	echo - 's /gdb-[0-9\.]*/$(PACKAGE)-'"$(VER)"'/'
+	sed < djunpack.bat > djunpack.new \
+		-e 's/gdb-[0-9][0-9\.]*/$(PACKAGE)-'"$(VER)"'/'
+	-rm -f proto-toplev/djunpack.bat
+	mv djunpack.new proto-toplev/djunpack.bat
+
+TEXINFO_SUPPORT= texinfo/texinfo.tex
+DIST_SUPPORT= $(DEVO_SUPPORT) $(TEXINFO_SUPPORT)
+
+.PHONY: gas.tar.bz2
+GAS_SUPPORT_DIRS= bfd include libiberty opcodes intl setup.com makefile.vms mkdep
+gas.tar.bz2: $(DIST_SUPPORT) $(GAS_SUPPORT_DIRS) gas
+	$(MAKE) -f $(SELF) taz TOOL=gas \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(GAS_SUPPORT_DIRS)"
+
+# The FSF "binutils" release includes gprof and ld.
+.PHONY: binutils.tar.bz2
+BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld elfcpp gold gprof intl setup.com makefile.vms cpu
+binutils.tar.bz2: $(DIST_SUPPORT) $(BINUTILS_SUPPORT_DIRS) binutils
+	$(MAKE) -f $(SELF) taz TOOL=binutils \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(BINUTILS_SUPPORT_DIRS)"
+
+.PHONY: gas+binutils.tar.bz2
+GASB_SUPPORT_DIRS= $(GAS_SUPPORT_DIRS) binutils ld gprof
+gas+binutils.tar.bz2: $(DIST_SUPPORT) $(GASB_SUPPORT_DIRS) gas
+	$(MAKE) -f $(SELF) taz TOOL=gas \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(GASB_SUPPORT_DIRS)"
+
+GNATS_SUPPORT_DIRS=include libiberty send-pr
+gnats.tar.bz2: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats
+	$(MAKE) -f  $(SELF) taz TOOL=gnats \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)"
+
+.PHONY: gdb.tar.bz2
+GDB_SUPPORT_DIRS= bfd include libiberty opcodes readline sim intl libdecnumber
+gdb.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+	$(MAKE) -f $(SELF) gdb-taz TOOL=gdb \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
+.PHONY: gdb.tar
+gdb.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+	$(MAKE) -f $(SELF) gdb-tar TOOL=gdb \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
+
+.PHONY: insight.tar.bz2
+INSIGHT_SUPPORT_DIRS= $(GDB_SUPPORT_DIRS) tcl tk itcl libgui
+insight.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+	$(MAKE) -f $(SELF) gdb-taz TOOL=gdb PACKAGE=insight \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)"
+.PHONY: insight.tar
+insight.tar: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+	$(MAKE) -f $(SELF) gdb-tar TOOL=gdb PACKAGE=insight \
+		MD5PROG="$(MD5PROG)" \
+		SUPPORT_FILES="$(INSIGHT_SUPPORT_DIRS)"
+
+.NOEXPORT:
+MAKEOVERRIDES=
diff --git a/utils/Makefile.am b/utils/Makefile.am
new file mode 100644
index 0000000..b866042
--- /dev/null
+++ b/utils/Makefile.am
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = gtest
diff --git a/utils/README.MCLinker b/utils/README.MCLinker
new file mode 100644
index 0000000..6dc3185
--- /dev/null
+++ b/utils/README.MCLinker
@@ -0,0 +1,15 @@
+//=== ------------------------------------------------------------------ ===//
+//                        MCLinker Project                                  //
+//=== ------------------------------------------------------------------ ===//
+
+  gtest/ contains Google Test 1.6.0. MCLinker removes the original building
+system and integrates gtest in MCLinker's building system.
+
+===========
+Enhancement
+===========
+=======
+Details
+=======
+  see [ticket:37]
+
diff --git a/utils/gtest/CONTRIBUTORS b/utils/gtest/CONTRIBUTORS
new file mode 100644
index 0000000..feae2fc
--- /dev/null
+++ b/utils/gtest/CONTRIBUTORS
@@ -0,0 +1,37 @@
+# This file contains a list of people who've made non-trivial
+# contribution to the Google C++ Testing Framework project.  People
+# who commit code to the project are encouraged to add their names
+# here.  Please keep the list sorted by first names.
+
+Ajay Joshi <jaj@google.com>
+Balázs Dán <balazs.dan@gmail.com>
+Bharat Mediratta <bharat@menalto.com>
+Chandler Carruth <chandlerc@google.com>
+Chris Prince <cprince@google.com>
+Chris Taylor <taylorc@google.com>
+Dan Egnor <egnor@google.com>
+Eric Roman <eroman@chromium.org>
+Hady Zalek <hady.zalek@gmail.com>
+Jeffrey Yasskin <jyasskin@google.com>
+Jói Sigurðsson <joi@google.com>
+Keir Mierle <mierle@gmail.com>
+Keith Ray <keith.ray@gmail.com>
+Kenton Varda <kenton@google.com>
+Manuel Klimek <klimek@google.com>
+Markus Heule <markus.heule@gmail.com>
+Mika Raento <mikie@iki.fi>
+Miklós Fazekas <mfazekas@szemafor.com>
+Pasi Valminen <pasi.valminen@gmail.com>
+Patrick Hanna <phanna@google.com>
+Patrick Riley <pfr@google.com>
+Peter Kaminski <piotrk@google.com>
+Preston Jackson <preston.a.jackson@gmail.com>
+Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
+Russ Cox <rsc@google.com>
+Russ Rufer <russ@pentad.com>
+Sean Mcafee <eefacm@gmail.com>
+Sigurður Ásgeirsson <siggi@google.com>
+Tracy Bialik <tracy@pentad.com>
+Vadim Berman <vadimb@google.com>
+Vlad Losev <vladl@google.com>
+Zhanyong Wan <wan@google.com>
diff --git a/utils/gtest/COPYING b/utils/gtest/COPYING
new file mode 100644
index 0000000..1941a11
--- /dev/null
+++ b/utils/gtest/COPYING
@@ -0,0 +1,28 @@
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/utils/gtest/Makefile.am b/utils/gtest/Makefile.am
new file mode 100644
index 0000000..7c7cdc7
--- /dev/null
+++ b/utils/gtest/Makefile.am
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = obj
diff --git a/utils/gtest/README b/utils/gtest/README
new file mode 100644
index 0000000..51a9376
--- /dev/null
+++ b/utils/gtest/README
@@ -0,0 +1,424 @@
+Google C++ Testing Framework
+============================
+
+http://code.google.com/p/googletest/
+
+Overview
+--------
+
+Google's framework for writing C++ tests on a variety of platforms
+(Linux, Mac OS X, Windows, Windows CE, Symbian, etc).  Based on the
+xUnit architecture.  Supports automatic test discovery, a rich set of
+assertions, user-defined assertions, death tests, fatal and non-fatal
+failures, various options for running the tests, and XML test report
+generation.
+
+Please see the project page above for more information as well as the
+mailing list for questions, discussions, and development.  There is
+also an IRC channel on OFTC (irc.oftc.net) #gtest available.  Please
+join us!
+
+Requirements for End Users
+--------------------------
+
+Google Test is designed to have fairly minimal requirements to build
+and use with your projects, but there are some.  Currently, we support
+Linux, Windows, Mac OS X, and Cygwin.  We will also make our best
+effort to support other platforms (e.g. Solaris, AIX, and z/OS).
+However, since core members of the Google Test project have no access
+to these platforms, Google Test may have outstanding issues there.  If
+you notice any problems on your platform, please notify
+googletestframework@googlegroups.com.  Patches for fixing them are
+even more welcome!
+
+### Linux Requirements ###
+
+These are the base requirements to build and use Google Test from a source
+package (as described below):
+  * GNU-compatible Make or gmake
+  * POSIX-standard shell
+  * POSIX(-2) Regular Expressions (regex.h)
+  * A C++98-standard-compliant compiler
+
+### Windows Requirements ###
+
+  * Microsoft Visual C++ 7.1 or newer
+
+### Cygwin Requirements ###
+
+  * Cygwin 1.5.25-14 or newer
+
+### Mac OS X Requirements ###
+
+  * Mac OS X 10.4 Tiger or newer
+  * Developer Tools Installed
+
+Also, you'll need CMake 2.6.4 or higher if you want to build the
+samples using the provided CMake script, regardless of the platform.
+
+Requirements for Contributors
+-----------------------------
+
+We welcome patches.  If you plan to contribute a patch, you need to
+build Google Test and its own tests from an SVN checkout (described
+below), which has further requirements:
+
+  * Python version 2.3 or newer (for running some of the tests and
+    re-generating certain source files from templates)
+  * CMake 2.6.4 or newer
+
+Getting the Source
+------------------
+
+There are two primary ways of getting Google Test's source code: you
+can download a stable source release in your preferred archive format,
+or directly check out the source from our Subversion (SVN) repositary.
+The SVN checkout requires a few extra steps and some extra software
+packages on your system, but lets you track the latest development and
+make patches much more easily, so we highly encourage it.
+
+### Source Package ###
+
+Google Test is released in versioned source packages which can be
+downloaded from the download page [1].  Several different archive
+formats are provided, but the only difference is the tools used to
+manipulate them, and the size of the resulting file.  Download
+whichever you are most comfortable with.
+
+  [1] http://code.google.com/p/googletest/downloads/list
+
+Once the package is downloaded, expand it using whichever tools you
+prefer for that type.  This will result in a new directory with the
+name "gtest-X.Y.Z" which contains all of the source code.  Here are
+some examples on Linux:
+
+  tar -xvzf gtest-X.Y.Z.tar.gz
+  tar -xvjf gtest-X.Y.Z.tar.bz2
+  unzip gtest-X.Y.Z.zip
+
+### SVN Checkout ###
+
+To check out the main branch (also known as the "trunk") of Google
+Test, run the following Subversion command:
+
+  svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
+
+Setting up the Build
+--------------------
+
+To build Google Test and your tests that use it, you need to tell your
+build system where to find its headers and source files.  The exact
+way to do it depends on which build system you use, and is usually
+straightforward.
+
+### Generic Build Instructions ###
+
+Suppose you put Google Test in directory ${GTEST_DIR}.  To build it,
+create a library build target (or a project as called by Visual Studio
+and Xcode) to compile
+
+  ${GTEST_DIR}/src/gtest-all.cc
+
+with
+
+  ${GTEST_DIR}/include and ${GTEST_DIR}
+
+in the header search path.  Assuming a Linux-like system and gcc,
+something like the following will do:
+
+  g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc
+  ar -rv libgtest.a gtest-all.o
+
+Next, you should compile your test source file with
+${GTEST_DIR}/include in the header search path, and link it with gtest
+and any other necessary libraries:
+
+  g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test
+
+As an example, the make/ directory contains a Makefile that you can
+use to build Google Test on systems where GNU make is available
+(e.g. Linux, Mac OS X, and Cygwin).  It doesn't try to build Google
+Test's own tests.  Instead, it just builds the Google Test library and
+a sample test.  You can use it as a starting point for your own build
+script.
+
+If the default settings are correct for your environment, the
+following commands should succeed:
+
+  cd ${GTEST_DIR}/make
+  make
+  ./sample1_unittest
+
+If you see errors, try to tweak the contents of make/Makefile to make
+them go away.  There are instructions in make/Makefile on how to do
+it.
+
+### Using CMake ###
+
+Google Test comes with a CMake build script (CMakeLists.txt) that can
+be used on a wide range of platforms ("C" stands for cross-platofrm.).
+If you don't have CMake installed already, you can download it for
+free from http://www.cmake.org/.
+
+CMake works by generating native makefiles or build projects that can
+be used in the compiler environment of your choice.  The typical
+workflow starts with:
+
+  mkdir mybuild       # Create a directory to hold the build output.
+  cd mybuild
+  cmake ${GTEST_DIR}  # Generate native build scripts.
+
+If you want to build Google Test's samples, you should replace the
+last command with
+
+  cmake -Dgtest_build_samples=ON ${GTEST_DIR}
+
+If you are on a *nix system, you should now see a Makefile in the
+current directory.  Just type 'make' to build gtest.
+
+If you use Windows and have Vistual Studio installed, a gtest.sln file
+and several .vcproj files will be created.  You can then build them
+using Visual Studio.
+
+On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
+
+### Legacy Build Scripts ###
+
+Before settling on CMake, we have been providing hand-maintained build
+projects/scripts for Visual Studio, Xcode, and Autotools.  While we
+continue to provide them for convenience, they are not actively
+maintained any more.  We highly recommend that you follow the
+instructions in the previous two sections to integrate Google Test
+with your existing build system.
+
+If you still need to use the legacy build scripts, here's how:
+
+The msvc\ folder contains two solutions with Visual C++ projects.
+Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
+are ready to build Google Test the same way you build any Visual
+Studio project.  Files that have names ending with -md use DLL
+versions of Microsoft runtime libraries (the /MD or the /MDd compiler
+option).  Files without that suffix use static versions of the runtime
+libraries (the /MT or the /MTd option).  Please note that one must use
+the same option to compile both gtest and the test code.  If you use
+Visual Studio 2005 or above, we recommend the -md version as /MD is
+the default for new projects in these versions of Visual Studio.
+
+On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
+Xcode.  Build the "gtest" target.  The universal binary framework will
+end up in your selected build directory (selected in the Xcode
+"Preferences..." -> "Building" pane and defaults to xcode/build).
+Alternatively, at the command line, enter:
+
+  xcodebuild
+
+This will build the "Release" configuration of gtest.framework in your
+default build location.  See the "xcodebuild" man page for more
+information about building different configurations and building in
+different locations.
+
+Tweaking Google Test
+--------------------
+
+Google Test can be used in diverse environments.  The default
+configuration may not work (or may not work well) out of the box in
+some environments.  However, you can easily tweak Google Test by
+defining control macros on the compiler command line.  Generally,
+these macros are named like GTEST_XYZ and you define them to either 1
+or 0 to enable or disable a certain feature.
+
+We list the most frequently used macros below.  For a complete list,
+see file include/gtest/internal/gtest-port.h.
+
+### Choosing a TR1 Tuple Library ###
+
+Some Google Test features require the C++ Technical Report 1 (TR1)
+tuple library, which is not yet available with all compilers.  The
+good news is that Google Test implements a subset of TR1 tuple that's
+enough for its own need, and will automatically use this when the
+compiler doesn't provide TR1 tuple.
+
+Usually you don't need to care about which tuple library Google Test
+uses.  However, if your project already uses TR1 tuple, you need to
+tell Google Test to use the same TR1 tuple library the rest of your
+project uses, or the two tuple implementations will clash.  To do
+that, add
+
+  -DGTEST_USE_OWN_TR1_TUPLE=0
+
+to the compiler flags while compiling Google Test and your tests.  If
+you want to force Google Test to use its own tuple library, just add
+
+  -DGTEST_USE_OWN_TR1_TUPLE=1
+
+to the compiler flags instead.
+
+If you don't want Google Test to use tuple at all, add
+
+  -DGTEST_HAS_TR1_TUPLE=0
+
+and all features using tuple will be disabled.
+
+### Multi-threaded Tests ###
+
+Google Test is thread-safe where the pthread library is available.
+After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE
+macro to see whether this is the case (yes if the macro is #defined to
+1, no if it's undefined.).
+
+If Google Test doesn't correctly detect whether pthread is available
+in your environment, you can force it with
+
+  -DGTEST_HAS_PTHREAD=1
+
+or
+
+  -DGTEST_HAS_PTHREAD=0
+
+When Google Test uses pthread, you may need to add flags to your
+compiler and/or linker to select the pthread library, or you'll get
+link errors.  If you use the CMake script or the deprecated Autotools
+script, this is taken care of for you.  If you use your own build
+script, you'll need to read your compiler and linker's manual to
+figure out what flags to add.
+
+### As a Shared Library (DLL) ###
+
+Google Test is compact, so most users can build and link it as a
+static library for the simplicity.  You can choose to use Google Test
+as a shared library (known as a DLL on Windows) if you prefer.
+
+To compile *gtest* as a shared library, add
+
+  -DGTEST_CREATE_SHARED_LIBRARY=1
+
+to the compiler flags.  You'll also need to tell the linker to produce
+a shared library instead - consult your linker's manual for how to do
+it.
+
+To compile your *tests* that use the gtest shared library, add
+
+  -DGTEST_LINKED_AS_SHARED_LIBRARY=1
+
+to the compiler flags.
+
+Note: while the above steps aren't technically necessary today when
+using some compilers (e.g. GCC), they may become necessary in the
+future, if we decide to improve the speed of loading the library (see
+http://gcc.gnu.org/wiki/Visibility for details).  Therefore you are
+recommended to always add the above flags when using Google Test as a
+shared library.  Otherwise a future release of Google Test may break
+your build script.
+
+### Avoiding Macro Name Clashes ###
+
+In C++, macros don't obey namespaces.  Therefore two libraries that
+both define a macro of the same name will clash if you #include both
+definitions.  In case a Google Test macro clashes with another
+library, you can force Google Test to rename its macro to avoid the
+conflict.
+
+Specifically, if both Google Test and some other code define macro
+FOO, you can add
+
+  -DGTEST_DONT_DEFINE_FOO=1
+
+to the compiler flags to tell Google Test to change the macro's name
+from FOO to GTEST_FOO.  Currently FOO can be FAIL, SUCCEED, or TEST.
+For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
+
+  GTEST_TEST(SomeTest, DoesThis) { ... }
+
+instead of
+
+  TEST(SomeTest, DoesThis) { ... }
+
+in order to define a test.
+
+Upgrating from an Earlier Version
+---------------------------------
+
+We strive to keep Google Test releases backward compatible.
+Sometimes, though, we have to make some breaking changes for the
+users' long-term benefits.  This section describes what you'll need to
+do if you are upgrading from an earlier version of Google Test.
+
+### Upgrading from 1.3.0 or Earlier ###
+
+You may need to explicitly enable or disable Google Test's own TR1
+tuple library.  See the instructions in section "Choosing a TR1 Tuple
+Library".
+
+### Upgrading from 1.4.0 or Earlier ###
+
+The Autotools build script (configure + make) is no longer officially
+supportted.  You are encouraged to migrate to your own build system or
+use CMake.  If you still need to use Autotools, you can find
+instructions in the README file from Google Test 1.4.0.
+
+On platforms where the pthread library is available, Google Test uses
+it in order to be thread-safe.  See the "Multi-threaded Tests" section
+for what this means to your build script.
+
+If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
+Test will no longer compile.  This should affect very few people, as a
+large portion of STL (including <string>) doesn't compile in this mode
+anyway.  We decided to stop supporting it in order to greatly simplify
+Google Test's implementation.
+
+Developing Google Test
+----------------------
+
+This section discusses how to make your own changes to Google Test.
+
+### Testing Google Test Itself ###
+
+To make sure your changes work as intended and don't break existing
+functionality, you'll want to compile and run Google Test's own tests.
+For that you can use CMake:
+
+  mkdir mybuild
+  cd mybuild
+  cmake -Dgtest_build_tests=ON ${GTEST_DIR}
+
+Make sure you have Python installed, as some of Google Test's tests
+are written in Python.  If the cmake command complains about not being
+able to find Python ("Could NOT find PythonInterp (missing:
+PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
+executable can be found:
+
+  cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
+
+Next, you can build Google Test and all of its own tests.  On *nix,
+this is usually done by 'make'.  To run the tests, do
+
+  make test
+
+All tests should pass.
+
+### Regenerating Source Files ###
+
+Some of Google Test's source files are generated from templates (not
+in the C++ sense) using a script.  A template file is named FOO.pump,
+where FOO is the name of the file it will generate.  For example, the
+file include/gtest/internal/gtest-type-util.h.pump is used to generate
+gtest-type-util.h in the same directory.
+
+Normally you don't need to worry about regenerating the source files,
+unless you need to modify them.  In that case, you should modify the
+corresponding .pump files instead and run the pump.py Python script to
+regenerate them.  You can find pump.py in the scripts/ directory.
+Read the Pump manual [2] for how to use it.
+
+  [2] http://code.google.com/p/googletest/wiki/PumpManual
+
+### Contributing a Patch ###
+
+We welcome patches.  Please read the Google Test developer's guide [3]
+for how you can contribute.  In particular, make sure you have signed
+the Contributor License Agreement, or we won't be able to accept the
+patch.
+
+  [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
+
+Happy testing!
diff --git a/utils/gtest/include/gtest.h b/utils/gtest/include/gtest.h
new file mode 100644
index 0000000..3143bd6
--- /dev/null
+++ b/utils/gtest/include/gtest.h
@@ -0,0 +1,19537 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for Google Test.  It should be
+// included by any test program that uses Google Test.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+//
+// Acknowledgment: Google Test borrowed the idea of automatic test
+// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
+// easyUnit framework.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_H_
+
+#include <limits>
+#include <vector>
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares functions and macros used internally by
+// Google Test.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan)
+//
+// Low-level types and utilities for porting Google Test to various
+// platforms.  They are subject to change without notice.  DO NOT USE
+// THEM IN USER CODE.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior.  If the user doesn't define a macro
+// in this list, Google Test will define it.
+//
+//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)
+//                              is/isn't available.
+//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions
+//                              are enabled.
+//   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::string, which is different to std::string).
+//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::wstring, which is different to std::wstring).
+//   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular
+//                              expressions are/aren't available.
+//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>
+//                              is/isn't available.
+//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't
+//                              enabled.
+//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
+//                              std::wstring does/doesn't work (Google Test can
+//                              be used where std::wstring is unavailable).
+//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple
+//                              is/isn't available.
+//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the
+//                              compiler supports Microsoft's "Structured
+//                              Exception Handling".
+//   GTEST_HAS_STREAM_REDIRECTION
+//                            - Define it to 1/0 to indicate whether the
+//                              platform supports I/O stream redirection using
+//                              dup() and dup2().
+//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google
+//                              Test's own tr1 tuple implementation should be
+//                              used.  Unused when the user sets
+//                              GTEST_HAS_TR1_TUPLE to 0.
+//   GTEST_LINKED_AS_SHARED_LIBRARY
+//                            - Define to 1 when compiling tests that use
+//                              Google Test as a shared library (known as
+//                              DLL on Windows).
+//   GTEST_CREATE_SHARED_LIBRARY
+//                            - Define to 1 when compiling Google Test itself
+//                              as a shared library.
+
+// This header defines the following utilities:
+//
+// Macros indicating the current platform (defined to 1 if compiled on
+// the given platform; otherwise undefined):
+//   GTEST_OS_AIX      - IBM AIX
+//   GTEST_OS_CYGWIN   - Cygwin
+//   GTEST_OS_HPUX     - HP-UX
+//   GTEST_OS_LINUX    - Linux
+//     GTEST_OS_LINUX_ANDROID - Google Android
+//   GTEST_OS_MAC      - Mac OS X
+//   GTEST_OS_NACL     - Google Native Client (NaCl)
+//   GTEST_OS_SOLARIS  - Sun Solaris
+//   GTEST_OS_SYMBIAN  - Symbian
+//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)
+//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop
+//     GTEST_OS_WINDOWS_MINGW    - MinGW
+//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile
+//   GTEST_OS_ZOS      - z/OS
+//
+// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// most stable support.  Since core members of the Google Test project
+// don't have access to other platforms, support for them may be less
+// stable.  If you notice any problems on your platform, please notify
+// googletestframework@googlegroups.com (patches for fixing them are
+// even more welcome!).
+//
+// Note that it is possible that none of the GTEST_OS_* macros are defined.
+//
+// Macros indicating available Google Test features (defined to 1 if
+// the corresponding feature is supported; otherwise undefined):
+//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized
+//                            tests)
+//   GTEST_HAS_DEATH_TEST   - death tests
+//   GTEST_HAS_PARAM_TEST   - value-parameterized tests
+//   GTEST_HAS_TYPED_TEST   - typed tests
+//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests
+//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with
+//                            GTEST_HAS_POSIX_RE (see above) which users can
+//                            define themselves.
+//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;
+//                            the above two are mutually exclusive.
+//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//
+// Macros for basic C++ coding:
+//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
+//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a
+//                              variable don't have to be used.
+//   GTEST_DISALLOW_ASSIGN_   - disables operator=.
+//   GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
+//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.
+//
+// Synchronization:
+//   Mutex, MutexLock, ThreadLocal, GetThreadCount()
+//                  - synchronization primitives.
+//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
+//                         synchronization primitives have real implementations
+//                         and Google Test is thread-safe; or 0 otherwise.
+//
+// Template meta programming:
+//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only.
+//   IteratorTraits - partial implementation of std::iterator_traits, which
+//                    is not available in libCstd when compiled with Sun C++.
+//
+// Smart pointers:
+//   scoped_ptr     - as in TR2.
+//
+// Regular expressions:
+//   RE             - a simple regular expression class using the POSIX
+//                    Extended Regular Expression syntax on UNIX-like
+//                    platforms, or a reduced regular exception syntax on
+//                    other platforms, including Windows.
+//
+// Logging:
+//   GTEST_LOG_()   - logs messages at the specified severity level.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+//
+// Stdout and stderr capturing:
+//   CaptureStdout()     - starts capturing stdout.
+//   GetCapturedStdout() - stops capturing stdout and returns the captured
+//                         string.
+//   CaptureStderr()     - starts capturing stderr.
+//   GetCapturedStderr() - stops capturing stderr and returns the captured
+//                         string.
+//
+// Integer types:
+//   TypeWithSize   - maps an integer to a int type.
+//   Int32, UInt32, Int64, UInt64, TimeInMillis
+//                  - integers of known sizes.
+//   BiggestInt     - the biggest signed integer type.
+//
+// Command-line utilities:
+//   GTEST_FLAG()       - references a flag.
+//   GTEST_DECLARE_*()  - declares a flag.
+//   GTEST_DEFINE_*()   - defines a flag.
+//   GetArgvs()         - returns the command line as a vector of strings.
+//
+// Environment variable utilities:
+//   GetEnv()             - gets the value of an environment variable.
+//   BoolFromGTestEnv()   - parses a bool environment variable.
+//   Int32FromGTestEnv()  - parses an Int32 environment variable.
+//   StringFromGTestEnv() - parses a string environment variable.
+
+#include <ctype.h>   // for isspace, etc
+#include <stddef.h>  // for ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32_WCE
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif  // !_WIN32_WCE
+
+#include <iostream>  // NOLINT
+#include <sstream>  // NOLINT
+#include <string>  // NOLINT
+
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
+#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
+
+// Determines the version of gcc that is used to compile this.
+#ifdef __GNUC__
+// 40302 means version 4.3.2.
+# define GTEST_GCC_VER_ \
+    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
+#endif  // __GNUC__
+
+// Determines the platform on which Google Test is compiled.
+#ifdef __CYGWIN__
+# define GTEST_OS_CYGWIN 1
+#elif defined __SYMBIAN32__
+# define GTEST_OS_SYMBIAN 1
+#elif defined _WIN32
+# define GTEST_OS_WINDOWS 1
+# ifdef _WIN32_WCE
+#  define GTEST_OS_WINDOWS_MOBILE 1
+# elif defined(__MINGW__) || defined(__MINGW32__)
+#  define GTEST_OS_WINDOWS_MINGW 1
+# else
+#  define GTEST_OS_WINDOWS_DESKTOP 1
+# endif  // _WIN32_WCE
+#elif defined __APPLE__
+# define GTEST_OS_MAC 1
+#elif defined __linux__
+# define GTEST_OS_LINUX 1
+# ifdef ANDROID
+#  define GTEST_OS_LINUX_ANDROID 1
+# endif  // ANDROID
+#elif defined __MVS__
+# define GTEST_OS_ZOS 1
+#elif defined(__sun) && defined(__SVR4)
+# define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+# define GTEST_OS_AIX 1
+#elif defined(__hpux)
+# define GTEST_OS_HPUX 1
+#elif defined __native_client__
+# define GTEST_OS_NACL 1
+#endif  // __CYGWIN__
+
+// Brings in definitions for functions used in the testing::internal::posix
+// namespace (read, write, close, chdir, isatty, stat). We do not currently
+// use them on Windows Mobile.
+#if !GTEST_OS_WINDOWS
+// This assumes that non-Windows OSes provide unistd.h. For OSes where this
+// is not the case, we need to include headers that provide the functions
+// mentioned above.
+# include <unistd.h>
+# if !GTEST_OS_NACL
+// TODO(vladl@google.com): Remove this condition when Native Client SDK adds
+// strings.h (tracked in
+// http://code.google.com/p/nativeclient/issues/detail?id=1175).
+#  include <strings.h>  // Native Client doesn't provide strings.h.
+# endif
+#elif !GTEST_OS_WINDOWS_MOBILE
+# include <direct.h>
+# include <io.h>
+#endif
+
+// Defines this to true iff Google Test can use POSIX regular expressions.
+#ifndef GTEST_HAS_POSIX_RE
+# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS)
+#endif
+
+#if GTEST_HAS_POSIX_RE
+
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile otherwise.  We can #include it here as we already
+// included <stdlib.h>, which is guaranteed to define size_t through
+// <stddef.h>.
+# include <regex.h>  // NOLINT
+
+# define GTEST_USES_POSIX_RE 1
+
+#elif GTEST_OS_WINDOWS
+
+// <regex.h> is not available on Windows.  Use our own simple regex
+// implementation instead.
+# define GTEST_USES_SIMPLE_RE 1
+
+#else
+
+// <regex.h> may not be available on this platform.  Use our own
+// simple regex implementation instead.
+# define GTEST_USES_SIMPLE_RE 1
+
+#endif  // GTEST_HAS_POSIX_RE
+
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+// macro to enable exceptions, so we'll do the same.
+// Assumes that exceptions are enabled by default.
+#  ifndef _HAS_EXCEPTIONS
+#   define _HAS_EXCEPTIONS 1
+#  endif  // _HAS_EXCEPTIONS
+#  define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+# elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#  define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions.  However, there is no compile-time way of
+// detecting whether they are enabled or not.  Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#  define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#  define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__HP_aCC)
+// Exception handling is in effect by default in HP aCC compiler. It has to
+// be turned of by +noeh compiler option if desired.
+#  define GTEST_HAS_EXCEPTIONS 1
+# else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
+#  define GTEST_HAS_EXCEPTIONS 0
+# endif  // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif  // GTEST_HAS_EXCEPTIONS
+
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
+# define GTEST_HAS_STD_STRING 1
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+# error "Google Test cannot be used where ::std::string isn't available."
+#endif  // !defined(GTEST_HAS_STD_STRING)
+
+#ifndef GTEST_HAS_GLOBAL_STRING
+// The user didn't tell us whether ::string is available, so we need
+// to figure it out.
+
+# define GTEST_HAS_GLOBAL_STRING 0
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#ifndef GTEST_HAS_STD_WSTRING
+// The user didn't tell us whether ::std::wstring is available, so we need
+// to figure it out.
+// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
+//   is available.
+
+// Cygwin 1.7 and below doesn't support ::std::wstring.
+// Solaris' libc++ doesn't support it either.  Android has
+// no support for it at least as recent as Froyo (2.2).
+# define GTEST_HAS_STD_WSTRING \
+    (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+#ifndef GTEST_HAS_GLOBAL_WSTRING
+// The user didn't tell us whether ::wstring is available, so we need
+// to figure it out.
+# define GTEST_HAS_GLOBAL_WSTRING \
+    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Determines whether RTTI is available.
+#ifndef GTEST_HAS_RTTI
+// The user didn't tell us whether RTTI is enabled, so we need to
+// figure it out.
+
+# ifdef _MSC_VER
+
+#  ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.
+#   define GTEST_HAS_RTTI 1
+#  else
+#   define GTEST_HAS_RTTI 0
+#  endif
+
+// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
+# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
+#  ifdef __GXX_RTTI
+#   define GTEST_HAS_RTTI 1
+#  else
+#   define GTEST_HAS_RTTI 0
+#  endif  // __GXX_RTTI
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#  ifdef __RTTI_ALL__
+#   define GTEST_HAS_RTTI 1
+#  else
+#   define GTEST_HAS_RTTI 0
+#  endif
+
+# else
+
+// For all other compilers, we assume RTTI is enabled.
+#  define GTEST_HAS_RTTI 1
+
+# endif  // _MSC_VER
+
+#endif  // GTEST_HAS_RTTI
+
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+# include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
+#ifndef GTEST_HAS_PTHREAD
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
+# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX)
+#endif  // GTEST_HAS_PTHREAD
+
+#if GTEST_HAS_PTHREAD
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+# include <pthread.h>  // NOLINT
+
+// For timespec and nanosleep, used below.
+# include <time.h>  // NOLINT
+#endif
+
+// Determines whether Google Test can use tr1/tuple.  You can define
+// this macro to 0 to prevent Google Test from using tuple (any
+// feature depending on tuple with be disabled in this mode).
+#ifndef GTEST_HAS_TR1_TUPLE
+// The user didn't tell us not to do it, so we assume it's OK.
+# define GTEST_HAS_TR1_TUPLE 1
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether Google Test's own tr1 tuple implementation
+// should be used.
+#ifndef GTEST_USE_OWN_TR1_TUPLE
+// The user didn't tell us, so we need to figure it out.
+
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already.  At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation.  NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation.  MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+    || _MSC_VER >= 1600
+#  define GTEST_USE_OWN_TR1_TUPLE 0
+# else
+#  define GTEST_USE_OWN_TR1_TUPLE 1
+# endif
+
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+// To avoid conditional compilation everywhere, we make it
+// gtest-port.h's responsibility to #include the header implementing
+// tr1/tuple.
+#if GTEST_HAS_TR1_TUPLE
+
+# if GTEST_USE_OWN_TR1_TUPLE
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2009 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility>  // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined).  This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+    void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+    void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+    void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+    void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, void, void>
+#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, void>
+#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, T##9>
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+#define GTEST_0_TYPENAMES_(T)
+#define GTEST_1_TYPENAMES_(T) typename T##0
+#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
+#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
+#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3
+#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4
+#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5
+#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6
+#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
+#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8
+#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8, typename T##9
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior.  We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+    typename T3 = void, typename T4 = void, typename T5 = void,
+    typename T6 = void, typename T7 = void, typename T8 = void,
+    typename T9 = void>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; };  // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>.  kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
+
+}  // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+  tuple() {}
+  tuple(const tuple& /* t */)  {}
+  tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+template <GTEST_1_TYPENAMES_(T)>
+class GTEST_1_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
+
+  tuple(const tuple& t) : f0_(t.f0_) {}
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    return *this;
+  }
+
+  T0 f0_;
+};
+
+template <GTEST_2_TYPENAMES_(T)>
+class GTEST_2_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
+      f1_(f1) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
+  template <typename U0, typename U1>
+  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+  template <typename U0, typename U1>
+  tuple& operator=(const ::std::pair<U0, U1>& p) {
+    f0_ = p.first;
+    f1_ = p.second;
+    return *this;
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+};
+
+template <GTEST_3_TYPENAMES_(T)>
+class GTEST_3_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+};
+
+template <GTEST_4_TYPENAMES_(T)>
+class GTEST_4_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+};
+
+template <GTEST_5_TYPENAMES_(T)>
+class GTEST_5_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
+      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_) {}
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+};
+
+template <GTEST_6_TYPENAMES_(T)>
+class GTEST_6_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_) {}
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+};
+
+template <GTEST_7_TYPENAMES_(T)>
+class GTEST_7_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+};
+
+template <GTEST_8_TYPENAMES_(T)>
+class GTEST_8_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
+      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+};
+
+template <GTEST_9_TYPENAMES_(T)>
+class GTEST_9_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+};
+
+template <GTEST_10_TYPENAMES_(T)>
+class tuple {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+      f9_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
+      f9_(t.f9_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    f9_ = t.f9_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+  T9 f9_;
+};
+
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+template <GTEST_1_TYPENAMES_(T)>
+inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
+  return GTEST_1_TUPLE_(T)(f0);
+}
+
+template <GTEST_2_TYPENAMES_(T)>
+inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
+  return GTEST_2_TUPLE_(T)(f0, f1);
+}
+
+template <GTEST_3_TYPENAMES_(T)>
+inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
+  return GTEST_3_TUPLE_(T)(f0, f1, f2);
+}
+
+template <GTEST_4_TYPENAMES_(T)>
+inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3) {
+  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
+}
+
+template <GTEST_5_TYPENAMES_(T)>
+inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4) {
+  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
+}
+
+template <GTEST_6_TYPENAMES_(T)>
+inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5) {
+  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
+}
+
+template <GTEST_7_TYPENAMES_(T)>
+inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
+  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
+}
+
+template <GTEST_8_TYPENAMES_(T)>
+inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
+  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
+}
+
+template <GTEST_9_TYPENAMES_(T)>
+inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8) {
+  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
+}
+
+template <GTEST_10_TYPENAMES_(T)>
+inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8, const T9& f9) {
+  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
+}
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+template <GTEST_0_TYPENAMES_(T)>
+struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
+
+template <GTEST_1_TYPENAMES_(T)>
+struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
+
+template <GTEST_2_TYPENAMES_(T)>
+struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
+
+template <GTEST_3_TYPENAMES_(T)>
+struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
+
+template <GTEST_4_TYPENAMES_(T)>
+struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
+
+template <GTEST_5_TYPENAMES_(T)>
+struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
+
+template <GTEST_6_TYPENAMES_(T)>
+struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
+
+template <GTEST_7_TYPENAMES_(T)>
+struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
+
+template <GTEST_8_TYPENAMES_(T)>
+struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
+
+template <GTEST_9_TYPENAMES_(T)>
+struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
+
+template <int k, class Tuple>
+struct tuple_element {
+  typedef typename gtest_internal::TupleElement<
+      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+template <>
+class Get<0> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  Field(Tuple& t) { return t.f0_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  ConstField(const Tuple& t) { return t.f0_; }
+};
+
+template <>
+class Get<1> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  Field(Tuple& t) { return t.f1_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  ConstField(const Tuple& t) { return t.f1_; }
+};
+
+template <>
+class Get<2> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  Field(Tuple& t) { return t.f2_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  ConstField(const Tuple& t) { return t.f2_; }
+};
+
+template <>
+class Get<3> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  Field(Tuple& t) { return t.f3_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  ConstField(const Tuple& t) { return t.f3_; }
+};
+
+template <>
+class Get<4> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  Field(Tuple& t) { return t.f4_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  ConstField(const Tuple& t) { return t.f4_; }
+};
+
+template <>
+class Get<5> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  Field(Tuple& t) { return t.f5_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  ConstField(const Tuple& t) { return t.f5_; }
+};
+
+template <>
+class Get<6> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  Field(Tuple& t) { return t.f6_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  ConstField(const Tuple& t) { return t.f6_; }
+};
+
+template <>
+class Get<7> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  Field(Tuple& t) { return t.f7_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  ConstField(const Tuple& t) { return t.f7_; }
+};
+
+template <>
+class Get<8> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  Field(Tuple& t) { return t.f8_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  ConstField(const Tuple& t) { return t.f8_; }
+};
+
+template <>
+class Get<9> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  Field(Tuple& t) { return t.f9_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  ConstField(const Tuple& t) { return t.f9_; }
+};
+
+}  // namespace gtest_internal
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
+get(const GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+    return true;
+  }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+  }
+};
+
+}  // namespace gtest_internal
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator==(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) {
+  return gtest_internal::SameSizeTuplePrefixComparator<
+      tuple_size<GTEST_10_TUPLE_(T)>::value,
+      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+}  // namespace tr1
+}  // namespace std
+
+#undef GTEST_0_TUPLE_
+#undef GTEST_1_TUPLE_
+#undef GTEST_2_TUPLE_
+#undef GTEST_3_TUPLE_
+#undef GTEST_4_TUPLE_
+#undef GTEST_5_TUPLE_
+#undef GTEST_6_TUPLE_
+#undef GTEST_7_TUPLE_
+#undef GTEST_8_TUPLE_
+#undef GTEST_9_TUPLE_
+#undef GTEST_10_TUPLE_
+
+#undef GTEST_0_TYPENAMES_
+#undef GTEST_1_TYPENAMES_
+#undef GTEST_2_TYPENAMES_
+#undef GTEST_3_TYPENAMES_
+#undef GTEST_4_TYPENAMES_
+#undef GTEST_5_TYPENAMES_
+#undef GTEST_6_TYPENAMES_
+#undef GTEST_7_TYPENAMES_
+#undef GTEST_8_TYPENAMES_
+#undef GTEST_9_TYPENAMES_
+#undef GTEST_10_TYPENAMES_
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+# elif GTEST_OS_SYMBIAN
+
+// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
+// use STLport's tuple implementation, which unfortunately doesn't
+// work as the copy of STLport distributed with Symbian is incomplete.
+// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
+// use its own tuple implementation.
+#  ifdef BOOST_HAS_TR1_TUPLE
+#   undef BOOST_HAS_TR1_TUPLE
+#  endif  // BOOST_HAS_TR1_TUPLE
+
+// This prevents <boost/tr1/detail/config.hpp>, which defines
+// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
+#  define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
+#  include <tuple>
+
+# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does
+// not conform to the TR1 spec, which requires the header to be <tuple>.
+
+#  if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
+// which is #included by <tr1/tuple>, to not compile when RTTI is
+// disabled.  _TR1_FUNCTIONAL is the header guard for
+// <tr1/functional>.  Hence the following #define is a hack to prevent
+// <tr1/functional> from being included.
+#   define _TR1_FUNCTIONAL 1
+#   include <tr1/tuple>
+#   undef _TR1_FUNCTIONAL  // Allows the user to #include
+                        // <tr1/functional> if he chooses to.
+#  else
+#   include <tr1/tuple>  // NOLINT
+#  endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+
+# else
+// If the compiler is not GCC 4.0+, we assume the user is using a
+// spec-conforming TR1 implementation.
+#  include <tuple>  // NOLINT
+# endif  // GTEST_USE_OWN_TR1_TUPLE
+
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether clone(2) is supported.
+// Usually it will only be available on Linux, excluding
+// Linux on the Itanium architecture.
+// Also see http://linux.die.net/man/2/clone.
+#ifndef GTEST_HAS_CLONE
+// The user didn't tell us, so we need to figure it out.
+
+# if GTEST_OS_LINUX && !defined(__ia64__)
+#  define GTEST_HAS_CLONE 1
+# else
+#  define GTEST_HAS_CLONE 0
+# endif  // GTEST_OS_LINUX && !defined(__ia64__)
+
+#endif  // GTEST_HAS_CLONE
+
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#ifndef GTEST_HAS_STREAM_REDIRECTION
+// By default, we assume that stream redirection is supported on all
+// platforms except known mobile ones.
+# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN
+#  define GTEST_HAS_STREAM_REDIRECTION 0
+# else
+#  define GTEST_HAS_STREAM_REDIRECTION 1
+# endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#endif  // GTEST_HAS_STREAM_REDIRECTION
+
+// Determines whether to support death tests.
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX)
+# define GTEST_HAS_DEATH_TEST 1
+# include <vector>  // NOLINT
+#endif
+
+// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
+#define GTEST_HAS_PARAM_TEST 1
+
+// Determines whether to support type-driven tests.
+
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, IBM Visual Age, and HP aCC support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+    defined(__IBMCPP__) || defined(__HP_aCC)
+# define GTEST_HAS_TYPED_TEST 1
+# define GTEST_HAS_TYPED_TEST_P 1
+#endif
+
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled.  The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
+# define GTEST_HAS_COMBINE 1
+#endif
+
+// Determines whether the system compiler uses UTF-16 for encoding wide strings.
+#define GTEST_WIDE_STRING_USES_UTF16_ \
+    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+
+// Determines whether test results can be streamed to a socket.
+#if GTEST_OS_LINUX
+# define GTEST_CAN_STREAM_RESULTS_ 1
+#endif
+
+// Defines some utility macros.
+
+// The GNU compiler emits a warning if nested "if" statements are followed by
+// an "else" statement and braces are not used to explicitly disambiguate the
+// "else" binding.  This leads to problems with code like:
+//
+//   if (gate)
+//     ASSERT_*(condition) << "Some message";
+//
+// The "switch (0) case 0:" idiom is used to suppress this.
+#ifdef __INTEL_COMPILER
+# define GTEST_AMBIGUOUS_ELSE_BLOCKER_
+#else
+# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:  // NOLINT
+#endif
+
+// Use this annotation at the end of a struct/class definition to
+// prevent the compiler from optimizing away instances that are never
+// used.  This is useful when all interesting logic happens inside the
+// c'tor and / or d'tor.  Example:
+//
+//   struct Foo {
+//     Foo() { ... }
+//   } GTEST_ATTRIBUTE_UNUSED_;
+//
+// Also use it after a variable or parameter declaration to tell the
+// compiler the variable/parameter does not have to be used.
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
+# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
+#else
+# define GTEST_ATTRIBUTE_UNUSED_
+#endif
+
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+  void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
+  type(type const &);\
+  GTEST_DISALLOW_ASSIGN_(type)
+
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro.  The macro should be used on function declarations
+// following the argument list:
+//
+//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
+#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
+#else
+# define GTEST_MUST_USE_RESULT_
+#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+
+// Determine whether the compiler supports Microsoft's Structured Exception
+// Handling.  This is supported by several Windows compilers but generally
+// does not exist on any other system.
+#ifndef GTEST_HAS_SEH
+// The user didn't tell us, so we need to figure it out.
+
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+// These two compilers are known to support SEH.
+#  define GTEST_HAS_SEH 1
+# else
+// Assume no SEH.
+#  define GTEST_HAS_SEH 0
+# endif
+
+#endif  // GTEST_HAS_SEH
+
+#ifdef _MSC_VER
+
+# if GTEST_LINKED_AS_SHARED_LIBRARY
+#  define GTEST_API_ __declspec(dllimport)
+# elif GTEST_CREATE_SHARED_LIBRARY
+#  define GTEST_API_ __declspec(dllexport)
+# endif
+
+#endif  // _MSC_VER
+
+#ifndef GTEST_API_
+# define GTEST_API_
+#endif
+
+#ifdef __GNUC__
+// Ask the compiler to never inline a given function.
+# define GTEST_NO_INLINE_ __attribute__((noinline))
+#else
+# define GTEST_NO_INLINE_
+#endif
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+//   GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
+//                         content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+//   GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+
+template <bool>
+struct CompileAssert {
+};
+
+#define GTEST_COMPILE_ASSERT_(expr, msg) \
+  typedef ::testing::internal::CompileAssert<(bool(expr))> \
+      msg[bool(expr) ? 1 : -1]
+
+// Implementation details of GTEST_COMPILE_ASSERT_:
+//
+// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1
+//   elements (and thus is invalid) when the expression is false.
+//
+// - The simpler definition
+//
+//    #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
+//
+//   does not work, as gcc supports variable-length arrays whose sizes
+//   are determined at run-time (this is gcc's extension and not part
+//   of the C++ standard).  As a result, gcc fails to reject the
+//   following code with the simple definition:
+//
+//     int foo;
+//     GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
+//                                      // not a compile-time constant.
+//
+// - By using the type CompileAssert<(bool(expr))>, we ensures that
+//   expr is a compile-time constant.  (Template arguments must be
+//   determined at compile-time.)
+//
+// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
+//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
+//
+//     CompileAssert<bool(expr)>
+//
+//   instead, these compilers will refuse to compile
+//
+//     GTEST_COMPILE_ASSERT_(5 > 0, some_message);
+//
+//   (They seem to think the ">" in "5 > 0" marks the end of the
+//   template argument list.)
+//
+// - The array size is (bool(expr) ? 1 : -1), instead of simply
+//
+//     ((expr) ? 1 : -1).
+//
+//   This is to avoid running into a bug in MS VC 7.1, which
+//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+
+// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.
+//
+// This template is declared, but intentionally undefined.
+template <typename T1, typename T2>
+struct StaticAssertTypeEqHelper;
+
+template <typename T>
+struct StaticAssertTypeEqHelper<T, T> {};
+
+#if GTEST_HAS_GLOBAL_STRING
+typedef ::string string;
+#else
+typedef ::std::string string;
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+typedef ::wstring wstring;
+#elif GTEST_HAS_STD_WSTRING
+typedef ::std::wstring wstring;
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// A helper for suppressing warnings on constant condition.  It just
+// returns 'condition'.
+GTEST_API_ bool IsTrue(bool condition);
+
+// Defines scoped_ptr.
+
+// This implementation of scoped_ptr is PARTIAL - it only contains
+// enough stuff to satisfy Google Test's need.
+template <typename T>
+class scoped_ptr {
+ public:
+  typedef T element_type;
+
+  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
+  ~scoped_ptr() { reset(); }
+
+  T& operator*() const { return *ptr_; }
+  T* operator->() const { return ptr_; }
+  T* get() const { return ptr_; }
+
+  T* release() {
+    T* const ptr = ptr_;
+    ptr_ = NULL;
+    return ptr;
+  }
+
+  void reset(T* p = NULL) {
+    if (p != ptr_) {
+      if (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.
+        delete ptr_;
+      }
+      ptr_ = p;
+    }
+  }
+ private:
+  T* ptr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
+};
+
+// Defines RE.
+
+// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended
+// Regular Expression syntax.
+class GTEST_API_ RE {
+ public:
+  // A copy constructor is required by the Standard to initialize object
+  // references from r-values.
+  RE(const RE& other) { Init(other.pattern()); }
+
+  // Constructs an RE from a string.
+  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+
+  RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  RE(const char* regex) { Init(regex); }  // NOLINT
+  ~RE();
+
+  // Returns the string representation of the regex.
+  const char* pattern() const { return pattern_; }
+
+  // FullMatch(str, re) returns true iff regular expression re matches
+  // the entire str.
+  // PartialMatch(str, re) returns true iff regular expression re
+  // matches a substring of str (including str itself).
+  //
+  // TODO(wan@google.com): make FullMatch() and PartialMatch() work
+  // when str contains NUL characters.
+  static bool FullMatch(const ::std::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::std::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+
+#if GTEST_HAS_GLOBAL_STRING
+
+  static bool FullMatch(const ::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  static bool FullMatch(const char* str, const RE& re);
+  static bool PartialMatch(const char* str, const RE& re);
+
+ private:
+  void Init(const char* regex);
+
+  // We use a const char* instead of a string, as Google Test may be used
+  // where string is not available.  We also do not use Google Test's own
+  // String type here, in order to simplify dependencies between the
+  // files.
+  const char* pattern_;
+  bool is_valid_;
+
+#if GTEST_USES_POSIX_RE
+
+  regex_t full_regex_;     // For FullMatch().
+  regex_t partial_regex_;  // For PartialMatch().
+
+#else  // GTEST_USES_SIMPLE_RE
+
+  const char* full_pattern_;  // For FullMatch();
+
+#endif
+
+  GTEST_DISALLOW_ASSIGN_(RE);
+};
+
+// Formats a source file path and a line number as they would appear
+// in an error message from the compiler used to compile this code.
+GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
+
+// Formats a file location for compiler-independent XML output.
+// Although this function is not platform dependent, we put it next to
+// FormatFileLocation in order to contrast the two functions.
+GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,
+                                                               int line);
+
+// Defines logging utilities:
+//   GTEST_LOG_(severity) - logs messages at the specified severity level. The
+//                          message itself is streamed into the macro.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+  GTEST_INFO,
+  GTEST_WARNING,
+  GTEST_ERROR,
+  GTEST_FATAL
+};
+
+// Formats log entry severity, provides a stream object for streaming the
+// log message, and terminates the message with a newline when going out of
+// scope.
+class GTEST_API_ GTestLog {
+ public:
+  GTestLog(GTestLogSeverity severity, const char* file, int line);
+
+  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+  ~GTestLog();
+
+  ::std::ostream& GetStream() { return ::std::cerr; }
+
+ private:
+  const GTestLogSeverity severity_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
+};
+
+#define GTEST_LOG_(severity) \
+    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
+                                  __FILE__, __LINE__).GetStream()
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+//  Synopsys:
+//    GTEST_CHECK_(boolean_condition);
+//     or
+//    GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+//    This checks the condition and if the condition is not satisfied
+//    it prints message about the condition violation, including the
+//    condition itself, plus additional message streamed into it, if any,
+//    and then it aborts the program. It aborts the program irrespective of
+//    whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::IsTrue(condition)) \
+      ; \
+    else \
+      GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success).  Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+  if (const int gtest_error = (posix_call)) \
+    GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+                      << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Use ImplicitCast_ as a safe version of static_cast for upcasting in
+// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a
+// const Foo*).  When you use ImplicitCast_, the compiler checks that
+// the cast is safe.  Such explicit ImplicitCast_s are necessary in
+// surprisingly many situations where C++ demands an exact type match
+// instead of an argument type convertable to a target type.
+//
+// The syntax for using ImplicitCast_ is the same as for static_cast:
+//
+//   ImplicitCast_<ToType>(expr)
+//
+// ImplicitCast_ would have been part of the C++ standard library,
+// but the proposal was submitted too late.  It will probably make
+// its way into the language in the future.
+//
+// This relatively ugly name is intentional. It prevents clashes with
+// similar functions users may have (e.g., implicit_cast). The internal
+// namespace alone is not enough because the function can be found by ADL.
+template<typename To>
+inline To ImplicitCast_(To x) { return x; }
+
+// When you upcast (that is, cast a pointer from type Foo to type
+// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts
+// always succeed.  When you downcast (that is, cast a pointer from
+// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
+// how do you know the pointer is really of type SubclassOfFoo?  It
+// could be a bare Foo, or of type DifferentSubclassOfFoo.  Thus,
+// when you downcast, you should use this macro.  In debug mode, we
+// use dynamic_cast<> to double-check the downcast is legal (we die
+// if it's not).  In normal mode, we do the efficient static_cast<>
+// instead.  Thus, it's important to test in debug mode to make sure
+// the cast is legal!
+//    This is the only place in the code we should use dynamic_cast<>.
+// In particular, you SHOULDN'T be using dynamic_cast<> in order to
+// do RTTI (eg code like this:
+//    if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
+//    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
+// You should design the code some other way not to need this.
+//
+// This relatively ugly name is intentional. It prevents clashes with
+// similar functions users may have (e.g., down_cast). The internal
+// namespace alone is not enough because the function can be found by ADL.
+template<typename To, typename From>  // use like this: DownCast_<T*>(foo);
+inline To DownCast_(From* f) {  // so we only accept pointers
+  // Ensures that To is a sub-type of From *.  This test is here only
+  // for compile-time type checking, and has no overhead in an
+  // optimized build at run-time, as it will be optimized away
+  // completely.
+  if (false) {
+    const To to = NULL;
+    ::testing::internal::ImplicitCast_<From*>(to);
+  }
+
+#if GTEST_HAS_RTTI
+  // RTTI: debug mode only!
+  GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL);
+#endif
+  return static_cast<To>(f);
+}
+
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+  GTEST_CHECK_(typeid(*base) == typeid(Derived));
+  return dynamic_cast<Derived*>(base);  // NOLINT
+#else
+  return static_cast<Derived*>(base);  // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION
+
+// Defines the stderr capturer:
+//   CaptureStdout     - starts capturing stdout.
+//   GetCapturedStdout - stops capturing stdout and returns the captured string.
+//   CaptureStderr     - starts capturing stderr.
+//   GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION
+
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+extern ::std::vector<String> g_argvs;
+
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+const ::std::vector<String>& GetArgvs();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds.  This function is only for
+// testing Google Test's own constructs.  Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+  const timespec time = {
+    0,                  // 0 seconds.
+    n * 1000L * 1000L,  // And n ms.
+  };
+  nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified.  Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+  Notification() : notified_(false) {}
+
+  // Notifies all threads created with this notification to start. Must
+  // be called from the controller thread.
+  void Notify() { notified_ = true; }
+
+  // Blocks until the controller thread notifies. Must be called from a test
+  // thread.
+  void WaitForNotification() {
+    while(!notified_) {
+      SleepMilliseconds(10);
+    }
+  }
+
+ private:
+  volatile bool notified_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+  virtual ~ThreadWithParamBase() {}
+  virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical.  Some compilers (for
+// example, SunStudio) treat them as different types.  Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+  static_cast<ThreadWithParamBase*>(thread)->Run();
+  return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+//   void ThreadFunc(int param) { /* Do things with param */ }
+//   Notification thread_can_start;
+//   ...
+//   // The thread_can_start parameter is optional; you can supply NULL.
+//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+//   thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+  typedef void (*UserThreadFunc)(T);
+
+  ThreadWithParam(
+      UserThreadFunc func, T param, Notification* thread_can_start)
+      : func_(func),
+        param_(param),
+        thread_can_start_(thread_can_start),
+        finished_(false) {
+    ThreadWithParamBase* const base = this;
+    // The thread can be created only after all fields except thread_
+    // have been initialized.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+  }
+  ~ThreadWithParam() { Join(); }
+
+  void Join() {
+    if (!finished_) {
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+      finished_ = true;
+    }
+  }
+
+  virtual void Run() {
+    if (thread_can_start_ != NULL)
+      thread_can_start_->WaitForNotification();
+    func_(param_);
+  }
+
+ private:
+  const UserThreadFunc func_;  // User-supplied thread function.
+  const T param_;  // User-supplied parameter to the thread function.
+  // When non-NULL, used to block execution until the controller thread
+  // notifies.
+  Notification* const thread_can_start_;
+  bool finished_;  // true iff we know that the thread function has finished.
+  pthread_t thread_;  // The native thread object.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+//   Mutex mutex;
+//   ...
+//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end
+//                            // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes.  Do not use MutexBase directly.  Instead, write
+// the following to define a static mutex:
+//
+//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+  // Acquires this mutex.
+  void Lock() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+    owner_ = pthread_self();
+  }
+
+  // Releases this mutex.
+  void Unlock() {
+    // We don't protect writing to owner_ here, as it's the caller's
+    // responsibility to ensure that the current thread holds the
+    // mutex when this is called.
+    owner_ = 0;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+  }
+
+  // Does nothing if the current thread holds the mutex. Otherwise, crashes
+  // with high probability.
+  void AssertHeld() const {
+    GTEST_CHECK_(owner_ == pthread_self())
+        << "The current thread is not holding the mutex @" << this;
+  }
+
+  // A static mutex may be used before main() is entered.  It may even
+  // be used before the dynamic initialization stage.  Therefore we
+  // must be able to initialize a static mutex object at link time.
+  // This means MutexBase has to be a POD and its member variables
+  // have to be public.
+ public:
+  pthread_mutex_t mutex_;  // The underlying pthread mutex.
+  pthread_t owner_;  // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+    extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+  Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    owner_ = 0;
+  }
+  ~Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock as the ctor declaration would
+// conflict with a macro named MutexLock, which is defined on some
+// platforms.  Hence the typedef trick below.
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(MutexBase* mutex)
+      : mutex_(mutex) { mutex_->Lock(); }
+
+  ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+  MutexBase* const mutex_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage.  Therefore it cannot be templatized to access
+// ThreadLocal<T>.  Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+  virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+//   // Thread 1
+//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.
+//
+//   // Thread 2
+//   tl.set(150);  // Changes the value for thread 2 only.
+//   EXPECT_EQ(150, tl.get());
+//
+//   // Thread 1
+//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.
+//   tl.set(200);
+//   EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits.  Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies.  It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects.  That means they
+// will die after main() has returned.  Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : key_(CreateKey()),
+                  default_() {}
+  explicit ThreadLocal(const T& value) : key_(CreateKey()),
+                                         default_(value) {}
+
+  ~ThreadLocal() {
+    // Destroys the managed object for the current thread, if any.
+    DeleteThreadLocalValue(pthread_getspecific(key_));
+
+    // Releases resources associated with the key.  This will *not*
+    // delete managed objects for other threads.
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+  }
+
+  T* pointer() { return GetOrCreateValue(); }
+  const T* pointer() const { return GetOrCreateValue(); }
+  const T& get() const { return *pointer(); }
+  void set(const T& value) { *pointer() = value; }
+
+ private:
+  // Holds a value of type T.
+  class ValueHolder : public ThreadLocalValueHolderBase {
+   public:
+    explicit ValueHolder(const T& value) : value_(value) {}
+
+    T* pointer() { return &value_; }
+
+   private:
+    T value_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+  };
+
+  static pthread_key_t CreateKey() {
+    pthread_key_t key;
+    // When a thread exits, DeleteThreadLocalValue() will be called on
+    // the object managed for that thread.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_key_create(&key, &DeleteThreadLocalValue));
+    return key;
+  }
+
+  T* GetOrCreateValue() const {
+    ThreadLocalValueHolderBase* const holder =
+        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+    if (holder != NULL) {
+      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+    }
+
+    ValueHolder* const new_holder = new ValueHolder(default_);
+    ThreadLocalValueHolderBase* const holder_base = new_holder;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+    return new_holder->pointer();
+  }
+
+  // A key pthreads uses for looking up per-thread values.
+  const pthread_key_t key_;
+  const T default_;  // The default value for each thread.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+# define GTEST_IS_THREADSAFE 1
+
+#else  // GTEST_HAS_PTHREAD
+
+// A dummy implementation of synchronization primitives (mutex, lock,
+// and thread-local variable).  Necessary for compiling Google Test where
+// mutex is not supported - using Google Test in multiple threads is not
+// supported on such platforms.
+
+class Mutex {
+ public:
+  Mutex() {}
+  void AssertHeld() const {}
+};
+
+# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+  extern ::testing::internal::Mutex mutex
+
+# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(Mutex*) {}  // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : value_() {}
+  explicit ThreadLocal(const T& value) : value_(value) {}
+  T* pointer() { return &value_; }
+  const T* pointer() const { return &value_; }
+  const T& get() const { return value_; }
+  void set(const T& value) { value_ = value; }
+ private:
+  T value_;
+};
+
+// The above synchronization primitives have dummy implementations.
+// Therefore Google Test is not thread-safe.
+# define GTEST_IS_THREADSAFE 0
+
+#endif  // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
+
+// Passing non-POD classes through ellipsis (...) crashes the ARM
+// compiler and generates a warning in Sun Studio.  The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects.  We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+# define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+# define GTEST_CAN_COMPARE_NULL 1
+#endif
+
+// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
+// const T& and const T* in a function template.  These compilers
+// _can_ decide between class template specializations for T and T*,
+// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+# define GTEST_NEEDS_IS_POINTER_ 1
+#endif
+
+template <bool bool_value>
+struct bool_constant {
+  typedef bool_constant<bool_value> type;
+  static const bool value = bool_value;
+};
+template <bool bool_value> const bool bool_constant<bool_value>::value;
+
+typedef bool_constant<false> false_type;
+typedef bool_constant<true> true_type;
+
+template <typename T>
+struct is_pointer : public false_type {};
+
+template <typename T>
+struct is_pointer<T*> : public true_type {};
+
+template <typename Iterator>
+struct IteratorTraits {
+  typedef typename Iterator::value_type value_type;
+};
+
+template <typename T>
+struct IteratorTraits<T*> {
+  typedef T value_type;
+};
+
+template <typename T>
+struct IteratorTraits<const T*> {
+  typedef T value_type;
+};
+
+#if GTEST_OS_WINDOWS
+# define GTEST_PATH_SEP_ "\\"
+# define GTEST_HAS_ALT_PATH_SEP_ 1
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
+#else
+# define GTEST_PATH_SEP_ "/"
+# define GTEST_HAS_ALT_PATH_SEP_ 0
+typedef long long BiggestInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+// Utilities for char.
+
+// isspace(int ch) and friends accept an unsigned char or EOF.  char
+// may be signed, depending on the compiler (or compiler flags).
+// Therefore we need to cast a char to unsigned char before calling
+// isspace(), etc.
+
+inline bool IsAlpha(char ch) {
+  return isalpha(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsAlNum(char ch) {
+  return isalnum(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsDigit(char ch) {
+  return isdigit(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsLower(char ch) {
+  return islower(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsSpace(char ch) {
+  return isspace(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsUpper(char ch) {
+  return isupper(static_cast<unsigned char>(ch)) != 0;
+}
+inline bool IsXDigit(char ch) {
+  return isxdigit(static_cast<unsigned char>(ch)) != 0;
+}
+
+inline char ToLower(char ch) {
+  return static_cast<char>(tolower(static_cast<unsigned char>(ch)));
+}
+inline char ToUpper(char ch) {
+  return static_cast<char>(toupper(static_cast<unsigned char>(ch)));
+}
+
+// The testing::internal::posix namespace holds wrappers for common
+// POSIX functions.  These wrappers hide the differences between
+// Windows/MSVC and POSIX systems.  Since some compilers define these
+// standard functions as macros, the wrapper cannot have the same name
+// as the wrapped function.
+
+namespace posix {
+
+// Functions with a different name on Windows.
+
+#if GTEST_OS_WINDOWS
+
+typedef struct _stat StatStruct;
+
+# ifdef __BORLANDC__
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+# else  // !__BORLANDC__
+#  if GTEST_OS_WINDOWS_MOBILE
+inline int IsATTY(int /* fd */) { return 0; }
+#  else
+inline int IsATTY(int fd) { return _isatty(fd); }
+#  endif  // GTEST_OS_WINDOWS_MOBILE
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return _stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return _strdup(src); }
+# endif  // __BORLANDC__
+
+# if GTEST_OS_WINDOWS_MOBILE
+inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
+// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
+// time and thus not defined there.
+# else
+inline int FileNo(FILE* file) { return _fileno(file); }
+inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
+inline int RmDir(const char* dir) { return _rmdir(dir); }
+inline bool IsDir(const StatStruct& st) {
+  return (_S_IFDIR & st.st_mode) != 0;
+}
+# endif  // GTEST_OS_WINDOWS_MOBILE
+
+#else
+
+typedef struct stat StatStruct;
+
+inline int FileNo(FILE* file) { return fileno(file); }
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return strcasecmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+inline int RmDir(const char* dir) { return rmdir(dir); }
+inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
+
+#endif  // GTEST_OS_WINDOWS
+
+// Functions deprecated by MSVC 8.0.
+
+#ifdef _MSC_VER
+// Temporarily disable warning 4996 (deprecated function).
+# pragma warning(push)
+# pragma warning(disable:4996)
+#endif
+
+inline const char* StrNCpy(char* dest, const char* src, size_t n) {
+  return strncpy(dest, src, n);
+}
+
+// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
+// StrError() aren't needed on Windows CE at this time and thus not
+// defined there.
+
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int ChDir(const char* dir) { return chdir(dir); }
+#endif
+inline FILE* FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+#if !GTEST_OS_WINDOWS_MOBILE
+inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
+  return freopen(path, mode, stream);
+}
+inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
+#endif
+inline int FClose(FILE* fp) { return fclose(fp); }
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int Read(int fd, void* buf, unsigned int count) {
+  return static_cast<int>(read(fd, buf, count));
+}
+inline int Write(int fd, const void* buf, unsigned int count) {
+  return static_cast<int>(write(fd, buf, count));
+}
+inline int Close(int fd) { return close(fd); }
+inline const char* StrError(int errnum) { return strerror(errnum); }
+#endif
+inline const char* GetEnv(const char* name) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // We are on Windows CE, which has no environment variables.
+  return NULL;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+  // Environment variables which we programmatically clear will be set to the
+  // empty string rather than unset (NULL).  Handle that case.
+  const char* const env = getenv(name);
+  return (env != NULL && env[0] != '\0') ? env : NULL;
+#else
+  return getenv(name);
+#endif
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)  // Restores the warning state.
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE has no C library. The abort() function is used in
+// several places in Google Test. This implementation provides a reasonable
+// imitation of standard behaviour.
+void Abort();
+#else
+inline void Abort() { abort(); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+}  // namespace posix
+
+// The maximum number a BiggestInt can represent.  This definition
+// works no matter BiggestInt is represented in one's complement or
+// two's complement.
+//
+// We cannot rely on numeric_limits in STL, as __int64 and long long
+// are not part of standard C++ and numeric_limits doesn't need to be
+// defined for them.
+const BiggestInt kMaxBiggestInt =
+    ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
+
+// This template class serves as a compile-time function from size to
+// type.  It maps a size in bytes to a primitive type with that
+// size. e.g.
+//
+//   TypeWithSize<4>::UInt
+//
+// is typedef-ed to be unsigned int (unsigned integer made up of 4
+// bytes).
+//
+// Such functionality should belong to STL, but I cannot find it
+// there.
+//
+// Google Test uses this class in the implementation of floating-point
+// comparison.
+//
+// For now it only handles UInt (unsigned int) as that's all Google Test
+// needs.  Other types can be easily added in the future if need
+// arises.
+template <size_t size>
+class TypeWithSize {
+ public:
+  // This prevents the user from using TypeWithSize<N> with incorrect
+  // values of N.
+  typedef void UInt;
+};
+
+// The specialization for size 4.
+template <>
+class TypeWithSize<4> {
+ public:
+  // unsigned int has size 4 in both gcc and MSVC.
+  //
+  // As base/basictypes.h doesn't compile on Windows, we cannot use
+  // uint32, uint64, and etc here.
+  typedef int Int;
+  typedef unsigned int UInt;
+};
+
+// The specialization for size 8.
+template <>
+class TypeWithSize<8> {
+ public:
+
+#if GTEST_OS_WINDOWS
+  typedef __int64 Int;
+  typedef unsigned __int64 UInt;
+#else
+  typedef long long Int;  // NOLINT
+  typedef unsigned long long UInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+};
+
+// Integer types of known sizes.
+typedef TypeWithSize<4>::Int Int32;
+typedef TypeWithSize<4>::UInt UInt32;
+typedef TypeWithSize<8>::Int Int64;
+typedef TypeWithSize<8>::UInt UInt64;
+typedef TypeWithSize<8>::Int TimeInMillis;  // Represents time in milliseconds.
+
+// Utilities for command line flags and environment variables.
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32_(name) \
+    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string_(name) \
+    GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool_(name, default_val, doc) \
+    GTEST_API_ bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val)
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes the result
+// to *value and returns true; otherwise leaves *value unchanged and returns
+// false.
+// TODO(chandlerc): Find a better way to refactor flag and environment parsing
+// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
+// function.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value);
+
+// Parses a bool/Int32/string from the environment variable
+// corresponding to the given Google Test flag.
+bool BoolFromGTestEnv(const char* flag, bool default_val);
+GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+#if GTEST_OS_LINUX
+# include <stdlib.h>
+# include <sys/types.h>
+# include <sys/wait.h>
+# include <unistd.h>
+#endif  // GTEST_OS_LINUX
+
+#include <ctype.h>
+#include <string.h>
+#include <iomanip>
+#include <limits>
+#include <set>
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares the String class and functions used internally by
+// Google Test.  They are subject to change without notice. They should not used
+// by code external to Google Test.
+//
+// This header file is #included by <gtest/internal/gtest-internal.h>.
+// It should not be #included by other files.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+# include <mem.h>
+#endif
+
+#include <string.h>
+
+#include <string>
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// For historic reasons, we don't use std::string.
+//
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String can represent both NULL and the empty string,
+// while std::string cannot represent NULL.
+//
+// NULL and the empty string are considered different.  NULL is less
+// than anything (including the empty string) except itself.
+//
+// This class only provides minimum functionality necessary for
+// implementing Google Test.  We do not intend to implement a full-fledged
+// string class here.
+//
+// Since the purpose of this class is to provide a substitute for
+// std::string on platforms where it cannot be used, we define a copy
+// constructor and assignment operators such that we don't need
+// conditional compilation in a lot of places.
+//
+// In order to make the representation efficient, the d'tor of String
+// is not virtual.  Therefore DO NOT INHERIT FROM String.
+class GTEST_API_ String {
+ public:
+  // Static utility methods
+
+  // Returns the input enclosed in double quotes if it's not NULL;
+  // otherwise returns "(null)".  For example, "\"Hello\"" is returned
+  // for input "Hello".
+  //
+  // This is useful for printing a C string in the syntax of a literal.
+  //
+  // Known issue: escape sequences are not handled yet.
+  static String ShowCStringQuoted(const char* c_str);
+
+  // Clones a 0-terminated C string, allocating memory using new.  The
+  // caller is responsible for deleting the return value using
+  // delete[].  Returns the cloned string, or NULL if the input is
+  // NULL.
+  //
+  // This is different from strdup() in string.h, which allocates
+  // memory using malloc().
+  static const char* CloneCString(const char* c_str);
+
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
+  // able to pass strings to Win32 APIs on CE we need to convert them
+  // to 'Unicode', UTF-16.
+
+  // Creates a UTF-16 wide string from the given ANSI string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the wide string, or NULL if the
+  // input is NULL.
+  //
+  // The wide string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static LPCWSTR AnsiToUtf16(const char* c_str);
+
+  // Creates an ANSI string from the given wide string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the ANSI string, or NULL if the
+  // input is NULL.
+  //
+  // The returned string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static const char* Utf16ToAnsi(LPCWSTR utf16_str);
+#endif
+
+  // Compares two C strings.  Returns true iff they have the same content.
+  //
+  // Unlike strcmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CStringEquals(const char* lhs, const char* rhs);
+
+  // Converts a wide C string to a String using the UTF-8 encoding.
+  // NULL will be converted to "(null)".  If an error occurred during
+  // the conversion, "(failed to convert from wide string)" is
+  // returned.
+  static String ShowWideCString(const wchar_t* wide_c_str);
+
+  // Similar to ShowWideCString(), except that this function encloses
+  // the converted string in double quotes.
+  static String ShowWideCStringQuoted(const wchar_t* wide_c_str);
+
+  // Compares two wide C strings.  Returns true iff they have the same
+  // content.
+  //
+  // Unlike wcscmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
+
+  // Compares two C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike strcasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CaseInsensitiveCStringEquals(const char* lhs,
+                                           const char* rhs);
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                               const wchar_t* rhs);
+
+  // Formats a list of arguments to a String, using the same format
+  // spec string as for printf.
+  //
+  // We do not use the StringPrintf class as it is not universally
+  // available.
+  //
+  // The result is limited to 4096 characters (including the tailing
+  // 0).  If 4096 characters are not enough to format the input,
+  // "<buffer exceeded>" is returned.
+  static String Format(const char* format, ...);
+
+  // C'tors
+
+  // The default c'tor constructs a NULL string.
+  String() : c_str_(NULL), length_(0) {}
+
+  // Constructs a String by cloning a 0-terminated C string.
+  String(const char* a_c_str) {  // NOLINT
+    if (a_c_str == NULL) {
+      c_str_ = NULL;
+      length_ = 0;
+    } else {
+      ConstructNonNull(a_c_str, strlen(a_c_str));
+    }
+  }
+
+  // Constructs a String by copying a given number of chars from a
+  // buffer.  E.g. String("hello", 3) creates the string "hel",
+  // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
+  // and String(NULL, 1) results in access violation.
+  String(const char* buffer, size_t a_length) {
+    ConstructNonNull(buffer, a_length);
+  }
+
+  // The copy c'tor creates a new copy of the string.  The two
+  // String objects do not share content.
+  String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
+
+  // D'tor.  String is intended to be a final class, so the d'tor
+  // doesn't need to be virtual.
+  ~String() { delete[] c_str_; }
+
+  // Allows a String to be implicitly converted to an ::std::string or
+  // ::string, and vice versa.  Converting a String containing a NULL
+  // pointer to ::std::string or ::string is undefined behavior.
+  // Converting a ::std::string or ::string containing an embedded NUL
+  // character to a String will result in the prefix up to the first
+  // NUL character.
+  String(const ::std::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::std::string() const { return ::std::string(c_str(), length()); }
+
+#if GTEST_HAS_GLOBAL_STRING
+  String(const ::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::string() const { return ::string(c_str(), length()); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  // Returns true iff this is an empty string (i.e. "").
+  bool empty() const { return (c_str() != NULL) && (length() == 0); }
+
+  // Compares this with another String.
+  // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+  // if this is greater than rhs.
+  int Compare(const String& rhs) const;
+
+  // Returns true iff this String equals the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }
+
+  // Returns true iff this String is less than the given String.  A
+  // NULL string is considered less than "".
+  bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
+
+  // Returns true iff this String doesn't equal the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }
+
+  // Returns true iff this String ends with the given suffix.  *Any*
+  // String is considered to end with a NULL or empty suffix.
+  bool EndsWith(const char* suffix) const;
+
+  // Returns true iff this String ends with the given suffix, not considering
+  // case. Any String is considered to end with a NULL or empty suffix.
+  bool EndsWithCaseInsensitive(const char* suffix) const;
+
+  // Returns the length of the encapsulated string, or 0 if the
+  // string is NULL.
+  size_t length() const { return length_; }
+
+  // Gets the 0-terminated C string this String object represents.
+  // The String object still owns the string.  Therefore the caller
+  // should NOT delete the return value.
+  const char* c_str() const { return c_str_; }
+
+  // Assigns a C string to this object.  Self-assignment works.
+  const String& operator=(const char* a_c_str) {
+    return *this = String(a_c_str);
+  }
+
+  // Assigns a String object to this object.  Self-assignment works.
+  const String& operator=(const String& rhs) {
+    if (this != &rhs) {
+      delete[] c_str_;
+      if (rhs.c_str() == NULL) {
+        c_str_ = NULL;
+        length_ = 0;
+      } else {
+        ConstructNonNull(rhs.c_str(), rhs.length());
+      }
+    }
+
+    return *this;
+  }
+
+ private:
+  // Constructs a non-NULL String from the given content.  This
+  // function can only be called when c_str_ has not been allocated.
+  // ConstructNonNull(NULL, 0) results in an empty string ("").
+  // ConstructNonNull(NULL, non_zero) is undefined behavior.
+  void ConstructNonNull(const char* buffer, size_t a_length) {
+    char* const str = new char[a_length + 1];
+    memcpy(str, buffer, a_length);
+    str[a_length] = '\0';
+    c_str_ = str;
+    length_ = a_length;
+  }
+
+  const char* c_str_;
+  size_t length_;
+};  // class String
+
+// Streams a String to an ostream.  Each '\0' character in the String
+// is replaced with "\\0".
+inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
+  if (str.c_str() == NULL) {
+    os << "(null)";
+  } else {
+    const char* const c_str = str.c_str();
+    for (size_t i = 0; i != str.length(); i++) {
+      if (c_str[i] == '\0') {
+        os << "\\0";
+      } else {
+        os << c_str[i];
+      }
+    }
+  }
+  return os;
+}
+
+// Gets the content of the stringstream's buffer as a String.  Each '\0'
+// character in the buffer is replaced with "\\0".
+GTEST_API_ String StringStreamToString(::std::stringstream* stream);
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keith.ray@gmail.com (Keith Ray)
+//
+// Google Test filepath utilities
+//
+// This header file declares classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included in <gtest/internal/gtest-internal.h>.
+// Do not include this header file separately!
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+
+
+namespace testing {
+namespace internal {
+
+// FilePath - a class for file and directory pathname manipulation which
+// handles platform-specific conventions (like the pathname separator).
+// Used for helper functions for naming files in a directory for xml output.
+// Except for Set methods, all methods are const or static, which provides an
+// "immutable value object" -- useful for peace of mind.
+// A FilePath with a value ending in a path separator ("like/this/") represents
+// a directory, otherwise it is assumed to represent a file. In either case,
+// it may or may not represent an actual file or directory in the file system.
+// Names are NOT checked for syntax correctness -- no checking for illegal
+// characters, malformed paths, etc.
+
+class GTEST_API_ FilePath {
+ public:
+  FilePath() : pathname_("") { }
+  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+
+  explicit FilePath(const char* pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  explicit FilePath(const String& pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  FilePath& operator=(const FilePath& rhs) {
+    Set(rhs);
+    return *this;
+  }
+
+  void Set(const FilePath& rhs) {
+    pathname_ = rhs.pathname_;
+  }
+
+  String ToString() const { return pathname_; }
+  const char* c_str() const { return pathname_.c_str(); }
+
+  // Returns the current working directory, or "" if unsuccessful.
+  static FilePath GetCurrentDir();
+
+  // Given directory = "dir", base_name = "test", number = 0,
+  // extension = "xml", returns "dir/test.xml". If number is greater
+  // than zero (e.g., 12), returns "dir/test_12.xml".
+  // On Windows platform, uses \ as the separator rather than /.
+  static FilePath MakeFileName(const FilePath& directory,
+                               const FilePath& base_name,
+                               int number,
+                               const char* extension);
+
+  // Given directory = "dir", relative_path = "test.xml",
+  // returns "dir/test.xml".
+  // On Windows, uses \ as the separator rather than /.
+  static FilePath ConcatPaths(const FilePath& directory,
+                              const FilePath& relative_path);
+
+  // Returns a pathname for a file that does not currently exist. The pathname
+  // will be directory/base_name.extension or
+  // directory/base_name_<number>.extension if directory/base_name.extension
+  // already exists. The number will be incremented until a pathname is found
+  // that does not already exist.
+  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+  // There could be a race condition if two or more processes are calling this
+  // function at the same time -- they could both pick the same filename.
+  static FilePath GenerateUniqueFileName(const FilePath& directory,
+                                         const FilePath& base_name,
+                                         const char* extension);
+
+  // Returns true iff the path is NULL or "".
+  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; }
+
+  // If input name has a trailing separator character, removes it and returns
+  // the name, otherwise return the name string unmodified.
+  // On Windows platform, uses \ as the separator, other platforms use /.
+  FilePath RemoveTrailingPathSeparator() const;
+
+  // Returns a copy of the FilePath with the directory part removed.
+  // Example: FilePath("path/to/file").RemoveDirectoryName() returns
+  // FilePath("file"). If there is no directory part ("just_a_file"), it returns
+  // the FilePath unmodified. If there is no file part ("just_a_dir/") it
+  // returns an empty FilePath ("").
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveDirectoryName() const;
+
+  // RemoveFileName returns the directory path with the filename removed.
+  // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+  // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+  // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+  // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveFileName() const;
+
+  // Returns a copy of the FilePath with the case-insensitive extension removed.
+  // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+  // FilePath("dir/file"). If a case-insensitive extension is not
+  // found, returns a copy of the original FilePath.
+  FilePath RemoveExtension(const char* extension) const;
+
+  // Creates directories so that path exists. Returns true if successful or if
+  // the directories already exist; returns false if unable to create
+  // directories for any reason. Will also return false if the FilePath does
+  // not represent a directory (that is, it doesn't end with a path separator).
+  bool CreateDirectoriesRecursively() const;
+
+  // Create the directory so that path exists. Returns true if successful or
+  // if the directory already exists; returns false if unable to create the
+  // directory for any reason, including if the parent directory does not
+  // exist. Not named "CreateDirectory" because that's a macro on Windows.
+  bool CreateFolder() const;
+
+  // Returns true if FilePath describes something in the file-system,
+  // either a file, directory, or whatever, and that something exists.
+  bool FileOrDirectoryExists() const;
+
+  // Returns true if pathname describes a directory in the file-system
+  // that exists.
+  bool DirectoryExists() const;
+
+  // Returns true if FilePath ends with a path separator, which indicates that
+  // it is intended to represent a directory. Returns false otherwise.
+  // This does NOT check that a directory (or file) actually exists.
+  bool IsDirectory() const;
+
+  // Returns true if pathname describes a root directory. (Windows has one
+  // root directory per disk drive.)
+  bool IsRootDirectory() const;
+
+  // Returns true if pathname describes an absolute path.
+  bool IsAbsolutePath() const;
+
+ private:
+  // Replaces multiple consecutive separators with a single separator.
+  // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+  // redundancies that might be in a pathname involving "." or "..".
+  //
+  // A pathname with multiple consecutive separators may occur either through
+  // user error or as a result of some scripts or APIs that generate a pathname
+  // with a trailing separator. On other platforms the same API or script
+  // may NOT generate a pathname with a trailing "/". Then elsewhere that
+  // pathname may have another "/" and pathname components added to it,
+  // without checking for the separator already being there.
+  // The script language and operating system may allow paths like "foo//bar"
+  // but some of the functions in FilePath will not handle that correctly. In
+  // particular, RemoveTrailingPathSeparator() only removes one separator, and
+  // it is called in CreateDirectoriesRecursively() assuming that it will change
+  // a pathname from directory syntax (trailing separator) to filename syntax.
+  //
+  // On Windows this method also replaces the alternate path separator '/' with
+  // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+  // "bar\\foo".
+
+  void Normalize();
+
+  // Returns a pointer to the last occurence of a valid path separator in
+  // the FilePath. On Windows, for example, both '/' and '\' are valid path
+  // separators. Returns NULL if no path separator was found.
+  const char* FindLastPathSeparator() const;
+
+  String pathname_;
+};  // class FilePath
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+// This file was GENERATED by command:
+//     pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently we support at most 50 types in a list, and at most 50
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+
+// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+# ifdef __GLIBCXX__
+#  include <cxxabi.h>
+# elif defined(__HP_aCC)
+#  include <acxx_demangle.h>
+# endif  // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// GetTypeName<T>() returns a human-readable name of type T.
+// NB: This function is also used in Google Mock, so don't move it inside of
+// the typed-test-only section below.
+template <typename T>
+String GetTypeName() {
+# if GTEST_HAS_RTTI
+
+  const char* const name = typeid(T).name();
+#  if defined(__GLIBCXX__) || defined(__HP_aCC)
+  int status = 0;
+  // gcc's implementation of typeid(T).name() mangles the type name,
+  // so we have to demangle it.
+#   ifdef __GLIBCXX__
+  using abi::__cxa_demangle;
+#   endif // __GLIBCXX__
+  char* const readable_name = __cxa_demangle(name, 0, 0, &status);
+  const String name_str(status == 0 ? readable_name : name);
+  free(readable_name);
+  return name_str;
+#  else
+  return name;
+#  endif  // __GLIBCXX__ || __HP_aCC
+
+# else
+
+  return "<type>";
+
+# endif  // GTEST_HAS_RTTI
+}
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type.  This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+  typedef bool type;
+};
+
+// A unique type used as the default value for the arguments of class
+// template Types.  This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists.  In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+  typedef T1 Head;
+  typedef Types0 Tail;
+};
+template <typename T1, typename T2>
+struct Types2 {
+  typedef T1 Head;
+  typedef Types1<T2> Tail;
+};
+
+template <typename T1, typename T2, typename T3>
+struct Types3 {
+  typedef T1 Head;
+  typedef Types2<T2, T3> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types4 {
+  typedef T1 Head;
+  typedef Types3<T2, T3, T4> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types5 {
+  typedef T1 Head;
+  typedef Types4<T2, T3, T4, T5> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types6 {
+  typedef T1 Head;
+  typedef Types5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types7 {
+  typedef T1 Head;
+  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types8 {
+  typedef T1 Head;
+  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types9 {
+  typedef T1 Head;
+  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types10 {
+  typedef T1 Head;
+  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types11 {
+  typedef T1 Head;
+  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types12 {
+  typedef T1 Head;
+  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types13 {
+  typedef T1 Head;
+  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types14 {
+  typedef T1 Head;
+  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types15 {
+  typedef T1 Head;
+  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types16 {
+  typedef T1 Head;
+  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types17 {
+  typedef T1 Head;
+  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types18 {
+  typedef T1 Head;
+  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types19 {
+  typedef T1 Head;
+  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types20 {
+  typedef T1 Head;
+  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types21 {
+  typedef T1 Head;
+  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types22 {
+  typedef T1 Head;
+  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types23 {
+  typedef T1 Head;
+  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types24 {
+  typedef T1 Head;
+  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types25 {
+  typedef T1 Head;
+  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types26 {
+  typedef T1 Head;
+  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types27 {
+  typedef T1 Head;
+  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types28 {
+  typedef T1 Head;
+  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types29 {
+  typedef T1 Head;
+  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types30 {
+  typedef T1 Head;
+  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types31 {
+  typedef T1 Head;
+  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types32 {
+  typedef T1 Head;
+  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types33 {
+  typedef T1 Head;
+  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types34 {
+  typedef T1 Head;
+  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types35 {
+  typedef T1 Head;
+  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types36 {
+  typedef T1 Head;
+  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types37 {
+  typedef T1 Head;
+  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types38 {
+  typedef T1 Head;
+  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types39 {
+  typedef T1 Head;
+  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types40 {
+  typedef T1 Head;
+  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types41 {
+  typedef T1 Head;
+  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types42 {
+  typedef T1 Head;
+  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types43 {
+  typedef T1 Head;
+  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types44 {
+  typedef T1 Head;
+  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types45 {
+  typedef T1 Head;
+  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types46 {
+  typedef T1 Head;
+  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types47 {
+  typedef T1 Head;
+  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types48 {
+  typedef T1 Head;
+  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types49 {
+  typedef T1 Head;
+  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct Types50 {
+  typedef T1 Head;
+  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+}  // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length.  Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Types template.
+template <typename T1 = internal::None, typename T2 = internal::None,
+    typename T3 = internal::None, typename T4 = internal::None,
+    typename T5 = internal::None, typename T6 = internal::None,
+    typename T7 = internal::None, typename T8 = internal::None,
+    typename T9 = internal::None, typename T10 = internal::None,
+    typename T11 = internal::None, typename T12 = internal::None,
+    typename T13 = internal::None, typename T14 = internal::None,
+    typename T15 = internal::None, typename T16 = internal::None,
+    typename T17 = internal::None, typename T18 = internal::None,
+    typename T19 = internal::None, typename T20 = internal::None,
+    typename T21 = internal::None, typename T22 = internal::None,
+    typename T23 = internal::None, typename T24 = internal::None,
+    typename T25 = internal::None, typename T26 = internal::None,
+    typename T27 = internal::None, typename T28 = internal::None,
+    typename T29 = internal::None, typename T30 = internal::None,
+    typename T31 = internal::None, typename T32 = internal::None,
+    typename T33 = internal::None, typename T34 = internal::None,
+    typename T35 = internal::None, typename T36 = internal::None,
+    typename T37 = internal::None, typename T38 = internal::None,
+    typename T39 = internal::None, typename T40 = internal::None,
+    typename T41 = internal::None, typename T42 = internal::None,
+    typename T43 = internal::None, typename T44 = internal::None,
+    typename T45 = internal::None, typename T46 = internal::None,
+    typename T47 = internal::None, typename T48 = internal::None,
+    typename T49 = internal::None, typename T50 = internal::None>
+struct Types {
+  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Types<internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types0 type;
+};
+template <typename T1>
+struct Types<T1, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types1<T1> type;
+};
+template <typename T1, typename T2>
+struct Types<T1, T2, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types2<T1, T2> type;
+};
+template <typename T1, typename T2, typename T3>
+struct Types<T1, T2, T3, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types3<T1, T2, T3> type;
+};
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types4<T1, T2, T3, T4> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types<T1, T2, T3, T4, T5, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types5<T1, T2, T3, T4, T5> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, internal::None, internal::None, internal::None> {
+  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, internal::None, internal::None> {
+  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, T49, internal::None> {
+  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+namespace internal {
+
+# define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>.  This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+  template <typename T>
+  struct Bind {
+    typedef Tmpl<T> type;
+  };
+};
+
+# define GTEST_BIND_(TmplSel, T) \
+  TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates.  This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists.  In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN).  Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates0 Tail;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates2 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates1<T2> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates3 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates2<T2, T3> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates4 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates3<T2, T3, T4> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates5 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates4<T2, T3, T4, T5> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates6 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates7 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates8 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates9 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates10 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates11 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates12 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates13 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates14 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates15 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates16 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates17 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates18 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates19 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates20 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates21 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates22 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates23 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates24 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates25 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates26 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates27 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates28 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates29 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates30 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates31 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates32 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates33 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates34 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates35 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates36 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates37 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates38 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates39 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates40 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates41 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates42 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates43 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates44 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates45 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates46 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates47 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates48 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates49 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>
+struct Templates50 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length.  Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Templates template.
+template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,
+    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,
+    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,
+    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,
+    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,
+    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,
+    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,
+    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,
+    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,
+    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,
+    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,
+    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,
+    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,
+    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,
+    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,
+    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,
+    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,
+    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,
+    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,
+    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,
+    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,
+    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,
+    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,
+    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,
+    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>
+struct Templates {
+  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates0 type;
+};
+template <GTEST_TEMPLATE_ T1>
+struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates1<T1> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates2<T1, T2> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates3<T1, T2, T3> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates4<T1, T2, T3, T4> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates5<T1, T2, T3, T4, T5> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates6<T1, T2, T3, T4, T5, T6> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, NoneT, NoneT, NoneT> {
+  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, NoneT, NoneT> {
+  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, T49, NoneT> {
+  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> > {
+  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;
+};
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+// Due to C++ preprocessor weirdness, we need double indirection to
+// concatenate two tokens when one of them is __LINE__.  Writing
+//
+//   foo ## __LINE__
+//
+// will result in the token foo__LINE__, instead of foo followed by
+// the current line number.  For more details, see
+// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
+#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
+#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
+
+// Google Test defines the testing::Message class to allow construction of
+// test messages via the << operator.  The idea is that anything
+// streamable to std::ostream can be streamed to a testing::Message.
+// This allows a user to use his own types in Google Test assertions by
+// overloading the << operator.
+//
+// util/gtl/stl_logging-inl.h overloads << for STL containers.  These
+// overloads cannot be defined in the std namespace, as that will be
+// undefined behavior.  Therefore, they are defined in the global
+// namespace instead.
+//
+// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
+// overloads are visible in either the std namespace or the global
+// namespace, but not other namespaces, including the testing
+// namespace which Google Test's Message class is in.
+//
+// To allow STL containers (and other types that has a << operator
+// defined in the global namespace) to be used in Google Test assertions,
+// testing::Message must access the custom << operator from the global
+// namespace.  Hence this helper function.
+//
+// Note: Jeffrey Yasskin suggested an alternative fix by "using
+// ::operator<<;" in the definition of Message's operator<<.  That fix
+// doesn't require a helper function, but unfortunately doesn't
+// compile with MSVC.
+template <typename T>
+inline void GTestStreamToHelper(std::ostream* os, const T& val) {
+  *os << val;
+}
+
+class ProtocolMessage;
+namespace proto2 { class Message; }
+
+namespace testing {
+
+// Forward declarations.
+
+class AssertionResult;                 // Result of an assertion.
+class Message;                         // Represents a failure message.
+class Test;                            // Represents a test.
+class TestInfo;                        // Information about a test.
+class TestPartResult;                  // Result of a test part.
+class UnitTest;                        // A collection of test cases.
+
+template <typename T>
+::std::string PrintToString(const T& value);
+
+namespace internal {
+
+struct TraceInfo;                      // Information about a trace point.
+class ScopedTrace;                     // Implements scoped trace.
+class TestInfoImpl;                    // Opaque implementation of TestInfo
+class UnitTestImpl;                    // Opaque implementation of UnitTest
+
+// How many times InitGoogleTest() has been called.
+extern int g_init_gtest_count;
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+GTEST_API_ extern const char kStackTraceMarker[];
+
+// A secret type that Google Test users don't know about.  It has no
+// definition on purpose.  Therefore it's impossible to create a
+// Secret object, which is what we want.
+class Secret;
+
+// Two overloaded helpers for checking at compile time whether an
+// expression is a null pointer literal (i.e. NULL or any 0-valued
+// compile-time integral constant).  Their return values have
+// different sizes, so we can use sizeof() to test which version is
+// picked by the compiler.  These helpers have no implementations, as
+// we only need their signatures.
+//
+// Given IsNullLiteralHelper(x), the compiler will pick the first
+// version if x can be implicitly converted to Secret*, and pick the
+// second version otherwise.  Since Secret is a secret and incomplete
+// type, the only expression a user can write that has type Secret* is
+// a null pointer literal.  Therefore, we know that x is a null
+// pointer literal if and only if the first version is picked by the
+// compiler.
+char IsNullLiteralHelper(Secret* p);
+char (&IsNullLiteralHelper(...))[2];  // NOLINT
+
+// A compile-time bool constant that is true if and only if x is a
+// null pointer literal (i.e. NULL or any 0-valued compile-time
+// integral constant).
+#ifdef GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+# define GTEST_IS_NULL_LITERAL_(x) false
+#else
+# define GTEST_IS_NULL_LITERAL_(x) \
+    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif  // GTEST_ELLIPSIS_NEEDS_POD_
+
+// Appends the user-supplied message to the Google-Test-generated message.
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+                                    const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class GTEST_API_ ScopedTrace {
+ public:
+  // The c'tor pushes the given source file location and message onto
+  // a trace stack maintained by Google Test.
+  ScopedTrace(const char* file, int line, const Message& message);
+
+  // The d'tor pops the info pushed by the c'tor.
+  //
+  // Note that the d'tor is not virtual in order to be efficient.
+  // Don't inherit from ScopedTrace!
+  ~ScopedTrace();
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its
+                            // c'tor and d'tor.  Therefore it doesn't
+                            // need to be used otherwise.
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+// The Symbian compiler has a bug that prevents it from selecting the
+// correct overload of FormatForComparisonFailureMessage (see below)
+// unless we pass the first argument by reference.  If we do that,
+// however, Visual Age C++ 10.1 generates a compiler error.  Therefore
+// we only apply the work-around for Symbian.
+#if defined(__SYMBIAN32__)
+# define GTEST_CREF_WORKAROUND_ const&
+#else
+# define GTEST_CREF_WORKAROUND_
+#endif
+
+// When this operand is a const char* or char*, if the other operand
+// is a ::std::string or ::string, we print this operand as a C string
+// rather than a pointer (we do the same for wide strings); otherwise
+// we print it as a pointer to be safe.
+
+// This internal macro is used to avoid duplicated code.
+#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\
+inline String FormatForComparisonFailureMessage(\
+    operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \
+    const operand2_type& /*operand2*/) {\
+  return operand1_printer(str);\
+}\
+inline String FormatForComparisonFailureMessage(\
+    const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \
+    const operand2_type& /*operand2*/) {\
+  return operand1_printer(str);\
+}
+
+GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
+#if GTEST_HAS_STD_WSTRING
+GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+#undef GTEST_FORMAT_IMPL_
+
+// The next four overloads handle the case where the operand being
+// printed is a char/wchar_t pointer and the other operand is not a
+// string/wstring object.  In such cases, we just print the operand as
+// a pointer to be safe.
+#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType)                       \
+  template <typename T>                                             \
+  String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \
+                                           const T&) { \
+    return PrintToString(static_cast<const void*>(p));              \
+  }
+
+GTEST_FORMAT_CHAR_PTR_IMPL_(char)
+GTEST_FORMAT_CHAR_PTR_IMPL_(const char)
+GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t)
+GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t)
+
+#undef GTEST_FORMAT_CHAR_PTR_IMPL_
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+                                     const char* actual_expression,
+                                     const String& expected_value,
+                                     const String& actual_value,
+                                     bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+    const AssertionResult& assertion_result,
+    const char* expression_text,
+    const char* actual_predicate_value,
+    const char* expected_predicate_value);
+
+// This template class represents an IEEE floating-point number
+// (either single-precision or double-precision, depending on the
+// template parameters).
+//
+// The purpose of this class is to do more sophisticated number
+// comparison.  (Due to round-off error, etc, it's very unlikely that
+// two floating-points will be equal exactly.  Hence a naive
+// comparison by the == operation often doesn't work.)
+//
+// Format of IEEE floating-point:
+//
+//   The most-significant bit being the leftmost, an IEEE
+//   floating-point looks like
+//
+//     sign_bit exponent_bits fraction_bits
+//
+//   Here, sign_bit is a single bit that designates the sign of the
+//   number.
+//
+//   For float, there are 8 exponent bits and 23 fraction bits.
+//
+//   For double, there are 11 exponent bits and 52 fraction bits.
+//
+//   More details can be found at
+//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+template <typename RawType>
+class FloatingPoint {
+ public:
+  // Defines the unsigned integer type that has the same size as the
+  // floating point number.
+  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
+
+  // Constants.
+
+  // # of bits in a number.
+  static const size_t kBitCount = 8*sizeof(RawType);
+
+  // # of fraction bits in a number.
+  static const size_t kFractionBitCount =
+    std::numeric_limits<RawType>::digits - 1;
+
+  // # of exponent bits in a number.
+  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
+
+  // The mask for the sign bit.
+  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
+
+  // The mask for the fraction bits.
+  static const Bits kFractionBitMask =
+    ~static_cast<Bits>(0) >> (kExponentBitCount + 1);
+
+  // The mask for the exponent bits.
+  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
+
+  // How many ULP's (Units in the Last Place) we want to tolerate when
+  // comparing two numbers.  The larger the value, the more error we
+  // allow.  A 0 value means that two numbers must be exactly the same
+  // to be considered equal.
+  //
+  // The maximum error of a single floating-point operation is 0.5
+  // units in the last place.  On Intel CPU's, all floating-point
+  // calculations are done with 80-bit precision, while double has 64
+  // bits.  Therefore, 4 should be enough for ordinary use.
+  //
+  // See the following article for more details on ULP:
+  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.
+  static const size_t kMaxUlps = 4;
+
+  // Constructs a FloatingPoint from a raw floating-point number.
+  //
+  // On an Intel CPU, passing a non-normalized NAN (Not a Number)
+  // around may change its bits, although the new value is guaranteed
+  // to be also a NAN.  Therefore, don't expect this constructor to
+  // preserve the bits in x when x is a NAN.
+  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
+
+  // Static methods
+
+  // Reinterprets a bit pattern as a floating-point number.
+  //
+  // This function is needed to test the AlmostEquals() method.
+  static RawType ReinterpretBits(const Bits bits) {
+    FloatingPoint fp(0);
+    fp.u_.bits_ = bits;
+    return fp.u_.value_;
+  }
+
+  // Returns the floating-point number that represent positive infinity.
+  static RawType Infinity() {
+    return ReinterpretBits(kExponentBitMask);
+  }
+
+  // Non-static methods
+
+  // Returns the bits that represents this number.
+  const Bits &bits() const { return u_.bits_; }
+
+  // Returns the exponent bits of this number.
+  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+
+  // Returns the fraction bits of this number.
+  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+
+  // Returns the sign bit of this number.
+  Bits sign_bit() const { return kSignBitMask & u_.bits_; }
+
+  // Returns true iff this is NAN (not a number).
+  bool is_nan() const {
+    // It's a NAN if the exponent bits are all ones and the fraction
+    // bits are not entirely zeros.
+    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
+  }
+
+  // Returns true iff this number is at most kMaxUlps ULP's away from
+  // rhs.  In particular, this function:
+  //
+  //   - returns false if either number is (or both are) NAN.
+  //   - treats really large numbers as almost equal to infinity.
+  //   - thinks +0.0 and -0.0 are 0 DLP's apart.
+  bool AlmostEquals(const FloatingPoint& rhs) const {
+    // The IEEE standard says that any comparison operation involving
+    // a NAN must return false.
+    if (is_nan() || rhs.is_nan()) return false;
+
+    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)
+        <= kMaxUlps;
+  }
+
+ private:
+  // The data type used to store the actual floating-point number.
+  union FloatingPointUnion {
+    RawType value_;  // The raw floating-point number.
+    Bits bits_;      // The bits that represent the number.
+  };
+
+  // Converts an integer from the sign-and-magnitude representation to
+  // the biased representation.  More precisely, let N be 2 to the
+  // power of (kBitCount - 1), an integer x is represented by the
+  // unsigned number x + N.
+  //
+  // For instance,
+  //
+  //   -N + 1 (the most negative number representable using
+  //          sign-and-magnitude) is represented by 1;
+  //   0      is represented by N; and
+  //   N - 1  (the biggest number representable using
+  //          sign-and-magnitude) is represented by 2N - 1.
+  //
+  // Read http://en.wikipedia.org/wiki/Signed_number_representations
+  // for more details on signed number representations.
+  static Bits SignAndMagnitudeToBiased(const Bits &sam) {
+    if (kSignBitMask & sam) {
+      // sam represents a negative number.
+      return ~sam + 1;
+    } else {
+      // sam represents a positive number.
+      return kSignBitMask | sam;
+    }
+  }
+
+  // Given two numbers in the sign-and-magnitude representation,
+  // returns the distance between them as an unsigned number.
+  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
+                                                     const Bits &sam2) {
+    const Bits biased1 = SignAndMagnitudeToBiased(sam1);
+    const Bits biased2 = SignAndMagnitudeToBiased(sam2);
+    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+  }
+
+  FloatingPointUnion u_;
+};
+
+// Typedefs the instances of the FloatingPoint template class that we
+// care to use.
+typedef FloatingPoint<float> Float;
+typedef FloatingPoint<double> Double;
+
+// In order to catch the mistake of putting tests that use different
+// test fixture classes in the same test case, we need to assign
+// unique IDs to fixture classes and compare them.  The TypeId type is
+// used to hold such IDs.  The user should treat TypeId as an opaque
+// type: the only operation allowed on TypeId values is to compare
+// them for equality using the == operator.
+typedef const void* TypeId;
+
+template <typename T>
+class TypeIdHelper {
+ public:
+  // dummy_ must not have a const type.  Otherwise an overly eager
+  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
+  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
+  static bool dummy_;
+};
+
+template <typename T>
+bool TypeIdHelper<T>::dummy_ = false;
+
+// GetTypeId<T>() returns the ID of type T.  Different values will be
+// returned for different types.  Calling the function twice with the
+// same type argument is guaranteed to return the same ID.
+template <typename T>
+TypeId GetTypeId() {
+  // The compiler is required to allocate a different
+  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
+  // the template.  Therefore, the address of dummy_ is guaranteed to
+  // be unique.
+  return &(TypeIdHelper<T>::dummy_);
+}
+
+// Returns the type ID of ::testing::Test.  Always call this instead
+// of GetTypeId< ::testing::Test>() to get the type ID of
+// ::testing::Test, as the latter may give the wrong result due to a
+// suspected linker bug when compiling Google Test as a Mac OS X
+// framework.
+GTEST_API_ TypeId GetTestTypeId();
+
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+  virtual ~TestFactoryBase() {}
+
+  // Creates a test instance to run. The instance is both created and destroyed
+  // within TestInfoImpl::Run()
+  virtual Test* CreateTest() = 0;
+
+ protected:
+  TestFactoryBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+  virtual Test* CreateTest() { return new TestClass; }
+};
+
+#if GTEST_OS_WINDOWS
+
+// Predicate-formatters for implementing the HRESULT checking macros
+// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
+// We pass a long instead of HRESULT to avoid causing an
+// include dependency for the HRESULT type.
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+                                            long hr);  // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+                                            long hr);  // NOLINT
+
+#endif  // GTEST_OS_WINDOWS
+
+// Types of SetUpTestCase() and TearDownTestCase() functions.
+typedef void (*SetUpTestCaseFunc)();
+typedef void (*TearDownTestCaseFunc)();
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   type_param        the name of the test's type parameter, or NULL if
+//                     this is not  a typed or a type-parameterized test.
+//   value_param       text representation of the test's value parameter,
+//                     or NULL if this is not a type-parameterized test.
+//   fixture_class_id: ID of the test fixture class
+//   set_up_tc:        pointer to the function that sets up the test case
+//   tear_down_tc:     pointer to the function that tears down the test case
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* type_param,
+    const char* value_param,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory);
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// State of the definition of a type-parameterized test case.
+class GTEST_API_ TypedTestCasePState {
+ public:
+  TypedTestCasePState() : registered_(false) {}
+
+  // Adds the given test name to defined_test_names_ and return true
+  // if the test case hasn't been registered; otherwise aborts the
+  // program.
+  bool AddTestName(const char* file, int line, const char* case_name,
+                   const char* test_name) {
+    if (registered_) {
+      fprintf(stderr, "%s Test %s must be defined before "
+              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+              FormatFileLocation(file, line).c_str(), test_name, case_name);
+      fflush(stderr);
+      posix::Abort();
+    }
+    defined_test_names_.insert(test_name);
+    return true;
+  }
+
+  // Verifies that registered_tests match the test names in
+  // defined_test_names_; returns registered_tests if successful, or
+  // aborts the program otherwise.
+  const char* VerifyRegisteredTestNames(
+      const char* file, int line, const char* registered_tests);
+
+ private:
+  bool registered_;
+  ::std::set<const char*> defined_test_names_;
+};
+
+// Skips to the first non-space char after the first comma in 'str';
+// returns NULL if no comma is found in 'str'.
+inline const char* SkipComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  if (comma == NULL) {
+    return NULL;
+  }
+  while (IsSpace(*(++comma))) {}
+  return comma;
+}
+
+// Returns the prefix of 'str' before the first comma in it; returns
+// the entire string if it contains no comma.
+inline String GetPrefixUntilComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  return comma == NULL ? String(str) : String(str, comma - str);
+}
+
+// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
+// registers a list of type-parameterized tests with Google Test.  The
+// return value is insignificant - we just need to return something
+// such that we can call this function in a namespace scope.
+//
+// Implementation note: The GTEST_TEMPLATE_ macro declares a template
+// template parameter.  It's defined in gtest-type-util.h.
+template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
+class TypeParameterizedTest {
+ public:
+  // 'index' is the index of the test in the type list 'Types'
+  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+  // Types).  Valid values for 'index' are [0, N - 1] where N is the
+  // length of Types.
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names, int index) {
+    typedef typename Types::Head Type;
+    typedef Fixture<Type> FixtureClass;
+    typedef typename GTEST_BIND_(TestSel, Type) TestClass;
+
+    // First, registers the first type-parameterized test in the type
+    // list.
+    MakeAndRegisterTestInfo(
+        String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
+                       case_name, index).c_str(),
+        GetPrefixUntilComma(test_names).c_str(),
+        GetTypeName<Type>().c_str(),
+        NULL,  // No value parameter.
+        GetTypeId<FixtureClass>(),
+        TestClass::SetUpTestCase,
+        TestClass::TearDownTestCase,
+        new TestFactoryImpl<TestClass>);
+
+    // Next, recurses (at compile time) with the tail of the type list.
+    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
+        ::Register(prefix, case_name, test_names, index + 1);
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, class TestSel>
+class TypeParameterizedTest<Fixture, TestSel, Types0> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/, int /*index*/) {
+    return true;
+  }
+};
+
+// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// registers *all combinations* of 'Tests' and 'Types' with Google
+// Test.  The return value is insignificant - we just need to return
+// something such that we can call this function in a namespace scope.
+template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
+class TypeParameterizedTestCase {
+ public:
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names) {
+    typedef typename Tests::Head Head;
+
+    // First, register the first test in 'Test' for each type in 'Types'.
+    TypeParameterizedTest<Fixture, Head, Types>::Register(
+        prefix, case_name, test_names, 0);
+
+    // Next, recurses (at compile time) with the tail of the test list.
+    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
+        ::Register(prefix, case_name, SkipComma(test_names));
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, typename Types>
+class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/) {
+    return true;
+  }
+};
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+                                                  int skip_count);
+
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
+
+// Always returns true.
+GTEST_API_ bool AlwaysTrue();
+
+// Always returns false.
+inline bool AlwaysFalse() { return !AlwaysTrue(); }
+
+// Helper for suppressing false warning from Clang on a const char*
+// variable declared in a conditional expression always being NULL in
+// the else branch.
+struct GTEST_API_ ConstCharPtr {
+  ConstCharPtr(const char* str) : value(str) {}
+  operator bool() const { return true; }
+  const char* value;
+};
+
+// A simple Linear Congruential Generator for generating random
+// numbers with a uniform distribution.  Unlike rand() and srand(), it
+// doesn't use global state (and therefore can't interfere with user
+// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,
+// but it's good enough for our purposes.
+class GTEST_API_ Random {
+ public:
+  static const UInt32 kMaxRange = 1u << 31;
+
+  explicit Random(UInt32 seed) : state_(seed) {}
+
+  void Reseed(UInt32 seed) { state_ = seed; }
+
+  // Generates a random number from [0, range).  Crashes if 'range' is
+  // 0 or greater than kMaxRange.
+  UInt32 Generate(UInt32 range);
+
+ private:
+  UInt32 state_;
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
+};
+
+// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
+// compiler error iff T1 and T2 are different types.
+template <typename T1, typename T2>
+struct CompileAssertTypesEqual;
+
+template <typename T>
+struct CompileAssertTypesEqual<T, T> {
+};
+
+// Removes the reference from a type if it is a reference type,
+// otherwise leaves it unchanged.  This is the same as
+// tr1::remove_reference, which is not widely available yet.
+template <typename T>
+struct RemoveReference { typedef T type; };  // NOLINT
+template <typename T>
+struct RemoveReference<T&> { typedef T type; };  // NOLINT
+
+// A handy wrapper around RemoveReference that works when the argument
+// T depends on template parameters.
+#define GTEST_REMOVE_REFERENCE_(T) \
+    typename ::testing::internal::RemoveReference<T>::type
+
+// Removes const from a type if it is a const type, otherwise leaves
+// it unchanged.  This is the same as tr1::remove_const, which is not
+// widely available yet.
+template <typename T>
+struct RemoveConst { typedef T type; };  // NOLINT
+template <typename T>
+struct RemoveConst<const T> { typedef T type; };  // NOLINT
+
+// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
+// definition to fail to remove the const in 'const int[3]' and 'const
+// char[3][4]'.  The following specialization works around the bug.
+// However, it causes trouble with GCC and thus needs to be
+// conditionally compiled.
+#if defined(_MSC_VER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+template <typename T, size_t N>
+struct RemoveConst<const T[N]> {
+  typedef typename RemoveConst<T>::type type[N];
+};
+#endif
+
+// A handy wrapper around RemoveConst that works when the argument
+// T depends on template parameters.
+#define GTEST_REMOVE_CONST_(T) \
+    typename ::testing::internal::RemoveConst<T>::type
+
+// Turns const U&, U&, const U, and U all into U.
+#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
+    GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
+
+// Adds reference to a type if it is not a reference type,
+// otherwise leaves it unchanged.  This is the same as
+// tr1::add_reference, which is not widely available yet.
+template <typename T>
+struct AddReference { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddReference<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper around AddReference that works when the argument T
+// depends on template parameters.
+#define GTEST_ADD_REFERENCE_(T) \
+    typename ::testing::internal::AddReference<T>::type
+
+// Adds a reference to const on top of T as necessary.  For example,
+// it transforms
+//
+//   char         ==> const char&
+//   const char   ==> const char&
+//   char&        ==> const char&
+//   const char&  ==> const char&
+//
+// The argument T must depend on some template parameters.
+#define GTEST_REFERENCE_TO_CONST_(T) \
+    GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))
+
+// ImplicitlyConvertible<From, To>::value is a compile-time bool
+// constant that's true iff type From can be implicitly converted to
+// type To.
+template <typename From, typename To>
+class ImplicitlyConvertible {
+ private:
+  // We need the following helper functions only for their types.
+  // They have no implementations.
+
+  // MakeFrom() is an expression whose type is From.  We cannot simply
+  // use From(), as the type From may not have a public default
+  // constructor.
+  static From MakeFrom();
+
+  // These two functions are overloaded.  Given an expression
+  // Helper(x), the compiler will pick the first version if x can be
+  // implicitly converted to type To; otherwise it will pick the
+  // second version.
+  //
+  // The first version returns a value of size 1, and the second
+  // version returns a value of size 2.  Therefore, by checking the
+  // size of Helper(x), which can be done at compile time, we can tell
+  // which version of Helper() is used, and hence whether x can be
+  // implicitly converted to type To.
+  static char Helper(To);
+  static char (&Helper(...))[2];  // NOLINT
+
+  // We have to put the 'public' section after the 'private' section,
+  // or MSVC refuses to compile the code.
+ public:
+  // MSVC warns about implicitly converting from double to int for
+  // possible loss of data, so we need to temporarily disable the
+  // warning.
+#ifdef _MSC_VER
+# pragma warning(push)          // Saves the current warning state.
+# pragma warning(disable:4244)  // Temporarily disables warning 4244.
+
+  static const bool value =
+      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
+# pragma warning(pop)           // Restores the warning state.
+#elif defined(__BORLANDC__)
+  // C++Builder cannot use member overload resolution during template
+  // instantiation.  The simplest workaround is to use its C++0x type traits
+  // functions (C++Builder 2009 and above only).
+  static const bool value = __is_convertible(From, To);
+#else
+  static const bool value =
+      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
+#endif  // _MSV_VER
+};
+template <typename From, typename To>
+const bool ImplicitlyConvertible<From, To>::value;
+
+// IsAProtocolMessage<T>::value is a compile-time bool constant that's
+// true iff T is type ProtocolMessage, proto2::Message, or a subclass
+// of those.
+template <typename T>
+struct IsAProtocolMessage
+    : public bool_constant<
+  ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
+  ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
+};
+
+// When the compiler sees expression IsContainerTest<C>(0), if C is an
+// STL-style container class, the first overload of IsContainerTest
+// will be viable (since both C::iterator* and C::const_iterator* are
+// valid types and NULL can be implicitly converted to them).  It will
+// be picked over the second overload as 'int' is a perfect match for
+// the type of argument 0.  If C::iterator or C::const_iterator is not
+// a valid type, the first overload is not viable, and the second
+// overload will be picked.  Therefore, we can determine whether C is
+// a container class by checking the type of IsContainerTest<C>(0).
+// The value of the expression is insignificant.
+//
+// Note that we look for both C::iterator and C::const_iterator.  The
+// reason is that C++ injects the name of a class as a member of the
+// class itself (e.g. you can refer to class iterator as either
+// 'iterator' or 'iterator::iterator').  If we look for C::iterator
+// only, for example, we would mistakenly think that a class named
+// iterator is an STL container.
+//
+// Also note that the simpler approach of overloading
+// IsContainerTest(typename C::const_iterator*) and
+// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
+typedef int IsContainer;
+template <class C>
+IsContainer IsContainerTest(int /* dummy */,
+                            typename C::iterator* /* it */ = NULL,
+                            typename C::const_iterator* /* const_it */ = NULL) {
+  return 0;
+}
+
+typedef char IsNotContainer;
+template <class C>
+IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; }
+
+// EnableIf<condition>::type is void when 'Cond' is true, and
+// undefined when 'Cond' is false.  To use SFINAE to make a function
+// overload only apply when a particular expression is true, add
+// "typename EnableIf<expression>::type* = 0" as the last parameter.
+template<bool> struct EnableIf;
+template<> struct EnableIf<true> { typedef void type; };  // NOLINT
+
+// Utilities for native arrays.
+
+// ArrayEq() compares two k-dimensional native arrays using the
+// elements' operator==, where k can be any integer >= 0.  When k is
+// 0, ArrayEq() degenerates into comparing a single pair of values.
+
+template <typename T, typename U>
+bool ArrayEq(const T* lhs, size_t size, const U* rhs);
+
+// This generic version is used when k is 0.
+template <typename T, typename U>
+inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; }
+
+// This overload is used when k >= 1.
+template <typename T, typename U, size_t N>
+inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) {
+  return internal::ArrayEq(lhs, N, rhs);
+}
+
+// This helper reduces code bloat.  If we instead put its logic inside
+// the previous ArrayEq() function, arrays with different sizes would
+// lead to different copies of the template code.
+template <typename T, typename U>
+bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
+  for (size_t i = 0; i != size; i++) {
+    if (!internal::ArrayEq(lhs[i], rhs[i]))
+      return false;
+  }
+  return true;
+}
+
+// Finds the first element in the iterator range [begin, end) that
+// equals elem.  Element may be a native array type itself.
+template <typename Iter, typename Element>
+Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
+  for (Iter it = begin; it != end; ++it) {
+    if (internal::ArrayEq(*it, elem))
+      return it;
+  }
+  return end;
+}
+
+// CopyArray() copies a k-dimensional native array using the elements'
+// operator=, where k can be any integer >= 0.  When k is 0,
+// CopyArray() degenerates into copying a single value.
+
+template <typename T, typename U>
+void CopyArray(const T* from, size_t size, U* to);
+
+// This generic version is used when k is 0.
+template <typename T, typename U>
+inline void CopyArray(const T& from, U* to) { *to = from; }
+
+// This overload is used when k >= 1.
+template <typename T, typename U, size_t N>
+inline void CopyArray(const T(&from)[N], U(*to)[N]) {
+  internal::CopyArray(from, N, *to);
+}
+
+// This helper reduces code bloat.  If we instead put its logic inside
+// the previous CopyArray() function, arrays with different sizes
+// would lead to different copies of the template code.
+template <typename T, typename U>
+void CopyArray(const T* from, size_t size, U* to) {
+  for (size_t i = 0; i != size; i++) {
+    internal::CopyArray(from[i], to + i);
+  }
+}
+
+// The relation between an NativeArray object (see below) and the
+// native array it represents.
+enum RelationToSource {
+  kReference,  // The NativeArray references the native array.
+  kCopy        // The NativeArray makes a copy of the native array and
+               // owns the copy.
+};
+
+// Adapts a native array to a read-only STL-style container.  Instead
+// of the complete STL container concept, this adaptor only implements
+// members useful for Google Mock's container matchers.  New members
+// should be added as needed.  To simplify the implementation, we only
+// support Element being a raw type (i.e. having no top-level const or
+// reference modifier).  It's the client's responsibility to satisfy
+// this requirement.  Element can be an array type itself (hence
+// multi-dimensional arrays are supported).
+template <typename Element>
+class NativeArray {
+ public:
+  // STL-style container typedefs.
+  typedef Element value_type;
+  typedef Element* iterator;
+  typedef const Element* const_iterator;
+
+  // Constructs from a native array.
+  NativeArray(const Element* array, size_t count, RelationToSource relation) {
+    Init(array, count, relation);
+  }
+
+  // Copy constructor.
+  NativeArray(const NativeArray& rhs) {
+    Init(rhs.array_, rhs.size_, rhs.relation_to_source_);
+  }
+
+  ~NativeArray() {
+    // Ensures that the user doesn't instantiate NativeArray with a
+    // const or reference type.
+    static_cast<void>(StaticAssertTypeEqHelper<Element,
+        GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>());
+    if (relation_to_source_ == kCopy)
+      delete[] array_;
+  }
+
+  // STL-style container methods.
+  size_t size() const { return size_; }
+  const_iterator begin() const { return array_; }
+  const_iterator end() const { return array_ + size_; }
+  bool operator==(const NativeArray& rhs) const {
+    return size() == rhs.size() &&
+        ArrayEq(begin(), size(), rhs.begin());
+  }
+
+ private:
+  // Initializes this object; makes a copy of the input array if
+  // 'relation' is kCopy.
+  void Init(const Element* array, size_t a_size, RelationToSource relation) {
+    if (relation == kReference) {
+      array_ = array;
+    } else {
+      Element* const copy = new Element[a_size];
+      CopyArray(array, a_size, copy);
+      array_ = copy;
+    }
+    size_ = a_size;
+    relation_to_source_ = relation;
+  }
+
+  const Element* array_;
+  size_t size_;
+  RelationToSource relation_to_source_;
+
+  GTEST_DISALLOW_ASSIGN_(NativeArray);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
+  ::testing::internal::AssertHelper(result_type, file, line, message) \
+    = ::testing::Message()
+
+#define GTEST_MESSAGE_(message, result_type) \
+  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
+
+#define GTEST_FATAL_FAILURE_(message) \
+  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define GTEST_SUCCESS_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
+
+// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+// statement if it returns or throws (or doesn't return or throw in some
+// situations).
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
+  if (::testing::internal::AlwaysTrue()) { statement; }
+
+#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::ConstCharPtr gtest_msg = "") { \
+    bool gtest_caught_expected = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (expected_exception const&) { \
+      gtest_caught_expected = true; \
+    } \
+    catch (...) { \
+      gtest_msg.value = \
+          "Expected: " #statement " throws an exception of type " \
+          #expected_exception ".\n  Actual: it throws a different type."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+    if (!gtest_caught_expected) { \
+      gtest_msg.value = \
+          "Expected: " #statement " throws an exception of type " \
+          #expected_exception ".\n  Actual: it throws nothing."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
+      fail(gtest_msg.value)
+
+#define GTEST_TEST_NO_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::AlwaysTrue()) { \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
+      fail("Expected: " #statement " doesn't throw an exception.\n" \
+           "  Actual: it throws.")
+
+#define GTEST_TEST_ANY_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::AlwaysTrue()) { \
+    bool gtest_caught_any = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_caught_any = true; \
+    } \
+    if (!gtest_caught_any) { \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \
+      fail("Expected: " #statement " throws an exception.\n" \
+           "  Actual: it doesn't.")
+
+
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar_ = \
+      ::testing::AssertionResult(expression)) \
+    ; \
+  else \
+    fail(::testing::internal::GetBoolAssertionFailureMessage(\
+        gtest_ar_, text, #actual, #expected).c_str())
+
+#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::AlwaysTrue()) { \
+    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \
+      fail("Expected: " #statement " doesn't generate new fatal " \
+           "failures in the current thread.\n" \
+           "  Actual: it does.")
+
+// Expands to the name of the class that implements the given test.
+#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+  test_case_name##_##test_name##_Test
+
+// Helper macro for defining tests.
+#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
+class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
+ public:\
+  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
+ private:\
+  virtual void TestBody();\
+  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
+};\
+\
+::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
+  ::test_info_ =\
+    ::testing::internal::MakeAndRegisterTestInfo(\
+        #test_case_name, #test_name, NULL, NULL, \
+        (parent_id), \
+        parent_class::SetUpTestCase, \
+        parent_class::TearDownTestCase, \
+        new ::testing::internal::TestFactoryImpl<\
+            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
+void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for death tests.  It is
+// #included by gtest.h so a user doesn't need to include this
+// directly.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines internal utilities needed for implementing
+// death tests.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+
+#include <stdio.h>
+
+namespace testing {
+namespace internal {
+
+GTEST_DECLARE_string_(internal_run_death_test);
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kDeathTestStyleFlag[] = "death_test_style";
+const char kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if GTEST_HAS_DEATH_TEST
+
+// DeathTest is a class that hides much of the complexity of the
+// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method
+// returns a concrete class that depends on the prevailing death test
+// style, as defined by the --gtest_death_test_style and/or
+// --gtest_internal_run_death_test flags.
+
+// In describing the results of death tests, these terms are used with
+// the corresponding definitions:
+//
+// exit status:  The integer exit information in the format specified
+//               by wait(2)
+// exit code:    The integer code passed to exit(3), _exit(2), or
+//               returned from main()
+class GTEST_API_ DeathTest {
+ public:
+  // Create returns false if there was an error determining the
+  // appropriate action to take for the current death test; for example,
+  // if the gtest_death_test_style flag is set to an invalid value.
+  // The LastMessage method will return a more detailed message in that
+  // case.  Otherwise, the DeathTest pointer pointed to by the "test"
+  // argument is set.  If the death test should be skipped, the pointer
+  // is set to NULL; otherwise, it is set to the address of a new concrete
+  // DeathTest object that controls the execution of the current test.
+  static bool Create(const char* statement, const RE* regex,
+                     const char* file, int line, DeathTest** test);
+  DeathTest();
+  virtual ~DeathTest() { }
+
+  // A helper class that aborts a death test when it's deleted.
+  class ReturnSentinel {
+   public:
+    explicit ReturnSentinel(DeathTest* test) : test_(test) { }
+    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
+   private:
+    DeathTest* const test_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
+  } GTEST_ATTRIBUTE_UNUSED_;
+
+  // An enumeration of possible roles that may be taken when a death
+  // test is encountered.  EXECUTE means that the death test logic should
+  // be executed immediately.  OVERSEE means that the program should prepare
+  // the appropriate environment for a child process to execute the death
+  // test, then wait for it to complete.
+  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
+
+  // An enumeration of the three reasons that a test might be aborted.
+  enum AbortReason {
+    TEST_ENCOUNTERED_RETURN_STATEMENT,
+    TEST_THREW_EXCEPTION,
+    TEST_DID_NOT_DIE
+  };
+
+  // Assumes one of the above roles.
+  virtual TestRole AssumeRole() = 0;
+
+  // Waits for the death test to finish and returns its status.
+  virtual int Wait() = 0;
+
+  // Returns true if the death test passed; that is, the test process
+  // exited during the test, its exit status matches a user-supplied
+  // predicate, and its stderr output matches a user-supplied regular
+  // expression.
+  // The user-supplied predicate may be a macro expression rather
+  // than a function pointer or functor, or else Wait and Passed could
+  // be combined.
+  virtual bool Passed(bool exit_status_ok) = 0;
+
+  // Signals that the death test did not die as expected.
+  virtual void Abort(AbortReason reason) = 0;
+
+  // Returns a human-readable outcome message regarding the outcome of
+  // the last death test.
+  static const char* LastMessage();
+
+  static void set_last_death_test_message(const String& message);
+
+ private:
+  // A string containing a description of the outcome of the last death test.
+  static String last_death_test_message_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
+};
+
+// Factory interface for death tests.  May be mocked out for testing.
+class DeathTestFactory {
+ public:
+  virtual ~DeathTestFactory() { }
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test) = 0;
+};
+
+// A concrete DeathTestFactory implementation for normal use.
+class DefaultDeathTestFactory : public DeathTestFactory {
+ public:
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test);
+};
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+
+// Traps C++ exceptions escaping statement and reports them as test
+// failures. Note that trapping SEH exceptions is not implemented here.
+# if GTEST_HAS_EXCEPTIONS
+#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+  try { \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+  } catch (const ::std::exception& gtest_exception) { \
+    fprintf(\
+        stderr, \
+        "\n%s: Caught std::exception-derived exception escaping the " \
+        "death test statement. Exception message: %s\n", \
+        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
+        gtest_exception.what()); \
+    fflush(stderr); \
+    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+  } catch (...) { \
+    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+  }
+
+# else
+#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+
+# endif
+
+// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
+// ASSERT_EXIT*, and EXPECT_EXIT*.
+# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (::testing::internal::AlwaysTrue()) { \
+    const ::testing::internal::RE& gtest_regex = (regex); \
+    ::testing::internal::DeathTest* gtest_dt; \
+    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
+        __FILE__, __LINE__, &gtest_dt)) { \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+    } \
+    if (gtest_dt != NULL) { \
+      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
+          gtest_dt_ptr(gtest_dt); \
+      switch (gtest_dt->AssumeRole()) { \
+        case ::testing::internal::DeathTest::OVERSEE_TEST: \
+          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
+            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+          } \
+          break; \
+        case ::testing::internal::DeathTest::EXECUTE_TEST: { \
+          ::testing::internal::DeathTest::ReturnSentinel \
+              gtest_sentinel(gtest_dt); \
+          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
+          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
+          break; \
+        } \
+        default: \
+          break; \
+      } \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
+      fail(::testing::internal::DeathTest::LastMessage())
+// The symbol "fail" here expands to something into which a message
+// can be streamed.
+
+// A class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+  InternalRunDeathTestFlag(const String& a_file,
+                           int a_line,
+                           int an_index,
+                           int a_write_fd)
+      : file_(a_file), line_(a_line), index_(an_index),
+        write_fd_(a_write_fd) {}
+
+  ~InternalRunDeathTestFlag() {
+    if (write_fd_ >= 0)
+      posix::Close(write_fd_);
+  }
+
+  String file() const { return file_; }
+  int line() const { return line_; }
+  int index() const { return index_; }
+  int write_fd() const { return write_fd_; }
+
+ private:
+  String file_;
+  int line_;
+  int index_;
+  int write_fd_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
+
+#else  // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system.
+//
+// Parameters:
+//   statement -  A statement that a macro such as EXPECT_DEATH would test
+//                for program termination. This macro has to make sure this
+//                statement is compiled but not executed, to ensure that
+//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+//                parameter iff EXPECT_DEATH compiles with it.
+//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
+//                the output of statement.  This parameter has to be
+//                compiled but not evaluated by this macro, to ensure that
+//                this macro only accepts expressions that a macro such as
+//                EXPECT_DEATH would accept.
+//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+//                compile inside functions where ASSERT_DEATH doesn't
+//                compile.
+//
+//  The branch that has an always false condition is used to ensure that
+//  statement and regex are compiled (and thus syntactically correct) but
+//  never executed. The unreachable code macro protects the terminator
+//  statement from generating an 'unreachable code' warning in case
+//  statement unconditionally returns or throws. The Message constructor at
+//  the end allows the syntax of streaming additional messages into the
+//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::AlwaysTrue()) { \
+      GTEST_LOG_(WARNING) \
+          << "Death tests are not supported on this platform.\n" \
+          << "Statement '" #statement "' cannot be verified."; \
+    } else if (::testing::internal::AlwaysFalse()) { \
+      ::testing::internal::RE::PartialMatch(".*", (regex)); \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+      terminator; \
+    } else \
+      ::testing::Message()
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+namespace testing {
+
+// This flag controls the style of death tests.  Valid values are "threadsafe",
+// meaning that the death test child process will re-execute the test binary
+// from the start, running only a single death test, or "fast",
+// meaning that the child process will execute the test logic immediately
+// after forking.
+GTEST_DECLARE_string_(death_test_style);
+
+#if GTEST_HAS_DEATH_TEST
+
+// The following macros are useful for writing death tests.
+
+// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
+// executed:
+//
+//   1. It generates a warning if there is more than one active
+//   thread.  This is because it's safe to fork() or clone() only
+//   when there is a single thread.
+//
+//   2. The parent process clone()s a sub-process and runs the death
+//   test in it; the sub-process exits with code 0 at the end of the
+//   death test, if it hasn't exited already.
+//
+//   3. The parent process waits for the sub-process to terminate.
+//
+//   4. The parent process checks the exit code and error message of
+//   the sub-process.
+//
+// Examples:
+//
+//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
+//   for (int i = 0; i < 5; i++) {
+//     EXPECT_DEATH(server.ProcessRequest(i),
+//                  "Invalid request .* in ProcessRequest()")
+//         << "Failed to die on request " << i);
+//   }
+//
+//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
+//
+//   bool KilledBySIGHUP(int exit_code) {
+//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
+//   }
+//
+//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
+//
+// On the regular expressions used in death tests:
+//
+//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
+//   which uses the POSIX extended regex syntax.
+//
+//   On other platforms (e.g. Windows), we only support a simple regex
+//   syntax implemented as part of Google Test.  This limited
+//   implementation should be enough most of the time when writing
+//   death tests; though it lacks many features you can find in PCRE
+//   or POSIX extended regex syntax.  For example, we don't support
+//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+//   repetition count ("x{5,7}"), among others.
+//
+//   Below is the syntax that we do support.  We chose it to be a
+//   subset of both PCRE and POSIX extended regex, so it's easy to
+//   learn wherever you come from.  In the following: 'A' denotes a
+//   literal character, period (.), or a single \\ escape sequence;
+//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
+//   natural numbers.
+//
+//     c     matches any literal character c
+//     \\d   matches any decimal digit
+//     \\D   matches any character that's not a decimal digit
+//     \\f   matches \f
+//     \\n   matches \n
+//     \\r   matches \r
+//     \\s   matches any ASCII whitespace, including \n
+//     \\S   matches any character that's not a whitespace
+//     \\t   matches \t
+//     \\v   matches \v
+//     \\w   matches any letter, _, or decimal digit
+//     \\W   matches any character that \\w doesn't match
+//     \\c   matches any literal character c, which must be a punctuation
+//     .     matches any single character except \n
+//     A?    matches 0 or 1 occurrences of A
+//     A*    matches 0 or many occurrences of A
+//     A+    matches 1 or many occurrences of A
+//     ^     matches the beginning of a string (not that of each line)
+//     $     matches the end of a string (not that of each line)
+//     xy    matches x followed by y
+//
+//   If you accidentally use PCRE or POSIX extended regex features
+//   not implemented by us, you will get a run-time failure.  In that
+//   case, please try to rewrite your regular expression within the
+//   above syntax.
+//
+//   This implementation is *not* meant to be as highly tuned or robust
+//   as a compiled regex library, but should perform well enough for a
+//   death test, which already incurs significant overhead by launching
+//   a child process.
+//
+// Known caveats:
+//
+//   A "threadsafe" style death test obtains the path to the test
+//   program from argv[0] and re-executes it in the sub-process.  For
+//   simplicity, the current implementation doesn't search the PATH
+//   when launching the sub-process.  This means that the user must
+//   invoke the test program via a path that contains at least one
+//   path separator (e.g. path/to/foo_test and
+//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
+//   is rarely a problem as people usually don't put the test binary
+//   directory in PATH.
+//
+// TODO(wan@google.com): make thread-safe death tests search the PATH.
+
+// Asserts that a given statement causes the program to exit, with an
+// integer exit status that satisfies predicate, and emitting error output
+// that matches regex.
+# define ASSERT_EXIT(statement, predicate, regex) \
+    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
+
+// Like ASSERT_EXIT, but continues on to successive tests in the
+// test case, if any:
+# define EXPECT_EXIT(statement, predicate, regex) \
+    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
+
+// Asserts that a given statement causes the program to exit, either by
+// explicitly exiting with a nonzero exit code or being killed by a
+// signal, and emitting error output that matches regex.
+# define ASSERT_DEATH(statement, regex) \
+    ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Like ASSERT_DEATH, but continues on to successive tests in the
+// test case, if any:
+# define EXPECT_DEATH(statement, regex) \
+    EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
+
+// Tests that an exit code describes a normal exit with a given exit code.
+class GTEST_API_ ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ExitedWithCode& other);
+
+  const int exit_code_;
+};
+
+# if !GTEST_OS_WINDOWS
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class GTEST_API_ KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+# endif  // !GTEST_OS_WINDOWS
+
+// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
+// The death testing framework causes this to have interesting semantics,
+// since the sideeffects of the call are only visible in opt mode, and not
+// in debug mode.
+//
+// In practice, this can be used to test functions that utilize the
+// LOG(DFATAL) macro using the following style:
+//
+// int DieInDebugOr12(int* sideeffect) {
+//   if (sideeffect) {
+//     *sideeffect = 12;
+//   }
+//   LOG(DFATAL) << "death";
+//   return 12;
+// }
+//
+// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
+//   int sideeffect = 0;
+//   // Only asserts in dbg.
+//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
+//
+// #ifdef NDEBUG
+//   // opt-mode has sideeffect visible.
+//   EXPECT_EQ(12, sideeffect);
+// #else
+//   // dbg-mode no visible sideeffect.
+//   EXPECT_EQ(0, sideeffect);
+// #endif
+// }
+//
+// This will assert that DieInDebugReturn12InOpt() crashes in debug
+// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
+// appropriate fallback value (12 in this case) in opt mode. If you
+// need to test that a function has appropriate side-effects in opt
+// mode, include assertions against the side-effects.  A general
+// pattern for this is:
+//
+// EXPECT_DEBUG_DEATH({
+//   // Side-effects here will have an effect after this statement in
+//   // opt mode, but none in debug mode.
+//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
+// }, "death");
+//
+# ifdef NDEBUG
+
+#  define EXPECT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+#  define ASSERT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+# else
+
+#  define EXPECT_DEBUG_DEATH(statement, regex) \
+  EXPECT_DEATH(statement, regex)
+
+#  define ASSERT_DEBUG_DEATH(statement, regex) \
+  ASSERT_DEATH(statement, regex)
+
+# endif  // NDEBUG for EXPECT_DEBUG_DEATH
+#endif  // GTEST_HAS_DEATH_TEST
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning.  This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    EXPECT_DEATH(statement, regex)
+# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    ASSERT_DEATH(statement, regex)
+#else
+# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+#endif
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the Message class.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+
+#include <limits>
+
+
+namespace testing {
+
+// The Message class works like an ostream repeater.
+//
+// Typical usage:
+//
+//   1. You stream a bunch of values to a Message object.
+//      It will remember the text in a stringstream.
+//   2. Then you stream the Message object to an ostream.
+//      This causes the text in the Message to be streamed
+//      to the ostream.
+//
+// For example;
+//
+//   testing::Message foo;
+//   foo << 1 << " != " << 2;
+//   std::cout << foo;
+//
+// will print "1 != 2".
+//
+// Message is not intended to be inherited from.  In particular, its
+// destructor is not virtual.
+//
+// Note that stringstream behaves differently in gcc and in MSVC.  You
+// can stream a NULL char pointer to it in the former, but not in the
+// latter (it causes an access violation if you do).  The Message
+// class hides this difference by treating a NULL char pointer as
+// "(null)".
+class GTEST_API_ Message {
+ private:
+  // The type of basic IO manipulators (endl, ends, and flush) for
+  // narrow streams.
+  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
+
+ public:
+  // Constructs an empty Message.
+  // We allocate the stringstream separately because otherwise each use of
+  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
+  // stack frame leading to huge stack frames in some cases; gcc does not reuse
+  // the stack space.
+  Message() : ss_(new ::std::stringstream) {
+    // By default, we want there to be enough precision when printing
+    // a double to a Message.
+    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+  }
+
+  // Copy constructor.
+  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT
+    *ss_ << msg.GetString();
+  }
+
+  // Constructs a Message from a C-string.
+  explicit Message(const char* str) : ss_(new ::std::stringstream) {
+    *ss_ << str;
+  }
+
+#if GTEST_OS_SYMBIAN
+  // Streams a value (either a pointer or not) to this object.
+  template <typename T>
+  inline Message& operator <<(const T& value) {
+    StreamHelper(typename internal::is_pointer<T>::type(), value);
+    return *this;
+  }
+#else
+  // Streams a non-pointer value to this object.
+  template <typename T>
+  inline Message& operator <<(const T& val) {
+    ::GTestStreamToHelper(ss_.get(), val);
+    return *this;
+  }
+
+  // Streams a pointer value to this object.
+  //
+  // This function is an overload of the previous one.  When you
+  // stream a pointer to a Message, this definition will be used as it
+  // is more specialized.  (The C++ Standard, section
+  // [temp.func.order].)  If you stream a non-pointer, then the
+  // previous definition will be used.
+  //
+  // The reason for this overload is that streaming a NULL pointer to
+  // ostream is undefined behavior.  Depending on the compiler, you
+  // may get "0", "(nil)", "(null)", or an access violation.  To
+  // ensure consistent result across compilers, we always treat NULL
+  // as "(null)".
+  template <typename T>
+  inline Message& operator <<(T* const& pointer) {  // NOLINT
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_.get(), pointer);
+    }
+    return *this;
+  }
+#endif  // GTEST_OS_SYMBIAN
+
+  // Since the basic IO manipulators are overloaded for both narrow
+  // and wide streams, we have to provide this specialized definition
+  // of operator <<, even though its body is the same as the
+  // templatized version above.  Without this definition, streaming
+  // endl or other basic IO manipulators to Message will confuse the
+  // compiler.
+  Message& operator <<(BasicNarrowIoManip val) {
+    *ss_ << val;
+    return *this;
+  }
+
+  // Instead of 1/0, we want to see true/false for bool values.
+  Message& operator <<(bool b) {
+    return *this << (b ? "true" : "false");
+  }
+
+  // These two overloads allow streaming a wide C string to a Message
+  // using the UTF-8 encoding.
+  Message& operator <<(const wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+  Message& operator <<(wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+
+#if GTEST_HAS_STD_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::std::wstring& wstr);
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::wstring& wstr);
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+  // Gets the text streamed to this object so far as a String.
+  // Each '\0' character in the buffer is replaced with "\\0".
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::String GetString() const {
+    return internal::StringStreamToString(ss_.get());
+  }
+
+ private:
+
+#if GTEST_OS_SYMBIAN
+  // These are needed as the Nokia Symbian Compiler cannot decide between
+  // const T& and const T* in a function template. The Nokia compiler _can_
+  // decide between class template specializations for T and T*, so a
+  // tr1::type_traits-like is_pointer works, and we can overload on that.
+  template <typename T>
+  inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_.get(), pointer);
+    }
+  }
+  template <typename T>
+  inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
+    ::GTestStreamToHelper(ss_.get(), value);
+  }
+#endif  // GTEST_OS_SYMBIAN
+
+  // We'll hold the text streamed to this object here.
+  const internal::scoped_ptr< ::std::stringstream> ss_;
+
+  // We declare (but don't implement) this to prevent the compiler
+  // from implementing the assignment operator.
+  void operator=(const Message&);
+};
+
+// Streams a Message to an ostream.
+inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
+  return os << sb.GetString();
+}
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+// This file was GENERATED by command:
+//     pump.py gtest-param-test.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It is usually derived from testing::TestWithParam<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> is itself derived from testing::Test. T can be any
+// copyable type. If it's a raw pointer, you are responsible for managing the
+// lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a  summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+                        FooTest,
+                        Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+//
+//
+// A parameterized test fixture must be derived from testing::Test and from
+// testing::WithParamInterface<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> inherits from both Test and WithParamInterface. In more
+// complicated hierarchies, however, it is occasionally useful to inherit
+// separately from Test and WithParamInterface. For example:
+
+class BaseTest : public ::testing::Test {
+  // You can inherit all the usual members for a non-parameterized test
+  // fixture here.
+};
+
+class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
+  // The usual test fixture members go here too.
+};
+
+TEST_F(BaseTest, HasFoo) {
+  // This is an ordinary non-parameterized test.
+}
+
+TEST_P(DerivedTest, DoesBlah) {
+  // GetParam works just the same here as if you inherit from TestWithParam.
+  EXPECT_TRUE(foo.Blah(GetParam()));
+}
+
+#endif  // 0
+
+
+#if !GTEST_OS_SYMBIAN
+# include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// Copyright 2003 Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Dan Egnor (egnor@google.com)
+//
+// A "smart" pointer type with reference tracking.  Every pointer to a
+// particular object is kept on a circular linked list.  When the last pointer
+// to an object is destroyed or reassigned, the object is deleted.
+//
+// Used properly, this deletes the object when the last reference goes away.
+// There are several caveats:
+// - Like all reference counting schemes, cycles lead to leaks.
+// - Each smart pointer is actually two pointers (8 bytes instead of 4).
+// - Every time a pointer is assigned, the entire list of pointers to that
+//   object is traversed.  This class is therefore NOT SUITABLE when there
+//   will often be more than two or three pointers to a particular object.
+// - References are only tracked as long as linked_ptr<> objects are copied.
+//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
+//   will happen (double deletion).
+//
+// A good use of this class is storing object references in STL containers.
+// You can safely put linked_ptr<> in a vector<>.
+// Other uses may not be as good.
+//
+// Note: If you use an incomplete type with linked_ptr<>, the class
+// *containing* linked_ptr<> must have a constructor and destructor (even
+// if they do nothing!).
+//
+// Bill Gibbons suggested we use something like this.
+//
+// Thread Safety:
+//   Unlike other linked_ptr implementations, in this implementation
+//   a linked_ptr object is thread-safe in the sense that:
+//     - it's safe to copy linked_ptr objects concurrently,
+//     - it's safe to copy *from* a linked_ptr and read its underlying
+//       raw pointer (e.g. via get()) concurrently, and
+//     - it's safe to write to two linked_ptrs that point to the same
+//       shared object concurrently.
+// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
+// confusion with normal linked_ptr.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+
+namespace testing {
+namespace internal {
+
+// Protects copying of all linked_ptr objects.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// This is used internally by all instances of linked_ptr<>.  It needs to be
+// a non-template class because different types of linked_ptr<> can refer to
+// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
+// So, it needs to be possible for different types of linked_ptr to participate
+// in the same circular linked list, so we need a single class type here.
+//
+// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.
+class linked_ptr_internal {
+ public:
+  // Create a new circle that includes only this instance.
+  void join_new() {
+    next_ = this;
+  }
+
+  // Many linked_ptr operations may change p.link_ for some linked_ptr
+  // variable p in the same circle as this object.  Therefore we need
+  // to prevent two such operations from occurring concurrently.
+  //
+  // Note that different types of linked_ptr objects can coexist in a
+  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
+  // linked_ptr<Derived2>).  Therefore we must use a single mutex to
+  // protect all linked_ptr objects.  This can create serious
+  // contention in production code, but is acceptable in a testing
+  // framework.
+
+  // Join an existing circle.
+  // L < g_linked_ptr_mutex
+  void join(linked_ptr_internal const* ptr) {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    linked_ptr_internal const* p = ptr;
+    while (p->next_ != ptr) p = p->next_;
+    p->next_ = this;
+    next_ = ptr;
+  }
+
+  // Leave whatever circle we're part of.  Returns true if we were the
+  // last member of the circle.  Once this is done, you can join() another.
+  // L < g_linked_ptr_mutex
+  bool depart() {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    if (next_ == this) return true;
+    linked_ptr_internal const* p = next_;
+    while (p->next_ != this) p = p->next_;
+    p->next_ = next_;
+    return false;
+  }
+
+ private:
+  mutable linked_ptr_internal const* next_;
+};
+
+template <typename T>
+class linked_ptr {
+ public:
+  typedef T element_type;
+
+  // Take over ownership of a raw pointer.  This should happen as soon as
+  // possible after the object is created.
+  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
+  ~linked_ptr() { depart(); }
+
+  // Copy an existing linked_ptr<>, adding ourselves to the list of references.
+  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
+  linked_ptr(linked_ptr const& ptr) {  // NOLINT
+    assert(&ptr != this);
+    copy(&ptr);
+  }
+
+  // Assignment releases the old value and acquires the new.
+  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
+    depart();
+    copy(&ptr);
+    return *this;
+  }
+
+  linked_ptr& operator=(linked_ptr const& ptr) {
+    if (&ptr != this) {
+      depart();
+      copy(&ptr);
+    }
+    return *this;
+  }
+
+  // Smart pointer members.
+  void reset(T* ptr = NULL) {
+    depart();
+    capture(ptr);
+  }
+  T* get() const { return value_; }
+  T* operator->() const { return value_; }
+  T& operator*() const { return *value_; }
+
+  bool operator==(T* p) const { return value_ == p; }
+  bool operator!=(T* p) const { return value_ != p; }
+  template <typename U>
+  bool operator==(linked_ptr<U> const& ptr) const {
+    return value_ == ptr.get();
+  }
+  template <typename U>
+  bool operator!=(linked_ptr<U> const& ptr) const {
+    return value_ != ptr.get();
+  }
+
+ private:
+  template <typename U>
+  friend class linked_ptr;
+
+  T* value_;
+  linked_ptr_internal link_;
+
+  void depart() {
+    if (link_.depart()) delete value_;
+  }
+
+  void capture(T* ptr) {
+    value_ = ptr;
+    link_.join_new();
+  }
+
+  template <typename U> void copy(linked_ptr<U> const* ptr) {
+    value_ = ptr->get();
+    if (value_)
+      link_.join(&ptr->link_);
+    else
+      link_.join_new();
+  }
+};
+
+template<typename T> inline
+bool operator==(T* ptr, const linked_ptr<T>& x) {
+  return ptr == x.get();
+}
+
+template<typename T> inline
+bool operator!=(T* ptr, const linked_ptr<T>& x) {
+  return ptr != x.get();
+}
+
+// A function to convert T* into linked_ptr<T>
+// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+linked_ptr<T> make_linked_ptr(T* ptr) {
+  return linked_ptr<T>(ptr);
+}
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Test - The Google C++ Testing Framework
+//
+// This file implements a universal value printer that can print a
+// value of any type T:
+//
+//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
+//
+// A user can teach this function how to print a class type T by
+// defining either operator<<() or PrintTo() in the namespace that
+// defines T.  More specifically, the FIRST defined function in the
+// following list will be used (assuming T is defined in namespace
+// foo):
+//
+//   1. foo::PrintTo(const T&, ostream*)
+//   2. operator<<(ostream&, const T&) defined in either foo or the
+//      global namespace.
+//
+// If none of the above is defined, it will print the debug string of
+// the value if it is a protocol buffer, or print the raw bytes in the
+// value otherwise.
+//
+// To aid debugging: when T is a reference type, the address of the
+// value is also printed; when T is a (const) char pointer, both the
+// pointer value and the NUL-terminated string it points to are
+// printed.
+//
+// We also provide some convenient wrappers:
+//
+//   // Prints a value to a string.  For a (const or not) char
+//   // pointer, the NUL-terminated string (but not the pointer) is
+//   // printed.
+//   std::string ::testing::PrintToString(const T& value);
+//
+//   // Prints a value tersely: for a reference type, the referenced
+//   // value (but not the address) is printed; for a (const or not) char
+//   // pointer, the NUL-terminated string (but not the pointer) is
+//   // printed.
+//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
+//
+//   // Prints value using the type inferred by the compiler.  The difference
+//   // from UniversalTersePrint() is that this function prints both the
+//   // pointer and the NUL-terminated string for a (const or not) char pointer.
+//   void ::testing::internal::UniversalPrint(const T& value, ostream*);
+//
+//   // Prints the fields of a tuple tersely to a string vector, one
+//   // element for each field. Tuple support must be enabled in
+//   // gtest-port.h.
+//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(
+//       const Tuple& value);
+//
+// Known limitation:
+//
+// The print primitives print the elements of an STL-style container
+// using the compiler-inferred type of *iter where iter is a
+// const_iterator of the container.  When const_iterator is an input
+// iterator but not a forward iterator, this inferred type may not
+// match value_type, and the print output may be incorrect.  In
+// practice, this is rarely a problem as for most containers
+// const_iterator is a forward iterator.  We'll fix this if there's an
+// actual need for it.  Note that this fix cannot rely on value_type
+// being defined as many user-defined container types don't have
+// value_type.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
+
+#include <ostream>  // NOLINT
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace testing {
+
+// Definitions in the 'internal' and 'internal2' name spaces are
+// subject to change without notice.  DO NOT USE THEM IN USER CODE!
+namespace internal2 {
+
+// Prints the given number of bytes in the given object to the given
+// ostream.
+GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
+                                     size_t count,
+                                     ::std::ostream* os);
+
+// For selecting which printer to use when a given type has neither <<
+// nor PrintTo().
+enum TypeKind {
+  kProtobuf,              // a protobuf type
+  kConvertibleToInteger,  // a type implicitly convertible to BiggestInt
+                          // (e.g. a named or unnamed enum type)
+  kOtherType              // anything else
+};
+
+// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
+// by the universal printer to print a value of type T when neither
+// operator<< nor PrintTo() is defined for T, where kTypeKind is the
+// "kind" of T as defined by enum TypeKind.
+template <typename T, TypeKind kTypeKind>
+class TypeWithoutFormatter {
+ public:
+  // This default version is called when kTypeKind is kOtherType.
+  static void PrintValue(const T& value, ::std::ostream* os) {
+    PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
+                         sizeof(value), os);
+  }
+};
+
+// We print a protobuf using its ShortDebugString() when the string
+// doesn't exceed this many characters; otherwise we print it using
+// DebugString() for better readability.
+const size_t kProtobufOneLinerMaxLength = 50;
+
+template <typename T>
+class TypeWithoutFormatter<T, kProtobuf> {
+ public:
+  static void PrintValue(const T& value, ::std::ostream* os) {
+    const ::testing::internal::string short_str = value.ShortDebugString();
+    const ::testing::internal::string pretty_str =
+        short_str.length() <= kProtobufOneLinerMaxLength ?
+        short_str : ("\n" + value.DebugString());
+    *os << ("<" + pretty_str + ">");
+  }
+};
+
+template <typename T>
+class TypeWithoutFormatter<T, kConvertibleToInteger> {
+ public:
+  // Since T has no << operator or PrintTo() but can be implicitly
+  // converted to BiggestInt, we print it as a BiggestInt.
+  //
+  // Most likely T is an enum type (either named or unnamed), in which
+  // case printing it as an integer is the desired behavior.  In case
+  // T is not an enum, printing it as an integer is the best we can do
+  // given that it has no user-defined printer.
+  static void PrintValue(const T& value, ::std::ostream* os) {
+    const internal::BiggestInt kBigInt = value;
+    *os << kBigInt;
+  }
+};
+
+// Prints the given value to the given ostream.  If the value is a
+// protocol message, its debug string is printed; if it's an enum or
+// of a type implicitly convertible to BiggestInt, it's printed as an
+// integer; otherwise the bytes in the value are printed.  This is
+// what UniversalPrinter<T>::Print() does when it knows nothing about
+// type T and T has neither << operator nor PrintTo().
+//
+// A user can override this behavior for a class type Foo by defining
+// a << operator in the namespace where Foo is defined.
+//
+// We put this operator in namespace 'internal2' instead of 'internal'
+// to simplify the implementation, as much code in 'internal' needs to
+// use << in STL, which would conflict with our own << were it defined
+// in 'internal'.
+//
+// Note that this operator<< takes a generic std::basic_ostream<Char,
+// CharTraits> type instead of the more restricted std::ostream.  If
+// we define it to take an std::ostream instead, we'll get an
+// "ambiguous overloads" compiler error when trying to print a type
+// Foo that supports streaming to std::basic_ostream<Char,
+// CharTraits>, as the compiler cannot tell whether
+// operator<<(std::ostream&, const T&) or
+// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
+// specific.
+template <typename Char, typename CharTraits, typename T>
+::std::basic_ostream<Char, CharTraits>& operator<<(
+    ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
+  TypeWithoutFormatter<T,
+      (internal::IsAProtocolMessage<T>::value ? kProtobuf :
+       internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
+       kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
+  return os;
+}
+
+}  // namespace internal2
+}  // namespace testing
+
+// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
+// magic needed for implementing UniversalPrinter won't work.
+namespace testing_internal {
+
+// Used to print a value that is not an STL-style container when the
+// user doesn't define PrintTo() for it.
+template <typename T>
+void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
+  // With the following statement, during unqualified name lookup,
+  // testing::internal2::operator<< appears as if it was declared in
+  // the nearest enclosing namespace that contains both
+  // ::testing_internal and ::testing::internal2, i.e. the global
+  // namespace.  For more details, refer to the C++ Standard section
+  // 7.3.4-1 [namespace.udir].  This allows us to fall back onto
+  // testing::internal2::operator<< in case T doesn't come with a <<
+  // operator.
+  //
+  // We cannot write 'using ::testing::internal2::operator<<;', which
+  // gcc 3.3 fails to compile due to a compiler bug.
+  using namespace ::testing::internal2;  // NOLINT
+
+  // Assuming T is defined in namespace foo, in the next statement,
+  // the compiler will consider all of:
+  //
+  //   1. foo::operator<< (thanks to Koenig look-up),
+  //   2. ::operator<< (as the current namespace is enclosed in ::),
+  //   3. testing::internal2::operator<< (thanks to the using statement above).
+  //
+  // The operator<< whose type matches T best will be picked.
+  //
+  // We deliberately allow #2 to be a candidate, as sometimes it's
+  // impossible to define #1 (e.g. when foo is ::std, defining
+  // anything in it is undefined behavior unless you are a compiler
+  // vendor.).
+  *os << value;
+}
+
+}  // namespace testing_internal
+
+namespace testing {
+namespace internal {
+
+// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
+// value to the given ostream.  The caller must ensure that
+// 'ostream_ptr' is not NULL, or the behavior is undefined.
+//
+// We define UniversalPrinter as a class template (as opposed to a
+// function template), as we need to partially specialize it for
+// reference types, which cannot be done with function templates.
+template <typename T>
+class UniversalPrinter;
+
+template <typename T>
+void UniversalPrint(const T& value, ::std::ostream* os);
+
+// Used to print an STL-style container when the user doesn't define
+// a PrintTo() for it.
+template <typename C>
+void DefaultPrintTo(IsContainer /* dummy */,
+                    false_type /* is not a pointer */,
+                    const C& container, ::std::ostream* os) {
+  const size_t kMaxCount = 32;  // The maximum number of elements to print.
+  *os << '{';
+  size_t count = 0;
+  for (typename C::const_iterator it = container.begin();
+       it != container.end(); ++it, ++count) {
+    if (count > 0) {
+      *os << ',';
+      if (count == kMaxCount) {  // Enough has been printed.
+        *os << " ...";
+        break;
+      }
+    }
+    *os << ' ';
+    // We cannot call PrintTo(*it, os) here as PrintTo() doesn't
+    // handle *it being a native array.
+    internal::UniversalPrint(*it, os);
+  }
+
+  if (count > 0) {
+    *os << ' ';
+  }
+  *os << '}';
+}
+
+// Used to print a pointer that is neither a char pointer nor a member
+// pointer, when the user doesn't define PrintTo() for it.  (A member
+// variable pointer or member function pointer doesn't really point to
+// a location in the address space.  Their representation is
+// implementation-defined.  Therefore they will be printed as raw
+// bytes.)
+template <typename T>
+void DefaultPrintTo(IsNotContainer /* dummy */,
+                    true_type /* is a pointer */,
+                    T* p, ::std::ostream* os) {
+  if (p == NULL) {
+    *os << "NULL";
+  } else {
+    // C++ doesn't allow casting from a function pointer to any object
+    // pointer.
+    //
+    // IsTrue() silences warnings: "Condition is always true",
+    // "unreachable code".
+    if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
+      // T is not a function type.  We just call << to print p,
+      // relying on ADL to pick up user-defined << for their pointer
+      // types, if any.
+      *os << p;
+    } else {
+      // T is a function type, so '*os << p' doesn't do what we want
+      // (it just prints p as bool).  We want to print p as a const
+      // void*.  However, we cannot cast it to const void* directly,
+      // even using reinterpret_cast, as earlier versions of gcc
+      // (e.g. 3.4.5) cannot compile the cast when p is a function
+      // pointer.  Casting to UInt64 first solves the problem.
+      *os << reinterpret_cast<const void*>(
+          reinterpret_cast<internal::UInt64>(p));
+    }
+  }
+}
+
+// Used to print a non-container, non-pointer value when the user
+// doesn't define PrintTo() for it.
+template <typename T>
+void DefaultPrintTo(IsNotContainer /* dummy */,
+                    false_type /* is not a pointer */,
+                    const T& value, ::std::ostream* os) {
+  ::testing_internal::DefaultPrintNonContainerTo(value, os);
+}
+
+// Prints the given value using the << operator if it has one;
+// otherwise prints the bytes in it.  This is what
+// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
+// or overloaded for type T.
+//
+// A user can override this behavior for a class type Foo by defining
+// an overload of PrintTo() in the namespace where Foo is defined.  We
+// give the user this option as sometimes defining a << operator for
+// Foo is not desirable (e.g. the coding style may prevent doing it,
+// or there is already a << operator but it doesn't do what the user
+// wants).
+template <typename T>
+void PrintTo(const T& value, ::std::ostream* os) {
+  // DefaultPrintTo() is overloaded.  The type of its first two
+  // arguments determine which version will be picked.  If T is an
+  // STL-style container, the version for container will be called; if
+  // T is a pointer, the pointer version will be called; otherwise the
+  // generic version will be called.
+  //
+  // Note that we check for container types here, prior to we check
+  // for protocol message types in our operator<<.  The rationale is:
+  //
+  // For protocol messages, we want to give people a chance to
+  // override Google Mock's format by defining a PrintTo() or
+  // operator<<.  For STL containers, other formats can be
+  // incompatible with Google Mock's format for the container
+  // elements; therefore we check for container types here to ensure
+  // that our format is used.
+  //
+  // The second argument of DefaultPrintTo() is needed to bypass a bug
+  // in Symbian's C++ compiler that prevents it from picking the right
+  // overload between:
+  //
+  //   PrintTo(const T& x, ...);
+  //   PrintTo(T* x, ...);
+  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
+}
+
+// The following list of PrintTo() overloads tells
+// UniversalPrinter<T>::Print() how to print standard types (built-in
+// types, strings, plain arrays, and pointers).
+
+// Overloads for various char types.
+GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
+GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
+inline void PrintTo(char c, ::std::ostream* os) {
+  // When printing a plain char, we always treat it as unsigned.  This
+  // way, the output won't be affected by whether the compiler thinks
+  // char is signed or not.
+  PrintTo(static_cast<unsigned char>(c), os);
+}
+
+// Overloads for other simple built-in types.
+inline void PrintTo(bool x, ::std::ostream* os) {
+  *os << (x ? "true" : "false");
+}
+
+// Overload for wchar_t type.
+// Prints a wchar_t as a symbol if it is printable or as its internal
+// code otherwise and also as its decimal code (except for L'\0').
+// The L'\0' char is printed as "L'\\0'". The decimal code is printed
+// as signed integer when wchar_t is implemented by the compiler
+// as a signed type and is printed as an unsigned integer when wchar_t
+// is implemented as an unsigned type.
+GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
+
+// Overloads for C strings.
+GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
+inline void PrintTo(char* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const char*>(s), os);
+}
+
+// signed/unsigned char is often used for representing binary data, so
+// we print pointers to it as void* to be safe.
+inline void PrintTo(const signed char* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const void*>(s), os);
+}
+inline void PrintTo(signed char* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const void*>(s), os);
+}
+inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const void*>(s), os);
+}
+inline void PrintTo(unsigned char* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const void*>(s), os);
+}
+
+// MSVC can be configured to define wchar_t as a typedef of unsigned
+// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
+// type.  When wchar_t is a typedef, defining an overload for const
+// wchar_t* would cause unsigned short* be printed as a wide string,
+// possibly causing invalid memory accesses.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+// Overloads for wide C strings
+GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
+inline void PrintTo(wchar_t* s, ::std::ostream* os) {
+  PrintTo(ImplicitCast_<const wchar_t*>(s), os);
+}
+#endif
+
+// Overload for C arrays.  Multi-dimensional arrays are printed
+// properly.
+
+// Prints the given number of elements in an array, without printing
+// the curly braces.
+template <typename T>
+void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
+  UniversalPrint(a[0], os);
+  for (size_t i = 1; i != count; i++) {
+    *os << ", ";
+    UniversalPrint(a[i], os);
+  }
+}
+
+// Overloads for ::string and ::std::string.
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
+inline void PrintTo(const ::string& s, ::std::ostream* os) {
+  PrintStringTo(s, os);
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
+inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
+  PrintStringTo(s, os);
+}
+
+// Overloads for ::wstring and ::std::wstring.
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
+inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
+  PrintWideStringTo(s, os);
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
+inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
+  PrintWideStringTo(s, os);
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_TR1_TUPLE
+// Overload for ::std::tr1::tuple.  Needed for printing function arguments,
+// which are packed as tuples.
+
+// Helper function for printing a tuple.  T must be instantiated with
+// a tuple type.
+template <typename T>
+void PrintTupleTo(const T& t, ::std::ostream* os);
+
+// Overloaded PrintTo() for tuples of various arities.  We support
+// tuples of up-to 10 fields.  The following implementation works
+// regardless of whether tr1::tuple is implemented using the
+// non-standard variadic template feature or not.
+
+inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1>
+void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2>
+void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
+             ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
+             ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6, typename T7>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
+             ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6, typename T7, typename T8>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
+             ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6, typename T7, typename T8, typename T9>
+void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
+             ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6, typename T7, typename T8, typename T9, typename T10>
+void PrintTo(
+    const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
+    ::std::ostream* os) {
+  PrintTupleTo(t, os);
+}
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Overload for std::pair.
+template <typename T1, typename T2>
+void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
+  *os << '(';
+  // We cannot use UniversalPrint(value.first, os) here, as T1 may be
+  // a reference type.  The same for printing value.second.
+  UniversalPrinter<T1>::Print(value.first, os);
+  *os << ", ";
+  UniversalPrinter<T2>::Print(value.second, os);
+  *os << ')';
+}
+
+// Implements printing a non-reference type T by letting the compiler
+// pick the right overload of PrintTo() for T.
+template <typename T>
+class UniversalPrinter {
+ public:
+  // MSVC warns about adding const to a function type, so we want to
+  // disable the warning.
+#ifdef _MSC_VER
+# pragma warning(push)          // Saves the current warning state.
+# pragma warning(disable:4180)  // Temporarily disables warning 4180.
+#endif  // _MSC_VER
+
+  // Note: we deliberately don't call this PrintTo(), as that name
+  // conflicts with ::testing::internal::PrintTo in the body of the
+  // function.
+  static void Print(const T& value, ::std::ostream* os) {
+    // By default, ::testing::internal::PrintTo() is used for printing
+    // the value.
+    //
+    // Thanks to Koenig look-up, if T is a class and has its own
+    // PrintTo() function defined in its namespace, that function will
+    // be visible here.  Since it is more specific than the generic ones
+    // in ::testing::internal, it will be picked by the compiler in the
+    // following statement - exactly what we want.
+    PrintTo(value, os);
+  }
+
+#ifdef _MSC_VER
+# pragma warning(pop)           // Restores the warning state.
+#endif  // _MSC_VER
+};
+
+// UniversalPrintArray(begin, len, os) prints an array of 'len'
+// elements, starting at address 'begin'.
+template <typename T>
+void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
+  if (len == 0) {
+    *os << "{}";
+  } else {
+    *os << "{ ";
+    const size_t kThreshold = 18;
+    const size_t kChunkSize = 8;
+    // If the array has more than kThreshold elements, we'll have to
+    // omit some details by printing only the first and the last
+    // kChunkSize elements.
+    // TODO(wan@google.com): let the user control the threshold using a flag.
+    if (len <= kThreshold) {
+      PrintRawArrayTo(begin, len, os);
+    } else {
+      PrintRawArrayTo(begin, kChunkSize, os);
+      *os << ", ..., ";
+      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
+    }
+    *os << " }";
+  }
+}
+// This overload prints a (const) char array compactly.
+GTEST_API_ void UniversalPrintArray(const char* begin,
+                                    size_t len,
+                                    ::std::ostream* os);
+
+// Implements printing an array type T[N].
+template <typename T, size_t N>
+class UniversalPrinter<T[N]> {
+ public:
+  // Prints the given array, omitting some elements when there are too
+  // many.
+  static void Print(const T (&a)[N], ::std::ostream* os) {
+    UniversalPrintArray(a, N, os);
+  }
+};
+
+// Implements printing a reference type T&.
+template <typename T>
+class UniversalPrinter<T&> {
+ public:
+  // MSVC warns about adding const to a function type, so we want to
+  // disable the warning.
+#ifdef _MSC_VER
+# pragma warning(push)          // Saves the current warning state.
+# pragma warning(disable:4180)  // Temporarily disables warning 4180.
+#endif  // _MSC_VER
+
+  static void Print(const T& value, ::std::ostream* os) {
+    // Prints the address of the value.  We use reinterpret_cast here
+    // as static_cast doesn't compile when T is a function type.
+    *os << "@" << reinterpret_cast<const void*>(&value) << " ";
+
+    // Then prints the value itself.
+    UniversalPrint(value, os);
+  }
+
+#ifdef _MSC_VER
+# pragma warning(pop)           // Restores the warning state.
+#endif  // _MSC_VER
+};
+
+// Prints a value tersely: for a reference type, the referenced value
+// (but not the address) is printed; for a (const) char pointer, the
+// NUL-terminated string (but not the pointer) is printed.
+template <typename T>
+void UniversalTersePrint(const T& value, ::std::ostream* os) {
+  UniversalPrint(value, os);
+}
+inline void UniversalTersePrint(const char* str, ::std::ostream* os) {
+  if (str == NULL) {
+    *os << "NULL";
+  } else {
+    UniversalPrint(string(str), os);
+  }
+}
+inline void UniversalTersePrint(char* str, ::std::ostream* os) {
+  UniversalTersePrint(static_cast<const char*>(str), os);
+}
+
+// Prints a value using the type inferred by the compiler.  The
+// difference between this and UniversalTersePrint() is that for a
+// (const) char pointer, this prints both the pointer and the
+// NUL-terminated string.
+template <typename T>
+void UniversalPrint(const T& value, ::std::ostream* os) {
+  UniversalPrinter<T>::Print(value, os);
+}
+
+#if GTEST_HAS_TR1_TUPLE
+typedef ::std::vector<string> Strings;
+
+// This helper template allows PrintTo() for tuples and
+// UniversalTersePrintTupleFieldsToStrings() to be defined by
+// induction on the number of tuple fields.  The idea is that
+// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
+// fields in tuple t, and can be defined in terms of
+// TuplePrefixPrinter<N - 1>.
+
+// The inductive case.
+template <size_t N>
+struct TuplePrefixPrinter {
+  // Prints the first N fields of a tuple.
+  template <typename Tuple>
+  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
+    TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
+    *os << ", ";
+    UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
+        ::Print(::std::tr1::get<N - 1>(t), os);
+  }
+
+  // Tersely prints the first N fields of a tuple to a string vector,
+  // one element for each field.
+  template <typename Tuple>
+  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
+    TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
+    ::std::stringstream ss;
+    UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
+    strings->push_back(ss.str());
+  }
+};
+
+// Base cases.
+template <>
+struct TuplePrefixPrinter<0> {
+  template <typename Tuple>
+  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
+
+  template <typename Tuple>
+  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
+};
+// We have to specialize the entire TuplePrefixPrinter<> class
+// template here, even though the definition of
+// TersePrintPrefixToStrings() is the same as the generic version, as
+// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't
+// support specializing a method template of a class template.
+template <>
+struct TuplePrefixPrinter<1> {
+  template <typename Tuple>
+  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
+    UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
+        Print(::std::tr1::get<0>(t), os);
+  }
+
+  template <typename Tuple>
+  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
+    ::std::stringstream ss;
+    UniversalTersePrint(::std::tr1::get<0>(t), &ss);
+    strings->push_back(ss.str());
+  }
+};
+
+// Helper function for printing a tuple.  T must be instantiated with
+// a tuple type.
+template <typename T>
+void PrintTupleTo(const T& t, ::std::ostream* os) {
+  *os << "(";
+  TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::
+      PrintPrefixTo(t, os);
+  *os << ")";
+}
+
+// Prints the fields of a tuple tersely to a string vector, one
+// element for each field.  See the comment before
+// UniversalTersePrint() for how we define "tersely".
+template <typename Tuple>
+Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
+  Strings result;
+  TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
+      TersePrintPrefixToStrings(value, &result);
+  return result;
+}
+#endif  // GTEST_HAS_TR1_TUPLE
+
+}  // namespace internal
+
+template <typename T>
+::std::string PrintToString(const T& value) {
+  ::std::stringstream ss;
+  internal::UniversalTersePrint(value, &ss);
+  return ss.str();
+}
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+namespace internal {
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Outputs a message explaining invalid registration of different
+// fixture class for the same test case. This may happen when
+// TEST_P macro is used to define two tests with the same name
+// but in different namespaces.
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+                                          const char* file, int line);
+
+template <typename> class ParamGeneratorInterface;
+template <typename> class ParamGenerator;
+
+// Interface for iterating over elements provided by an implementation
+// of ParamGeneratorInterface<T>.
+template <typename T>
+class ParamIteratorInterface {
+ public:
+  virtual ~ParamIteratorInterface() {}
+  // A pointer to the base generator instance.
+  // Used only for the purposes of iterator comparison
+  // to make sure that two iterators belong to the same generator.
+  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
+  // Advances iterator to point to the next element
+  // provided by the generator. The caller is responsible
+  // for not calling Advance() on an iterator equal to
+  // BaseGenerator()->End().
+  virtual void Advance() = 0;
+  // Clones the iterator object. Used for implementing copy semantics
+  // of ParamIterator<T>.
+  virtual ParamIteratorInterface* Clone() const = 0;
+  // Dereferences the current iterator and provides (read-only) access
+  // to the pointed value. It is the caller's responsibility not to call
+  // Current() on an iterator equal to BaseGenerator()->End().
+  // Used for implementing ParamGenerator<T>::operator*().
+  virtual const T* Current() const = 0;
+  // Determines whether the given iterator and other point to the same
+  // element in the sequence generated by the generator.
+  // Used for implementing ParamGenerator<T>::operator==().
+  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
+};
+
+// Class iterating over elements provided by an implementation of
+// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
+// and implements the const forward iterator concept.
+template <typename T>
+class ParamIterator {
+ public:
+  typedef T value_type;
+  typedef const T& reference;
+  typedef ptrdiff_t difference_type;
+
+  // ParamIterator assumes ownership of the impl_ pointer.
+  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
+  ParamIterator& operator=(const ParamIterator& other) {
+    if (this != &other)
+      impl_.reset(other.impl_->Clone());
+    return *this;
+  }
+
+  const T& operator*() const { return *impl_->Current(); }
+  const T* operator->() const { return impl_->Current(); }
+  // Prefix version of operator++.
+  ParamIterator& operator++() {
+    impl_->Advance();
+    return *this;
+  }
+  // Postfix version of operator++.
+  ParamIterator operator++(int /*unused*/) {
+    ParamIteratorInterface<T>* clone = impl_->Clone();
+    impl_->Advance();
+    return ParamIterator(clone);
+  }
+  bool operator==(const ParamIterator& other) const {
+    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
+  }
+  bool operator!=(const ParamIterator& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  friend class ParamGenerator<T>;
+  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
+  scoped_ptr<ParamIteratorInterface<T> > impl_;
+};
+
+// ParamGeneratorInterface<T> is the binary interface to access generators
+// defined in other translation units.
+template <typename T>
+class ParamGeneratorInterface {
+ public:
+  typedef T ParamType;
+
+  virtual ~ParamGeneratorInterface() {}
+
+  // Generator interface definition
+  virtual ParamIteratorInterface<T>* Begin() const = 0;
+  virtual ParamIteratorInterface<T>* End() const = 0;
+};
+
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
+// compatible with the STL Container concept.
+// This class implements copy initialization semantics and the contained
+// ParamGeneratorInterface<T> instance is shared among all copies
+// of the original object. This is possible because that instance is immutable.
+template<typename T>
+class ParamGenerator {
+ public:
+  typedef ParamIterator<T> iterator;
+
+  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
+  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
+
+  ParamGenerator& operator=(const ParamGenerator& other) {
+    impl_ = other.impl_;
+    return *this;
+  }
+
+  iterator begin() const { return iterator(impl_->Begin()); }
+  iterator end() const { return iterator(impl_->End()); }
+
+ private:
+  linked_ptr<const ParamGeneratorInterface<T> > impl_;
+};
+
+// Generates values from a range of two comparable values. Can be used to
+// generate sequences of user-defined types that implement operator+() and
+// operator<().
+// This class is used in the Range() function.
+template <typename T, typename IncrementT>
+class RangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  RangeGenerator(T begin, T end, IncrementT step)
+      : begin_(begin), end_(end),
+        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
+  virtual ~RangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, begin_, 0, step_);
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, end_, end_index_, step_);
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
+             IncrementT step)
+        : base_(base), value_(value), index_(index), step_(step) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      value_ = value_ + step_;
+      index_++;
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const T* Current() const { return &value_; }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const int other_index =
+          CheckedDowncastToActualType<const Iterator>(&other)->index_;
+      return index_ == other_index;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : ParamIteratorInterface<T>(),
+          base_(other.base_), value_(other.value_), index_(other.index_),
+          step_(other.step_) {}
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<T>* const base_;
+    T value_;
+    int index_;
+    const IncrementT step_;
+  };  // class RangeGenerator::Iterator
+
+  static int CalculateEndIndex(const T& begin,
+                               const T& end,
+                               const IncrementT& step) {
+    int end_index = 0;
+    for (T i = begin; i < end; i = i + step)
+      end_index++;
+    return end_index;
+  }
+
+  // No implementation - assignment is unsupported.
+  void operator=(const RangeGenerator& other);
+
+  const T begin_;
+  const T end_;
+  const IncrementT step_;
+  // The index for the end() iterator. All the elements in the generated
+  // sequence are indexed (0-based) to aid iterator comparison.
+  const int end_index_;
+};  // class RangeGenerator
+
+
+// Generates values from a pair of STL-style iterators. Used in the
+// ValuesIn() function. The elements are copied from the source range
+// since the source can be located on the stack, and the generator
+// is likely to persist beyond that stack frame.
+template <typename T>
+class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  template <typename ForwardIterator>
+  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
+      : container_(begin, end) {}
+  virtual ~ValuesInIteratorRangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, container_.begin());
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, container_.end());
+  }
+
+ private:
+  typedef typename ::std::vector<T> ContainerType;
+
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base,
+             typename ContainerType::const_iterator iterator)
+        : base_(base), iterator_(iterator) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      ++iterator_;
+      value_.reset();
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    // We need to use cached value referenced by iterator_ because *iterator_
+    // can return a temporary object (and of type other then T), so just
+    // having "return &*iterator_;" doesn't work.
+    // value_ is updated here and not in Advance() because Advance()
+    // can advance iterator_ beyond the end of the range, and we cannot
+    // detect that fact. The client code, on the other hand, is
+    // responsible for not calling Current() on an out-of-range iterator.
+    virtual const T* Current() const {
+      if (value_.get() == NULL)
+        value_.reset(new T(*iterator_));
+      return value_.get();
+    }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      return iterator_ ==
+          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+          // The explicit constructor call suppresses a false warning
+          // emitted by gcc when supplied with the -Wextra option.
+        : ParamIteratorInterface<T>(),
+          base_(other.base_),
+          iterator_(other.iterator_) {}
+
+    const ParamGeneratorInterface<T>* const base_;
+    typename ContainerType::const_iterator iterator_;
+    // A cached value of *iterator_. We keep it here to allow access by
+    // pointer in the wrapping iterator's operator->().
+    // value_ needs to be mutable to be accessed in Current().
+    // Use of scoped_ptr helps manage cached value's lifetime,
+    // which is bound by the lifespan of the iterator itself.
+    mutable scoped_ptr<const T> value_;
+  };  // class ValuesInIteratorRangeGenerator::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const ValuesInIteratorRangeGenerator& other);
+
+  const ContainerType container_;
+};  // class ValuesInIteratorRangeGenerator
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Stores a parameter value and later creates tests parameterized with that
+// value.
+template <class TestClass>
+class ParameterizedTestFactory : public TestFactoryBase {
+ public:
+  typedef typename TestClass::ParamType ParamType;
+  explicit ParameterizedTestFactory(ParamType parameter) :
+      parameter_(parameter) {}
+  virtual Test* CreateTest() {
+    TestClass::SetParam(&parameter_);
+    return new TestClass();
+  }
+
+ private:
+  const ParamType parameter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactoryBase is a base class for meta-factories that create
+// test factories for passing into MakeAndRegisterTestInfo function.
+template <class ParamType>
+class TestMetaFactoryBase {
+ public:
+  virtual ~TestMetaFactoryBase() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactory creates test factories for passing into
+// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
+// ownership of test factory pointer, same factory object cannot be passed
+// into that method twice. But ParameterizedTestCaseInfo is going to call
+// it for each Test/Parameter value combination. Thus it needs meta factory
+// creator class.
+template <class TestCase>
+class TestMetaFactory
+    : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ public:
+  typedef typename TestCase::ParamType ParamType;
+
+  TestMetaFactory() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
+    return new ParameterizedTestFactory<TestCase>(parameter);
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfoBase is a generic interface
+// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// accumulates test information provided by TEST_P macro invocations
+// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and uses that information to register all resulting test instances
+// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
+// a collection of pointers to the ParameterizedTestCaseInfo objects
+// and calls RegisterTests() on each of them when asked.
+class ParameterizedTestCaseInfoBase {
+ public:
+  virtual ~ParameterizedTestCaseInfoBase() {}
+
+  // Base part of test case name for display purposes.
+  virtual const string& GetTestCaseName() const = 0;
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const = 0;
+  // UnitTest class invokes this method to register tests in this
+  // test case right before running them in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  virtual void RegisterTests() = 0;
+
+ protected:
+  ParameterizedTestCaseInfoBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test case and generators
+// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
+// test case. It registers tests with all values generated by all
+// generators when asked.
+template <class TestCase>
+class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+ public:
+  // ParamType and GeneratorCreationFunc are private types but are required
+  // for declarations of public methods AddTestPattern() and
+  // AddTestCaseInstantiation().
+  typedef typename TestCase::ParamType ParamType;
+  // A function that returns an instance of appropriate generator type.
+  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
+
+  explicit ParameterizedTestCaseInfo(const char* name)
+      : test_case_name_(name) {}
+
+  // Test case base name for display purposes.
+  virtual const string& GetTestCaseName() const { return test_case_name_; }
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+  // TEST_P macro uses AddTestPattern() to record information
+  // about a single test in a LocalTestInfo structure.
+  // test_case_name is the base name of the test case (without invocation
+  // prefix). test_base_name is the name of an individual test without
+  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
+  // test case base name and DoBar is test base name.
+  void AddTestPattern(const char* test_case_name,
+                      const char* test_base_name,
+                      TestMetaFactoryBase<ParamType>* meta_factory) {
+    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
+                                                       test_base_name,
+                                                       meta_factory)));
+  }
+  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+  // about a generator.
+  int AddTestCaseInstantiation(const string& instantiation_name,
+                               GeneratorCreationFunc* func,
+                               const char* /* file */,
+                               int /* line */) {
+    instantiations_.push_back(::std::make_pair(instantiation_name, func));
+    return 0;  // Return value used only to run this method in namespace scope.
+  }
+  // UnitTest class invokes this method to register tests in this test case
+  // test cases right before running tests in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // UnitTest has a guard to prevent from calling this method more then once.
+  virtual void RegisterTests() {
+    for (typename TestInfoContainer::iterator test_it = tests_.begin();
+         test_it != tests_.end(); ++test_it) {
+      linked_ptr<TestInfo> test_info = *test_it;
+      for (typename InstantiationContainer::iterator gen_it =
+               instantiations_.begin(); gen_it != instantiations_.end();
+               ++gen_it) {
+        const string& instantiation_name = gen_it->first;
+        ParamGenerator<ParamType> generator((*gen_it->second)());
+
+        Message test_case_name_stream;
+        if ( !instantiation_name.empty() )
+          test_case_name_stream << instantiation_name << "/";
+        test_case_name_stream << test_info->test_case_base_name;
+
+        int i = 0;
+        for (typename ParamGenerator<ParamType>::iterator param_it =
+                 generator.begin();
+             param_it != generator.end(); ++param_it, ++i) {
+          Message test_name_stream;
+          test_name_stream << test_info->test_base_name << "/" << i;
+          MakeAndRegisterTestInfo(
+              test_case_name_stream.GetString().c_str(),
+              test_name_stream.GetString().c_str(),
+              NULL,  // No type parameter.
+              PrintToString(*param_it).c_str(),
+              GetTestCaseTypeId(),
+              TestCase::SetUpTestCase,
+              TestCase::TearDownTestCase,
+              test_info->test_meta_factory->CreateTestFactory(*param_it));
+        }  // for param_it
+      }  // for gen_it
+    }  // for test_it
+  }  // RegisterTests
+
+ private:
+  // LocalTestInfo structure keeps information about a single test registered
+  // with TEST_P macro.
+  struct TestInfo {
+    TestInfo(const char* a_test_case_base_name,
+             const char* a_test_base_name,
+             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+        test_case_base_name(a_test_case_base_name),
+        test_base_name(a_test_base_name),
+        test_meta_factory(a_test_meta_factory) {}
+
+    const string test_case_base_name;
+    const string test_base_name;
+    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+  };
+  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
+  // Keeps pairs of <Instantiation name, Sequence generator creation function>
+  // received from INSTANTIATE_TEST_CASE_P macros.
+  typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >
+      InstantiationContainer;
+
+  const string test_case_name_;
+  TestInfoContainer tests_;
+  InstantiationContainer instantiations_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
+};  // class ParameterizedTestCaseInfo
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
+// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
+// macros use it to locate their corresponding ParameterizedTestCaseInfo
+// descriptors.
+class ParameterizedTestCaseRegistry {
+ public:
+  ParameterizedTestCaseRegistry() {}
+  ~ParameterizedTestCaseRegistry() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      delete *it;
+    }
+  }
+
+  // Looks up or creates and returns a structure containing information about
+  // tests and instantiations of a particular test case.
+  template <class TestCase>
+  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+      const char* test_case_name,
+      const char* file,
+      int line) {
+    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      if ((*it)->GetTestCaseName() == test_case_name) {
+        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+          // Complain about incorrect usage of Google Test facilities
+          // and terminate the program since we cannot guaranty correct
+          // test case setup and tear-down in this case.
+          ReportInvalidTestCaseType(test_case_name,  file, line);
+          posix::Abort();
+        } else {
+          // At this point we are sure that the object we found is of the same
+          // type we are looking for, so we downcast it to that type
+          // without further checks.
+          typed_test_info = CheckedDowncastToActualType<
+              ParameterizedTestCaseInfo<TestCase> >(*it);
+        }
+        break;
+      }
+    }
+    if (typed_test_info == NULL) {
+      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
+      test_case_infos_.push_back(typed_test_info);
+    }
+    return typed_test_info;
+  }
+  void RegisterTests() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      (*it)->RegisterTests();
+    }
+  }
+
+ private:
+  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+
+  TestCaseInfoContainer test_case_infos_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+// This file was GENERATED by command:
+//     pump.py gtest-param-util-generated.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most 50 arguments in Values,
+// and at most 10 arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at 10.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
+ValuesIn(ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+  explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray1& other);
+
+  const T1 v1_;
+};
+
+template <typename T1, typename T2>
+class ValueArray2 {
+ public:
+  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray2& other);
+
+  const T1 v1_;
+  const T2 v2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ValueArray3 {
+ public:
+  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray3& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ValueArray4 {
+ public:
+  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray4& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ValueArray5 {
+ public:
+  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray5& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class ValueArray6 {
+ public:
+  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray6& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class ValueArray7 {
+ public:
+  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray7& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class ValueArray8 {
+ public:
+  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray8& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class ValueArray9 {
+ public:
+  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray9& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class ValueArray10 {
+ public:
+  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray10& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+class ValueArray11 {
+ public:
+  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray11& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+class ValueArray12 {
+ public:
+  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray12& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+class ValueArray13 {
+ public:
+  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray13& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+class ValueArray14 {
+ public:
+  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray14& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+class ValueArray15 {
+ public:
+  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray15& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+class ValueArray16 {
+ public:
+  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray16& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+class ValueArray17 {
+ public:
+  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray17& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+class ValueArray18 {
+ public:
+  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray18& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+class ValueArray19 {
+ public:
+  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray19& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+class ValueArray20 {
+ public:
+  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray20& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+class ValueArray21 {
+ public:
+  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray21& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+class ValueArray22 {
+ public:
+  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray22& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+class ValueArray23 {
+ public:
+  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
+        v23_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray23& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+class ValueArray24 {
+ public:
+  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray24& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+class ValueArray25 {
+ public:
+  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray25& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+class ValueArray26 {
+ public:
+  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray26& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+class ValueArray27 {
+ public:
+  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray27& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+class ValueArray28 {
+ public:
+  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray28& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+class ValueArray29 {
+ public:
+  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray29& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+class ValueArray30 {
+ public:
+  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray30& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+class ValueArray31 {
+ public:
+  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray31& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+class ValueArray32 {
+ public:
+  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray32& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+class ValueArray33 {
+ public:
+  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray33& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+class ValueArray34 {
+ public:
+  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray34& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+class ValueArray35 {
+ public:
+  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
+        v35_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray35& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+class ValueArray36 {
+ public:
+  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray36& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+class ValueArray37 {
+ public:
+  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray37& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+class ValueArray38 {
+ public:
+  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray38& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+class ValueArray39 {
+ public:
+  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray39& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+class ValueArray40 {
+ public:
+  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray40& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+class ValueArray41 {
+ public:
+  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray41& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+class ValueArray42 {
+ public:
+  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray42& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+class ValueArray43 {
+ public:
+  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
+      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray43& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+class ValueArray44 {
+ public:
+  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
+      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
+      v43_(v43), v44_(v44) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray44& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+class ValueArray45 {
+ public:
+  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
+      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray45& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+class ValueArray46 {
+ public:
+  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray46& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+class ValueArray47 {
+ public:
+  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
+      v47_(v47) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
+        v47_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray47& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+class ValueArray48 {
+ public:
+  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
+      v46_(v46), v47_(v47), v48_(v48) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray48& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+class ValueArray49 {
+ public:
+  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
+      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray49& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+class ValueArray50 {
+ public:
+  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
+      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_, v50_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray50& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+  const T50 v50_;
+};
+
+# if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+template <typename T1, typename T2>
+class CartesianProductGenerator2
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2> ParamType;
+
+  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2)
+      : g1_(g1), g2_(g2) {}
+  virtual ~CartesianProductGenerator2() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current2_;
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator2::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator2& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+};  // class CartesianProductGenerator2
+
+
+template <typename T1, typename T2, typename T3>
+class CartesianProductGenerator3
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
+
+  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  virtual ~CartesianProductGenerator3() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current3_;
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator3::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator3& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+};  // class CartesianProductGenerator3
+
+
+template <typename T1, typename T2, typename T3, typename T4>
+class CartesianProductGenerator4
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
+
+  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  virtual ~CartesianProductGenerator4() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current4_;
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator4::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator4& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+};  // class CartesianProductGenerator4
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class CartesianProductGenerator5
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
+
+  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  virtual ~CartesianProductGenerator5() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current5_;
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator5::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator5& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+};  // class CartesianProductGenerator5
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class CartesianProductGenerator6
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
+        T6> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
+
+  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  virtual ~CartesianProductGenerator6() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current6_;
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator6::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator6& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+};  // class CartesianProductGenerator6
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class CartesianProductGenerator7
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
+
+  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  virtual ~CartesianProductGenerator7() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current7_;
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator7::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator7& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+};  // class CartesianProductGenerator7
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class CartesianProductGenerator8
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
+
+  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  virtual ~CartesianProductGenerator8() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current8_;
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator8::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator8& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+};  // class CartesianProductGenerator8
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class CartesianProductGenerator9
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
+
+  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  virtual ~CartesianProductGenerator9() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current9_;
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator9::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator9& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+};  // class CartesianProductGenerator9
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class CartesianProductGenerator10
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9, T10> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
+
+  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
+      const ParamGenerator<T10>& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  virtual ~CartesianProductGenerator10() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9,
+      const ParamGenerator<T10>& g10,
+      const typename ParamGenerator<T10>::iterator& current10)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
+          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current10_;
+      if (current10_ == end10_) {
+        current10_ = begin10_;
+        ++current9_;
+      }
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_ &&
+          current10_ == typed_other->current10_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_),
+        begin10_(other.begin10_),
+        end10_(other.end10_),
+        current10_(other.current10_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_, *current10_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_ ||
+          current10_ == end10_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    const typename ParamGenerator<T10>::iterator begin10_;
+    const typename ParamGenerator<T10>::iterator end10_;
+    typename ParamGenerator<T10>::iterator current10_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator10::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator10& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+  const ParamGenerator<T10> g10_;
+};  // class CartesianProductGenerator10
+
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+template <class Generator1, class Generator2>
+class CartesianProductHolder2 {
+ public:
+CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
+      : g1_(g1), g2_(g2) {}
+  template <typename T1, typename T2>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
+        new CartesianProductGenerator2<T1, T2>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder2& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+};  // class CartesianProductHolder2
+
+template <class Generator1, class Generator2, class Generator3>
+class CartesianProductHolder3 {
+ public:
+CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  template <typename T1, typename T2, typename T3>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
+        new CartesianProductGenerator3<T1, T2, T3>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder3& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+};  // class CartesianProductHolder3
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4>
+class CartesianProductHolder4 {
+ public:
+CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  template <typename T1, typename T2, typename T3, typename T4>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
+        new CartesianProductGenerator4<T1, T2, T3, T4>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder4& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+};  // class CartesianProductHolder4
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5>
+class CartesianProductHolder5 {
+ public:
+CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
+        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder5& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+};  // class CartesianProductHolder5
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6>
+class CartesianProductHolder6 {
+ public:
+CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
+        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder6& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+};  // class CartesianProductHolder6
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7>
+class CartesianProductHolder7 {
+ public:
+CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+      T7> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
+        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder7& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+};  // class CartesianProductHolder7
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8>
+class CartesianProductHolder8 {
+ public:
+CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
+      T8> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
+        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder8& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+};  // class CartesianProductHolder8
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9>
+class CartesianProductHolder9 {
+ public:
+CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9> >(
+        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder9& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+};  // class CartesianProductHolder9
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9, class Generator10>
+class CartesianProductHolder10 {
+ public:
+CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9, const Generator10& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9, typename T10>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9, T10> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9, T10> >(
+        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+            T10>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_),
+        static_cast<ParamGenerator<T10> >(g10_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder10& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+  const Generator10 g10_;
+};  // class CartesianProductHolder10
+
+# endif  // GTEST_HAS_COMBINE
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+//   - returns a generator producing a sequence of values {start, start+1,
+//     start+2, ..., }.
+// Range(start, end, step)
+//   - returns a generator producing a sequence of values {start, start+step,
+//     start+step+step, ..., }.
+// Notes:
+//   * The generated sequences never include end. For example, Range(1, 5)
+//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+//     returns a generator producing {1, 3, 5, 7}.
+//   * start and end must have the same type. That type may be any integral or
+//     floating-point type or a user defined type satisfying these conditions:
+//     * It must be assignable (have operator=() defined).
+//     * It must have operator+() (operator+(int-compatible type) for
+//       two-operand version).
+//     * It must have operator<() defined.
+//     Elements in the resulting sequences will also have that type.
+//   * Condition start < end must be satisfied in order for resulting sequences
+//     to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+  return internal::ParamGenerator<T>(
+      new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+  return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+//   - returns a generator producing sequences with elements from
+//     a C-style array.
+// ValuesIn(const Container& container)
+//   - returns a generator producing sequences with elements from
+//     an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+//   - returns a generator producing sequences with elements from
+//     a range [begin, end) defined by a pair of STL-style iterators. These
+//     iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+//   ::std::vector< ::std::string> v;
+//   v.push_back("a");
+//   v.push_back("b");
+//   return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+//                         StlStringTest,
+//                         ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+//   ::std::list<char> list;
+//   list.push_back('a');
+//   list.push_back('b');
+//   return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+//                         CharTest,
+//                         ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
+ValuesIn(ForwardIterator begin, ForwardIterator end) {
+  typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
+      ::value_type ParamType;
+  return internal::ParamGenerator<ParamType>(
+      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+  return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container) {
+  return ValuesIn(container.begin(), container.end());
+}
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+//   - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to 50 parameters.
+//
+template <typename T1>
+internal::ValueArray1<T1> Values(T1 v1) {
+  return internal::ValueArray1<T1>(v1);
+}
+
+template <typename T1, typename T2>
+internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
+  return internal::ValueArray2<T1, T2>(v1, v2);
+}
+
+template <typename T1, typename T2, typename T3>
+internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
+  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
+  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5) {
+  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6) {
+  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7) {
+  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
+      v6, v7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
+      v5, v6, v7, v8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11) {
+  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12) {
+  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13) {
+  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16) {
+  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17) {
+  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18) {
+  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
+  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
+  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
+  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22) {
+  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23) {
+  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24) {
+  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
+  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26) {
+  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27) {
+  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28) {
+  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29) {
+  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
+  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
+  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32) {
+  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33) {
+  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34) {
+  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
+  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
+  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37) {
+  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38) {
+  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
+      v33, v34, v35, v36, v37, v38);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38, T39 v39) {
+  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
+      v32, v33, v34, v35, v36, v37, v38, v39);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
+    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
+    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
+  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
+  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
+      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42) {
+  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
+      v42);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43) {
+  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
+      v41, v42, v43);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43, T44 v44) {
+  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+      v40, v41, v42, v43, v44);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
+  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
+      v39, v40, v41, v42, v43, v44, v45);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
+  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
+  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
+    T48 v48) {
+  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
+      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
+    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
+    T47 v47, T48 v48, T49 v49) {
+  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
+      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
+    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
+    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
+  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
+      v48, v49, v50);
+}
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+//   - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+//   virtual void SetUp() {
+//     external_flag = GetParam();
+//   }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+  return Values(false, true);
+}
+
+# if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+//   - returns a generator producing sequences with elements coming from
+//     the Cartesian product of elements from the sequences generated by
+//     gen1, gen2, ..., genN. The sequence elements will have a type of
+//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to 10 arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+//                         Combine(Values("cat", "dog"),
+//                                 Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+//     : public testing::TestWithParam<tuple(bool, bool)> > {
+//   virtual void SetUp() {
+//     // Assigns external_flag_1 and external_flag_2 values from the tuple.
+//     tie(external_flag_1, external_flag_2) = GetParam();
+//   }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+//   // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+//                         Combine(Bool(), Bool()));
+//
+template <typename Generator1, typename Generator2>
+internal::CartesianProductHolder2<Generator1, Generator2> Combine(
+    const Generator1& g1, const Generator2& g2) {
+  return internal::CartesianProductHolder2<Generator1, Generator2>(
+      g1, g2);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3>
+internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3) {
+  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
+      g1, g2, g3);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4>
+internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+    Generator4> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4) {
+  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+      Generator4>(
+      g1, g2, g3, g4);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5>
+internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+    Generator4, Generator5> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5) {
+  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+      Generator4, Generator5>(
+      g1, g2, g3, g4, g5);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6>
+internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6) {
+  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6>(
+      g1, g2, g3, g4, g5, g6);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7>
+internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7) {
+  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7>(
+      g1, g2, g3, g4, g5, g6, g7);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8>
+internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8) {
+  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8>(
+      g1, g2, g3, g4, g5, g6, g7, g8);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9>
+internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8,
+    Generator9> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9) {
+  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9,
+    typename Generator10>
+internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+    Generator10> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9,
+        const Generator10& g10) {
+  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+      Generator10>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
+}
+# endif  // GTEST_HAS_COMBINE
+
+
+
+# define TEST_P(test_case_name, test_name) \
+  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+      : public test_case_name { \
+   public: \
+    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+    virtual void TestBody(); \
+   private: \
+    static int AddToRegistry() { \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+                  #test_case_name, \
+                  #test_name, \
+                  new ::testing::internal::TestMetaFactory< \
+                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+      return 0; \
+    } \
+    static int gtest_registering_dummy_; \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+  }; \
+  int GTEST_TEST_CLASS_NAME_(test_case_name, \
+                             test_name)::gtest_registering_dummy_ = \
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+  int gtest_##prefix##test_case_name##_dummy_ = \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+                  #prefix, \
+                  &gtest_##prefix##test_case_name##_EvalGenerator_, \
+                  __FILE__, __LINE__)
+
+}  // namespace testing
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Google C++ Testing Framework definitions useful in production code.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+
+// When you need to test the private or protected members of a class,
+// use the FRIEND_TEST macro to declare your tests as friends of the
+// class.  For example:
+//
+// class MyClass {
+//  private:
+//   void MyMethod();
+//   FRIEND_TEST(MyClassTest, MyMethod);
+// };
+//
+// class MyClassTest : public testing::Test {
+//   // ...
+// };
+//
+// TEST_F(MyClassTest, MyMethod) {
+//   // Can call MyClass::MyMethod() here.
+// }
+
+#define FRIEND_TEST(test_case_name, test_name)\
+friend class test_case_name##_##test_name##_Test
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+
+#include <iosfwd>
+#include <vector>
+
+namespace testing {
+
+// A copyable object representing the result of a test part (i.e. an
+// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
+//
+// Don't inherit from TestPartResult as its destructor is not virtual.
+class GTEST_API_ TestPartResult {
+ public:
+  // The possible outcomes of a test part (i.e. an assertion or an
+  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+  enum Type {
+    kSuccess,          // Succeeded.
+    kNonFatalFailure,  // Failed but the test can continue.
+    kFatalFailure      // Failed and the test should be terminated.
+  };
+
+  // C'tor.  TestPartResult does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestPartResult object.
+  TestPartResult(Type a_type,
+                 const char* a_file_name,
+                 int a_line_number,
+                 const char* a_message)
+      : type_(a_type),
+        file_name_(a_file_name),
+        line_number_(a_line_number),
+        summary_(ExtractSummary(a_message)),
+        message_(a_message) {
+  }
+
+  // Gets the outcome of the test part.
+  Type type() const { return type_; }
+
+  // Gets the name of the source file where the test part took place, or
+  // NULL if it's unknown.
+  const char* file_name() const { return file_name_.c_str(); }
+
+  // Gets the line in the source file where the test part took place,
+  // or -1 if it's unknown.
+  int line_number() const { return line_number_; }
+
+  // Gets the summary of the failure message.
+  const char* summary() const { return summary_.c_str(); }
+
+  // Gets the message associated with the test part.
+  const char* message() const { return message_.c_str(); }
+
+  // Returns true iff the test part passed.
+  bool passed() const { return type_ == kSuccess; }
+
+  // Returns true iff the test part failed.
+  bool failed() const { return type_ != kSuccess; }
+
+  // Returns true iff the test part non-fatally failed.
+  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
+
+  // Returns true iff the test part fatally failed.
+  bool fatally_failed() const { return type_ == kFatalFailure; }
+ private:
+  Type type_;
+
+  // Gets the summary of the failure message by omitting the stack
+  // trace in it.
+  static internal::String ExtractSummary(const char* message);
+
+  // The name of the source file where the test part took place, or
+  // NULL if the source file is unknown.
+  internal::String file_name_;
+  // The line in the source file where the test part took place, or -1
+  // if the line number is unknown.
+  int line_number_;
+  internal::String summary_;  // The test failure summary.
+  internal::String message_;  // The test failure message.
+};
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
+
+// An array of TestPartResult objects.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class GTEST_API_ TestPartResultArray {
+ public:
+  TestPartResultArray() {}
+
+  // Appends the given TestPartResult to the array.
+  void Append(const TestPartResult& result);
+
+  // Returns the TestPartResult at the given index (0-based).
+  const TestPartResult& GetTestPartResult(int index) const;
+
+  // Returns the number of TestPartResult objects in the array.
+  int size() const;
+
+ private:
+  std::vector<TestPartResult> array_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
+};
+
+// This interface knows how to report a test part result.
+class TestPartResultReporterInterface {
+ public:
+  virtual ~TestPartResultReporterInterface() {}
+
+  virtual void ReportTestPartResult(const TestPartResult& result) = 0;
+};
+
+namespace internal {
+
+// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
+// statement generates new fatal failures. To do so it registers itself as the
+// current test part result reporter. Besides checking if fatal failures were
+// reported, it only delegates the reporting to the former result reporter.
+// The original result reporter is restored in the destructor.
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+class GTEST_API_ HasNewFatalFailureHelper
+    : public TestPartResultReporterInterface {
+ public:
+  HasNewFatalFailureHelper();
+  virtual ~HasNewFatalFailureHelper();
+  virtual void ReportTestPartResult(const TestPartResult& result);
+  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
+ private:
+  bool has_new_fatal_failure_;
+  TestPartResultReporterInterface* original_reporter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// This header implements typed tests and type-parameterized tests.
+
+// Typed (aka type-driven) tests repeat the same test for types in a
+// list.  You must know which types you want to test with when writing
+// typed tests. Here's how you do it:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ public:
+  ...
+  typedef std::list<T> List;
+  static T shared_;
+  T value_;
+};
+
+// Next, associate a list of types with the test case, which will be
+// repeated for each type in the list.  The typedef is necessary for
+// the macro to parse correctly.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+TYPED_TEST_CASE(FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   TYPED_TEST_CASE(FooTest, int);
+
+// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
+// tests for this test case as you want.
+TYPED_TEST(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  // Since we are inside a derived class template, C++ requires use to
+  // visit the members of FooTest via 'this'.
+  TypeParam n = this->value_;
+
+  // To visit static members of the fixture, add the TestFixture::
+  // prefix.
+  n += TestFixture::shared_;
+
+  // To refer to typedefs in the fixture, add the "typename
+  // TestFixture::" prefix.
+  typename TestFixture::List values;
+  values.push_back(n);
+  ...
+}
+
+TYPED_TEST(FooTest, HasPropertyA) { ... }
+
+#endif  // 0
+
+// Type-parameterized tests are abstract test patterns parameterized
+// by a type.  Compared with typed tests, type-parameterized tests
+// allow you to define the test pattern without knowing what the type
+// parameters are.  The defined pattern can be instantiated with
+// different types any number of times, in any number of translation
+// units.
+//
+// If you are designing an interface or concept, you can define a
+// suite of type-parameterized tests to verify properties that any
+// valid implementation of the interface/concept should have.  Then,
+// each implementation can easily instantiate the test suite to verify
+// that it conforms to the requirements, without having to write
+// similar tests repeatedly.  Here's an example:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+  ...
+};
+
+// Next, declare that you will define a type-parameterized test case
+// (the _P suffix is for "parameterized" or "pattern", whichever you
+// prefer):
+TYPED_TEST_CASE_P(FooTest);
+
+// Then, use TYPED_TEST_P() to define as many type-parameterized tests
+// for this type-parameterized test case as you want.
+TYPED_TEST_P(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  TypeParam n = 0;
+  ...
+}
+
+TYPED_TEST_P(FooTest, HasPropertyA) { ... }
+
+// Now the tricky part: you need to register all test patterns before
+// you can instantiate them.  The first argument of the macro is the
+// test case name; the rest are the names of the tests in this test
+// case.
+REGISTER_TYPED_TEST_CASE_P(FooTest,
+                           DoesBlah, HasPropertyA);
+
+// Finally, you are free to instantiate the pattern with the types you
+// want.  If you put the above code in a header file, you can #include
+// it in multiple C++ source files and instantiate it multiple times.
+//
+// To distinguish different instances of the pattern, the first
+// argument to the INSTANTIATE_* macro is a prefix that will be added
+// to the actual test case name.  Remember to pick unique prefixes for
+// different instances.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+
+#endif  // 0
+
+
+// Implements typed tests.
+
+#if GTEST_HAS_TYPED_TEST
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the typedef for the type parameters of the
+// given test case.
+# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+# define TYPED_TEST_CASE(CaseName, Types) \
+  typedef ::testing::internal::TypeList< Types >::type \
+      GTEST_TYPE_PARAMS_(CaseName)
+
+# define TYPED_TEST(CaseName, TestName) \
+  template <typename gtest_TypeParam_> \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+      : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
+      ::testing::internal::TypeParameterizedTest< \
+          CaseName, \
+          ::testing::internal::TemplateSel< \
+              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
+          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
+              "", #CaseName, #TestName, 0); \
+  template <typename gtest_TypeParam_> \
+  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// Implements type-parameterized tests.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the namespace name that the type-parameterized tests for
+// the given type-parameterized test case are defined in.  The exact
+// name of the namespace is subject to change without notice.
+# define GTEST_CASE_NAMESPACE_(TestCaseName) \
+  gtest_case_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the variable used to remember the names of
+// the defined tests in the given test case.
+# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
+  gtest_typed_test_case_p_state_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
+//
+// Expands to the name of the variable used to remember the names of
+// the registered tests in the given test case.
+# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
+  gtest_registered_test_names_##TestCaseName##_
+
+// The variables defined in the type-parameterized test macros are
+// static as typically these macros are used in a .h file that can be
+// #included in multiple translation units linked together.
+# define TYPED_TEST_CASE_P(CaseName) \
+  static ::testing::internal::TypedTestCasePState \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+
+# define TYPED_TEST_P(CaseName, TestName) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  template <typename gtest_TypeParam_> \
+  class TestName : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
+          __FILE__, __LINE__, #CaseName, #TestName); \
+  } \
+  template <typename gtest_TypeParam_> \
+  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+
+# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+  } \
+  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+          __FILE__, __LINE__, #__VA_ARGS__)
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
+  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
+      ::testing::internal::TypeParameterizedTestCase<CaseName, \
+          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
+          ::testing::internal::TypeList< Types >::type>::Register(\
+              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// Depending on the platform, different string classes are available.
+// On Linux, in addition to ::std::string, Google also makes use of
+// class ::string, which has the same interface as ::std::string, but
+// has a different implementation.
+//
+// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
+// ::string is available AND is a distinct type to ::std::string, or
+// define it to 0 to indicate otherwise.
+//
+// If the user's ::std::string and ::string are the same class due to
+// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
+
+namespace testing {
+
+// Declares the flags.
+
+// This flag temporary enables the disabled tests.
+GTEST_DECLARE_bool_(also_run_disabled_tests);
+
+// This flag brings the debugger on an assertion failure.
+GTEST_DECLARE_bool_(break_on_failure);
+
+// This flag controls whether Google Test catches all test-thrown exceptions
+// and logs them as failures.
+GTEST_DECLARE_bool_(catch_exceptions);
+
+// This flag enables using colors in terminal output. Available values are
+// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
+// to let Google Test decide.
+GTEST_DECLARE_string_(color);
+
+// This flag sets up the filter to select by name using a glob pattern
+// the tests to run. If the filter is not given all tests are executed.
+GTEST_DECLARE_string_(filter);
+
+// This flag causes the Google Test to list tests. None of the tests listed
+// are actually run if the flag is provided.
+GTEST_DECLARE_bool_(list_tests);
+
+// This flag controls whether Google Test emits a detailed XML report to a file
+// in addition to its normal textual output.
+GTEST_DECLARE_string_(output);
+
+// This flags control whether Google Test prints the elapsed time for each
+// test.
+GTEST_DECLARE_bool_(print_time);
+
+// This flag specifies the random number seed.
+GTEST_DECLARE_int32_(random_seed);
+
+// This flag sets how many times the tests are repeated. The default value
+// is 1. If the value is -1 the tests are repeating forever.
+GTEST_DECLARE_int32_(repeat);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool_(show_internal_stack_frames);
+
+// When this flag is specified, tests' order is randomized on every iteration.
+GTEST_DECLARE_bool_(shuffle);
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32_(stack_trace_depth);
+
+// When this flag is specified, a failed assertion will throw an
+// exception if exceptions are enabled, or exit the program with a
+// non-zero code otherwise.
+GTEST_DECLARE_bool_(throw_on_failure);
+
+// When this flag is set with a "host:port" string, on supported
+// platforms test results are streamed to the specified port on
+// the specified host machine.
+GTEST_DECLARE_string_(stream_result_to);
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+namespace internal {
+
+class AssertHelper;
+class DefaultGlobalTestPartResultReporter;
+class ExecDeathTest;
+class NoExecDeathTest;
+class FinalSuccessChecker;
+class GTestFlagSaver;
+class TestResultAccessor;
+class TestEventListenersAccessor;
+class TestEventRepeater;
+class WindowsDeathTest;
+class UnitTestImpl* GetUnitTestImpl();
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message);
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared in gtest-internal.h but defined here, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable) {
+  return (Message() << streamable).GetString();
+}
+
+}  // namespace internal
+
+// The friend relationship of some of these classes is cyclic.
+// If we don't forward declare them the compiler might confuse the classes
+// in friendship clauses with same named classes on the scope.
+class Test;
+class TestCase;
+class TestInfo;
+class UnitTest;
+
+// A class for indicating whether an assertion was successful.  When
+// the assertion wasn't successful, the AssertionResult object
+// remembers a non-empty message that describes how it failed.
+//
+// To create an instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// This class is useful for two purposes:
+//   1. Defining predicate functions to be used with Boolean test assertions
+//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+//   2. Defining predicate-format functions to be
+//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false (5 is odd)
+//   Expected: true
+//
+// instead of a more opaque
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false
+//   Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess() << n << " is even";
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+//   Value of: IsEven(Fib(6))
+//     Actual: true (8 is even)
+//   Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
+//
+//   // Verifies that Foo() returns an even number.
+//   EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you need to define:
+//
+//   testing::AssertionResult IsEven(const char* expr, int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure()
+//         << "Expected: " << expr << " is even\n  Actual: it's " << n;
+//   }
+//
+// If Foo() returns 5, you will see the following message:
+//
+//   Expected: Foo() is even
+//     Actual: it's 5
+//
+class GTEST_API_ AssertionResult {
+ public:
+  // Copy constructor.
+  // Used in EXPECT_TRUE/FALSE(assertion_result).
+  AssertionResult(const AssertionResult& other);
+  // Used in the EXPECT_TRUE/FALSE(bool_expression).
+  explicit AssertionResult(bool success) : success_(success) {}
+
+  // Returns true iff the assertion succeeded.
+  operator bool() const { return success_; }  // NOLINT
+
+  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+  AssertionResult operator!() const;
+
+  // Returns the text streamed into this AssertionResult. Test assertions
+  // use it when they fail (i.e., the predicate's outcome doesn't match the
+  // assertion's expectation). When nothing has been streamed into the
+  // object, returns an empty string.
+  const char* message() const {
+    return message_.get() != NULL ?  message_->c_str() : "";
+  }
+  // TODO(vladl@google.com): Remove this after making sure no clients use it.
+  // Deprecated; please use message() instead.
+  const char* failure_message() const { return message(); }
+
+  // Streams a custom failure message into this object.
+  template <typename T> AssertionResult& operator<<(const T& value) {
+    AppendMessage(Message() << value);
+    return *this;
+  }
+
+  // Allows streaming basic output manipulators such as endl or flush into
+  // this object.
+  AssertionResult& operator<<(
+      ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
+    AppendMessage(Message() << basic_manipulator);
+    return *this;
+  }
+
+ private:
+  // Appends the contents of message to message_.
+  void AppendMessage(const Message& a_message) {
+    if (message_.get() == NULL)
+      message_.reset(new ::std::string);
+    message_->append(a_message.GetString().c_str());
+  }
+
+  // Stores result of the assertion predicate.
+  bool success_;
+  // Stores the message describing the condition in case the expectation
+  // construct is not satisfied with the predicate's outcome.
+  // Referenced via a pointer to avoid taking too much stack frame space
+  // with test assertions.
+  internal::scoped_ptr< ::std::string> message_;
+
+  GTEST_DISALLOW_ASSIGN_(AssertionResult);
+};
+
+// Makes a successful assertion result.
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
+
+// The abstract class that all tests inherit from.
+//
+// In Google Test, a unit test program contains one or many TestCases, and
+// each TestCase contains one or many Tests.
+//
+// When you define a test using the TEST macro, you don't need to
+// explicitly derive from Test - the TEST macro automatically does
+// this for you.
+//
+// The only time you derive from Test is when defining a test fixture
+// to be used a TEST_F.  For example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { ... }
+//     virtual void TearDown() { ... }
+//     ...
+//   };
+//
+//   TEST_F(FooTest, Bar) { ... }
+//   TEST_F(FooTest, Baz) { ... }
+//
+// Test is not copyable.
+class GTEST_API_ Test {
+ public:
+  friend class TestInfo;
+
+  // Defines types for pointers to functions that set up and tear down
+  // a test case.
+  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
+  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
+
+  // The d'tor is virtual as we intend to inherit from Test.
+  virtual ~Test();
+
+  // Sets up the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::SetUpTestCase() before running the first
+  // test in test case Foo.  Hence a sub-class can define its own
+  // SetUpTestCase() method to shadow the one defined in the super
+  // class.
+  static void SetUpTestCase() {}
+
+  // Tears down the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::TearDownTestCase() after running the last
+  // test in test case Foo.  Hence a sub-class can define its own
+  // TearDownTestCase() method to shadow the one defined in the super
+  // class.
+  static void TearDownTestCase() {}
+
+  // Returns true iff the current test has a fatal failure.
+  static bool HasFatalFailure();
+
+  // Returns true iff the current test has a non-fatal failure.
+  static bool HasNonfatalFailure();
+
+  // Returns true iff the current test has a (either fatal or
+  // non-fatal) failure.
+  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
+
+  // Logs a property for the current test.  Only the last value for a given
+  // key is remembered.
+  // These are public static so they can be called from utility functions
+  // that are not members of the test fixture.
+  // The arguments are const char* instead strings, as Google Test is used
+  // on platforms where string doesn't compile.
+  //
+  // Note that a driving consideration for these RecordProperty methods
+  // was to produce xml output suited to the Greenspan charting utility,
+  // which at present will only chart values that fit in a 32-bit int. It
+  // is the user's responsibility to restrict their values to 32-bit ints
+  // if they intend them to be used with Greenspan.
+  static void RecordProperty(const char* key, const char* value);
+  static void RecordProperty(const char* key, int value);
+
+ protected:
+  // Creates a Test object.
+  Test();
+
+  // Sets up the test fixture.
+  virtual void SetUp();
+
+  // Tears down the test fixture.
+  virtual void TearDown();
+
+ private:
+  // Returns true iff the current test has the same fixture class as
+  // the first test in the current test case.
+  static bool HasSameFixtureClass();
+
+  // Runs the test after the test fixture has been set up.
+  //
+  // A sub-class must implement this to define the test logic.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
+  // Instead, use the TEST or TEST_F macro.
+  virtual void TestBody() = 0;
+
+  // Sets up, executes, and tears down the test.
+  void Run();
+
+  // Deletes self.  We deliberately pick an unusual name for this
+  // internal method to avoid clashing with names used in user TESTs.
+  void DeleteSelf_() { delete this; }
+
+  // Uses a GTestFlagSaver to save and restore all Google Test flags.
+  const internal::GTestFlagSaver* const gtest_flag_saver_;
+
+  // Often a user mis-spells SetUp() as Setup() and spends a long time
+  // wondering why it is never called by Google Test.  The declaration of
+  // the following method is solely for catching such an error at
+  // compile time:
+  //
+  //   - The return type is deliberately chosen to be not void, so it
+  //   will be a conflict if a user declares void Setup() in his test
+  //   fixture.
+  //
+  //   - This method is private, so it will be another compiler error
+  //   if a user calls it from his test fixture.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION.
+  //
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+
+  // We disallow copying Tests.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
+};
+
+typedef internal::TimeInMillis TimeInMillis;
+
+// A copyable object representing a user specified test property which can be
+// output as a key/value string pair.
+//
+// Don't inherit from TestProperty as its destructor is not virtual.
+class TestProperty {
+ public:
+  // C'tor.  TestProperty does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestProperty object.
+  TestProperty(const char* a_key, const char* a_value) :
+    key_(a_key), value_(a_value) {
+  }
+
+  // Gets the user supplied key.
+  const char* key() const {
+    return key_.c_str();
+  }
+
+  // Gets the user supplied value.
+  const char* value() const {
+    return value_.c_str();
+  }
+
+  // Sets a new value, overriding the one supplied in the constructor.
+  void SetValue(const char* new_value) {
+    value_ = new_value;
+  }
+
+ private:
+  // The key supplied by the user.
+  internal::String key_;
+  // The value supplied by the user.
+  internal::String value_;
+};
+
+// The result of a single Test.  This includes a list of
+// TestPartResults, a list of TestProperties, a count of how many
+// death tests there are in the Test, and how much time it took to run
+// the Test.
+//
+// TestResult is not copyable.
+class GTEST_API_ TestResult {
+ public:
+  // Creates an empty TestResult.
+  TestResult();
+
+  // D'tor.  Do not inherit from TestResult.
+  ~TestResult();
+
+  // Gets the number of all test parts.  This is the sum of the number
+  // of successful test parts and the number of failed test parts.
+  int total_part_count() const;
+
+  // Returns the number of the test properties.
+  int test_property_count() const;
+
+  // Returns true iff the test passed (i.e. no test part failed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test failed.
+  bool Failed() const;
+
+  // Returns true iff the test fatally failed.
+  bool HasFatalFailure() const;
+
+  // Returns true iff the test has a non-fatal failure.
+  bool HasNonfatalFailure() const;
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test part result among all the results. i can range
+  // from 0 to test_property_count() - 1. If i is not in that range, aborts
+  // the program.
+  const TestPartResult& GetTestPartResult(int i) const;
+
+  // Returns the i-th test property. i can range from 0 to
+  // test_property_count() - 1. If i is not in that range, aborts the
+  // program.
+  const TestProperty& GetTestProperty(int i) const;
+
+ private:
+  friend class TestInfo;
+  friend class UnitTest;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::ExecDeathTest;
+  friend class internal::TestResultAccessor;
+  friend class internal::UnitTestImpl;
+  friend class internal::WindowsDeathTest;
+
+  // Gets the vector of TestPartResults.
+  const std::vector<TestPartResult>& test_part_results() const {
+    return test_part_results_;
+  }
+
+  // Gets the vector of TestProperties.
+  const std::vector<TestProperty>& test_properties() const {
+    return test_properties_;
+  }
+
+  // Sets the elapsed time.
+  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+  // Adds a test property to the list. The property is validated and may add
+  // a non-fatal failure if invalid (e.g., if it conflicts with reserved
+  // key names). If a property is already recorded for the same key, the
+  // value will be updated, rather than storing multiple values for the same
+  // key.
+  void RecordProperty(const TestProperty& test_property);
+
+  // Adds a failure if the key is a reserved attribute of Google Test
+  // testcase tags.  Returns true if the property is valid.
+  // TODO(russr): Validate attribute names are legal and human readable.
+  static bool ValidateTestProperty(const TestProperty& test_property);
+
+  // Adds a test part result to the list.
+  void AddTestPartResult(const TestPartResult& test_part_result);
+
+  // Returns the death test count.
+  int death_test_count() const { return death_test_count_; }
+
+  // Increments the death test count, returning the new count.
+  int increment_death_test_count() { return ++death_test_count_; }
+
+  // Clears the test part results.
+  void ClearTestPartResults();
+
+  // Clears the object.
+  void Clear();
+
+  // Protects mutable state of the property vector and of owned
+  // properties, whose values may be updated.
+  internal::Mutex test_properites_mutex_;
+
+  // The vector of TestPartResults
+  std::vector<TestPartResult> test_part_results_;
+  // The vector of TestProperties
+  std::vector<TestProperty> test_properties_;
+  // Running count of death tests.
+  int death_test_count_;
+  // The elapsed time, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestResult.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);
+};  // class TestResult
+
+// A TestInfo object stores the following information about a test:
+//
+//   Test case name
+//   Test name
+//   Whether the test should be run
+//   A function pointer that creates the test object when invoked
+//   Test result
+//
+// The constructor of TestInfo registers itself with the UnitTest
+// singleton such that the RUN_ALL_TESTS() macro knows which tests to
+// run.
+class GTEST_API_ TestInfo {
+ public:
+  // Destructs a TestInfo object.  This function is not virtual, so
+  // don't inherit from TestInfo.
+  ~TestInfo();
+
+  // Returns the test case name.
+  const char* test_case_name() const { return test_case_name_.c_str(); }
+
+  // Returns the test name.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns the name of the parameter type, or NULL if this is not a typed
+  // or a type-parameterized test.
+  const char* type_param() const {
+    if (type_param_.get() != NULL)
+      return type_param_->c_str();
+    return NULL;
+  }
+
+  // Returns the text representation of the value parameter, or NULL if this
+  // is not a value-parameterized test.
+  const char* value_param() const {
+    if (value_param_.get() != NULL)
+      return value_param_->c_str();
+    return NULL;
+  }
+
+  // Returns true if this test should run, that is if the test is not disabled
+  // (or it is disabled but the also_run_disabled_tests flag has been specified)
+  // and its full name matches the user-specified filter.
+  //
+  // Google Test allows the user to filter the tests by their full names.
+  // The full name of a test Bar in test case Foo is defined as
+  // "Foo.Bar".  Only the tests that match the filter will run.
+  //
+  // A filter is a colon-separated list of glob (not regex) patterns,
+  // optionally followed by a '-' and a colon-separated list of
+  // negative patterns (tests to exclude).  A test is run if it
+  // matches one of the positive patterns and does not match any of
+  // the negative patterns.
+  //
+  // For example, *A*:Foo.* is a filter that matches any string that
+  // contains the character 'A' or starts with "Foo.".
+  bool should_run() const { return should_run_; }
+
+  // Returns the result of the test.
+  const TestResult* result() const { return &result_; }
+
+ private:
+
+#if GTEST_HAS_DEATH_TEST
+  friend class internal::DefaultDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+  friend class Test;
+  friend class TestCase;
+  friend class internal::UnitTestImpl;
+  friend TestInfo* internal::MakeAndRegisterTestInfo(
+      const char* test_case_name, const char* name,
+      const char* type_param,
+      const char* value_param,
+      internal::TypeId fixture_class_id,
+      Test::SetUpTestCaseFunc set_up_tc,
+      Test::TearDownTestCaseFunc tear_down_tc,
+      internal::TestFactoryBase* factory);
+
+  // Constructs a TestInfo object. The newly constructed instance assumes
+  // ownership of the factory object.
+  TestInfo(const char* test_case_name, const char* name,
+           const char* a_type_param,
+           const char* a_value_param,
+           internal::TypeId fixture_class_id,
+           internal::TestFactoryBase* factory);
+
+  // Increments the number of death tests encountered in this test so
+  // far.
+  int increment_death_test_count() {
+    return result_.increment_death_test_count();
+  }
+
+  // Creates the test object, runs it, records its result, and then
+  // deletes it.
+  void Run();
+
+  static void ClearTestResult(TestInfo* test_info) {
+    test_info->result_.Clear();
+  }
+
+  // These fields are immutable properties of the test.
+  const std::string test_case_name_;     // Test case name
+  const std::string name_;               // Test name
+  // Name of the parameter type, or NULL if this is not a typed or a
+  // type-parameterized test.
+  const internal::scoped_ptr<const ::std::string> type_param_;
+  // Text representation of the value parameter, or NULL if this is not a
+  // value-parameterized test.
+  const internal::scoped_ptr<const ::std::string> value_param_;
+  const internal::TypeId fixture_class_id_;   // ID of the test fixture class
+  bool should_run_;                 // True iff this test should run
+  bool is_disabled_;                // True iff this test is disabled
+  bool matches_filter_;             // True if this test matches the
+                                    // user-specified filter.
+  internal::TestFactoryBase* const factory_;  // The factory that creates
+                                              // the test object
+
+  // This field is mutable and needs to be reset before running the
+  // test for the second time.
+  TestResult result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
+};
+
+// A test case, which consists of a vector of TestInfos.
+//
+// TestCase is not copyable.
+class GTEST_API_ TestCase {
+ public:
+  // Creates a TestCase with the given name.
+  //
+  // TestCase does NOT have a default constructor.  Always use this
+  // constructor to create a TestCase object.
+  //
+  // Arguments:
+  //
+  //   name:         name of the test case
+  //   a_type_param: the name of the test's type parameter, or NULL if
+  //                 this is not a type-parameterized test.
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  TestCase(const char* name, const char* a_type_param,
+           Test::SetUpTestCaseFunc set_up_tc,
+           Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Destructor of TestCase.
+  virtual ~TestCase();
+
+  // Gets the name of the TestCase.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns the name of the parameter type, or NULL if this is not a
+  // type-parameterized test case.
+  const char* type_param() const {
+    if (type_param_.get() != NULL)
+      return type_param_->c_str();
+    return NULL;
+  }
+
+  // Returns true if any test in this test case should run.
+  bool should_run() const { return should_run_; }
+
+  // Gets the number of successful tests in this test case.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests in this test case.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests in this test case.
+  int disabled_test_count() const;
+
+  // Get the number of tests in this test case that should run.
+  int test_to_run_count() const;
+
+  // Gets the number of all tests in this test case.
+  int total_test_count() const;
+
+  // Returns true iff the test case passed.
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test case failed.
+  bool Failed() const { return failed_test_count() > 0; }
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  const TestInfo* GetTestInfo(int i) const;
+
+ private:
+  friend class Test;
+  friend class internal::UnitTestImpl;
+
+  // Gets the (mutable) vector of TestInfos in this TestCase.
+  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
+
+  // Gets the (immutable) vector of TestInfos in this TestCase.
+  const std::vector<TestInfo*>& test_info_list() const {
+    return test_info_list_;
+  }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  TestInfo* GetMutableTestInfo(int i);
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
+  // destruction of the TestCase object.
+  void AddTestInfo(TestInfo * test_info);
+
+  // Clears the results of all tests in this test case.
+  void ClearResult();
+
+  // Clears the results of all tests in the given test case.
+  static void ClearTestCaseResult(TestCase* test_case) {
+    test_case->ClearResult();
+  }
+
+  // Runs every test in this TestCase.
+  void Run();
+
+  // Runs SetUpTestCase() for this TestCase.  This wrapper is needed
+  // for catching exceptions thrown from SetUpTestCase().
+  void RunSetUpTestCase() { (*set_up_tc_)(); }
+
+  // Runs TearDownTestCase() for this TestCase.  This wrapper is
+  // needed for catching exceptions thrown from TearDownTestCase().
+  void RunTearDownTestCase() { (*tear_down_tc_)(); }
+
+  // Returns true iff test passed.
+  static bool TestPassed(const TestInfo* test_info) {
+    return test_info->should_run() && test_info->result()->Passed();
+  }
+
+  // Returns true iff test failed.
+  static bool TestFailed(const TestInfo* test_info) {
+    return test_info->should_run() && test_info->result()->Failed();
+  }
+
+  // Returns true iff test is disabled.
+  static bool TestDisabled(const TestInfo* test_info) {
+    return test_info->is_disabled_;
+  }
+
+  // Returns true if the given test should run.
+  static bool ShouldRunTest(const TestInfo* test_info) {
+    return test_info->should_run();
+  }
+
+  // Shuffles the tests in this test case.
+  void ShuffleTests(internal::Random* random);
+
+  // Restores the test order to before the first shuffle.
+  void UnshuffleTests();
+
+  // Name of the test case.
+  internal::String name_;
+  // Name of the parameter type, or NULL if this is not a typed or a
+  // type-parameterized test.
+  const internal::scoped_ptr<const ::std::string> type_param_;
+  // The vector of TestInfos in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestInfo*> test_info_list_;
+  // Provides a level of indirection for the test list to allow easy
+  // shuffling and restoring the test order.  The i-th element in this
+  // vector is the index of the i-th test in the shuffled test list.
+  std::vector<int> test_indices_;
+  // Pointer to the function that sets up the test case.
+  Test::SetUpTestCaseFunc set_up_tc_;
+  // Pointer to the function that tears down the test case.
+  Test::TearDownTestCaseFunc tear_down_tc_;
+  // True iff any test in this test case should run.
+  bool should_run_;
+  // Elapsed time, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestCases.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+};
+
+// An Environment object is capable of setting up and tearing down an
+// environment.  The user should subclass this to define his own
+// environment(s).
+//
+// An Environment object does the set-up and tear-down in virtual
+// methods SetUp() and TearDown() instead of the constructor and the
+// destructor, as:
+//
+//   1. You cannot safely throw from a destructor.  This is a problem
+//      as in some cases Google Test is used where exceptions are enabled, and
+//      we may want to implement ASSERT_* using exceptions where they are
+//      available.
+//   2. You cannot use ASSERT_* directly in a constructor or
+//      destructor.
+class Environment {
+ public:
+  // The d'tor is virtual as we need to subclass Environment.
+  virtual ~Environment() {}
+
+  // Override this to define how to set up the environment.
+  virtual void SetUp() {}
+
+  // Override this to define how to tear down the environment.
+  virtual void TearDown() {}
+ private:
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+};
+
+// The interface for tracing execution of tests. The methods are organized in
+// the order the corresponding events are fired.
+class TestEventListener {
+ public:
+  virtual ~TestEventListener() {}
+
+  // Fired before any test activity starts.
+  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
+
+  // Fired before each iteration of tests starts.  There may be more than
+  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
+  // index, starting from 0.
+  virtual void OnTestIterationStart(const UnitTest& unit_test,
+                                    int iteration) = 0;
+
+  // Fired before environment set-up for each iteration of tests starts.
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment set-up for each iteration of tests ends.
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
+
+  // Fired before the test case starts.
+  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+
+  // Fired before the test starts.
+  virtual void OnTestStart(const TestInfo& test_info) = 0;
+
+  // Fired after a failed assertion or a SUCCEED() invocation.
+  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
+
+  // Fired after the test ends.
+  virtual void OnTestEnd(const TestInfo& test_info) = 0;
+
+  // Fired after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+
+  // Fired before environment tear-down for each iteration of tests starts.
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment tear-down for each iteration of tests ends.
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
+
+  // Fired after each iteration of tests finishes.
+  virtual void OnTestIterationEnd(const UnitTest& unit_test,
+                                  int iteration) = 0;
+
+  // Fired after all test activities have ended.
+  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build.  For
+// comments about each method please see the definition of TestEventListener
+// above.
+class EmptyTestEventListener : public TestEventListener {
+ public:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int /*iteration*/) {}
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int /*iteration*/) {}
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+// TestEventListeners lets users add listeners to track events in Google Test.
+class GTEST_API_ TestEventListeners {
+ public:
+  TestEventListeners();
+  ~TestEventListeners();
+
+  // Appends an event listener to the end of the list. Google Test assumes
+  // the ownership of the listener (i.e. it will delete the listener when
+  // the test program finishes).
+  void Append(TestEventListener* listener);
+
+  // Removes the given event listener from the list and returns it.  It then
+  // becomes the caller's responsibility to delete the listener. Returns
+  // NULL if the listener is not found in the list.
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Returns the standard listener responsible for the default console
+  // output.  Can be removed from the listeners list to shut down default
+  // console output.  Note that removing this object from the listener list
+  // with Release transfers its ownership to the caller and makes this
+  // function return NULL the next time.
+  TestEventListener* default_result_printer() const {
+    return default_result_printer_;
+  }
+
+  // Returns the standard listener responsible for the default XML output
+  // controlled by the --gtest_output=xml flag.  Can be removed from the
+  // listeners list by users who want to shut down the default XML output
+  // controlled by this flag and substitute it with custom one.  Note that
+  // removing this object from the listener list with Release transfers its
+  // ownership to the caller and makes this function return NULL the next
+  // time.
+  TestEventListener* default_xml_generator() const {
+    return default_xml_generator_;
+  }
+
+ private:
+  friend class TestCase;
+  friend class TestInfo;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::NoExecDeathTest;
+  friend class internal::TestEventListenersAccessor;
+  friend class internal::UnitTestImpl;
+
+  // Returns repeater that broadcasts the TestEventListener events to all
+  // subscribers.
+  TestEventListener* repeater();
+
+  // Sets the default_result_printer attribute to the provided listener.
+  // The listener is also added to the listener list and previous
+  // default_result_printer is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultResultPrinter(TestEventListener* listener);
+
+  // Sets the default_xml_generator attribute to the provided listener.  The
+  // listener is also added to the listener list and previous
+  // default_xml_generator is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultXmlGenerator(TestEventListener* listener);
+
+  // Controls whether events will be forwarded by the repeater to the
+  // listeners in the list.
+  bool EventForwardingEnabled() const;
+  void SuppressEventForwarding();
+
+  // The actual list of listeners.
+  internal::TestEventRepeater* repeater_;
+  // Listener responsible for the standard result output.
+  TestEventListener* default_result_printer_;
+  // Listener responsible for the creation of the XML output file.
+  TestEventListener* default_xml_generator_;
+
+  // We disallow copying TestEventListeners.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
+};
+
+// A UnitTest consists of a vector of TestCases.
+//
+// This is a singleton class.  The only instance of UnitTest is
+// created when UnitTest::GetInstance() is first called.  This
+// instance is never deleted.
+//
+// UnitTest is not copyable.
+//
+// This class is thread-safe as long as the methods are called
+// according to their specification.
+class GTEST_API_ UnitTest {
+ public:
+  // Gets the singleton UnitTest object.  The first time this method
+  // is called, a UnitTest object is constructed and returned.
+  // Consecutive calls will return the same object.
+  static UnitTest* GetInstance();
+
+  // Runs all tests in this UnitTest object and prints the result.
+  // Returns 0 if successful, or 1 otherwise.
+  //
+  // This method can only be called from the main thread.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  int Run() GTEST_MUST_USE_RESULT_;
+
+  // Returns the working directory when the first TEST() or TEST_F()
+  // was executed.  The UnitTest object owns the string.
+  const char* original_working_dir() const;
+
+  // Returns the TestCase object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestCase* current_test_case() const;
+
+  // Returns the TestInfo object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestInfo* current_test_info() const;
+
+  // Returns the random seed used at the start of the current test run.
+  int random_seed() const;
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns the ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const;
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const;
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const;
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const;
+
+  // Returns the list of event listeners that can be used to track events
+  // inside Google Test.
+  TestEventListeners& listeners();
+
+ private:
+  // Registers and returns a global test environment.  When a test
+  // program is run, all global test environments will be set-up in
+  // the order they were registered.  After all tests in the program
+  // have finished, all global test environments will be torn-down in
+  // the *reverse* order they were registered.
+  //
+  // The UnitTest object takes ownership of the given environment.
+  //
+  // This method can only be called from the main thread.
+  Environment* AddEnvironment(Environment* env);
+
+  // Adds a TestPartResult to the current TestResult object.  All
+  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
+  // eventually call this to report their results.  The user code
+  // should use the assertion macros instead of calling this directly.
+  void AddTestPartResult(TestPartResult::Type result_type,
+                         const char* file_name,
+                         int line_number,
+                         const internal::String& message,
+                         const internal::String& os_stack_trace);
+
+  // Adds a TestProperty to the current TestResult object. If the result already
+  // contains a property with the same key, the value will be updated.
+  void RecordPropertyForCurrentTest(const char* key, const char* value);
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i);
+
+  // Accessors for the implementation object.
+  internal::UnitTestImpl* impl() { return impl_; }
+  const internal::UnitTestImpl* impl() const { return impl_; }
+
+  // These classes and funcions are friends as they need to access private
+  // members of UnitTest.
+  friend class Test;
+  friend class internal::AssertHelper;
+  friend class internal::ScopedTrace;
+  friend Environment* AddGlobalTestEnvironment(Environment* env);
+  friend internal::UnitTestImpl* internal::GetUnitTestImpl();
+  friend void internal::ReportFailureInUnknownLocation(
+      TestPartResult::Type result_type,
+      const internal::String& message);
+
+  // Creates an empty UnitTest.
+  UnitTest();
+
+  // D'tor
+  virtual ~UnitTest();
+
+  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+  // Google Test trace stack.
+  void PushGTestTrace(const internal::TraceInfo& trace);
+
+  // Pops a trace from the per-thread Google Test trace stack.
+  void PopGTestTrace();
+
+  // Protects mutable state in *impl_.  This is mutable as some const
+  // methods need to lock it too.
+  mutable internal::Mutex mutex_;
+
+  // Opaque implementation object.  This field is never changed once
+  // the object is constructed.  We don't mark it as const here, as
+  // doing so will cause a warning in the constructor of UnitTest.
+  // Mutable state in *impl_ is protected by mutex_.
+  internal::UnitTestImpl* impl_;
+
+  // We disallow copying UnitTest.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest);
+};
+
+// A convenient wrapper for adding an environment for the test
+// program.
+//
+// You should call this before RUN_ALL_TESTS() is called, probably in
+// main().  If you use gtest_main, you need to call this before main()
+// starts for it to take effect.  For example, you can define a global
+// variable like this:
+//
+//   testing::Environment* const foo_env =
+//       testing::AddGlobalTestEnvironment(new FooEnvironment);
+//
+// However, we strongly recommend you to write your own main() and
+// call AddGlobalTestEnvironment() there, as relying on initialization
+// of global variables makes the code harder to read and may cause
+// problems when you register multiple environments from different
+// translation units and the environments have dependencies among them
+// (remember that the compiler doesn't guarantee the order in which
+// global variables from different translation units are initialized).
+inline Environment* AddGlobalTestEnvironment(Environment* env) {
+  return UnitTest::GetInstance()->AddEnvironment(env);
+}
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it parses a command line for the
+// flags that Google Test recognizes.  Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+
+namespace internal {
+
+// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
+// operand to be used in a failure message.  The type (but not value)
+// of the other operand may affect the format.  This allows us to
+// print a char* as a raw pointer when it is compared against another
+// char*, and print it as a C string when it is compared against an
+// std::string object, for example.
+//
+// The default implementation ignores the type of the other operand.
+// Some specialized versions are used to handle formatting wide or
+// narrow C strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename T1, typename T2>
+String FormatForComparisonFailureMessage(const T1& value,
+                                         const T2& /* other_operand */) {
+  // C++Builder compiles this incorrectly if the namespace isn't explicitly
+  // given.
+  return ::testing::PrintToString(value);
+}
+
+// The helper function for {ASSERT|EXPECT}_EQ.
+template <typename T1, typename T2>
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            const T1& expected,
+                            const T2& actual) {
+#ifdef _MSC_VER
+# pragma warning(push)          // Saves the current warning state.
+# pragma warning(disable:4389)  // Temporarily disables warning on
+                               // signed/unsigned mismatch.
+#endif
+
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+#ifdef _MSC_VER
+# pragma warning(pop)          // Restores the warning state.
+#endif
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// With this overloaded version, we allow anonymous enums to be used
+// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
+// can be implicitly cast to BiggestInt.
+GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,
+                                       const char* actual_expression,
+                                       BiggestInt expected,
+                                       BiggestInt actual);
+
+// The helper class for {ASSERT|EXPECT}_EQ.  The template argument
+// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
+// is a null pointer literal.  The following default implementation is
+// for lhs_is_null_literal being false.
+template <bool lhs_is_null_literal>
+class EqHelper {
+ public:
+  // This templatized version is for the general case.
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 const T2& actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // With this overloaded version, we allow anonymous enums to be used
+  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
+  // enums can be implicitly cast to BiggestInt.
+  //
+  // Even though its body looks the same as the above version, we
+  // cannot merge the two, as it will make anonymous enums unhappy.
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 BiggestInt expected,
+                                 BiggestInt actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+};
+
+// This specialization is used when the first argument to ASSERT_EQ()
+// is a null pointer literal, like NULL, false, or 0.
+template <>
+class EqHelper<true> {
+ public:
+  // We define two overloaded versions of Compare().  The first
+  // version will be picked when the second argument to ASSERT_EQ() is
+  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
+  // EXPECT_EQ(false, a_bool).
+  template <typename T1, typename T2>
+  static AssertionResult Compare(
+      const char* expected_expression,
+      const char* actual_expression,
+      const T1& expected,
+      const T2& actual,
+      // The following line prevents this overload from being considered if T2
+      // is not a pointer type.  We need this because ASSERT_EQ(NULL, my_ptr)
+      // expands to Compare("", "", NULL, my_ptr), which requires a conversion
+      // to match the Secret* in the other overload, which would otherwise make
+      // this template match better.
+      typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // This version will be picked when the second argument to ASSERT_EQ() is a
+  // pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+  template <typename T>
+  static AssertionResult Compare(
+      const char* expected_expression,
+      const char* actual_expression,
+      // We used to have a second template parameter instead of Secret*.  That
+      // template parameter would deduce to 'long', making this a better match
+      // than the first overload even without the first overload's EnableIf.
+      // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to
+      // non-pointer argument" (even a deduced integral argument), so the old
+      // implementation caused warnings in user code.
+      Secret* /* expected (NULL) */,
+      T* actual) {
+    // We already know that 'expected' is a null pointer.
+    return CmpHelperEQ(expected_expression, actual_expression,
+                       static_cast<T*>(NULL), actual);
+  }
+};
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste
+// of similar code.
+//
+// For each templatized helper function, we also define an overloaded
+// version for BiggestInt in order to reduce code bloat and allow
+// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
+// with gcc 4.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+template <typename T1, typename T2>\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   const T1& val1, const T2& val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    return AssertionFailure() \
+        << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+  }\
+}\
+GTEST_API_ AssertionResult CmpHelper##op_name(\
+    const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+
+// Implements the helper function for {ASSERT|EXPECT}_NE
+GTEST_IMPL_CMP_HELPER_(NE, !=);
+// Implements the helper function for {ASSERT|EXPECT}_LE
+GTEST_IMPL_CMP_HELPER_(LE, <=);
+// Implements the helper function for {ASSERT|EXPECT}_LT
+GTEST_IMPL_CMP_HELPER_(LT, < );
+// Implements the helper function for {ASSERT|EXPECT}_GE
+GTEST_IMPL_CMP_HELPER_(GE, >=);
+// Implements the helper function for {ASSERT|EXPECT}_GT
+GTEST_IMPL_CMP_HELPER_(GT, > );
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                                          const char* actual_expression,
+                                          const char* expected,
+                                          const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                              const char* actual_expression,
+                                              const char* expected,
+                                              const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                                          const char* s2_expression,
+                                          const char* s1,
+                                          const char* s2);
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                              const char* s2_expression,
+                                              const char* s1,
+                                              const char* s2);
+
+
+// Helper function for *_STREQ on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                                          const char* actual_expression,
+                                          const wchar_t* expected,
+                                          const wchar_t* actual);
+
+// Helper function for *_STRNE on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                                          const char* s2_expression,
+                                          const wchar_t* s1,
+                                          const wchar_t* s2);
+
+}  // namespace internal
+
+// IsSubstring() and IsNotSubstring() are intended to be used as the
+// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by
+// themselves.  They check whether needle is a substring of haystack
+// (NULL is considered a substring of itself only), and return an
+// appropriate error message when they fail.
+//
+// The {needle,haystack}_expr arguments are the stringified
+// expressions that generated the two real arguments.
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+// Helper template function for comparing floating-points.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename RawType>
+AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,
+                                         const char* actual_expression,
+                                         RawType expected,
+                                         RawType actual) {
+  const FloatingPoint<RawType> lhs(expected), rhs(actual);
+
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  ::std::stringstream expected_ss;
+  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+              << expected;
+
+  ::std::stringstream actual_ss;
+  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+            << actual;
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   StringStreamToString(&expected_ss),
+                   StringStreamToString(&actual_ss),
+                   false);
+}
+
+// Helper function for implementing ASSERT_NEAR.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,
+                                                const char* expr2,
+                                                const char* abs_error_expr,
+                                                double val1,
+                                                double val2,
+                                                double abs_error);
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+// A class that enables one to stream messages to assertion macros
+class GTEST_API_ AssertHelper {
+ public:
+  // Constructor.
+  AssertHelper(TestPartResult::Type type,
+               const char* file,
+               int line,
+               const char* message);
+  ~AssertHelper();
+
+  // Message assignment is a semantic trick to enable assertion
+  // streaming; see the GTEST_MESSAGE_ macro below.
+  void operator=(const Message& message) const;
+
+ private:
+  // We put our data in a struct so that the size of the AssertHelper class can
+  // be as small as possible.  This is important because gcc is incapable of
+  // re-using stack space even for temporary variables, so every EXPECT_EQ
+  // reserves stack space for another AssertHelper.
+  struct AssertHelperData {
+    AssertHelperData(TestPartResult::Type t,
+                     const char* srcfile,
+                     int line_num,
+                     const char* msg)
+        : type(t), file(srcfile), line(line_num), message(msg) { }
+
+    TestPartResult::Type const type;
+    const char*        const file;
+    int                const line;
+    String             const message;
+
+   private:
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
+  };
+
+  AssertHelperData* const data_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
+};
+
+}  // namespace internal
+
+#if GTEST_HAS_PARAM_TEST
+// The pure interface class that all value-parameterized tests inherit from.
+// A value-parameterized class must inherit from both ::testing::Test and
+// ::testing::WithParamInterface. In most cases that just means inheriting
+// from ::testing::TestWithParam, but more complicated test hierarchies
+// may need to inherit from Test and WithParamInterface at different levels.
+//
+// This interface has support for accessing the test parameter value via
+// the GetParam() method.
+//
+// Use it with one of the parameter generator defining functions, like Range(),
+// Values(), ValuesIn(), Bool(), and Combine().
+//
+// class FooTest : public ::testing::TestWithParam<int> {
+//  protected:
+//   FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual ~FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void SetUp() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void TearDown {
+//     // Can use GetParam() here.
+//   }
+// };
+// TEST_P(FooTest, DoesBar) {
+//   // Can use GetParam() method here.
+//   Foo foo;
+//   ASSERT_TRUE(foo.DoesBar(GetParam()));
+// }
+// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+
+template <typename T>
+class WithParamInterface {
+ public:
+  typedef T ParamType;
+  virtual ~WithParamInterface() {}
+
+  // The current parameter value. Is also available in the test fixture's
+  // constructor. This member function is non-static, even though it only
+  // references static data, to reduce the opportunity for incorrect uses
+  // like writing 'WithParamInterface<bool>::GetParam()' for a test that
+  // uses a fixture whose parameter type is int.
+  const ParamType& GetParam() const { return *parameter_; }
+
+ private:
+  // Sets parameter value. The caller is responsible for making sure the value
+  // remains alive and unchanged throughout the current test.
+  static void SetParam(const ParamType* parameter) {
+    parameter_ = parameter;
+  }
+
+  // Static value used for accessing parameter during a test lifetime.
+  static const ParamType* parameter_;
+
+  // TestClass must be a subclass of WithParamInterface<T> and Test.
+  template <class TestClass> friend class internal::ParameterizedTestFactory;
+};
+
+template <typename T>
+const T* WithParamInterface<T>::parameter_ = NULL;
+
+// Most value-parameterized classes can ignore the existence of
+// WithParamInterface, and can just inherit from ::testing::TestWithParam.
+
+template <typename T>
+class TestWithParam : public Test, public WithParamInterface<T> {
+};
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+// Macros for indicating success/failure in test code.
+
+// ADD_FAILURE unconditionally adds a failure to the current test.
+// SUCCEED generates a success - it doesn't automatically make the
+// current test successful, as a test is only successful when it has
+// no failure.
+//
+// EXPECT_* verifies that a certain condition is satisfied.  If not,
+// it behaves like ADD_FAILURE.  In particular:
+//
+//   EXPECT_TRUE  verifies that a Boolean condition is true.
+//   EXPECT_FALSE verifies that a Boolean condition is false.
+//
+// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except
+// that they will also abort the current function on failure.  People
+// usually want the fail-fast behavior of FAIL and ASSERT_*, but those
+// writing data-driven tests often find themselves using ADD_FAILURE
+// and EXPECT_* more.
+//
+// Examples:
+//
+//   EXPECT_TRUE(server.StatusIsOK());
+//   ASSERT_FALSE(server.HasPendingRequest(port))
+//       << "There are still pending requests " << "on port " << port;
+
+// Generates a nonfatal failure with a generic message.
+#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed")
+
+// Generates a nonfatal failure at the given source file location with
+// a generic message.
+#define ADD_FAILURE_AT(file, line) \
+  GTEST_MESSAGE_AT_(file, line, "Failed", \
+                    ::testing::TestPartResult::kNonFatalFailure)
+
+// Generates a fatal failure with a generic message.
+#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+# define FAIL() GTEST_FAIL()
+#endif
+
+// Generates a success with a generic message.
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+# define SUCCEED() GTEST_SUCCEED()
+#endif
+
+// Macros for testing exceptions.
+//
+//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+//         Tests that the statement throws the expected exception.
+//    * {ASSERT|EXPECT}_NO_THROW(statement):
+//         Tests that the statement doesn't throw any exception.
+//    * {ASSERT|EXPECT}_ANY_THROW(statement):
+//         Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
+#define ASSERT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
+#define ASSERT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
+
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
+#define EXPECT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+                      GTEST_NONFATAL_FAILURE_)
+#define EXPECT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+                      GTEST_NONFATAL_FAILURE_)
+#define ASSERT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
+                      GTEST_FATAL_FAILURE_)
+#define ASSERT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+                      GTEST_FATAL_FAILURE_)
+
+// Includes the auto-generated header that implements a family of
+// generic predicate assertion macros.
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command
+// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Makes sure this header is not included before gtest.h.
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+# error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+//   ASSERT_PRED_FORMAT1(pred_format, v1)
+//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+//   ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult.  See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+//   ASSERT_PRED1(pred, v1)
+//   ASSERT_PRED2(pred, v1, v2)
+//   ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most 5.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT_ is the basic statement to which all of the assertions
+// in this file reduce.  Don't use this in your code.
+
+#define GTEST_ASSERT_(expression, on_failure) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar = (expression)) \
+    ; \
+  else \
+    on_failure(gtest_ar.failure_message())
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1>
+AssertionResult AssertPred1Helper(const char* pred_text,
+                                  const char* e1,
+                                  Pred pred,
+                                  const T1& v1) {
+  if (pred(v1)) return AssertionSuccess();
+
+  return AssertionFailure() << pred_text << "("
+                            << e1 << ") evaluates to false, where"
+                            << "\n" << e1 << " evaluates to " << v1;
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, v1),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+#define GTEST_PRED1_(pred, v1, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
+                                             #v1, \
+                                             pred, \
+                                             v1), on_failure)
+
+// Unary predicate assertion macros.
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2>
+AssertionResult AssertPred2Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2) {
+  if (pred(v1, v2)) return AssertionSuccess();
+
+  return AssertionFailure() << pred_text << "("
+                            << e1 << ", "
+                            << e2 << ") evaluates to false, where"
+                            << "\n" << e1 << " evaluates to " << v1
+                            << "\n" << e2 << " evaluates to " << v2;
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+#define GTEST_PRED2_(pred, v1, v2, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             pred, \
+                                             v1, \
+                                             v2), on_failure)
+
+// Binary predicate assertion macros.
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3>
+AssertionResult AssertPred3Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3) {
+  if (pred(v1, v2, v3)) return AssertionSuccess();
+
+  return AssertionFailure() << pred_text << "("
+                            << e1 << ", "
+                            << e2 << ", "
+                            << e3 << ") evaluates to false, where"
+                            << "\n" << e1 << " evaluates to " << v1
+                            << "\n" << e2 << " evaluates to " << v2
+                            << "\n" << e3 << " evaluates to " << v3;
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3), on_failure)
+
+// Ternary predicate assertion macros.
+#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4>
+AssertionResult AssertPred4Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4) {
+  if (pred(v1, v2, v3, v4)) return AssertionSuccess();
+
+  return AssertionFailure() << pred_text << "("
+                            << e1 << ", "
+                            << e2 << ", "
+                            << e3 << ", "
+                            << e4 << ") evaluates to false, where"
+                            << "\n" << e1 << " evaluates to " << v1
+                            << "\n" << e2 << " evaluates to " << v2
+                            << "\n" << e3 << " evaluates to " << v3
+                            << "\n" << e4 << " evaluates to " << v4;
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4), on_failure)
+
+// 4-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4,
+          typename T5>
+AssertionResult AssertPred5Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  const char* e5,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4,
+                                  const T5& v5) {
+  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
+
+  return AssertionFailure() << pred_text << "("
+                            << e1 << ", "
+                            << e2 << ", "
+                            << e3 << ", "
+                            << e4 << ", "
+                            << e5 << ") evaluates to false, where"
+                            << "\n" << e1 << " evaluates to " << v1
+                            << "\n" << e2 << " evaluates to " << v2
+                            << "\n" << e3 << " evaluates to " << v3
+                            << "\n" << e4 << " evaluates to " << v4
+                            << "\n" << e5 << " evaluates to " << v5;
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             #v5, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4, \
+                                             v5), on_failure)
+
+// 5-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+
+
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Macros for testing equalities and inequalities.
+//
+//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
+//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2
+//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2
+//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2
+//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2
+//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2
+//
+// When they are not, Google Test prints both the tested expressions and
+// their actual values.  The values must be compatible built-in types,
+// or you will get a compiler error.  By "compatible" we mean that the
+// values can be compared by the respective operator.
+//
+// Note:
+//
+//   1. It is possible to make a user-defined type work with
+//   {ASSERT|EXPECT}_??(), but that requires overloading the
+//   comparison operators and is thus discouraged by the Google C++
+//   Usage Guide.  Therefore, you are advised to use the
+//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are
+//   equal.
+//
+//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on
+//   pointers (in particular, C strings).  Therefore, if you use it
+//   with two C strings, you are testing how their locations in memory
+//   are related, not how their content is related.  To compare two C
+//   strings by content, use {ASSERT|EXPECT}_STR*().
+//
+//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to
+//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you
+//   what the actual value is when it fails, and similarly for the
+//   other comparisons.
+//
+//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()
+//   evaluate their arguments, which is undefined.
+//
+//   5. These macros evaluate their arguments exactly once.
+//
+// Examples:
+//
+//   EXPECT_NE(5, Foo());
+//   EXPECT_EQ(NULL, a_pointer);
+//   ASSERT_LT(i, array_size);
+//   ASSERT_GT(records.size(), 0) << "There is no record left.";
+
+#define EXPECT_EQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+                      expected, actual)
+#define EXPECT_NE(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
+#define EXPECT_LE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define EXPECT_LT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define EXPECT_GE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define EXPECT_GT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+#define GTEST_ASSERT_EQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
+                      expected, actual)
+#define GTEST_ASSERT_NE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
+#define GTEST_ASSERT_LE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define GTEST_ASSERT_LT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define GTEST_ASSERT_GE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define GTEST_ASSERT_GT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of
+// ASSERT_XY(), which clashes with some users' own code.
+
+#if !GTEST_DONT_DEFINE_ASSERT_EQ
+# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)
+#endif
+
+#if !GTEST_DONT_DEFINE_ASSERT_NE
+# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)
+#endif
+
+#if !GTEST_DONT_DEFINE_ASSERT_LE
+# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)
+#endif
+
+#if !GTEST_DONT_DEFINE_ASSERT_LT
+# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)
+#endif
+
+#if !GTEST_DONT_DEFINE_ASSERT_GE
+# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)
+#endif
+
+#if !GTEST_DONT_DEFINE_ASSERT_GT
+# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)
+#endif
+
+// C String Comparisons.  All tests treat NULL and any non-NULL string
+// as different.  Two NULLs are equal.
+//
+//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2
+//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2
+//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
+//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
+//
+// For wide or narrow string objects, you can use the
+// {ASSERT|EXPECT}_??() macros.
+//
+// Don't depend on the order in which the arguments are evaluated,
+// which is undefined.
+//
+// These macros evaluate their arguments exactly once.
+
+#define EXPECT_STREQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define EXPECT_STRNE(s1, s2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define EXPECT_STRCASEEQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define EXPECT_STRCASENE(s1, s2)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+#define ASSERT_STREQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define ASSERT_STRNE(s1, s2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define ASSERT_STRCASEEQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define ASSERT_STRCASENE(s1, s2)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+// Macros for comparing floating-point numbers.
+//
+//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):
+//         Tests that two float values are almost equal.
+//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):
+//         Tests that two double values are almost equal.
+//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
+//         Tests that v1 and v2 are within the given distance to each other.
+//
+// Google Test uses ULP-based comparison to automatically pick a default
+// error bound that is appropriate for the operands.  See the
+// FloatingPoint template class in gtest-internal.h if you are
+// interested in the implementation details.
+
+#define EXPECT_FLOAT_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define EXPECT_DOUBLE_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define ASSERT_FLOAT_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define ASSERT_DOUBLE_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define EXPECT_NEAR(val1, val2, abs_error)\
+  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+#define ASSERT_NEAR(val1, val2, abs_error)\
+  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+// These predicate format functions work on floating-point values, and
+// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
+//
+//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+                                   float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                                    double val1, double val2);
+
+
+#if GTEST_OS_WINDOWS
+
+// Macros that test for HRESULT failure and success, these are only useful
+// on Windows, and rely on Windows SDK macros and APIs to compile.
+//
+//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
+//
+// When expr unexpectedly fails or succeeds, Google Test prints the
+// expected result and the actual result with both a human-readable
+// string representation of the error, if available, as well as the
+// hex result code.
+# define EXPECT_HRESULT_SUCCEEDED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+# define ASSERT_HRESULT_SUCCEEDED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+# define EXPECT_HRESULT_FAILED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+# define ASSERT_HRESULT_FAILED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#endif  // GTEST_OS_WINDOWS
+
+// Macros that execute statement and check that it doesn't generate new fatal
+// failures in the current thread.
+//
+//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
+//
+// Examples:
+//
+//   EXPECT_NO_FATAL_FAILURE(Process());
+//   ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
+//
+#define ASSERT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
+#define EXPECT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+
+// Causes a trace (including the source file path, the current line
+// number, and the given message) to be included in every test failure
+// message generated by code in the current scope.  The effect is
+// undone when the control leaves the current scope.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// In the implementation, we include the current line number as part
+// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
+// to appear in the same block - as long as they are on different
+// lines.
+#define SCOPED_TRACE(message) \
+  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
+    __FILE__, __LINE__, ::testing::Message() << (message))
+
+// Compile-time assertion for type equality.
+// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
+// the same type.  The value it returns is not interesting.
+//
+// Instead of making StaticAssertTypeEq a class template, we make it a
+// function template that invokes a helper class template.  This
+// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
+// defining objects of that type.
+//
+// CAVEAT:
+//
+// When used inside a method of a class template,
+// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
+// instantiated.  For example, given:
+//
+//   template <typename T> class Foo {
+//    public:
+//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }
+//   };
+//
+// the code:
+//
+//   void Test1() { Foo<bool> foo; }
+//
+// will NOT generate a compiler error, as Foo<bool>::Bar() is never
+// actually instantiated.  Instead, you need:
+//
+//   void Test2() { Foo<bool> foo; foo.Bar(); }
+//
+// to cause a compiler error.
+template <typename T1, typename T2>
+bool StaticAssertTypeEq() {
+  (void)internal::StaticAssertTypeEqHelper<T1, T2>();
+  return true;
+}
+
+// Defines a test.
+//
+// The first parameter is the name of the test case, and the second
+// parameter is the name of the test within the test case.
+//
+// The convention is to end the test case name with "Test".  For
+// example, a test case for the Foo class can be named FooTest.
+//
+// The user should put his test code between braces after using this
+// macro.  Example:
+//
+//   TEST(FooTest, InitializesCorrectly) {
+//     Foo foo;
+//     EXPECT_TRUE(foo.StatusIsOK());
+//   }
+
+// Note that we call GetTestTypeId() instead of GetTypeId<
+// ::testing::Test>() here to get the type ID of testing::Test.  This
+// is to work around a suspected linker bug when using Google Test as
+// a framework on Mac OS X.  The bug causes GetTypeId<
+// ::testing::Test>() to return different values depending on whether
+// the call is from the Google Test framework itself or from user test
+// code.  GetTestTypeId() is guaranteed to always return the same
+// value, as it always calls GetTypeId<>() from the Google Test
+// framework.
+#define GTEST_TEST(test_case_name, test_name)\
+  GTEST_TEST_(test_case_name, test_name, \
+              ::testing::Test, ::testing::internal::GetTestTypeId())
+
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
+
+// Defines a test that uses a test fixture.
+//
+// The first parameter is the name of the test fixture class, which
+// also doubles as the test case name.  The second parameter is the
+// name of the test within the test case.
+//
+// A test fixture class must be declared earlier.  The user should put
+// his test code between braces after using this macro.  Example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { b_.AddElement(3); }
+//
+//     Foo a_;
+//     Foo b_;
+//   };
+//
+//   TEST_F(FooTest, InitializesCorrectly) {
+//     EXPECT_TRUE(a_.StatusIsOK());
+//   }
+//
+//   TEST_F(FooTest, ReturnsElementCountCorrectly) {
+//     EXPECT_EQ(0, a_.size());
+//     EXPECT_EQ(1, b_.size());
+//   }
+
+#define TEST_F(test_fixture, test_name)\
+  GTEST_TEST_(test_fixture, test_name, test_fixture, \
+              ::testing::internal::GetTypeId<test_fixture>())
+
+// Use this macro in main() to run all tests.  It returns 0 if all
+// tests are successful, or 1 otherwise.
+//
+// RUN_ALL_TESTS() should be invoked after the command line has been
+// parsed by InitGoogleTest().
+
+#define RUN_ALL_TESTS()\
+  (::testing::UnitTest::GetInstance()->Run())
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/utils/gtest/obj/Makefile.am b/utils/gtest/obj/Makefile.am
new file mode 100644
index 0000000..4e80759
--- /dev/null
+++ b/utils/gtest/obj/Makefile.am
@@ -0,0 +1,20 @@
+# Automake file
+
+ACLOCAL_AMFLAGS = -I m4
+
+# We define the global AM_CPPFLAGS as everything we compile includes from these
+# directories.
+AM_CPPFLAGS = -I$(srcdir)/../include/
+
+# Modifies compiler and linker flags for pthreads compatibility.
+if HAVE_PTHREADS
+  AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
+  AM_LIBS = @PTHREAD_LIBS@
+else
+  AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
+endif
+
+# Build rules for libraries.
+noinst_LTLIBRARIES = ../lib/libgtest.la
+___lib_libgtest_la_SOURCES = ../src/gtest-all.cpp
+
diff --git a/utils/gtest/src/gtest-all.cpp b/utils/gtest/src/gtest-all.cpp
new file mode 100644
index 0000000..f8a58ae
--- /dev/null
+++ b/utils/gtest/src/gtest-all.cpp
@@ -0,0 +1,9118 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+// Google C++ Testing Framework (Google Test)
+//
+// Sometimes it's desirable to build Google Test by compiling a single file.
+// This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Utilities for testing Google Test itself and code that uses Google Test
+// (e.g. frameworks built on top of Google Test).
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+
+namespace testing {
+
+// This helper class can be used to mock out Google Test failure reporting
+// so that we can test Google Test or code that builds on Google Test.
+//
+// An object of this class appends a TestPartResult object to the
+// TestPartResultArray object given in the constructor whenever a Google Test
+// failure is reported. It can either intercept only failures that are
+// generated in the same thread that created this object or it can intercept
+// all generated failures. The scope of this mock object can be controlled with
+// the second argument to the two arguments constructor.
+class GTEST_API_ ScopedFakeTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  // The two possible mocking modes of this object.
+  enum InterceptMode {
+    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
+    INTERCEPT_ALL_THREADS           // Intercepts all failures.
+  };
+
+  // The c'tor sets this object as the test part result reporter used
+  // by Google Test.  The 'result' parameter specifies where to report the
+  // results. This reporter will only catch failures generated in the current
+  // thread. DEPRECATED
+  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+  // Same as above, but you can choose the interception scope of this object.
+  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
+                                   TestPartResultArray* result);
+
+  // The d'tor restores the previous test part result reporter.
+  virtual ~ScopedFakeTestPartResultReporter();
+
+  // Appends the TestPartResult object to the TestPartResultArray
+  // received in the constructor.
+  //
+  // This method is from the TestPartResultReporterInterface
+  // interface.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+ private:
+  void Init();
+
+  const InterceptMode intercept_mode_;
+  TestPartResultReporterInterface* old_reporter_;
+  TestPartResultArray* const result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
+};
+
+namespace internal {
+
+// A helper class for implementing EXPECT_FATAL_FAILURE() and
+// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+class GTEST_API_ SingleFailureChecker {
+ public:
+  // The constructor remembers the arguments.
+  SingleFailureChecker(const TestPartResultArray* results,
+                       TestPartResult::Type type,
+                       const string& substr);
+  ~SingleFailureChecker();
+ private:
+  const TestPartResultArray* const results_;
+  const TestPartResult::Type type_;
+  const string substr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+// A set of macros for testing Google Test assertions or code that's expected
+// to generate Google Test fatal failures.  It verifies that the given
+// statement will cause exactly one fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - 'statement' cannot reference local non-static variables or
+//     non-static members of the current object.
+//   - 'statement' cannot return a value.
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
+// gtest_unittest.cc will fail to compile if we do that.
+#define EXPECT_FATAL_FAILURE(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ALL_THREADS, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+// A macro for testing Google Test assertions or code that's expected to
+// generate Google Test non-fatal failures.  It asserts that the given
+// statement will cause exactly one non-fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  If we do that, the code won't compile when the user gives
+// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
+// expands to code containing an unprotected comma.  The
+// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
+// catches that.
+//
+// For the same reason, we have to write
+//   if (::testing::internal::AlwaysTrue()) { statement; }
+// instead of
+//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+// to avoid an MSVC warning on unreachable code.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
+          &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <algorithm>
+#include <ostream>  // NOLINT
+#include <sstream>
+#include <vector>
+
+#if GTEST_OS_LINUX
+
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+# define GTEST_HAS_GETTIMEOFDAY_ 1
+
+# include <fcntl.h>  // NOLINT
+# include <limits.h>  // NOLINT
+# include <sched.h>  // NOLINT
+// Declares vsnprintf().  This header is not available on Windows.
+# include <strings.h>  // NOLINT
+# include <sys/mman.h>  // NOLINT
+# include <sys/time.h>  // NOLINT
+# include <unistd.h>  // NOLINT
+# include <string>
+
+#elif GTEST_OS_SYMBIAN
+# define GTEST_HAS_GETTIMEOFDAY_ 1
+# include <sys/time.h>  // NOLINT
+
+#elif GTEST_OS_ZOS
+# define GTEST_HAS_GETTIMEOFDAY_ 1
+# include <sys/time.h>  // NOLINT
+
+// On z/OS we additionally need strings.h for strcasecmp.
+# include <strings.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.
+
+# include <windows.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS  // We are on Windows proper.
+
+# include <io.h>  // NOLINT
+# include <sys/timeb.h>  // NOLINT
+# include <sys/types.h>  // NOLINT
+# include <sys/stat.h>  // NOLINT
+
+# if GTEST_OS_WINDOWS_MINGW
+// MinGW has gettimeofday() but not _ftime64().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+// TODO(kenton@google.com): There are other ways to get the time on
+//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
+//   supports these.  consider using them instead.
+#  define GTEST_HAS_GETTIMEOFDAY_ 1
+#  include <sys/time.h>  // NOLINT
+# endif  // GTEST_OS_WINDOWS_MINGW
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+# include <windows.h>  // NOLINT
+
+#else
+
+// Assume other platforms have gettimeofday().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+# define GTEST_HAS_GETTIMEOFDAY_ 1
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+# include <sys/time.h>  // NOLINT
+# include <unistd.h>  // NOLINT
+
+#endif  // GTEST_OS_LINUX
+
+#if GTEST_HAS_EXCEPTIONS
+# include <stdexcept>
+#endif
+
+#if GTEST_CAN_STREAM_RESULTS_
+# include <arpa/inet.h>  // NOLINT
+# include <netdb.h>  // NOLINT
+#endif
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Utility functions and classes used by the Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// This file contains purely Google Test's internal implementation.  Please
+// DO NOT #INCLUDE IT IN A USER PROGRAM.
+
+#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
+#define GTEST_SRC_GTEST_INTERNAL_INL_H_
+
+// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
+// part of Google Test's implementation; otherwise it's undefined.
+#if !GTEST_IMPLEMENTATION_
+// A user is trying to include this from his code - just say no.
+# error "gtest-internal-inl.h is part of Google Test's internal implementation."
+# error "It must not be included except by Google Test itself."
+#endif  // GTEST_IMPLEMENTATION_
+
+#ifndef _WIN32_WCE
+# include <errno.h>
+#endif  // !_WIN32_WCE
+#include <stddef.h>
+#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
+#include <string.h>  // For memmove.
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+
+#if GTEST_OS_WINDOWS
+# include <windows.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify this flag in the code, but want
+// Google Test's own unit tests to be able to access it. Therefore we
+// declare it here as opposed to in gtest.h.
+GTEST_DECLARE_bool_(death_test_use_fork);
+
+namespace internal {
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kColorFlag[] = "color";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kPrintTimeFlag[] = "print_time";
+const char kRandomSeedFlag[] = "random_seed";
+const char kRepeatFlag[] = "repeat";
+const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
+const char kStreamResultToFlag[] = "stream_result_to";
+const char kThrowOnFailureFlag[] = "throw_on_failure";
+
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
+// Returns the current time in milliseconds.
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// Parses a string for an Int32 flag, in the form of "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+GTEST_API_ bool ParseInt32Flag(
+    const char* str, const char* flag, Int32* value);
+
+// Returns a random seed in range [1, kMaxRandomSeed] based on the
+// given --gtest_random_seed flag value.
+inline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
+  const unsigned int raw_seed = (random_seed_flag == 0) ?
+      static_cast<unsigned int>(GetTimeInMillis()) :
+      static_cast<unsigned int>(random_seed_flag);
+
+  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
+  // it's easy to type.
+  const int normalized_seed =
+      static_cast<int>((raw_seed - 1U) %
+                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;
+  return normalized_seed;
+}
+
+// Returns the first valid random seed after 'seed'.  The behavior is
+// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is
+// considered to be 1.
+inline int GetNextRandomSeed(int seed) {
+  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
+      << "Invalid random seed " << seed << " - must be in [1, "
+      << kMaxRandomSeed << "].";
+  const int next_seed = seed + 1;
+  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
+}
+
+// This class saves the values of all Google Test flags in its c'tor, and
+// restores them in its d'tor.
+class GTestFlagSaver {
+ public:
+  // The c'tor.
+  GTestFlagSaver() {
+    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
+    break_on_failure_ = GTEST_FLAG(break_on_failure);
+    catch_exceptions_ = GTEST_FLAG(catch_exceptions);
+    color_ = GTEST_FLAG(color);
+    death_test_style_ = GTEST_FLAG(death_test_style);
+    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
+    filter_ = GTEST_FLAG(filter);
+    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+    list_tests_ = GTEST_FLAG(list_tests);
+    output_ = GTEST_FLAG(output);
+    print_time_ = GTEST_FLAG(print_time);
+    random_seed_ = GTEST_FLAG(random_seed);
+    repeat_ = GTEST_FLAG(repeat);
+    shuffle_ = GTEST_FLAG(shuffle);
+    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
+    stream_result_to_ = GTEST_FLAG(stream_result_to);
+    throw_on_failure_ = GTEST_FLAG(throw_on_failure);
+  }
+
+  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
+  ~GTestFlagSaver() {
+    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
+    GTEST_FLAG(break_on_failure) = break_on_failure_;
+    GTEST_FLAG(catch_exceptions) = catch_exceptions_;
+    GTEST_FLAG(color) = color_;
+    GTEST_FLAG(death_test_style) = death_test_style_;
+    GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
+    GTEST_FLAG(filter) = filter_;
+    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
+    GTEST_FLAG(list_tests) = list_tests_;
+    GTEST_FLAG(output) = output_;
+    GTEST_FLAG(print_time) = print_time_;
+    GTEST_FLAG(random_seed) = random_seed_;
+    GTEST_FLAG(repeat) = repeat_;
+    GTEST_FLAG(shuffle) = shuffle_;
+    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
+    GTEST_FLAG(stream_result_to) = stream_result_to_;
+    GTEST_FLAG(throw_on_failure) = throw_on_failure_;
+  }
+ private:
+  // Fields for saving the original values of flags.
+  bool also_run_disabled_tests_;
+  bool break_on_failure_;
+  bool catch_exceptions_;
+  String color_;
+  String death_test_style_;
+  bool death_test_use_fork_;
+  String filter_;
+  String internal_run_death_test_;
+  bool list_tests_;
+  String output_;
+  bool print_time_;
+  bool pretty_;
+  internal::Int32 random_seed_;
+  internal::Int32 repeat_;
+  bool shuffle_;
+  internal::Int32 stack_trace_depth_;
+  String stream_result_to_;
+  bool throw_on_failure_;
+} GTEST_ATTRIBUTE_UNUSED_;
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded();
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (e.g., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+                            const char* shard_index_str,
+                            bool in_subprocess_for_death_test);
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error and
+// and aborts.
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+GTEST_API_ bool ShouldRunTestOnShard(
+    int total_shards, int shard_index, int test_id);
+
+// STL container utilities.
+
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+  // Implemented as an explicit loop since std::count_if() in libCstd on
+  // Solaris has a non-standard signature.
+  int count = 0;
+  for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {
+    if (predicate(*it))
+      ++count;
+  }
+  return count;
+}
+
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+  std::for_each(c.begin(), c.end(), functor);
+}
+
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
+
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+                  std::vector<E>* v) {
+  const int size = static_cast<int>(v->size());
+  GTEST_CHECK_(0 <= begin && begin <= size)
+      << "Invalid shuffle range start " << begin << ": must be in range [0, "
+      << size << "].";
+  GTEST_CHECK_(begin <= end && end <= size)
+      << "Invalid shuffle range finish " << end << ": must be in range ["
+      << begin << ", " << size << "].";
+
+  // Fisher-Yates shuffle, from
+  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  for (int range_width = end - begin; range_width >= 2; range_width--) {
+    const int last_in_range = begin + range_width - 1;
+    const int selected = begin + random->Generate(range_width);
+    std::swap((*v)[selected], (*v)[last_in_range]);
+  }
+}
+
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
+
+// A function for deleting an object.  Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T* x) {
+  delete x;
+}
+
+// A predicate that checks the key of a TestProperty against a known key.
+//
+// TestPropertyKeyIs is copyable.
+class TestPropertyKeyIs {
+ public:
+  // Constructor.
+  //
+  // TestPropertyKeyIs has NO default constructor.
+  explicit TestPropertyKeyIs(const char* key)
+      : key_(key) {}
+
+  // Returns true iff the test name of test property matches on key_.
+  bool operator()(const TestProperty& test_property) const {
+    return String(test_property.key()).Compare(key_) == 0;
+  }
+
+ private:
+  String key_;
+};
+
+// Class UnitTestOptions.
+//
+// This class contains functions for processing options the user
+// specifies when running the tests.  It has only static members.
+//
+// In most cases, the user can specify an option using either an
+// environment variable or a command line flag.  E.g. you can set the
+// test filter using either GTEST_FILTER or --gtest_filter.  If both
+// the variable and the flag are present, the latter overrides the
+// former.
+class GTEST_API_ UnitTestOptions {
+ public:
+  // Functions for processing the gtest_output flag.
+
+  // Returns the output format, or "" for normal printed output.
+  static String GetOutputFormat();
+
+  // Returns the absolute path of the requested output file, or the
+  // default (test_detail.xml in the original working directory) if
+  // none was explicitly specified.
+  static String GetAbsolutePathToOutputFile();
+
+  // Functions for processing the gtest_filter flag.
+
+  // Returns true iff the wildcard pattern matches the string.  The
+  // first ':' or '\0' character in pattern marks the end of it.
+  //
+  // This recursive algorithm isn't very efficient, but is clear and
+  // works well enough for matching test names, which are short.
+  static bool PatternMatchesString(const char *pattern, const char *str);
+
+  // Returns true iff the user-specified filter matches the test case
+  // name and the test name.
+  static bool FilterMatchesTest(const String &test_case_name,
+                                const String &test_name);
+
+#if GTEST_OS_WINDOWS
+  // Function for supporting the gtest_catch_exception flag.
+
+  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+  // This function is useful as an __except condition.
+  static int GTestShouldProcessSEH(DWORD exception_code);
+#endif  // GTEST_OS_WINDOWS
+
+  // Returns true if "name" matches the ':' separated list of glob-style
+  // filters in "filter".
+  static bool MatchesFilter(const String& name, const char* filter);
+};
+
+// Returns the current application's name, removing directory path if that
+// is present.  Used by UnitTestOptions::GetOutputFile.
+GTEST_API_ FilePath GetCurrentExecutableName();
+
+// The role interface for getting the OS stack trace as a string.
+class OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetterInterface() {}
+  virtual ~OsStackTraceGetterInterface() {}
+
+  // Returns the current OS stack trace as a String.  Parameters:
+  //
+  //   max_depth  - the maximum number of stack frames to be included
+  //                in the trace.
+  //   skip_count - the number of top frames to be skipped; doesn't count
+  //                against max_depth.
+  virtual String CurrentStackTrace(int max_depth, int skip_count) = 0;
+
+  // UponLeavingGTest() should be called immediately before Google Test calls
+  // user code. It saves some information about the current stack that
+  // CurrentStackTrace() will use to find and hide Google Test stack frames.
+  virtual void UponLeavingGTest() = 0;
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
+};
+
+// A working implementation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetter() : caller_frame_(NULL) {}
+  virtual String CurrentStackTrace(int max_depth, int skip_count);
+  virtual void UponLeavingGTest();
+
+  // This string is inserted in place of stack frames that are part of
+  // Google Test's implementation.
+  static const char* const kElidedFramesMarker;
+
+ private:
+  Mutex mutex_;  // protects all internal state
+
+  // We save the stack frame below the frame that calls user code.
+  // We do this because the address of the frame immediately below
+  // the user code changes between the call to UponLeavingGTest()
+  // and any calls to CurrentStackTrace() from within the user code.
+  void* caller_frame_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
+};
+
+// Information about a Google Test trace point.
+struct TraceInfo {
+  const char* file;
+  int line;
+  String message;
+};
+
+// This is the default global test part result reporter used in UnitTestImpl.
+// This class should only be used by UnitTestImpl.
+class DefaultGlobalTestPartResultReporter
+  : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. Reports the test part
+  // result in the current test.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
+};
+
+// This is the default per thread test part result reporter used in
+// UnitTestImpl. This class should only be used by UnitTestImpl.
+class DefaultPerThreadTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. The implementation just
+  // delegates to the current global test part result reporter of *unit_test_.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
+};
+
+// The private implementation of the UnitTest class.  We don't protect
+// the methods under a mutex, as this class is not accessible by a
+// user and the UnitTest class that delegates work to this class does
+// proper locking.
+class GTEST_API_ UnitTestImpl {
+ public:
+  explicit UnitTestImpl(UnitTest* parent);
+  virtual ~UnitTestImpl();
+
+  // There are two different ways to register your own TestPartResultReporter.
+  // You can register your own repoter to listen either only for test results
+  // from the current thread or for results from all threads.
+  // By default, each per-thread test result repoter just passes a new
+  // TestPartResult to the global test result reporter, which registers the
+  // test part result for the currently running test.
+
+  // Returns the global test part result reporter.
+  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
+
+  // Sets the global test part result reporter.
+  void SetGlobalTestPartResultReporter(
+      TestPartResultReporterInterface* reporter);
+
+  // Returns the test part result reporter for the current thread.
+  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
+
+  // Sets the test part result reporter for the current thread.
+  void SetTestPartResultReporterForCurrentThread(
+      TestPartResultReporterInterface* reporter);
+
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const {
+    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[i];
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i) {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[index];
+  }
+
+  // Provides access to the event listener list.
+  TestEventListeners* listeners() { return &listeners_; }
+
+  // Returns the TestResult for the test that's currently running, or
+  // the TestResult for the ad hoc test if no test is running.
+  TestResult* current_test_result();
+
+  // Returns the TestResult for the ad hoc test.
+  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
+
+  // Sets the OS stack trace getter.
+  //
+  // Does nothing if the input and the current OS stack trace getter
+  // are the same; otherwise, deletes the old getter and makes the
+  // input the current getter.
+  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
+
+  // Returns the current OS stack trace getter if it is not NULL;
+  // otherwise, creates an OsStackTraceGetter, makes it the current
+  // getter, and returns it.
+  OsStackTraceGetterInterface* os_stack_trace_getter();
+
+  // Returns the current OS stack trace as a String.
+  //
+  // The maximum number of stack frames to be included is specified by
+  // the gtest_stack_trace_depth flag.  The skip_count parameter
+  // specifies the number of top frames to be skipped, which doesn't
+  // count against the number of frames to be included.
+  //
+  // For example, if Foo() calls Bar(), which in turn calls
+  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+  String CurrentOsStackTraceExceptTop(int skip_count);
+
+  // Finds and returns a TestCase with the given name.  If one doesn't
+  // exist, creates one and returns it.
+  //
+  // Arguments:
+  //
+  //   test_case_name: name of the test case
+  //   type_param:     the name of the test's type parameter, or NULL if
+  //                   this is not a typed or a type-parameterized test.
+  //   set_up_tc:      pointer to the function that sets up the test case
+  //   tear_down_tc:   pointer to the function that tears down the test case
+  TestCase* GetTestCase(const char* test_case_name,
+                        const char* type_param,
+                        Test::SetUpTestCaseFunc set_up_tc,
+                        Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Adds a TestInfo to the unit test.
+  //
+  // Arguments:
+  //
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  //   test_info:    the TestInfo object
+  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc,
+                   TestInfo* test_info) {
+    // In order to support thread-safe death tests, we need to
+    // remember the original working directory when the test program
+    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as
+    // the user may have changed the current directory before calling
+    // RUN_ALL_TESTS().  Therefore we capture the current directory in
+    // AddTestInfo(), which is called to register a TEST or TEST_F
+    // before main() is reached.
+    if (original_working_dir_.IsEmpty()) {
+      original_working_dir_.Set(FilePath::GetCurrentDir());
+      GTEST_CHECK_(!original_working_dir_.IsEmpty())
+          << "Failed to get the current working directory.";
+    }
+
+    GetTestCase(test_info->test_case_name(),
+                test_info->type_param(),
+                set_up_tc,
+                tear_down_tc)->AddTestInfo(test_info);
+  }
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+    return parameterized_test_registry_;
+  }
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Sets the TestCase object for the test that's currently running.
+  void set_current_test_case(TestCase* a_current_test_case) {
+    current_test_case_ = a_current_test_case;
+  }
+
+  // Sets the TestInfo object for the test that's currently running.  If
+  // current_test_info is NULL, the assertion results will be stored in
+  // ad_hoc_test_result_.
+  void set_current_test_info(TestInfo* a_current_test_info) {
+    current_test_info_ = a_current_test_info;
+  }
+
+  // Registers all parameterized tests defined using TEST_P and
+  // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter
+  // combination. This method can be called more then once; it has guards
+  // protecting from registering the tests more then once.  If
+  // value-parameterized tests are disabled, RegisterParameterizedTests is
+  // present but does nothing.
+  void RegisterParameterizedTests();
+
+  // Runs all tests in this UnitTest object, prints the result, and
+  // returns true if all tests are successful.  If any exception is
+  // thrown during a test, this test is considered to be failed, but
+  // the rest of the tests will still be run.
+  bool RunAllTests();
+
+  // Clears the results of all tests, except the ad hoc tests.
+  void ClearNonAdHocTestResult() {
+    ForEach(test_cases_, TestCase::ClearTestCaseResult);
+  }
+
+  // Clears the results of ad-hoc test assertions.
+  void ClearAdHocTestResult() {
+    ad_hoc_test_result_.Clear();
+  }
+
+  enum ReactionToSharding {
+    HONOR_SHARDING_PROTOCOL,
+    IGNORE_SHARDING_PROTOCOL
+  };
+
+  // Matches the full name of each test against the user-specified
+  // filter to decide whether the test should run, then records the
+  // result in each TestCase and TestInfo object.
+  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
+  // based on sharding variables in the environment.
+  // Returns the number of tests that should run.
+  int FilterTests(ReactionToSharding shard_tests);
+
+  // Prints the names of the tests matching the user-specified filter flag.
+  void ListTestsMatchingFilter();
+
+  const TestCase* current_test_case() const { return current_test_case_; }
+  TestInfo* current_test_info() { return current_test_info_; }
+  const TestInfo* current_test_info() const { return current_test_info_; }
+
+  // Returns the vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*>& environments() { return environments_; }
+
+  // Getters for the per-thread Google Test trace stack.
+  std::vector<TraceInfo>& gtest_trace_stack() {
+    return *(gtest_trace_stack_.pointer());
+  }
+  const std::vector<TraceInfo>& gtest_trace_stack() const {
+    return gtest_trace_stack_.get();
+  }
+
+#if GTEST_HAS_DEATH_TEST
+  void InitDeathTestSubprocessControlInfo() {
+    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+  }
+  // Returns a pointer to the parsed --gtest_internal_run_death_test
+  // flag, or NULL if that flag was not specified.
+  // This information is useful only in a death test child process.
+  // Must not be called before a call to InitGoogleTest.
+  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
+    return internal_run_death_test_flag_.get();
+  }
+
+  // Returns a pointer to the current death test factory.
+  internal::DeathTestFactory* death_test_factory() {
+    return death_test_factory_.get();
+  }
+
+  void SuppressTestEventsIfInSubprocess();
+
+  friend class ReplaceDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // Initializes the event listener performing XML output as specified by
+  // UnitTestOptions. Must not be called before InitGoogleTest.
+  void ConfigureXmlOutput();
+
+#if GTEST_CAN_STREAM_RESULTS_
+  // Initializes the event listener for streaming test results to a socket.
+  // Must not be called before InitGoogleTest.
+  void ConfigureStreamingOutput();
+#endif
+
+  // Performs initialization dependent upon flag values obtained in
+  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+  // this function is also called from RunAllTests.  Since this function can be
+  // called more than once, it has to be idempotent.
+  void PostFlagParsingInit();
+
+  // Gets the random seed used at the start of the current test iteration.
+  int random_seed() const { return random_seed_; }
+
+  // Gets the random number generator.
+  internal::Random* random() { return &random_; }
+
+  // Shuffles all test cases, and the tests within each test case,
+  // making sure that death tests are still run first.
+  void ShuffleTests();
+
+  // Restores the test cases and tests to their order before the first shuffle.
+  void UnshuffleTests();
+
+  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment
+  // UnitTest::Run() starts.
+  bool catch_exceptions() const { return catch_exceptions_; }
+
+ private:
+  friend class ::testing::UnitTest;
+
+  // Used by UnitTest::Run() to capture the state of
+  // GTEST_FLAG(catch_exceptions) at the moment it starts.
+  void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
+
+  // The UnitTest object that owns this implementation object.
+  UnitTest* const parent_;
+
+  // The working directory when the first TEST() or TEST_F() was
+  // executed.
+  internal::FilePath original_working_dir_;
+
+  // The default test part result reporters.
+  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
+  DefaultPerThreadTestPartResultReporter
+      default_per_thread_test_part_result_reporter_;
+
+  // Points to (but doesn't own) the global test part result reporter.
+  TestPartResultReporterInterface* global_test_part_result_repoter_;
+
+  // Protects read and write access to global_test_part_result_reporter_.
+  internal::Mutex global_test_part_result_reporter_mutex_;
+
+  // Points to (but doesn't own) the per-thread test part result reporter.
+  internal::ThreadLocal<TestPartResultReporterInterface*>
+      per_thread_test_part_result_reporter_;
+
+  // The vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*> environments_;
+
+  // The vector of TestCases in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestCase*> test_cases_;
+
+  // Provides a level of indirection for the test case list to allow
+  // easy shuffling and restoring the test case order.  The i-th
+  // element of this vector is the index of the i-th test case in the
+  // shuffled order.
+  std::vector<int> test_case_indices_;
+
+#if GTEST_HAS_PARAM_TEST
+  // ParameterizedTestRegistry object used to register value-parameterized
+  // tests.
+  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+
+  // Indicates whether RegisterParameterizedTests() has been called already.
+  bool parameterized_tests_registered_;
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Index of the last death test case registered.  Initially -1.
+  int last_death_test_case_;
+
+  // This points to the TestCase for the currently running test.  It
+  // changes as Google Test goes through one test case after another.
+  // When no test is running, this is set to NULL and Google Test
+  // stores assertion results in ad_hoc_test_result_.  Initially NULL.
+  TestCase* current_test_case_;
+
+  // This points to the TestInfo for the currently running test.  It
+  // changes as Google Test goes through one test after another.  When
+  // no test is running, this is set to NULL and Google Test stores
+  // assertion results in ad_hoc_test_result_.  Initially NULL.
+  TestInfo* current_test_info_;
+
+  // Normally, a user only writes assertions inside a TEST or TEST_F,
+  // or inside a function called by a TEST or TEST_F.  Since Google
+  // Test keeps track of which test is current running, it can
+  // associate such an assertion with the test it belongs to.
+  //
+  // If an assertion is encountered when no TEST or TEST_F is running,
+  // Google Test attributes the assertion result to an imaginary "ad hoc"
+  // test, and records the result in ad_hoc_test_result_.
+  TestResult ad_hoc_test_result_;
+
+  // The list of event listeners that can be used to track events inside
+  // Google Test.
+  TestEventListeners listeners_;
+
+  // The OS stack trace getter.  Will be deleted when the UnitTest
+  // object is destructed.  By default, an OsStackTraceGetter is used,
+  // but the user can set this field to use a custom getter if that is
+  // desired.
+  OsStackTraceGetterInterface* os_stack_trace_getter_;
+
+  // True iff PostFlagParsingInit() has been called.
+  bool post_flag_parse_init_performed_;
+
+  // The random number seed used at the beginning of the test run.
+  int random_seed_;
+
+  // Our random number generator.
+  internal::Random random_;
+
+  // How long the test took to run, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+#if GTEST_HAS_DEATH_TEST
+  // The decomposed components of the gtest_internal_run_death_test flag,
+  // parsed when RUN_ALL_TESTS is called.
+  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // A per-thread stack of traces created by the SCOPED_TRACE() macro.
+  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;
+
+  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()
+  // starts.
+  bool catch_exceptions_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
+};  // class UnitTestImpl
+
+// Convenience function for accessing the global UnitTest
+// implementation object.
+inline UnitTestImpl* GetUnitTestImpl() {
+  return UnitTest::GetInstance()->impl();
+}
+
+#if GTEST_USES_SIMPLE_RE
+
+// Internal helper functions for implementing the simple regular
+// expression matcher.
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsAsciiDigit(char ch);
+GTEST_API_ bool IsAsciiPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsAsciiWhiteSpace(char ch);
+GTEST_API_ bool IsAsciiWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char ch, char repeat, const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
+
+#endif  // GTEST_USES_SIMPLE_RE
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+
+#if GTEST_HAS_DEATH_TEST
+
+// Returns the message describing the last system error, regardless of the
+// platform.
+GTEST_API_ String GetLastErrnoDescription();
+
+# if GTEST_OS_WINDOWS
+// Provides leak-safe Windows kernel handle ownership.
+class AutoHandle {
+ public:
+  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
+  explicit AutoHandle(HANDLE handle) : handle_(handle) {}
+
+  ~AutoHandle() { Reset(); }
+
+  HANDLE Get() const { return handle_; }
+  void Reset() { Reset(INVALID_HANDLE_VALUE); }
+  void Reset(HANDLE handle) {
+    if (handle != handle_) {
+      if (handle_ != INVALID_HANDLE_VALUE)
+        ::CloseHandle(handle_);
+      handle_ = handle;
+    }
+  }
+
+ private:
+  HANDLE handle_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
+};
+# endif  // GTEST_OS_WINDOWS
+
+// Attempts to parse a string into a positive integer pointed to by the
+// number parameter.  Returns true if that is possible.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
+// it here.
+template <typename Integer>
+bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
+  // Fail fast if the given string does not begin with a digit;
+  // this bypasses strtoXXX's "optional leading whitespace and plus
+  // or minus sign" semantics, which are undesirable here.
+  if (str.empty() || !IsDigit(str[0])) {
+    return false;
+  }
+  errno = 0;
+
+  char* end;
+  // BiggestConvertible is the largest integer type that system-provided
+  // string-to-number conversion routines can return.
+
+# if GTEST_OS_WINDOWS && !defined(__GNUC__)
+
+  // MSVC and C++ Builder define __int64 instead of the standard long long.
+  typedef unsigned __int64 BiggestConvertible;
+  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
+
+# else
+
+  typedef unsigned long long BiggestConvertible;  // NOLINT
+  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
+
+# endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)
+
+  const bool parse_success = *end == '\0' && errno == 0;
+
+  // TODO(vladl@google.com): Convert this to compile time assertion when it is
+  // available.
+  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
+
+  const Integer result = static_cast<Integer>(parsed);
+  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
+    *number = result;
+    return true;
+  }
+  return false;
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// TestResult contains some private methods that should be hidden from
+// Google Test user but are required for testing. This class allow our tests
+// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
+class TestResultAccessor {
+ public:
+  static void RecordProperty(TestResult* test_result,
+                             const TestProperty& property) {
+    test_result->RecordProperty(property);
+  }
+
+  static void ClearTestPartResults(TestResult* test_result) {
+    test_result->ClearTestPartResults();
+  }
+
+  static const std::vector<testing::TestPartResult>& test_part_results(
+      const TestResult& test_result) {
+    return test_result.test_part_results();
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS
+# define vsnprintf _vsnprintf
+#endif  // GTEST_OS_WINDOWS
+
+namespace testing {
+
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
+// Constants.
+
+// A test whose test case name or test name matches this filter is
+// disabled and not run.
+static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
+
+// A test case whose name matches this filter is considered a death
+// test case and will be run before test cases whose name doesn't
+// match this filter.
+static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+// The environment variable name for the test shard index.
+static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
+// The environment variable name for the total number of test shards.
+static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
+// The environment variable name for the test shard status file.
+static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+
+namespace internal {
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+const char kStackTraceMarker[] = "\nStack trace:\n";
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
+}  // namespace internal
+
+GTEST_DEFINE_bool_(
+    also_run_disabled_tests,
+    internal::BoolFromGTestEnv("also_run_disabled_tests", false),
+    "Run disabled tests too, in addition to the tests normally being run.");
+
+GTEST_DEFINE_bool_(
+    break_on_failure,
+    internal::BoolFromGTestEnv("break_on_failure", false),
+    "True iff a failed assertion should be a debugger break-point.");
+
+GTEST_DEFINE_bool_(
+    catch_exceptions,
+    internal::BoolFromGTestEnv("catch_exceptions", true),
+    "True iff " GTEST_NAME_
+    " should catch exceptions and treat them as test failures.");
+
+GTEST_DEFINE_string_(
+    color,
+    internal::StringFromGTestEnv("color", "auto"),
+    "Whether to use colors in the output.  Valid values: yes, no, "
+    "and auto.  'auto' means to use colors if the output is "
+    "being sent to a terminal and the TERM environment variable "
+    "is set to xterm, xterm-color, xterm-256color, linux or cygwin.");
+
+GTEST_DEFINE_string_(
+    filter,
+    internal::StringFromGTestEnv("filter", kUniversalFilter),
+    "A colon-separated list of glob (not regex) patterns "
+    "for filtering the tests to run, optionally followed by a "
+    "'-' and a : separated list of negative patterns (tests to "
+    "exclude).  A test is run if it matches one of the positive "
+    "patterns and does not match any of the negative patterns.");
+
+GTEST_DEFINE_bool_(list_tests, false,
+                   "List all tests without running them.");
+
+GTEST_DEFINE_string_(
+    output,
+    internal::StringFromGTestEnv("output", ""),
+    "A format (currently must be \"xml\"), optionally followed "
+    "by a colon and an output file name or directory. A directory "
+    "is indicated by a trailing pathname separator. "
+    "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
+    "If a directory is specified, output files will be created "
+    "within that directory, with file-names based on the test "
+    "executable's name and, if necessary, made unique by adding "
+    "digits.");
+
+GTEST_DEFINE_bool_(
+    print_time,
+    internal::BoolFromGTestEnv("print_time", true),
+    "True iff " GTEST_NAME_
+    " should display elapsed time in text output.");
+
+GTEST_DEFINE_int32_(
+    random_seed,
+    internal::Int32FromGTestEnv("random_seed", 0),
+    "Random number seed to use when shuffling test orders.  Must be in range "
+    "[1, 99999], or 0 to use a seed based on the current time.");
+
+GTEST_DEFINE_int32_(
+    repeat,
+    internal::Int32FromGTestEnv("repeat", 1),
+    "How many times to repeat each test.  Specify a negative number "
+    "for repeating forever.  Useful for shaking out flaky tests.");
+
+GTEST_DEFINE_bool_(
+    show_internal_stack_frames, false,
+    "True iff " GTEST_NAME_ " should include internal stack frames when "
+    "printing test failure stack traces.");
+
+GTEST_DEFINE_bool_(
+    shuffle,
+    internal::BoolFromGTestEnv("shuffle", false),
+    "True iff " GTEST_NAME_
+    " should randomize tests' order on every run.");
+
+GTEST_DEFINE_int32_(
+    stack_trace_depth,
+    internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
+    "The maximum number of stack frames to print when an "
+    "assertion fails.  The valid range is 0 through 100, inclusive.");
+
+GTEST_DEFINE_string_(
+    stream_result_to,
+    internal::StringFromGTestEnv("stream_result_to", ""),
+    "This flag specifies the host name and the port number on which to stream "
+    "test results. Example: \"localhost:555\". The flag is effective only on "
+    "Linux.");
+
+GTEST_DEFINE_bool_(
+    throw_on_failure,
+    internal::BoolFromGTestEnv("throw_on_failure", false),
+    "When this flag is specified, a failed assertion will throw an exception "
+    "if exceptions are enabled or exit the program with a non-zero code "
+    "otherwise.");
+
+namespace internal {
+
+// Generates a random number from [0, range), using a Linear
+// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
+// than kMaxRange.
+UInt32 Random::Generate(UInt32 range) {
+  // These constants are the same as are used in glibc's rand(3).
+  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+
+  GTEST_CHECK_(range > 0)
+      << "Cannot generate a number in the range [0, 0).";
+  GTEST_CHECK_(range <= kMaxRange)
+      << "Generation of a number in [0, " << range << ") was requested, "
+      << "but this can only generate numbers in [0, " << kMaxRange << ").";
+
+  // Converting via modulus introduces a bit of downward bias, but
+  // it's simple, and a linear congruential generator isn't too good
+  // to begin with.
+  return state_ % range;
+}
+
+// GTestIsInitialized() returns true iff the user has initialized
+// Google Test.  Useful for catching the user mistake of not initializing
+// Google Test before calling RUN_ALL_TESTS().
+//
+// A user must call testing::InitGoogleTest() to initialize Google
+// Test.  g_init_gtest_count is set to the number of times
+// InitGoogleTest() has been called.  We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+int g_init_gtest_count = 0;
+static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
+
+// Iterates over a vector of TestCases, keeping a running sum of the
+// results of calling a given int-returning method on each.
+// Returns the sum.
+static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
+                               int (TestCase::*method)() const) {
+  int sum = 0;
+  for (size_t i = 0; i < case_list.size(); i++) {
+    sum += (case_list[i]->*method)();
+  }
+  return sum;
+}
+
+// Returns true iff the test case passed.
+static bool TestCasePassed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Passed();
+}
+
+// Returns true iff the test case failed.
+static bool TestCaseFailed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Failed();
+}
+
+// Returns true iff test_case contains at least one test that should
+// run.
+static bool ShouldRunTestCase(const TestCase* test_case) {
+  return test_case->should_run();
+}
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResult::Type type,
+                           const char* file,
+                           int line,
+                           const char* message)
+    : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+  delete data_;
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+  UnitTest::GetInstance()->
+    AddTestPartResult(data_->type, data_->file, data_->line,
+                      AppendUserMessage(data_->message, message),
+                      UnitTest::GetInstance()->impl()
+                      ->CurrentOsStackTraceExceptTop(1)
+                      // Skips the stack frame for this function itself.
+                      );  // NOLINT
+}
+
+// Mutex for linked pointers.
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// Application pathname gotten in InitGoogleTest.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+  FilePath result;
+
+#if GTEST_OS_WINDOWS
+  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+  result.Set(FilePath(g_executable_path));
+#endif  // GTEST_OS_WINDOWS
+
+  return result.RemoveDirectoryName();
+}
+
+// Functions for processing the gtest_output flag.
+
+// Returns the output format, or "" for normal printed output.
+String UnitTestOptions::GetOutputFormat() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL) return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  return (colon == NULL) ?
+      String(gtest_output_flag) :
+      String(gtest_output_flag, colon - gtest_output_flag);
+}
+
+// Returns the name of the requested output file, or the default if none
+// was explicitly specified.
+String UnitTestOptions::GetAbsolutePathToOutputFile() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL)
+    return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  if (colon == NULL)
+    return String(internal::FilePath::ConcatPaths(
+               internal::FilePath(
+                   UnitTest::GetInstance()->original_working_dir()),
+               internal::FilePath(kDefaultOutputFile)).ToString() );
+
+  internal::FilePath output_name(colon + 1);
+  if (!output_name.IsAbsolutePath())
+    // TODO(wan@google.com): on Windows \some\path is not an absolute
+    // path (as its meaning depends on the current drive), yet the
+    // following logic for turning it into an absolute path is wrong.
+    // Fix it.
+    output_name = internal::FilePath::ConcatPaths(
+        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
+        internal::FilePath(colon + 1));
+
+  if (!output_name.IsDirectory())
+    return output_name.ToString();
+
+  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
+      output_name, internal::GetCurrentExecutableName(),
+      GetOutputFormat().c_str()));
+  return result.ToString();
+}
+
+// Returns true iff the wildcard pattern matches the string.  The
+// first ':' or '\0' character in pattern marks the end of it.
+//
+// This recursive algorithm isn't very efficient, but is clear and
+// works well enough for matching test names, which are short.
+bool UnitTestOptions::PatternMatchesString(const char *pattern,
+                                           const char *str) {
+  switch (*pattern) {
+    case '\0':
+    case ':':  // Either ':' or '\0' marks the end of the pattern.
+      return *str == '\0';
+    case '?':  // Matches any single character.
+      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
+    case '*':  // Matches any string (possibly empty) of characters.
+      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
+          PatternMatchesString(pattern + 1, str);
+    default:  // Non-special character.  Matches itself.
+      return *pattern == *str &&
+          PatternMatchesString(pattern + 1, str + 1);
+  }
+}
+
+bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) {
+  const char *cur_pattern = filter;
+  for (;;) {
+    if (PatternMatchesString(cur_pattern, name.c_str())) {
+      return true;
+    }
+
+    // Finds the next pattern in the filter.
+    cur_pattern = strchr(cur_pattern, ':');
+
+    // Returns if no more pattern can be found.
+    if (cur_pattern == NULL) {
+      return false;
+    }
+
+    // Skips the pattern separater (the ':' character).
+    cur_pattern++;
+  }
+}
+
+// TODO(keithray): move String function implementations to gtest-string.cc.
+
+// Returns true iff the user-specified filter matches the test case
+// name and the test name.
+bool UnitTestOptions::FilterMatchesTest(const String &test_case_name,
+                                        const String &test_name) {
+  const String& full_name = String::Format("%s.%s",
+                                           test_case_name.c_str(),
+                                           test_name.c_str());
+
+  // Split --gtest_filter at '-', if there is one, to separate into
+  // positive filter and negative filter portions
+  const char* const p = GTEST_FLAG(filter).c_str();
+  const char* const dash = strchr(p, '-');
+  String positive;
+  String negative;
+  if (dash == NULL) {
+    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter
+    negative = String("");
+  } else {
+    positive = String(p, dash - p);  // Everything up to the dash
+    negative = String(dash+1);       // Everything after the dash
+    if (positive.empty()) {
+      // Treat '-test1' as the same as '*-test1'
+      positive = kUniversalFilter;
+    }
+  }
+
+  // A filter is a colon-separated list of patterns.  It matches a
+  // test if any pattern in it matches the test.
+  return (MatchesFilter(full_name, positive.c_str()) &&
+          !MatchesFilter(full_name, negative.c_str()));
+}
+
+#if GTEST_HAS_SEH
+// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+// This function is useful as an __except condition.
+int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
+  // Google Test should handle a SEH exception if:
+  //   1. the user wants it to, AND
+  //   2. this is not a breakpoint exception, AND
+  //   3. this is not a C++ exception (VC++ implements them via SEH,
+  //      apparently).
+  //
+  // SEH exception code for C++ exceptions.
+  // (see http://support.microsoft.com/kb/185294 for more information).
+  const DWORD kCxxExceptionCode = 0xe06d7363;
+
+  bool should_handle = true;
+
+  if (!GTEST_FLAG(catch_exceptions))
+    should_handle = false;
+  else if (exception_code == EXCEPTION_BREAKPOINT)
+    should_handle = false;
+  else if (exception_code == kCxxExceptionCode)
+    should_handle = false;
+
+  return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
+}
+#endif  // GTEST_HAS_SEH
+
+}  // namespace internal
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results. Intercepts only failures from the current thread.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    TestPartResultArray* result)
+    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
+      result_(result) {
+  Init();
+}
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    InterceptMode intercept_mode, TestPartResultArray* result)
+    : intercept_mode_(intercept_mode),
+      result_(result) {
+  Init();
+}
+
+void ScopedFakeTestPartResultReporter::Init() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    old_reporter_ = impl->GetGlobalTestPartResultReporter();
+    impl->SetGlobalTestPartResultReporter(this);
+  } else {
+    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
+    impl->SetTestPartResultReporterForCurrentThread(this);
+  }
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    impl->SetGlobalTestPartResultReporter(old_reporter_);
+  } else {
+    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
+  }
+}
+
+// Increments the test part result count and remembers the result.
+// This method is from the TestPartResultReporterInterface interface.
+void ScopedFakeTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  result_->Append(result);
+}
+
+namespace internal {
+
+// Returns the type ID of ::testing::Test.  We should always call this
+// instead of GetTypeId< ::testing::Test>() to get the type ID of
+// testing::Test.  This is to work around a suspected linker bug when
+// using Google Test as a framework on Mac OS X.  The bug causes
+// GetTypeId< ::testing::Test>() to return different values depending
+// on whether the call is from the Google Test framework itself or
+// from user test code.  GetTestTypeId() is guaranteed to always
+// return the same value, as it always calls GetTypeId<>() from the
+// gtest.cc, which is within the Google Test framework.
+TypeId GetTestTypeId() {
+  return GetTypeId<Test>();
+}
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
+
+// This predicate-formatter checks that 'results' contains a test part
+// failure of the given type and that the failure message contains the
+// given substring.
+AssertionResult HasOneFailure(const char* /* results_expr */,
+                              const char* /* type_expr */,
+                              const char* /* substr_expr */,
+                              const TestPartResultArray& results,
+                              TestPartResult::Type type,
+                              const string& substr) {
+  const String expected(type == TestPartResult::kFatalFailure ?
+                        "1 fatal failure" :
+                        "1 non-fatal failure");
+  Message msg;
+  if (results.size() != 1) {
+    msg << "Expected: " << expected << "\n"
+        << "  Actual: " << results.size() << " failures";
+    for (int i = 0; i < results.size(); i++) {
+      msg << "\n" << results.GetTestPartResult(i);
+    }
+    return AssertionFailure() << msg;
+  }
+
+  const TestPartResult& r = results.GetTestPartResult(0);
+  if (r.type() != type) {
+    return AssertionFailure() << "Expected: " << expected << "\n"
+                              << "  Actual:\n"
+                              << r;
+  }
+
+  if (strstr(r.message(), substr.c_str()) == NULL) {
+    return AssertionFailure() << "Expected: " << expected << " containing \""
+                              << substr << "\"\n"
+                              << "  Actual:\n"
+                              << r;
+  }
+
+  return AssertionSuccess();
+}
+
+// The constructor of SingleFailureChecker remembers where to look up
+// test part results, what type of failure we expect, and what
+// substring the failure message should contain.
+SingleFailureChecker:: SingleFailureChecker(
+    const TestPartResultArray* results,
+    TestPartResult::Type type,
+    const string& substr)
+    : results_(results),
+      type_(type),
+      substr_(substr) {}
+
+// The destructor of SingleFailureChecker verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+SingleFailureChecker::~SingleFailureChecker() {
+  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);
+}
+
+DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->current_test_result()->AddTestPartResult(result);
+  unit_test_->listeners()->repeater()->OnTestPartResult(result);
+}
+
+DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
+}
+
+// Returns the global test part result reporter.
+TestPartResultReporterInterface*
+UnitTestImpl::GetGlobalTestPartResultReporter() {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  return global_test_part_result_repoter_;
+}
+
+// Sets the global test part result reporter.
+void UnitTestImpl::SetGlobalTestPartResultReporter(
+    TestPartResultReporterInterface* reporter) {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  global_test_part_result_repoter_ = reporter;
+}
+
+// Returns the test part result reporter for the current thread.
+TestPartResultReporterInterface*
+UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
+  return per_thread_test_part_result_reporter_.get();
+}
+
+// Sets the test part result reporter for the current thread.
+void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
+    TestPartResultReporterInterface* reporter) {
+  per_thread_test_part_result_reporter_.set(reporter);
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+  return CountIf(test_cases_, TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+  return CountIf(test_cases_, TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+  return static_cast<int>(test_cases_.size());
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTestImpl::test_case_to_run_count() const {
+  return CountIf(test_cases_, ShouldRunTestCase);
+}
+
+// Gets the number of successful tests.
+int UnitTestImpl::successful_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+}
+
+// Gets the number of failed tests.
+int UnitTestImpl::failed_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+}
+
+// Gets the number of disabled tests.
+int UnitTestImpl::disabled_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+}
+
+// Gets the number of all tests.
+int UnitTestImpl::total_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+}
+
+// Gets the number of tests that should run.
+int UnitTestImpl::test_to_run_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
+  (void)skip_count;
+  return String("");
+}
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis() {
+#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
+  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
+  // http://analogous.blogspot.com/2005/04/epoch.html
+  const TimeInMillis kJavaEpochToWinFileTimeDelta =
+    static_cast<TimeInMillis>(116444736UL) * 100000UL;
+  const DWORD kTenthMicrosInMilliSecond = 10000;
+
+  SYSTEMTIME now_systime;
+  FILETIME now_filetime;
+  ULARGE_INTEGER now_int64;
+  // TODO(kenton@google.com): Shouldn't this just use
+  //   GetSystemTimeAsFileTime()?
+  GetSystemTime(&now_systime);
+  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
+    now_int64.LowPart = now_filetime.dwLowDateTime;
+    now_int64.HighPart = now_filetime.dwHighDateTime;
+    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -
+      kJavaEpochToWinFileTimeDelta;
+    return now_int64.QuadPart;
+  }
+  return 0;
+#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
+  __timeb64 now;
+
+# ifdef _MSC_VER
+
+  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+  // (deprecated function) there.
+  // TODO(kenton@google.com): Use GetTickCount()?  Or use
+  //   SystemTimeToFileTime()
+#  pragma warning(push)          // Saves the current warning state.
+#  pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  _ftime64(&now);
+#  pragma warning(pop)           // Restores the warning state.
+# else
+
+  _ftime64(&now);
+
+# endif  // _MSC_VER
+
+  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
+#elif GTEST_HAS_GETTIMEOFDAY_
+  struct timeval now;
+  gettimeofday(&now, NULL);
+  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
+#else
+# error "Don't know how to get the current time on your system."
+#endif
+}
+
+// Utilities
+
+// class String
+
+// Returns the input enclosed in double quotes if it's not NULL;
+// otherwise returns "(null)".  For example, "\"Hello\"" is returned
+// for input "Hello".
+//
+// This is useful for printing a C string in the syntax of a literal.
+//
+// Known issue: escape sequences are not handled yet.
+String String::ShowCStringQuoted(const char* c_str) {
+  return c_str ? String::Format("\"%s\"", c_str) : String("(null)");
+}
+
+// Copies at most length characters from str into a newly-allocated
+// piece of memory of size length+1.  The memory is allocated with new[].
+// A terminating null byte is written to the memory, and a pointer to it
+// is returned.  If str is NULL, NULL is returned.
+static char* CloneString(const char* str, size_t length) {
+  if (str == NULL) {
+    return NULL;
+  } else {
+    char* const clone = new char[length + 1];
+    posix::StrNCpy(clone, str, length);
+    clone[length] = '\0';
+    return clone;
+  }
+}
+
+// Clones a 0-terminated C string, allocating memory using new.  The
+// caller is responsible for deleting[] the return value.  Returns the
+// cloned string, or NULL if the input is NULL.
+const char * String::CloneCString(const char* c_str) {
+  return (c_str == NULL) ?
+                    NULL : CloneString(c_str, strlen(c_str));
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Creates a UTF-16 wide string from the given ANSI string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the wide string, or NULL if the
+// input is NULL.
+LPCWSTR String::AnsiToUtf16(const char* ansi) {
+  if (!ansi) return NULL;
+  const int length = strlen(ansi);
+  const int unicode_length =
+      MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                          NULL, 0);
+  WCHAR* unicode = new WCHAR[unicode_length + 1];
+  MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                      unicode, unicode_length);
+  unicode[unicode_length] = 0;
+  return unicode;
+}
+
+// Creates an ANSI string from the given wide string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the ANSI string, or NULL if the
+// input is NULL.
+const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
+  if (!utf16_str) return NULL;
+  const int ansi_length =
+      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                          NULL, 0, NULL, NULL);
+  char* ansi = new char[ansi_length + 1];
+  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                      ansi, ansi_length, NULL, NULL);
+  ansi[ansi_length] = 0;
+  return ansi;
+}
+
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// Compares two C strings.  Returns true iff they have the same content.
+//
+// Unlike strcmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CStringEquals(const char * lhs, const char * rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+  return strcmp(lhs, rhs) == 0;
+}
+
+#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+// Converts an array of wide chars to a narrow string using the UTF-8
+// encoding, and streams the result to the given Message object.
+static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
+                                     Message* msg) {
+  // TODO(wan): consider allowing a testing::String object to
+  // contain '\0'.  This will make it behave more like std::string,
+  // and will allow ToUtf8String() to return the correct encoding
+  // for '\0' s.t. we can get rid of the conditional here (and in
+  // several other places).
+  for (size_t i = 0; i != length; ) {  // NOLINT
+    if (wstr[i] != L'\0') {
+      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+      while (i != length && wstr[i] != L'\0')
+        i++;
+    } else {
+      *msg << '\0';
+      i++;
+    }
+  }
+}
+
+#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+}  // namespace internal
+
+#if GTEST_HAS_STD_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::std::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+    : success_(other.success_),
+      message_(other.message_.get() != NULL ?
+               new ::std::string(*other.message_) :
+               static_cast< ::std::string*>(NULL)) {
+}
+
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+  AssertionResult negation(!success_);
+  if (message_.get() != NULL)
+    negation << *message_;
+  return negation;
+}
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+  return AssertionResult(true);
+}
+
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+  return AssertionResult(false);
+}
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
+AssertionResult AssertionFailure(const Message& message) {
+  return AssertionFailure() << message;
+}
+
+namespace internal {
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+AssertionResult EqFailure(const char* expected_expression,
+                          const char* actual_expression,
+                          const String& expected_value,
+                          const String& actual_value,
+                          bool ignoring_case) {
+  Message msg;
+  msg << "Value of: " << actual_expression;
+  if (actual_value != actual_expression) {
+    msg << "\n  Actual: " << actual_value;
+  }
+
+  msg << "\nExpected: " << expected_expression;
+  if (ignoring_case) {
+    msg << " (ignoring case)";
+  }
+  if (expected_value != expected_expression) {
+    msg << "\nWhich is: " << expected_value;
+  }
+
+  return AssertionFailure() << msg;
+}
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+                                      const char* expression_text,
+                                      const char* actual_predicate_value,
+                                      const char* expected_predicate_value) {
+  const char* actual_message = assertion_result.message();
+  Message msg;
+  msg << "Value of: " << expression_text
+      << "\n  Actual: " << actual_predicate_value;
+  if (actual_message[0] != '\0')
+    msg << " (" << actual_message << ")";
+  msg << "\nExpected: " << expected_predicate_value;
+  return msg.GetString();
+}
+
+// Helper function for implementing ASSERT_NEAR.
+AssertionResult DoubleNearPredFormat(const char* expr1,
+                                     const char* expr2,
+                                     const char* abs_error_expr,
+                                     double val1,
+                                     double val2,
+                                     double abs_error) {
+  const double diff = fabs(val1 - val2);
+  if (diff <= abs_error) return AssertionSuccess();
+
+  // TODO(wan): do not print the value of an expression if it's
+  // already a literal.
+  return AssertionFailure()
+      << "The difference between " << expr1 << " and " << expr2
+      << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
+      << expr1 << " evaluates to " << val1 << ",\n"
+      << expr2 << " evaluates to " << val2 << ", and\n"
+      << abs_error_expr << " evaluates to " << abs_error << ".";
+}
+
+
+// Helper template for implementing FloatLE() and DoubleLE().
+template <typename RawType>
+AssertionResult FloatingPointLE(const char* expr1,
+                                const char* expr2,
+                                RawType val1,
+                                RawType val2) {
+  // Returns success if val1 is less than val2,
+  if (val1 < val2) {
+    return AssertionSuccess();
+  }
+
+  // or if val1 is almost equal to val2.
+  const FloatingPoint<RawType> lhs(val1), rhs(val2);
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  // Note that the above two checks will both fail if either val1 or
+  // val2 is NaN, as the IEEE floating-point standard requires that
+  // any predicate involving a NaN must return false.
+
+  ::std::stringstream val1_ss;
+  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val1;
+
+  ::std::stringstream val2_ss;
+  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val2;
+
+  return AssertionFailure()
+      << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
+      << "  Actual: " << StringStreamToString(&val1_ss) << " vs "
+      << StringStreamToString(&val2_ss);
+}
+
+}  // namespace internal
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult FloatLE(const char* expr1, const char* expr2,
+                        float val1, float val2) {
+  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
+}
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                         double val1, double val2) {
+  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
+}
+
+namespace internal {
+
+// The helper function for {ASSERT|EXPECT}_EQ with int or enum
+// arguments.
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            BiggestInt expected,
+                            BiggestInt actual) {
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here
+// just to avoid copy-and-paste of similar code.
+#define GTEST_IMPL_CMP_HELPER_(op_name, op)\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   BiggestInt val1, BiggestInt val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    return AssertionFailure() \
+        << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+  }\
+}
+
+// Implements the helper function for {ASSERT|EXPECT}_NE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(NE, !=)
+// Implements the helper function for {ASSERT|EXPECT}_LE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LE, <=)
+// Implements the helper function for {ASSERT|EXPECT}_LT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(LT, < )
+// Implements the helper function for {ASSERT|EXPECT}_GE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GE, >=)
+// Implements the helper function for {ASSERT|EXPECT}_GT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER_(GT, > )
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const char* expected,
+                               const char* actual) {
+  if (String::CStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   false);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                   const char* actual_expression,
+                                   const char* expected,
+                                   const char* actual) {
+  if (String::CaseInsensitiveCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   true);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const char* s1,
+                               const char* s2) {
+  if (!String::CStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
+                              << s2_expression << "), actual: \""
+                              << s1 << "\" vs \"" << s2 << "\"";
+  }
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                   const char* s2_expression,
+                                   const char* s1,
+                                   const char* s2) {
+  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    return AssertionFailure()
+        << "Expected: (" << s1_expression << ") != ("
+        << s2_expression << ") (ignoring case), actual: \""
+        << s1 << "\" vs \"" << s2 << "\"";
+  }
+}
+
+}  // namespace internal
+
+namespace {
+
+// Helper functions for implementing IsSubString() and IsNotSubstring().
+
+// This group of overloaded functions return true iff needle is a
+// substring of haystack.  NULL is considered a substring of itself
+// only.
+
+bool IsSubstringPred(const char* needle, const char* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return strstr(haystack, needle) != NULL;
+}
+
+bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return wcsstr(haystack, needle) != NULL;
+}
+
+// StringType here can be either ::std::string or ::std::wstring.
+template <typename StringType>
+bool IsSubstringPred(const StringType& needle,
+                     const StringType& haystack) {
+  return haystack.find(needle) != StringType::npos;
+}
+
+// This function implements either IsSubstring() or IsNotSubstring(),
+// depending on the value of the expected_to_be_substring parameter.
+// StringType here can be const char*, const wchar_t*, ::std::string,
+// or ::std::wstring.
+template <typename StringType>
+AssertionResult IsSubstringImpl(
+    bool expected_to_be_substring,
+    const char* needle_expr, const char* haystack_expr,
+    const StringType& needle, const StringType& haystack) {
+  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
+    return AssertionSuccess();
+
+  const bool is_wide_string = sizeof(needle[0]) > 1;
+  const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
+  return AssertionFailure()
+      << "Value of: " << needle_expr << "\n"
+      << "  Actual: " << begin_string_quote << needle << "\"\n"
+      << "Expected: " << (expected_to_be_substring ? "" : "not ")
+      << "a substring of " << haystack_expr << "\n"
+      << "Which is: " << begin_string_quote << haystack << "\"";
+}
+
+}  // namespace
+
+// IsSubstring() and IsNotSubstring() check whether needle is a
+// substring of haystack (NULL is considered a substring of itself
+// only), and return an appropriate error message when they fail.
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+#if GTEST_HAS_STD_WSTRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+                                     const char* expected,
+                                     long hr) {  // NOLINT
+# if GTEST_OS_WINDOWS_MOBILE
+
+  // Windows CE doesn't support FormatMessage.
+  const char error_text[] = "";
+
+# else
+
+  // Looks up the human-readable system message for the HRESULT code
+  // and since we're not passing any params to FormatMessage, we don't
+  // want inserts expanded.
+  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS;
+  const DWORD kBufSize = 4096;  // String::Format can't exceed this length.
+  // Gets the system's human readable message string for this HRESULT.
+  char error_text[kBufSize] = { '\0' };
+  DWORD message_length = ::FormatMessageA(kFlags,
+                                          0,  // no source, we're asking system
+                                          hr,  // the error
+                                          0,  // no line width restrictions
+                                          error_text,  // output buffer
+                                          kBufSize,  // buf size
+                                          NULL);  // no arguments for inserts
+  // Trims tailing white space (FormatMessage leaves a trailing cr-lf)
+  for (; message_length && IsSpace(error_text[message_length - 1]);
+          --message_length) {
+    error_text[message_length - 1] = '\0';
+  }
+
+# endif  // GTEST_OS_WINDOWS_MOBILE
+
+  const String error_hex(String::Format("0x%08X ", hr));
+  return ::testing::AssertionFailure()
+      << "Expected: " << expr << " " << expected << ".\n"
+      << "  Actual: " << error_hex << error_text << "\n";
+}
+
+}  // namespace
+
+AssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT
+  if (SUCCEEDED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "succeeds", hr);
+}
+
+AssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT
+  if (FAILED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "fails", hr);
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Utility functions for encoding Unicode text (wide strings) in
+// UTF-8.
+
+// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// like this:
+//
+// Code-point length   Encoding
+//   0 -  7 bits       0xxxxxxx
+//   8 - 11 bits       110xxxxx 10xxxxxx
+//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx
+//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+// The maximum code-point a one-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;
+
+// The maximum code-point a two-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;
+
+// The maximum code-point a three-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;
+
+// The maximum code-point a four-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;
+
+// Chops off the n lowest bits from a bit pattern.  Returns the n
+// lowest bits.  As a side effect, the original bit pattern will be
+// shifted to the right by n bits.
+inline UInt32 ChopLowBits(UInt32* bits, int n) {
+  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);
+  *bits >>= n;
+  return low_bits;
+}
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+char* CodePointToUtf8(UInt32 code_point, char* str) {
+  if (code_point <= kMaxCodePoint1) {
+    str[1] = '\0';
+    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx
+  } else if (code_point <= kMaxCodePoint2) {
+    str[2] = '\0';
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx
+  } else if (code_point <= kMaxCodePoint3) {
+    str[3] = '\0';
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx
+  } else if (code_point <= kMaxCodePoint4) {
+    str[4] = '\0';
+    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx
+  } else {
+    // The longest string String::Format can produce when invoked
+    // with these parameters is 28 character long (not including
+    // the terminating nul character). We are asking for 32 character
+    // buffer just in case. This is also enough for strncpy to
+    // null-terminate the destination string.
+    posix::StrNCpy(
+        str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32);
+    str[31] = '\0';  // Makes sure no change in the format to strncpy leaves
+                     // the result unterminated.
+  }
+  return str;
+}
+
+// The following two functions only make sense if the the system
+// uses UTF-16 for wide string encoding. All supported systems
+// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+
+// Determines if the arguments constitute UTF-16 surrogate pair
+// and thus should be combined into a single Unicode code point
+// using CreateCodePointFromUtf16SurrogatePair.
+inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
+  return sizeof(wchar_t) == 2 &&
+      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
+}
+
+// Creates a Unicode code point from UTF16 surrogate pair.
+inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
+                                                    wchar_t second) {
+  const UInt32 mask = (1 << 10) - 1;
+  return (sizeof(wchar_t) == 2) ?
+      (((first & mask) << 10) | (second & mask)) + 0x10000 :
+      // This function should not be called when the condition is
+      // false, but we provide a sensible default in case it is.
+      static_cast<UInt32>(first);
+}
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+String WideStringToUtf8(const wchar_t* str, int num_chars) {
+  if (num_chars == -1)
+    num_chars = static_cast<int>(wcslen(str));
+
+  ::std::stringstream stream;
+  for (int i = 0; i < num_chars; ++i) {
+    UInt32 unicode_code_point;
+
+    if (str[i] == L'\0') {
+      break;
+    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
+      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
+                                                                 str[i + 1]);
+      i++;
+    } else {
+      unicode_code_point = static_cast<UInt32>(str[i]);
+    }
+
+    char buffer[32];  // CodePointToUtf8 requires a buffer this big.
+    stream << CodePointToUtf8(unicode_code_point, buffer);
+  }
+  return StringStreamToString(&stream);
+}
+
+// Converts a wide C string to a String using the UTF-8 encoding.
+// NULL will be converted to "(null)".
+String String::ShowWideCString(const wchar_t * wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
+}
+
+// Similar to ShowWideCString(), except that this function encloses
+// the converted string in double quotes.
+String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  return String::Format("L\"%s\"",
+                        String::ShowWideCString(wide_c_str).c_str());
+}
+
+// Compares two wide C strings.  Returns true iff they have the same
+// content.
+//
+// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
+  if (lhs == NULL) return rhs == NULL;
+
+  if (rhs == NULL) return false;
+
+  return wcscmp(lhs, rhs) == 0;
+}
+
+// Helper function for *_STREQ on wide strings.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const wchar_t* expected,
+                               const wchar_t* actual) {
+  if (String::WideCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowWideCStringQuoted(expected),
+                   String::ShowWideCStringQuoted(actual),
+                   false);
+}
+
+// Helper function for *_STRNE on wide strings.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const wchar_t* s1,
+                               const wchar_t* s2) {
+  if (!String::WideCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  }
+
+  return AssertionFailure() << "Expected: (" << s1_expression << ") != ("
+                            << s2_expression << "), actual: "
+                            << String::ShowWideCStringQuoted(s1)
+                            << " vs " << String::ShowWideCStringQuoted(s2);
+}
+
+// Compares two C strings, ignoring case.  Returns true iff they have
+// the same content.
+//
+// Unlike strcasecmp(), this function can handle NULL argument(s).  A
+// NULL C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
+  if (lhs == NULL)
+    return rhs == NULL;
+  if (rhs == NULL)
+    return false;
+  return posix::StrCaseCmp(lhs, rhs) == 0;
+}
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                              const wchar_t* rhs) {
+  if (lhs == NULL) return rhs == NULL;
+
+  if (rhs == NULL) return false;
+
+#if GTEST_OS_WINDOWS
+  return _wcsicmp(lhs, rhs) == 0;
+#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID
+  return wcscasecmp(lhs, rhs) == 0;
+#else
+  // Android, Mac OS X and Cygwin don't define wcscasecmp.
+  // Other unknown OSes may not define it either.
+  wint_t left, right;
+  do {
+    left = towlower(*lhs++);
+    right = towlower(*rhs++);
+  } while (left && left == right);
+  return left == right;
+#endif  // OS selector
+}
+
+// Compares this with another String.
+// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+// if this is greater than rhs.
+int String::Compare(const String & rhs) const {
+  const char* const lhs_c_str = c_str();
+  const char* const rhs_c_str = rhs.c_str();
+
+  if (lhs_c_str == NULL) {
+    return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL
+  } else if (rhs_c_str == NULL) {
+    return 1;
+  }
+
+  const size_t shorter_str_len =
+      length() <= rhs.length() ? length() : rhs.length();
+  for (size_t i = 0; i != shorter_str_len; i++) {
+    if (lhs_c_str[i] < rhs_c_str[i]) {
+      return -1;
+    } else if (lhs_c_str[i] > rhs_c_str[i]) {
+      return 1;
+    }
+  }
+  return (length() < rhs.length()) ? -1 :
+      (length() > rhs.length()) ? 1 : 0;
+}
+
+// Returns true iff this String ends with the given suffix.  *Any*
+// String is considered to end with a NULL or empty suffix.
+bool String::EndsWith(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str() == NULL) return false;
+
+  const size_t this_len = strlen(c_str());
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Returns true iff this String ends with the given suffix, ignoring case.
+// Any String is considered to end with a NULL or empty suffix.
+bool String::EndsWithCaseInsensitive(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str() == NULL) return false;
+
+  const size_t this_len = strlen(c_str());
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix);
+}
+
+// Formats a list of arguments to a String, using the same format
+// spec string as for printf.
+//
+// We do not use the StringPrintf class as it is not universally
+// available.
+//
+// The result is limited to 4096 characters (including the tailing 0).
+// If 4096 characters are not enough to format the input, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
+String String::Format(const char * format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  char buffer[4096];
+  const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
+  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+  // 4996 (deprecated function) there.
+#ifdef _MSC_VER  // We are using MSVC.
+# pragma warning(push)          // Saves the current warning state.
+# pragma warning(disable:4996)  // Temporarily disables warning 4996.
+
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+
+# pragma warning(pop)           // Restores the warning state.
+#else  // We are not using MSVC.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#endif  // _MSC_VER
+  va_end(args);
+
+  // vsnprintf()'s behavior is not portable.  When the buffer is not
+  // big enough, it returns a negative value in MSVC, and returns the
+  // needed buffer size on Linux.  When there is an output error, it
+  // always returns a negative value.  For simplicity, we lump the two
+  // error cases together.
+  if (size < 0 || size >= kBufferSize) {
+    return String("<formatting error or buffer exceeded>");
+  } else {
+    return String(buffer, size);
+  }
+}
+
+// Converts the buffer in a stringstream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StringStreamToString(::std::stringstream* ss) {
+  const ::std::string& str = ss->str();
+  const char* const start = str.c_str();
+  const char* const end = start + str.length();
+
+  // We need to use a helper stringstream to do this transformation
+  // because String doesn't support push_back().
+  ::std::stringstream helper;
+  for (const char* ch = start; ch != end; ++ch) {
+    if (*ch == '\0') {
+      helper << "\\0";  // Replaces NUL with "\\0";
+    } else {
+      helper.put(*ch);
+    }
+  }
+
+  return String(helper.str().c_str());
+}
+
+// Appends the user-supplied message to the Google-Test-generated message.
+String AppendUserMessage(const String& gtest_msg,
+                         const Message& user_msg) {
+  // Appends the user message if it's non-empty.
+  const String user_msg_string = user_msg.GetString();
+  if (user_msg_string.empty()) {
+    return gtest_msg;
+  }
+
+  Message msg;
+  msg << gtest_msg << "\n" << user_msg_string;
+
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+    : death_test_count_(0),
+      elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Returns the i-th test part result among all the results. i can
+// range from 0 to total_part_count() - 1. If i is not in that range,
+// aborts the program.
+const TestPartResult& TestResult::GetTestPartResult(int i) const {
+  if (i < 0 || i >= total_part_count())
+    internal::posix::Abort();
+  return test_part_results_.at(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, aborts the
+// program.
+const TestProperty& TestResult::GetTestProperty(int i) const {
+  if (i < 0 || i >= test_property_count())
+    internal::posix::Abort();
+  return test_properties_.at(i);
+}
+
+// Clears the test part results.
+void TestResult::ClearTestPartResults() {
+  test_part_results_.clear();
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+  test_part_results_.push_back(test_part_result);
+}
+
+// Adds a test property to the list. If a property with the same key as the
+// supplied property is already represented, the value of this test_property
+// replaces the old value for that key.
+void TestResult::RecordProperty(const TestProperty& test_property) {
+  if (!ValidateTestProperty(test_property)) {
+    return;
+  }
+  internal::MutexLock lock(&test_properites_mutex_);
+  const std::vector<TestProperty>::iterator property_with_matching_key =
+      std::find_if(test_properties_.begin(), test_properties_.end(),
+                   internal::TestPropertyKeyIs(test_property.key()));
+  if (property_with_matching_key == test_properties_.end()) {
+    test_properties_.push_back(test_property);
+    return;
+  }
+  property_with_matching_key->SetValue(test_property.value());
+}
+
+// Adds a failure if the key is a reserved attribute of Google Test
+// testcase tags.  Returns true if the property is valid.
+bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
+  internal::String key(test_property.key());
+  if (key == "name" || key == "status" || key == "time" || key == "classname") {
+    ADD_FAILURE()
+        << "Reserved key used in RecordProperty(): "
+        << key
+        << " ('name', 'status', 'time', and 'classname' are reserved by "
+        << GTEST_NAME_ << ")";
+    return false;
+  }
+  return true;
+}
+
+// Clears the object.
+void TestResult::Clear() {
+  test_part_results_.clear();
+  test_properties_.clear();
+  death_test_count_ = 0;
+  elapsed_time_ = 0;
+}
+
+// Returns true iff the test failed.
+bool TestResult::Failed() const {
+  for (int i = 0; i < total_part_count(); ++i) {
+    if (GetTestPartResult(i).failed())
+      return true;
+  }
+  return false;
+}
+
+// Returns true iff the test part fatally failed.
+static bool TestPartFatallyFailed(const TestPartResult& result) {
+  return result.fatally_failed();
+}
+
+// Returns true iff the test fatally failed.
+bool TestResult::HasFatalFailure() const {
+  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
+}
+
+// Returns true iff the test part non-fatally failed.
+static bool TestPartNonfatallyFailed(const TestPartResult& result) {
+  return result.nonfatally_failed();
+}
+
+// Returns true iff the test has a non-fatal failure.
+bool TestResult::HasNonfatalFailure() const {
+  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
+}
+
+// Gets the number of all test parts.  This is the sum of the number
+// of successful test parts and the number of failed test parts.
+int TestResult::total_part_count() const {
+  return static_cast<int>(test_part_results_.size());
+}
+
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+  return static_cast<int>(test_properties_.size());
+}
+
+// class Test
+
+// Creates a Test object.
+
+// The c'tor saves the values of all Google Test flags.
+Test::Test()
+    : gtest_flag_saver_(new internal::GTestFlagSaver) {
+}
+
+// The d'tor restores the values of all Google Test flags.
+Test::~Test() {
+  delete gtest_flag_saver_;
+}
+
+// Sets up the test fixture.
+//
+// A sub-class may override this.
+void Test::SetUp() {
+}
+
+// Tears down the test fixture.
+//
+// A sub-class may override this.
+void Test::TearDown() {
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, const char* value) {
+  UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value);
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, int value) {
+  Message value_message;
+  value_message << value;
+  RecordProperty(key, value_message.GetString().c_str());
+}
+
+namespace internal {
+
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message) {
+  // This function is a friend of UnitTest and as such has access to
+  // AddTestPartResult.
+  UnitTest::GetInstance()->AddTestPartResult(
+      result_type,
+      NULL,  // No info about the source file where the exception occurred.
+      -1,    // We have no info on which line caused the exception.
+      message,
+      String());  // No stack trace, either.
+}
+
+}  // namespace internal
+
+// Google Test requires all tests in the same test case to use the same test
+// fixture class.  This function checks if the current test has the
+// same fixture class as the first test in the current test case.  If
+// yes, it returns true; otherwise it generates a Google Test failure and
+// returns false.
+bool Test::HasSameFixtureClass() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  const TestCase* const test_case = impl->current_test_case();
+
+  // Info about the first test in the current test case.
+  const TestInfo* const first_test_info = test_case->test_info_list()[0];
+  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;
+  const char* const first_test_name = first_test_info->name();
+
+  // Info about the current test.
+  const TestInfo* const this_test_info = impl->current_test_info();
+  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;
+  const char* const this_test_name = this_test_info->name();
+
+  if (this_fixture_id != first_fixture_id) {
+    // Is the first test defined using TEST?
+    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();
+    // Is this test defined using TEST?
+    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
+
+    if (first_is_TEST || this_is_TEST) {
+      // The user mixed TEST and TEST_F in this test case - we'll tell
+      // him/her how to fix it.
+
+      // Gets the name of the TEST and the name of the TEST_F.  Note
+      // that first_is_TEST and this_is_TEST cannot both be true, as
+      // the fixture IDs are different for the two tests.
+      const char* const TEST_name =
+          first_is_TEST ? first_test_name : this_test_name;
+      const char* const TEST_F_name =
+          first_is_TEST ? this_test_name : first_test_name;
+
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class, so mixing TEST_F and TEST in the same test case is\n"
+          << "illegal.  In test case " << this_test_info->test_case_name()
+          << ",\n"
+          << "test " << TEST_F_name << " is defined using TEST_F but\n"
+          << "test " << TEST_name << " is defined using TEST.  You probably\n"
+          << "want to change the TEST to TEST_F or move it to another test\n"
+          << "case.";
+    } else {
+      // The user defined two fixture classes with the same name in
+      // two namespaces - we'll tell him/her how to fix it.
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class.  However, in test case "
+          << this_test_info->test_case_name() << ",\n"
+          << "you defined test " << first_test_name
+          << " and test " << this_test_name << "\n"
+          << "using two different test fixture classes.  This can happen if\n"
+          << "the two classes are from different namespaces or translation\n"
+          << "units and have the same name.  You should probably rename one\n"
+          << "of the classes to put the tests into different test cases.";
+    }
+    return false;
+  }
+
+  return true;
+}
+
+#if GTEST_HAS_SEH
+
+// Adds an "exception thrown" fatal failure to the current test.  This
+// function returns its result via an output parameter pointer because VC++
+// prohibits creation of objects with destructors on stack in functions
+// using __try (see error C2712).
+static internal::String* FormatSehExceptionMessage(DWORD exception_code,
+                                                   const char* location) {
+  Message message;
+  message << "SEH exception with code 0x" << std::setbase(16) <<
+    exception_code << std::setbase(10) << " thrown in " << location << ".";
+
+  return new internal::String(message.GetString());
+}
+
+#endif  // GTEST_HAS_SEH
+
+#if GTEST_HAS_EXCEPTIONS
+
+// Adds an "exception thrown" fatal failure to the current test.
+static internal::String FormatCxxExceptionMessage(const char* description,
+                                                  const char* location) {
+  Message message;
+  if (description != NULL) {
+    message << "C++ exception with description \"" << description << "\"";
+  } else {
+    message << "Unknown C++ exception";
+  }
+  message << " thrown in " << location << ".";
+
+  return message.GetString();
+}
+
+static internal::String PrintTestPartResultToString(
+    const TestPartResult& test_part_result);
+
+// A failed Google Test assertion will throw an exception of this type when
+// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled).  We
+// derive it from std::runtime_error, which is for errors presumably
+// detectable only at run time.  Since std::runtime_error inherits from
+// std::exception, many testing frameworks know how to extract and print the
+// message inside it.
+class GoogleTestFailureException : public ::std::runtime_error {
+ public:
+  explicit GoogleTestFailureException(const TestPartResult& failure)
+      : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+};
+#endif  // GTEST_HAS_EXCEPTIONS
+
+namespace internal {
+// We put these helper functions in the internal namespace as IBM's xlC
+// compiler rejects the code if they were declared static.
+
+// Runs the given method and handles SEH exceptions it throws, when
+// SEH is supported; returns the 0-value for type Result in case of an
+// SEH exception.  (Microsoft compilers cannot handle SEH and C++
+// exceptions in the same function.  Therefore, we provide a separate
+// wrapper function for handling SEH exceptions.)
+template <class T, typename Result>
+Result HandleSehExceptionsInMethodIfSupported(
+    T* object, Result (T::*method)(), const char* location) {
+#if GTEST_HAS_SEH
+  __try {
+    return (object->*method)();
+  } __except (internal::UnitTestOptions::GTestShouldProcessSEH(  // NOLINT
+      GetExceptionCode())) {
+    // We create the exception message on the heap because VC++ prohibits
+    // creation of objects with destructors on stack in functions using __try
+    // (see error C2712).
+    internal::String* exception_message = FormatSehExceptionMessage(
+        GetExceptionCode(), location);
+    internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
+                                             *exception_message);
+    delete exception_message;
+    return static_cast<Result>(0);
+  }
+#else
+  (void)location;
+  return (object->*method)();
+#endif  // GTEST_HAS_SEH
+}
+
+// Runs the given method and catches and reports C++ and/or SEH-style
+// exceptions, if they are supported; returns the 0-value for type
+// Result in case of an SEH exception.
+template <class T, typename Result>
+Result HandleExceptionsInMethodIfSupported(
+    T* object, Result (T::*method)(), const char* location) {
+  // NOTE: The user code can affect the way in which Google Test handles
+  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before
+  // RUN_ALL_TESTS() starts. It is technically possible to check the flag
+  // after the exception is caught and either report or re-throw the
+  // exception based on the flag's value:
+  //
+  // try {
+  //   // Perform the test method.
+  // } catch (...) {
+  //   if (GTEST_FLAG(catch_exceptions))
+  //     // Report the exception as failure.
+  //   else
+  //     throw;  // Re-throws the original exception.
+  // }
+  //
+  // However, the purpose of this flag is to allow the program to drop into
+  // the debugger when the exception is thrown. On most platforms, once the
+  // control enters the catch block, the exception origin information is
+  // lost and the debugger will stop the program at the point of the
+  // re-throw in this function -- instead of at the point of the original
+  // throw statement in the code under test.  For this reason, we perform
+  // the check early, sacrificing the ability to affect Google Test's
+  // exception handling in the method where the exception is thrown.
+  if (internal::GetUnitTestImpl()->catch_exceptions()) {
+#if GTEST_HAS_EXCEPTIONS
+    try {
+      return HandleSehExceptionsInMethodIfSupported(object, method, location);
+    } catch (const GoogleTestFailureException&) {  // NOLINT
+      // This exception doesn't originate in code under test. It makes no
+      // sense to report it as a test failure.
+      throw;
+    } catch (const std::exception& e) {  // NOLINT
+      internal::ReportFailureInUnknownLocation(
+          TestPartResult::kFatalFailure,
+          FormatCxxExceptionMessage(e.what(), location));
+    } catch (...) {  // NOLINT
+      internal::ReportFailureInUnknownLocation(
+          TestPartResult::kFatalFailure,
+          FormatCxxExceptionMessage(NULL, location));
+    }
+    return static_cast<Result>(0);
+#else
+    return HandleSehExceptionsInMethodIfSupported(object, method, location);
+#endif  // GTEST_HAS_EXCEPTIONS
+  } else {
+    return (object->*method)();
+  }
+}
+
+}  // namespace internal
+
+// Runs the test and updates the test result.
+void Test::Run() {
+  if (!HasSameFixtureClass()) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
+  // We will run the test only if SetUp() was successful.
+  if (!HasFatalFailure()) {
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    internal::HandleExceptionsInMethodIfSupported(
+        this, &Test::TestBody, "the test body");
+  }
+
+  // However, we want to clean up as much as possible.  Hence we will
+  // always call TearDown(), even if SetUp() or the test body has
+  // failed.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  internal::HandleExceptionsInMethodIfSupported(
+      this, &Test::TearDown, "TearDown()");
+}
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// Returns true iff the current test has a non-fatal failure.
+bool Test::HasNonfatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->
+      HasNonfatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object.
+// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s
+// to signify they cannot be NULLs.
+TestInfo::TestInfo(const char* a_test_case_name,
+                   const char* a_name,
+                   const char* a_type_param,
+                   const char* a_value_param,
+                   internal::TypeId fixture_class_id,
+                   internal::TestFactoryBase* factory)
+    : test_case_name_(a_test_case_name),
+      name_(a_name),
+      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
+      value_param_(a_value_param ? new std::string(a_value_param) : NULL),
+      fixture_class_id_(fixture_class_id),
+      should_run_(false),
+      is_disabled_(false),
+      matches_filter_(false),
+      factory_(factory),
+      result_() {}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() { delete factory_; }
+
+namespace internal {
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   type_param:       the name of the test's type parameter, or NULL if
+//                     this is not a typed or a type-parameterized test.
+//   value_param:      text representation of the test's value parameter,
+//                     or NULL if this is not a value-parameterized test.
+//   fixture_class_id: ID of the test fixture class
+//   set_up_tc:        pointer to the function that sets up the test case
+//   tear_down_tc:     pointer to the function that tears down the test case
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* type_param,
+    const char* value_param,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory) {
+  TestInfo* const test_info =
+      new TestInfo(test_case_name, name, type_param, value_param,
+                   fixture_class_id, factory);
+  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+  return test_info;
+}
+
+#if GTEST_HAS_PARAM_TEST
+void ReportInvalidTestCaseType(const char* test_case_name,
+                               const char* file, int line) {
+  Message errors;
+  errors
+      << "Attempted redefinition of test case " << test_case_name << ".\n"
+      << "All tests in the same test case must use the same test fixture\n"
+      << "class.  However, in test case " << test_case_name << ", you tried\n"
+      << "to define a test using a fixture class different from the one\n"
+      << "used earlier. This can happen if the two fixture classes are\n"
+      << "from different namespaces and have the same name. You should\n"
+      << "probably rename one of the classes to put the tests into different\n"
+      << "test cases.";
+
+  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+          errors.GetString().c_str());
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+}  // namespace internal
+
+namespace {
+
+// A predicate that checks the test name of a TestInfo against a known
+// value.
+//
+// This is used for implementation of the TestCase class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestNameIs is copyable.
+class TestNameIs {
+ public:
+  // Constructor.
+  //
+  // TestNameIs has NO default constructor.
+  explicit TestNameIs(const char* name)
+      : name_(name) {}
+
+  // Returns true iff the test name of test_info matches name_.
+  bool operator()(const TestInfo * test_info) const {
+    return test_info && internal::String(test_info->name()).Compare(name_) == 0;
+  }
+
+ private:
+  internal::String name_;
+};
+
+}  // namespace
+
+namespace internal {
+
+// This method expands all parameterized tests registered with macros TEST_P
+// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// This will be done just once during the program runtime.
+void UnitTestImpl::RegisterParameterizedTests() {
+#if GTEST_HAS_PARAM_TEST
+  if (!parameterized_tests_registered_) {
+    parameterized_test_registry_.RegisterTests();
+    parameterized_tests_registered_ = true;
+  }
+#endif
+}
+
+}  // namespace internal
+
+// Creates the test object, runs it, records its result, and then
+// deletes it.
+void TestInfo::Run() {
+  if (!should_run_) return;
+
+  // Tells UnitTest where to store test result.
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_info(this);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  // Notifies the unit test event listeners that a test is about to start.
+  repeater->OnTestStart(*this);
+
+  const TimeInMillis start = internal::GetTimeInMillis();
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+
+  // Creates the test object.
+  Test* const test = internal::HandleExceptionsInMethodIfSupported(
+      factory_, &internal::TestFactoryBase::CreateTest,
+      "the test fixture's constructor");
+
+  // Runs the test only if the test object was created and its
+  // constructor didn't generate a fatal failure.
+  if ((test != NULL) && !Test::HasFatalFailure()) {
+    // This doesn't throw as all user code that can throw are wrapped into
+    // exception handling code.
+    test->Run();
+  }
+
+  // Deletes the test object.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  internal::HandleExceptionsInMethodIfSupported(
+      test, &Test::DeleteSelf_, "the test fixture's destructor");
+
+  result_.set_elapsed_time(internal::GetTimeInMillis() - start);
+
+  // Notifies the unit test event listener that a test has just finished.
+  repeater->OnTestEnd(*this);
+
+  // Tells UnitTest to stop associating assertion results to this
+  // test.
+  impl->set_current_test_info(NULL);
+}
+
+// class TestCase
+
+// Gets the number of successful tests in this test case.
+int TestCase::successful_test_count() const {
+  return CountIf(test_info_list_, TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+  return CountIf(test_info_list_, TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+  return CountIf(test_info_list_, TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+  return CountIf(test_info_list_, ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+  return static_cast<int>(test_info_list_.size());
+}
+
+// Creates a TestCase with the given name.
+//
+// Arguments:
+//
+//   name:         name of the test case
+//   a_type_param: the name of the test case's type parameter, or NULL if
+//                 this is not a typed or a type-parameterized test case.
+//   set_up_tc:    pointer to the function that sets up the test case
+//   tear_down_tc: pointer to the function that tears down the test case
+TestCase::TestCase(const char* a_name, const char* a_type_param,
+                   Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc)
+    : name_(a_name),
+      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
+      set_up_tc_(set_up_tc),
+      tear_down_tc_(tear_down_tc),
+      should_run_(false),
+      elapsed_time_(0) {
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+  // Deletes every Test in the collection.
+  ForEach(test_info_list_, internal::Delete<TestInfo>);
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+TestInfo* TestCase::GetMutableTestInfo(int i) {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Adds a test to this test case.  Will delete the test upon
+// destruction of the TestCase object.
+void TestCase::AddTestInfo(TestInfo * test_info) {
+  test_info_list_.push_back(test_info);
+  test_indices_.push_back(static_cast<int>(test_indices_.size()));
+}
+
+// Runs every test in this TestCase.
+void TestCase::Run() {
+  if (!should_run_) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_case(this);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  repeater->OnTestCaseStart(*this);
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  internal::HandleExceptionsInMethodIfSupported(
+      this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
+
+  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  for (int i = 0; i < total_test_count(); i++) {
+    GetMutableTestInfo(i)->Run();
+  }
+  elapsed_time_ = internal::GetTimeInMillis() - start;
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  internal::HandleExceptionsInMethodIfSupported(
+      this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
+
+  repeater->OnTestCaseEnd(*this);
+  impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+  ForEach(test_info_list_, TestInfo::ClearTestResult);
+}
+
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+  Shuffle(random, &test_indices_);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+  for (size_t i = 0; i < test_indices_.size(); i++) {
+    test_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// Formats a countable noun.  Depending on its quantity, either the
+// singular form or the plural form is used. e.g.
+//
+// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
+// FormatCountableNoun(5, "book", "books") returns "5 books".
+static internal::String FormatCountableNoun(int count,
+                                            const char * singular_form,
+                                            const char * plural_form) {
+  return internal::String::Format("%d %s", count,
+                                  count == 1 ? singular_form : plural_form);
+}
+
+// Formats the count of tests.
+static internal::String FormatTestCount(int test_count) {
+  return FormatCountableNoun(test_count, "test", "tests");
+}
+
+// Formats the count of test cases.
+static internal::String FormatTestCaseCount(int test_case_count) {
+  return FormatCountableNoun(test_case_count, "test case", "test cases");
+}
+
+// Converts a TestPartResult::Type enum to human-friendly string
+// representation.  Both kNonFatalFailure and kFatalFailure are translated
+// to "Failure", as the user usually doesn't care about the difference
+// between the two when viewing the test result.
+static const char * TestPartResultTypeToString(TestPartResult::Type type) {
+  switch (type) {
+    case TestPartResult::kSuccess:
+      return "Success";
+
+    case TestPartResult::kNonFatalFailure:
+    case TestPartResult::kFatalFailure:
+#ifdef _MSC_VER
+      return "error: ";
+#else
+      return "Failure\n";
+#endif
+    default:
+      return "Unknown result type";
+  }
+}
+
+// Prints a TestPartResult to a String.
+static internal::String PrintTestPartResultToString(
+    const TestPartResult& test_part_result) {
+  return (Message()
+          << internal::FormatFileLocation(test_part_result.file_name(),
+                                          test_part_result.line_number())
+          << " " << TestPartResultTypeToString(test_part_result.type())
+          << test_part_result.message()).GetString();
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(const TestPartResult& test_part_result) {
+  const internal::String& result =
+      PrintTestPartResultToString(test_part_result);
+  printf("%s\n", result.c_str());
+  fflush(stdout);
+  // If the test program runs in Visual Studio or a debugger, the
+  // following statements add the test part result message to the Output
+  // window such that the user can double-click on it to jump to the
+  // corresponding source code location; otherwise they do nothing.
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  // We don't call OutputDebugString*() on Windows Mobile, as printing
+  // to stdout is done by OutputDebugString() there already - we don't
+  // want the same message printed twice.
+  ::OutputDebugStringA(result.c_str());
+  ::OutputDebugStringA("\n");
+#endif
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+  COLOR_DEFAULT,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns the character attribute for the given color.
+WORD GetColorAttribute(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:    return FOREGROUND_RED;
+    case COLOR_GREEN:  return FOREGROUND_GREEN;
+    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+    default:           return 0;
+  }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.  COLOR_DEFAULT is
+// an invalid input.
+const char* GetAnsiColorCode(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:     return "1";
+    case COLOR_GREEN:   return "2";
+    case COLOR_YELLOW:  return "3";
+    default:            return NULL;
+  };
+}
+
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// Returns true iff Google Test should use colors in the output.
+bool ShouldUseColor(bool stdout_is_tty) {
+  const char* const gtest_color = GTEST_FLAG(color).c_str();
+
+  if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
+#if GTEST_OS_WINDOWS
+    // On Windows the TERM variable is usually not set, but the
+    // console there does support colors.
+    return stdout_is_tty;
+#else
+    // On non-Windows platforms, we rely on the TERM variable.
+    const char* const term = posix::GetEnv("TERM");
+    const bool term_supports_color =
+        String::CStringEquals(term, "xterm") ||
+        String::CStringEquals(term, "xterm-color") ||
+        String::CStringEquals(term, "xterm-256color") ||
+        String::CStringEquals(term, "screen") ||
+        String::CStringEquals(term, "linux") ||
+        String::CStringEquals(term, "cygwin");
+    return stdout_is_tty && term_supports_color;
+#endif  // GTEST_OS_WINDOWS
+  }
+
+  return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
+      String::CStringEquals(gtest_color, "1");
+  // We take "yes", "true", "t", and "1" as meaning "yes".  If the
+  // value is neither one of these nor "auto", we treat it as "no" to
+  // be conservative.
+}
+
+// Helpers for printing colored strings to stdout. Note that on Windows, we
+// cannot simply emit special characters and have the terminal change colors.
+// This routine must actually emit the characters rather than return a string
+// that would be colored when printed, as can be done on Linux.
+void ColoredPrintf(GTestColor color, const char* fmt, ...) {
+  va_list args;
+  va_start(args, fmt);
+
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  const bool use_color = false;
+#else
+  static const bool in_color_mode =
+      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
+  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
+#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+  if (!use_color) {
+    vprintf(fmt, args);
+    va_end(args);
+    return;
+  }
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+  // Gets the current text color.
+  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
+  const WORD old_color_attrs = buffer_info.wAttributes;
+
+  // We need to flush the stream buffers into the console before each
+  // SetConsoleTextAttribute call lest it affect the text that is already
+  // printed but has not yet reached the console.
+  fflush(stdout);
+  SetConsoleTextAttribute(stdout_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  vprintf(fmt, args);
+
+  fflush(stdout);
+  // Restores the text color.
+  SetConsoleTextAttribute(stdout_handle, old_color_attrs);
+#else
+  printf("\033[0;3%sm", GetAnsiColorCode(color));
+  vprintf(fmt, args);
+  printf("\033[m");  // Resets the terminal to default.
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  va_end(args);
+}
+
+void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
+  const char* const type_param = test_info.type_param();
+  const char* const value_param = test_info.value_param();
+
+  if (type_param != NULL || value_param != NULL) {
+    printf(", where ");
+    if (type_param != NULL) {
+      printf("TypeParam = %s", type_param);
+      if (value_param != NULL)
+        printf(" and ");
+    }
+    if (value_param != NULL) {
+      printf("GetParam() = %s", value_param);
+    }
+  }
+}
+
+// This class implements the TestEventListener interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public TestEventListener {
+ public:
+  PrettyUnitTestResultPrinter() {}
+  static void PrintTestName(const char * test_case, const char * test) {
+    printf("%s.%s", test_case, test);
+  }
+
+  // The following methods override what's in the TestEventListener class.
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+
+ private:
+  static void PrintFailedTests(const UnitTest& unit_test);
+
+  internal::String test_case_name_;
+};
+
+  // Fired before each iteration of tests starts.
+void PrettyUnitTestResultPrinter::OnTestIterationStart(
+    const UnitTest& unit_test, int iteration) {
+  if (GTEST_FLAG(repeat) != 1)
+    printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
+
+  const char* const filter = GTEST_FLAG(filter).c_str();
+
+  // Prints the filter if it's not *.  This reminds the user that some
+  // tests may be skipped.
+  if (!internal::String::CStringEquals(filter, kUniversalFilter)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: %s filter = %s\n", GTEST_NAME_, filter);
+  }
+
+  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
+    const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: This is test shard %d of %s.\n",
+                  static_cast<int>(shard_index) + 1,
+                  internal::posix::GetEnv(kTestTotalShards));
+  }
+
+  if (GTEST_FLAG(shuffle)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: Randomizing tests' orders with a seed of %d .\n",
+                  unit_test.random_seed());
+  }
+
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("Running %s from %s.\n",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment set-up.\n");
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
+  test_case_name_ = test_case.name();
+  const internal::String counts =
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+  ColoredPrintf(COLOR_GREEN, "[----------] ");
+  printf("%s from %s", counts.c_str(), test_case_name_.c_str());
+  if (test_case.type_param() == NULL) {
+    printf("\n");
+  } else {
+    printf(", where TypeParam = %s\n", test_case.type_param());
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
+  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  printf("\n");
+  fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnTestPartResult(
+    const TestPartResult& result) {
+  // If the test part succeeded, we don't need to do anything.
+  if (result.type() == TestPartResult::kSuccess)
+    return;
+
+  // Print failure message from the assertion (e.g. expected this and got that).
+  PrintTestPartResult(result);
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
+  if (test_info.result()->Passed()) {
+    ColoredPrintf(COLOR_GREEN, "[       OK ] ");
+  } else {
+    ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+  }
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (test_info.result()->Failed())
+    PrintFullTestCommentIfPresent(test_info);
+
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms)\n", internal::StreamableToString(
+           test_info.result()->elapsed_time()).c_str());
+  } else {
+    printf("\n");
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+  if (!GTEST_FLAG(print_time)) return;
+
+  test_case_name_ = test_case.name();
+  const internal::String counts =
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+  ColoredPrintf(COLOR_GREEN, "[----------] ");
+  printf("%s from %s (%s ms total)\n\n",
+         counts.c_str(), test_case_name_.c_str(),
+         internal::StreamableToString(test_case.elapsed_time()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment tear-down\n");
+  fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
+  const int failed_test_count = unit_test.failed_test_count();
+  if (failed_test_count == 0) {
+    return;
+  }
+
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+    const TestCase& test_case = *unit_test.GetTestCase(i);
+    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+      continue;
+    }
+    for (int j = 0; j < test_case.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_case.GetTestInfo(j);
+      if (!test_info.should_run() || test_info.result()->Passed()) {
+        continue;
+      }
+      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+      printf("%s.%s", test_case.name(), test_info.name());
+      PrintFullTestCommentIfPresent(test_info);
+      printf("\n");
+    }
+  }
+}
+
+void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                     int /*iteration*/) {
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("%s from %s ran.",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms total)",
+           internal::StreamableToString(unit_test.elapsed_time()).c_str());
+  }
+  printf("\n");
+  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
+  printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+
+  int num_failures = unit_test.failed_test_count();
+  if (!unit_test.Passed()) {
+    const int failed_test_count = unit_test.failed_test_count();
+    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
+    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+    PrintFailedTests(unit_test);
+    printf("\n%2d FAILED %s\n", num_failures,
+                        num_failures == 1 ? "TEST" : "TESTS");
+  }
+
+  int num_disabled = unit_test.disabled_test_count();
+  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+    if (!num_failures) {
+      printf("\n");  // Add a spacer if no FAILURE banner is displayed.
+    }
+    ColoredPrintf(COLOR_YELLOW,
+                  "  YOU HAVE %d DISABLED %s\n\n",
+                  num_disabled,
+                  num_disabled == 1 ? "TEST" : "TESTS");
+  }
+  // Ensure that Google Test output is printed before, e.g., heapchecker output.
+  fflush(stdout);
+}
+
+// End PrettyUnitTestResultPrinter
+
+// class TestEventRepeater
+//
+// This class forwards events to other event listeners.
+class TestEventRepeater : public TestEventListener {
+ public:
+  TestEventRepeater() : forwarding_enabled_(true) {}
+  virtual ~TestEventRepeater();
+  void Append(TestEventListener *listener);
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled() const { return forwarding_enabled_; }
+  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
+
+  virtual void OnTestProgramStart(const UnitTest& unit_test);
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& unit_test);
+
+ private:
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled_;
+  // The list of listeners that receive events.
+  std::vector<TestEventListener*> listeners_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
+};
+
+TestEventRepeater::~TestEventRepeater() {
+  ForEach(listeners_, Delete<TestEventListener>);
+}
+
+void TestEventRepeater::Append(TestEventListener *listener) {
+  listeners_.push_back(listener);
+}
+
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+  for (size_t i = 0; i < listeners_.size(); ++i) {
+    if (listeners_[i] == listener) {
+      listeners_.erase(listeners_.begin() + i);
+      return listener;
+    }
+  }
+
+  return NULL;
+}
+
+// Since most methods are very similar, use macros to reduce boilerplate.
+// This defines a member that forwards the call to all listeners.
+#define GTEST_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (size_t i = 0; i < listeners_.size(); i++) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+// This defines a member that forwards the call to all listeners in reverse
+// order.
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+
+GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
+GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
+
+#undef GTEST_REPEATER_METHOD_
+#undef GTEST_REVERSE_REPEATER_METHOD_
+
+void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
+                                             int iteration) {
+  if (forwarding_enabled_) {
+    for (size_t i = 0; i < listeners_.size(); i++) {
+      listeners_[i]->OnTestIterationStart(unit_test, iteration);
+    }
+  }
+}
+
+void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
+                                           int iteration) {
+  if (forwarding_enabled_) {
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
+      listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+    }
+  }
+}
+
+// End TestEventRepeater
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+  explicit XmlUnitTestResultPrinter(const char* output_file);
+
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ private:
+  // Is c a whitespace character that is normalized to a space character
+  // when it appears in an XML attribute value?
+  static bool IsNormalizableWhitespace(char c) {
+    return c == 0x9 || c == 0xA || c == 0xD;
+  }
+
+  // May c appear in a well-formed XML document?
+  static bool IsValidXmlCharacter(char c) {
+    return IsNormalizableWhitespace(c) || c >= 0x20;
+  }
+
+  // Returns an XML-escaped copy of the input string str.  If
+  // is_attribute is true, the text is meant to appear as an attribute
+  // value, and normalizable whitespace is preserved by replacing it
+  // with character references.
+  static String EscapeXml(const char* str, bool is_attribute);
+
+  // Returns the given string with all characters invalid in XML removed.
+  static string RemoveInvalidXmlCharacters(const string& str);
+
+  // Convenience wrapper around EscapeXml when str is an attribute value.
+  static String EscapeXmlAttribute(const char* str) {
+    return EscapeXml(str, true);
+  }
+
+  // Convenience wrapper around EscapeXml when str is not an attribute value.
+  static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
+
+  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+  // Streams an XML representation of a TestInfo object.
+  static void OutputXmlTestInfo(::std::ostream* stream,
+                                const char* test_case_name,
+                                const TestInfo& test_info);
+
+  // Prints an XML representation of a TestCase object
+  static void PrintXmlTestCase(FILE* out, const TestCase& test_case);
+
+  // Prints an XML summary of unit_test to output stream out.
+  static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);
+
+  // Produces a string representing the test properties in a result as space
+  // delimited XML attributes based on the property key="value" pairs.
+  // When the String is not empty, it includes a space at the beginning,
+  // to delimit this attribute from prior attributes.
+  static String TestPropertiesAsXmlAttributes(const TestResult& result);
+
+  // The output file.
+  const String output_file_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
+};
+
+// Creates a new XmlUnitTestResultPrinter.
+XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
+    : output_file_(output_file) {
+  if (output_file_.c_str() == NULL || output_file_.empty()) {
+    fprintf(stderr, "XML output file may not be null\n");
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+}
+
+// Called after the unit test ends.
+void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                  int /*iteration*/) {
+  FILE* xmlout = NULL;
+  FilePath output_file(output_file_);
+  FilePath output_dir(output_file.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+    xmlout = posix::FOpen(output_file_.c_str(), "w");
+  }
+  if (xmlout == NULL) {
+    // TODO(wan): report the reason of the failure.
+    //
+    // We don't do it for now as:
+    //
+    //   1. There is no urgent need for it.
+    //   2. It's a bit involved to make the errno variable thread-safe on
+    //      all three operating systems (Linux, Windows, and Mac OS).
+    //   3. To interpret the meaning of errno in a thread-safe way,
+    //      we need the strerror_r() function, which is not available on
+    //      Windows.
+    fprintf(stderr,
+            "Unable to open file \"%s\"\n",
+            output_file_.c_str());
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+  PrintXmlUnitTest(xmlout, unit_test);
+  fclose(xmlout);
+}
+
+// Returns an XML-escaped copy of the input string str.  If is_attribute
+// is true, the text is meant to appear as an attribute value, and
+// normalizable whitespace is preserved by replacing it with character
+// references.
+//
+// Invalid XML characters in str, if any, are stripped from the output.
+// It is expected that most, if not all, of the text processed by this
+// module will consist of ordinary English text.
+// If this module is ever modified to produce version 1.1 XML output,
+// most invalid characters can be retained using character references.
+// TODO(wan): It might be nice to have a minimally invasive, human-readable
+// escaping scheme for invalid characters, rather than dropping them.
+String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {
+  Message m;
+
+  if (str != NULL) {
+    for (const char* src = str; *src; ++src) {
+      switch (*src) {
+        case '<':
+          m << "&lt;";
+          break;
+        case '>':
+          m << "&gt;";
+          break;
+        case '&':
+          m << "&amp;";
+          break;
+        case '\'':
+          if (is_attribute)
+            m << "&apos;";
+          else
+            m << '\'';
+          break;
+        case '"':
+          if (is_attribute)
+            m << "&quot;";
+          else
+            m << '"';
+          break;
+        default:
+          if (IsValidXmlCharacter(*src)) {
+            if (is_attribute && IsNormalizableWhitespace(*src))
+              m << String::Format("&#x%02X;", unsigned(*src));
+            else
+              m << *src;
+          }
+          break;
+      }
+    }
+  }
+
+  return m.GetString();
+}
+
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) {
+  string output;
+  output.reserve(str.size());
+  for (string::const_iterator it = str.begin(); it != str.end(); ++it)
+    if (IsValidXmlCharacter(*it))
+      output.push_back(*it);
+
+  return output;
+}
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuites name="AllTests">        <-- corresponds to a UnitTest object
+//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object
+//     <testcase name="test-name">     <-- corresponds to a TestInfo object
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//                                     <-- individual assertion failures
+//     </testcase>
+//   </testsuite>
+// </testsuites>
+
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+  ::std::stringstream ss;
+  ss << ms/1000.0;
+  return ss.str();
+}
+
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+                                                     const char* data) {
+  const char* segment = data;
+  *stream << "<![CDATA[";
+  for (;;) {
+    const char* const next_segment = strstr(segment, "]]>");
+    if (next_segment != NULL) {
+      stream->write(
+          segment, static_cast<std::streamsize>(next_segment - segment));
+      *stream << "]]>]]&gt;<![CDATA[";
+      segment = next_segment + strlen("]]>");
+    } else {
+      *stream << segment;
+      break;
+    }
+  }
+  *stream << "]]>";
+}
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+                                                 const char* test_case_name,
+                                                 const TestInfo& test_info) {
+  const TestResult& result = *test_info.result();
+  *stream << "    <testcase name=\""
+          << EscapeXmlAttribute(test_info.name()).c_str() << "\"";
+
+  if (test_info.value_param() != NULL) {
+    *stream << " value_param=\"" << EscapeXmlAttribute(test_info.value_param())
+            << "\"";
+  }
+  if (test_info.type_param() != NULL) {
+    *stream << " type_param=\"" << EscapeXmlAttribute(test_info.type_param())
+            << "\"";
+  }
+
+  *stream << " status=\""
+          << (test_info.should_run() ? "run" : "notrun")
+          << "\" time=\""
+          << FormatTimeInMillisAsSeconds(result.elapsed_time())
+          << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+          << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
+
+  int failures = 0;
+  for (int i = 0; i < result.total_part_count(); ++i) {
+    const TestPartResult& part = result.GetTestPartResult(i);
+    if (part.failed()) {
+      if (++failures == 1)
+        *stream << ">\n";
+      *stream << "      <failure message=\""
+              << EscapeXmlAttribute(part.summary()).c_str()
+              << "\" type=\"\">";
+      const string location = internal::FormatCompilerIndependentFileLocation(
+          part.file_name(), part.line_number());
+      const string message = location + "\n" + part.message();
+      OutputXmlCDataSection(stream,
+                            RemoveInvalidXmlCharacters(message).c_str());
+      *stream << "</failure>\n";
+    }
+  }
+
+  if (failures == 0)
+    *stream << " />\n";
+  else
+    *stream << "    </testcase>\n";
+}
+
+// Prints an XML representation of a TestCase object
+void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
+                                                const TestCase& test_case) {
+  fprintf(out,
+          "  <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" "
+          "disabled=\"%d\" ",
+          EscapeXmlAttribute(test_case.name()).c_str(),
+          test_case.total_test_count(),
+          test_case.failed_test_count(),
+          test_case.disabled_test_count());
+  fprintf(out,
+          "errors=\"0\" time=\"%s\">\n",
+          FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
+  for (int i = 0; i < test_case.total_test_count(); ++i) {
+    ::std::stringstream stream;
+    OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+    fprintf(out, "%s", StringStreamToString(&stream).c_str());
+  }
+  fprintf(out, "  </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+                                                const UnitTest& unit_test) {
+  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  fprintf(out,
+          "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+          "errors=\"0\" time=\"%s\" ",
+          unit_test.total_test_count(),
+          unit_test.failed_test_count(),
+          unit_test.disabled_test_count(),
+          FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
+  if (GTEST_FLAG(shuffle)) {
+    fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
+  }
+  fprintf(out, "name=\"AllTests\">\n");
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+    PrintXmlTestCase(out, *unit_test.GetTestCase(i));
+  fprintf(out, "</testsuites>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+    const TestResult& result) {
+  Message attributes;
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    attributes << " " << property.key() << "="
+        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+#if GTEST_CAN_STREAM_RESULTS_
+
+// Streams test results to the given port on the given host machine.
+class StreamingListener : public EmptyTestEventListener {
+ public:
+  // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
+  static string UrlEncode(const char* str);
+
+  StreamingListener(const string& host, const string& port)
+      : sockfd_(-1), host_name_(host), port_num_(port) {
+    MakeConnection();
+    Send("gtest_streaming_protocol_version=1.0\n");
+  }
+
+  virtual ~StreamingListener() {
+    if (sockfd_ != -1)
+      CloseConnection();
+  }
+
+  void OnTestProgramStart(const UnitTest& /* unit_test */) {
+    Send("event=TestProgramStart\n");
+  }
+
+  void OnTestProgramEnd(const UnitTest& unit_test) {
+    // Note that Google Test current only report elapsed time for each
+    // test iteration, not for the entire test program.
+    Send(String::Format("event=TestProgramEnd&passed=%d\n",
+                        unit_test.Passed()));
+
+    // Notify the streaming server to stop.
+    CloseConnection();
+  }
+
+  void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {
+    Send(String::Format("event=TestIterationStart&iteration=%d\n",
+                        iteration));
+  }
+
+  void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {
+    Send(String::Format("event=TestIterationEnd&passed=%d&elapsed_time=%sms\n",
+                        unit_test.Passed(),
+                        StreamableToString(unit_test.elapsed_time()).c_str()));
+  }
+
+  void OnTestCaseStart(const TestCase& test_case) {
+    Send(String::Format("event=TestCaseStart&name=%s\n", test_case.name()));
+  }
+
+  void OnTestCaseEnd(const TestCase& test_case) {
+    Send(String::Format("event=TestCaseEnd&passed=%d&elapsed_time=%sms\n",
+                        test_case.Passed(),
+                        StreamableToString(test_case.elapsed_time()).c_str()));
+  }
+
+  void OnTestStart(const TestInfo& test_info) {
+    Send(String::Format("event=TestStart&name=%s\n", test_info.name()));
+  }
+
+  void OnTestEnd(const TestInfo& test_info) {
+    Send(String::Format(
+        "event=TestEnd&passed=%d&elapsed_time=%sms\n",
+        (test_info.result())->Passed(),
+        StreamableToString((test_info.result())->elapsed_time()).c_str()));
+  }
+
+  void OnTestPartResult(const TestPartResult& test_part_result) {
+    const char* file_name = test_part_result.file_name();
+    if (file_name == NULL)
+      file_name = "";
+    Send(String::Format("event=TestPartResult&file=%s&line=%d&message=",
+                        UrlEncode(file_name).c_str(),
+                        test_part_result.line_number()));
+    Send(UrlEncode(test_part_result.message()) + "\n");
+  }
+
+ private:
+  // Creates a client socket and connects to the server.
+  void MakeConnection();
+
+  // Closes the socket.
+  void CloseConnection() {
+    GTEST_CHECK_(sockfd_ != -1)
+        << "CloseConnection() can be called only when there is a connection.";
+
+    close(sockfd_);
+    sockfd_ = -1;
+  }
+
+  // Sends a string to the socket.
+  void Send(const string& message) {
+    GTEST_CHECK_(sockfd_ != -1)
+        << "Send() can be called only when there is a connection.";
+
+    const int len = static_cast<int>(message.length());
+    if (write(sockfd_, message.c_str(), len) != len) {
+      GTEST_LOG_(WARNING)
+          << "stream_result_to: failed to stream to "
+          << host_name_ << ":" << port_num_;
+    }
+  }
+
+  int sockfd_;   // socket file descriptor
+  const string host_name_;
+  const string port_num_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
+};  // class StreamingListener
+
+// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
+// replaces them by "%xx" where xx is their hexadecimal value. For
+// example, replaces "=" with "%3D".  This algorithm is O(strlen(str))
+// in both time and space -- important as the input str may contain an
+// arbitrarily long test failure message and stack trace.
+string StreamingListener::UrlEncode(const char* str) {
+  string result;
+  result.reserve(strlen(str) + 1);
+  for (char ch = *str; ch != '\0'; ch = *++str) {
+    switch (ch) {
+      case '%':
+      case '=':
+      case '&':
+      case '\n':
+        result.append(String::Format("%%%02x", static_cast<unsigned char>(ch)));
+        break;
+      default:
+        result.push_back(ch);
+        break;
+    }
+  }
+  return result;
+}
+
+void StreamingListener::MakeConnection() {
+  GTEST_CHECK_(sockfd_ == -1)
+      << "MakeConnection() can't be called when there is already a connection.";
+
+  addrinfo hints;
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;    // To allow both IPv4 and IPv6 addresses.
+  hints.ai_socktype = SOCK_STREAM;
+  addrinfo* servinfo = NULL;
+
+  // Use the getaddrinfo() to get a linked list of IP addresses for
+  // the given host name.
+  const int error_num = getaddrinfo(
+      host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);
+  if (error_num != 0) {
+    GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: "
+                        << gai_strerror(error_num);
+  }
+
+  // Loop through all the results and connect to the first we can.
+  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;
+       cur_addr = cur_addr->ai_next) {
+    sockfd_ = socket(
+        cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);
+    if (sockfd_ != -1) {
+      // Connect the client socket to the server socket.
+      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {
+        close(sockfd_);
+        sockfd_ = -1;
+      }
+    }
+  }
+
+  freeaddrinfo(servinfo);  // all done with this structure
+
+  if (sockfd_ == -1) {
+    GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to "
+                        << host_name_ << ":" << port_num_;
+  }
+}
+
+// End of class Streaming Listener
+#endif  // GTEST_CAN_STREAM_RESULTS__
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+// L < UnitTest::mutex_
+ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
+  TraceInfo trace;
+  trace.file = file;
+  trace.line = line;
+  trace.message = message.GetString();
+
+  UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+// L < UnitTest::mutex_
+ScopedTrace::~ScopedTrace() {
+  UnitTest::GetInstance()->PopGTestTrace();
+}
+
+
+// class OsStackTraceGetter
+
+// Returns the current OS stack trace as a String.  Parameters:
+//
+//   max_depth  - the maximum number of stack frames to be included
+//                in the trace.
+//   skip_count - the number of top frames to be skipped; doesn't count
+//                against max_depth.
+//
+// L < mutex_
+// We use "L < mutex_" to denote that the function may acquire mutex_.
+String OsStackTraceGetter::CurrentStackTrace(int, int) {
+  return String("");
+}
+
+// L < mutex_
+void OsStackTraceGetter::UponLeavingGTest() {
+}
+
+const char* const
+OsStackTraceGetter::kElidedFramesMarker =
+    "... " GTEST_NAME_ " internal frames ...";
+
+}  // namespace internal
+
+// class TestEventListeners
+
+TestEventListeners::TestEventListeners()
+    : repeater_(new internal::TestEventRepeater()),
+      default_result_printer_(NULL),
+      default_xml_generator_(NULL) {
+}
+
+TestEventListeners::~TestEventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output.  Can be removed from the listeners list to shut down default
+// console output.  Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void TestEventListeners::Append(TestEventListener* listener) {
+  repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it.  It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
+  if (listener == default_result_printer_)
+    default_result_printer_ = NULL;
+  else if (listener == default_xml_generator_)
+    default_xml_generator_ = NULL;
+  return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the TestEventListener events to all
+// subscribers.
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+  if (default_result_printer_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_result_printer_);
+    default_result_printer_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Sets the default_xml_generator attribute to the provided listener.  The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+  if (default_xml_generator_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_xml_generator_);
+    default_xml_generator_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool TestEventListeners::EventForwardingEnabled() const {
+  return repeater_->forwarding_enabled();
+}
+
+void TestEventListeners::SuppressEventForwarding() {
+  repeater_->set_forwarding_enabled(false);
+}
+
+// class UnitTest
+
+// Gets the singleton UnitTest object.  The first time this method is
+// called, a UnitTest object is constructed and returned.  Consecutive
+// calls will return the same object.
+//
+// We don't protect this under mutex_ as a user is not supposed to
+// call this before main() starts, from which point on the return
+// value will never change.
+UnitTest * UnitTest::GetInstance() {
+  // When compiled with MSVC 7.1 in optimized mode, destroying the
+  // UnitTest object upon exiting the program messes up the exit code,
+  // causing successful tests to appear failed.  We have to use a
+  // different implementation in this case to bypass the compiler bug.
+  // This implementation makes the compiler happy, at the cost of
+  // leaking the UnitTest object.
+
+  // CodeGear C++Builder insists on a public destructor for the
+  // default implementation.  Use this implementation to keep good OO
+  // design with private destructor.
+
+#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+  static UnitTest* const instance = new UnitTest;
+  return instance;
+#else
+  static UnitTest instance;
+  return &instance;
+#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+}
+
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+  return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+  return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+  return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+  return impl()->GetTestCase(i);
+}
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+TestCase* UnitTest::GetMutableTestCase(int i) {
+  return impl()->GetMutableTestCase(i);
+}
+
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+TestEventListeners& UnitTest::listeners() {
+  return *impl()->listeners();
+}
+
+// Registers and returns a global test environment.  When a test
+// program is run, all global test environments will be set-up in the
+// order they were registered.  After all tests in the program have
+// finished, all global test environments will be torn-down in the
+// *reverse* order they were registered.
+//
+// The UnitTest object takes ownership of the given environment.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+Environment* UnitTest::AddEnvironment(Environment* env) {
+  if (env == NULL) {
+    return NULL;
+  }
+
+  impl_->environments().push_back(env);
+  return env;
+}
+
+// Adds a TestPartResult to the current TestResult object.  All Google Test
+// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
+// this to report their results.  The user code should use the
+// assertion macros instead of calling this directly.
+// L < mutex_
+void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
+                                 const char* file_name,
+                                 int line_number,
+                                 const internal::String& message,
+                                 const internal::String& os_stack_trace) {
+  Message msg;
+  msg << message;
+
+  internal::MutexLock lock(&mutex_);
+  if (impl_->gtest_trace_stack().size() > 0) {
+    msg << "\n" << GTEST_NAME_ << " trace:";
+
+    for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+         i > 0; --i) {
+      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
+      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+          << " " << trace.message;
+    }
+  }
+
+  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+    msg << internal::kStackTraceMarker << os_stack_trace;
+  }
+
+  const TestPartResult result =
+    TestPartResult(result_type, file_name, line_number,
+                   msg.GetString().c_str());
+  impl_->GetTestPartResultReporterForCurrentThread()->
+      ReportTestPartResult(result);
+
+  if (result_type != TestPartResult::kSuccess) {
+    // gtest_break_on_failure takes precedence over
+    // gtest_throw_on_failure.  This allows a user to set the latter
+    // in the code (perhaps in order to use Google Test assertions
+    // with another testing framework) and specify the former on the
+    // command line for debugging.
+    if (GTEST_FLAG(break_on_failure)) {
+#if GTEST_OS_WINDOWS
+      // Using DebugBreak on Windows allows gtest to still break into a debugger
+      // when a failure happens and both the --gtest_break_on_failure and
+      // the --gtest_catch_exceptions flags are specified.
+      DebugBreak();
+#else
+      // Dereference NULL through a volatile pointer to prevent the compiler
+      // from removing. We use this rather than abort() or __builtin_trap() for
+      // portability: Symbian doesn't implement abort() well, and some debuggers
+      // don't correctly trap abort().
+      *static_cast<volatile int*>(NULL) = 1;
+#endif  // GTEST_OS_WINDOWS
+    } else if (GTEST_FLAG(throw_on_failure)) {
+#if GTEST_HAS_EXCEPTIONS
+      throw GoogleTestFailureException(result);
+#else
+      // We cannot call abort() as it generates a pop-up in debug mode
+      // that cannot be suppressed in VC 7.1 or below.
+      exit(1);
+#endif
+    }
+  }
+}
+
+// Creates and adds a property to the current TestResult. If a property matching
+// the supplied value already exists, updates its value instead.
+void UnitTest::RecordPropertyForCurrentTest(const char* key,
+                                            const char* value) {
+  const TestProperty test_property(key, value);
+  impl_->current_test_result()->RecordProperty(test_property);
+}
+
+// Runs all tests in this UnitTest object and prints the result.
+// Returns 0 if successful, or 1 otherwise.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+int UnitTest::Run() {
+  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be
+  // used for the duration of the program.
+  impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
+
+#if GTEST_HAS_SEH
+  const bool in_death_test_child_process =
+      internal::GTEST_FLAG(internal_run_death_test).length() > 0;
+
+  // Either the user wants Google Test to catch exceptions thrown by the
+  // tests or this is executing in the context of death test child
+  // process. In either case the user does not want to see pop-up dialogs
+  // about crashes - they are expected.
+  if (impl()->catch_exceptions() || in_death_test_child_process) {
+
+# if !GTEST_OS_WINDOWS_MOBILE
+    // SetErrorMode doesn't exist on CE.
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+# endif  // !GTEST_OS_WINDOWS_MOBILE
+
+# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
+    // Death test children can be terminated with _abort().  On Windows,
+    // _abort() can show a dialog with a warning message.  This forces the
+    // abort message to go to stderr instead.
+    _set_error_mode(_OUT_TO_STDERR);
+# endif
+
+# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+    // In the debug version, Visual Studio pops up a separate dialog
+    // offering a choice to debug the aborted program. We need to suppress
+    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
+    // executed. Google Test will notify the user of any unexpected
+    // failure via stderr.
+    //
+    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
+    // Users of prior VC versions shall suffer the agony and pain of
+    // clicking through the countless debug dialogs.
+    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
+    // debug mode when compiled with VC 7.1 or lower.
+    if (!GTEST_FLAG(break_on_failure))
+      _set_abort_behavior(
+          0x0,                                    // Clear the following flags:
+          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
+# endif
+
+  }
+#endif  // GTEST_HAS_SEH
+
+  return internal::HandleExceptionsInMethodIfSupported(
+      impl(),
+      &internal::UnitTestImpl::RunAllTests,
+      "auxiliary test code (environments or event listeners)") ? 0 : 1;
+}
+
+// Returns the working directory when the first TEST() or TEST_F() was
+// executed.
+const char* UnitTest::original_working_dir() const {
+  return impl_->original_working_dir_.c_str();
+}
+
+// Returns the TestCase object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestCase* UnitTest::current_test_case() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_case();
+}
+
+// Returns the TestInfo object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestInfo* UnitTest::current_test_info() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_info();
+}
+
+// Returns the random seed used at the start of the current test run.
+int UnitTest::random_seed() const { return impl_->random_seed(); }
+
+#if GTEST_HAS_PARAM_TEST
+// Returns ParameterizedTestCaseRegistry object used to keep track of
+// value-parameterized tests and instantiate and register them.
+// L < mutex_
+internal::ParameterizedTestCaseRegistry&
+    UnitTest::parameterized_test_registry() {
+  return impl_->parameterized_test_registry();
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+// Creates an empty UnitTest.
+UnitTest::UnitTest() {
+  impl_ = new internal::UnitTestImpl(this);
+}
+
+// Destructor of UnitTest.
+UnitTest::~UnitTest() {
+  delete impl_;
+}
+
+// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+// Google Test trace stack.
+// L < mutex_
+void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack().push_back(trace);
+}
+
+// Pops a trace from the per-thread Google Test trace stack.
+// L < mutex_
+void UnitTest::PopGTestTrace() {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack().pop_back();
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+    : parent_(parent),
+#ifdef _MSC_VER
+# pragma warning(push)                    // Saves the current warning state.
+# pragma warning(disable:4355)            // Temporarily disables warning 4355
+                                         // (using this in initializer).
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+# pragma warning(pop)                     // Restores the warning state again.
+#else
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#endif  // _MSC_VER
+      global_test_part_result_repoter_(
+          &default_global_test_part_result_reporter_),
+      per_thread_test_part_result_reporter_(
+          &default_per_thread_test_part_result_reporter_),
+#if GTEST_HAS_PARAM_TEST
+      parameterized_test_registry_(),
+      parameterized_tests_registered_(false),
+#endif  // GTEST_HAS_PARAM_TEST
+      last_death_test_case_(-1),
+      current_test_case_(NULL),
+      current_test_info_(NULL),
+      ad_hoc_test_result_(),
+      os_stack_trace_getter_(NULL),
+      post_flag_parse_init_performed_(false),
+      random_seed_(0),  // Will be overridden by the flag before first use.
+      random_(0),  // Will be reseeded before first use.
+      elapsed_time_(0),
+#if GTEST_HAS_DEATH_TEST
+      internal_run_death_test_flag_(NULL),
+      death_test_factory_(new DefaultDeathTestFactory),
+#endif
+      // Will be overridden by the flag before first use.
+      catch_exceptions_(false) {
+  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
+}
+
+UnitTestImpl::~UnitTestImpl() {
+  // Deletes every TestCase.
+  ForEach(test_cases_, internal::Delete<TestCase>);
+
+  // Deletes every Environment.
+  ForEach(environments_, internal::Delete<Environment>);
+
+  delete os_stack_trace_getter_;
+}
+
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+  if (internal_run_death_test_flag_.get() != NULL)
+    listeners()->SuppressEventForwarding();
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+  const String& output_format = UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml") {
+    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+  } else if (output_format != "") {
+    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+           output_format.c_str());
+    fflush(stdout);
+  }
+}
+
+#if GTEST_CAN_STREAM_RESULTS_
+// Initializes event listeners for streaming test results in String form.
+// Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureStreamingOutput() {
+  const string& target = GTEST_FLAG(stream_result_to);
+  if (!target.empty()) {
+    const size_t pos = target.find(':');
+    if (pos != string::npos) {
+      listeners()->Append(new StreamingListener(target.substr(0, pos),
+                                                target.substr(pos+1)));
+    } else {
+      printf("WARNING: unrecognized streaming target \"%s\" ignored.\n",
+             target.c_str());
+      fflush(stdout);
+    }
+  }
+}
+#endif  // GTEST_CAN_STREAM_RESULTS_
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests.  Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+  // Ensures that this function does not execute more than once.
+  if (!post_flag_parse_init_performed_) {
+    post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+    InitDeathTestSubprocessControlInfo();
+    SuppressTestEventsIfInSubprocess();
+#endif  // GTEST_HAS_DEATH_TEST
+
+    // Registers parameterized tests. This makes parameterized tests
+    // available to the UnitTest reflection API without running
+    // RUN_ALL_TESTS.
+    RegisterParameterizedTests();
+
+    // Configures listeners for XML output. This makes it possible for users
+    // to shut down the default XML output before invoking RUN_ALL_TESTS.
+    ConfigureXmlOutput();
+
+#if GTEST_CAN_STREAM_RESULTS_
+    // Configures listeners for streaming test results to the specified server.
+    ConfigureStreamingOutput();
+#endif  // GTEST_CAN_STREAM_RESULTS_
+  }
+}
+
+// A predicate that checks the name of a TestCase against a known
+// value.
+//
+// This is used for implementation of the UnitTest class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestCaseNameIs is copyable.
+class TestCaseNameIs {
+ public:
+  // Constructor.
+  explicit TestCaseNameIs(const String& name)
+      : name_(name) {}
+
+  // Returns true iff the name of test_case matches name_.
+  bool operator()(const TestCase* test_case) const {
+    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+  }
+
+ private:
+  String name_;
+};
+
+// Finds and returns a TestCase with the given name.  If one doesn't
+// exist, creates one and returns it.  It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
+//
+// Arguments:
+//
+//   test_case_name: name of the test case
+//   type_param:     the name of the test case's type parameter, or NULL if
+//                   this is not a typed or a type-parameterized test case.
+//   set_up_tc:      pointer to the function that sets up the test case
+//   tear_down_tc:   pointer to the function that tears down the test case
+TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
+                                    const char* type_param,
+                                    Test::SetUpTestCaseFunc set_up_tc,
+                                    Test::TearDownTestCaseFunc tear_down_tc) {
+  // Can we find a TestCase with the given name?
+  const std::vector<TestCase*>::const_iterator test_case =
+      std::find_if(test_cases_.begin(), test_cases_.end(),
+                   TestCaseNameIs(test_case_name));
+
+  if (test_case != test_cases_.end())
+    return *test_case;
+
+  // No.  Let's create one.
+  TestCase* const new_test_case =
+      new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
+
+  // Is this a death test case?
+  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
+                                               kDeathTestCaseFilter)) {
+    // Yes.  Inserts the test case after the last death test case
+    // defined so far.  This only works when the test cases haven't
+    // been shuffled.  Otherwise we may end up running a death test
+    // after a non-death test.
+    ++last_death_test_case_;
+    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+                       new_test_case);
+  } else {
+    // No.  Appends to the end of the list.
+    test_cases_.push_back(new_test_case);
+  }
+
+  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
+  return new_test_case;
+}
+
+// Helpers for setting up / tearing down the given environment.  They
+// are for use in the ForEach() function.
+static void SetUpEnvironment(Environment* env) { env->SetUp(); }
+static void TearDownEnvironment(Environment* env) { env->TearDown(); }
+
+// Runs all tests in this UnitTest object, prints the result, and
+// returns true if all tests are successful.  If any exception is
+// thrown during a test, the test is considered to be failed, but the
+// rest of the tests will still be run.
+//
+// When parameterized tests are enabled, it expands and registers
+// parameterized tests first in RegisterParameterizedTests().
+// All other functions called from RunAllTests() may safely assume that
+// parameterized tests are ready to be counted and run.
+bool UnitTestImpl::RunAllTests() {
+  // Makes sure InitGoogleTest() was called.
+  if (!GTestIsInitialized()) {
+    printf("%s",
+           "\nThis test program did NOT call ::testing::InitGoogleTest "
+           "before calling RUN_ALL_TESTS().  Please fix it.\n");
+    return false;
+  }
+
+  // Do not run any test if the --help flag was specified.
+  if (g_help_flag)
+    return true;
+
+  // Repeats the call to the post-flag parsing initialization in case the
+  // user didn't call InitGoogleTest.
+  PostFlagParsingInit();
+
+  // Even if sharding is not on, test runners may want to use the
+  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
+  // protocol.
+  internal::WriteToShardStatusFileIfNeeded();
+
+  // True iff we are in a subprocess for running a thread-safe-style
+  // death test.
+  bool in_subprocess_for_death_test = false;
+
+#if GTEST_HAS_DEATH_TEST
+  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif  // GTEST_HAS_DEATH_TEST
+
+  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
+                                        in_subprocess_for_death_test);
+
+  // Compares the full test names with the filter to decide which
+  // tests to run.
+  const bool has_tests_to_run = FilterTests(should_shard
+                                              ? HONOR_SHARDING_PROTOCOL
+                                              : IGNORE_SHARDING_PROTOCOL) > 0;
+
+  // Lists the tests and exits if the --gtest_list_tests flag was specified.
+  if (GTEST_FLAG(list_tests)) {
+    // This must be called *after* FilterTests() has been called.
+    ListTestsMatchingFilter();
+    return true;
+  }
+
+  random_seed_ = GTEST_FLAG(shuffle) ?
+      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
+
+  // True iff at least one test has failed.
+  bool failed = false;
+
+  TestEventListener* repeater = listeners()->repeater();
+
+  repeater->OnTestProgramStart(*parent_);
+
+  // How many times to repeat the tests?  We don't want to repeat them
+  // when we are inside the subprocess of a death test.
+  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
+  // Repeats forever if the repeat count is negative.
+  const bool forever = repeat < 0;
+  for (int i = 0; forever || i != repeat; i++) {
+    // We want to preserve failures generated by ad-hoc test
+    // assertions executed before RUN_ALL_TESTS().
+    ClearNonAdHocTestResult();
+
+    const TimeInMillis start = GetTimeInMillis();
+
+    // Shuffles test cases and tests if requested.
+    if (has_tests_to_run && GTEST_FLAG(shuffle)) {
+      random()->Reseed(random_seed_);
+      // This should be done before calling OnTestIterationStart(),
+      // such that a test event listener can see the actual test order
+      // in the event.
+      ShuffleTests();
+    }
+
+    // Tells the unit test event listeners that the tests are about to start.
+    repeater->OnTestIterationStart(*parent_, i);
+
+    // Runs each test case if there is at least one test to run.
+    if (has_tests_to_run) {
+      // Sets up all environments beforehand.
+      repeater->OnEnvironmentsSetUpStart(*parent_);
+      ForEach(environments_, SetUpEnvironment);
+      repeater->OnEnvironmentsSetUpEnd(*parent_);
+
+      // Runs the tests only if there was no fatal failure during global
+      // set-up.
+      if (!Test::HasFatalFailure()) {
+        for (int test_index = 0; test_index < total_test_case_count();
+             test_index++) {
+          GetMutableTestCase(test_index)->Run();
+        }
+      }
+
+      // Tears down all environments in reverse order afterwards.
+      repeater->OnEnvironmentsTearDownStart(*parent_);
+      std::for_each(environments_.rbegin(), environments_.rend(),
+                    TearDownEnvironment);
+      repeater->OnEnvironmentsTearDownEnd(*parent_);
+    }
+
+    elapsed_time_ = GetTimeInMillis() - start;
+
+    // Tells the unit test event listener that the tests have just finished.
+    repeater->OnTestIterationEnd(*parent_, i);
+
+    // Gets the result and clears it.
+    if (!Passed()) {
+      failed = true;
+    }
+
+    // Restores the original test order after the iteration.  This
+    // allows the user to quickly repro a failure that happens in the
+    // N-th iteration without repeating the first (N - 1) iterations.
+    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
+    // case the user somehow changes the value of the flag somewhere
+    // (it's always safe to unshuffle the tests).
+    UnshuffleTests();
+
+    if (GTEST_FLAG(shuffle)) {
+      // Picks a new random seed for each iteration.
+      random_seed_ = GetNextRandomSeed(random_seed_);
+    }
+  }
+
+  repeater->OnTestProgramEnd(*parent_);
+
+  return !failed;
+}
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded() {
+  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
+  if (test_shard_file != NULL) {
+    FILE* const file = posix::FOpen(test_shard_file, "w");
+    if (file == NULL) {
+      ColoredPrintf(COLOR_RED,
+                    "Could not write to the test shard status file \"%s\" "
+                    "specified by the %s environment variable.\n",
+                    test_shard_file, kTestShardStatusFile);
+      fflush(stdout);
+      exit(EXIT_FAILURE);
+    }
+    fclose(file);
+  }
+}
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (i.e., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+bool ShouldShard(const char* total_shards_env,
+                 const char* shard_index_env,
+                 bool in_subprocess_for_death_test) {
+  if (in_subprocess_for_death_test) {
+    return false;
+  }
+
+  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
+  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
+
+  if (total_shards == -1 && shard_index == -1) {
+    return false;
+  } else if (total_shards == -1 && shard_index != -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestShardIndex << " = " << shard_index
+      << ", but have left " << kTestTotalShards << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (total_shards != -1 && shard_index == -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestTotalShards << " = " << total_shards
+      << ", but have left " << kTestShardIndex << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (shard_index < 0 || shard_index >= total_shards) {
+    const Message msg = Message()
+      << "Invalid environment variables: we require 0 <= "
+      << kTestShardIndex << " < " << kTestTotalShards
+      << ", but you have " << kTestShardIndex << "=" << shard_index
+      << ", " << kTestTotalShards << "=" << total_shards << ".\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  }
+
+  return total_shards > 1;
+}
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error
+// and aborts.
+Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) {
+  const char* str_val = posix::GetEnv(var);
+  if (str_val == NULL) {
+    return default_val;
+  }
+
+  Int32 result;
+  if (!ParseInt32(Message() << "The value of environment variable " << var,
+                  str_val, &result)) {
+    exit(EXIT_FAILURE);
+  }
+  return result;
+}
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
+  return (test_id % total_shards) == shard_index;
+}
+
+// Compares the name of each test with the user-specified filter to
+// decide whether the test should be run, then records the result in
+// each TestCase and TestInfo object.
+// If shard_tests == true, further filters tests based on sharding
+// variables in the environment - see
+// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
+  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+
+  // num_runnable_tests are the number of tests that will
+  // run across all shards (i.e., match filter and are not disabled).
+  // num_selected_tests are the number of tests to be run on
+  // this shard.
+  int num_runnable_tests = 0;
+  int num_selected_tests = 0;
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    TestCase* const test_case = test_cases_[i];
+    const String &test_case_name = test_case->name();
+    test_case->set_should_run(false);
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      TestInfo* const test_info = test_case->test_info_list()[j];
+      const String test_name(test_info->name());
+      // A test is disabled if test case name or test name matches
+      // kDisableTestFilter.
+      const bool is_disabled =
+          internal::UnitTestOptions::MatchesFilter(test_case_name,
+                                                   kDisableTestFilter) ||
+          internal::UnitTestOptions::MatchesFilter(test_name,
+                                                   kDisableTestFilter);
+      test_info->is_disabled_ = is_disabled;
+
+      const bool matches_filter =
+          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+                                                       test_name);
+      test_info->matches_filter_ = matches_filter;
+
+      const bool is_runnable =
+          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+          matches_filter;
+
+      const bool is_selected = is_runnable &&
+          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
+           ShouldRunTestOnShard(total_shards, shard_index,
+                                num_runnable_tests));
+
+      num_runnable_tests += is_runnable;
+      num_selected_tests += is_selected;
+
+      test_info->should_run_ = is_selected;
+      test_case->set_should_run(test_case->should_run() || is_selected);
+    }
+  }
+  return num_selected_tests;
+}
+
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    const TestCase* const test_case = test_cases_[i];
+    bool printed_test_case_name = false;
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      const TestInfo* const test_info =
+          test_case->test_info_list()[j];
+      if (test_info->matches_filter_) {
+        if (!printed_test_case_name) {
+          printed_test_case_name = true;
+          printf("%s.\n", test_case->name());
+        }
+        printf("  %s\n", test_info->name());
+      }
+    }
+  }
+  fflush(stdout);
+}
+
+// Sets the OS stack trace getter.
+//
+// Does nothing if the input and the current OS stack trace getter are
+// the same; otherwise, deletes the old getter and makes the input the
+// current getter.
+void UnitTestImpl::set_os_stack_trace_getter(
+    OsStackTraceGetterInterface* getter) {
+  if (os_stack_trace_getter_ != getter) {
+    delete os_stack_trace_getter_;
+    os_stack_trace_getter_ = getter;
+  }
+}
+
+// Returns the current OS stack trace getter if it is not NULL;
+// otherwise, creates an OsStackTraceGetter, makes it the current
+// getter, and returns it.
+OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
+  if (os_stack_trace_getter_ == NULL) {
+    os_stack_trace_getter_ = new OsStackTraceGetter;
+  }
+
+  return os_stack_trace_getter_;
+}
+
+// Returns the TestResult for the test that's currently running, or
+// the TestResult for the ad hoc test if no test is running.
+TestResult* UnitTestImpl::current_test_result() {
+  return current_test_info_ ?
+      &(current_test_info_->result_) : &ad_hoc_test_result_;
+}
+
+// Shuffles all test cases, and the tests within each test case,
+// making sure that death tests are still run first.
+void UnitTestImpl::ShuffleTests() {
+  // Shuffles the death test cases.
+  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+
+  // Shuffles the non-death test cases.
+  ShuffleRange(random(), last_death_test_case_ + 1,
+               static_cast<int>(test_cases_.size()), &test_case_indices_);
+
+  // Shuffles the tests inside each test case.
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    test_cases_[i]->ShuffleTests(random());
+  }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    // Unshuffles the tests in each test case.
+    test_cases_[i]->UnshuffleTests();
+    // Resets the index of each test case.
+    test_case_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+                                       int skip_count) {
+  // We pass skip_count + 1 to skip this wrapper function in addition
+  // to what the user really wants to skip.
+  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
+}
+
+// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to
+// suppress unreachable code warnings.
+namespace {
+class ClassUniqueToAlwaysTrue {};
+}
+
+bool IsTrue(bool condition) { return condition; }
+
+bool AlwaysTrue() {
+#if GTEST_HAS_EXCEPTIONS
+  // This condition is always false so AlwaysTrue() never actually throws,
+  // but it makes the compiler think that it may throw.
+  if (IsTrue(false))
+    throw ClassUniqueToAlwaysTrue();
+#endif  // GTEST_HAS_EXCEPTIONS
+  return true;
+}
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+  const size_t prefix_len = strlen(prefix);
+  if (strncmp(*pstr, prefix, prefix_len) == 0) {
+    *pstr += prefix_len;
+    return true;
+  }
+  return false;
+}
+
+// Parses a string as a command line flag.  The string should have
+// the format "--flag=value".  When def_optional is true, the "=value"
+// part can be omitted.
+//
+// Returns the value of the flag, or NULL if the parsing failed.
+const char* ParseFlagValue(const char* str,
+                           const char* flag,
+                           bool def_optional) {
+  // str and flag must not be NULL.
+  if (str == NULL || flag == NULL) return NULL;
+
+  // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
+  const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag);
+  const size_t flag_len = flag_str.length();
+  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+
+  // Skips the flag name.
+  const char* flag_end = str + flag_len;
+
+  // When def_optional is true, it's OK to not have a "=value" part.
+  if (def_optional && (flag_end[0] == '\0')) {
+    return flag_end;
+  }
+
+  // If def_optional is true and there are more characters after the
+  // flag name, or if def_optional is false, there must be a '=' after
+  // the flag name.
+  if (flag_end[0] != '=') return NULL;
+
+  // Returns the string after "=".
+  return flag_end + 1;
+}
+
+// Parses a string for a bool flag, in the form of either
+// "--flag=value" or "--flag".
+//
+// In the former case, the value is taken as true as long as it does
+// not start with '0', 'f', or 'F'.
+//
+// In the latter case, the value is taken as true.
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Converts the string value to a bool.
+  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
+  return true;
+}
+
+// Parses a string for an Int32 flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  return ParseInt32(Message() << "The value of flag --" << flag,
+                    value_str, value);
+}
+
+// Parses a string for a string flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseStringFlag(const char* str, const char* flag, String* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  *value = value_str;
+  return true;
+}
+
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+  return (SkipPrefix("--", &str) ||
+          SkipPrefix("-", &str) ||
+          SkipPrefix("/", &str)) &&
+         !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
+// Prints a string containing code-encoded text.  The following escape
+// sequences can be used in the string to control the text color:
+//
+//   @@    prints a single '@' character.
+//   @R    changes the color to red.
+//   @G    changes the color to green.
+//   @Y    changes the color to yellow.
+//   @D    changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+  GTestColor color = COLOR_DEFAULT;  // The current color.
+
+  // Conceptually, we split the string into segments divided by escape
+  // sequences.  Then we print one segment at a time.  At the end of
+  // each iteration, the str pointer advances to the beginning of the
+  // next segment.
+  for (;;) {
+    const char* p = strchr(str, '@');
+    if (p == NULL) {
+      ColoredPrintf(color, "%s", str);
+      return;
+    }
+
+    ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+    const char ch = p[1];
+    str = p + 2;
+    if (ch == '@') {
+      ColoredPrintf(color, "@");
+    } else if (ch == 'D') {
+      color = COLOR_DEFAULT;
+    } else if (ch == 'R') {
+      color = COLOR_RED;
+    } else if (ch == 'G') {
+      color = COLOR_GREEN;
+    } else if (ch == 'Y') {
+      color = COLOR_YELLOW;
+    } else {
+      --str;
+    }
+  }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+"      List the names of all tests instead of running them. The name of\n"
+"      TEST(Foo, Bar) is \"Foo.Bar\".\n"
+"  @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+    "[@G-@YNEGATIVE_PATTERNS]@D\n"
+"      Run only the tests whose name matches one of the positive patterns but\n"
+"      none of the negative patterns. '?' matches any single character; '*'\n"
+"      matches any substring; ':' separates two patterns.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+"      Run all disabled tests too.\n"
+"\n"
+"Test Execution:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+"      Run the tests repeatedly; use a negative count to repeat forever.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+"      Randomize tests' orders on every iteration.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
+"      Random number seed to use for shuffling test orders (between 1 and\n"
+"      99999, or 0 to use a seed based on the current time).\n"
+"\n"
+"Test Output:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+"      Enable/disable colored output. The default is @Gauto@D.\n"
+"  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+"      Don't print the elapsed time of each test.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+    GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+"      Generate an XML report in the given directory or with the given file\n"
+"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+#if GTEST_CAN_STREAM_RESULTS_
+"  @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
+"      Stream test results to the given server.\n"
+#endif  // GTEST_CAN_STREAM_RESULTS_
+"\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
+"      Set the default death test style.\n"
+#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+"      Turn assertion failures into debugger break-points.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+"      Turn assertion failures into C++ exceptions.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
+"      Do not report exceptions as test failures. Instead, allow them\n"
+"      to crash the program or throw a pop-up (on Windows).\n"
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+    "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+    "color=no@D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.  The type parameter CharType can be
+// instantiated to either char or wchar_t.
+template <typename CharType>
+void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
+  for (int i = 1; i < *argc; i++) {
+    const String arg_string = StreamableToString(argv[i]);
+    const char* const arg = arg_string.c_str();
+
+    using internal::ParseBoolFlag;
+    using internal::ParseInt32Flag;
+    using internal::ParseStringFlag;
+
+    // Do we see a Google Test flag?
+    if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
+                      &GTEST_FLAG(also_run_disabled_tests)) ||
+        ParseBoolFlag(arg, kBreakOnFailureFlag,
+                      &GTEST_FLAG(break_on_failure)) ||
+        ParseBoolFlag(arg, kCatchExceptionsFlag,
+                      &GTEST_FLAG(catch_exceptions)) ||
+        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
+        ParseStringFlag(arg, kDeathTestStyleFlag,
+                        &GTEST_FLAG(death_test_style)) ||
+        ParseBoolFlag(arg, kDeathTestUseFork,
+                      &GTEST_FLAG(death_test_use_fork)) ||
+        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
+        ParseStringFlag(arg, kInternalRunDeathTestFlag,
+                        &GTEST_FLAG(internal_run_death_test)) ||
+        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
+        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
+        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
+        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
+        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+        ParseInt32Flag(arg, kStackTraceDepthFlag,
+                       &GTEST_FLAG(stack_trace_depth)) ||
+        ParseStringFlag(arg, kStreamResultToFlag,
+                        &GTEST_FLAG(stream_result_to)) ||
+        ParseBoolFlag(arg, kThrowOnFailureFlag,
+                      &GTEST_FLAG(throw_on_failure))
+        ) {
+      // Yes.  Shift the remainder of the argv list left by one.  Note
+      // that argv has (*argc + 1) elements, the last one always being
+      // NULL.  The following loop moves the trailing NULL element as
+      // well.
+      for (int j = i; j != *argc; j++) {
+        argv[j] = argv[j + 1];
+      }
+
+      // Decrements the argument count.
+      (*argc)--;
+
+      // We also need to decrement the iterator as we just removed
+      // an element.
+      i--;
+    } else if (arg_string == "--help" || arg_string == "-h" ||
+               arg_string == "-?" || arg_string == "/?" ||
+               HasGoogleTestFlagPrefix(arg)) {
+      // Both help flag and unrecognized Google Test flags (excluding
+      // internal ones) trigger help display.
+      g_help_flag = true;
+    }
+  }
+
+  if (g_help_flag) {
+    // We print the help here instead of in RUN_ALL_TESTS(), as the
+    // latter may not be called at all if the user is using Google
+    // Test with another testing framework.
+    PrintColorEncoded(kColorEncodedHelpMessage);
+  }
+}
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+
+// The internal implementation of InitGoogleTest().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleTestImpl(int* argc, CharType** argv) {
+  g_init_gtest_count++;
+
+  // We don't want to run the initialization code twice.
+  if (g_init_gtest_count != 1) return;
+
+  if (*argc <= 0) return;
+
+  internal::g_executable_path = internal::StreamableToString(argv[0]);
+
+#if GTEST_HAS_DEATH_TEST
+
+  g_argvs.clear();
+  for (int i = 0; i != *argc; i++) {
+    g_argvs.push_back(StreamableToString(argv[i]));
+  }
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+  ParseGoogleTestFlagsOnly(argc, argv);
+  GetUnitTestImpl()->PostFlagParsingInit();
+}
+
+}  // namespace internal
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it parses a command line for the
+// flags that Google Test recognizes.  Whenever a Google Test flag is
+// seen, it is removed from argv, and *argc is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+//
+// Calling the function for the second time has no user-visible effect.
+void InitGoogleTest(int* argc, char** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleTest(int* argc, wchar_t** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+}  // namespace testing
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
+//
+// This file implements death tests.
+
+
+#if GTEST_HAS_DEATH_TEST
+
+# if GTEST_OS_MAC
+#  include <crt_externs.h>
+# endif  // GTEST_OS_MAC
+
+# include <errno.h>
+# include <fcntl.h>
+# include <limits.h>
+# include <stdarg.h>
+
+# if GTEST_OS_WINDOWS
+#  include <windows.h>
+# else
+#  include <sys/mman.h>
+#  include <sys/wait.h>
+# endif  // GTEST_OS_WINDOWS
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+// Constants.
+
+// The default death test style.
+static const char kDefaultDeathTestStyle[] = "fast";
+
+GTEST_DEFINE_string_(
+    death_test_style,
+    internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
+    "Indicates how to run a death test in a forked child process: "
+    "\"threadsafe\" (child process re-executes the test binary "
+    "from the beginning, running only the specific death test) or "
+    "\"fast\" (child process runs the death test immediately "
+    "after forking).");
+
+GTEST_DEFINE_bool_(
+    death_test_use_fork,
+    internal::BoolFromGTestEnv("death_test_use_fork", false),
+    "Instructs to use fork()/_exit() instead of clone() in death tests. "
+    "Ignored and always uses fork() on POSIX systems where clone() is not "
+    "implemented. Useful when running under valgrind or similar tools if "
+    "those do not support clone(). Valgrind 3.3.1 will just fail if "
+    "it sees an unsupported combination of clone() flags. "
+    "It is not recommended to use this flag w/o valgrind though it will "
+    "work in 99% of the cases. Once valgrind is fixed, this flag will "
+    "most likely be removed.");
+
+namespace internal {
+GTEST_DEFINE_string_(
+    internal_run_death_test, "",
+    "Indicates the file, line number, temporal index of "
+    "the single death test to run, and a file descriptor to "
+    "which a success code may be sent, all separated by "
+    "colons.  This flag is specified if and only if the current "
+    "process is a sub-process launched for running a thread-safe "
+    "death test.  FOR INTERNAL USE ONLY.");
+}  // namespace internal
+
+#if GTEST_HAS_DEATH_TEST
+
+// ExitedWithCode constructor.
+ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
+}
+
+// ExitedWithCode function-call operator.
+bool ExitedWithCode::operator()(int exit_status) const {
+# if GTEST_OS_WINDOWS
+
+  return exit_status == exit_code_;
+
+# else
+
+  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+
+# endif  // GTEST_OS_WINDOWS
+}
+
+# if !GTEST_OS_WINDOWS
+// KilledBySignal constructor.
+KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
+}
+
+// KilledBySignal function-call operator.
+bool KilledBySignal::operator()(int exit_status) const {
+  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
+}
+# endif  // !GTEST_OS_WINDOWS
+
+namespace internal {
+
+// Utilities needed for death tests.
+
+// Generates a textual description of a given exit code, in the format
+// specified by wait(2).
+static String ExitSummary(int exit_code) {
+  Message m;
+
+# if GTEST_OS_WINDOWS
+
+  m << "Exited with exit status " << exit_code;
+
+# else
+
+  if (WIFEXITED(exit_code)) {
+    m << "Exited with exit status " << WEXITSTATUS(exit_code);
+  } else if (WIFSIGNALED(exit_code)) {
+    m << "Terminated by signal " << WTERMSIG(exit_code);
+  }
+#  ifdef WCOREDUMP
+  if (WCOREDUMP(exit_code)) {
+    m << " (core dumped)";
+  }
+#  endif
+# endif  // GTEST_OS_WINDOWS
+
+  return m.GetString();
+}
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+bool ExitedUnsuccessfully(int exit_status) {
+  return !ExitedWithCode(0)(exit_status);
+}
+
+# if !GTEST_OS_WINDOWS
+// Generates a textual failure message when a death test finds more than
+// one thread running, or cannot determine the number of threads, prior
+// to executing the given statement.  It is the responsibility of the
+// caller not to pass a thread_count of 1.
+static String DeathTestThreadWarning(size_t thread_count) {
+  Message msg;
+  msg << "Death tests use fork(), which is unsafe particularly"
+      << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
+  if (thread_count == 0)
+    msg << "couldn't detect the number of threads.";
+  else
+    msg << "detected " << thread_count << " threads.";
+  return msg.GetString();
+}
+# endif  // !GTEST_OS_WINDOWS
+
+// Flag characters for reporting a death test that did not die.
+static const char kDeathTestLived = 'L';
+static const char kDeathTestReturned = 'R';
+static const char kDeathTestThrew = 'T';
+static const char kDeathTestInternalError = 'I';
+
+// An enumeration describing all of the possible ways that a death test can
+// conclude.  DIED means that the process died while executing the test
+// code; LIVED means that process lived beyond the end of the test code;
+// RETURNED means that the test statement attempted to execute a return
+// statement, which is not allowed; THREW means that the test statement
+// returned control by throwing an exception.  IN_PROGRESS means the test
+// has not yet concluded.
+// TODO(vladl@google.com): Unify names and possibly values for
+// AbortReason, DeathTestOutcome, and flag characters above.
+enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
+
+// Routine for aborting the program which is safe to call from an
+// exec-style death test child process, in which case the error
+// message is propagated back to the parent process.  Otherwise, the
+// message is simply printed to stderr.  In either case, the program
+// then exits with status 1.
+void DeathTestAbort(const String& message) {
+  // On a POSIX system, this function may be called from a threadsafe-style
+  // death test child process, which operates on a very small stack.  Use
+  // the heap for any additional non-minuscule memory requirements.
+  const InternalRunDeathTestFlag* const flag =
+      GetUnitTestImpl()->internal_run_death_test_flag();
+  if (flag != NULL) {
+    FILE* parent = posix::FDOpen(flag->write_fd(), "w");
+    fputc(kDeathTestInternalError, parent);
+    fprintf(parent, "%s", message.c_str());
+    fflush(parent);
+    _exit(1);
+  } else {
+    fprintf(stderr, "%s", message.c_str());
+    fflush(stderr);
+    posix::Abort();
+  }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+# define GTEST_DEATH_TEST_CHECK_(expression) \
+  do { \
+    if (!::testing::internal::IsTrue(expression)) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
+// evaluating any system call that fulfills two conditions: it must return
+// -1 on failure, and set errno to EINTR when it is interrupted and
+// should be tried again.  The macro expands to a loop that repeatedly
+// evaluates the expression as long as it evaluates to -1 and sets
+// errno to EINTR.  If the expression evaluates to -1 but errno is
+// something other than EINTR, DeathTestAbort is called.
+# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \
+  do { \
+    int gtest_retval; \
+    do { \
+      gtest_retval = (expression); \
+    } while (gtest_retval == -1 && errno == EINTR); \
+    if (gtest_retval == -1) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s != -1", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+    return String(errno == 0 ? "" : posix::StrError(errno));
+}
+
+// This is called from a death test parent process to read a failure
+// message from the death test child process and log it with the FATAL
+// severity. On Windows, the message is read from a pipe handle. On other
+// platforms, it is read from a file descriptor.
+static void FailFromInternalError(int fd) {
+  Message error;
+  char buffer[256];
+  int num_read;
+
+  do {
+    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+      buffer[num_read] = '\0';
+      error << buffer;
+    }
+  } while (num_read == -1 && errno == EINTR);
+
+  if (num_read == 0) {
+    GTEST_LOG_(FATAL) << error.GetString();
+  } else {
+    const int last_error = errno;
+    GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+                      << GetLastErrnoDescription() << " [" << last_error << "]";
+  }
+}
+
+// Death test constructor.  Increments the running death test count
+// for the current test.
+DeathTest::DeathTest() {
+  TestInfo* const info = GetUnitTestImpl()->current_test_info();
+  if (info == NULL) {
+    DeathTestAbort("Cannot run a death test outside of a TEST or "
+                   "TEST_F construct");
+  }
+}
+
+// Creates and returns a death test by dispatching to the current
+// death test factory.
+bool DeathTest::Create(const char* statement, const RE* regex,
+                       const char* file, int line, DeathTest** test) {
+  return GetUnitTestImpl()->death_test_factory()->Create(
+      statement, regex, file, line, test);
+}
+
+const char* DeathTest::LastMessage() {
+  return last_death_test_message_.c_str();
+}
+
+void DeathTest::set_last_death_test_message(const String& message) {
+  last_death_test_message_ = message;
+}
+
+String DeathTest::last_death_test_message_;
+
+// Provides cross platform implementation for some death functionality.
+class DeathTestImpl : public DeathTest {
+ protected:
+  DeathTestImpl(const char* a_statement, const RE* a_regex)
+      : statement_(a_statement),
+        regex_(a_regex),
+        spawned_(false),
+        status_(-1),
+        outcome_(IN_PROGRESS),
+        read_fd_(-1),
+        write_fd_(-1) {}
+
+  // read_fd_ is expected to be closed and cleared by a derived class.
+  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+
+  void Abort(AbortReason reason);
+  virtual bool Passed(bool status_ok);
+
+  const char* statement() const { return statement_; }
+  const RE* regex() const { return regex_; }
+  bool spawned() const { return spawned_; }
+  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
+  int status() const { return status_; }
+  void set_status(int a_status) { status_ = a_status; }
+  DeathTestOutcome outcome() const { return outcome_; }
+  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
+  int read_fd() const { return read_fd_; }
+  void set_read_fd(int fd) { read_fd_ = fd; }
+  int write_fd() const { return write_fd_; }
+  void set_write_fd(int fd) { write_fd_ = fd; }
+
+  // Called in the parent process only. Reads the result code of the death
+  // test child process via a pipe, interprets it to set the outcome_
+  // member, and closes read_fd_.  Outputs diagnostics and terminates in
+  // case of unexpected codes.
+  void ReadAndInterpretStatusByte();
+
+ private:
+  // The textual content of the code this object is testing.  This class
+  // doesn't own this string and should not attempt to delete it.
+  const char* const statement_;
+  // The regular expression which test output must match.  DeathTestImpl
+  // doesn't own this object and should not attempt to delete it.
+  const RE* const regex_;
+  // True if the death test child process has been successfully spawned.
+  bool spawned_;
+  // The exit status of the child process.
+  int status_;
+  // How the death test concluded.
+  DeathTestOutcome outcome_;
+  // Descriptor to the read end of the pipe to the child process.  It is
+  // always -1 in the child process.  The child keeps its write end of the
+  // pipe in write_fd_.
+  int read_fd_;
+  // Descriptor to the child's write end of the pipe to the parent process.
+  // It is always -1 in the parent process.  The parent keeps its end of the
+  // pipe in read_fd_.
+  int write_fd_;
+};
+
+// Called in the parent process only. Reads the result code of the death
+// test child process via a pipe, interprets it to set the outcome_
+// member, and closes read_fd_.  Outputs diagnostics and terminates in
+// case of unexpected codes.
+void DeathTestImpl::ReadAndInterpretStatusByte() {
+  char flag;
+  int bytes_read;
+
+  // The read() here blocks until data is available (signifying the
+  // failure of the death test) or until the pipe is closed (signifying
+  // its success), so it's okay to call this in the parent before
+  // the child process has exited.
+  do {
+    bytes_read = posix::Read(read_fd(), &flag, 1);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    set_outcome(DIED);
+  } else if (bytes_read == 1) {
+    switch (flag) {
+      case kDeathTestReturned:
+        set_outcome(RETURNED);
+        break;
+      case kDeathTestThrew:
+        set_outcome(THREW);
+        break;
+      case kDeathTestLived:
+        set_outcome(LIVED);
+        break;
+      case kDeathTestInternalError:
+        FailFromInternalError(read_fd());  // Does not return.
+        break;
+      default:
+        GTEST_LOG_(FATAL) << "Death test child process reported "
+                          << "unexpected status byte ("
+                          << static_cast<unsigned int>(flag) << ")";
+    }
+  } else {
+    GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+                      << GetLastErrnoDescription();
+  }
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+  set_read_fd(-1);
+}
+
+// Signals that the death test code which should have exited, didn't.
+// Should be called only in a death test child process.
+// Writes a status byte to the child's status file descriptor, then
+// calls _exit(1).
+void DeathTestImpl::Abort(AbortReason reason) {
+  // The parent process considers the death test to be a failure if
+  // it finds any data in our pipe.  So, here we write a single flag byte
+  // to the pipe, then exit.
+  const char status_ch =
+      reason == TEST_DID_NOT_DIE ? kDeathTestLived :
+      reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned;
+
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
+  // We are leaking the descriptor here because on some platforms (i.e.,
+  // when built as Windows DLL), destructors of global objects will still
+  // run after calling _exit(). On such systems, write_fd_ will be
+  // indirectly closed from the destructor of UnitTestImpl, causing double
+  // close if it is also closed here. On debug configurations, double close
+  // may assert. As there are no in-process buffers to flush here, we are
+  // relying on the OS to close the descriptor after the process terminates
+  // when the destructors are not run.
+  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// Returns an indented copy of stderr output for a death test.
+// This makes distinguishing death test output lines from regular log lines
+// much easier.
+static ::std::string FormatDeathTestOutput(const ::std::string& output) {
+  ::std::string ret;
+  for (size_t at = 0; ; ) {
+    const size_t line_end = output.find('\n', at);
+    ret += "[  DEATH   ] ";
+    if (line_end == ::std::string::npos) {
+      ret += output.substr(at);
+      break;
+    }
+    ret += output.substr(at, line_end + 1 - at);
+    at = line_end + 1;
+  }
+  return ret;
+}
+
+// Assesses the success or failure of a death test, using both private
+// members which have previously been set, and one argument:
+//
+// Private data members:
+//   outcome:  An enumeration describing how the death test
+//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test
+//             fails in the latter three cases.
+//   status:   The exit status of the child process. On *nix, it is in the
+//             in the format specified by wait(2). On Windows, this is the
+//             value supplied to the ExitProcess() API or a numeric code
+//             of the exception that terminated the program.
+//   regex:    A regular expression object to be applied to
+//             the test's captured standard error output; the death test
+//             fails if it does not match.
+//
+// Argument:
+//   status_ok: true if exit_status is acceptable in the context of
+//              this particular death test, which fails if it is false
+//
+// Returns true iff all of the above conditions are met.  Otherwise, the
+// first failing condition, in the order given above, is the one that is
+// reported. Also sets the last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+  if (!spawned())
+    return false;
+
+  const String error_message = GetCapturedStderr();
+
+  bool success = false;
+  Message buffer;
+
+  buffer << "Death test: " << statement() << "\n";
+  switch (outcome()) {
+    case LIVED:
+      buffer << "    Result: failed to die.\n"
+             << " Error msg:\n" << FormatDeathTestOutput(error_message);
+      break;
+    case THREW:
+      buffer << "    Result: threw an exception.\n"
+             << " Error msg:\n" << FormatDeathTestOutput(error_message);
+      break;
+    case RETURNED:
+      buffer << "    Result: illegal return in test statement.\n"
+             << " Error msg:\n" << FormatDeathTestOutput(error_message);
+      break;
+    case DIED:
+      if (status_ok) {
+        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+        if (matched) {
+          success = true;
+        } else {
+          buffer << "    Result: died but not with expected error.\n"
+                 << "  Expected: " << regex()->pattern() << "\n"
+                 << "Actual msg:\n" << FormatDeathTestOutput(error_message);
+        }
+      } else {
+        buffer << "    Result: died but not with expected exit code:\n"
+               << "            " << ExitSummary(status()) << "\n"
+               << "Actual msg:\n" << FormatDeathTestOutput(error_message);
+      }
+      break;
+    case IN_PROGRESS:
+    default:
+      GTEST_LOG_(FATAL)
+          << "DeathTest::Passed somehow called before conclusion of test";
+  }
+
+  DeathTest::set_last_death_test_message(buffer.GetString());
+  return success;
+}
+
+# if GTEST_OS_WINDOWS
+// WindowsDeathTest implements death tests on Windows. Due to the
+// specifics of starting new processes on Windows, death tests there are
+// always threadsafe, and Google Test considers the
+// --gtest_death_test_style=fast setting to be equivalent to
+// --gtest_death_test_style=threadsafe there.
+//
+// A few implementation notes:  Like the Linux version, the Windows
+// implementation uses pipes for child-to-parent communication. But due to
+// the specifics of pipes on Windows, some extra steps are required:
+//
+// 1. The parent creates a communication pipe and stores handles to both
+//    ends of it.
+// 2. The parent starts the child and provides it with the information
+//    necessary to acquire the handle to the write end of the pipe.
+// 3. The child acquires the write end of the pipe and signals the parent
+//    using a Windows event.
+// 4. Now the parent can release the write end of the pipe on its side. If
+//    this is done before step 3, the object's reference count goes down to
+//    0 and it is destroyed, preventing the child from acquiring it. The
+//    parent now has to release it, or read operations on the read end of
+//    the pipe will not return when the child terminates.
+// 5. The parent reads child's output through the pipe (outcome code and
+//    any possible error messages) from the pipe, and its stderr and then
+//    determines whether to fail the test.
+//
+// Note: to distinguish Win32 API calls from the local method and function
+// calls, the former are explicitly resolved in the global namespace.
+//
+class WindowsDeathTest : public DeathTestImpl {
+ public:
+  WindowsDeathTest(const char* a_statement,
+                   const RE* a_regex,
+                   const char* file,
+                   int line)
+      : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+  virtual TestRole AssumeRole();
+
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+  // Handle to the write end of the pipe to the child process.
+  AutoHandle write_handle_;
+  // Child process handle.
+  AutoHandle child_handle_;
+  // Event the child process uses to signal the parent that it has
+  // acquired the handle to the write end of the pipe. After seeing this
+  // event the parent can release its own handles to make sure its
+  // ReadFile() calls return when the child terminates.
+  AutoHandle event_handle_;
+};
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int WindowsDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  // Wait until the child either signals that it has acquired the write end
+  // of the pipe or it dies.
+  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
+  switch (::WaitForMultipleObjects(2,
+                                   wait_handles,
+                                   FALSE,  // Waits for any of the handles.
+                                   INFINITE)) {
+    case WAIT_OBJECT_0:
+    case WAIT_OBJECT_0 + 1:
+      break;
+    default:
+      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.
+  }
+
+  // The child has acquired the write end of the pipe or exited.
+  // We release the handle on our side and continue.
+  write_handle_.Reset();
+  event_handle_.Reset();
+
+  ReadAndInterpretStatusByte();
+
+  // Waits for the child process to exit if it haven't already. This
+  // returns immediately if the child has already exited, regardless of
+  // whether previous calls to WaitForMultipleObjects synchronized on this
+  // handle or not.
+  GTEST_DEATH_TEST_CHECK_(
+      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
+                                             INFINITE));
+  DWORD status_code;
+  GTEST_DEATH_TEST_CHECK_(
+      ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);
+  child_handle_.Reset();
+  set_status(static_cast<int>(status_code));
+  return status();
+}
+
+// The AssumeRole process for a Windows death test.  It creates a child
+// process with the same executable as the current process to run the
+// death test.  The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole WindowsDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != NULL) {
+    // ParseInternalRunDeathTestFlag() has performed all the necessary
+    // processing.
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  // WindowsDeathTest uses an anonymous pipe to communicate results of
+  // a death test.
+  SECURITY_ATTRIBUTES handles_are_inheritable = {
+    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+  HANDLE read_handle, write_handle;
+  GTEST_DEATH_TEST_CHECK_(
+      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+                   0)  // Default buffer size.
+      != FALSE);
+  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
+                                O_RDONLY));
+  write_handle_.Reset(write_handle);
+  event_handle_.Reset(::CreateEvent(
+      &handles_are_inheritable,
+      TRUE,    // The event will automatically reset to non-signaled state.
+      FALSE,   // The initial state is non-signalled.
+      NULL));  // The even is unnamed.
+  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
+  const String filter_flag = String::Format("--%s%s=%s.%s",
+                                            GTEST_FLAG_PREFIX_, kFilterFlag,
+                                            info->test_case_name(),
+                                            info->name());
+  const String internal_flag = String::Format(
+    "--%s%s=%s|%d|%d|%u|%Iu|%Iu",
+      GTEST_FLAG_PREFIX_,
+      kInternalRunDeathTestFlag,
+      file_, line_,
+      death_test_index,
+      static_cast<unsigned int>(::GetCurrentProcessId()),
+      // size_t has the same with as pointers on both 32-bit and 64-bit
+      // Windows platforms.
+      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
+      reinterpret_cast<size_t>(write_handle),
+      reinterpret_cast<size_t>(event_handle_.Get()));
+
+  char executable_path[_MAX_PATH + 1];  // NOLINT
+  GTEST_DEATH_TEST_CHECK_(
+      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
+                                            executable_path,
+                                            _MAX_PATH));
+
+  String command_line = String::Format("%s %s \"%s\"",
+                                       ::GetCommandLineA(),
+                                       filter_flag.c_str(),
+                                       internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // Flush the log buffers since the log streams are shared with the child.
+  FlushInfoLog();
+
+  // The child process will share the standard handles with the parent.
+  STARTUPINFOA startup_info;
+  memset(&startup_info, 0, sizeof(STARTUPINFO));
+  startup_info.dwFlags = STARTF_USESTDHANDLES;
+  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+
+  PROCESS_INFORMATION process_info;
+  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
+      executable_path,
+      const_cast<char*>(command_line.c_str()),
+      NULL,   // Retuned process handle is not inheritable.
+      NULL,   // Retuned thread handle is not inheritable.
+      TRUE,   // Child inherits all inheritable handles (for write_handle_).
+      0x0,    // Default creation flags.
+      NULL,   // Inherit the parent's environment.
+      UnitTest::GetInstance()->original_working_dir(),
+      &startup_info,
+      &process_info) != FALSE);
+  child_handle_.Reset(process_info.hProcess);
+  ::CloseHandle(process_info.hThread);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+# else  // We are not on Windows.
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface.  Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTestImpl {
+ public:
+  ForkingDeathTest(const char* statement, const RE* regex);
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+
+ protected:
+  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+
+ private:
+  // PID of child process during death test; 0 in the child process itself.
+  pid_t child_pid_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+    : DeathTestImpl(a_statement, a_regex),
+      child_pid_(-1) {}
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int ForkingDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  ReadAndInterpretStatusByte();
+
+  int status_value;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+  set_status(status_value);
+  return status_value;
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+      ForkingDeathTest(a_statement, a_regex) { }
+  virtual TestRole AssumeRole();
+};
+
+// The AssumeRole process for a fork-and-run death test.  It implements a
+// straightforward fork, with a simple pipe to transmit the status byte.
+DeathTest::TestRole NoExecDeathTest::AssumeRole() {
+  const size_t thread_count = GetThreadCount();
+  if (thread_count != 1) {
+    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+
+  DeathTest::set_last_death_test_message("");
+  CaptureStderr();
+  // When we fork the process below, the log file buffers are copied, but the
+  // file descriptors are shared.  We flush all log files here so that closing
+  // the file descriptors in the child process doesn't throw off the
+  // synchronization between descriptors and buffers in the parent process.
+  // This is as close to the fork as possible to avoid a race condition in case
+  // there are multiple threads running before the death test, and another
+  // thread writes to the log file.
+  FlushInfoLog();
+
+  const pid_t child_pid = fork();
+  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+  set_child_pid(child_pid);
+  if (child_pid == 0) {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));
+    set_write_fd(pipe_fd[1]);
+    // Redirects all logging to stderr in the child process to prevent
+    // concurrent writes to the log files.  We capture stderr in the parent
+    // process and append the child process' output to a log.
+    LogToStderr();
+    // Event forwarding to the listeners of event listener API mush be shut
+    // down in death test subprocesses.
+    GetUnitTestImpl()->listeners()->SuppressEventForwarding();
+    return EXECUTE_TEST;
+  } else {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+    set_read_fd(pipe_fd[0]);
+    set_spawned(true);
+    return OVERSEE_TEST;
+  }
+}
+
+// A concrete death test class that forks and re-executes the main
+// program from the beginning, with command-line flags set that cause
+// only this specific death test to be run.
+class ExecDeathTest : public ForkingDeathTest {
+ public:
+  ExecDeathTest(const char* a_statement, const RE* a_regex,
+                const char* file, int line) :
+      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
+  virtual TestRole AssumeRole();
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+  Arguments() {
+    args_.push_back(NULL);
+  }
+
+  ~Arguments() {
+    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, posix::StrDup(argument));
+  }
+
+  template <typename Str>
+  void AddArguments(const ::std::vector<Str>& arguments) {
+    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+         i != arguments.end();
+         ++i) {
+      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
+    }
+  }
+  char* const* Argv() {
+    return &args_[0];
+  }
+ private:
+  std::vector<char*> args_;
+};
+
+// A struct that encompasses the arguments to the child process of a
+// threadsafe-style death test process.
+struct ExecDeathTestArgs {
+  char* const* argv;  // Command-line arguments for the child's call to exec
+  int close_fd;       // File descriptor to close; the read end of a pipe
+};
+
+#  if GTEST_OS_MAC
+inline char** GetEnviron() {
+  // When Google Test is built as a framework on MacOS X, the environ variable
+  // is unavailable. Apple's documentation (man environ) recommends using
+  // _NSGetEnviron() instead.
+  return *_NSGetEnviron();
+}
+#  else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#  endif  // GTEST_OS_MAC
+
+// The main function for a threadsafe-style death test child process.
+// This function is called in a clone()-ed process and thus must avoid
+// any potentially unsafe operations like malloc or libc functions.
+static int ExecDeathTestChildMain(void* child_arg) {
+  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
+
+  // We need to execute the test program in the same environment where
+  // it was originally invoked.  Therefore we change to the original
+  // working directory first.
+  const char* const original_dir =
+      UnitTest::GetInstance()->original_working_dir();
+  // We can safely call chdir() as it's a direct system call.
+  if (chdir(original_dir) != 0) {
+    DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
+                                  original_dir,
+                                  GetLastErrnoDescription().c_str()));
+    return EXIT_FAILURE;
+  }
+
+  // We can safely call execve() as it's a direct system call.  We
+  // cannot use execvp() as it's a libc function and thus potentially
+  // unsafe.  Since execve() doesn't search the PATH, the user must
+  // invoke the test program via a valid path that contains at least
+  // one path separator.
+  execve(args->argv[0], args->argv, GetEnviron());
+  DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
+                                args->argv[0],
+                                original_dir,
+                                GetLastErrnoDescription().c_str()));
+  return EXIT_FAILURE;
+}
+
+// Two utility routines that together determine the direction the stack
+// grows.
+// This could be accomplished more elegantly by a single recursive
+// function, but we want to guard against the unlikely possibility of
+// a smart compiler optimizing the recursion away.
+//
+// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
+// StackLowerThanAddress into StackGrowsDown, which then doesn't give
+// correct answer.
+bool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_;
+bool StackLowerThanAddress(const void* ptr) {
+  int dummy;
+  return &dummy < ptr;
+}
+
+bool StackGrowsDown() {
+  int dummy;
+  return StackLowerThanAddress(&dummy);
+}
+
+// A threadsafe implementation of fork(2) for threadsafe-style death tests
+// that uses clone(2).  It dies with an error message if anything goes
+// wrong.
+static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
+  ExecDeathTestArgs args = { argv, close_fd };
+  pid_t child_pid = -1;
+
+#  if GTEST_HAS_CLONE
+  const bool use_fork = GTEST_FLAG(death_test_use_fork);
+
+  if (!use_fork) {
+    static const bool stack_grows_down = StackGrowsDown();
+    const size_t stack_size = getpagesize();
+    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
+    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+                             MAP_ANON | MAP_PRIVATE, -1, 0);
+    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
+    void* const stack_top =
+        static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);
+
+    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
+
+    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
+  }
+#  else
+  const bool use_fork = true;
+#  endif  // GTEST_HAS_CLONE
+
+  if (use_fork && (child_pid = fork()) == 0) {
+      ExecDeathTestChildMain(&args);
+      _exit(0);
+  }
+
+  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
+  return child_pid;
+}
+
+// The AssumeRole process for a fork-and-exec death test.  It re-executes the
+// main program from the beginning, setting the --gtest_filter
+// and --gtest_internal_run_death_test flags to cause only the current
+// death test to be re-run.
+DeathTest::TestRole ExecDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != NULL) {
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);
+  // Clear the close-on-exec flag on the write end of the pipe, lest
+  // it be closed when the child process does an exec:
+  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
+
+  const String filter_flag =
+      String::Format("--%s%s=%s.%s",
+                     GTEST_FLAG_PREFIX_, kFilterFlag,
+                     info->test_case_name(), info->name());
+  const String internal_flag =
+      String::Format("--%s%s=%s|%d|%d|%d",
+                     GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,
+                     file_, line_, death_test_index, pipe_fd[1]);
+  Arguments args;
+  args.AddArguments(GetArgvs());
+  args.AddArgument(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // See the comment in NoExecDeathTest::AssumeRole for why the next line
+  // is necessary.
+  FlushInfoLog();
+
+  const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+  set_child_pid(child_pid);
+  set_read_fd(pipe_fd[0]);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+
+# endif  // !GTEST_OS_WINDOWS
+
+// Creates a concrete DeathTest-derived class that depends on the
+// --gtest_death_test_style flag, and sets the pointer pointed to
+// by the "test" argument to its address.  If the test should be
+// skipped, sets that pointer to NULL.  Returns true, unless the
+// flag is set to an invalid value.
+bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+                                     const char* file, int line,
+                                     DeathTest** test) {
+  UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const int death_test_index = impl->current_test_info()
+      ->increment_death_test_count();
+
+  if (flag != NULL) {
+    if (death_test_index > flag->index()) {
+      DeathTest::set_last_death_test_message(String::Format(
+          "Death test count (%d) somehow exceeded expected maximum (%d)",
+          death_test_index, flag->index()));
+      return false;
+    }
+
+    if (!(flag->file() == file && flag->line() == line &&
+          flag->index() == death_test_index)) {
+      *test = NULL;
+      return true;
+    }
+  }
+
+# if GTEST_OS_WINDOWS
+
+  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+      GTEST_FLAG(death_test_style) == "fast") {
+    *test = new WindowsDeathTest(statement, regex, file, line);
+  }
+
+# else
+
+  if (GTEST_FLAG(death_test_style) == "threadsafe") {
+    *test = new ExecDeathTest(statement, regex, file, line);
+  } else if (GTEST_FLAG(death_test_style) == "fast") {
+    *test = new NoExecDeathTest(statement, regex);
+  }
+
+# endif  // GTEST_OS_WINDOWS
+
+  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.
+    DeathTest::set_last_death_test_message(String::Format(
+        "Unknown death test style \"%s\" encountered",
+        GTEST_FLAG(death_test_style).c_str()));
+    return false;
+  }
+
+  return true;
+}
+
+// Splits a given string on a given delimiter, populating a given
+// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have
+// ::std::string, so we can use it here.
+static void SplitString(const ::std::string& str, char delimiter,
+                        ::std::vector< ::std::string>* dest) {
+  ::std::vector< ::std::string> parsed;
+  ::std::string::size_type pos = 0;
+  while (::testing::internal::AlwaysTrue()) {
+    const ::std::string::size_type colon = str.find(delimiter, pos);
+    if (colon == ::std::string::npos) {
+      parsed.push_back(str.substr(pos));
+      break;
+    } else {
+      parsed.push_back(str.substr(pos, colon - pos));
+      pos = colon + 1;
+    }
+  }
+  dest->swap(parsed);
+}
+
+# if GTEST_OS_WINDOWS
+// Recreates the pipe and event handles from the provided parameters,
+// signals the event, and returns a file descriptor wrapped around the pipe
+// handle. This function is called in the child process only.
+int GetStatusFileDescriptor(unsigned int parent_process_id,
+                            size_t write_handle_as_size_t,
+                            size_t event_handle_as_size_t) {
+  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
+                                                   FALSE,  // Non-inheritable.
+                                                   parent_process_id));
+  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
+    DeathTestAbort(String::Format("Unable to open parent process %u",
+                                  parent_process_id));
+  }
+
+  // TODO(vladl@google.com): Replace the following check with a
+  // compile-time assertion when available.
+  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
+
+  const HANDLE write_handle =
+      reinterpret_cast<HANDLE>(write_handle_as_size_t);
+  HANDLE dup_write_handle;
+
+  // The newly initialized handle is accessible only in in the parent
+  // process. To obtain one accessible within the child, we need to use
+  // DuplicateHandle.
+  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
+                         ::GetCurrentProcess(), &dup_write_handle,
+                         0x0,    // Requested privileges ignored since
+                                 // DUPLICATE_SAME_ACCESS is used.
+                         FALSE,  // Request non-inheritable handler.
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the pipe handle %Iu from the parent process %u",
+        write_handle_as_size_t, parent_process_id));
+  }
+
+  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
+  HANDLE dup_event_handle;
+
+  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
+                         ::GetCurrentProcess(), &dup_event_handle,
+                         0x0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the event handle %Iu from the parent process %u",
+        event_handle_as_size_t, parent_process_id));
+  }
+
+  const int write_fd =
+      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
+  if (write_fd == -1) {
+    DeathTestAbort(String::Format(
+        "Unable to convert pipe handle %Iu to a file descriptor",
+        write_handle_as_size_t));
+  }
+
+  // Signals the parent that the write end of the pipe has been acquired
+  // so the parent can release its own write end.
+  ::SetEvent(dup_event_handle);
+
+  return write_fd;
+}
+# endif  // GTEST_OS_WINDOWS
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
+  if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  int line = -1;
+  int index = -1;
+  ::std::vector< ::std::string> fields;
+  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
+  int write_fd = -1;
+
+# if GTEST_OS_WINDOWS
+
+  unsigned int parent_process_id = 0;
+  size_t write_handle_as_size_t = 0;
+  size_t event_handle_as_size_t = 0;
+
+  if (fields.size() != 6
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &parent_process_id)
+      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
+      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+  write_fd = GetStatusFileDescriptor(parent_process_id,
+                                     write_handle_as_size_t,
+                                     event_handle_as_size_t);
+# else
+
+  if (fields.size() != 4
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &write_fd)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+
+# endif  // GTEST_OS_WINDOWS
+
+  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
+}
+
+}  // namespace internal
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: keith.ray@gmail.com (Keith Ray)
+
+
+#include <stdlib.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+# include <windows.h>
+#elif GTEST_OS_WINDOWS
+# include <direct.h>
+# include <io.h>
+#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL
+// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h
+# include <sys/syslimits.h>
+#else
+# include <limits.h>
+# include <climits>  // Some Linux distributions define PATH_MAX here.
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_WINDOWS
+# define GTEST_PATH_MAX_ _MAX_PATH
+#elif defined(PATH_MAX)
+# define GTEST_PATH_MAX_ PATH_MAX
+#elif defined(_XOPEN_PATH_MAX)
+# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
+#else
+# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
+#endif  // GTEST_OS_WINDOWS
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
+const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
+const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
+# if GTEST_OS_WINDOWS_MOBILE
+// Windows CE doesn't have a current directory. You should not use
+// the current directory in tests on Windows CE, but this at least
+// provides a reasonable fallback.
+const char kCurrentDirectoryString[] = "\\";
+// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
+const DWORD kInvalidFileAttributes = 0xffffffff;
+# else
+const char kCurrentDirectoryString[] = ".\\";
+# endif  // GTEST_OS_WINDOWS_MOBILE
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif  // GTEST_OS_WINDOWS
+
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+  return c == kPathSeparator;
+#endif
+}
+
+// Returns the current working directory, or "" if unsuccessful.
+FilePath FilePath::GetCurrentDir() {
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE doesn't have a current directory, so we just return
+  // something reasonable.
+  return FilePath(kCurrentDirectoryString);
+#elif GTEST_OS_WINDOWS
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#else
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns a copy of the FilePath with the case-insensitive extension removed.
+// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+// FilePath("dir/file"). If a case-insensitive extension is not
+// found, returns a copy of the original FilePath.
+FilePath FilePath::RemoveExtension(const char* extension) const {
+  String dot_extension(String::Format(".%s", extension));
+  if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
+    return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
+  }
+  return *this;
+}
+
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+  // Comparing two pointers of which only one is NULL is undefined.
+  if (last_alt_sep != NULL &&
+      (last_sep == NULL || last_alt_sep > last_sep)) {
+    return last_alt_sep;
+  }
+#endif
+  return last_sep;
+}
+
+// Returns a copy of the FilePath with the directory part removed.
+// Example: FilePath("path/to/file").RemoveDirectoryName() returns
+// FilePath("file"). If there is no directory part ("just_a_file"), it returns
+// the FilePath unmodified. If there is no file part ("just_a_dir/") it
+// returns an empty FilePath ("").
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveDirectoryName() const {
+  const char* const last_sep = FindLastPathSeparator();
+  return last_sep ? FilePath(String(last_sep + 1)) : *this;
+}
+
+// RemoveFileName returns the directory path with the filename removed.
+// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveFileName() const {
+  const char* const last_sep = FindLastPathSeparator();
+  String dir;
+  if (last_sep) {
+    dir = String(c_str(), last_sep + 1 - c_str());
+  } else {
+    dir = kCurrentDirectoryString;
+  }
+  return FilePath(dir);
+}
+
+// Helper functions for naming files in a directory for xml output.
+
+// Given directory = "dir", base_name = "test", number = 0,
+// extension = "xml", returns "dir/test.xml". If number is greater
+// than zero (e.g., 12), returns "dir/test_12.xml".
+// On Windows platform, uses \ as the separator rather than /.
+FilePath FilePath::MakeFileName(const FilePath& directory,
+                                const FilePath& base_name,
+                                int number,
+                                const char* extension) {
+  String file;
+  if (number == 0) {
+    file = String::Format("%s.%s", base_name.c_str(), extension);
+  } else {
+    file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+  }
+  return ConcatPaths(directory, FilePath(file));
+}
+
+// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
+// On Windows, uses \ as the separator rather than /.
+FilePath FilePath::ConcatPaths(const FilePath& directory,
+                               const FilePath& relative_path) {
+  if (directory.IsEmpty())
+    return relative_path;
+  const FilePath dir(directory.RemoveTrailingPathSeparator());
+  return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
+                                 relative_path.c_str()));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  return attributes != kInvalidFileAttributes;
+#else
+  posix::StatStruct file_stat;
+  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+  bool result = false;
+#if GTEST_OS_WINDOWS
+  // Don't strip off trailing separator if path is a root directory on
+  // Windows (like "C:\\").
+  const FilePath& path(IsRootDirectory() ? *this :
+                                           RemoveTrailingPathSeparator());
+#else
+  const FilePath& path(*this);
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  if ((attributes != kInvalidFileAttributes) &&
+      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+    result = true;
+  }
+#else
+  posix::StatStruct file_stat;
+  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
+      posix::IsDir(file_stat);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  return result;
+}
+
+// Returns true if pathname describes a root directory. (Windows has one
+// root directory per disk drive.)
+bool FilePath::IsRootDirectory() const {
+#if GTEST_OS_WINDOWS
+  // TODO(wan@google.com): on Windows a network share like
+  // \\server\share can be a root directory, although it cannot be the
+  // current directory.  Handle this properly.
+  return pathname_.length() == 3 && IsAbsolutePath();
+#else
+  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
+#endif
+}
+
+// Returns true if pathname describes an absolute path.
+bool FilePath::IsAbsolutePath() const {
+  const char* const name = pathname_.c_str();
+#if GTEST_OS_WINDOWS
+  return pathname_.length() >= 3 &&
+     ((name[0] >= 'a' && name[0] <= 'z') ||
+      (name[0] >= 'A' && name[0] <= 'Z')) &&
+     name[1] == ':' &&
+     IsPathSeparator(name[2]);
+#else
+  return IsPathSeparator(name[0]);
+#endif
+}
+
+// Returns a pathname for a file that does not currently exist. The pathname
+// will be directory/base_name.extension or
+// directory/base_name_<number>.extension if directory/base_name.extension
+// already exists. The number will be incremented until a pathname is found
+// that does not already exist.
+// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+// There could be a race condition if two or more processes are calling this
+// function at the same time -- they could both pick the same filename.
+FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
+                                          const FilePath& base_name,
+                                          const char* extension) {
+  FilePath full_pathname;
+  int number = 0;
+  do {
+    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
+  } while (full_pathname.FileOrDirectoryExists());
+  return full_pathname;
+}
+
+// Returns true if FilePath ends with a path separator, which indicates that
+// it is intended to represent a directory. Returns false otherwise.
+// This does NOT check that a directory (or file) actually exists.
+bool FilePath::IsDirectory() const {
+  return !pathname_.empty() &&
+         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
+}
+
+// Create directories so that path exists. Returns true if successful or if
+// the directories already exist; returns false if unable to create directories
+// for any reason.
+bool FilePath::CreateDirectoriesRecursively() const {
+  if (!this->IsDirectory()) {
+    return false;
+  }
+
+  if (pathname_.length() == 0 || this->DirectoryExists()) {
+    return true;
+  }
+
+  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
+  return parent.CreateDirectoriesRecursively() && this->CreateFolder();
+}
+
+// Create the directory so that path exists. Returns true if successful or
+// if the directory already exists; returns false if unable to create the
+// directory for any reason, including if the parent directory does not
+// exist. Not named "CreateDirectory" because that's a macro on Windows.
+bool FilePath::CreateFolder() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  FilePath removed_sep(this->RemoveTrailingPathSeparator());
+  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
+  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+  delete [] unicode;
+#elif GTEST_OS_WINDOWS
+  int result = _mkdir(pathname_.c_str());
+#else
+  int result = mkdir(pathname_.c_str(), 0777);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  if (result == -1) {
+    return this->DirectoryExists();  // An error is OK if the directory exists.
+  }
+  return true;  // No error.
+}
+
+// If input name has a trailing separator character, remove it and return the
+// name, otherwise return the name string unmodified.
+// On Windows platform, uses \ as the separator, other platforms use /.
+FilePath FilePath::RemoveTrailingPathSeparator() const {
+  return IsDirectory()
+      ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
+      : *this;
+}
+
+// Removes any redundant separators that might be in the pathname.
+// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
+void FilePath::Normalize() {
+  if (pathname_.c_str() == NULL) {
+    pathname_ = "";
+    return;
+  }
+  const char* src = pathname_.c_str();
+  char* const dest = new char[pathname_.length() + 1];
+  char* dest_ptr = dest;
+  memset(dest_ptr, 0, pathname_.length() + 1);
+
+  while (*src != '\0') {
+    *dest_ptr = *src;
+    if (!IsPathSeparator(*src)) {
+      src++;
+    } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+      if (*dest_ptr == kAlternatePathSeparator) {
+        *dest_ptr = kPathSeparator;
+      }
+#endif
+      while (IsPathSeparator(*src))
+        src++;
+    }
+    dest_ptr++;
+  }
+  *dest_ptr = '\0';
+  pathname_ = dest;
+  delete[] dest;
+}
+
+}  // namespace internal
+}  // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+# include <windows.h>  // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
+# include <io.h>
+# include <sys/stat.h>
+#else
+# include <unistd.h>
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_MAC
+# include <mach/mach_init.h>
+# include <mach/task.h>
+# include <mach/vm_map.h>
+#endif  // GTEST_OS_MAC
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
+const int kStdErrFileno = 2;
+#else
+const int kStdOutFileno = STDOUT_FILENO;
+const int kStdErrFileno = STDERR_FILENO;
+#endif  // _MSC_VER
+
+#if GTEST_OS_MAC
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  const task_t task = mach_task_self();
+  mach_msg_type_number_t thread_count;
+  thread_act_array_t thread_list;
+  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+  if (status == KERN_SUCCESS) {
+    // task_threads allocates resources in thread_list and we need to free them
+    // to avoid leaks.
+    vm_deallocate(task,
+                  reinterpret_cast<vm_address_t>(thread_list),
+                  sizeof(thread_t) * thread_count);
+    return static_cast<size_t>(thread_count);
+  } else {
+    return 0;
+  }
+}
+
+#else
+
+size_t GetThreadCount() {
+  // There's no portable way to detect the number of threads, so we just
+  // return 0 to indicate that we cannot detect it.
+  return 0;
+}
+
+#endif  // GTEST_OS_MAC
+
+#if GTEST_USES_POSIX_RE
+
+// Implements RE.  Currently only needed for death tests.
+
+RE::~RE() {
+  if (is_valid_) {
+    // regfree'ing an invalid regex might crash because the content
+    // of the regex is undefined. Since the regex's are essentially
+    // the same, one cannot be valid (or invalid) without the other
+    // being so too.
+    regfree(&partial_regex_);
+    regfree(&full_regex_);
+  }
+  free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = posix::StrDup(regex);
+
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match.
+  const size_t full_regex_len = strlen(regex) + 10;
+  char* const full_pattern = new char[full_regex_len];
+
+  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
+  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
+  // We want to call regcomp(&partial_regex_, ...) even if the
+  // previous expression returns false.  Otherwise partial_regex_ may
+  // not be properly initialized can may cause trouble when it's
+  // freed.
+  //
+  // Some implementation of POSIX regex (e.g. on at least some
+  // versions of Cygwin) doesn't accept the empty string as a valid
+  // regex.  We change it to an equivalent form "()" to be safe.
+  if (is_valid_) {
+    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+  }
+  EXPECT_TRUE(is_valid_)
+      << "Regular expression \"" << regex
+      << "\" is not a valid POSIX Extended regular expression.";
+
+  delete[] full_pattern;
+}
+
+#elif GTEST_USES_SIMPLE_RE
+
+// Returns true iff ch appears anywhere in str (excluding the
+// terminating '\0' character).
+bool IsInSet(char ch, const char* str) {
+  return ch != '\0' && strchr(str, ch) != NULL;
+}
+
+// Returns true iff ch belongs to the given classification.  Unlike
+// similar functions in <ctype.h>, these aren't affected by the
+// current locale.
+bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
+bool IsAsciiPunct(char ch) {
+  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
+}
+bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
+bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
+bool IsAsciiWordChar(char ch) {
+  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
+      ('0' <= ch && ch <= '9') || ch == '_';
+}
+
+// Returns true iff "\\c" is a supported escape sequence.
+bool IsValidEscape(char c) {
+  return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
+}
+
+// Returns true iff the given atom (specified by escaped and pattern)
+// matches ch.  The result is undefined if the atom is invalid.
+bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
+  if (escaped) {  // "\\p" where p is pattern_char.
+    switch (pattern_char) {
+      case 'd': return IsAsciiDigit(ch);
+      case 'D': return !IsAsciiDigit(ch);
+      case 'f': return ch == '\f';
+      case 'n': return ch == '\n';
+      case 'r': return ch == '\r';
+      case 's': return IsAsciiWhiteSpace(ch);
+      case 'S': return !IsAsciiWhiteSpace(ch);
+      case 't': return ch == '\t';
+      case 'v': return ch == '\v';
+      case 'w': return IsAsciiWordChar(ch);
+      case 'W': return !IsAsciiWordChar(ch);
+    }
+    return IsAsciiPunct(pattern_char) && pattern_char == ch;
+  }
+
+  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
+}
+
+// Helper function used by ValidateRegex() to format error messages.
+String FormatRegexSyntaxError(const char* regex, int index) {
+  return (Message() << "Syntax error at index " << index
+          << " in simple regular expression \"" << regex << "\": ").GetString();
+}
+
+// Generates non-fatal failures and returns false if regex is invalid;
+// otherwise returns true.
+bool ValidateRegex(const char* regex) {
+  if (regex == NULL) {
+    // TODO(wan@google.com): fix the source file location in the
+    // assertion failures to match where the regex is used in user
+    // code.
+    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
+    return false;
+  }
+
+  bool is_valid = true;
+
+  // True iff ?, *, or + can follow the previous atom.
+  bool prev_repeatable = false;
+  for (int i = 0; regex[i]; i++) {
+    if (regex[i] == '\\') {  // An escape sequence
+      i++;
+      if (regex[i] == '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "'\\' cannot appear at the end.";
+        return false;
+      }
+
+      if (!IsValidEscape(regex[i])) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "invalid escape sequence \"\\" << regex[i] << "\".";
+        is_valid = false;
+      }
+      prev_repeatable = true;
+    } else {  // Not an escape sequence.
+      const char ch = regex[i];
+
+      if (ch == '^' && i > 0) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'^' can only appear at the beginning.";
+        is_valid = false;
+      } else if (ch == '$' && regex[i + 1] != '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'$' can only appear at the end.";
+        is_valid = false;
+      } else if (IsInSet(ch, "()[]{}|")) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' is unsupported.";
+        is_valid = false;
+      } else if (IsRepeat(ch) && !prev_repeatable) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' can only follow a repeatable token.";
+        is_valid = false;
+      }
+
+      prev_repeatable = !IsInSet(ch, "^$?*+");
+    }
+  }
+
+  return is_valid;
+}
+
+// Matches a repeated regex atom followed by a valid simple regular
+// expression.  The regex atom is defined as c if escaped is false,
+// or \c otherwise.  repeat is the repetition meta character (?, *,
+// or +).  The behavior is undefined if str contains too many
+// characters to be indexable by size_t, in which case the test will
+// probably time out anyway.  We are fine with this limitation as
+// std::string has it too.
+bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char c, char repeat, const char* regex,
+    const char* str) {
+  const size_t min_count = (repeat == '+') ? 1 : 0;
+  const size_t max_count = (repeat == '?') ? 1 :
+      static_cast<size_t>(-1) - 1;
+  // We cannot call numeric_limits::max() as it conflicts with the
+  // max() macro on Windows.
+
+  for (size_t i = 0; i <= max_count; ++i) {
+    // We know that the atom matches each of the first i characters in str.
+    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
+      // We have enough matches at the head, and the tail matches too.
+      // Since we only care about *whether* the pattern matches str
+      // (as opposed to *how* it matches), there is no need to find a
+      // greedy match.
+      return true;
+    }
+    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
+      return false;
+  }
+  return false;
+}
+
+// Returns true iff regex matches a prefix of str.  regex must be a
+// valid simple regular expression and not start with "^", or the
+// result is undefined.
+bool MatchRegexAtHead(const char* regex, const char* str) {
+  if (*regex == '\0')  // An empty regex matches a prefix of anything.
+    return true;
+
+  // "$" only matches the end of a string.  Note that regex being
+  // valid guarantees that there's nothing after "$" in it.
+  if (*regex == '$')
+    return *str == '\0';
+
+  // Is the first thing in regex an escape sequence?
+  const bool escaped = *regex == '\\';
+  if (escaped)
+    ++regex;
+  if (IsRepeat(regex[1])) {
+    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
+    // here's an indirect recursion.  It terminates as the regex gets
+    // shorter in each recursion.
+    return MatchRepetitionAndRegexAtHead(
+        escaped, regex[0], regex[1], regex + 2, str);
+  } else {
+    // regex isn't empty, isn't "$", and doesn't start with a
+    // repetition.  We match the first atom of regex with the first
+    // character of str and recurse.
+    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
+        MatchRegexAtHead(regex + 1, str + 1);
+  }
+}
+
+// Returns true iff regex matches any substring of str.  regex must be
+// a valid simple regular expression, or the result is undefined.
+//
+// The algorithm is recursive, but the recursion depth doesn't exceed
+// the regex length, so we won't need to worry about running out of
+// stack space normally.  In rare cases the time complexity can be
+// exponential with respect to the regex length + the string length,
+// but usually it's must faster (often close to linear).
+bool MatchRegexAnywhere(const char* regex, const char* str) {
+  if (regex == NULL || str == NULL)
+    return false;
+
+  if (*regex == '^')
+    return MatchRegexAtHead(regex + 1, str);
+
+  // A successful match can be anywhere in str.
+  do {
+    if (MatchRegexAtHead(regex, str))
+      return true;
+  } while (*str++ != '\0');
+  return false;
+}
+
+// Implements the RE class.
+
+RE::~RE() {
+  free(const_cast<char*>(pattern_));
+  free(const_cast<char*>(full_pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = full_pattern_ = NULL;
+  if (regex != NULL) {
+    pattern_ = posix::StrDup(regex);
+  }
+
+  is_valid_ = ValidateRegex(regex);
+  if (!is_valid_) {
+    // No need to calculate the full pattern when the regex is invalid.
+    return;
+  }
+
+  const size_t len = strlen(regex);
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match: we need space to prepend a '^', append a '$', and
+  // terminate the string with '\0'.
+  char* buffer = static_cast<char*>(malloc(len + 3));
+  full_pattern_ = buffer;
+
+  if (*regex != '^')
+    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
+
+  // We don't use snprintf or strncpy, as they trigger a warning when
+  // compiled with VC++ 8.0.
+  memcpy(buffer, regex, len);
+  buffer += len;
+
+  if (len == 0 || regex[len - 1] != '$')
+    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
+
+  *buffer = '\0';
+}
+
+#endif  // GTEST_USES_POSIX_RE
+
+const char kUnknownFile[] = "unknown file";
+
+// Formats a source file path and a line number as they would appear
+// in an error message from the compiler used to compile this code.
+GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
+  const char* const file_name = file == NULL ? kUnknownFile : file;
+
+  if (line < 0) {
+    return String::Format("%s:", file_name).c_str();
+  }
+#ifdef _MSC_VER
+  return String::Format("%s(%d):", file_name, line).c_str();
+#else
+  return String::Format("%s:%d:", file_name, line).c_str();
+#endif  // _MSC_VER
+}
+
+// Formats a file location for compiler-independent XML output.
+// Although this function is not platform dependent, we put it next to
+// FormatFileLocation in order to contrast the two functions.
+// Note that FormatCompilerIndependentFileLocation() does NOT append colon
+// to the file location it produces, unlike FormatFileLocation().
+GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
+    const char* file, int line) {
+  const char* const file_name = file == NULL ? kUnknownFile : file;
+
+  if (line < 0)
+    return file_name;
+  else
+    return String::Format("%s:%d", file_name, line).c_str();
+}
+
+
+GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
+    : severity_(severity) {
+  const char* const marker =
+      severity == GTEST_INFO ?    "[  INFO ]" :
+      severity == GTEST_WARNING ? "[WARNING]" :
+      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
+  GetStream() << ::std::endl << marker << " "
+              << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+GTestLog::~GTestLog() {
+  GetStream() << ::std::endl;
+  if (severity_ == GTEST_FATAL) {
+    fflush(stderr);
+    posix::Abort();
+  }
+}
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4996)
+#endif  // _MSC_VER
+
+#if GTEST_HAS_STREAM_REDIRECTION
+
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
+ public:
+  // The ctor redirects the stream to a temporary file.
+  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+
+# if GTEST_OS_WINDOWS
+    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+
+    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+    const UINT success = ::GetTempFileNameA(temp_dir_path,
+                                            "gtest_redir",
+                                            0,  // Generate unique file name.
+                                            temp_file_path);
+    GTEST_CHECK_(success != 0)
+        << "Unable to create a temporary file in " << temp_dir_path;
+    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+                                    << temp_file_path;
+    filename_ = temp_file_path;
+# else
+    // There's no guarantee that a test has write access to the
+    // current directory, so we create the temporary file in the /tmp
+    // directory instead.
+    char name_template[] = "/tmp/captured_stream.XXXXXX";
+    const int captured_fd = mkstemp(name_template);
+    filename_ = name_template;
+# endif  // GTEST_OS_WINDOWS
+    fflush(NULL);
+    dup2(captured_fd, fd_);
+    close(captured_fd);
+  }
+
+  ~CapturedStream() {
+    remove(filename_.c_str());
+  }
+
+  String GetCapturedString() {
+    if (uncaptured_fd_ != -1) {
+      // Restores the original stream.
+      fflush(NULL);
+      dup2(uncaptured_fd_, fd_);
+      close(uncaptured_fd_);
+      uncaptured_fd_ = -1;
+    }
+
+    FILE* const file = posix::FOpen(filename_.c_str(), "r");
+    const String content = ReadEntireFile(file);
+    posix::FClose(file);
+    return content;
+  }
+
+ private:
+  // Reads the entire content of a file as a String.
+  static String ReadEntireFile(FILE* file);
+
+  // Returns the size (in bytes) of a file.
+  static size_t GetFileSize(FILE* file);
+
+  const int fd_;  // A stream to capture.
+  int uncaptured_fd_;
+  // Name of the temporary file holding the stderr output.
+  ::std::string filename_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
+
+// Returns the size (in bytes) of a file.
+size_t CapturedStream::GetFileSize(FILE* file) {
+  fseek(file, 0, SEEK_END);
+  return static_cast<size_t>(ftell(file));
+}
+
+// Reads the entire content of a file as a string.
+String CapturedStream::ReadEntireFile(FILE* file) {
+  const size_t file_size = GetFileSize(file);
+  char* const buffer = new char[file_size];
+
+  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
+  size_t bytes_read = 0;       // # of bytes read so far
+
+  fseek(file, 0, SEEK_SET);
+
+  // Keeps reading the file until we cannot read further or the
+  // pre-determined file size is reached.
+  do {
+    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
+    bytes_read += bytes_last_read;
+  } while (bytes_last_read > 0 && bytes_read < file_size);
+
+  const String content(buffer, bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+
+# ifdef _MSC_VER
+#  pragma warning(pop)
+# endif  // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+  if (*stream != NULL) {
+    GTEST_LOG_(FATAL) << "Only one " << stream_name
+                      << " capturer can exist at a time.";
+  }
+  *stream = new CapturedStream(fd);
+}
+
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+  const String content = (*captured_stream)->GetCapturedString();
+
+  delete *captured_stream;
+  *captured_stream = NULL;
+
+  return content;
+}
+
+// Starts capturing stdout.
+void CaptureStdout() {
+  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+::std::vector<String> g_argvs;
+
+// Returns the command line as a vector of strings.
+const ::std::vector<String>& GetArgvs() { return g_argvs; }
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_WINDOWS_MOBILE
+namespace posix {
+void Abort() {
+  DebugBreak();
+  TerminateProcess(GetCurrentProcess(), 1);
+}
+}  // namespace posix
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// Returns the name of the environment variable corresponding to the
+// given flag.  For example, FlagToEnvVar("foo") will return
+// "GTEST_FOO" in the open-source version.
+static String FlagToEnvVar(const char* flag) {
+  const String full_flag =
+      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
+
+  Message env_var;
+  for (size_t i = 0; i != full_flag.length(); i++) {
+    env_var << ToUpper(full_flag.c_str()[i]);
+  }
+
+  return env_var.GetString();
+}
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes
+// the result to *value and returns true; otherwise leaves *value
+// unchanged and returns false.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
+  // Parses the environment variable as a decimal integer.
+  char* end = NULL;
+  const long long_value = strtol(str, &end, 10);  // NOLINT
+
+  // Has strtol() consumed all characters in the string?
+  if (*end != '\0') {
+    // No - an invalid character was encountered.
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value \"" << str << "\".\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  // Is the parsed value in the range of an Int32?
+  const Int32 result = static_cast<Int32>(long_value);
+  if (long_value == LONG_MAX || long_value == LONG_MIN ||
+      // The parsed value overflows as a long.  (strtol() returns
+      // LONG_MAX or LONG_MIN when the input overflows.)
+      result != long_value
+      // The parsed value overflows as an Int32.
+      ) {
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value " << str << ", which overflows.\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  *value = result;
+  return true;
+}
+
+// Reads and returns the Boolean environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+//
+// The value is considered true iff it's not "0".
+bool BoolFromGTestEnv(const char* flag, bool default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = posix::GetEnv(env_var.c_str());
+  return string_value == NULL ?
+      default_value : strcmp(string_value, "0") != 0;
+}
+
+// Reads and returns a 32-bit integer stored in the environment
+// variable corresponding to the given flag; if it isn't set or
+// doesn't represent a valid 32-bit integer, returns default_value.
+Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = posix::GetEnv(env_var.c_str());
+  if (string_value == NULL) {
+    // The environment variable is not set.
+    return default_value;
+  }
+
+  Int32 result = default_value;
+  if (!ParseInt32(Message() << "Environment variable " << env_var,
+                  string_value, &result)) {
+    printf("The default value %s is used.\n",
+           (Message() << default_value).GetString().c_str());
+    fflush(stdout);
+    return default_value;
+  }
+
+  return result;
+}
+
+// Reads and returns the string environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const value = posix::GetEnv(env_var.c_str());
+  return value == NULL ? default_value : value;
+}
+
+}  // namespace internal
+}  // namespace testing
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Test - The Google C++ Testing Framework
+//
+// This file implements a universal value printer that can print a
+// value of any type T:
+//
+//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
+//
+// It uses the << operator when possible, and prints the bytes in the
+// object otherwise.  A user can override its behavior for a class
+// type Foo by defining either operator<<(::std::ostream&, const Foo&)
+// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
+// defines Foo.
+
+#include <ctype.h>
+#include <stdio.h>
+#include <ostream>  // NOLINT
+#include <string>
+
+namespace testing {
+
+namespace {
+
+using ::std::ostream;
+
+#if GTEST_OS_WINDOWS_MOBILE  // Windows CE does not define _snprintf_s.
+# define snprintf _snprintf
+#elif _MSC_VER >= 1400  // VC 8.0 and later deprecate snprintf and _snprintf.
+# define snprintf _snprintf_s
+#elif _MSC_VER
+# define snprintf _snprintf
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// Prints a segment of bytes in the given object.
+void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
+                                size_t count, ostream* os) {
+  char text[5] = "";
+  for (size_t i = 0; i != count; i++) {
+    const size_t j = start + i;
+    if (i != 0) {
+      // Organizes the bytes into groups of 2 for easy parsing by
+      // human.
+      if ((j % 2) == 0)
+        *os << ' ';
+      else
+        *os << '-';
+    }
+    snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
+    *os << text;
+  }
+}
+
+// Prints the bytes in the given value to the given ostream.
+void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
+                              ostream* os) {
+  // Tells the user how big the object is.
+  *os << count << "-byte object <";
+
+  const size_t kThreshold = 132;
+  const size_t kChunkSize = 64;
+  // If the object size is bigger than kThreshold, we'll have to omit
+  // some details by printing only the first and the last kChunkSize
+  // bytes.
+  // TODO(wan): let the user control the threshold using a flag.
+  if (count < kThreshold) {
+    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
+  } else {
+    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
+    *os << " ... ";
+    // Rounds up to 2-byte boundary.
+    const size_t resume_pos = (count - kChunkSize + 1)/2*2;
+    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
+  }
+  *os << ">";
+}
+
+}  // namespace
+
+namespace internal2 {
+
+// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
+// given object.  The delegation simplifies the implementation, which
+// uses the << operator and thus is easier done outside of the
+// ::testing::internal namespace, which contains a << operator that
+// sometimes conflicts with the one in STL.
+void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
+                          ostream* os) {
+  PrintBytesInObjectToImpl(obj_bytes, count, os);
+}
+
+}  // namespace internal2
+
+namespace internal {
+
+// Depending on the value of a char (or wchar_t), we print it in one
+// of three formats:
+//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
+//   - as a hexidecimal escape sequence (e.g. '\x7F'), or
+//   - as a special escape sequence (e.g. '\r', '\n').
+enum CharFormat {
+  kAsIs,
+  kHexEscape,
+  kSpecialEscape
+};
+
+// Returns true if c is a printable ASCII character.  We test the
+// value of c directly instead of calling isprint(), which is buggy on
+// Windows Mobile.
+inline bool IsPrintableAscii(wchar_t c) {
+  return 0x20 <= c && c <= 0x7E;
+}
+
+// Prints a wide or narrow char c as a character literal without the
+// quotes, escaping it when necessary; returns how c was formatted.
+// The template argument UnsignedChar is the unsigned version of Char,
+// which is the type of c.
+template <typename UnsignedChar, typename Char>
+static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
+  switch (static_cast<wchar_t>(c)) {
+    case L'\0':
+      *os << "\\0";
+      break;
+    case L'\'':
+      *os << "\\'";
+      break;
+    case L'\\':
+      *os << "\\\\";
+      break;
+    case L'\a':
+      *os << "\\a";
+      break;
+    case L'\b':
+      *os << "\\b";
+      break;
+    case L'\f':
+      *os << "\\f";
+      break;
+    case L'\n':
+      *os << "\\n";
+      break;
+    case L'\r':
+      *os << "\\r";
+      break;
+    case L'\t':
+      *os << "\\t";
+      break;
+    case L'\v':
+      *os << "\\v";
+      break;
+    default:
+      if (IsPrintableAscii(c)) {
+        *os << static_cast<char>(c);
+        return kAsIs;
+      } else {
+        *os << String::Format("\\x%X", static_cast<UnsignedChar>(c));
+        return kHexEscape;
+      }
+  }
+  return kSpecialEscape;
+}
+
+// Prints a char c as if it's part of a string literal, escaping it when
+// necessary; returns how c was formatted.
+static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
+  switch (c) {
+    case L'\'':
+      *os << "'";
+      return kAsIs;
+    case L'"':
+      *os << "\\\"";
+      return kSpecialEscape;
+    default:
+      return PrintAsCharLiteralTo<wchar_t>(c, os);
+  }
+}
+
+// Prints a char c as if it's part of a string literal, escaping it when
+// necessary; returns how c was formatted.
+static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
+  return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
+}
+
+// Prints a wide or narrow character c and its code.  '\0' is printed
+// as "'\\0'", other unprintable characters are also properly escaped
+// using the standard C++ escape sequence.  The template argument
+// UnsignedChar is the unsigned version of Char, which is the type of c.
+template <typename UnsignedChar, typename Char>
+void PrintCharAndCodeTo(Char c, ostream* os) {
+  // First, print c as a literal in the most readable form we can find.
+  *os << ((sizeof(c) > 1) ? "L'" : "'");
+  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
+  *os << "'";
+
+  // To aid user debugging, we also print c's code in decimal, unless
+  // it's 0 (in which case c was printed as '\\0', making the code
+  // obvious).
+  if (c == 0)
+    return;
+  *os << " (" << String::Format("%d", c).c_str();
+
+  // For more convenience, we print c's code again in hexidecimal,
+  // unless c was already printed in the form '\x##' or the code is in
+  // [1, 9].
+  if (format == kHexEscape || (1 <= c && c <= 9)) {
+    // Do nothing.
+  } else {
+    *os << String::Format(", 0x%X",
+                          static_cast<UnsignedChar>(c)).c_str();
+  }
+  *os << ")";
+}
+
+void PrintTo(unsigned char c, ::std::ostream* os) {
+  PrintCharAndCodeTo<unsigned char>(c, os);
+}
+void PrintTo(signed char c, ::std::ostream* os) {
+  PrintCharAndCodeTo<unsigned char>(c, os);
+}
+
+// Prints a wchar_t as a symbol if it is printable or as its internal
+// code otherwise and also as its code.  L'\0' is printed as "L'\\0'".
+void PrintTo(wchar_t wc, ostream* os) {
+  PrintCharAndCodeTo<wchar_t>(wc, os);
+}
+
+// Prints the given array of characters to the ostream.
+// The array starts at *begin, the length is len, it may include '\0' characters
+// and may not be null-terminated.
+static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
+  *os << "\"";
+  bool is_previous_hex = false;
+  for (size_t index = 0; index < len; ++index) {
+    const char cur = begin[index];
+    if (is_previous_hex && IsXDigit(cur)) {
+      // Previous character is of '\x..' form and this character can be
+      // interpreted as another hexadecimal digit in its number. Break string to
+      // disambiguate.
+      *os << "\" \"";
+    }
+    is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
+  }
+  *os << "\"";
+}
+
+// Prints a (const) char array of 'len' elements, starting at address 'begin'.
+void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
+  PrintCharsAsStringTo(begin, len, os);
+}
+
+// Prints the given array of wide characters to the ostream.
+// The array starts at *begin, the length is len, it may include L'\0'
+// characters and may not be null-terminated.
+static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
+                                     ostream* os) {
+  *os << "L\"";
+  bool is_previous_hex = false;
+  for (size_t index = 0; index < len; ++index) {
+    const wchar_t cur = begin[index];
+    if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {
+      // Previous character is of '\x..' form and this character can be
+      // interpreted as another hexadecimal digit in its number. Break string to
+      // disambiguate.
+      *os << "\" L\"";
+    }
+    is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
+  }
+  *os << "\"";
+}
+
+// Prints the given C string to the ostream.
+void PrintTo(const char* s, ostream* os) {
+  if (s == NULL) {
+    *os << "NULL";
+  } else {
+    *os << ImplicitCast_<const void*>(s) << " pointing to ";
+    PrintCharsAsStringTo(s, strlen(s), os);
+  }
+}
+
+// MSVC compiler can be configured to define whar_t as a typedef
+// of unsigned short. Defining an overload for const wchar_t* in that case
+// would cause pointers to unsigned shorts be printed as wide strings,
+// possibly accessing more memory than intended and causing invalid
+// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
+// wchar_t is implemented as a native type.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+// Prints the given wide C string to the ostream.
+void PrintTo(const wchar_t* s, ostream* os) {
+  if (s == NULL) {
+    *os << "NULL";
+  } else {
+    *os << ImplicitCast_<const void*>(s) << " pointing to ";
+    PrintWideCharsAsStringTo(s, wcslen(s), os);
+  }
+}
+#endif  // wchar_t is native
+
+// Prints a ::string object.
+#if GTEST_HAS_GLOBAL_STRING
+void PrintStringTo(const ::string& s, ostream* os) {
+  PrintCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+void PrintStringTo(const ::std::string& s, ostream* os) {
+  PrintCharsAsStringTo(s.data(), s.size(), os);
+}
+
+// Prints a ::wstring object.
+#if GTEST_HAS_GLOBAL_WSTRING
+void PrintWideStringTo(const ::wstring& s, ostream* os) {
+  PrintWideCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+#if GTEST_HAS_STD_WSTRING
+void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
+  PrintWideCharsAsStringTo(s.data(), s.size(), os);
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+}  // namespace internal
+
+}  // namespace testing
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+// The Google C++ Testing Framework (Google Test)
+
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+using internal::GetUnitTestImpl;
+
+// Gets the summary of the failure message by omitting the stack trace
+// in it.
+internal::String TestPartResult::ExtractSummary(const char* message) {
+  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
+  return stack_trace == NULL ? internal::String(message) :
+      internal::String(message, stack_trace - message);
+}
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+  return os
+      << result.file_name() << ":" << result.line_number() << ": "
+      << (result.type() == TestPartResult::kSuccess ? "Success" :
+          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
+          "Non-fatal failure") << ":\n"
+      << result.message() << std::endl;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+  array_.push_back(result);
+}
+
+// Returns the TestPartResult at the given index (0-based).
+const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
+  if (index < 0 || index >= size()) {
+    printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
+    internal::posix::Abort();
+  }
+
+  return array_[index];
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+  return static_cast<int>(array_.size());
+}
+
+namespace internal {
+
+HasNewFatalFailureHelper::HasNewFatalFailureHelper()
+    : has_new_fatal_failure_(false),
+      original_reporter_(GetUnitTestImpl()->
+                         GetTestPartResultReporterForCurrentThread()) {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
+}
+
+HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
+      original_reporter_);
+}
+
+void HasNewFatalFailureHelper::ReportTestPartResult(
+    const TestPartResult& result) {
+  if (result.fatally_failed())
+    has_new_fatal_failure_ = true;
+  original_reporter_->ReportTestPartResult(result);
+}
+
+}  // namespace internal
+
+}  // namespace testing
+// Copyright 2008 Google Inc.
+// All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+  while (IsSpace(*str))
+    str++;
+  return str;
+}
+
+// Verifies that registered_tests match the test names in
+// defined_test_names_; returns registered_tests if successful, or
+// aborts the program otherwise.
+const char* TypedTestCasePState::VerifyRegisteredTestNames(
+    const char* file, int line, const char* registered_tests) {
+  typedef ::std::set<const char*>::const_iterator DefinedTestIter;
+  registered_ = true;
+
+  // Skip initial whitespace in registered_tests since some
+  // preprocessors prefix stringizied literals with whitespace.
+  registered_tests = SkipSpaces(registered_tests);
+
+  Message errors;
+  ::std::set<String> tests;
+  for (const char* names = registered_tests; names != NULL;
+       names = SkipComma(names)) {
+    const String name = GetPrefixUntilComma(names);
+    if (tests.count(name) != 0) {
+      errors << "Test " << name << " is listed more than once.\n";
+      continue;
+    }
+
+    bool found = false;
+    for (DefinedTestIter it = defined_test_names_.begin();
+         it != defined_test_names_.end();
+         ++it) {
+      if (name == *it) {
+        found = true;
+        break;
+      }
+    }
+
+    if (found) {
+      tests.insert(name);
+    } else {
+      errors << "No test named " << name
+             << " can be found in this test case.\n";
+    }
+  }
+
+  for (DefinedTestIter it = defined_test_names_.begin();
+       it != defined_test_names_.end();
+       ++it) {
+    if (tests.count(*it) == 0) {
+      errors << "You forgot to list test " << *it << ".\n";
+    }
+  }
+
+  const String& errors_str = errors.GetString();
+  if (errors_str != "") {
+    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+            errors_str.c_str());
+    fflush(stderr);
+    posix::Abort();
+  }
+
+  return registered_tests;
+}
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+}  // namespace internal
+}  // namespace testing