Linkloader improvement: mclinker.

Change-Id: I8805e39ccbc2ee204234fb3e71c70c906f3990bb
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=