diff --git a/CMakeLists.txt b/CMakeLists.txt
index 18d6a911a..b3773861e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,22 @@
 # cmake global
 cmake_minimum_required(VERSION 2.8.12)
+
+project(ethereum)
+
+set(CMAKE_AUTOMOC ON)
+
+# link_directories interprate relative paths with respect to CMAKE_CURRENT_SOURCE_DIR
+cmake_policy(SET CMP0015 NEW)
+
 # let cmake autolink dependencies on windows
 # it's specified globally, cause qt libraries requires that on windows and they are also found globally
 cmake_policy(SET CMP0020 NEW)
 
-project(ethereum)
+# 3.1 and above
+if ((${CMAKE_MAJOR_VERSION} GREATER 2) AND (${CMAKE_MINOR_VERSION} GREATER 0))
+	# implicitly dereference variables (deprecated in 3.1)
+	cmake_policy(SET CMP0054 NEW)
+endif()
 
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
 
@@ -124,9 +136,6 @@ endfunction()
 ######################################################################################################
 
 
-set(CMAKE_AUTOMOC ON)
-cmake_policy(SET CMP0015 NEW)
-
 # Clear invalid option
 if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
 	if (PARANOID)
@@ -242,11 +251,11 @@ if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
 	set(CMAKE_BUILD_TYPE "Release")
 endif ()
 
-# Default TARGET_PLATFORM to ${CMAKE_SYSTEM}
+# Default TARGET_PLATFORM to ${CMAKE_SYSTEM_NAME}
 # change this once we support cross compiling
-set(TARGET_PLATFORM CACHE STRING ${CMAKE_SYSTEM})
+set(TARGET_PLATFORM CACHE STRING ${CMAKE_SYSTEM_NAME})
 if ("x${TARGET_PLATFORM}" STREQUAL "x")
-	set(TARGET_PLATFORM ${CMAKE_SYSTEM})
+	set(TARGET_PLATFORM ${CMAKE_SYSTEM_NAME})
 endif ()
 
 include(EthDependencies)
diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt
index fb134a82d..d9e8dff6f 100644
--- a/alethzero/CMakeLists.txt
+++ b/alethzero/CMakeLists.txt
@@ -51,7 +51,9 @@ target_link_libraries(${EXECUTABLE} ethcore)
 target_link_libraries(${EXECUTABLE} devcrypto)
 target_link_libraries(${EXECUTABLE} secp256k1)
 target_link_libraries(${EXECUTABLE} lll)
-target_link_libraries(${EXECUTABLE} solidity)
+if (SOLIDITY)
+	target_link_libraries(${EXECUTABLE} solidity)
+endif ()
 target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 target_link_libraries(${EXECUTABLE} web3jsonrpc)
diff --git a/alethzero/Main.ui b/alethzero/Main.ui
index 8e48793c9..1fd9669e9 100644
--- a/alethzero/Main.ui
+++ b/alethzero/Main.ui
@@ -176,6 +176,7 @@
     <addaction name="clearPending"/>
     <addaction name="killBlockchain"/>
     <addaction name="inject"/>
+    <addaction name="injectBlock"/>
     <addaction name="forceMining"/>
     <addaction name="separator"/>
     <addaction name="usePrivate"/>
@@ -1685,6 +1686,11 @@ font-size: 14pt</string>
     <string>Retry Unknown Parent Blocks</string>
    </property>
   </action>
+  <action name="injectBlock">
+   <property name="text">
+    <string>In&amp;ject Block</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 270996a30..eb2431f10 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -116,6 +116,11 @@ QString contentsOfQResource(string const& res)
 Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
 //Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1");
 
+static QString filterOutTerminal(QString _s)
+{
+	return _s.replace(QRegExp("\x1b\\[(\\d;)?\\d+m"), "");
+}
+
 Main::Main(QWidget *parent) :
 	QMainWindow(parent),
 	ui(new Ui::Main),
@@ -130,7 +135,7 @@ Main::Main(QWidget *parent) :
 	{
 		simpleDebugOut(s, c);
 		m_logLock.lock();
-		m_logHistory.append(QString::fromStdString(s) + "\n");
+		m_logHistory.append(filterOutTerminal(QString::fromStdString(s)) + "\n");
 		m_logChanged = true;
 		m_logLock.unlock();
 //		ui->log->addItem(QString::fromStdString(s));
@@ -164,7 +169,7 @@ Main::Main(QWidget *parent) :
 	statusBar()->addPermanentWidget(ui->chainStatus);
 	statusBar()->addPermanentWidget(ui->blockCount);
 
-	ui->blockCount->setText(QString("PV%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version));
+	ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version));
 
 	connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
 	
@@ -1448,6 +1453,25 @@ void Main::on_inject_triggered()
 	}
 }
 
+void Main::on_injectBlock_triggered()
+{
+	QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex");
+	try
+	{
+		bytes b = fromHex(s.toStdString(), WhenError::Throw);
+		ethereum()->injectBlock(b);
+	}
+	catch (BadHexCharacter& _e)
+	{
+		cwarn << "invalid hex character, transaction rejected";
+		cwarn << boost::diagnostic_information(_e);
+	}
+	catch (...)
+	{
+		cwarn << "block rejected";
+	}
+}
+
 void Main::on_blocks_currentItemChanged()
 {
 	ui->info->clear();
diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h
index a8579ed01..1a53ec62b 100644
--- a/alethzero/MainWin.h
+++ b/alethzero/MainWin.h
@@ -159,6 +159,7 @@ private slots:
 	void on_killBlockchain_triggered();
 	void on_clearPending_triggered();
 	void on_inject_triggered();
+	void on_injectBlock_triggered();
 	void on_forceMining_triggered();
 	void on_usePrivate_triggered();
 	void on_turboMining_triggered();
diff --git a/alethzero/NatspecHandler.cpp b/alethzero/NatspecHandler.cpp
index 27cf00341..ffab6db58 100644
--- a/alethzero/NatspecHandler.cpp
+++ b/alethzero/NatspecHandler.cpp
@@ -51,7 +51,7 @@ NatspecHandler::~NatspecHandler()
 void NatspecHandler::add(dev::h256 const& _contractHash, string const& _doc)
 {
 	m_db->Put(m_writeOptions, _contractHash.ref(), _doc);
-	cdebug << "Registering NatSpec: " << _contractHash.abridged() << _doc;
+	cdebug << "Registering NatSpec: " << _contractHash << _doc;
 }
 
 string NatspecHandler::retrieve(dev::h256 const& _contractHash) const
diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp
index 1ebdf9e23..d3e5650bf 100644
--- a/alethzero/Transact.cpp
+++ b/alethzero/Transact.cpp
@@ -168,6 +168,7 @@ static std::string toString(TransactionException _te)
 	}
 }
 
+#if ETH_SOLIDITY
 static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName)
 {
 	string ret = "";
@@ -182,6 +183,7 @@ static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, s
 	}
 	return ret;
 }
+#endif
 
 static tuple<vector<string>, bytes, string> userInputToCode(string const& _user, bool _opt)
 {
@@ -197,6 +199,7 @@ static tuple<vector<string>, bytes, string> userInputToCode(string const& _user,
 		boost::replace_all_copy(u, " ", "");
 		data = fromHex(u);
 	}
+#if ETH_SOLIDITY
 	else if (sourceIsSolidity(_user))
 	{
 		dev::solidity::CompilerStack compiler(true);
@@ -220,6 +223,7 @@ static tuple<vector<string>, bytes, string> userInputToCode(string const& _user,
 			errors.push_back("Solidity: Uncaught exception");
 		}
 	}
+#endif
 #if ETH_SERPENT
 	else if (sourceIsSerpent(_user))
 	{
@@ -394,6 +398,7 @@ void Transact::on_send_clicked()
 		// If execution is a contract creation, add Natspec to
 		// a local Natspec LEVELDB
 		ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice());
+#if ETH_SOLIDITY
 		string src = ui->data->toPlainText().toStdString();
 		if (sourceIsSolidity(src))
 			try
@@ -407,6 +412,7 @@ void Transact::on_send_clicked()
 				}
 			}
 			catch (...) {}
+#endif
 	}
 	else
 		ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice());
diff --git a/eth/main.cpp b/eth/main.cpp
index 0344e66d6..2d79f4954 100644
--- a/eth/main.cpp
+++ b/eth/main.cpp
@@ -136,6 +136,7 @@ void help()
 		<< "    -G,--opencl  When mining use the GPU via OpenCL." << endl
 		<< "    --opencl-platform <n>  When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
 		<< "    --opencl-device <n>  When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
+		<< "    -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
 		<< "Client networking:" << endl
 		<< "    --client-name <name>  Add a name to your client's version string (default: blank)." << endl
 		<< "    -b,--bootstrap  Connect to the default Ethereum peerserver." << endl
@@ -370,7 +371,7 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
 			for (unsigned i = 0; !completed; ++i)
 			{
 				if (current)
-					cnote << "Mining on PoWhash" << current.headerHash.abridged() << ": " << f.miningProgress();
+					cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress();
 				else
 					cnote << "Getting work package...";
 				Json::Value v = rpc.eth_getWork();
@@ -380,12 +381,12 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
 					current.headerHash = hh;
 					current.seedHash = h256(v[1].asString());
 					current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight);
-					cnote << "Got work package:" << current.headerHash.abridged() << " < " << current.boundary;
+					cnote << "Got work package:" << current.headerHash << " < " << current.boundary;
 					f.setWork(current);
 				}
 				this_thread::sleep_for(chrono::milliseconds(_recheckPeriod));
 			}
-			cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash.abridged() << "," << solution.mixHash.abridged() << "] to" << _remote << "...";
+			cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "...";
 			bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash));
 			if (ok)
 				clog(HappyChannel) << "Submitted and accepted.";
@@ -405,6 +406,72 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod)
 
 int main(int argc, char** argv)
 {
+	cout << "\x1b[30mEthBlack\x1b[0m" << endl;
+	cout << "\x1b[90mEthCoal\x1b[0m" << endl;
+	cout << "\x1b[37mEthGray\x1b[0m" << endl;
+	cout << "\x1b[97mEthWhite\x1b[0m" << endl;
+	cout << "\x1b[31mEthRed\x1b[0m" << endl;
+	cout << "\x1b[32mEthGreen\x1b[0m" << endl;
+	cout << "\x1b[33mEthYellow\x1b[0m" << endl;
+	cout << "\x1b[34mEthBlue\x1b[0m" << endl;
+	cout << "\x1b[35mEthPurple\x1b[0m" << endl;
+	cout << "\x1b[36mEthCyan\x1b[0m" << endl;
+	// High Intensity
+	cout << "\x1b[91mEthRedI\x1b[0m" << endl;
+	cout << "\x1b[92mEthLime\x1b[0m" << endl;
+	cout << "\x1b[93mEthYellowI\x1b[0m" << endl;
+	cout << "\x1b[94mEthBlueI\x1b[0m" << endl;
+	cout << "\x1b[95mEthPurpleI\x1b[0m" << endl;
+	cout << "\x1b[96mEthCyanI\x1b[0m" << endl;
+
+	// Bold
+	cout << "\x1b[1;30mEthBlackB\x1b[0m" << endl;
+	cout << "\x1b[1;90mEthCoalB\x1b[0m" << endl;
+	cout << "\x1b[1;37mEthGrayB\x1b[0m" << endl;
+	cout << "\x1b[1;97mEthWhiteB\x1b[0m" << endl;
+	cout << "\x1b[1;31mEthRedB\x1b[0m" << endl;
+	cout << "\x1b[1;32mEthGreenB\x1b[0m" << endl;
+	cout << "\x1b[1;33mEthYellowB\x1b[0m" << endl;
+	cout << "\x1b[1;34mEthBlueB\x1b[0m" << endl;
+	cout << "\x1b[1;35mEthPurpleB\x1b[0m" << endl;
+	cout << "\x1b[1;36mEthCyanB\x1b[0m" << endl;
+	// Bold High Intensity
+	cout << "\x1b[1;91mEthRedBI\x1b[0m" << endl;
+	cout << "\x1b[1;92mEthGreenBI\x1b[0m" << endl;
+	cout << "\x1b[1;93mEthYellowBI\x1b[0m" << endl;
+	cout << "\x1b[1;94mEthBlueBI\x1b[0m" << endl;
+	cout << "\x1b[1;95mEthPurpleBI\x1b[0m" << endl;
+	cout << "\x1b[1;96mEthCyanBI\x1b[0m" << endl;
+
+	// Background
+	cout << "\x1b[40mEthBlackOn\x1b[0m" << endl;
+	cout << "\x1b[100mEthCoalOn\x1b[0m" << endl;
+	cout << "\x1b[47mEthGrayOn\x1b[0m" << endl;
+	cout << "\x1b[107mEthWhiteOn\x1b[0m" << endl;
+	cout << "\x1b[41mEthRedOn\x1b[0m" << endl;
+	cout << "\x1b[42mEthGreenOn\x1b[0m" << endl;
+	cout << "\x1b[43mEthYellowOn\x1b[0m" << endl;
+	cout << "\x1b[44mEthBlueOn\x1b[0m" << endl;
+	cout << "\x1b[45mEthPurpleOn\x1b[0m" << endl;
+	cout << "\x1b[46mEthCyanOn\x1b[0m" << endl;
+	// High Intensity backgrounds
+	cout << "\x1b[101mEthRedOnI\x1b[0m" << endl;
+	cout << "\x1b[102mEthGreenOnI\x1b[0m" << endl;
+	cout << "\x1b[103mEthYellowOnI\x1b[0m" << endl;
+	cout << "\x1b[104mEthBlueOnI\x1b[0m" << endl;
+	cout << "\x1b[105mEthPurpleOnI\x1b[0m" << endl;
+	cout << "\x1b[106mEthCyanOnI\x1b[0m" << endl;
+
+	// Underline
+	cout << "\x1b[4;30mEthBlackU\x1b[0m" << endl;
+	cout << "\x1b[4;31mEthRedU\x1b[0m" << endl;
+	cout << "\x1b[4;32mEthGreenU\x1b[0m" << endl;
+	cout << "\x1b[4;33mEthYellowU\x1b[0m" << endl;
+	cout << "\x1b[4;34mEthBlueU\x1b[0m" << endl;
+	cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl;
+	cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl;
+	cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl;
+
 	// Init defaults
 	Defaults::get();
 
@@ -416,6 +483,7 @@ int main(int argc, char** argv)
 	MinerType minerType = MinerType::CPU;
 	unsigned openclPlatform = 0;
 	unsigned openclDevice = 0;
+	unsigned miningThreads = UINT_MAX;
 
 	/// File name for import/export.
 	string filename;
@@ -534,13 +602,13 @@ int main(int argc, char** argv)
 			}
 		else if (arg == "--opencl-platform" && i + 1 < argc)
 			try {
-			openclPlatform= stol(argv[++i]);
-		}
-		catch (...)
-		{
-			cerr << "Bad " << arg << " option: " << argv[i] << endl;
-			return -1;
-		}
+				openclPlatform = stol(argv[++i]);
+			}
+			catch (...)
+			{
+				cerr << "Bad " << arg << " option: " << argv[i] << endl;
+				return -1;
+			}
 		else if (arg == "--opencl-device" && i + 1 < argc)
 			try {
 				openclDevice = stol(argv[++i]);
@@ -784,6 +852,17 @@ int main(int argc, char** argv)
 					return -1;
 				}
 		}
+		else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc)
+		{
+			try {
+				miningThreads = stol(argv[++i]);
+			}
+			catch (...)
+			{
+				cerr << "Bad " << arg << " option: " << argv[i] << endl;
+				return -1;
+			}
+		}
 		else if (arg == "-b" || arg == "--bootstrap")
 			bootstrap = true;
 		else if (arg == "-f" || arg == "--force-mining")
@@ -839,8 +918,16 @@ int main(int argc, char** argv)
 	if (sessionSecret)
 		sigKey = KeyPair(sessionSecret);
 
-	ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform);
-	ProofOfWork::GPUMiner::setDefaultDevice(openclDevice);
+	
+
+	if (minerType == MinerType::CPU)
+		ProofOfWork::CPUMiner::setNumInstances(miningThreads);
+	else if (minerType == MinerType::GPU)
+	{
+		ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform);
+		ProofOfWork::GPUMiner::setDefaultDevice(openclDevice);
+		ProofOfWork::GPUMiner::setNumInstances(miningThreads);
+	}
 
 	// Two codepaths is necessary since named block require database, but numbered
 	// blocks are superuseful to have when database is already open in another process.
@@ -860,7 +947,7 @@ int main(int argc, char** argv)
 	VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
 	auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
 	auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp");
-	std::string clientImplString = "Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
+	std::string clientImplString = "++eth/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
 	dev::WebThreeDirect web3(
 		clientImplString,
 		dbPath,
diff --git a/exp/main.cpp b/exp/main.cpp
index 20f287f43..366c5b2ff 100644
--- a/exp/main.cpp
+++ b/exp/main.cpp
@@ -22,7 +22,14 @@
 #if ETH_ETHASHCL
 #define __CL_ENABLE_EXCEPTIONS
 #define CL_USE_DEPRECATED_OPENCL_2_0_APIS
-#include "libethash-cl/cl.hpp"
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#include <libethash-cl/cl.hpp>
+#pragma clang diagnostic pop
+#else
+#include <libethash-cl/cl.hpp>
+#endif
 #endif
 #include <functional>
 #include <boost/filesystem.hpp>
diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp
index 1f0d188fa..f27637dec 100644
--- a/libdevcore/Common.cpp
+++ b/libdevcore/Common.cpp
@@ -27,7 +27,7 @@ using namespace dev;
 namespace dev
 {
 
-char const* Version = "0.9.12";
+char const* Version = "0.9.13";
 
 }
 
diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h
index 478383b25..80334fa31 100644
--- a/libdevcore/CommonIO.h
+++ b/libdevcore/CommonIO.h
@@ -77,7 +77,11 @@ template <class T, class U> inline std::ostream& operator<<(std::ostream& _out,
 template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e);
 template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p);
 
+#ifdef _WIN32
+template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%Y-%m-%d %H:%M:%S")
+#else
 template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%F %T")
+#endif
 {
 	unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(_e.time_since_epoch()).count();
 	auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch);
diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp
index 0edc3e039..983431b88 100644
--- a/libdevcore/Log.cpp
+++ b/libdevcore/Log.cpp
@@ -28,10 +28,47 @@
 using namespace std;
 using namespace dev;
 
+//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙
+
 // Logging
 int dev::g_logVerbosity = 5;
 map<type_info const*, bool> dev::g_logOverride;
 
+#ifdef _WIN32
+const char* LogChannel::name() { return EthGray "..."; }
+const char* LeftChannel::name() { return EthNavy "<--"; }
+const char* RightChannel::name() { return EthGreen "-->"; }
+const char* WarnChannel::name() { return EthOnRed EthBlackBold "  X"; }
+const char* NoteChannel::name() { return EthBlue "  i"; }
+const char* DebugChannel::name() { return EthWhite "  D"; }
+#else
+const char* LogChannel::name() { return EthGray "···"; }
+const char* LeftChannel::name() { return EthNavy "◀▬▬"; }
+const char* RightChannel::name() { return EthGreen "▬▬▶"; }
+const char* WarnChannel::name() { return EthOnRed EthBlackBold "  ✘"; }
+const char* NoteChannel::name() { return EthBlue "  ℹ"; }
+const char* DebugChannel::name() { return EthWhite "  ◇"; }
+#endif
+
+LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing):
+	m_autospacing(_autospacing),
+	m_verbosity(_v)
+{
+	auto it = g_logOverride.find(_info);
+	if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && (int)_v <= g_logVerbosity))
+	{
+		time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+		char buf[24];
+		if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
+			buf[0] = '\0'; // empty if case strftime fails
+		static char const* c_begin = "  " EthViolet;
+		static char const* c_sep1 = EthReset EthBlack "|" EthNavy;
+		static char const* c_sep2 = EthReset EthBlack "|" EthTeal;
+		static char const* c_end = EthReset "  ";
+		m_sstr << _id << c_begin << buf << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end;
+	}
+}
+
 /// Associate a name with each thread for nice logging.
 struct ThreadLocalLogName
 {
diff --git a/libdevcore/Log.h b/libdevcore/Log.h
index 812ec0886..71c2b3450 100644
--- a/libdevcore/Log.h
+++ b/libdevcore/Log.h
@@ -26,8 +26,13 @@
 #include <ctime>
 #include <chrono>
 #include <boost/thread.hpp>
+#include <boost/asio.hpp>
 #include "vector_ref.h"
+#include "Common.h"
 #include "CommonIO.h"
+#include "CommonData.h"
+#include "FixedHash.h"
+#include "Terminal.h"
 
 namespace dev
 {
@@ -74,42 +79,129 @@ std::string getThreadName();
 
 /// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ).
 /// Channels should inherit from LogChannel and define name() and verbosity.
-struct LogChannel { static const char* name() { return "   "; } static const int verbosity = 1; };
-struct LeftChannel: public LogChannel  { static const char* name() { return "<<<"; } };
-struct RightChannel: public LogChannel { static const char* name() { return ">>>"; } };
-struct WarnChannel: public LogChannel  { static const char* name() { return "!!!"; } static const int verbosity = 0; };
-struct NoteChannel: public LogChannel  { static const char* name() { return "***"; } };
-struct DebugChannel: public LogChannel { static const char* name() { return "---"; } static const int verbosity = 0; };
+struct LogChannel { static const char* name(); static const int verbosity = 1; };
+struct LeftChannel: public LogChannel { static const char* name(); };
+struct RightChannel: public LogChannel { static const char* name(); };
+struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
+struct NoteChannel: public LogChannel { static const char* name(); };
+struct DebugChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
+
+enum LogTag
+{
+	None,
+	url,
+	error
+};
 
-/// Logging class, iostream-like, that can be shifted to.
-template <class Id, bool _AutoSpacing = true>
-class LogOutputStream
+class LogOutputStreamBase
 {
 public:
-	/// Construct a new object.
-	/// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character.
-	LogOutputStream(bool _term = true)
+	LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing);
+
+	void comment(std::string const& _t)
+	{
+		switch (m_logTag)
+		{
+		case url: m_sstr << EthNavyUnder; break;
+		case error: m_sstr << EthRedBold; break;
+		default:;
+		}
+		m_sstr << _t << EthReset;
+		m_logTag = None;
+	}
+
+	void append(unsigned long _t) { m_sstr << EthBlue << _t << EthReset; }
+	void append(long _t) { m_sstr << EthBlue << _t << EthReset; }
+	void append(unsigned int _t) { m_sstr << EthBlue << _t << EthReset; }
+	void append(int _t) { m_sstr << EthBlue << _t << EthReset; }
+	void append(bigint const& _t) { m_sstr << EthNavy << _t << EthReset; }
+	void append(u256 const& _t) { m_sstr << EthNavy << _t << EthReset; }
+	void append(u160 const& _t) { m_sstr << EthNavy << _t << EthReset; }
+	void append(double _t) { m_sstr << EthBlue << _t << EthReset; }
+	template <unsigned N> void append(FixedHash<N> const& _t) { m_sstr << EthTeal "#" << _t.abridged() << EthReset; }
+	void append(h160 const& _t) { m_sstr << EthRed "@" << _t.abridged() << EthReset; }
+	void append(h256 const& _t) { m_sstr << EthCyan "#" << _t.abridged() << EthReset; }
+	void append(h512 const& _t) { m_sstr << EthTeal "##" << _t.abridged() << EthReset; }
+	void append(std::string const& _t) { m_sstr << EthGreen "\"" + _t + "\"" EthReset; }
+	void append(bytes const& _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; }
+	void append(bytesConstRef _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; }
+	template <class T> void append(std::vector<T> const& _t)
+	{
+		m_sstr << EthWhite "[" EthReset;
+		int n = 0;
+		for (auto const& i: _t)
+		{
+			m_sstr << (n++ ? EthWhite ", " EthReset : "");
+			append(i);
+		}
+		m_sstr << EthWhite "]" EthReset;
+	}
+	template <class T> void append(std::set<T> const& _t)
+	{
+		m_sstr << EthYellow "{" EthReset;
+		int n = 0;
+		for (auto const& i: _t)
+		{
+			m_sstr << (n++ ? EthYellow ", " EthReset : "");
+			append(i);
+		}
+		m_sstr << EthYellow "}" EthReset;
+	}
+	template <class T, class U> void append(std::map<T, U> const& _t)
 	{
-		std::type_info const* i = &typeid(Id);
-		auto it = g_logOverride.find(i);
-		if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && Id::verbosity <= g_logVerbosity))
+		m_sstr << EthLime "{" EthReset;
+		int n = 0;
+		for (auto const& i: _t)
 		{
-			time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
-			char buf[24];
-			if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
-				buf[0] = '\0'; // empty if case strftime fails
-			m_sstr << Id::name() << " [ " << buf << " | " << getThreadName() << ThreadContext::join(" | ") << (_term ? " ] " : "");
+			m_sstr << (n++ ? EthLime ", " EthReset : "");
+			append(i.first);
+			m_sstr << (n++ ? EthLime ": " EthReset : "");
+			append(i.second);
 		}
+		m_sstr << EthLime "}" EthReset;
 	}
+	template <class T, class U> void append(std::pair<T, U> const& _t)
+	{
+		m_sstr << EthPurple "(" EthReset;
+		append(_t.first);
+		m_sstr << EthPurple ", " EthReset;
+		append(_t.second);
+		m_sstr << EthPurple ")" EthReset;
+	}
+	template <class T> void append(T const& _t)
+	{
+		m_sstr << toString(_t);
+	}
+	template <class T> void append(boost::asio::ip::tcp::endpoint const& _t)
+	{
+		m_sstr << EthNavyUnder "tcp://" << _t << EthReset;
+	}
+
+protected:
+	bool m_autospacing = false;
+	unsigned m_verbosity = 0;
+	std::stringstream m_sstr;	///< The accrued log entry.
+	LogTag m_logTag;
+};
+
+/// Logging class, iostream-like, that can be shifted to.
+template <class Id, bool _AutoSpacing = true>
+class LogOutputStream: LogOutputStreamBase
+{
+public:
+	/// Construct a new object.
+	/// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character.
+	LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity, _AutoSpacing) {}
 
 	/// Destructor. Posts the accrued log entry to the g_logPost function.
 	~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(m_sstr.str(), Id::name()); }
 
-	/// Shift arbitrary data to the log. Spaces will be added between items as required.
-	template <class T> LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; m_sstr << _t; } return *this; }
+	LogOutputStream& operator<<(std::string const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; comment(_t); } return *this; }
 
-private:
-	std::stringstream m_sstr;	///< The accrued log entry.
+	LogOutputStream& operator<<(LogTag _t) { m_logTag = _t; return *this; }
+
+	/// Shift arbitrary data to the log. Spaces will be added between items as required.
+	template <class T> LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; append(_t); } return *this; }
 };
 
 // Simple cout-like stream objects for accessing common log channels.
diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp
index 25e843c77..846664cfd 100644
--- a/libdevcore/RLP.cpp
+++ b/libdevcore/RLP.cpp
@@ -166,6 +166,9 @@ unsigned RLP::length() const
 	{
 		if ((int)m_data.size() <= n - c_rlpDataIndLenZero)
 			BOOST_THROW_EXCEPTION(BadRLP());
+		if ((int)m_data.size() > 1)
+			if (m_data[1] == 0)
+				BOOST_THROW_EXCEPTION(BadRLP());
 		for (int i = 0; i < n - c_rlpDataIndLenZero; ++i)
 			ret = (ret << 8) | m_data[i + 1];
 	}
@@ -175,6 +178,9 @@ unsigned RLP::length() const
 	{
 		if ((int)m_data.size() <= n - c_rlpListIndLenZero)
 			BOOST_THROW_EXCEPTION(BadRLP());
+		if ((int)m_data.size() > 1)
+			if (m_data[1] == 0)
+				BOOST_THROW_EXCEPTION(BadRLP());
 		for (int i = 0; i < n - c_rlpListIndLenZero; ++i)
 			ret = (ret << 8) | m_data[i + 1];
 	}
diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h
index c99d1a358..ac5e2ef1e 100644
--- a/libdevcore/RLP.h
+++ b/libdevcore/RLP.h
@@ -308,7 +308,7 @@ private:
 	/// Single-byte data payload.
 	bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; }
 
-	/// @returns the bytes used to encode the length of the data. Valid for all types.
+	/// @returns the amount of bytes used to encode the length of the data. Valid for all types.
 	unsigned lengthSize() const { if (isData() && m_data[0] > c_rlpDataIndLenZero) return m_data[0] - c_rlpDataIndLenZero; if (isList() && m_data[0] > c_rlpListIndLenZero) return m_data[0] - c_rlpListIndLenZero; return 0; }
 
 	/// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data.
diff --git a/libdevcore/Terminal.h b/libdevcore/Terminal.h
new file mode 100644
index 000000000..a30a527f2
--- /dev/null
+++ b/libdevcore/Terminal.h
@@ -0,0 +1,148 @@
+#pragma once
+
+namespace dev
+{
+namespace con
+{
+
+#ifdef _WIN32
+
+#define EthReset ""       // Text Reset
+
+#define EthReset ""       // Text Reset
+
+	// Regular Colors
+#define EthBlack	""    // Black
+#define EthCoal		""    // Black
+#define EthGray		""    // White
+#define EthWhite	""    // White
+#define EthMaroon	""    // Red
+#define EthRed		""    // Red
+#define EthGreen	""    // Green
+#define EthLime		""    // Green
+#define EthOrange	""    // Yellow
+#define EthYellow	""    // Yellow
+#define EthNavy		""    // Blue
+#define EthBlue		""    // Blue
+#define EthViolet	""    // Purple
+#define EthPurple	""    // Purple
+#define EthTeal		""    // Cyan
+#define EthCyan		""    // Cyan
+
+#define EthBlackBold	""      // Black
+#define EthCoalBold		""      // Black
+#define EthGrayBold		""      // White
+#define EthWhiteBold	""      // White
+#define EthMaroonBold	""      // Red
+#define EthRedBold		""      // Red
+#define EthGreenBold	""      // Green
+#define EthLimeBold		""      // Green
+#define EthOrangeBold	""      // Yellow
+#define EthYellowBold	""      // Yellow
+#define EthNavyBold		""      // Blue
+#define EthBlueBold		""      // Blue
+#define EthVioletBold	""      // Purple
+#define EthPurpleBold	""      // Purple
+#define EthTealBold		""      // Cyan
+#define EthCyanBold		""      // Cyan
+
+	// Background
+#define EthOnBlack		""       // Black
+#define EthOnCoal		""		 // Black
+#define EthOnGray		""       // White
+#define EthOnWhite		""		 // White
+#define EthOnMaroon		""       // Red
+#define EthOnRed		""       // Red
+#define EthOnGreen		""       // Green
+#define EthOnLime		""		 // Green
+#define EthOnOrange		""       // Yellow
+#define EthOnYellow		""		 // Yellow
+#define EthOnNavy		""       // Blue
+#define EthOnBlue		""		 // Blue
+#define EthOnViolet		""       // Purple
+#define EthOnPurple		""		 // Purple
+#define EthOnTeal		""       // Cyan
+#define EthOnCyan		""		 // Cyan
+
+	// Underline
+#define EthBlackUnder	""       // Black
+#define EthGrayUnder	""       // White
+#define EthMaroonUnder	""       // Red
+#define EthGreenUnder	""       // Green
+#define EthOrangeUnder	""       // Yellow
+#define EthNavyUnder	""       // Blue
+#define EthVioletUnder	""       // Purple
+#define EthTealUnder	""       // Cyan
+
+#else
+
+#define EthReset "\x1b[0m"       // Text Reset
+
+// Regular Colors
+#define EthBlack "\x1b[30m"        // Black
+#define EthCoal "\x1b[90m"       // Black
+#define EthGray "\x1b[37m"        // White
+#define EthWhite "\x1b[97m"       // White
+#define EthMaroon "\x1b[31m"          // Red
+#define EthRed "\x1b[91m"         // Red
+#define EthGreen "\x1b[32m"        // Green
+#define EthLime "\x1b[92m"       // Green
+#define EthOrange "\x1b[33m"       // Yellow
+#define EthYellow "\x1b[93m"      // Yellow
+#define EthNavy "\x1b[34m"         // Blue
+#define EthBlue "\x1b[94m"        // Blue
+#define EthViolet "\x1b[35m"       // Purple
+#define EthPurple "\x1b[95m"      // Purple
+#define EthTeal "\x1b[36m"         // Cyan
+#define EthCyan "\x1b[96m"        // Cyan
+
+#define EthBlackBold "\x1b[1;30m"       // Black
+#define EthCoalBold "\x1b[1;90m"      // Black
+#define EthGrayBold "\x1b[1;37m"       // White
+#define EthWhiteBold "\x1b[1;97m"      // White
+#define EthMaroonBold "\x1b[1;31m"         // Red
+#define EthRedBold "\x1b[1;91m"        // Red
+#define EthGreenBold "\x1b[1;32m"       // Green
+#define EthLimeBold "\x1b[1;92m"      // Green
+#define EthOrangeBold "\x1b[1;33m"      // Yellow
+#define EthYellowBold "\x1b[1;93m"     // Yellow
+#define EthNavyBold "\x1b[1;34m"        // Blue
+#define EthBlueBold "\x1b[1;94m"       // Blue
+#define EthVioletBold "\x1b[1;35m"      // Purple
+#define EthPurpleBold "\x1b[1;95m"     // Purple
+#define EthTealBold "\x1b[1;36m"        // Cyan
+#define EthCyanBold "\x1b[1;96m"       // Cyan
+
+// Background
+#define EthOnBlack "\x1b[40m"       // Black
+#define EthOnCoal "\x1b[100m"   // Black
+#define EthOnGray "\x1b[47m"       // White
+#define EthOnWhite "\x1b[107m"   // White
+#define EthOnMaroon "\x1b[41m"         // Red
+#define EthOnRed "\x1b[101m"     // Red
+#define EthOnGreen "\x1b[42m"       // Green
+#define EthOnLime "\x1b[102m"   // Green
+#define EthOnOrange "\x1b[43m"      // Yellow
+#define EthOnYellow "\x1b[103m"  // Yellow
+#define EthOnNavy "\x1b[44m"        // Blue
+#define EthOnBlue "\x1b[104m"    // Blue
+#define EthOnViolet "\x1b[45m"      // Purple
+#define EthOnPurple "\x1b[105m"  // Purple
+#define EthOnTeal "\x1b[46m"        // Cyan
+#define EthOnCyan "\x1b[106m"    // Cyan
+
+// Underline
+#define EthBlackUnder "\x1b[4;30m"       // Black
+#define EthGrayUnder "\x1b[4;37m"       // White
+#define EthMaroonUnder "\x1b[4;31m"      // Red
+#define EthGreenUnder "\x1b[4;32m"       // Green
+#define EthOrangeUnder "\x1b[4;33m"      // Yellow
+#define EthNavyUnder "\x1b[4;34m"        // Blue
+#define EthVioletUnder "\x1b[4;35m"      // Purple
+#define EthTealUnder "\x1b[4;36m"        // Cyan
+
+#endif
+
+}
+
+}
diff --git a/libdevcrypto/MemoryDB.cpp b/libdevcrypto/MemoryDB.cpp
index 56b77ddee..a207bb7d6 100644
--- a/libdevcrypto/MemoryDB.cpp
+++ b/libdevcrypto/MemoryDB.cpp
@@ -27,6 +27,9 @@ using namespace dev;
 namespace dev
 {
 
+const char* DBChannel::name() { return "TDB"; }
+const char* DBWarn::name() { return "TDB"; }
+
 std::map<h256, std::string> MemoryDB::get() const
 {
 	if (!m_enforceRefs)
@@ -46,7 +49,7 @@ std::string MemoryDB::lookup(h256 _h) const
 		if (!m_enforceRefs || (m_refCount.count(it->first) && m_refCount.at(it->first)))
 			return it->second;
 //		else if (m_enforceRefs && m_refCount.count(it->first) && !m_refCount.at(it->first))
-//			cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h.abridged();
+//			cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h;
 	}
 	return std::string();
 }
@@ -64,7 +67,7 @@ void MemoryDB::insert(h256 _h, bytesConstRef _v)
 	m_over[_h] = _v.toString();
 	m_refCount[_h]++;
 #if ETH_PARANOIA
-	dbdebug << "INST" << _h.abridged() << "=>" << m_refCount[_h];
+	dbdebug << "INST" << _h << "=>" << m_refCount[_h];
 #endif
 }
 
@@ -79,15 +82,15 @@ bool MemoryDB::kill(h256 _h)
 		{
 			// If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously
 			// used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*.
-			dbdebug << "NOKILL-WAS" << _h.abridged();
+			dbdebug << "NOKILL-WAS" << _h;
 			return false;
 		}
-		dbdebug << "KILL" << _h.abridged() << "=>" << m_refCount[_h];
+		dbdebug << "KILL" << _h << "=>" << m_refCount[_h];
 		return true;
 	}
 	else
 	{
-		dbdebug << "NOKILL" << _h.abridged();
+		dbdebug << "NOKILL" << _h;
 		return false;
 	}
 #else
diff --git a/libdevcrypto/MemoryDB.h b/libdevcrypto/MemoryDB.h
index 7858126f8..58b1339a5 100644
--- a/libdevcrypto/MemoryDB.h
+++ b/libdevcrypto/MemoryDB.h
@@ -31,8 +31,8 @@
 namespace dev
 {
 
-struct DBChannel: public LogChannel  { static const char* name() { return "TDB"; } static const int verbosity = 18; };
-struct DBWarn: public LogChannel  { static const char* name() { return "TDB"; } static const int verbosity = 1; };
+struct DBChannel: public LogChannel  { static const char* name(); static const int verbosity = 18; };
+struct DBWarn: public LogChannel  { static const char* name(); static const int verbosity = 1; };
 
 #define dbdebug clog(DBChannel)
 #define dbwarn clog(DBWarn)
diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp
index 5f8aea667..91f73ad49 100644
--- a/libdevcrypto/OverlayDB.cpp
+++ b/libdevcrypto/OverlayDB.cpp
@@ -103,7 +103,7 @@ void OverlayDB::kill(h256 _h)
 		if (m_db)
 			m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret);
 		if (ret.empty())
-			cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h.abridged();
+			cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h;
 	}
 #else
 	MemoryDB::kill(_h);
diff --git a/libdevcrypto/TrieDB.cpp b/libdevcrypto/TrieDB.cpp
index 6f476c14b..6f84a3e29 100644
--- a/libdevcrypto/TrieDB.cpp
+++ b/libdevcrypto/TrieDB.cpp
@@ -26,3 +26,5 @@ using namespace dev;
 
 h256 const dev::c_shaNull = sha3(rlp(""));
 h256 const dev::EmptyTrie = c_shaNull;
+
+const char* TrieDBChannel::name() { return "-T-"; }
diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h
index f645f15fa..a707c30f0 100644
--- a/libdevcrypto/TrieDB.h
+++ b/libdevcrypto/TrieDB.h
@@ -40,7 +40,7 @@ namespace ldb = leveldb;
 namespace dev
 {
 
-struct TrieDBChannel: public LogChannel  { static const char* name() { return "-T-"; } static const int verbosity = 17; };
+struct TrieDBChannel: public LogChannel  { static const char* name(); static const int verbosity = 17; };
 #define tdebug clog(TrieDBChannel)
 
 struct InvalidTrie: virtual dev::Exception {};
@@ -120,14 +120,14 @@ public:
 		if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out))
 		{
 			if (_out)
-				(*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2  ") << sha3(_r.data()).abridged() << ": " << _r << "\n";
+				(*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2  ") << sha3(_r.data()) << ": " << _r << "\n";
 			if (!isLeaf(_r))						// don't go down leaves
 				descendEntry(_r[1], _keyMask, true, _out, _indent + 1);
 		}
 		else if (_r.isList() && _r.itemCount() == 17)
 		{
 			if (_out)
-				(*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()).abridged() << ": " << _r << "\n";
+				(*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()) << ": " << _r << "\n";
 			for (unsigned i = 0; i < 16; ++i)
 				if (!_r[i].isEmpty())				// 16 branches are allowed to be empty
 					descendEntry(_r[i], _keyMask, false, _out, _indent + 1);
@@ -779,7 +779,7 @@ template <class DB> std::string GenericTrieDB<DB>::atAux(RLP const& _here, Nibbl
 template <class DB> bytes GenericTrieDB<DB>::mergeAt(RLP const& _orig, NibbleSlice _k, bytesConstRef _v, bool _inLine)
 {
 #if ETH_PARANOIA
-	tdebug << "mergeAt " << _orig << _k << sha3(_orig.data()).abridged();
+	tdebug << "mergeAt " << _orig << _k << sha3(_orig.data());
 #endif
 
 	// The caller will make sure that the bytes are inserted properly.
@@ -854,7 +854,7 @@ template <class DB> bytes GenericTrieDB<DB>::mergeAt(RLP const& _orig, NibbleSli
 template <class DB> void GenericTrieDB<DB>::mergeAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k, bytesConstRef _v)
 {
 #if ETH_PARANOIA
-	tdebug << "mergeAtAux " << _orig << _k << sha3(_orig.data()).abridged() << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash<h256>().abridged() : std::string());
+	tdebug << "mergeAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash<h256>() : std::string());
 #endif
 
 	RLP r = _orig;
@@ -902,7 +902,7 @@ template <class DB> std::string GenericTrieDB<DB>::deref(RLP const& _n) const
 template <class DB> bytes GenericTrieDB<DB>::deleteAt(RLP const& _orig, NibbleSlice _k)
 {
 #if ETH_PARANOIA
-	tdebug << "deleteAt " << _orig << _k << sha3(_orig.data()).abridged();
+	tdebug << "deleteAt " << _orig << _k << sha3(_orig.data());
 #endif
 
 	// The caller will make sure that the bytes are inserted properly.
@@ -1009,7 +1009,7 @@ template <class DB> bytes GenericTrieDB<DB>::deleteAt(RLP const& _orig, NibbleSl
 template <class DB> bool GenericTrieDB<DB>::deleteAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k)
 {
 #if ETH_PARANOIA
-	tdebug << "deleteAtAux " << _orig << _k << sha3(_orig.data()).abridged() << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash<h256>().abridged() : std::string());
+	tdebug << "deleteAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash<h256>() : std::string());
 #endif
 
 	bytes b = _orig.isEmpty() ? bytes() : deleteAt(_orig.isList() ? _orig : RLP(node(_orig.toHash<h256>())), _k);
diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp
index 53eabe349..891d3f97d 100644
--- a/libethash-cl/ethash_cl_miner.cpp
+++ b/libethash-cl/ethash_cl_miner.cpp
@@ -85,6 +85,27 @@ std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _devic
 	return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }";
 }
 
+unsigned ethash_cl_miner::get_num_devices(unsigned _platformId)
+{
+	std::vector<cl::Platform> platforms;
+	cl::Platform::get(&platforms);
+	if (platforms.empty())
+	{
+		debugf("No OpenCL platforms found.\n");
+		return 0;
+	}
+
+	std::vector<cl::Device> devices;
+	unsigned platform_num = std::min<unsigned>(_platformId, platforms.size() - 1);
+	platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
+	if (devices.empty())
+	{
+		debugf("No OpenCL devices found.\n");
+		return 0;
+	}
+	return devices.size();
+}
+
 void ethash_cl_miner::finish()
 {
 	if (m_queue())
diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h
index 3046f037b..21635df91 100644
--- a/libethash-cl/ethash_cl_miner.h
+++ b/libethash-cl/ethash_cl_miner.h
@@ -33,6 +33,8 @@ public:
 
 	bool init(ethash_params const& params, std::function<void(void*)> _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0);
 	static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
+	static unsigned get_num_devices(unsigned _platformId = 0);
+
 
 	void finish();
 	void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count);
diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp
index a0ceb389e..56120471b 100644
--- a/libethcore/Common.cpp
+++ b/libethcore/Common.cpp
@@ -34,7 +34,7 @@ namespace eth
 {
 
 const unsigned c_protocolVersion = 60;
-const unsigned c_minorProtocolVersion = 0;
+const unsigned c_minorProtocolVersion = 1;
 const unsigned c_databaseBaseVersion = 9;
 #if ETH_FATDB
 const unsigned c_databaseVersionModifier = 1;
diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp
index 7ff35fd2b..c40ce2625 100644
--- a/libethcore/Ethash.cpp
+++ b/libethcore/Ethash.cpp
@@ -121,6 +121,8 @@ bool Ethash::verify(BlockInfo const& _header)
 	return slow;
 }
 
+unsigned Ethash::CPUMiner::s_numInstances = 1;
+
 void Ethash::CPUMiner::workLoop()
 {
 	auto tid = std::this_thread::get_id();
@@ -264,10 +266,11 @@ private:
 
 unsigned Ethash::GPUMiner::s_platformId = 0;
 unsigned Ethash::GPUMiner::s_deviceId = 0;
+unsigned Ethash::GPUMiner::s_numInstances = 1;
 
 Ethash::GPUMiner::GPUMiner(ConstructionInfo const& _ci):
 	Miner(_ci),
-	Worker("gpuminer"),
+	Worker("gpuminer" + toString(index())),
 	m_hook(new EthashCLHook(this))
 {
 }
@@ -308,7 +311,8 @@ void Ethash::GPUMiner::workLoop()
 
 			auto p = EthashAux::params(m_minerSeed);
 			auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); };
-			m_miner->init(p, cb, 32, s_platformId, s_deviceId);
+			unsigned device = instances() > 0 ? index() : s_deviceId;
+			m_miner->init(p, cb, 32, s_platformId, device);
 		}
 
 		uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
@@ -331,6 +335,11 @@ std::string Ethash::GPUMiner::platformInfo()
 	return ethash_cl_miner::platform_info(s_platformId, s_deviceId);
 }
 
+unsigned Ethash::GPUMiner::getNumDevices()
+{
+	return ethash_cl_miner::get_num_devices(s_platformId);
+}
+
 #endif
 
 }
diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h
index 2bbe7d649..9a66e9865 100644
--- a/libethcore/Ethash.h
+++ b/libethcore/Ethash.h
@@ -78,17 +78,18 @@ public:
 	static bool preVerify(BlockInfo const& _header);
 	static WorkPackage package(BlockInfo const& _header);
 	static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
+	
 
 	class CPUMiner: public Miner, Worker
 	{
 	public:
 		CPUMiner(ConstructionInfo const& _ci): Miner(_ci), Worker("miner" + toString(index())) {}
 
-		static unsigned instances() { return std::thread::hardware_concurrency(); }
+		static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); }
 		static std::string platformInfo();
 		static void setDefaultPlatform(unsigned) {}
 		static void setDefaultDevice(unsigned) {}
-
+		static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); }
 	protected:
 		void kickOff() override
 		{
@@ -100,7 +101,7 @@ public:
 
 	private:
 		void workLoop() override;
-		static unsigned s_deviceId;
+		static unsigned s_numInstances;
 	};
 
 #if ETH_ETHASHCL || !ETH_TRUE
@@ -112,11 +113,13 @@ public:
 		GPUMiner(ConstructionInfo const& _ci);
 		~GPUMiner();
 
-		static unsigned instances() { return 1; }
+		static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; }
 		static std::string platformInfo();
+		static unsigned getNumDevices();
 		static void setDefaultPlatform(unsigned _id) { s_platformId = _id; }
 		static void setDefaultDevice(unsigned _id) { s_deviceId = _id; }
-
+		static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); }
+		
 	protected:
 		void kickOff() override;
 		void pause() override;
@@ -133,6 +136,7 @@ public:
 		h256 m_minerSeed;		///< Last seed in m_miner
 		static unsigned s_platformId;
 		static unsigned s_deviceId;
+		static unsigned s_numInstances;
 	};
 #else
 	using GPUMiner = CPUMiner;
diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp
index 68c5f3057..44064cde6 100644
--- a/libethcore/EthashAux.cpp
+++ b/libethcore/EthashAux.cpp
@@ -75,11 +75,11 @@ h256 EthashAux::seedHash(unsigned _number)
 			n = get()->m_seedHashes.size() - 1;
 		}
 		get()->m_seedHashes.resize(epoch + 1);
-		cdebug << "Searching for seedHash of epoch " << epoch;
+//		cdebug << "Searching for seedHash of epoch " << epoch;
 		for (; n <= epoch; ++n, ret = sha3(ret))
 		{
 			get()->m_seedHashes[n] = ret;
-			cdebug << "Epoch" << n << "is" << ret.abridged();
+//			cdebug << "Epoch" << n << "is" << ret;
 		}
 	}
 	return get()->m_seedHashes[epoch];
@@ -95,12 +95,12 @@ ethash_params EthashAux::params(h256 const& _seedHash)
 	}
 	catch (...)
 	{
-		cdebug << "Searching for seedHash " << _seedHash.abridged();
+//		cdebug << "Searching for seedHash " << _seedHash;
 		for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {}
 		if (epoch == 2048)
 		{
 			std::ostringstream error;
-			error << "apparent block number for " << _seedHash.abridged() << " is too high; max is " << (ETHASH_EPOCH_LENGTH * 2048);
+			error << "apparent block number for " << _seedHash << " is too high; max is " << (ETHASH_EPOCH_LENGTH * 2048);
 			throw std::invalid_argument(error.str());
 		}
 	}
diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp
index 2e089dd3b..fbc92a863 100644
--- a/libethereum/BlockChain.cpp
+++ b/libethereum/BlockChain.cpp
@@ -48,6 +48,18 @@ namespace js = json_spirit;
 #define ETH_CATCH 1
 #define ETH_TIMED_IMPORTS 0
 
+#ifdef _WIN32
+const char* BlockChainDebug::name() { return EthBlue "8" EthWhite " <>"; }
+const char* BlockChainWarn::name() { return EthBlue "8" EthOnRed EthBlackBold " X"; }
+const char* BlockChainNote::name() { return EthBlue "8" EthBlue " i"; }
+const char* BlockChainChat::name() { return EthBlue "8" EthWhite " o"; }
+#else
+const char* BlockChainDebug::name() { return EthBlue "☍" EthWhite " ◇"; }
+const char* BlockChainWarn::name() { return EthBlue "☍" EthOnRed EthBlackBold " ✘"; }
+const char* BlockChainNote::name() { return EthBlue "☍" EthBlue " ℹ"; }
+const char* BlockChainChat::name() { return EthBlue "☍" EthWhite " ◌"; }
+#endif
+
 std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
 {
 	string cmp = toBigEndianString(_bc.currentHash());
@@ -167,6 +179,7 @@ void BlockChain::open(std::string const& _path, WithExisting _we)
 	std::string l;
 	m_extrasDB->Get(m_readOptions, ldb::Slice("best"), &l);
 	m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data();
+	m_lastBlockNumber = number(m_lastBlockHash);
 
 	cnote << "Opened blockchain DB. Latest: " << currentHash();
 }
@@ -177,6 +190,7 @@ void BlockChain::close()
 	delete m_extrasDB;
 	delete m_blocksDB;
 	m_lastBlockHash = m_genesisHash;
+	m_lastBlockNumber = 0;
 	m_details.clear();
 	m_blocks.clear();
 }
@@ -191,8 +205,7 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
 	ProfilerStart("BlockChain_rebuild.log");
 #endif
 
-//	unsigned originalNumber = (unsigned)BlockInfo(oldBlock(m_lastBlockHash)).number;
-	unsigned originalNumber = number();
+	unsigned originalNumber = m_lastBlockNumber;
 
 	// Keep extras DB around, but under a temp name
 	delete m_extrasDB;
@@ -217,8 +230,13 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
 	m_blocksBlooms.clear();
 	m_lastLastHashes.clear();
 	m_lastBlockHash = genesisHash();
+	m_lastBlockNumber = 0;
+
+	m_details[m_lastBlockHash].totalDifficulty = c_genesisDifficulty;
 
-	h256 lastHash = genesisHash();
+	m_extrasDB->Put(m_writeOptions, toSlice(m_lastBlockHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[m_lastBlockHash].rlp()));
+
+	h256 lastHash = m_lastBlockHash;
 	boost::timer t;
 	for (unsigned d = 1; d < originalNumber; ++d)
 	{
@@ -236,11 +254,11 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
 
 			if (bi.parentHash != lastHash)
 			{
-				cwarn << "DISJOINT CHAIN DETECTED; " << bi.hash().abridged() << "#" << d << " -> parent is" << bi.parentHash.abridged() << "; expected" << lastHash.abridged() << "#" << (d - 1);
+				cwarn << "DISJOINT CHAIN DETECTED; " << bi.hash() << "#" << d << " -> parent is" << bi.parentHash << "; expected" << lastHash << "#" << (d - 1);
 				return;
 			}
 			lastHash = bi.hash();
-			import(b, s.db(), ImportRequirements::Default);
+			import(b, s.db(), 0);
 		}
 		catch (...)
 		{
@@ -269,16 +287,6 @@ bool contains(T const& _t, V const& _v)
 	return false;
 }
 
-inline string toString(h256s const& _bs)
-{
-	ostringstream out;
-	out << "[ ";
-	for (auto i: _bs)
-		out << i.abridged() << ", ";
-	out << "]";
-	return out.str();
-}
-
 LastHashes BlockChain::lastHashes(unsigned _n) const
 {
 	Guard l(x_lastLastHashes);
@@ -312,14 +320,14 @@ tuple<h256s, h256s, bool> BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st
 		}
 		catch (dev::eth::UnknownParent)
 		{
-			cwarn << "ODD: Import queue contains block with unknown parent." << boost::current_exception_diagnostic_information();
+			cwarn << "ODD: Import queue contains block with unknown parent." << error << boost::current_exception_diagnostic_information();
 			// NOTE: don't reimport since the queue should guarantee everything in the right order.
 			// Can't continue - chain bad.
 			badBlocks.push_back(BlockInfo::headerHash(block));
 		}
 		catch (Exception const& _e)
 		{
-			cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << diagnostic_information(_e);
+			cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << error << diagnostic_information(_e);
 			// NOTE: don't reimport since the queue should guarantee everything in the right order.
 			// Can't continue - chain  bad.
 			badBlocks.push_back(BlockInfo::headerHash(block));
@@ -400,7 +408,10 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 		auto pdata = pd.rlp();
 		clog(BlockChainDebug) << "Details is returning false despite block known:" << RLP(pdata);
 		auto parentBlock = block(bi.parentHash);
-		clog(BlockChainDebug) << "Block:" << RLP(parentBlock);
+		clog(BlockChainDebug) << "isKnown:" << isKnown(bi.parentHash);
+		clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << bi.number;
+		clog(BlockChainDebug) << "Block:" << BlockInfo(parentBlock);
+		clog(BlockChainDebug) << "RLP:" << RLP(parentBlock);
 		clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE";
 		exit(-1);
 	}
@@ -408,12 +419,12 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 	// Check it's not crazy
 	if (bi.timestamp > (u256)time(0))
 	{
-		clog(BlockChainNote) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")";
+		clog(BlockChainChat) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")";
 		// Block has a timestamp in the future. This is no good.
 		BOOST_THROW_EXCEPTION(FutureTime());
 	}
 
-	clog(BlockChainNote) << "Attempting import of " << bi.hash().abridged() << "...";
+	clog(BlockChainChat) << "Attempting import of " << bi.hash() << "...";
 
 #if ETH_TIMED_IMPORTS
 	preliminaryChecks = t.elapsed();
@@ -476,14 +487,15 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 #endif
 
 		{
+			ReadGuard l1(x_blocks);
 			ReadGuard l2(x_details);
 			ReadGuard l4(x_receipts);
 			ReadGuard l5(x_logBlooms);
-			m_blocksDB->Put(m_writeOptions, toSlice(bi.hash()), (ldb::Slice)ref(_block));
 			m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.hash()].rlp()));
 			m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
 			m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(m_logBlooms[bi.hash()].rlp()));
 			m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(m_receipts[bi.hash()].rlp()));
+			m_blocksDB->Put(m_writeOptions, toSlice(bi.hash()), (ldb::Slice)ref(_block));
 		}
 
 #if ETH_TIMED_IMPORTS
@@ -531,12 +543,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 	{
 		unsigned commonIndex;
 		tie(route, common, commonIndex) = treeRoute(last, bi.hash());
-		{
-			WriteGuard l(x_lastBlockHash);
-			m_lastBlockHash = bi.hash();
-		}
-
-		m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32));
 
 		// Most of the time these two will be equal - only when we're doing a chain revert will they not be
 		if (common != last)
@@ -597,6 +603,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 				m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp()));
 		}
 
+		// FINALLY! change our best hash.
+		{
+			WriteGuard l(x_lastBlockHash);
+			m_lastBlockHash = bi.hash();
+			m_lastBlockNumber = (unsigned)bi.number;
+			m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32));
+		}
+
 		clog(BlockChainNote) << "   Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(route);
 		noteCanonChanged();
 
@@ -609,7 +623,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
 	}
 	else
 	{
-		clog(BlockChainNote) << "   Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << ")";
+		clog(BlockChainChat) << "   Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << ")";
 	}
 
 #if ETH_TIMED_IMPORTS
@@ -687,7 +701,7 @@ void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end)
 
 tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const
 {
-//	cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged();
+//	cdebug << "treeRoute" << _from << "..." << _to;
 	if (!_from || !_to)
 		return make_tuple(h256s(), h256(), 0);
 	h256s ret;
@@ -702,7 +716,7 @@ tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const
 			ret.push_back(from);
 		from = details(from).parent;
 		fn--;
-//		cdebug << "from:" << fn << _from.abridged();
+//		cdebug << "from:" << fn << _from;
 	}
 	h256 to = _to;
 	while (fn < tn)
@@ -711,7 +725,7 @@ tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const
 			back.push_back(to);
 		to = details(to).parent;
 		tn--;
-//		cdebug << "to:" << tn << _to.abridged();
+//		cdebug << "to:" << tn << _to;
 	}
 	for (;; from = details(from).parent, to = details(to).parent)
 	{
@@ -721,7 +735,7 @@ tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const
 			back.push_back(to);
 		fn--;
 		tn--;
-//		cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
+//		cdebug << "from:" << fn << _from << "; to:" << tn << _to;
 		if (from == to)
 			break;
 		if (!from)
@@ -956,14 +970,24 @@ bool BlockChain::isKnown(h256 const& _hash) const
 {
 	if (_hash == m_genesisHash)
 		return true;
-	{
-		ReadGuard l(x_blocks);
-		if (m_blocks.count(_hash))
-			return true;
-	}
-	string d;
-	m_blocksDB->Get(m_readOptions, toSlice(_hash), &d);
-	return !!d.size();
+
+	ETH_READ_GUARDED(x_blocks)
+		if (!m_blocks.count(_hash))
+		{
+			string d;
+			m_blocksDB->Get(m_readOptions, toSlice(_hash), &d);
+			if (d.empty())
+				return false;
+		}
+	ETH_READ_GUARDED(x_details)
+		if (!m_details.count(_hash))
+		{
+			string d;
+			m_extrasDB->Get(m_readOptions, toSlice(_hash, ExtraDetails), &d);
+			if (d.empty())
+				return false;
+		}
+	return true;
 }
 
 bytes BlockChain::block(h256 const& _hash) const
@@ -981,9 +1005,9 @@ bytes BlockChain::block(h256 const& _hash) const
 	string d;
 	m_blocksDB->Get(m_readOptions, toSlice(_hash), &d);
 
-	if (!d.size())
+	if (d.empty())
 	{
-		cwarn << "Couldn't find requested block:" << _hash.abridged();
+		cwarn << "Couldn't find requested block:" << _hash;
 		return bytes();
 	}
 
diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h
index 70a9f93db..e40d928f9 100644
--- a/libethereum/BlockChain.h
+++ b/libethereum/BlockChain.h
@@ -56,10 +56,10 @@ struct AlreadyHaveBlock: virtual Exception {};
 struct UnknownParent: virtual Exception {};
 struct FutureTime: virtual Exception {};
 
-struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; };
-struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; };
-struct BlockChainWarn: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 1; };
-struct BlockChainDebug: public LogChannel { static const char* name() { return "#B#"; } static const int verbosity = 0; };
+struct BlockChainChat: public LogChannel { static const char* name(); static const int verbosity = 5; };
+struct BlockChainNote: public LogChannel { static const char* name(); static const int verbosity = 3; };
+struct BlockChainWarn: public LogChannel { static const char* name(); static const int verbosity = 1; };
+struct BlockChainDebug: public LogChannel { static const char* name(); static const int verbosity = 0; };
 
 // TODO: Move all this Genesis stuff into Genesis.h/.cpp
 std::map<Address, Account> const& genesisState();
@@ -185,7 +185,7 @@ public:
 
 	/// Get a number for the given hash (or the most recent mined if none given). Thread-safe.
 	unsigned number(h256 const& _hash) const { return details(_hash).number; }
-	unsigned number() const { return number(currentHash()); }
+	unsigned number() const { return m_lastBlockNumber; }
 
 	/// Get a given block (RLP format). Thread-safe.
 	h256 currentHash() const { ReadGuard l(x_lastBlockHash); return m_lastBlockHash; }
@@ -315,6 +315,7 @@ private:
 	/// Hash of the last (valid) block on the longest chain.
 	mutable boost::shared_mutex x_lastBlockHash;
 	h256 m_lastBlockHash;
+	unsigned m_lastBlockNumber = 0;
 
 	/// Genesis block info.
 	h256 m_genesisHash;
diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp
index 4fd63aa86..44ddda637 100644
--- a/libethereum/BlockQueue.cpp
+++ b/libethereum/BlockQueue.cpp
@@ -29,12 +29,18 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
+#ifdef _WIN32
+const char* BlockQueueChannel::name() { return EthOrange "[]>"; }
+#else
+const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; }
+#endif
+
 ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs)
 {
 	// Check if we already know this block.
 	h256 h = BlockInfo::headerHash(_block);
 
-	cblockq << "Queuing block" << h.abridged() << "for import...";
+	cblockq << "Queuing block" << h << "for import...";
 
 	UpgradableGuard l(m_lock);
 
@@ -93,7 +99,7 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo
 		else if (!m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.isKnown(bi.parentHash))
 		{
 			// We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on.
-			cblockq << "OK - queued as unknown parent:" << bi.parentHash.abridged();
+			cblockq << "OK - queued as unknown parent:" << bi.parentHash;
 			m_unknown.insert(make_pair(bi.parentHash, make_pair(h, _block.toBytes())));
 			m_unknownSet.insert(h);
 
diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h
index 1932b2f66..adcc6ab39 100644
--- a/libethereum/BlockQueue.h
+++ b/libethereum/BlockQueue.h
@@ -35,7 +35,7 @@ namespace eth
 
 class BlockChain;
 
-struct BlockQueueChannel: public LogChannel { static const char* name() { return "[]Q"; } static const int verbosity = 4; };
+struct BlockQueueChannel: public LogChannel { static const char* name(); static const int verbosity = 4; };
 #define cblockq dev::LogOutputStream<dev::eth::BlockQueueChannel, true>()
 
 struct BlockQueueStatus
diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp
index 7ab4a99f4..408f8ebca 100644
--- a/libethereum/Client.cpp
+++ b/libethereum/Client.cpp
@@ -124,6 +124,18 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r)
 	return _out;
 }
 
+#ifdef _WIN32
+const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; }
+const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; }
+const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; }
+const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; }
+#else
+const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; }
+const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; }
+const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; }
+const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; }
+#endif
+
 Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId):
 	Worker("eth"),
 	m_vc(_dbPath),
@@ -205,20 +217,11 @@ void Client::startedWorking()
 	// TODO: currently it contains keys for *all* blocks. Make it remove old ones.
 	cdebug << "startedWorking()";
 
-	cdebug << m_bc.number() << m_bc.currentHash();
-	cdebug << "Pre:" << m_preMine.info();
-	cdebug << "Post:" << m_postMine.info();
-	cdebug << "Pre:" << m_preMine.info().headerHash(WithoutNonce) << "; Post:" << m_postMine.info().headerHash(WithoutNonce);
-
 	ETH_WRITE_GUARDED(x_preMine)
 		m_preMine.sync(m_bc);
 	ETH_WRITE_GUARDED(x_postMine)
 		ETH_READ_GUARDED(x_preMine)
 			m_postMine = m_preMine;
-
-	cdebug << "Pre:" << m_preMine.info();
-	cdebug << "Post:" << m_postMine.info();
-	cdebug << "Pre:" << m_preMine.info().headerHash(WithoutNonce) << "; Post:" << m_postMine.info().headerHash(WithoutNonce);
 }
 
 void Client::doneWorking()
@@ -295,7 +298,15 @@ static string filtersToString(T const& _fs)
 	ret << "{";
 	unsigned i = 0;
 	for (h256 const& f: _fs)
-		ret << (i++ ? ", " : "") << (f == PendingChangedFilter ? "pending" : f == ChainChangedFilter ? "chain" : f.abridged());
+	{
+		ret << (i++ ? ", " : "");
+		if (f == PendingChangedFilter)
+			ret << url << "pending";
+		else if (f == ChainChangedFilter)
+			ret << url << "chain";
+		else
+			ret << f;
+	}
 	ret << "}";
 	return ret.str();
 }
@@ -479,7 +490,7 @@ void Client::onChainChanged(ImportRoute const& _ir)
 	// insert transactions that we are declaring the dead part of the chain
 	for (auto const& h: _ir.second)
 	{
-		clog(ClientNote) << "Dead block:" << h.abridged();
+		clog(ClientNote) << "Dead block:" << h;
 		for (auto const& t: m_bc.transactions(h))
 		{
 			clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckTransaction::None);
@@ -490,10 +501,10 @@ void Client::onChainChanged(ImportRoute const& _ir)
 	// remove transactions from m_tq nicely rather than relying on out of date nonce later on.
 	for (auto const& h: _ir.first)
 	{
-		clog(ClientChat) << "Live block:" << h.abridged();
+		clog(ClientChat) << "Live block:" << h;
 		for (auto const& th: m_bc.transactionHashes(h))
 		{
-			clog(ClientNote) << "Safely dropping transaction " << th.abridged();
+			clog(ClientNote) << "Safely dropping transaction " << th;
 			m_tq.drop(th);
 		}
 	}
diff --git a/libethereum/Client.h b/libethereum/Client.h
index b1cfaf4ac..d4c55ef55 100644
--- a/libethereum/Client.h
+++ b/libethereum/Client.h
@@ -92,10 +92,10 @@ private:
 	std::array<u256, 9> m_octiles;
 };
 
-struct ClientNote: public LogChannel { static const char* name() { return "*C*"; } static const int verbosity = 2; };
-struct ClientChat: public LogChannel { static const char* name() { return "=C="; } static const int verbosity = 4; };
-struct ClientTrace: public LogChannel { static const char* name() { return "-C-"; } static const int verbosity = 7; };
-struct ClientDetail: public LogChannel { static const char* name() { return " C "; } static const int verbosity = 14; };
+struct ClientNote: public LogChannel { static const char* name(); static const int verbosity = 2; };
+struct ClientChat: public LogChannel { static const char* name(); static const int verbosity = 4; };
+struct ClientTrace: public LogChannel { static const char* name(); static const int verbosity = 7; };
+struct ClientDetail: public LogChannel { static const char* name(); static const int verbosity = 14; };
 
 struct ActivityReport
 {
diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp
index 5ac9f44d9..6092879b9 100644
--- a/libethereum/ClientBase.cpp
+++ b/libethereum/ClientBase.cpp
@@ -31,6 +31,11 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
+const char* WatchChannel::name() { return EthBlue "ℹ" EthWhite "  "; }
+const char* WorkInChannel::name() { return EthOrange "⚒" EthGreen "▬▶"; }
+const char* WorkOutChannel::name() { return EthOrange "⚒" EthNavy "◀▬"; }
+const char* WorkChannel::name() { return EthOrange "⚒" EthWhite "  "; }
+
 State ClientBase::asOf(BlockNumber _h) const
 {
 	if (_h == PendingBlock)
diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h
index 629791b31..531318736 100644
--- a/libethereum/ClientBase.h
+++ b/libethereum/ClientBase.h
@@ -60,11 +60,11 @@ struct ClientWatch
 	mutable std::chrono::system_clock::time_point lastPoll = std::chrono::system_clock::now();
 };
 
-struct WatchChannel: public LogChannel { static const char* name() { return "(o)"; } static const int verbosity = 7; };
+struct WatchChannel: public LogChannel { static const char* name(); static const int verbosity = 7; };
 #define cwatch LogOutputStream<WatchChannel, true>()
-struct WorkInChannel: public LogChannel { static const char* name() { return ">W>"; } static const int verbosity = 16; };
-struct WorkOutChannel: public LogChannel { static const char* name() { return "<W<"; } static const int verbosity = 16; };
-struct WorkChannel: public LogChannel { static const char* name() { return "-W-"; } static const int verbosity = 21; };
+struct WorkInChannel: public LogChannel { static const char* name(); static const int verbosity = 16; };
+struct WorkOutChannel: public LogChannel { static const char* name(); static const int verbosity = 16; };
+struct WorkChannel: public LogChannel { static const char* name(); static const int verbosity = 21; };
 #define cwork LogOutputStream<WorkChannel, true>()
 #define cworkin LogOutputStream<WorkInChannel, true>()
 #define cworkout LogOutputStream<WorkOutChannel, true>()
diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp
index d4ad0ef1d..2d8dbdc16 100644
--- a/libethereum/Executive.cpp
+++ b/libethereum/Executive.cpp
@@ -31,6 +31,8 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
+const char* VMTraceChannel::name() { return "EVM"; }
+
 Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level):
 	m_s(_s),
 	m_lastHashes(_bc.lastHashes((unsigned)_s.info().number - 1)),
@@ -199,8 +201,8 @@ OnOpFunc Executive::simpleTrace()
 		o << "    STORAGE" << endl;
 		for (auto const& i: ext.state().storage(ext.myAddress))
 			o << showbase << hex << i.first << ": " << i.second << endl;
-		dev::LogOutputStream<VMTraceChannel, false>(true) << o.str();
-		dev::LogOutputStream<VMTraceChannel, false>(false) << " | " << dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << dec << vm.gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32" << " ]";
+		dev::LogOutputStream<VMTraceChannel, false>() << o.str();
+		dev::LogOutputStream<VMTraceChannel, false>() << " < " << dec << ext.depth << " : " << ext.myAddress << " : #" << steps << " : " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " : " << dec << vm.gas() << " : -" << dec << gasCost << " : " << newMemSize << "x32" << " >";
 	};
 }
 
diff --git a/libethereum/Executive.h b/libethereum/Executive.h
index c55341cb8..8903fd464 100644
--- a/libethereum/Executive.h
+++ b/libethereum/Executive.h
@@ -35,7 +35,7 @@ class BlockChain;
 class ExtVM;
 struct Manifest;
 
-struct VMTraceChannel: public LogChannel { static const char* name() { return "EVM"; } static const int verbosity = 11; };
+struct VMTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 11; };
 
 /**
  * @brief Message-call/contract-creation executor; useful for executing transactions.
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 19cec8614..ea2834cc1 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -47,6 +47,11 @@ using namespace dev::eth;
 
 static const u256 c_blockReward = 1500 * finney;
 
+const char* StateSafeExceptions::name() { return EthViolet "⚙" EthBlue " ℹ"; }
+const char* StateDetail::name() { return EthViolet "⚙" EthWhite " ◌"; }
+const char* StateTrace::name() { return EthViolet "⚙" EthGray " ◎"; }
+const char* StateChat::name() { return EthViolet "⚙" EthWhite " ◌"; }
+
 OverlayDB State::openDB(std::string _path, WithExisting _we)
 {
 	if (_path.empty())
@@ -663,7 +668,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
 		uncle.verifyParent(uncleParent);
 
 		nonces.insert(uncle.nonce);
-		tdIncrease += uncle.difficulty;
+//		tdIncrease += uncle.difficulty;
 		rewarded.push_back(uncle);
 	}
 
@@ -704,15 +709,15 @@ void State::cleanup(bool _fullCommit)
 		paranoia("immediately before database commit", true);
 
 		// Commit the new trie to disk.
-		cnote << "Committing to disk: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
+		clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
 		m_db.commit();
-		cnote << "Committed: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
+		clog(StateTrace) << "Committed: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
 
 		paranoia("immediately after database commit", true);
 		m_previousBlock = m_currentBlock;
 		m_currentBlock.populateFromParent(m_previousBlock);
 
-		cdebug << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash().abridged();
+		clog(StateTrace) << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash().abridged();
 	}
 	else
 		m_db.rollback();
diff --git a/libethereum/State.h b/libethereum/State.h
index 28b005243..85ca30649 100644
--- a/libethereum/State.h
+++ b/libethereum/State.h
@@ -50,10 +50,10 @@ namespace eth
 class BlockChain;
 class State;
 
-struct StateChat: public LogChannel { static const char* name() { return "-S-"; } static const int verbosity = 4; };
-struct StateTrace: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 7; };
-struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; };
-struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; };
+struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; };
+struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 7; };
+struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; };
+struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; };
 
 enum class BaseState
 {
@@ -161,15 +161,18 @@ public:
 	/// This may be called multiple times and without issue.
 	void commitToMine(BlockChain const& _bc);
 
+	/// @returns true iff commitToMine() has been called without any subsequest transactions added &c.
+	bool isCommittedToMine() const { return m_committedToMine; }
+
 	/// Pass in a solution to the proof-of-work.
-	/// @returns true iff the given nonce is a proof-of-work for this State's block.
+	/// @returns true iff we were previously committed to mining.
 	template <class PoW>
 	bool completeMine(typename PoW::Solution const& _result)
 	{
-		PoW::assignResult(_result, m_currentBlock);
+		if (!m_committedToMine)
+			return false;
 
-	//	if (!m_pow.verify(m_currentBlock))
-	//		return false;
+		PoW::assignResult(_result, m_currentBlock);
 
 		cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << PoW::verify(m_currentBlock);
 
@@ -178,24 +181,6 @@ public:
 		return true;
 	}
 
-	/** Commit to DB and build the final block if the previous call to mine()'s result is completion.
-	 * Typically looks like:
-	 * @code
-	 * while (notYetMined)
-	 * {
-	 * // lock
-	 * commitToMine(_blockChain);  // will call uncommitToMine if a repeat.
-	 * // unlock
-	 * MineInfo info;
-	 * for (info.completed = false; !info.completed; info = mine()) {}
-	 * }
-	 * // lock
-	 * completeMine();
-	 * // unlock
-	 * @endcode
-	 */
-	void completeMine();
-
 	/// Get the complete current block, including valid nonce.
 	/// Only valid after mine() returns true.
 	bytes const& blockData() const { return m_currentBytes; }
@@ -327,6 +312,19 @@ public:
 	void resetCurrent();
 
 private:
+	/** Commit to DB and build the final block if the previous call to mine()'s result is completion.
+	 * Typically looks like:
+	 * @code
+	 * while (notYetMined)
+	 * {
+	 * // lock
+	 * commitToMine(_blockChain);  // will call uncommitToMine if a repeat.
+	 * completeMine();
+	 * // unlock
+	 * @endcode
+	 */
+	void completeMine();
+
 	/// Undo the changes to the state for committing to mine.
 	void uncommitToMine();
 
diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp
index c23fd8db4..a4eb5cee8 100644
--- a/libethereum/TransactionQueue.cpp
+++ b/libethereum/TransactionQueue.cpp
@@ -28,6 +28,8 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
+const char* TransactionQueueChannel::name() { return EthCyan "┉┅▶"; }
+
 ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallback const& _cb, IfDropped _ik)
 {
 	// Check if we already know this transaction.
diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h
index e2d1c3aee..3858949cc 100644
--- a/libethereum/TransactionQueue.h
+++ b/libethereum/TransactionQueue.h
@@ -35,7 +35,7 @@ namespace eth
 
 class BlockChain;
 
-struct TransactionQueueChannel: public LogChannel { static const char* name() { return "->Q"; } static const int verbosity = 4; };
+struct TransactionQueueChannel: public LogChannel { static const char* name(); static const int verbosity = 4; };
 #define ctxq dev::LogOutputStream<dev::eth::TransactionQueueChannel, true>()
 
 enum class IfDropped { Ignore, Retry };
diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp
index ae8567e2a..eac946230 100644
--- a/libevmcore/Assembly.cpp
+++ b/libevmcore/Assembly.cpp
@@ -311,7 +311,7 @@ Assembly& Assembly::optimise(bool _enable)
 	unsigned total = 0;
 	for (unsigned count = 1; count > 0; total += count)
 	{
-		copt << *this;
+		copt << toString(*this);
 		count = 0;
 
 		copt << "Performing control flow analysis...";
diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp
index 7206ec835..f4394b146 100644
--- a/libp2p/Common.cpp
+++ b/libp2p/Common.cpp
@@ -32,6 +32,34 @@ const dev::p2p::Node dev::p2p::UnspecifiedNode = dev::p2p::Node(NodeId(), Unspec
 
 bool dev::p2p::NodeIPEndpoint::test_allowLocal = false;
 
+//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙━┅┉▬
+
+#ifdef _WIN32
+const char* NetWarn::name() { return EthYellow "N" EthRed " X"; }
+const char* NetImpolite::name() { return EthYellow "N" EthRed " !"; }
+const char* NetNote::name() { return EthYellow "N" EthBlue " i"; }
+const char* NetConnect::name() { return EthYellow "N" EthYellow " C"; }
+const char* NetMessageSummary::name() { return EthYellow "N" EthWhite " ."; }
+const char* NetMessageDetail::name() { return EthYellow "N" EthGray " o"; }
+const char* NetTriviaSummary::name() { return EthYellow "N" EthGray " O"; }
+const char* NetTriviaDetail::name() { return EthYellow "N" EthCoal " 0"; }
+const char* NetAllDetail::name() { return EthYellow "N" EthCoal " A"; }
+const char* NetRight::name() { return EthYellow "N" EthGreen "->"; }
+const char* NetLeft::name() { return EthYellow "N" EthNavy "<-"; }
+#else
+const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; }
+const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; }
+const char* NetNote::name() { return EthYellow "⧎" EthBlue " ℹ"; }
+const char* NetConnect::name() { return EthYellow "⧎" EthYellow " ▢"; }
+const char* NetMessageSummary::name() { return EthYellow "⧎" EthWhite " ◌"; }
+const char* NetMessageDetail::name() { return EthYellow "⧎" EthGray " ○"; }
+const char* NetTriviaSummary::name() { return EthYellow "⧎" EthGray " ◎"; }
+const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; }
+const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; }
+const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; }
+const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; }
+#endif
+
 bool p2p::isPublicAddress(std::string const& _addressToCheck)
 {
 	return _addressToCheck.empty() ? false : isPublicAddress(bi::address::from_string(_addressToCheck));
diff --git a/libp2p/Common.h b/libp2p/Common.h
index 691ef7fb3..378064e7d 100644
--- a/libp2p/Common.h
+++ b/libp2p/Common.h
@@ -75,17 +75,17 @@ struct NetworkStartRequired: virtual dev::Exception {};
 struct InvalidPublicIPAddress: virtual dev::Exception {};
 struct InvalidHostIPAddress: virtual dev::Exception {};
 
-struct NetWarn: public LogChannel { static const char* name() { return "!N!"; } static const int verbosity = 0; };
-struct NetNote: public LogChannel { static const char* name() { return "*N*"; } static const int verbosity = 1; };
-struct NetImpolite: public LogChannel { static const char* name() { return "#!*"; } static const int verbosity = 1; };
-struct NetMessageSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 2; };
-struct NetConnect: public LogChannel { static const char* name() { return "+N+"; } static const int verbosity = 10; };
-struct NetMessageDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 5; };
-struct NetTriviaSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 10; };
-struct NetTriviaDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 11; };
-struct NetAllDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 13; };
-struct NetRight: public LogChannel { static const char* name() { return ">N>"; } static const int verbosity = 14; };
-struct NetLeft: public LogChannel { static const char* name() { return "<N<"; } static const int verbosity = 15; };
+struct NetWarn: public LogChannel { static const char* name(); static const int verbosity = 0; };
+struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 1; };
+struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 1; };
+struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 2; };
+struct NetConnect: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NetMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; };
+struct NetTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NetTriviaDetail: public LogChannel { static const char* name(); static const int verbosity = 11; };
+struct NetAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; };
+struct NetRight: public LogChannel { static const char* name(); static const int verbosity = 14; };
+struct NetLeft: public LogChannel { static const char* name(); static const int verbosity = 15; };
 
 enum PacketType
 {
diff --git a/libp2p/Network.cpp b/libp2p/Network.cpp
index 5702fbce7..1c780c5e9 100644
--- a/libp2p/Network.cpp
+++ b/libp2p/Network.cpp
@@ -228,7 +228,7 @@ bi::tcp::endpoint Network::resolveHost(string const& _addr)
 		bi::tcp::resolver r(s_resolverIoService);
 		auto it = r.resolve({split[0], toString(port)}, ec);
 		if (ec)
-			clog(NetWarn) << "Error resolving host address " << _addr << ":" << ec.message();
+			clog(NetWarn) << "Error resolving host address..." << url << _addr << ":" << error << ec.message();
 		else
 			ep = *it;
 	}
diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp
index 1f48d52b7..4f81e42b9 100644
--- a/libp2p/NodeTable.cpp
+++ b/libp2p/NodeTable.cpp
@@ -24,6 +24,20 @@ using namespace std;
 using namespace dev;
 using namespace dev::p2p;
 
+const char* NodeTableWarn::name() { return "!P!"; }
+const char* NodeTableNote::name() { return "*P*"; }
+const char* NodeTableMessageSummary::name() { return "-P-"; }
+const char* NodeTableMessageDetail::name() { return "=P="; }
+const char* NodeTableConnect::name() { return "+P+"; }
+const char* NodeTableEvent::name() { return "+P+"; }
+const char* NodeTableTimer::name() { return "+P+"; }
+const char* NodeTableUpdate::name() { return "+P+"; }
+const char* NodeTableTriviaSummary::name() { return "-P-"; }
+const char* NodeTableTriviaDetail::name() { return "=P="; }
+const char* NodeTableAllDetail::name() { return "=P="; }
+const char* NodeTableEgress::name() { return ">>P"; }
+const char* NodeTableIngress::name() { return "<<P"; }
+
 NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::distance(_src.id,_pubk)) {}
 
 NodeTable::NodeTable(ba::io_service& _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint):
@@ -73,7 +87,7 @@ shared_ptr<NodeEntry> NodeTable::addNode(Node const& _node)
 	// we handle when tcp endpoint is 0 below
 	if (_node.endpoint.address.to_string() == "0.0.0.0")
 	{
-		clog(NodeTableWarn) << "addNode Failed. Invalid UDP address 0.0.0.0 for" << _node.id.abridged();
+		clog(NodeTableWarn) << "addNode Failed. Invalid UDP address" << url << "0.0.0.0" << "for" << _node.id;
 		return move(shared_ptr<NodeEntry>());
 	}
 	
@@ -382,7 +396,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
 	// h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes)
 	if (_packet.size() < h256::size + Signature::size + 1 + 3)
 	{
-		clog(NodeTableWarn) << "Invalid message size from " << _from.address().to_string() << ":" << _from.port();
+		clog(NodeTableTriviaSummary) << "Invalid message size from " << _from.address().to_string() << ":" << _from.port();
 		return;
 	}
 	
@@ -390,7 +404,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
 	h256 hashSigned(sha3(hashedBytes));
 	if (!_packet.cropped(0, h256::size).contentsEqual(hashSigned.asBytes()))
 	{
-		clog(NodeTableWarn) << "Invalid message hash from " << _from.address().to_string() << ":" << _from.port();
+		clog(NodeTableTriviaSummary) << "Invalid message hash from " << _from.address().to_string() << ":" << _from.port();
 		return;
 	}
 	
@@ -402,7 +416,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes
 	Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(signedBytes)));
 	if (!nodeid)
 	{
-		clog(NodeTableWarn) << "Invalid message signature from " << _from.address().to_string() << ":" << _from.port();
+		clog(NodeTableTriviaSummary) << "Invalid message signature from " << _from.address().to_string() << ":" << _from.port();
 		return;
 	}
 	
diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h
index a308883fb..07247462f 100644
--- a/libp2p/NodeTable.h
+++ b/libp2p/NodeTable.h
@@ -416,19 +416,19 @@ struct Neighbours: RLPXDatagram<Neighbours>
 	void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); for (auto n: r[0]) nodes.push_back(Node(n)); ts = r[1].toInt<unsigned>(); }
 };
 
-struct NodeTableWarn: public LogChannel { static const char* name() { return "!P!"; } static const int verbosity = 0; };
-struct NodeTableNote: public LogChannel { static const char* name() { return "*P*"; } static const int verbosity = 1; };
-struct NodeTableMessageSummary: public LogChannel { static const char* name() { return "-P-"; } static const int verbosity = 2; };
-struct NodeTableMessageDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 5; };
-struct NodeTableConnect: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; };
-struct NodeTableEvent: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; };
-struct NodeTableTimer: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; };
-struct NodeTableUpdate: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; };
-struct NodeTableTriviaSummary: public LogChannel { static const char* name() { return "-P-"; } static const int verbosity = 10; };
-struct NodeTableTriviaDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 11; };
-struct NodeTableAllDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 13; };
-struct NodeTableEgress: public LogChannel { static const char* name() { return ">>P"; } static const int verbosity = 14; };
-struct NodeTableIngress: public LogChannel { static const char* name() { return "<<P"; } static const int verbosity = 15; };
+struct NodeTableWarn: public LogChannel { static const char* name(); static const int verbosity = 0; };
+struct NodeTableNote: public LogChannel { static const char* name(); static const int verbosity = 1; };
+struct NodeTableMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 2; };
+struct NodeTableMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; };
+struct NodeTableConnect: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NodeTableEvent: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NodeTableTimer: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NodeTableUpdate: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NodeTableTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; };
+struct NodeTableTriviaDetail: public LogChannel { static const char* name(); static const int verbosity = 11; };
+struct NodeTableAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; };
+struct NodeTableEgress: public LogChannel { static const char* name(); static const int verbosity = 14; };
+struct NodeTableIngress: public LogChannel { static const char* name(); static const int verbosity = 15; };
 
 }
 }
diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp
index bb9af2ef7..8566b4f50 100644
--- a/libp2p/RLPxHandshake.cpp
+++ b/libp2p/RLPxHandshake.cpp
@@ -249,7 +249,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech)
 						bytesRef frame(&m_handshakeInBuffer);
 						if (!m_io->authAndDecryptFrame(frame))
 						{
-							clog(NetWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: decrypt failed";
+							clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: decrypt failed";
 							m_nextState = Error;
 							transition();
 							return;
@@ -258,13 +258,13 @@ void RLPXHandshake::transition(boost::system::error_code _ech)
 						PacketType packetType = (PacketType)(frame[0] == 0x80 ? 0x0 : frame[0]);
 						if (packetType != 0)
 						{
-							clog(NetWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: invalid packet type";
+							clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: invalid packet type";
 							m_nextState = Error;
 							transition();
 							return;
 						}
 
-						clog(NetNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session.";
+						clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session.";
 						RLP rlp(frame.cropped(1), RLP::ThrowOnFail | RLP::FailIfTooSmall);
 						m_host->startPeerSession(m_remote, rlp, m_io, m_socket->remoteEndpoint());
 					}
@@ -279,7 +279,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech)
 		if (!_ec)
 		{
 			if (!m_socket->remoteEndpoint().address().is_unspecified())
-				clog(NetWarn) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)";
+				clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)";
 			cancel();
 		}
 	});
diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp
index cd4bccbf0..363953a20 100644
--- a/libp2p/Session.cpp
+++ b/libp2p/Session.cpp
@@ -48,7 +48,8 @@ Session::Session(Host* _s, RLPXFrameIO* _io, std::shared_ptr<Peer> const& _n, Pe
 
 Session::~Session()
 {
-	ThreadContext tc(info().id.abridged() + " | " + info().clientVersion);
+	ThreadContext tc(info().id.abridged());
+	ThreadContext tc2(info().clientVersion);
 	clog(NetMessageSummary) << "Closing peer session :-(";
 	m_peer->m_lastConnected = m_peer->m_lastAttempted - chrono::seconds(1);
 
@@ -323,7 +324,8 @@ void Session::write()
 	auto self(shared_from_this());
 	ba::async_write(m_socket, ba::buffer(bytes), [this, self](boost::system::error_code ec, std::size_t /*length*/)
 	{
-		ThreadContext tc(info().id.abridged() + " | " + info().clientVersion);
+		ThreadContext tc(info().id.abridged());
+		ThreadContext tc2(info().clientVersion);
 		// must check queue, as write callback can occur following dropped()
 		if (ec)
 		{
@@ -397,7 +399,8 @@ void Session::doRead()
 	auto self(shared_from_this());
 	ba::async_read(m_socket, boost::asio::buffer(m_data, h256::size), [this,self](boost::system::error_code ec, std::size_t length)
 	{
-		ThreadContext tc(info().id.abridged() + " | " + info().clientVersion);
+		ThreadContext tc(info().id.abridged());
+		ThreadContext tc2(info().clientVersion);
 		if (ec && ec.category() != boost::asio::error::get_misc_category() && ec.value() != boost::asio::error::eof)
 		{
 			clog(NetWarn) << "Error reading: " << ec.message();
@@ -433,7 +436,8 @@ void Session::doRead()
 			auto tlen = frameSize + ((16 - (frameSize % 16)) % 16) + h128::size;
 			ba::async_read(m_socket, boost::asio::buffer(m_data, tlen), [this, self, headerRLP, frameSize, tlen](boost::system::error_code ec, std::size_t length)
 			{
-				ThreadContext tc(info().id.abridged() + " | " + info().clientVersion);
+				ThreadContext tc(info().id.abridged());
+				ThreadContext tc2(info().clientVersion);
 				if (ec && ec.category() != boost::asio::error::get_misc_category() && ec.value() != boost::asio::error::eof)
 				{
 					clog(NetWarn) << "Error reading: " << ec.message();
diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp
index 5f681205d..78b83d064 100644
--- a/libsolidity/AST.cpp
+++ b/libsolidity/AST.cpp
@@ -52,6 +52,7 @@ void ContractDefinition::checkTypeRequirements()
 	for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: getBaseContracts())
 		baseSpecifier->checkTypeRequirements();
 
+	checkDuplicateFunctions();
 	checkIllegalOverrides();
 	checkAbstractFunctions();
 	checkAbstractConstructors();
@@ -87,6 +88,7 @@ void ContractDefinition::checkTypeRequirements()
 	for (ASTPointer<VariableDeclaration> const& variable: m_stateVariables)
 		variable->checkTypeRequirements();
 
+	checkExternalTypeClashes();
 	// check for hash collisions in function signatures
 	set<FixedHash<4>> hashes;
 	for (auto const& it: getInterfaceFunctionList())
@@ -131,6 +133,33 @@ FunctionDefinition const* ContractDefinition::getFallbackFunction() const
 	return nullptr;
 }
 
+void ContractDefinition::checkDuplicateFunctions() const
+{
+	/// Checks that two functions with the same name defined in this contract have different
+	/// argument types and that there is at most one constructor.
+	map<string, vector<FunctionDefinition const*>> functions;
+	for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
+		functions[function->getName()].push_back(function.get());
+	if (functions[getName()].size() > 1)
+		BOOST_THROW_EXCEPTION(
+			DeclarationError() <<
+			errinfo_sourceLocation(getLocation()) <<
+			errinfo_comment("More than one constructor defined.")
+		);
+	for (auto const& it: functions)
+	{
+		vector<FunctionDefinition const*> const& overloads = it.second;
+		for (size_t i = 0; i < overloads.size(); ++i)
+			for (size_t j = i + 1; j < overloads.size(); ++j)
+				if (FunctionType(*overloads[i]).hasEqualArgumentTypes(FunctionType(*overloads[j])))
+					BOOST_THROW_EXCEPTION(
+						DeclarationError() <<
+						errinfo_sourceLocation(overloads[j]->getLocation()) <<
+						errinfo_comment("Function with same name and arguments already defined.")
+					);
+	}
+}
+
 void ContractDefinition::checkAbstractFunctions()
 {
 	map<string, bool> functions;
@@ -171,7 +200,7 @@ void ContractDefinition::checkAbstractConstructors()
 			for (auto const& modifier: constructor->getModifiers())
 			{
 				auto baseContract = dynamic_cast<ContractDefinition const*>(
-					modifier->getName()->getReferencedDeclaration()
+					&modifier->getName()->getReferencedDeclaration()
 				);
 				if (baseContract)
 					argumentsNeeded.erase(baseContract);
@@ -181,7 +210,7 @@ void ContractDefinition::checkAbstractConstructors()
 		for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
 		{
 			auto baseContract = dynamic_cast<ContractDefinition const*>(
-				base->getName()->getReferencedDeclaration()
+				&base->getName()->getReferencedDeclaration()
 			);
 			solAssert(baseContract, "");
 			if (!base->getArguments().empty())
@@ -196,7 +225,7 @@ void ContractDefinition::checkIllegalOverrides() const
 {
 	// TODO unify this at a later point. for this we need to put the constness and the access specifier
 	// into the types
-	map<string, FunctionDefinition const*> functions;
+	map<string, vector<FunctionDefinition const*>> functions;
 	map<string, ModifierDefinition const*> modifiers;
 
 	// We search from derived to base, so the stored item causes the error.
@@ -209,28 +238,67 @@ void ContractDefinition::checkIllegalOverrides() const
 			string const& name = function->getName();
 			if (modifiers.count(name))
 				BOOST_THROW_EXCEPTION(modifiers[name]->createTypeError("Override changes function to modifier."));
-			FunctionDefinition const*& override = functions[name];
-			if (!override)
-				override = function.get();
-			else if (override->getVisibility() != function->getVisibility() ||
-					 override->isDeclaredConst() != function->isDeclaredConst() ||
-					 FunctionType(*override) != FunctionType(*function))
-				BOOST_THROW_EXCEPTION(override->createTypeError("Override changes extended function signature."));
+			FunctionType functionType(*function);
+			// function should not change the return type
+			for (FunctionDefinition const* overriding: functions[name])
+			{
+				FunctionType overridingType(*overriding);
+				if (!overridingType.hasEqualArgumentTypes(functionType))
+					continue;
+				if (
+					overriding->getVisibility() != function->getVisibility() ||
+					overriding->isDeclaredConst() != function->isDeclaredConst() ||
+					overridingType != functionType
+				)
+					BOOST_THROW_EXCEPTION(overriding->createTypeError("Override changes extended function signature."));
+			}
+			functions[name].push_back(function.get());
 		}
 		for (ASTPointer<ModifierDefinition> const& modifier: contract->getFunctionModifiers())
 		{
 			string const& name = modifier->getName();
-			if (functions.count(name))
-				BOOST_THROW_EXCEPTION(functions[name]->createTypeError("Override changes modifier to function."));
 			ModifierDefinition const*& override = modifiers[name];
 			if (!override)
 				override = modifier.get();
 			else if (ModifierType(*override) != ModifierType(*modifier))
 				BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier signature."));
+			if (!functions[name].empty())
+				BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier to function."));
 		}
 	}
 }
 
+void ContractDefinition::checkExternalTypeClashes() const
+{
+	map<string, vector<pair<Declaration const*, shared_ptr<FunctionType>>>> externalDeclarations;
+	for (ContractDefinition const* contract: getLinearizedBaseContracts())
+	{
+		for (ASTPointer<FunctionDefinition> const& f: contract->getDefinedFunctions())
+			if (f->isPartOfExternalInterface())
+			{
+				auto functionType = make_shared<FunctionType>(*f);
+				externalDeclarations[functionType->externalSignature(f->getName())].push_back(
+					make_pair(f.get(), functionType)
+				);
+			}
+		for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
+			if (v->isPartOfExternalInterface())
+			{
+				auto functionType = make_shared<FunctionType>(*v);
+				externalDeclarations[functionType->externalSignature(v->getName())].push_back(
+					make_pair(v.get(), functionType)
+				);
+			}
+	}
+	for (auto const& it: externalDeclarations)
+		for (size_t i = 0; i < it.second.size(); ++i)
+			for (size_t j = i + 1; j < it.second.size(); ++j)
+				if (!it.second[i].second->hasEqualArgumentTypes(*it.second[j].second))
+					BOOST_THROW_EXCEPTION(it.second[j].first->createTypeError(
+						"Function overload clash during conversion to external types for arguments."
+					));
+}
+
 std::vector<ASTPointer<EventDefinition>> const& ContractDefinition::getInterfaceEvents() const
 {
 	if (!m_interfaceEvents)
@@ -253,16 +321,21 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
 	if (!m_interfaceFunctionList)
 	{
 		set<string> functionsSeen;
+		set<string> signaturesSeen;
 		m_interfaceFunctionList.reset(new vector<pair<FixedHash<4>, FunctionTypePointer>>());
 		for (ContractDefinition const* contract: getLinearizedBaseContracts())
 		{
 			for (ASTPointer<FunctionDefinition> const& f: contract->getDefinedFunctions())
-				if (functionsSeen.count(f->getName()) == 0 && f->isPartOfExternalInterface())
+			{
+				string functionSignature = f->externalSignature();
+				if (f->isPartOfExternalInterface() && signaturesSeen.count(functionSignature) == 0)
 				{
 					functionsSeen.insert(f->getName());
-					FixedHash<4> hash(dev::sha3(f->externalSignature()));
+					signaturesSeen.insert(functionSignature);
+					FixedHash<4> hash(dev::sha3(functionSignature));
 					m_interfaceFunctionList->push_back(make_pair(hash, make_shared<FunctionType>(*f, false)));
 				}
+			}
 
 			for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
 				if (functionsSeen.count(v->getName()) == 0 && v->isPartOfExternalInterface())
@@ -314,11 +387,11 @@ TypePointer EnumValue::getType(ContractDefinition const*) const
 
 void InheritanceSpecifier::checkTypeRequirements()
 {
-	m_baseName->checkTypeRequirements();
+	m_baseName->checkTypeRequirements(nullptr);
 	for (ASTPointer<Expression> const& argument: m_arguments)
-		argument->checkTypeRequirements();
+		argument->checkTypeRequirements(nullptr);
 
-	ContractDefinition const* base = dynamic_cast<ContractDefinition const*>(m_baseName->getReferencedDeclaration());
+	ContractDefinition const* base = dynamic_cast<ContractDefinition const*>(&m_baseName->getReferencedDeclaration());
 	solAssert(base, "Base contract not available.");
 	TypePointers parameterTypes = ContractType(*base).getConstructorType()->getParameterTypes();
 	if (!m_arguments.empty() && parameterTypes.size() != m_arguments.size())
@@ -428,7 +501,8 @@ void VariableDeclaration::checkTypeRequirements()
 		if (!m_value)
 			// This feature might be extended in the future.
 			BOOST_THROW_EXCEPTION(createTypeError("Assignment necessary for type detection."));
-		m_value->checkTypeRequirements();
+		m_value->checkTypeRequirements(nullptr);
+
 		TypePointer type = m_value->getType();
 		if (type->getCategory() == Type::Category::IntegerConstant)
 		{
@@ -468,18 +542,22 @@ void ModifierDefinition::checkTypeRequirements()
 
 void ModifierInvocation::checkTypeRequirements(vector<ContractDefinition const*> const& _bases)
 {
-	m_modifierName->checkTypeRequirements();
+	TypePointers argumentTypes;
 	for (ASTPointer<Expression> const& argument: m_arguments)
-		argument->checkTypeRequirements();
+	{
+		argument->checkTypeRequirements(nullptr);
+		argumentTypes.push_back(argument->getType());
+	}
+	m_modifierName->checkTypeRequirements(&argumentTypes);
 
-	auto declaration = m_modifierName->getReferencedDeclaration();
+	auto const* declaration = &m_modifierName->getReferencedDeclaration();
 	vector<ASTPointer<VariableDeclaration>> emptyParameterList;
 	vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
 	if (auto modifier = dynamic_cast<ModifierDefinition const*>(declaration))
 		parameters = &modifier->getParameters();
 	else
 		// check parameters for Base constructors
-		for (auto const* base: _bases)
+		for (ContractDefinition const* base: _bases)
 			if (declaration == base)
 			{
 				if (auto referencedConstructor = base->getConstructor())
@@ -563,9 +641,9 @@ void VariableDeclarationStatement::checkTypeRequirements()
 	m_variable->checkTypeRequirements();
 }
 
-void Assignment::checkTypeRequirements()
+void Assignment::checkTypeRequirements(TypePointers const*)
 {
-	m_leftHandSide->checkTypeRequirements();
+	m_leftHandSide->checkTypeRequirements(nullptr);
 	m_leftHandSide->requireLValue();
 	if (m_leftHandSide->getType()->getCategory() == Type::Category::Mapping)
 		BOOST_THROW_EXCEPTION(createTypeError("Mappings cannot be assigned to."));
@@ -575,7 +653,7 @@ void Assignment::checkTypeRequirements()
 	else
 	{
 		// compound assignment
-		m_rightHandSide->checkTypeRequirements();
+		m_rightHandSide->checkTypeRequirements(nullptr);
 		TypePointer resultType = m_type->binaryOperatorResult(Token::AssignmentToBinaryOp(m_assigmentOperator),
 															  m_rightHandSide->getType());
 		if (!resultType || *resultType != *m_type)
@@ -588,7 +666,7 @@ void Assignment::checkTypeRequirements()
 
 void ExpressionStatement::checkTypeRequirements()
 {
-	m_expression->checkTypeRequirements();
+	m_expression->checkTypeRequirements(nullptr);
 	if (m_expression->getType()->getCategory() == Type::Category::IntegerConstant)
 		if (!dynamic_pointer_cast<IntegerConstantType const>(m_expression->getType())->getIntegerType())
 			BOOST_THROW_EXCEPTION(m_expression->createTypeError("Invalid integer constant."));
@@ -596,7 +674,7 @@ void ExpressionStatement::checkTypeRequirements()
 
 void Expression::expectType(Type const& _expectedType)
 {
-	checkTypeRequirements();
+	checkTypeRequirements(nullptr);
 	Type const& type = *getType();
 	if (!type.isImplicitlyConvertibleTo(_expectedType))
 		BOOST_THROW_EXCEPTION(createTypeError("Type " + type.toString() +
@@ -611,10 +689,10 @@ void Expression::requireLValue()
 	m_lvalueRequested = true;
 }
 
-void UnaryOperation::checkTypeRequirements()
+void UnaryOperation::checkTypeRequirements(TypePointers const*)
 {
 	// Inc, Dec, Add, Sub, Not, BitNot, Delete
-	m_subExpression->checkTypeRequirements();
+	m_subExpression->checkTypeRequirements(nullptr);
 	if (m_operator == Token::Value::Inc || m_operator == Token::Value::Dec || m_operator == Token::Value::Delete)
 		m_subExpression->requireLValue();
 	m_type = m_subExpression->getType()->unaryOperatorResult(m_operator);
@@ -622,10 +700,10 @@ void UnaryOperation::checkTypeRequirements()
 		BOOST_THROW_EXCEPTION(createTypeError("Unary operator not compatible with type."));
 }
 
-void BinaryOperation::checkTypeRequirements()
+void BinaryOperation::checkTypeRequirements(TypePointers const*)
 {
-	m_left->checkTypeRequirements();
-	m_right->checkTypeRequirements();
+	m_left->checkTypeRequirements(nullptr);
+	m_right->checkTypeRequirements(nullptr);
 	m_commonType = m_left->getType()->binaryOperatorResult(m_operator, m_right->getType());
 	if (!m_commonType)
 		BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) +
@@ -635,11 +713,22 @@ void BinaryOperation::checkTypeRequirements()
 	m_type = Token::isCompareOp(m_operator) ? make_shared<BoolType>() : m_commonType;
 }
 
-void FunctionCall::checkTypeRequirements()
+void FunctionCall::checkTypeRequirements(TypePointers const*)
 {
-	m_expression->checkTypeRequirements();
+	bool isPositionalCall = m_names.empty();
+
+	// we need to check arguments' type first as they will be forwarded to
+	// m_expression->checkTypeRequirements
+	TypePointers argumentTypes;
 	for (ASTPointer<Expression> const& argument: m_arguments)
-		argument->checkTypeRequirements();
+	{
+		argument->checkTypeRequirements(nullptr);
+		// only store them for positional calls
+		if (isPositionalCall)
+			argumentTypes.push_back(argument->getType());
+	}
+
+	m_expression->checkTypeRequirements(isPositionalCall ? &argumentTypes : nullptr);
 
 	Type const* expressionType = m_expression->getType().get();
 	if (isTypeConversion())
@@ -649,7 +738,7 @@ void FunctionCall::checkTypeRequirements()
 		// number of non-mapping members
 		if (m_arguments.size() != 1)
 			BOOST_THROW_EXCEPTION(createTypeError("More than one argument for explicit type conversion."));
-		if (!m_names.empty())
+		if (!isPositionalCall)
 			BOOST_THROW_EXCEPTION(createTypeError("Type conversion cannot allow named arguments."));
 		if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType()))
 			BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed."));
@@ -664,8 +753,9 @@ void FunctionCall::checkTypeRequirements()
 		if (!functionType->takesArbitraryParameters() && parameterTypes.size() != m_arguments.size())
 			BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call."));
 
-		if (m_names.empty())
+		if (isPositionalCall)
 		{
+			// call by positional arguments
 			for (size_t i = 0; i < m_arguments.size(); ++i)
 				if (!functionType->takesArbitraryParameters() &&
 						!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]))
@@ -673,6 +763,7 @@ void FunctionCall::checkTypeRequirements()
 		}
 		else
 		{
+			// call by named arguments
 			if (functionType->takesArbitraryParameters())
 				BOOST_THROW_EXCEPTION(createTypeError("Named arguments cannnot be used for functions "
 													  "that take arbitrary parameters."));
@@ -719,10 +810,10 @@ bool FunctionCall::isTypeConversion() const
 	return m_expression->getType()->getCategory() == Type::Category::TypeType;
 }
 
-void NewExpression::checkTypeRequirements()
+void NewExpression::checkTypeRequirements(TypePointers const*)
 {
-	m_contractName->checkTypeRequirements();
-	m_contract = dynamic_cast<ContractDefinition const*>(m_contractName->getReferencedDeclaration());
+	m_contractName->checkTypeRequirements(nullptr);
+	m_contract = dynamic_cast<ContractDefinition const*>(&m_contractName->getReferencedDeclaration());
 	if (!m_contract)
 		BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract."));
 	if (!m_contract->isFullyImplemented())
@@ -733,15 +824,37 @@ void NewExpression::checkTypeRequirements()
 									   FunctionType::Location::Creation);
 }
 
-void MemberAccess::checkTypeRequirements()
+void MemberAccess::checkTypeRequirements(TypePointers const* _argumentTypes)
 {
-	m_expression->checkTypeRequirements();
+	m_expression->checkTypeRequirements(nullptr);
 	Type const& type = *m_expression->getType();
-	m_type = type.getMemberType(*m_memberName);
-	if (!m_type)
-		BOOST_THROW_EXCEPTION(createTypeError("Member \"" + *m_memberName + "\" not found or not "
-											  "visible in " + type.toString()));
-	// This should probably move somewhere else.
+
+	MemberList::MemberMap possibleMembers = type.getMembers().membersByName(*m_memberName);
+	if (possibleMembers.size() > 1 && _argumentTypes)
+	{
+		// do override resolution
+		for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
+			if (
+				it->type->getCategory() == Type::Category::Function &&
+				!dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*_argumentTypes)
+			)
+				it = possibleMembers.erase(it);
+			else
+				++it;
+	}
+	if (possibleMembers.size() == 0)
+		BOOST_THROW_EXCEPTION(createTypeError(
+			"Member \"" + *m_memberName + "\" not found or not visible "
+			"after argument-dependent lookup in " + type.toString()
+		));
+	else if (possibleMembers.size() > 1)
+		BOOST_THROW_EXCEPTION(createTypeError(
+			"Member \"" + *m_memberName + "\" not unique "
+			"after argument-dependent lookup in " + type.toString()
+		));
+
+	m_referencedDeclaration = possibleMembers.front().declaration;
+	m_type = possibleMembers.front().type;
 	if (type.getCategory() == Type::Category::Struct)
 		m_isLValue = true;
 	else if (type.getCategory() == Type::Category::Array)
@@ -754,9 +867,9 @@ void MemberAccess::checkTypeRequirements()
 		m_isLValue = false;
 }
 
-void IndexAccess::checkTypeRequirements()
+void IndexAccess::checkTypeRequirements(TypePointers const*)
 {
-	m_base->checkTypeRequirements();
+	m_base->checkTypeRequirements(nullptr);
 	switch (m_base->getType()->getCategory())
 	{
 	case Type::Category::Array:
@@ -789,7 +902,7 @@ void IndexAccess::checkTypeRequirements()
 			m_type = make_shared<TypeType>(make_shared<ArrayType>(ArrayType::Location::Memory, type.getActualType()));
 		else
 		{
-			m_index->checkTypeRequirements();
+			m_index->checkTypeRequirements(nullptr);
 			auto length = dynamic_cast<IntegerConstantType const*>(m_index->getType().get());
 			if (!length)
 				BOOST_THROW_EXCEPTION(m_index->createTypeError("Integer constant expected."));
@@ -804,22 +917,57 @@ void IndexAccess::checkTypeRequirements()
 	}
 }
 
-void Identifier::checkTypeRequirements()
+void Identifier::checkTypeRequirements(TypePointers const* _argumentTypes)
 {
-	solAssert(m_referencedDeclaration, "Identifier not resolved.");
-
+	if (!m_referencedDeclaration)
+	{
+		if (!_argumentTypes)
+			BOOST_THROW_EXCEPTION(createTypeError("Unable to determine overloaded type."));
+		overloadResolution(*_argumentTypes);
+	}
+	solAssert(!!m_referencedDeclaration, "Referenced declaration is null after overload resolution.");
 	m_isLValue = m_referencedDeclaration->isLValue();
 	m_type = m_referencedDeclaration->getType(m_currentContract);
 	if (!m_type)
 		BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
 }
 
-void ElementaryTypeNameExpression::checkTypeRequirements()
+Declaration const& Identifier::getReferencedDeclaration() const
+{
+	solAssert(!!m_referencedDeclaration, "Identifier not resolved.");
+	return *m_referencedDeclaration;
+}
+
+void Identifier::overloadResolution(TypePointers const& _argumentTypes)
+{
+	solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution.");
+	solAssert(!m_overloadedDeclarations.empty(), "No candidates for overload resolution found.");
+
+	std::vector<Declaration const*> possibles;
+	if (m_overloadedDeclarations.size() == 1)
+		m_referencedDeclaration = *m_overloadedDeclarations.begin();
+
+	for (Declaration const* declaration: m_overloadedDeclarations)
+	{
+		TypePointer const& function = declaration->getType();
+		auto const* functionType = dynamic_cast<FunctionType const*>(function.get());
+		if (functionType && functionType->canTakeArguments(_argumentTypes))
+			possibles.push_back(declaration);
+	}
+	if (possibles.size() == 1)
+		m_referencedDeclaration = possibles.front();
+	else if (possibles.empty())
+		BOOST_THROW_EXCEPTION(createTypeError("No matching declaration found after argument-dependent lookup."));
+	else
+		BOOST_THROW_EXCEPTION(createTypeError("No unique declaration found after argument-dependent lookup."));
+}
+
+void ElementaryTypeNameExpression::checkTypeRequirements(TypePointers const*)
 {
 	m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
 }
 
-void Literal::checkTypeRequirements()
+void Literal::checkTypeRequirements(TypePointers const*)
 {
 	m_type = Type::forLiteral(*this);
 	if (!m_type)
diff --git a/libsolidity/AST.h b/libsolidity/AST.h
index 0c133ff1a..c9ad6447e 100644
--- a/libsolidity/AST.h
+++ b/libsolidity/AST.h
@@ -143,8 +143,8 @@ public:
 	ASTString const& getName() const { return *m_name; }
 	Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; }
 	bool isPublic() const { return getVisibility() >= Visibility::Public; }
-	bool isVisibleInContract() const { return getVisibility() != Visibility::External; }
-	virtual bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; }
+	virtual bool isVisibleInContract() const { return getVisibility() != Visibility::External; }
+	bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; }
 
 	/// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.
 	/// Available only after name and type resolution step.
@@ -156,7 +156,7 @@ public:
 	/// contract types.
 	virtual TypePointer getType(ContractDefinition const* m_currentContract = nullptr) const = 0;
 	virtual bool isLValue() const { return false; }
-	virtual bool isPartOfExternalInterface() const { return false; };
+	virtual bool isPartOfExternalInterface() const { return false; }
 
 protected:
 	virtual Visibility getDefaultVisibility() const { return Visibility::Public; }
@@ -282,9 +282,15 @@ public:
 	FunctionDefinition const* getFallbackFunction() const;
 
 private:
+	/// Checks that two functions defined in this contract with the same name have different
+	/// arguments and that there is at most one constructor.
+	void checkDuplicateFunctions() const;
 	void checkIllegalOverrides() const;
 	void checkAbstractFunctions();
 	void checkAbstractConstructors();
+	/// Checks that different functions with external visibility end up having different
+	/// external argument types (i.e. different signature).
+	void checkExternalTypeClashes() const;
 
 	std::vector<std::pair<FixedHash<4>, FunctionTypePointer>> const& getInterfaceFunctionList() const;
 
@@ -437,10 +443,9 @@ public:
 	ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
 	Block const& getBody() const { return *m_body; }
 
-	virtual bool isVisibleInDerivedContracts() const override
+	virtual bool isVisibleInContract() const override
 	{
-		return !isConstructor() && !getName().empty() && isVisibleInContract() &&
-			getVisibility() >= Visibility::Internal;
+		return Declaration::isVisibleInContract() && !isConstructor() && !getName().empty();
 	}
 	virtual TypePointer getType(ContractDefinition const*) const override;
 	virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !getName().empty(); }
@@ -968,7 +973,10 @@ class Expression: public ASTNode
 {
 public:
 	Expression(SourceLocation const& _location): ASTNode(_location) {}
-	virtual void checkTypeRequirements() = 0;
+	/// Performs type checking after which m_type should be set.
+	/// @arg _argumentTypes if set, provides the argument types for the case that this expression
+	/// is used in the context of a call, used for function overload resolution.
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) = 0;
 
 	std::shared_ptr<Type const> const& getType() const { return m_type; }
 	bool isLValue() const { return m_isLValue; }
@@ -1007,7 +1015,7 @@ public:
 	}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Expression const& getLeftHandSide() const { return *m_leftHandSide; }
 	Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
@@ -1035,7 +1043,7 @@ public:
 	}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Token::Value getOperator() const { return m_operator; }
 	bool isPrefixOperation() const { return m_isPrefix; }
@@ -1062,7 +1070,7 @@ public:
 	}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Expression const& getLeftExpression() const { return *m_left; }
 	Expression const& getRightExpression() const { return *m_right; }
@@ -1090,7 +1098,7 @@ public:
 		Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Expression const& getExpression() const { return *m_expression; }
 	std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; }
@@ -1116,7 +1124,7 @@ public:
 		Expression(_location), m_contractName(_contractName) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	/// Returns the referenced contract. Can only be called after type checking.
 	ContractDefinition const* getContract() const { solAssert(m_contract, ""); return m_contract; }
@@ -1140,11 +1148,18 @@ public:
 	virtual void accept(ASTConstVisitor& _visitor) const override;
 	Expression const& getExpression() const { return *m_expression; }
 	ASTString const& getMemberName() const { return *m_memberName; }
-	virtual void checkTypeRequirements() override;
+	/// @returns the declaration referenced by this expression. Might return nullptr even if the
+	/// expression is valid, e.g. if the member does not correspond to an AST node.
+	Declaration const* referencedDeclaration() const { return m_referencedDeclaration; }
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 private:
 	ASTPointer<Expression> m_expression;
 	ASTPointer<ASTString> m_memberName;
+
+	/// Pointer to the referenced declaration, this is sometimes needed to resolve function over
+	/// loads in the type-checking phase.
+	Declaration const* m_referencedDeclaration = nullptr;
 };
 
 /**
@@ -1158,7 +1173,7 @@ public:
 		Expression(_location), m_base(_base), m_index(_index) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Expression const& getBaseExpression() const { return *m_base; }
 	Expression const* getIndexExpression() const { return m_index.get(); }
@@ -1188,18 +1203,31 @@ public:
 		PrimaryExpression(_location), m_name(_name) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	ASTString const& getName() const { return *m_name; }
 
-	void setReferencedDeclaration(Declaration const& _referencedDeclaration,
-								  ContractDefinition const* _currentContract = nullptr)
+	void setReferencedDeclaration(
+		Declaration const& _referencedDeclaration,
+		ContractDefinition const* _currentContract = nullptr
+	)
 	{
 		m_referencedDeclaration = &_referencedDeclaration;
 		m_currentContract = _currentContract;
 	}
-	Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; }
-	ContractDefinition const* getCurrentContract() const { return m_currentContract; }
+	Declaration const& getReferencedDeclaration() const;
+
+	/// Stores a set of possible declarations referenced by this identifier. Has to be resolved
+	/// providing argument types using overloadResolution before the referenced declaration
+	/// is accessed.
+	void setOverloadedDeclarations(std::set<Declaration const*> const& _declarations)
+	{
+		m_overloadedDeclarations = _declarations;
+	}
+
+	/// Tries to find exactly one of the possible referenced declarations provided the given
+	/// argument types in a call context.
+	void overloadResolution(TypePointers const& _argumentTypes);
 
 private:
 	ASTPointer<ASTString> m_name;
@@ -1209,6 +1237,8 @@ private:
 	/// Stores a reference to the current contract. This is needed because types of base contracts
 	/// change depending on the context.
 	ContractDefinition const* m_currentContract = nullptr;
+	/// A set of overloaded declarations, right now only FunctionDefinition has overloaded declarations.
+	std::set<Declaration const*> m_overloadedDeclarations;
 };
 
 /**
@@ -1226,7 +1256,7 @@ public:
 	}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Token::Value getTypeToken() const { return m_typeToken; }
 
@@ -1260,7 +1290,7 @@ public:
 		PrimaryExpression(_location), m_token(_token), m_value(_value), m_subDenomination(_sub) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
-	virtual void checkTypeRequirements() override;
+	virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override;
 
 	Token::Value getToken() const { return m_token; }
 	/// @returns the non-parsed value of the literal
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp
index f0197e23b..37b577ccd 100644
--- a/libsolidity/Compiler.cpp
+++ b/libsolidity/Compiler.cpp
@@ -90,7 +90,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
 			for (auto const& modifier: constructor->getModifiers())
 			{
 				auto baseContract = dynamic_cast<ContractDefinition const*>(
-					modifier->getName()->getReferencedDeclaration());
+					&modifier->getName()->getReferencedDeclaration());
 				if (baseContract)
 					if (m_baseArguments.count(baseContract->getConstructor()) == 0)
 						m_baseArguments[baseContract->getConstructor()] = &modifier->getArguments();
@@ -99,7 +99,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
 		for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
 		{
 			ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>(
-						base->getName()->getReferencedDeclaration());
+						&base->getName()->getReferencedDeclaration());
 			solAssert(baseContract, "");
 
 			if (m_baseArguments.count(baseContract->getConstructor()) == 0)
@@ -542,7 +542,7 @@ void Compiler::appendModifierOrFunctionCode()
 		ASTPointer<ModifierInvocation> const& modifierInvocation = m_currentFunction->getModifiers()[m_modifierDepth];
 
 		// constructor call should be excluded
-		if (dynamic_cast<ContractDefinition const*>(modifierInvocation->getName()->getReferencedDeclaration()))
+		if (dynamic_cast<ContractDefinition const*>(&modifierInvocation->getName()->getReferencedDeclaration()))
 		{
 			++m_modifierDepth;
 			appendModifierOrFunctionCode();
diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp
index 7cade367c..f373fdfb0 100644
--- a/libsolidity/CompilerContext.cpp
+++ b/libsolidity/CompilerContext.cpp
@@ -102,23 +102,13 @@ eth::AssemblyItem CompilerContext::getFunctionEntryLabel(Declaration const& _dec
 eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(FunctionDefinition const& _function)
 {
 	solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
-	for (ContractDefinition const* contract: m_inheritanceHierarchy)
-		for (ASTPointer<FunctionDefinition> const& function: contract->getDefinedFunctions())
-			if (!function->isConstructor() && function->getName() == _function.getName())
-				return getFunctionEntryLabel(*function);
-	solAssert(false, "Virtual function " + _function.getName() + " not found.");
-	return m_asm.newTag(); // not reached
+	return getVirtualFunctionEntryLabel(_function, m_inheritanceHierarchy.begin());
 }
 
-eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(string const& _name, ContractDefinition const& _base)
+eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base)
 {
-	auto it = getSuperContract(_base);
-	for (; it != m_inheritanceHierarchy.end(); ++it)
-		for (ASTPointer<FunctionDefinition> const& function: (*it)->getDefinedFunctions())
-			if (!function->isConstructor() && function->getName() == _name)
-				return getFunctionEntryLabel(*function);
-	solAssert(false, "Super function " + _name + " not found.");
-	return m_asm.newTag(); // not reached
+	solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
+	return getVirtualFunctionEntryLabel(_function, getSuperContract(_base));
 }
 
 FunctionDefinition const* CompilerContext::getNextConstructor(ContractDefinition const& _contract) const
@@ -190,6 +180,26 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node)
 	updateSourceLocation();
 }
 
+eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(
+	FunctionDefinition const& _function,
+	vector<ContractDefinition const*>::const_iterator _searchStart
+)
+{
+	string name = _function.getName();
+	FunctionType functionType(_function);
+	auto it = _searchStart;
+	for (; it != m_inheritanceHierarchy.end(); ++it)
+		for (ASTPointer<FunctionDefinition> const& function: (*it)->getDefinedFunctions())
+			if (
+				function->getName() == name &&
+				!function->isConstructor() &&
+				FunctionType(*function).hasEqualArgumentTypes(functionType)
+			)
+				return getFunctionEntryLabel(*function);
+	solAssert(false, "Super function " + name + " not found.");
+	return m_asm.newTag(); // not reached
+}
+
 vector<ContractDefinition const*>::const_iterator CompilerContext::getSuperContract(ContractDefinition const& _contract) const
 {
 	solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h
index 9c2156bfa..34a3f97cd 100644
--- a/libsolidity/CompilerContext.h
+++ b/libsolidity/CompilerContext.h
@@ -63,9 +63,9 @@ public:
 	void setInheritanceHierarchy(std::vector<ContractDefinition const*> const& _hierarchy) { m_inheritanceHierarchy = _hierarchy; }
 	/// @returns the entry label of the given function and takes overrides into account.
 	eth::AssemblyItem getVirtualFunctionEntryLabel(FunctionDefinition const& _function);
-	/// @returns the entry label of function with the given name from the most derived class just
+	/// @returns the entry label of a function that overrides the given declaration from the most derived class just
 	/// above _base in the current inheritance hierarchy.
-	eth::AssemblyItem getSuperFunctionEntryLabel(std::string const& _name, ContractDefinition const& _base);
+	eth::AssemblyItem getSuperFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base);
 	FunctionDefinition const* getNextConstructor(ContractDefinition const& _contract) const;
 
 	/// @returns the set of functions for which we still need to generate code
@@ -141,6 +141,13 @@ public:
 	};
 
 private:
+	/// @returns the entry label of the given function - searches the inheritance hierarchy
+	/// startig from the given point towards the base.
+	eth::AssemblyItem getVirtualFunctionEntryLabel(
+		FunctionDefinition const& _function,
+		std::vector<ContractDefinition const*>::const_iterator _searchStart
+	);
+	/// @returns an iterator to the contract directly above the given contract.
 	std::vector<ContractDefinition const*>::const_iterator getSuperContract(const ContractDefinition &_contract) const;
 	/// Updates source location set in the assembly.
 	void updateSourceLocation();
diff --git a/libsolidity/DeclarationContainer.cpp b/libsolidity/DeclarationContainer.cpp
index 2594d4281..5f8d24e34 100644
--- a/libsolidity/DeclarationContainer.cpp
+++ b/libsolidity/DeclarationContainer.cpp
@@ -22,11 +22,11 @@
 
 #include <libsolidity/DeclarationContainer.h>
 #include <libsolidity/AST.h>
+#include <libsolidity/Types.h>
 
-namespace dev
-{
-namespace solidity
-{
+using namespace std;
+using namespace dev;
+using namespace dev::solidity;
 
 bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update)
 {
@@ -34,17 +34,34 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration,
 	if (name.empty())
 		return true;
 
-	if (!_update && (m_declarations.count(name) || m_invisibleDeclarations.count(name)))
-		return false;
+	if (_update)
+	{
+		solAssert(!dynamic_cast<FunctionDefinition const*>(&_declaration), "Attempt to update function definition.");
+		m_declarations[name].clear();
+		m_invisibleDeclarations[name].clear();
+	}
+	else
+	{
+		if (dynamic_cast<FunctionDefinition const*>(&_declaration))
+		{
+			// check that all other declarations with the same name are functions
+			for (auto&& declaration: m_invisibleDeclarations[name] + m_declarations[name])
+				if (!dynamic_cast<FunctionDefinition const*>(declaration))
+					return false;
+		}
+		else if (m_declarations.count(name) > 0 || m_invisibleDeclarations.count(name) > 0)
+			return false;
+	}
 
 	if (_invisible)
-		m_invisibleDeclarations.insert(name);
+		m_invisibleDeclarations[name].insert(&_declaration);
 	else
-		m_declarations[name] = &_declaration;
+		m_declarations[name].insert(&_declaration);
+
 	return true;
 }
 
-Declaration const* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
+set<Declaration const*> DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
 {
 	solAssert(!_name.empty(), "Attempt to resolve empty name.");
 	auto result = m_declarations.find(_name);
@@ -52,8 +69,5 @@ Declaration const* DeclarationContainer::resolveName(ASTString const& _name, boo
 		return result->second;
 	if (_recursive && m_enclosingContainer)
 		return m_enclosingContainer->resolveName(_name, true);
-	return nullptr;
-}
-
-}
+	return set<Declaration const*>({});
 }
diff --git a/libsolidity/DeclarationContainer.h b/libsolidity/DeclarationContainer.h
index f70881f5b..35a6ea077 100644
--- a/libsolidity/DeclarationContainer.h
+++ b/libsolidity/DeclarationContainer.h
@@ -48,15 +48,15 @@ public:
 	/// @param _update if true, replaces a potential declaration that is already present
 	/// @returns false if the name was already declared.
 	bool registerDeclaration(Declaration const& _declaration, bool _invisible = false, bool _update = false);
-	Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const;
+	std::set<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false) const;
 	Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
-	std::map<ASTString, Declaration const*> const& getDeclarations() const { return m_declarations; }
+	std::map<ASTString, std::set<Declaration const*>> const& getDeclarations() const { return m_declarations; }
 
 private:
 	Declaration const* m_enclosingDeclaration;
 	DeclarationContainer const* m_enclosingContainer;
-	std::map<ASTString, Declaration const*> m_declarations;
-	std::set<ASTString> m_invisibleDeclarations;
+	std::map<ASTString, std::set<Declaration const*>> m_declarations;
+	std::map<ASTString, std::set<Declaration const*>> m_invisibleDeclarations;
 };
 
 }
diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index 7ea71a7a4..cf6a01ec1 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -626,13 +626,25 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
 		bool alsoSearchInteger = false;
 		ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.getExpression().getType());
 		if (type.isSuper())
-			m_context << m_context.getSuperFunctionEntryLabel(member, type.getContractDefinition()).pushTag();
+		{
+			solAssert(!!_memberAccess.referencedDeclaration(), "Referenced declaration not resolved.");
+			m_context << m_context.getSuperFunctionEntryLabel(
+				dynamic_cast<FunctionDefinition const&>(*_memberAccess.referencedDeclaration()),
+				type.getContractDefinition()
+			).pushTag();
+		}
 		else
 		{
 			// ordinary contract type
-			u256 identifier = type.getFunctionIdentifier(member);
-			if (identifier != Invalid256)
+			if (Declaration const* declaration = _memberAccess.referencedDeclaration())
 			{
+				u256 identifier;
+				if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
+					identifier = FunctionType(*variable).externalIdentifier();
+				else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))
+					identifier = FunctionType(*function).externalIdentifier();
+				else
+					solAssert(false, "Contract member is neither variable nor function.");
 				appendTypeConversion(type, IntegerType(0, IntegerType::Modifier::Address), true);
 				m_context << identifier;
 			}
@@ -708,19 +720,16 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
 	case Type::Category::TypeType:
 	{
 		TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType());
-		if (!type.getMembers().getMemberType(member))
-			BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString()));
+		solAssert(
+			!type.getMembers().membersByName(_memberAccess.getMemberName()).empty(),
+			"Invalid member access to " + type.toString()
+		);
 
-		if (auto contractType = dynamic_cast<ContractType const*>(type.getActualType().get()))
+		if (dynamic_cast<ContractType const*>(type.getActualType().get()))
 		{
-			ContractDefinition const& contract = contractType->getContractDefinition();
-			for (ASTPointer<FunctionDefinition> const& function: contract.getDefinedFunctions())
-				if (function->getName() == member)
-				{
-					m_context << m_context.getFunctionEntryLabel(*function).pushTag();
-					return;
-				}
-			solAssert(false, "Function not found in member access.");
+			auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.referencedDeclaration());
+			solAssert(!!function, "Function not found in member access");
+			m_context << m_context.getFunctionEntryLabel(*function).pushTag();
 		}
 		else if (auto enumType = dynamic_cast<EnumType const*>(type.getActualType().get()))
 			m_context << enumType->getMemberValue(_memberAccess.getMemberName());
@@ -805,7 +814,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
 void ExpressionCompiler::endVisit(Identifier const& _identifier)
 {
 	CompilerContext::LocationSetter locationSetter(m_context, _identifier);
-	Declaration const* declaration = _identifier.getReferencedDeclaration();
+	Declaration const* declaration = &_identifier.getReferencedDeclaration();
 	if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
 	{
 		switch (magicVar->getType()->getCategory())
@@ -1066,7 +1075,13 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
 		m_context << eth::Instruction::POP;
 	m_context << eth::Instruction::POP; // pop contract address
 
-	if (firstType)
+	if (_functionType.getLocation() == FunctionType::Location::RIPEMD160)
+	{
+		// fix: built-in contract returns right-aligned data
+		CompilerUtils(m_context).loadFromMemory(0, IntegerType(160), false, true);
+		appendTypeConversion(IntegerType(160), FixedBytesType(20));
+	}
+	else if (firstType)
 		CompilerUtils(m_context).loadFromMemory(0, *firstType, false, true);
 }
 
diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp
index 68428a0bf..bb68a663f 100644
--- a/libsolidity/LValue.cpp
+++ b/libsolidity/LValue.cpp
@@ -193,10 +193,10 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
 			for (auto const& member: structType.getMembers())
 			{
 				// assign each member that is not a mapping
-				TypePointer const& memberType = member.second;
+				TypePointer const& memberType = member.type;
 				if (memberType->getCategory() == Type::Category::Mapping)
 					continue;
-				pair<u256, unsigned> const& offsets = structType.getStorageOffsetsOfMember(member.first);
+				pair<u256, unsigned> const& offsets = structType.getStorageOffsetsOfMember(member.name);
 				m_context
 					<< offsets.first << u256(offsets.second)
 					<< eth::Instruction::DUP6 << eth::Instruction::DUP3
@@ -247,10 +247,10 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const
 		for (auto const& member: structType.getMembers())
 		{
 			// zero each member that is not a mapping
-			TypePointer const& memberType = member.second;
+			TypePointer const& memberType = member.type;
 			if (memberType->getCategory() == Type::Category::Mapping)
 				continue;
-			pair<u256, unsigned> const& offsets = structType.getStorageOffsetsOfMember(member.first);
+			pair<u256, unsigned> const& offsets = structType.getStorageOffsetsOfMember(member.name);
 			m_context
 				<< offsets.first << eth::Instruction::DUP3 << eth::Instruction::ADD
 				<< u256(offsets.second);
diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp
index f6ee2f1d0..a286934a9 100644
--- a/libsolidity/NameAndTypeResolver.cpp
+++ b/libsolidity/NameAndTypeResolver.cpp
@@ -31,7 +31,7 @@ namespace dev
 namespace solidity
 {
 
-NameAndTypeResolver::NameAndTypeResolver(std::vector<Declaration const*> const& _globals)
+NameAndTypeResolver::NameAndTypeResolver(vector<Declaration const*> const& _globals)
 {
 	for (Declaration const* declaration: _globals)
 		m_scopes[nullptr].registerDeclaration(*declaration);
@@ -53,8 +53,9 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
 	m_currentScope = &m_scopes[&_contract];
 
 	linearizeBaseContracts(_contract);
+	// we first import non-functions only as we do not yet know the argument types
 	for (ContractDefinition const* base: _contract.getLinearizedBaseContracts())
-		importInheritedScope(*base);
+		importInheritedScope(*base, false); // import non-functions
 
 	for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
 		ReferencesResolver resolver(*structDef, *this, &_contract, nullptr);
@@ -64,6 +65,8 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
 		ReferencesResolver resolver(*variable, *this, &_contract, nullptr);
 	for (ASTPointer<EventDefinition> const& event: _contract.getEvents())
 		ReferencesResolver resolver(*event, *this, &_contract, nullptr);
+
+	// these can contain code, only resolve parameters for now
 	for (ASTPointer<ModifierDefinition> const& modifier: _contract.getFunctionModifiers())
 	{
 		m_currentScope = &m_scopes[modifier.get()];
@@ -75,6 +78,28 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
 		ReferencesResolver referencesResolver(*function, *this, &_contract,
 											  function->getReturnParameterList().get());
 	}
+
+	m_currentScope = &m_scopes[&_contract];
+	for (ContractDefinition const* base: _contract.getLinearizedBaseContracts())
+		importInheritedScope(*base, true); // import functions
+
+	// now resolve references inside the code
+	for (ASTPointer<ModifierDefinition> const& modifier: _contract.getFunctionModifiers())
+	{
+		m_currentScope = &m_scopes[modifier.get()];
+		ReferencesResolver resolver(*modifier, *this, &_contract, nullptr, true);
+	}
+	for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
+	{
+		m_currentScope = &m_scopes[function.get()];
+		ReferencesResolver referencesResolver(
+			*function,
+			*this,
+			&_contract,
+			function->getReturnParameterList().get(),
+			true
+		);
+	}
 }
 
 void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract)
@@ -90,31 +115,51 @@ void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
 	solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope.");
 }
 
-Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
+set<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
 {
 	auto iterator = m_scopes.find(_scope);
 	if (iterator == end(m_scopes))
-		return nullptr;
+		return set<Declaration const*>({});
 	return iterator->second.resolveName(_name, false);
 }
 
-Declaration const* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
+set<Declaration const*> NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
 {
 	return m_currentScope->resolveName(_name, _recursive);
 }
 
-void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base)
+void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base, bool _importFunctions)
 {
 	auto iterator = m_scopes.find(&_base);
 	solAssert(iterator != end(m_scopes), "");
 	for (auto const& nameAndDeclaration: iterator->second.getDeclarations())
-	{
-		Declaration const* declaration = nameAndDeclaration.second;
-		// Import if it was declared in the base, is not the constructor and is visible in derived classes
-		if (declaration->getScope() == &_base && declaration->getName() != _base.getName() &&
-				declaration->isVisibleInDerivedContracts())
-			m_currentScope->registerDeclaration(*declaration);
-	}
+		for (auto const& declaration: nameAndDeclaration.second)
+			// Import if it was declared in the base, is not the constructor and is visible in derived classes
+			if (declaration->getScope() == &_base && declaration->isVisibleInDerivedContracts())
+			{
+				auto function = dynamic_cast<FunctionDefinition const*>(declaration);
+				if ((function == nullptr) == _importFunctions)
+					continue;
+				if (!!function)
+				{
+					FunctionType functionType(*function);
+					// only import if a function with the same arguments does not exist yet
+					bool functionWithEqualArgumentsFound = false;
+					for (auto knownDeclaration: m_currentScope->resolveName(nameAndDeclaration.first))
+					{
+						auto knownFunction = dynamic_cast<FunctionDefinition const*>(knownDeclaration);
+						if (!knownFunction)
+							continue; // this is not legal, but will be caught later
+						if (!FunctionType(*knownFunction).hasEqualArgumentTypes(functionType))
+							continue;
+						functionWithEqualArgumentsFound = true;
+						break;
+					}
+					if (functionWithEqualArgumentsFound)
+						continue;
+				}
+				m_currentScope->registerDeclaration(*declaration);
+			}
 }
 
 void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const
@@ -125,8 +170,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
 	for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.getBaseContracts())
 	{
 		ASTPointer<Identifier> baseName = baseSpecifier->getName();
-		ContractDefinition const* base = dynamic_cast<ContractDefinition const*>(
-														baseName->getReferencedDeclaration());
+		auto base = dynamic_cast<ContractDefinition const*>(&baseName->getReferencedDeclaration());
 		if (!base)
 			BOOST_THROW_EXCEPTION(baseName->createTypeError("Contract expected."));
 		// "push_front" has the effect that bases mentioned later can overwrite members of bases
@@ -318,11 +362,19 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
 		enterNewSubScope(_declaration);
 }
 
-ReferencesResolver::ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver,
-									   ContractDefinition const* _currentContract,
-									   ParameterList const* _returnParameters, bool _allowLazyTypes):
-	m_resolver(_resolver), m_currentContract(_currentContract),
-	m_returnParameters(_returnParameters), m_allowLazyTypes(_allowLazyTypes)
+ReferencesResolver::ReferencesResolver(
+	ASTNode& _root,
+	NameAndTypeResolver& _resolver,
+	ContractDefinition const* _currentContract,
+	ParameterList const* _returnParameters,
+	bool _resolveInsideCode,
+	bool _allowLazyTypes
+):
+	m_resolver(_resolver),
+	m_currentContract(_currentContract),
+	m_returnParameters(_returnParameters),
+	m_resolveInsideCode(_resolveInsideCode),
+	m_allowLazyTypes(_allowLazyTypes)
 {
 	_root.accept(*this);
 }
@@ -361,24 +413,37 @@ bool ReferencesResolver::visit(Mapping&)
 
 bool ReferencesResolver::visit(UserDefinedTypeName& _typeName)
 {
-	Declaration const* declaration = m_resolver.getNameFromCurrentScope(_typeName.getName());
-	if (!declaration)
-		BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation())
-												 << errinfo_comment("Undeclared identifier."));
-	_typeName.setReferencedDeclaration(*declaration);
+	auto declarations = m_resolver.getNameFromCurrentScope(_typeName.getName());
+	if (declarations.empty())
+		BOOST_THROW_EXCEPTION(
+			DeclarationError() <<
+			errinfo_sourceLocation(_typeName.getLocation()) <<
+			errinfo_comment("Undeclared identifier.")
+		);
+	else if (declarations.size() > 1)
+		BOOST_THROW_EXCEPTION(
+			DeclarationError() <<
+			errinfo_sourceLocation(_typeName.getLocation()) <<
+			errinfo_comment("Duplicate identifier.")
+		);
+	else
+		_typeName.setReferencedDeclaration(**declarations.begin());
 	return false;
 }
 
 bool ReferencesResolver::visit(Identifier& _identifier)
 {
-	Declaration const* declaration = m_resolver.getNameFromCurrentScope(_identifier.getName());
-	if (!declaration)
+	auto declarations = m_resolver.getNameFromCurrentScope(_identifier.getName());
+	if (declarations.empty())
 		BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_identifier.getLocation())
 												 << errinfo_comment("Undeclared identifier."));
-	_identifier.setReferencedDeclaration(*declaration, m_currentContract);
+	else if (declarations.size() == 1)
+		_identifier.setReferencedDeclaration(**declarations.begin(), m_currentContract);
+	else
+		// Duplicate declaration will be checked in checkTypeRequirements()
+		_identifier.setOverloadedDeclarations(declarations);
 	return false;
 }
 
-
 }
 }
diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h
index 63b8ab637..6528bbef2 100644
--- a/libsolidity/NameAndTypeResolver.h
+++ b/libsolidity/NameAndTypeResolver.h
@@ -56,18 +56,19 @@ public:
 	/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
 	/// the global scope is used (i.e. the one containing only the contract).
 	/// @returns a pointer to the declaration on success or nullptr on failure.
-	Declaration const* resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
+	std::set<Declaration const*> resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
 
 	/// Resolves a name in the "current" scope. Should only be called during the initial
 	/// resolving phase.
-	Declaration const* getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
+	std::set<Declaration const*> getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
 
 private:
 	void reset();
 
-	/// Imports all members declared directly in the given contract (i.e. does not import inherited
-	/// members) into the current scope if they are not present already.
-	void importInheritedScope(ContractDefinition const& _base);
+	/// Either imports all non-function members or all function members declared directly in the
+	/// given contract (i.e. does not import inherited members) into the current scope if they are
+	///not present already.
+	void importInheritedScope(ContractDefinition const& _base, bool _importFunctions);
 
 	/// Computes "C3-Linearization" of base contracts and stores it inside the contract.
 	void linearizeBaseContracts(ContractDefinition& _contract) const;
@@ -126,13 +127,18 @@ private:
 class ReferencesResolver: private ASTVisitor
 {
 public:
-	ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver,
-					   ContractDefinition const* _currentContract,
-					   ParameterList const* _returnParameters,
-					   bool _allowLazyTypes = true);
+	ReferencesResolver(
+		ASTNode& _root,
+		NameAndTypeResolver& _resolver,
+		ContractDefinition const* _currentContract,
+		ParameterList const* _returnParameters,
+		bool _resolveInsideCode = false,
+		bool _allowLazyTypes = true
+	);
 
 private:
 	virtual void endVisit(VariableDeclaration& _variable) override;
+	virtual bool visit(Block&) override { return m_resolveInsideCode; }
 	virtual bool visit(Identifier& _identifier) override;
 	virtual bool visit(UserDefinedTypeName& _typeName) override;
 	virtual bool visit(Mapping&) override;
@@ -141,6 +147,7 @@ private:
 	NameAndTypeResolver& m_resolver;
 	ContractDefinition const* m_currentContract;
 	ParameterList const* m_returnParameters;
+	bool m_resolveInsideCode;
 	bool m_allowLazyTypes;
 };
 
diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp
index bfde7187a..a445d56e1 100644
--- a/libsolidity/Types.cpp
+++ b/libsolidity/Types.cpp
@@ -25,6 +25,7 @@
 #include <boost/range/adaptor/reversed.hpp>
 #include <libdevcore/CommonIO.h>
 #include <libdevcore/CommonData.h>
+#include <libdevcrypto/SHA3.h>
 #include <libsolidity/Utils.h>
 #include <libsolidity/AST.h>
 
@@ -92,13 +93,13 @@ std::pair<u256, unsigned> const* MemberList::getMemberStorageOffset(string const
 	{
 		TypePointers memberTypes;
 		memberTypes.reserve(m_memberTypes.size());
-		for (auto const& nameAndType: m_memberTypes)
-			memberTypes.push_back(nameAndType.second);
+		for (auto const& member: m_memberTypes)
+			memberTypes.push_back(member.type);
 		m_storageOffsets.reset(new StorageOffsets());
 		m_storageOffsets->computeOffsets(memberTypes);
 	}
 	for (size_t index = 0; index < m_memberTypes.size(); ++index)
-		if (m_memberTypes[index].first == _name)
+		if (m_memberTypes[index].name == _name)
 			return m_storageOffsets->getOffset(index);
 	return nullptr;
 }
@@ -189,7 +190,7 @@ TypePointer Type::fromArrayTypeName(TypeName& _baseTypeName, Expression* _length
 	if (_length)
 	{
 		if (!_length->getType())
-			_length->checkTypeRequirements();
+			_length->checkTypeRequirements(nullptr);
 		auto const* length = dynamic_cast<IntegerConstantType const*>(_length->getType().get());
 		if (!length)
 			BOOST_THROW_EXCEPTION(_length->createTypeError("Invalid array length."));
@@ -793,18 +794,46 @@ MemberList const& ContractType::getMembers() const
 	if (!m_members)
 	{
 		// All address members and all interface functions
-		vector<pair<string, TypePointer>> members(IntegerType::AddressMemberList.begin(),
-												  IntegerType::AddressMemberList.end());
+		MemberList::MemberMap members(
+			IntegerType::AddressMemberList.begin(),
+			IntegerType::AddressMemberList.end()
+		);
 		if (m_super)
 		{
+			// add the most derived of all functions which are visible in derived contracts
 			for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts())
 				for (ASTPointer<FunctionDefinition> const& function: base->getDefinedFunctions())
-					if (function->isVisibleInDerivedContracts())
-						members.push_back(make_pair(function->getName(), make_shared<FunctionType>(*function, true)));
+				{
+					if (!function->isVisibleInDerivedContracts())
+						continue;
+					auto functionType = make_shared<FunctionType>(*function, true);
+					bool functionWithEqualArgumentsFound = false;
+					for (auto const& member: members)
+					{
+						if (member.name != function->getName())
+							continue;
+						auto memberType = dynamic_cast<FunctionType const*>(member.type.get());
+						solAssert(!!memberType, "Override changes type.");
+						if (!memberType->hasEqualArgumentTypes(*functionType))
+							continue;
+						functionWithEqualArgumentsFound = true;
+						break;
+					}
+					if (!functionWithEqualArgumentsFound)
+						members.push_back(MemberList::Member(
+							function->getName(),
+							functionType,
+							function.get()
+						));
+				}
 		}
 		else
 			for (auto const& it: m_contract.getInterfaceFunctions())
-				members.push_back(make_pair(it.second->getDeclaration().getName(), it.second));
+				members.push_back(MemberList::Member(
+					it.second->getDeclaration().getName(),
+					it.second,
+					&it.second->getDeclaration()
+				));
 		m_members.reset(new MemberList(members));
 	}
 	return *m_members;
@@ -823,16 +852,6 @@ shared_ptr<FunctionType const> const& ContractType::getConstructorType() const
 	return m_constructorType;
 }
 
-u256 ContractType::getFunctionIdentifier(string const& _functionName) const
-{
-	auto interfaceFunctions = m_contract.getInterfaceFunctions();
-	for (auto const& it: m_contract.getInterfaceFunctions())
-		if (it.second->getDeclaration().getName() == _functionName)
-			return FixedHash<4>::Arith(it.first);
-
-	return Invalid256;
-}
-
 vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::getStateVariables() const
 {
 	vector<VariableDeclaration const*> variables;
@@ -873,8 +892,8 @@ u256 StructType::getStorageSize() const
 
 bool StructType::canLiveOutsideStorage() const
 {
-	for (pair<string, TypePointer> const& member: getMembers())
-		if (!member.second->canLiveOutsideStorage())
+	for (auto const& member: getMembers())
+		if (!member.type->canLiveOutsideStorage())
 			return false;
 	return true;
 }
@@ -891,7 +910,7 @@ MemberList const& StructType::getMembers() const
 	{
 		MemberList::MemberMap members;
 		for (ASTPointer<VariableDeclaration> const& variable: m_struct.getMembers())
-			members.push_back(make_pair(variable->getName(), variable->getType()));
+			members.push_back(MemberList::Member(variable->getName(), variable->getType(), variable.get()));
 		m_members.reset(new MemberList(members));
 	}
 	return *m_members;
@@ -1007,11 +1026,11 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
 	vector<string> retParamNames;
 	if (auto structType = dynamic_cast<StructType const*>(returnType.get()))
 	{
-		for (pair<string, TypePointer> const& member: structType->getMembers())
-			if (member.second->getCategory() != Category::Mapping && member.second->getCategory() != Category::Array)
+		for (auto const& member: structType->getMembers())
+			if (member.type->getCategory() != Category::Mapping && member.type->getCategory() != Category::Array)
 			{
-				retParamNames.push_back(member.first);
-				retParams.push_back(member.second);
+				retParamNames.push_back(member.name);
+				retParams.push_back(member.type);
 			}
 	}
 	else
@@ -1109,7 +1128,7 @@ unsigned FunctionType::getSizeOnStack() const
 	return size;
 }
 
-TypePointer FunctionType::externalType() const
+FunctionTypePointer FunctionType::externalFunctionType() const
 {
 	TypePointers paramTypes;
 	TypePointers retParamTypes;
@@ -1117,13 +1136,13 @@ TypePointer FunctionType::externalType() const
 	for (auto type: m_parameterTypes)
 	{
 		if (!type->externalType())
-			return TypePointer();
+			return FunctionTypePointer();
 		paramTypes.push_back(type->externalType());
 	}
 	for (auto type: m_returnParameterTypes)
 	{
 		if (!type->externalType())
-			return TypePointer();
+			return FunctionTypePointer();
 		retParamTypes.push_back(type->externalType());
 	}
 	return make_shared<FunctionType>(paramTypes, retParamTypes, m_location, m_arbitraryParameters);
@@ -1141,12 +1160,12 @@ MemberList const& FunctionType::getMembers() const
 	case Location::Bare:
 		if (!m_members)
 		{
-			vector<pair<string, TypePointer>> members{
+			MemberList::MemberMap members{
 				{"value", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
 													TypePointers{copyAndSetGasOrValue(false, true)},
 													Location::SetValue, false, m_gasSet, m_valueSet)}};
 			if (m_location != Location::Creation)
-				members.push_back(make_pair("gas", make_shared<FunctionType>(
+				members.push_back(MemberList::Member("gas", make_shared<FunctionType>(
 												parseElementaryTypeVector({"uint"}),
 												TypePointers{copyAndSetGasOrValue(true, false)},
 												Location::SetGas, false, m_gasSet, m_valueSet)));
@@ -1158,6 +1177,37 @@ MemberList const& FunctionType::getMembers() const
 	}
 }
 
+bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes) const
+{
+	TypePointers const& parameterTypes = getParameterTypes();
+	if (takesArbitraryParameters())
+		return true;
+	else if (_argumentTypes.size() != parameterTypes.size())
+		return false;
+	else
+		return std::equal(
+			_argumentTypes.cbegin(),
+			_argumentTypes.cend(),
+			parameterTypes.cbegin(),
+			[](TypePointer const& argumentType, TypePointer const& parameterType)
+			{
+				return argumentType->isImplicitlyConvertibleTo(*parameterType);
+			}
+		);
+}
+
+bool FunctionType::hasEqualArgumentTypes(FunctionType const& _other) const
+{
+	if (m_parameterTypes.size() != _other.m_parameterTypes.size())
+		return false;
+	return equal(
+		m_parameterTypes.cbegin(),
+		m_parameterTypes.cend(),
+		_other.m_parameterTypes.cbegin(),
+		[](TypePointer const& _a, TypePointer const& _b) -> bool { return *_a == *_b; }
+	);
+}
+
 string FunctionType::externalSignature(std::string const& _name) const
 {
 	std::string funcName = _name;
@@ -1168,7 +1218,7 @@ string FunctionType::externalSignature(std::string const& _name) const
 	}
 	string ret = funcName + "(";
 
-	TypePointers externalParameterTypes = dynamic_cast<FunctionType const&>(*externalType()).getParameterTypes();
+	TypePointers externalParameterTypes = externalFunctionType()->getParameterTypes();
 	for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it)
 	{
 		solAssert(!!(*it), "Parameter should have external type");
@@ -1178,6 +1228,11 @@ string FunctionType::externalSignature(std::string const& _name) const
 	return ret + ")";
 }
 
+u256 FunctionType::externalIdentifier() const
+{
+	return FixedHash<4>::Arith(FixedHash<4>(dev::sha3(externalSignature())));
+}
+
 TypePointers FunctionType::parseElementaryTypeVector(strings const& _types)
 {
 	TypePointers pointers;
@@ -1261,7 +1316,7 @@ MemberList const& TypeType::getMembers() const
 	// We need to lazy-initialize it because of recursive references.
 	if (!m_members)
 	{
-		vector<pair<string, TypePointer>> members;
+		MemberList::MemberMap members;
 		if (m_actualType->getCategory() == Category::Contract && m_currentContract != nullptr)
 		{
 			ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).getContractDefinition();
@@ -1270,14 +1325,14 @@ MemberList const& TypeType::getMembers() const
 				// We are accessing the type of a base contract, so add all public and protected
 				// members. Note that this does not add inherited functions on purpose.
 				for (Declaration const* decl: contract.getInheritableMembers())
-					members.push_back(make_pair(decl->getName(), decl->getType()));
+					members.push_back(MemberList::Member(decl->getName(), decl->getType(), decl));
 		}
 		else if (m_actualType->getCategory() == Category::Enum)
 		{
 			EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).getEnumDefinition();
 			auto enumType = make_shared<EnumType>(enumDef);
 			for (ASTPointer<EnumValue> const& enumValue: enumDef.getMembers())
-				members.push_back(make_pair(enumValue->getName(), enumType));
+				members.push_back(MemberList::Member(enumValue->getName(), enumType));
 		}
 		m_members.reset(new MemberList(members));
 	}
diff --git a/libsolidity/Types.h b/libsolidity/Types.h
index e6d32d175..ab41d4d4d 100644
--- a/libsolidity/Types.h
+++ b/libsolidity/Types.h
@@ -69,17 +69,43 @@ private:
 class MemberList
 {
 public:
-	using MemberMap = std::vector<std::pair<std::string, TypePointer>>;
+	struct Member
+	{
+		Member(std::string const& _name, TypePointer const& _type, Declaration const* _declaration = nullptr):
+			name(_name),
+			type(_type),
+			declaration(_declaration)
+		{
+		}
+
+		std::string name;
+		TypePointer type;
+		Declaration const* declaration = nullptr;
+	};
+
+	using MemberMap = std::vector<Member>;
 
 	MemberList() {}
 	explicit MemberList(MemberMap const& _members): m_memberTypes(_members) {}
 	MemberList& operator=(MemberList&& _other);
 	TypePointer getMemberType(std::string const& _name) const
 	{
+		TypePointer type;
 		for (auto const& it: m_memberTypes)
-			if (it.first == _name)
-				return it.second;
-		return TypePointer();
+			if (it.name == _name)
+			{
+				solAssert(!type, "Requested member type by non-unique name.");
+				type = it.type;
+			}
+		return type;
+	}
+	MemberMap membersByName(std::string const& _name) const
+	{
+		MemberMap members;
+		for (auto const& it: m_memberTypes)
+			if (it.name == _name)
+				members.push_back(it);
+		return members;
 	}
 	/// @returns the offset of the given member in storage slots and bytes inside a slot or
 	/// a nullptr if the member is not part of storage.
@@ -404,12 +430,20 @@ public:
 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
 	virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
 	virtual bool operator==(Type const& _other) const override;
+	virtual unsigned getCalldataEncodedSize(bool _padded = true) const override
+	{
+		return externalType()->getCalldataEncodedSize(_padded);
+	}
 	virtual unsigned getStorageBytes() const override { return 20; }
+	virtual bool canLiveOutsideStorage() const override { return true; }
 	virtual bool isValueType() const override { return true; }
 	virtual std::string toString() const override;
 
 	virtual MemberList const& getMembers() const override;
-	virtual TypePointer externalType() const override { return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address); }
+	virtual TypePointer externalType() const override
+	{
+		return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address);
+	}
 
 	bool isSuper() const { return m_super; }
 	ContractDefinition const& getContractDefinition() const { return m_contract; }
@@ -472,13 +506,21 @@ public:
 	explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
 	virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
 	virtual bool operator==(Type const& _other) const override;
+	virtual unsigned getCalldataEncodedSize(bool _padded = true) const override
+	{
+		return externalType()->getCalldataEncodedSize(_padded);
+	}
 	virtual unsigned getSizeOnStack() const override { return 1; }
 	virtual unsigned getStorageBytes() const override;
+	virtual bool canLiveOutsideStorage() const override { return true; }
 	virtual std::string toString() const override;
 	virtual bool isValueType() const override { return true; }
 
 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
-	virtual TypePointer externalType() const override { return std::make_shared<IntegerType>(8 * int(getStorageBytes())); }
+	virtual TypePointer externalType() const override
+	{
+		return std::make_shared<IntegerType>(8 * int(getStorageBytes()));
+	}
 
 	EnumDefinition const& getEnumDefinition() const { return m_enum; }
 	/// @returns the value that the string has in the Enum
@@ -512,9 +554,12 @@ public:
 
 	virtual Category getCategory() const override { return Category::Function; }
 
-	/// @returns TypePointer of a new FunctionType object. All input/return parameters are an appropriate external types of input/return parameters of current function.
-	/// Returns an empty shared pointer if one of the input/return parameters does not have an externaltype.
-	virtual TypePointer externalType() const override;
+	/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
+	/// appropriate external types of input/return parameters of current function.
+	/// Returns an empty shared pointer if one of the input/return parameters does not have an
+	/// external type.
+	virtual FunctionTypePointer externalFunctionType() const;
+	virtual TypePointer externalType() const override { return externalFunctionType(); }
 
 	explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
 	explicit FunctionType(VariableDeclaration const& _varDecl);
@@ -554,11 +599,18 @@ public:
 	virtual unsigned getSizeOnStack() const override;
 	virtual MemberList const& getMembers() const override;
 
+	/// @returns true if this function can take the given argument types (possibly
+	/// after implicit conversion).
+	bool canTakeArguments(TypePointers const& _arguments) const;
+	bool hasEqualArgumentTypes(FunctionType const& _other) const;
+
 	Location const& getLocation() const { return m_location; }
 	/// @returns the external signature of this function type given the function name
 	/// If @a _name is not provided (empty string) then the @c m_declaration member of the
 	/// function type is used
 	std::string externalSignature(std::string const& _name = "") const;
+	/// @returns the external identifier of this function (the hash of the signature).
+	u256 externalIdentifier() const;
 	Declaration const& getDeclaration() const
 	{
 		solAssert(m_declaration, "Requested declaration from a FunctionType that has none");
diff --git a/libtestutils/Common.cpp b/libtestutils/Common.cpp
index 86f96f667..5767be32c 100644
--- a/libtestutils/Common.cpp
+++ b/libtestutils/Common.cpp
@@ -20,6 +20,7 @@
  */
 
 #include <random>
+#include <boost/filesystem.hpp>
 #include <libdevcore/CommonData.h>
 #include <libdevcore/CommonIO.h>
 #include <libdevcrypto/FileSystem.h>
@@ -29,6 +30,8 @@ using namespace std;
 using namespace dev;
 using namespace dev::test;
 
+const char* TestChannel::name() { return "TST"; }
+
 std::string dev::test::getTestPath()
 {
 	string testPath;
@@ -71,6 +74,11 @@ std::string dev::test::toTestFilePath(std::string const& _filename)
 	return getTestPath() + "/" + _filename + ".json";
 }
 
+std::string dev::test::getFolder(std::string const& _file)
+{
+	return boost::filesystem::path(_file).parent_path().string();
+}
+
 std::string dev::test::getRandomPath()
 {
 	std::stringstream stream;
diff --git a/libtestutils/Common.h b/libtestutils/Common.h
index 4757a3b7a..866022464 100644
--- a/libtestutils/Common.h
+++ b/libtestutils/Common.h
@@ -30,13 +30,14 @@ namespace dev
 namespace test
 {
 
-struct TestChannel: public LogChannel  { static const char* name() { return "TEST"; } };
+struct TestChannel: public LogChannel  { static const char* name(); };
 #define ctest dev::LogOutputStream<dev::test::TestChannel, true>()
 
 std::string getTestPath();
 int randomNumber();
 Json::Value loadJsonFromFile(std::string const& _path);
 std::string toTestFilePath(std::string const& _filename);
+std::string getFolder(std::string const& _file);
 std::string getRandomPath();
 
 }
diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp
index d84bbd8f4..c14d26935 100644
--- a/mix/CodeModel.cpp
+++ b/mix/CodeModel.cpp
@@ -398,8 +398,8 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type)
 			StructType const* s = dynamic_cast<StructType const*>(_type);
 			for(auto const& structMember: s->getMembers())
 			{
-				auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.first);
-				r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.first), nodeType(structMember.second.get()), slotAndOffset.first, slotAndOffset.second });
+				auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name);
+				r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second });
 			}
 		}
 		break;
diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp
index 35d7dc413..b95dc5cf3 100644
--- a/mix/MixClient.cpp
+++ b/mix/MixClient.cpp
@@ -250,7 +250,7 @@ void MixClient::mine()
 {
 	WriteGuard l(x_state);
 	m_state.commitToMine(bc());
-	m_state.completeMine();
+	m_state.completeMine<Ethash>(Ethash::Solution());
 	bc().import(m_state.blockData(), m_stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce);
 	/*
 	GenericFarm<ProofOfWork> f;
diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml
index 7c4ef066f..e4d62ed81 100644
--- a/mix/qml/CodeEditorView.qml
+++ b/mix/qml/CodeEditorView.qml
@@ -3,6 +3,7 @@ import QtQuick.Window 2.0
 import QtQuick.Layouts 1.0
 import QtQuick.Controls 1.0
 import QtQuick.Dialogs 1.1
+import Qt.labs.settings 1.0
 
 Item {
 	id: codeEditorView
@@ -74,6 +75,7 @@ Item {
 		}
 		editor.document = document;
 		editor.sourceName = document.documentId;
+		editor.setFontSize(editorSettings.fontSize);
 		editor.setText(data, document.syntaxMode);
 		editor.changeGeneration();
 	}
@@ -158,6 +160,14 @@ Item {
 		}
 	}
 
+	function setFontSize(size) {
+		if (size <= 10 || size >= 48)
+			return;
+		editorSettings.fontSize = size;
+		for (var i = 0; i < editors.count; i++)
+			editors.itemAt(i).item.setFontSize(size);
+	}
+
 	Component.onCompleted: projectModel.codeEditor = codeEditorView;
 
 	Connections {
@@ -317,4 +327,23 @@ Item {
 	ListModel {
 		id: editorListModel
 	}
+
+	Action {
+		id: increaseFontSize
+		text: qsTr("Increase Font Size")
+		shortcut: "Ctrl+="
+		onTriggered: setFontSize(editorSettings.fontSize + 1)
+	}
+
+	Action {
+		id: decreaseFontSize
+		text: qsTr("Decrease Font Size")
+		shortcut: "Ctrl+-"
+		onTriggered: setFontSize(editorSettings.fontSize - 1)
+	}
+
+	Settings {
+		id: editorSettings
+		property int fontSize: 12;
+	}
 }
diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml
index 7c4a18492..38f2327b1 100644
--- a/mix/qml/WebCodeEditor.qml
+++ b/mix/qml/WebCodeEditor.qml
@@ -19,6 +19,7 @@ Item {
 	property var currentBreakpoints: []
 	property string sourceName
 	property var document
+	property int fontSize: 0
 
 	function setText(text, mode) {
 		currentText = text;
@@ -76,6 +77,12 @@ Item {
 			editorBrowser.runJavaScript("goToCompilationError()", function(result) {});
 	}
 
+	function setFontSize(size) {
+		fontSize = size;
+		if (initialized && editorBrowser)
+			editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {});
+	}
+
 	Clipboard
 	{
 		id: clipboard
@@ -108,6 +115,7 @@ Item {
 		{
 			if (!loading && editorBrowser) {
 				initialized = true;
+				setFontSize(fontSize);
 				setText(currentText, currentMode);
 				runJavaScript("getTextChanged()", function(result) { });
 				pollTimer.running = true;
diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml
index 72cb88401..4f7451680 100644
--- a/mix/qml/WebPreview.qml
+++ b/mix/qml/WebPreview.qml
@@ -186,7 +186,7 @@ Item {
 
 				if (documentName === urlInput.text.replace(httpServer.url + "/", "")) {
 					//root page, inject deployment script
-					content = "<script>web3=parent.web3;contracts=parent.contracts;</script>\n" + content;
+					content = "<script>web3=parent.web3;BigNumber=parent.BigNumber;contracts=parent.contracts;</script>\n" + content;
 					_request.setResponseContentType("text/html");
 				}
 				_request.setResponse(content);
diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html
index 30e203bed..9c458a4c7 100644
--- a/mix/qml/html/WebContainer.html
+++ b/mix/qml/html/WebContainer.html
@@ -21,6 +21,7 @@ updateContracts = function(contracts) {
 	if (window.web3) {
 		window.web3.reset();
 		window.contracts = {};
+		window.BigNumber = require('bignumber.js');
 		for (var c in contracts) {
 			var contractProto = window.web3.eth.contract(contracts[c].interface);
 			var contract = new contractProto(contracts[c].address);
diff --git a/mix/qml/html/cm/inkpot.css b/mix/qml/html/cm/inkpot.css
new file mode 100644
index 000000000..c6863e624
--- /dev/null
+++ b/mix/qml/html/cm/inkpot.css
@@ -0,0 +1,65 @@
+/*
+Inkpot theme for code-mirror
+https://github.com/ciaranm/inkpot
+*/
+
+/* Color scheme for code-mirror */
+
+.cm-s-inkpot.CodeMirror {
+  color: #cfbfad;
+  text-shadow: #1e1e27 0 1px;
+  background-color: #1e1e27;
+  line-height: 1.45em;
+  color-profile: sRGB;
+  rendering-intent: auto;
+}
+
+.cm-s-inkpot .CodeMirror-gutters { background: #2e2e2e; border-right: 0px solid #aaa; }
+.cm-s-inkpot .CodeMirror-linenumber { color: #8b8bcd; }
+.cm-s-inkpot .CodeMirror-cursor { border-left: 1px solid white !important; }
+
+.cm-s-inkpot span.cm-comment     { color: #cd8b00; }
+.cm-s-inkpot span.cm-def         { color: #cfbfad; font-weight:bold; }
+.cm-s-inkpot span.cm-keyword     { color: #808bed; }
+.cm-s-inkpot span.cm-builtin     { color: #cfbfad; }
+.cm-s-inkpot span.cm-variable    { color: #cfbfad; }
+.cm-s-inkpot span.cm-string      { color: #ffcd8b; }
+.cm-s-inkpot span.cm-number      { color: #f0ad6d; }
+.cm-s-inkpot span.cm-atom        { color: #cb6ecb; }
+.cm-s-inkpot span.cm-variable-2  { color: #ffb8ff; }
+
+.cm-s-inkpot span.cm-meta        { color: #409090; }
+.cm-s-inkpot span.cm-qualifier   { color: #808bed; }
+.cm-s-inkpot span.cm-tag         { color: #808bed; }
+.cm-s-inkpot span.cm-attribute   { color: #FF5555; }
+.cm-s-inkpot span.cm-error       { color: #f00; }
+
+.cm-s-inkpot .cm-bracket { color: #cb4b16; }
+.cm-s-inkpot .CodeMirror-matchingbracket { color: #859900; }
+.cm-s-inkpot .CodeMirror-nonmatchingbracket { color: #dc322f; }
+
+.cm-s-inkpot .CodeMirror-selected { background: #4e4e8f !important; }
+span.CodeMirror-selectedtext { color: #ffffff !important; }
+
+
+/* Code execution */
+.CodeMirror-exechighlight {
+	border-bottom: double 1px #94A2A2;
+}
+
+
+/* Error annotation */
+.CodeMirror-errorannotation {
+	border-bottom: 1px solid #DD3330;
+	margin-bottom: 4px;
+}
+
+.CodeMirror-errorannotation-context {
+	font-family: monospace;
+	color: #EEE9D5;
+	background: #b58900;
+	padding: 2px;
+	text-shadow: none !important;
+	border-top: solid 2px #063742;
+}
+
diff --git a/mix/qml/html/codeeditor.html b/mix/qml/html/codeeditor.html
index c9d4ff96a..f368404fe 100644
--- a/mix/qml/html/codeeditor.html
+++ b/mix/qml/html/codeeditor.html
@@ -1,7 +1,8 @@
 <!doctype html>
 <meta charset="utf-8"/>
 <link rel="stylesheet" href="cm/codemirror.css">
-<link rel="stylesheet" href="cm/solarized.css">
+<!--link rel="stylesheet" href="cm/solarized.css"-->
+<link rel="stylesheet" href="cm/inkpot.css">
 <link rel="stylesheet" href="cm/fullscreen.css">
 <link rel="stylesheet" href="cm/dialog.css">
 <link rel="stylesheet" href="cm/show-hint.css">
diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js
index 501e0bd57..e8504fee0 100644
--- a/mix/qml/html/codeeditor.js
+++ b/mix/qml/html/codeeditor.js
@@ -9,7 +9,7 @@ var editor = CodeMirror(document.body, {
 						});
 var ternServer;
 
-editor.setOption("theme", "solarized dark");
+editor.setOption("theme", "inkpot");
 editor.setOption("indentUnit", 4);
 editor.setOption("indentWithTabs", true);
 editor.setOption("fullScreen", true);
@@ -194,4 +194,11 @@ goToCompilationError = function()
 	editor.setCursor(annotation.line, annotation.column)
 }
 
+setFontSize = function(size)
+{
+	editor.getWrapperElement().style["font-size"] = size + "px";
+	editor.refresh();
+}
+
 editor.setOption("extraKeys", extraKeys);
+
diff --git a/mix/web.qrc b/mix/web.qrc
index 6870411c5..a34fd0b67 100644
--- a/mix/web.qrc
+++ b/mix/web.qrc
@@ -32,6 +32,7 @@
 		<file>qml/html/cm/show-hint.js</file>
 		<file>qml/html/cm/signal.js</file>
 		<file>qml/html/cm/solarized.css</file>
+		<file>qml/html/cm/inkpot.css</file>
 		<file>qml/html/cm/solidity.js</file>
 		<file>qml/html/cm/solidityToken.js</file>
 		<file>qml/html/cm/tern.js</file>
diff --git a/neth/main.cpp b/neth/main.cpp
index 31df2ffcb..4e83f64bc 100644
--- a/neth/main.cpp
+++ b/neth/main.cpp
@@ -542,7 +542,7 @@ int main(int argc, char** argv)
 	VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
 	auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
 	auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp");
-	std::string clientImplString = "NEthereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
+	std::string clientImplString = "N++eth/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : "");
 	dev::WebThreeDirect web3(
 		clientImplString,
 		dbPath,
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 90af5122e..a97bb86fc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,14 +1,39 @@
 cmake_policy(SET CMP0015 NEW)
 
 aux_source_directory(. SRC_LIST)
-list(REMOVE_ITEM SRC_LIST "./createRandomVMTest.cpp")
-list(REMOVE_ITEM SRC_LIST "./createRandomStateTest.cpp")
-list(REMOVE_ITEM SRC_LIST "./checkRandomVMTest.cpp")
-list(REMOVE_ITEM SRC_LIST "./checkRandomStateTest.cpp")
 
-if (NOT JSONRPC)
-	list(REMOVE_ITEM SRC_LIST "./AccountHolder.cpp")
-endif()
+macro (add_sources)
+	file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}")
+	foreach (_src ${ARGN})
+		if (_relPath)
+			list (APPEND SRC "${_relPath}/${_src}")
+		else()
+			list (APPEND SRC "${_src}")
+		endif()
+	endforeach()
+	if (_relPath)
+		# propagate SRCS to parent directory
+		set (SRC ${SRC} PARENT_SCOPE)
+	endif()
+endmacro()
+
+add_subdirectory(fuzzTesting)
+add_subdirectory(libdevcore)
+add_subdirectory(libdevcrypto)
+add_subdirectory(libethcore)
+add_subdirectory(libethereum)
+add_subdirectory(libevm)
+add_subdirectory(libnatspec)
+add_subdirectory(libp2p)
+if (SOLIDITY)
+	add_subdirectory(libsolidity)
+endif ()
+if (JSONRPC)
+add_subdirectory(libweb3jsonrpc)
+endif ()
+add_subdirectory(libwhisper)
+
+set(SRC_LIST ${SRC_LIST} ${SRC})
 
 include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
 include_directories(BEFORE ..)
@@ -34,10 +59,6 @@ endforeach(file)
 
 file(GLOB HEADERS "*.h")
 add_executable(testeth ${SRC_LIST} ${HEADERS})
-add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp)
-add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp Stats.cpp)
-add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp)
-add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp Stats.cpp)
 
 target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
 target_link_libraries(testeth ${CURL_LIBRARIES})
@@ -57,23 +78,6 @@ if (JSONRPC)
 	target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
 endif()
 
-target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
-target_link_libraries(createRandomVMTest ethereum)
-target_link_libraries(createRandomVMTest ethcore)
-target_link_libraries(createRandomVMTest  testutils)
-target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
-target_link_libraries(createRandomStateTest ethereum)
-target_link_libraries(createRandomStateTest ethcore)
-target_link_libraries(createRandomStateTest testutils)
-target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
-target_link_libraries(checkRandomVMTest ethereum)
-target_link_libraries(checkRandomVMTest ethcore)
-target_link_libraries(checkRandomVMTest testutils)
-target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
-target_link_libraries(checkRandomStateTest ethereum)
-target_link_libraries(checkRandomStateTest ethcore)
-target_link_libraries(checkRandomStateTest testutils)
-
 enable_testing()
 set(CTEST_OUTPUT_ON_FAILURE TRUE)
 
diff --git a/test/JSON_test.sol b/test/JSON_test.sol
new file mode 100644
index 000000000..ffd7cdc40
--- /dev/null
+++ b/test/JSON_test.sol
@@ -0,0 +1,120 @@
+ contract JSON_Test {
+    event Log0(uint value) ;
+    event Log0Anonym (uint value) anonymous;
+    event Log1(bool indexed aBool, uint value);
+    event Log1Anonym(bool indexed aBool, uint value) anonymous;
+    event Log2(bool indexed aBool, address indexed aAddress, uint value);
+    event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous;
+    event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value);
+    event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous;
+    event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value);
+    event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous;
+
+    function JSON_Test() {
+    }
+
+    function setBool(bool _bool) {
+        myBool = _bool;
+    }
+    
+    function setInt8(int8 _int8) {
+        myInt8 = _int8;
+    }
+    
+    function setUint8(uint8 _uint8) {
+        myUint8 = _uint8;
+    }
+    
+    function setInt256(int256 _int256) {
+        myInt256 = _int256;
+    }
+    
+    function setUint256(uint256 _uint256) {
+        myUint256 = _uint256;
+    }
+    
+    function setAddress(address _address) {
+        myAddress = _address;
+    }
+
+    function setBytes32(bytes32 _bytes32) {
+        myBytes32 = _bytes32;
+    }
+    
+    function getBool() returns (bool ret) {
+        return myBool;
+    }
+    
+    function getInt8() returns (int8 ret) {
+        return myInt8;
+    }
+    
+    function getUint8() returns (uint8 ret)  {
+        return myUint8;
+    }
+    
+    function getInt256() returns (int256 ret) {
+        return myInt256;
+    }
+    
+    function getUint256() returns (uint256 ret) {
+        return myUint256;
+    }
+    
+    function getAddress() returns (address ret) {
+        return myAddress;
+    }
+    
+    function getBytes32() returns (bytes32 ret) {
+        return myBytes32;
+    }
+    
+    function fireEventLog0() {
+        Log0(42);
+    }
+    
+    function fireEventLog0Anonym() {
+        Log0Anonym(42);
+    }
+    
+    function fireEventLog1() {
+        Log1(true, 42);
+    }
+    
+    function fireEventLog1Anonym() {
+        Log1Anonym(true, 42);
+    }
+    
+    function fireEventLog2() {
+        Log2(true, msg.sender, 42);
+    }
+    
+    function fireEventLog2Anonym() {
+        Log2Anonym(true, msg.sender, 42);
+    }
+    
+    function fireEventLog3() {
+        Log3(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42);
+    }
+    
+    function fireEventLog3Anonym() {
+        Log3Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42);
+    }
+    
+    function fireEventLog4() {
+        Log4(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42);
+    }
+    
+    function fireEventLog4Anonym() {
+        Log4Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42);
+    }
+
+    bool myBool;
+    int8 myInt8;
+    uint8 myUint8;
+    int256 myInt256;
+    uint256 myUint256;
+    address myAddress;
+    bytes32 myBytes32;    
+}
+
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp
index ed844e961..724bcaf61 100644
--- a/test/TestHelper.cpp
+++ b/test/TestHelper.cpp
@@ -23,9 +23,6 @@
 
 #include <thread>
 #include <chrono>
-
-#include <boost/filesystem/path.hpp>
-
 #include <libethereum/Client.h>
 #include <liblll/Compiler.h>
 #include <libevm/VMFactory.h>
@@ -542,6 +539,8 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e
 
 void userDefinedTest(string testTypeFlag, std::function<void(json_spirit::mValue&, bool)> doTests)
 {
+	Options::get(); // parse command line options, e.g. to enable JIT
+
 	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
 	{
 		string arg = boost::unit_test::framework::master_test_suite().argv[i];
@@ -592,7 +591,7 @@ void userDefinedTest(string testTypeFlag, std::function<void(json_spirit::mValue
 	}
 }
 
-void executeTests(const string& _name, const string& _testPathAppendix, std::function<void(json_spirit::mValue&, bool)> doTests)
+void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function<void(json_spirit::mValue&, bool)> doTests)
 {
 	string testPath = getTestPath();
 	testPath += _testPathAppendix;
@@ -607,9 +606,8 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun
 			cnote << "Populating tests...";
 			json_spirit::mValue v;
 			boost::filesystem::path p(__FILE__);
-			boost::filesystem::path dir = p.parent_path();
-			string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json"));
-			BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty.");
+			string s = asString(dev::contents(_pathToFiller.string() + "/" + _name + "Filler.json"));
+			BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + _pathToFiller.string() + "/" + _name + "Filler.json is empty.");
 			json_spirit::read_string(s, v);
 			doTests(v, true);
 			writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true)));
diff --git a/test/TestHelper.h b/test/TestHelper.h
index 36a84ecdb..bf4cdc16e 100644
--- a/test/TestHelper.h
+++ b/test/TestHelper.h
@@ -24,6 +24,7 @@
 #include <functional>
 
 #include <boost/test/unit_test.hpp>
+#include <boost/filesystem.hpp>
 
 #include "JsonSpiritHeaders.h"
 #include <libethereum/State.h>
@@ -155,7 +156,7 @@ void checkStorage(std::map<u256, u256> _expectedStore, std::map<u256, u256> _res
 void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs);
 void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates);
 
-void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function<void(json_spirit::mValue&, bool)> doTests);
+void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function<void(json_spirit::mValue&, bool)> doTests);
 void userDefinedTest(std::string testTypeFlag, std::function<void(json_spirit::mValue&, bool)> doTests);
 RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj);
 eth::LastHashes lastHashes(u256 _currentBlockNumber);
diff --git a/test/bcJS_API_TestFiller.json b/test/bcJS_API_TestFiller.json
deleted file mode 100644
index fe7396e59..000000000
--- a/test/bcJS_API_TestFiller.json
+++ /dev/null
@@ -1,247 +0,0 @@
-{
-    "JS_API_Tests" : {
-        "genesisBlockHeader" : {
-            "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-            "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
-            "difficulty" : "131072",
-            "extraData" : "0x42",
-            "gasLimit" : "3141592",
-            "gasUsed" : "0",
-            "number" : "0",
-            "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
-            "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
-            "timestamp" : "0x54c98c81",
-            "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "nonce" : "0x0102030405060708",
-            "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-            "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
-        },
-	"expect" : {
-            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
-                "balance" : "70"
-            },
-            "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
-                "storage" : {
-                    "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
-                    "0x01" : "0x42",
-                    "0x02" : "0x23",
-                    "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
-                    "0x04" : "0x01",
-                    "0x05" : "0x55114a49"
-                }
-            }
-	},
-        "pre" : {
-            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
-                "balance" : "10000000000000",
-                "nonce" : "0",
-                "code" : "",
-                "storage": {}
-            },
-            "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
-                "balance" : "100000",
-                "code" : "0x60003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b5056",
-                "nonce" : "0",
-                "storage" : {
-                    "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
-                    "0x01" : "0x42",
-                    "0x02" : "0x23",
-                    "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
-                    "0x05" : "0x54c98c81"
-                }
-            }
-        },
-        "blocks" : [
-            {
-                "transactions" : [
-                    {
-                        "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023",
-                        "gasLimit" : "600000",
-                        "gasPrice" : "1",
-                        "nonce" : "0",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "",
-                        "value" : "100000"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "1",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "0xfcfff16f",
-                        "gasLimit" : "600000",
-                        "gasPrice" : "1",
-                        "nonce" : "2",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
-                        "value" : "0x42"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "3",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                    {
-                        "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                        "coinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
-                        "difficulty" : "131072",
-                        "extraData" : "0x",
-                        "gasLimit" : "3141592",
-                        "gasUsed" : "0",
-                        "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
-                        "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
-                        "nonce" : "18a524c1790fa83b",
-                        "number" : "2",
-                        "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
-                        "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
-                        "timestamp" : "0x54c98c82",
-                        "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
-                    },
-                    {
-                        "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                        "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b",
-                        "difficulty" : "131072",
-                        "extraData" : "0x",
-                        "gasLimit" : "3141592",
-                        "gasUsed" : "0",
-                        "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
-                        "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
-                        "nonce" : "18a524c1790fa83b",
-                        "number" : "2",
-                        "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
-                        "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
-                        "timestamp" : "0x54c98c82",
-                        "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
-                    }
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "4",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "5",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                    {
-                        "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                        "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b",
-                        "difficulty" : "131072",
-                        "extraData" : "0x",
-                        "gasLimit" : "314159",
-                        "gasUsed" : "0",
-                        "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
-                        "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
-                        "nonce" : "18a524c1790fa83b",
-                        "number" : "2",
-                        "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
-                        "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
-                        "timestamp" : "0x54c98c82",
-                        "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
-                        "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
-                    }
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "6",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "7",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            },
-            {
-                "transactions" : [
-                    {
-                        "data" : "",
-                        "gasLimit" : "314159",
-                        "gasPrice" : "1",
-                        "nonce" : "8",
-                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-                        "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-                        "value" : "10"
-                    }
-                ],
-                "uncleHeaders" : [
-                ]
-            }
-        ]
-    }
-}
diff --git a/test/bcRPC_API_TestFiller.json b/test/bcRPC_API_TestFiller.json
new file mode 100644
index 000000000..b31f1fa48
--- /dev/null
+++ b/test/bcRPC_API_TestFiller.json
@@ -0,0 +1,579 @@
+{
+    "RPC_API_Test" : {
+        "genesisBlockHeader" : {
+            "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
+            "difficulty" : "131072",
+            "extraData" : "0x42",
+            "gasLimit" : "3141592",
+            "gasUsed" : "0",
+            "number" : "0",
+            "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+            "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
+            "timestamp" : "0x54c98c81",
+            "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "nonce" : "0x0102030405060708",
+            "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+            "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
+        },
+        "pre" : {
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "10000000000000",
+                "nonce" : "0",
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "blocks" : [
+            {
+                "transactions" : [
+                    {
+                        "data" : "create contract: 6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "data" : "0x5b5b610705806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104d6565b60006000f35b61014261039b565b8060005260206000f35b610157600435610326565b60006000f35b6101686004356102c9565b60006000f35b610176610442565b8060005260206000f35b6101886103d3565b8060ff1660005260206000f35b61019d610413565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104c5565b60006000f35b6101d36103b7565b8060000b60005260206000f35b6101e8610454565b60006000f35b6101f6610401565b8060005260206000f35b61020861051f565b60006000f35b6102196004356102e5565b60006000f35b610227610693565b60006000f35b610238600435610342565b60006000f35b610246610484565b60006000f35b610254610493565b60006000f35b61026560043561038d565b60006000f35b610276600435610350565b60006000f35b61028760043561035e565b60006000f35b6102956105b4565b60006000f35b6102a3610547565b60006000f35b6102b16103ef565b8060005260206000f35b6102c3610600565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff02191690837f01000000000000000000000000000000000000000000000000000000000000009081020402179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff1690506103b4565b90565b6000600060019054906101000a900460000b90506103d0565b90565b6000600060029054906101000a900460ff1690506103ec565b90565b600060016000505490506103fe565b90565b60006002600050549050610410565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061043f565b90565b60006004600050549050610451565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56",
+                        "gasLimit" : "3141592",
+                        "gasPrice" : "1",
+                        "nonce" : "0",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getBool",
+                        "data" : "0x12a7b914",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "1",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getInt8",
+                        "data" : "0x57cb2fc4",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "2",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getUint8",
+                        "data" : "0x343a875d",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "3",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                    {
+                        "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                        "coinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+                        "difficulty" : "131072",
+                        "extraData" : "0x",
+                        "gasLimit" : "3141592",
+                        "gasUsed" : "0",
+                        "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
+                        "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
+                        "nonce" : "18a524c1790fa83b",
+                        "number" : "2",
+                        "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
+                        "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+                        "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
+                        "timestamp" : "0x54c98c82",
+                        "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+                        "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
+                    },
+                    {
+                        "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                        "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b",
+                        "difficulty" : "131072",
+                        "extraData" : "0x",
+                        "gasLimit" : "3141592",
+                        "gasUsed" : "0",
+                        "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
+                        "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
+                        "nonce" : "18a524c1790fa83b",
+                        "number" : "2",
+                        "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
+                        "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+                        "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
+                        "timestamp" : "0x54c98c82",
+                        "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+                        "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
+                    }
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getInt256",
+                        "data" : "0xf5b53e17",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "4",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getUint256",
+                        "data" : "0x68895979",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "5",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getAddress",
+                        "data" : "0x38cc4831",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "6",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getBytes32",
+                        "data" : "0x1f903037",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "7",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setBool",
+                        "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "8",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setBool",
+                        "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "9",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setInt8",
+                        "data" : "0x9a19a953fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "10",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setUint8",
+                        "data" : "0x1774e6460000000000000000000000000000000000000000000000000000000000000008",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "11",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setInt256",
+                        "data" : "0xa53b1c1effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "12",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setUint256",
+                        "data" : "0xd2282dc5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "13",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setAddress",
+                        "data" : "0xe30081a0aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "14",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "setBytes32",
+                        "data" : "0xc2b12a73aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "15",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getInt8",
+                        "data" : "0x57cb2fc4",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "16",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getUint8",
+                        "data" : "0x343a875d",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "17",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getInt256",
+                        "data" : "0xf5b53e17",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "18",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getUint256",
+                        "data" : "0x68895979",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "19",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getAddress",
+                        "data" : "0x38cc4831",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "20",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "getBytes32",
+                        "data" : "0x1f903037",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "21",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log0",
+                        "data" : "0x65538c73",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "22",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log0a",
+                        "data" : "0xa6780857",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "23",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log1",
+                        "data" : "0xb61c0503",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "24",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log1a",
+                        "data" : "0x4e7ad367",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "25",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log2",
+                        "data" : "0x102accc1",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "26",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log2a",
+                        "data" : "0x76bc21d9",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "27",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log3",
+                        "data" : "0xf38b0600",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "28",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log3a",
+                        "data" : "0xe8beef5b",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "29",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log4",
+                        "data" : "0xfd408767",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "30",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            },
+            {
+                "transactions" : [
+                    {
+                        "data" : "log4a",
+                        "data" : "0x9dc2c8f5",
+                        "gasLimit" : "314159",
+                        "gasPrice" : "1",
+                        "nonce" : "31",
+                        "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+                        "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f",
+                        "value" : "10"
+                    }
+                ],
+                "uncleHeaders" : [
+                ]
+            }
+        ]
+    }
+}
diff --git a/test/fork.cpp b/test/deprecated/fork.cpp
similarity index 100%
rename from test/fork.cpp
rename to test/deprecated/fork.cpp
diff --git a/test/kademlia.cpp b/test/deprecated/kademlia.cpp
similarity index 100%
rename from test/kademlia.cpp
rename to test/deprecated/kademlia.cpp
diff --git a/test/main.cpp b/test/deprecated/main.cpp
similarity index 100%
rename from test/main.cpp
rename to test/deprecated/main.cpp
diff --git a/test/txTest.cpp b/test/deprecated/txTest.cpp
similarity index 100%
rename from test/txTest.cpp
rename to test/deprecated/txTest.cpp
diff --git a/test/fuzzTesting/CMakeLists.txt b/test/fuzzTesting/CMakeLists.txt
new file mode 100644
index 000000000..b0b3b0776
--- /dev/null
+++ b/test/fuzzTesting/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_policy(SET CMP0015 NEW)
+
+file(GLOB HEADERS "*.h")
+include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
+include_directories(BEFORE ..)
+include_directories(BEFORE ../..)
+include_directories(${Boost_INCLUDE_DIRS})
+include_directories(${CRYPTOPP_INCLUDE_DIRS})
+include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
+
+add_executable(createRandomVMTest "./createRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp")
+add_executable(createRandomStateTest "./createRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp")
+add_executable(checkRandomVMTest "./checkRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp")
+add_executable(checkRandomStateTest "./checkRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp")
+
+target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
+target_link_libraries(createRandomVMTest ethereum)
+target_link_libraries(createRandomVMTest ethcore)
+target_link_libraries(createRandomVMTest  testutils)
+target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
+target_link_libraries(createRandomStateTest ethereum)
+target_link_libraries(createRandomStateTest ethcore)
+target_link_libraries(createRandomStateTest testutils)
+target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
+target_link_libraries(checkRandomVMTest ethereum)
+target_link_libraries(checkRandomVMTest ethcore)
+target_link_libraries(checkRandomVMTest testutils)
+target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
+target_link_libraries(checkRandomStateTest ethereum)
+target_link_libraries(checkRandomStateTest ethcore)
+target_link_libraries(checkRandomStateTest testutils)
diff --git a/test/checkRandomStateTest.cpp b/test/fuzzTesting/checkRandomStateTest.cpp
similarity index 99%
rename from test/checkRandomStateTest.cpp
rename to test/fuzzTesting/checkRandomStateTest.cpp
index 49aca852f..260f9e004 100644
--- a/test/checkRandomStateTest.cpp
+++ b/test/fuzzTesting/checkRandomStateTest.cpp
@@ -26,7 +26,7 @@
 #include <libdevcore/Log.h>
 #include <libevm/VMFactory.h>
 #include "TestHelper.h"
-#include "vm.h"
+#include "../libevm/vm.h"
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 
 using namespace std;
diff --git a/test/checkRandomVMTest.cpp b/test/fuzzTesting/checkRandomVMTest.cpp
similarity index 99%
rename from test/checkRandomVMTest.cpp
rename to test/fuzzTesting/checkRandomVMTest.cpp
index a40922577..bb55dcffa 100644
--- a/test/checkRandomVMTest.cpp
+++ b/test/fuzzTesting/checkRandomVMTest.cpp
@@ -25,7 +25,8 @@
 #include <libdevcore/Exceptions.h>
 #include <libdevcore/Log.h>
 #include <libevm/VMFactory.h>
-#include "vm.h"
+#include "../libevm/vm.h"
+
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 
 using namespace std;
diff --git a/test/createRandomStateTest.cpp b/test/fuzzTesting/createRandomStateTest.cpp
similarity index 99%
rename from test/createRandomStateTest.cpp
rename to test/fuzzTesting/createRandomStateTest.cpp
index 5758598b9..6e42934bc 100644
--- a/test/createRandomStateTest.cpp
+++ b/test/fuzzTesting/createRandomStateTest.cpp
@@ -35,8 +35,8 @@
 #include <libdevcore/CommonData.h>
 #include <libevmcore/Instruction.h>
 #include <libevm/VMFactory.h>
-#include "TestHelper.h"
-#include "vm.h"
+#include "../TestHelper.h"
+#include "../libevm/vm.h"
 
 using namespace std;
 using namespace json_spirit;
diff --git a/test/createRandomVMTest.cpp b/test/fuzzTesting/createRandomVMTest.cpp
similarity index 99%
rename from test/createRandomVMTest.cpp
rename to test/fuzzTesting/createRandomVMTest.cpp
index de81099fe..abb4e184b 100644
--- a/test/createRandomVMTest.cpp
+++ b/test/fuzzTesting/createRandomVMTest.cpp
@@ -35,7 +35,7 @@
 #include <libdevcore/CommonData.h>
 #include <libevmcore/Instruction.h>
 #include <libevm/VMFactory.h>
-#include "vm.h"
+#include "../libevm/vm.h"
 
 using namespace std;
 using namespace json_spirit;
diff --git a/test/libdevcore/CMakeLists.txt b/test/libdevcore/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libdevcore/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/rlp.cpp b/test/libdevcore/rlp.cpp
similarity index 98%
rename from test/rlp.cpp
rename to test/libdevcore/rlp.cpp
index 9062b54f4..41362d569 100644
--- a/test/rlp.cpp
+++ b/test/libdevcore/rlp.cpp
@@ -30,8 +30,8 @@
 #include <libdevcore/Common.h>
 #include <libdevcore/CommonIO.h>
 #include <algorithm>
-#include "JsonSpiritHeaders.h"
-#include "TestHelper.h"
+#include "../JsonSpiritHeaders.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/libdevcrypto/CMakeLists.txt b/test/libdevcrypto/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libdevcrypto/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/MemTrie.cpp b/test/libdevcrypto/MemTrie.cpp
similarity index 100%
rename from test/MemTrie.cpp
rename to test/libdevcrypto/MemTrie.cpp
diff --git a/test/MemTrie.h b/test/libdevcrypto/MemTrie.h
similarity index 100%
rename from test/MemTrie.h
rename to test/libdevcrypto/MemTrie.h
diff --git a/test/TrieHash.cpp b/test/libdevcrypto/TrieHash.cpp
similarity index 100%
rename from test/TrieHash.cpp
rename to test/libdevcrypto/TrieHash.cpp
diff --git a/test/TrieHash.h b/test/libdevcrypto/TrieHash.h
similarity index 100%
rename from test/TrieHash.h
rename to test/libdevcrypto/TrieHash.h
diff --git a/test/crypto.cpp b/test/libdevcrypto/crypto.cpp
similarity index 100%
rename from test/crypto.cpp
rename to test/libdevcrypto/crypto.cpp
diff --git a/test/hexPrefix.cpp b/test/libdevcrypto/hexPrefix.cpp
similarity index 96%
rename from test/hexPrefix.cpp
rename to test/libdevcrypto/hexPrefix.cpp
index da294ba5b..c72f24535 100644
--- a/test/hexPrefix.cpp
+++ b/test/libdevcrypto/hexPrefix.cpp
@@ -24,11 +24,11 @@
 
 #include <boost/test/unit_test.hpp>
 
-#include "JsonSpiritHeaders.h"
+#include "../JsonSpiritHeaders.h"
 #include <libdevcore/Log.h>
 #include <libdevcore/CommonIO.h>
 #include <libdevcrypto/TrieCommon.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/trie.cpp b/test/libdevcrypto/trie.cpp
similarity index 99%
rename from test/trie.cpp
rename to test/libdevcrypto/trie.cpp
index 9e59dd316..0e7125624 100644
--- a/test/trie.cpp
+++ b/test/libdevcrypto/trie.cpp
@@ -25,12 +25,12 @@
 
 #include <boost/test/unit_test.hpp>
 
-#include "JsonSpiritHeaders.h"
+#include "../JsonSpiritHeaders.h"
 #include <libdevcore/CommonIO.h>
 #include <libdevcrypto/TrieDB.h>
 #include "TrieHash.h"
 #include "MemTrie.h"
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/libethcore/CMakeLists.txt b/test/libethcore/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libethcore/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/commonjs.cpp b/test/libethcore/commonjs.cpp
similarity index 100%
rename from test/commonjs.cpp
rename to test/libethcore/commonjs.cpp
diff --git a/test/dagger.cpp b/test/libethcore/dagger.cpp
similarity index 97%
rename from test/dagger.cpp
rename to test/libethcore/dagger.cpp
index cb8908d32..119780346 100644
--- a/test/dagger.cpp
+++ b/test/libethcore/dagger.cpp
@@ -22,12 +22,12 @@
 
 #include <fstream>
 #include <random>
-#include "JsonSpiritHeaders.h"
+#include "../JsonSpiritHeaders.h"
 #include <libdevcore/CommonIO.h>
 #include <libethcore/ProofOfWork.h>
 #include <libethcore/EthashAux.h>
 #include <boost/test/unit_test.hpp>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/bcInvalidHeaderTestFiller.json b/test/libethereum/BlockTestsFiller/bcInvalidHeaderTestFiller.json
similarity index 100%
rename from test/bcInvalidHeaderTestFiller.json
rename to test/libethereum/BlockTestsFiller/bcInvalidHeaderTestFiller.json
diff --git a/test/bcUncleHeaderValiditiyFiller.json b/test/libethereum/BlockTestsFiller/bcUncleHeaderValiditiyFiller.json
similarity index 100%
rename from test/bcUncleHeaderValiditiyFiller.json
rename to test/libethereum/BlockTestsFiller/bcUncleHeaderValiditiyFiller.json
diff --git a/test/bcUncleTestFiller.json b/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json
similarity index 100%
rename from test/bcUncleTestFiller.json
rename to test/libethereum/BlockTestsFiller/bcUncleTestFiller.json
diff --git a/test/bcValidBlockTestFiller.json b/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json
similarity index 100%
rename from test/bcValidBlockTestFiller.json
rename to test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json
diff --git a/test/libethereum/CMakeLists.txt b/test/libethereum/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libethereum/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/ClientBase.cpp b/test/libethereum/ClientBase.cpp
similarity index 99%
rename from test/ClientBase.cpp
rename to test/libethereum/ClientBase.cpp
index 7597b6612..9ee93779e 100644
--- a/test/ClientBase.cpp
+++ b/test/libethereum/ClientBase.cpp
@@ -21,7 +21,7 @@
 
 #include <boost/test/unit_test.hpp>
 #include <libdevcore/CommonJS.h>
-#include "TestUtils.h"
+#include "../TestUtils.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/ManyFunctions.sol b/test/libethereum/StateTestsFiller/ManyFunctions.sol
similarity index 100%
rename from test/ManyFunctions.sol
rename to test/libethereum/StateTestsFiller/ManyFunctions.sol
diff --git a/test/ManyFunctionsGenerator.py b/test/libethereum/StateTestsFiller/ManyFunctionsGenerator.py
similarity index 100%
rename from test/ManyFunctionsGenerator.py
rename to test/libethereum/StateTestsFiller/ManyFunctionsGenerator.py
diff --git a/test/stBlockHashTestFiller.json b/test/libethereum/StateTestsFiller/stBlockHashTestFiller.json
similarity index 100%
rename from test/stBlockHashTestFiller.json
rename to test/libethereum/StateTestsFiller/stBlockHashTestFiller.json
diff --git a/test/stCallCreateCallCodeTestFiller.json b/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json
similarity index 100%
rename from test/stCallCreateCallCodeTestFiller.json
rename to test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json
diff --git a/test/stExampleFiller.json b/test/libethereum/StateTestsFiller/stExampleFiller.json
similarity index 100%
rename from test/stExampleFiller.json
rename to test/libethereum/StateTestsFiller/stExampleFiller.json
diff --git a/test/stInitCodeTestFiller.json b/test/libethereum/StateTestsFiller/stInitCodeTestFiller.json
similarity index 100%
rename from test/stInitCodeTestFiller.json
rename to test/libethereum/StateTestsFiller/stInitCodeTestFiller.json
diff --git a/test/stLogTestsFiller.json b/test/libethereum/StateTestsFiller/stLogTestsFiller.json
similarity index 100%
rename from test/stLogTestsFiller.json
rename to test/libethereum/StateTestsFiller/stLogTestsFiller.json
diff --git a/test/stMemoryStressTestFiller.json b/test/libethereum/StateTestsFiller/stMemoryStressTestFiller.json
similarity index 100%
rename from test/stMemoryStressTestFiller.json
rename to test/libethereum/StateTestsFiller/stMemoryStressTestFiller.json
diff --git a/test/stMemoryTestFiller.json b/test/libethereum/StateTestsFiller/stMemoryTestFiller.json
similarity index 100%
rename from test/stMemoryTestFiller.json
rename to test/libethereum/StateTestsFiller/stMemoryTestFiller.json
diff --git a/test/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json
similarity index 100%
rename from test/stPreCompiledContractsFiller.json
rename to test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json
diff --git a/test/stQuadraticComplexityTestFiller.json b/test/libethereum/StateTestsFiller/stQuadraticComplexityTestFiller.json
similarity index 100%
rename from test/stQuadraticComplexityTestFiller.json
rename to test/libethereum/StateTestsFiller/stQuadraticComplexityTestFiller.json
diff --git a/test/stRecursiveCreateFiller.json b/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json
similarity index 100%
rename from test/stRecursiveCreateFiller.json
rename to test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json
diff --git a/test/stRefundTestFiller.json b/test/libethereum/StateTestsFiller/stRefundTestFiller.json
similarity index 100%
rename from test/stRefundTestFiller.json
rename to test/libethereum/StateTestsFiller/stRefundTestFiller.json
diff --git a/test/stSolidityTestFiller.json b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json
similarity index 100%
rename from test/stSolidityTestFiller.json
rename to test/libethereum/StateTestsFiller/stSolidityTestFiller.json
diff --git a/test/stSpecialTestFiller.json b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json
similarity index 100%
rename from test/stSpecialTestFiller.json
rename to test/libethereum/StateTestsFiller/stSpecialTestFiller.json
diff --git a/test/stSystemOperationsTestFiller.json b/test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json
similarity index 100%
rename from test/stSystemOperationsTestFiller.json
rename to test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json
diff --git a/test/stTransactionTestFiller.json b/test/libethereum/StateTestsFiller/stTransactionTestFiller.json
similarity index 100%
rename from test/stTransactionTestFiller.json
rename to test/libethereum/StateTestsFiller/stTransactionTestFiller.json
diff --git a/test/tt10mbDataFieldFiller.json b/test/libethereum/TransactionTestsFiller/tt10mbDataFieldFiller.json
similarity index 100%
rename from test/tt10mbDataFieldFiller.json
rename to test/libethereum/TransactionTestsFiller/tt10mbDataFieldFiller.json
diff --git a/test/ttTransactionTestFiller.json b/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json
similarity index 100%
rename from test/ttTransactionTestFiller.json
rename to test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json
diff --git a/test/blockchain.cpp b/test/libethereum/blockchain.cpp
similarity index 93%
rename from test/blockchain.cpp
rename to test/libethereum/blockchain.cpp
index ec8fb7539..28d838469 100644
--- a/test/blockchain.cpp
+++ b/test/libethereum/blockchain.cpp
@@ -24,7 +24,7 @@
 #include <libdevcrypto/FileSystem.h>
 #include <libdevcore/TransientDirectory.h>
 #include <libethereum/CanonBlockChain.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace json_spirit;
@@ -52,8 +52,10 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
 
 		BOOST_REQUIRE(o.count("pre"));
 		ImportTest importer(o["pre"].get_obj());
-		State state(OverlayDB(), BaseState::Empty, biGenesisBlock.coinbaseAddress);
-		State stateTemp(OverlayDB(), BaseState::Empty, biGenesisBlock.coinbaseAddress);
+		TransientDirectory td_stateDB;
+		TransientDirectory td_stateDB_tmp;
+		State state(OverlayDB(State::openDB(td_stateDB.path())), BaseState::Empty, biGenesisBlock.coinbaseAddress);
+		State stateTemp(OverlayDB(State::openDB(td_stateDB_tmp.path())), BaseState::Empty, biGenesisBlock.coinbaseAddress);
 		importer.importState(o["pre"].get_obj(), state);
 		o["pre"] = fillJsonWithState(state);
 		state.commit();
@@ -289,6 +291,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
 					state = stateTemp; //revert state as if it was before executing this block
 				}
 				blArray.push_back(blObj);
+				this_thread::sleep_for(chrono::seconds(1));
 			} //for blocks
 
 			if (o.count("expect") > 0)
@@ -625,11 +628,11 @@ void writeBlockHeaderToJson(mObject& _o, BlockInfo const& _bi)
 	_o["transactionsTrie"] = toString(_bi.transactionsRoot);
 	_o["receiptTrie"] = toString(_bi.receiptsRoot);
 	_o["bloom"] = toString(_bi.logBloom);
-	_o["difficulty"] = "0x" + toHex(toCompactBigEndian(_bi.difficulty), 1);
-	_o["number"] = "0x" + toHex(toCompactBigEndian(_bi.number), 1);
-	_o["gasLimit"] = "0x" + toHex(toCompactBigEndian(_bi.gasLimit), 1);
-	_o["gasUsed"] = "0x" + toHex(toCompactBigEndian(_bi.gasUsed), 1);
-	_o["timestamp"] = "0x" + toHex(toCompactBigEndian(_bi.timestamp), 1);
+	_o["difficulty"] = "0x" + toHex(toCompactBigEndian(_bi.difficulty, 1));
+	_o["number"] = "0x" + toHex(toCompactBigEndian(_bi.number, 1));
+	_o["gasLimit"] = "0x" + toHex(toCompactBigEndian(_bi.gasLimit, 1));
+	_o["gasUsed"] = "0x" + toHex(toCompactBigEndian(_bi.gasUsed, 1));
+	_o["timestamp"] = "0x" + toHex(toCompactBigEndian(_bi.timestamp, 1));
 	_o["extraData"] ="0x" + toHex(_bi.extraData);
 	_o["mixHash"] = toString(_bi.mixHash);
 	_o["nonce"] = toString(_bi.nonce);
@@ -655,37 +658,37 @@ BOOST_AUTO_TEST_SUITE(BlockChainTests)
 
 BOOST_AUTO_TEST_CASE(bcForkBlockTest)
 {
-	dev::test::executeTests("bcForkBlockTest", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcForkBlockTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(bcInvalidRLPTest)
 {
-	dev::test::executeTests("bcInvalidRLPTest", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcInvalidRLPTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
-BOOST_AUTO_TEST_CASE(bcJS_API_Test)
+BOOST_AUTO_TEST_CASE(bcRPC_API_Test)
 {
-	dev::test::executeTests("bcJS_API_Test", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcRPC_API_Test", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(bcValidBlockTest)
 {
-	dev::test::executeTests("bcValidBlockTest", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcValidBlockTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(bcInvalidHeaderTest)
 {
-	dev::test::executeTests("bcInvalidHeaderTest", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcInvalidHeaderTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(bcUncleTest)
 {
-	dev::test::executeTests("bcUncleTest", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcUncleTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(bcUncleHeaderValiditiy)
 {
-	dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockTests", dev::test::doBlockchainTests);
+	dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests);
 }
 
 BOOST_AUTO_TEST_CASE(userDefinedFile)
@@ -694,4 +697,3 @@ BOOST_AUTO_TEST_CASE(userDefinedFile)
 }
 
 BOOST_AUTO_TEST_SUITE_END()
-
diff --git a/test/genesis.cpp b/test/libethereum/genesis.cpp
similarity index 97%
rename from test/genesis.cpp
rename to test/libethereum/genesis.cpp
index 5ac3ea2a8..4633a0617 100644
--- a/test/genesis.cpp
+++ b/test/libethereum/genesis.cpp
@@ -25,10 +25,10 @@
 
 #include <boost/test/unit_test.hpp>
 
-#include "JsonSpiritHeaders.h"
+#include "../JsonSpiritHeaders.h"
 #include <libdevcore/CommonIO.h>
 #include <libethereum/CanonBlockChain.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace dev;
diff --git a/test/state.cpp b/test/libethereum/state.cpp
similarity index 77%
rename from test/state.cpp
rename to test/libethereum/state.cpp
index 65f333538..670ed0330 100644
--- a/test/state.cpp
+++ b/test/libethereum/state.cpp
@@ -23,14 +23,14 @@
 #include <boost/filesystem/operations.hpp>
 #include <boost/test/unit_test.hpp>
 
-#include "JsonSpiritHeaders.h"
+#include "../JsonSpiritHeaders.h"
 #include <libdevcore/CommonIO.h>
 #include <libethereum/CanonBlockChain.h>
 #include <libethereum/State.h>
 #include <libethereum/ExtVM.h>
 #include <libethereum/Defaults.h>
 #include <libevm/VM.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace json_spirit;
@@ -106,79 +106,81 @@ BOOST_AUTO_TEST_SUITE(StateTests)
 
 BOOST_AUTO_TEST_CASE(stExample)
 {
-	dev::test::executeTests("stExample", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stExample", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stSystemOperationsTest)
 {
-	dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stSystemOperationsTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stCallCreateCallCodeTest)
 {
-	dev::test::executeTests("stCallCreateCallCodeTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stCallCreateCallCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stPreCompiledContracts)
 {
-	dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stLogTests)
 {
-	dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stRecursiveCreate)
 {
-	dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stRecursiveCreate", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stInitCodeTest)
 {
-	dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stInitCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stTransactionTest)
 {
-	dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stTransactionTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stSpecialTest)
 {
-	dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stSpecialTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stRefundTest)
 {
-	dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stRefundTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stBlockHashTest)
 {
-	dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stBlockHashTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest)
 {
 	if (test::Options::get().quadratic)
-		dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests);
+		dev::test::executeTests("stQuadraticComplexityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_CASE(stMemoryStressTest)
 {
 	if (test::Options::get().memory)
-		dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests);
+		dev::test::executeTests("stMemoryStressTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
+#if ETH_SOLIDITY
 BOOST_AUTO_TEST_CASE(stSolidityTest)
 {
-	dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stSolidityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
+#endif
 
 BOOST_AUTO_TEST_CASE(stMemoryTest)
 {
-	dev::test::executeTests("stMemoryTest", "/StateTests", dev::test::doStateTests);
+	dev::test::executeTests("stMemoryTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests);
 }
 
 
diff --git a/test/stateOriginal.cpp b/test/libethereum/stateOriginal.cpp
similarity index 98%
rename from test/stateOriginal.cpp
rename to test/libethereum/stateOriginal.cpp
index 7f3371484..82d6288d6 100644
--- a/test/stateOriginal.cpp
+++ b/test/libethereum/stateOriginal.cpp
@@ -27,7 +27,7 @@
 #include <libethereum/State.h>
 #include <libethereum/Farm.h>
 #include <libethereum/Defaults.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 using namespace std;
 using namespace dev;
 using namespace dev::eth;
diff --git a/test/transaction.cpp b/test/libethereum/transaction.cpp
similarity index 96%
rename from test/transaction.cpp
rename to test/libethereum/transaction.cpp
index 78a1ac7f7..1a4716725 100644
--- a/test/transaction.cpp
+++ b/test/libethereum/transaction.cpp
@@ -20,7 +20,7 @@
  * Transaaction test functions.
  */
 
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 using namespace json_spirit;
@@ -137,12 +137,12 @@ BOOST_AUTO_TEST_SUITE(TransactionTests)
 
 BOOST_AUTO_TEST_CASE(ttTransactionTest)
 {
-	dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests);
+	dev::test::executeTests("ttTransactionTest", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests);
 }
 
 BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction)
 {
-	dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", dev::test::doTransactionTests);
+	dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests);
 }
 
 BOOST_AUTO_TEST_CASE(tt10mbDataField)
@@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(tt10mbDataField)
 	{
 		auto start = chrono::steady_clock::now();
 
-		dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests);
+		dev::test::executeTests("tt10mbDataField", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests);
 
 		auto end = chrono::steady_clock::now();
 		auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
diff --git a/test/libevm/CMakeLists.txt b/test/libevm/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libevm/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/PerformaceTester.sol b/test/libevm/VMTestsFiller/performanceTester.sol
similarity index 100%
rename from test/PerformaceTester.sol
rename to test/libevm/VMTestsFiller/performanceTester.sol
diff --git a/test/vmArithmeticTestFiller.json b/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json
similarity index 100%
rename from test/vmArithmeticTestFiller.json
rename to test/libevm/VMTestsFiller/vmArithmeticTestFiller.json
diff --git a/test/vmBitwiseLogicOperationTestFiller.json b/test/libevm/VMTestsFiller/vmBitwiseLogicOperationTestFiller.json
similarity index 100%
rename from test/vmBitwiseLogicOperationTestFiller.json
rename to test/libevm/VMTestsFiller/vmBitwiseLogicOperationTestFiller.json
diff --git a/test/vmBlockInfoTestFiller.json b/test/libevm/VMTestsFiller/vmBlockInfoTestFiller.json
similarity index 100%
rename from test/vmBlockInfoTestFiller.json
rename to test/libevm/VMTestsFiller/vmBlockInfoTestFiller.json
diff --git a/test/vmEnvironmentalInfoTestFiller.json b/test/libevm/VMTestsFiller/vmEnvironmentalInfoTestFiller.json
similarity index 100%
rename from test/vmEnvironmentalInfoTestFiller.json
rename to test/libevm/VMTestsFiller/vmEnvironmentalInfoTestFiller.json
diff --git a/test/vmIOandFlowOperationsTestFiller.json b/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
similarity index 100%
rename from test/vmIOandFlowOperationsTestFiller.json
rename to test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json
diff --git a/test/vmLogTestFiller.json b/test/libevm/VMTestsFiller/vmLogTestFiller.json
similarity index 100%
rename from test/vmLogTestFiller.json
rename to test/libevm/VMTestsFiller/vmLogTestFiller.json
diff --git a/test/vmPerformanceTestFiller.json b/test/libevm/VMTestsFiller/vmPerformanceTestFiller.json
similarity index 100%
rename from test/vmPerformanceTestFiller.json
rename to test/libevm/VMTestsFiller/vmPerformanceTestFiller.json
diff --git a/test/vmPushDupSwapTestFiller.json b/test/libevm/VMTestsFiller/vmPushDupSwapTestFiller.json
similarity index 100%
rename from test/vmPushDupSwapTestFiller.json
rename to test/libevm/VMTestsFiller/vmPushDupSwapTestFiller.json
diff --git a/test/vmSha3TestFiller.json b/test/libevm/VMTestsFiller/vmSha3TestFiller.json
similarity index 100%
rename from test/vmSha3TestFiller.json
rename to test/libevm/VMTestsFiller/vmSha3TestFiller.json
diff --git a/test/vmSystemOperationsTestFiller.json b/test/libevm/VMTestsFiller/vmSystemOperationsTestFiller.json
similarity index 100%
rename from test/vmSystemOperationsTestFiller.json
rename to test/libevm/VMTestsFiller/vmSystemOperationsTestFiller.json
diff --git a/test/vmtestsFiller.json b/test/libevm/VMTestsFiller/vmtestsFiller.json
similarity index 100%
rename from test/vmtestsFiller.json
rename to test/libevm/VMTestsFiller/vmtestsFiller.json
diff --git a/test/vm.cpp b/test/libevm/vm.cpp
similarity index 87%
rename from test/vm.cpp
rename to test/libevm/vm.cpp
index 9e21972f1..43dfa733d 100644
--- a/test/vm.cpp
+++ b/test/libevm/vm.cpp
@@ -261,8 +261,8 @@ eth::OnOpFunc FakeExtVM::simpleTrace()
 		for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second))
 			o << std::showbase << std::hex << i.first << ": " << i.second << std::endl;
 
-		dev::LogOutputStream<eth::VMTraceChannel, false>(true) << o.str();
-		dev::LogOutputStream<eth::VMTraceChannel, false>(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]";
+		dev::LogOutputStream<eth::VMTraceChannel, false>() << o.str();
+		dev::LogOutputStream<eth::VMTraceChannel, false>() << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]";
 
 		/*creates json stack trace*/
 		if (eth::VMTraceChannel::verbosity <= g_logVerbosity)
@@ -450,76 +450,76 @@ BOOST_AUTO_TEST_SUITE(VMTests)
 
 BOOST_AUTO_TEST_CASE(vmtests)
 {
-	dev::test::executeTests("vmtests", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmtests", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmArithmeticTest)
 {
-	dev::test::executeTests("vmArithmeticTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmArithmeticTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmBitwiseLogicOperationTest)
 {
-	dev::test::executeTests("vmBitwiseLogicOperationTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmBitwiseLogicOperationTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmSha3Test)
 {
-	dev::test::executeTests("vmSha3Test", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmSha3Test", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmEnvironmentalInfoTest)
 {
-	dev::test::executeTests("vmEnvironmentalInfoTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmEnvironmentalInfoTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmBlockInfoTest)
 {
-	dev::test::executeTests("vmBlockInfoTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmBlockInfoTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmIOandFlowOperationsTest)
 {
-	dev::test::executeTests("vmIOandFlowOperationsTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmIOandFlowOperationsTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmPushDupSwapTest)
 {
-	dev::test::executeTests("vmPushDupSwapTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmPushDupSwapTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmLogTest)
 {
-	dev::test::executeTests("vmLogTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmLogTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmSystemOperationsTest)
 {
-	dev::test::executeTests("vmSystemOperationsTest", "/VMTests", dev::test::doVMTests);
+	dev::test::executeTests("vmSystemOperationsTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmPerformanceTest)
 {
 	if (test::Options::get().performance)
-		dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests);
+		dev::test::executeTests("vmPerformanceTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmInputLimitsTest1)
 {
 	if (test::Options::get().inputLimits)
-		dev::test::executeTests("vmInputLimits1", "/VMTests", dev::test::doVMTests);
+		dev::test::executeTests("vmInputLimits1", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmInputLimitsTest2)
 {
 	if (test::Options::get().inputLimits)
-		dev::test::executeTests("vmInputLimits2", "/VMTests", dev::test::doVMTests);
+		dev::test::executeTests("vmInputLimits2", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmInputLimitsLightTest)
 {
 	if (test::Options::get().inputLimits)
-		dev::test::executeTests("vmInputLimitsLight", "/VMTests", dev::test::doVMTests);
+		dev::test::executeTests("vmInputLimitsLight", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests);
 }
 
 BOOST_AUTO_TEST_CASE(vmRandom)
diff --git a/test/vm.h b/test/libevm/vm.h
similarity index 99%
rename from test/vm.h
rename to test/libevm/vm.h
index 1c0190b69..2bfc68d56 100644
--- a/test/vm.h
+++ b/test/libevm/vm.h
@@ -38,7 +38,7 @@ along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 #include <libethereum/Transaction.h>
 #include <libethereum/ExtVM.h>
 #include <libethereum/State.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 namespace dev { namespace test {
 
diff --git a/test/libnatspec/CMakeLists.txt b/test/libnatspec/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libnatspec/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/natspec.cpp b/test/libnatspec/natspec.cpp
similarity index 100%
rename from test/natspec.cpp
rename to test/libnatspec/natspec.cpp
diff --git a/test/libp2p/CMakeLists.txt b/test/libp2p/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libp2p/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/net.cpp b/test/libp2p/net.cpp
similarity index 100%
rename from test/net.cpp
rename to test/libp2p/net.cpp
diff --git a/test/peer.cpp b/test/libp2p/peer.cpp
similarity index 100%
rename from test/peer.cpp
rename to test/libp2p/peer.cpp
diff --git a/test/rlpx.cpp b/test/libp2p/rlpx.cpp
similarity index 100%
rename from test/rlpx.cpp
rename to test/libp2p/rlpx.cpp
diff --git a/test/Assembly.cpp b/test/libsolidity/Assembly.cpp
similarity index 99%
rename from test/Assembly.cpp
rename to test/libsolidity/Assembly.cpp
index fab260a9d..8dcee7fb5 100644
--- a/test/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -20,8 +20,6 @@
  * Unit tests for Assembly Items from evmcore/Assembly.h
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 #include <iostream>
 #include <boost/test/unit_test.hpp>
@@ -120,5 +118,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/libsolidity/CMakeLists.txt b/test/libsolidity/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libsolidity/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
similarity index 99%
rename from test/SolidityABIJSON.cpp
rename to test/libsolidity/SolidityABIJSON.cpp
index bbe5fd8c4..f0e54a940 100644
--- a/test/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -19,9 +19,8 @@
  * @date 2014
  * Unit tests for the solidity compiler JSON Interface output.
  */
-#if ETH_SOLIDITY
 
-#include "TestHelper.h"
+#include "../TestHelper.h"
 #include <libsolidity/CompilerStack.h>
 #include <json/json.h>
 #include <libdevcore/Exceptions.h>
@@ -501,5 +500,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 }
-
-#endif
diff --git a/test/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp
similarity index 99%
rename from test/SolidityCompiler.cpp
rename to test/libsolidity/SolidityCompiler.cpp
index bb16c88cd..7b0ceedb6 100644
--- a/test/SolidityCompiler.cpp
+++ b/test/libsolidity/SolidityCompiler.cpp
@@ -20,8 +20,6 @@
  * Unit tests for the solidity compiler.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 #include <iostream>
 #include <boost/test/unit_test.hpp>
@@ -193,5 +191,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
similarity index 97%
rename from test/SolidityEndToEndTest.cpp
rename to test/libsolidity/SolidityEndToEndTest.cpp
index 3764949d9..8b926d6cf 100644
--- a/test/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -21,13 +21,11 @@
  * Unit tests for the solidity expression compiler, testing the behaviour of the code.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 #include <tuple>
 #include <boost/test/unit_test.hpp>
 #include <libdevcrypto/SHA3.h>
-#include <test/solidityExecutionFramework.h>
+#include <test/libsolidity/solidityExecutionFramework.h>
 
 using namespace std;
 
@@ -304,7 +302,6 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
 
 BOOST_AUTO_TEST_CASE(calling_other_functions)
 {
-	// note that the index of a function is its index in the sorted sequence of functions
 	char const* sourceCode = "contract collatz {\n"
 							 "  function run(uint x) returns(uint y) {\n"
 							 "    while ((y = x) > 1) {\n"
@@ -1149,26 +1146,6 @@ BOOST_AUTO_TEST_CASE(now)
 	BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true));
 }
 
-BOOST_AUTO_TEST_CASE(function_types)
-{
-	char const* sourceCode = "contract test {\n"
-							 "  function a(bool selector) returns (uint b) {\n"
-							 "    var f = fun1;\n"
-							 "    if (selector) f = fun2;\n"
-							 "    return f(9);\n"
-							 "  }\n"
-							 "  function fun1(uint x) returns (uint b) {\n"
-							 "    return 11;\n"
-							 "  }\n"
-							 "  function fun2(uint x) returns (uint b) {\n"
-							 "    return 12;\n"
-							 "  }\n"
-							 "}\n";
-	compileAndRun(sourceCode);
-	BOOST_CHECK(callContractFunction("a(bool)", false) == encodeArgs(11));
-	BOOST_CHECK(callContractFunction("a(bool)", true) == encodeArgs(12));
-}
-
 BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
 {
 	// 22-byte integer converted to a contract (i.e. address, 20 bytes), converted to a 32 byte
@@ -1499,7 +1476,7 @@ BOOST_AUTO_TEST_CASE(ripemd)
 	{
 		h256 ret;
 		dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32));
-		return u256(ret) >> (256 - 160);
+		return u256(ret);
 	};
 	testSolidityAgainstCpp("a(bytes32)", f, u256(4));
 	testSolidityAgainstCpp("a(bytes32)", f, u256(5));
@@ -1814,7 +1791,7 @@ BOOST_AUTO_TEST_CASE(gas_for_builtin)
 	)";
 	compileAndRun(sourceCode);
 	BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes());
-	BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), true));
+	BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc000000000000000000000000"), true));
 }
 
 BOOST_AUTO_TEST_CASE(value_complex)
@@ -3676,6 +3653,94 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0)
 	BOOST_CHECK(callContractFunction("test()") == encodeArgs(true));
 }
 
+BOOST_AUTO_TEST_CASE(overloaded_function_call_resolve_to_first)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint k) returns(uint d) { return k; }
+			function f(uint a, uint b) returns(uint d) { return a + b; }
+			function g() returns(uint d) { return f(3); }
+		}
+	)";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction("g()") == encodeArgs(3));
+}
+
+BOOST_AUTO_TEST_CASE(overloaded_function_call_resolve_to_second)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint a, uint b) returns(uint d) { return a + b; }
+			function f(uint k) returns(uint d) { return k; }
+			function g() returns(uint d) { return f(3, 7); }
+		}
+	)";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction("g()") == encodeArgs(10));
+}
+
+BOOST_AUTO_TEST_CASE(overloaded_function_call_with_if_else)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint a, uint b) returns(uint d) { return a + b; }
+			function f(uint k) returns(uint d) { return k; }
+			function g(bool flag) returns(uint d) {
+				if (flag)
+					return f(3);
+				else
+					return f(3, 7);
+			}
+		}
+	)";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction("g(bool)", true) == encodeArgs(3));
+	BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10));
+}
+
+BOOST_AUTO_TEST_CASE(derived_overload_base_function_direct)
+{
+	char const* sourceCode = R"(
+		contract B { function f() returns(uint) { return 10; } }
+		contract C is B {
+			function f(uint i) returns(uint) { return 2 * i; }
+			function g() returns(uint) { return f(1); }
+		}
+	)";
+	compileAndRun(sourceCode, 0, "C");
+	BOOST_CHECK(callContractFunction("g()") == encodeArgs(2));
+}
+
+BOOST_AUTO_TEST_CASE(derived_overload_base_function_indirect)
+{
+	char const* sourceCode = R"(
+		contract A { function f(uint a) returns(uint) { return 2 * a; } }
+		contract B { function f() returns(uint) { return 10; } }
+		contract C is A, B {
+			function g() returns(uint) { return f(); }
+			function h() returns(uint) { return f(1); }
+		}
+	)";
+	compileAndRun(sourceCode, 0, "C");
+	BOOST_CHECK(callContractFunction("g()") == encodeArgs(10));
+	BOOST_CHECK(callContractFunction("h()") == encodeArgs(2));
+}
+
+BOOST_AUTO_TEST_CASE(super_overload)
+{
+	char const* sourceCode = R"(
+		contract A { function f(uint a) returns(uint) { return 2 * a; } }
+		contract B { function f(bool b) returns(uint) { return 10; } }
+		contract C is A, B {
+			function g() returns(uint) { return super.f(true); }
+			function h() returns(uint) { return super.f(1); }
+		}
+	)";
+	compileAndRun(sourceCode, 0, "C");
+	BOOST_CHECK(callContractFunction("g()") == encodeArgs(10));
+	BOOST_CHECK(callContractFunction("h()") == encodeArgs(2));
+}
+
 BOOST_AUTO_TEST_CASE(packed_storage_signed)
 {
 	char const* sourceCode = R"(
@@ -3699,10 +3764,27 @@ BOOST_AUTO_TEST_CASE(packed_storage_signed)
 	BOOST_CHECK( callContractFunction("test()") == encodeArgs(u256(-2), u256(4), u256(-112), u256(0)));
 }
 
+BOOST_AUTO_TEST_CASE(external_types_in_calls)
+{
+	char const* sourceCode = R"(
+		contract C1 { C1 public bla; function C1(C1 x) { bla = x; } }
+		contract C {
+			function test() returns (C1 x, C1 y) {
+				C1 c = new C1(C1(9));
+				x = c.bla();
+				y = this.t1(C1(7));
+			}
+			function t1(C1 a) returns (C1) { return a; }
+			function() returns (C1) { return C1(9); }
+		}
+	)";
+	compileAndRun(sourceCode, 0, "C");
+	BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(9), u256(7)));
+	BOOST_CHECK(callContractFunction("nonexisting") == encodeArgs(u256(9)));
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
similarity index 98%
rename from test/SolidityExpressionCompiler.cpp
rename to test/libsolidity/SolidityExpressionCompiler.cpp
index b748d887d..b2436cfa7 100644
--- a/test/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -20,8 +20,6 @@
  * Unit tests for the solidity expression compiler.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 
 #include <libdevcore/Log.h>
@@ -31,7 +29,7 @@
 #include <libsolidity/CompilerContext.h>
 #include <libsolidity/ExpressionCompiler.h>
 #include <libsolidity/AST.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 
@@ -80,7 +78,9 @@ Declaration const& resolveDeclaration(
 	// bracers are required, cause msvc couldnt handle this macro in for statement
 	for (string const& namePart: _namespacedName)
 	{
-		BOOST_REQUIRE(declaration = _resolver.resolveName(namePart, declaration));
+		auto declarations = _resolver.resolveName(namePart, declaration);
+		BOOST_REQUIRE(!declarations.empty());
+		BOOST_REQUIRE(declaration = *declarations.begin());
 	}
 	BOOST_REQUIRE(declaration);
 	return *declaration;
@@ -491,5 +491,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityInterface.cpp b/test/libsolidity/SolidityInterface.cpp
similarity index 99%
rename from test/SolidityInterface.cpp
rename to test/libsolidity/SolidityInterface.cpp
index c836f0fa7..c8f74e3aa 100644
--- a/test/SolidityInterface.cpp
+++ b/test/libsolidity/SolidityInterface.cpp
@@ -20,9 +20,7 @@
  * Unit tests for generating source interfaces for Solidity contracts.
  */
 
-#if ETH_SOLIDITY
-
-#include "TestHelper.h"
+#include "../TestHelper.h"
 #include <libsolidity/CompilerStack.h>
 #include <libsolidity/AST.h>
 
@@ -149,5 +147,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 }
-
-#endif
diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
similarity index 95%
rename from test/SolidityNameAndTypeResolution.cpp
rename to test/libsolidity/SolidityNameAndTypeResolution.cpp
index c1a274b0c..c317dad97 100644
--- a/test/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -20,8 +20,6 @@
  * Unit tests for the name and type resolution of the solidity parser.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 
 #include <libdevcore/Log.h>
@@ -31,7 +29,7 @@
 #include <libsolidity/NameAndTypeResolver.h>
 #include <libsolidity/Exceptions.h>
 #include <libsolidity/GlobalContext.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 
@@ -625,23 +623,23 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance)
 	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
 }
 
-BOOST_AUTO_TEST_CASE(illegal_override_direct)
+BOOST_AUTO_TEST_CASE(legal_override_direct)
 {
 	char const* text = R"(
 		contract B { function f() {} }
 		contract C is B { function f(uint i) {} }
 	)";
-	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
 }
 
-BOOST_AUTO_TEST_CASE(illegal_override_indirect)
+BOOST_AUTO_TEST_CASE(legal_override_indirect)
 {
 	char const* text = R"(
 		contract A { function f(uint a) {} }
 		contract B { function f() {} }
 		contract C is A, B { }
 	)";
-	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
 }
 
 BOOST_AUTO_TEST_CASE(illegal_override_visibility)
@@ -1656,6 +1654,103 @@ BOOST_AUTO_TEST_CASE(bytes0_array)
 	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
 }
 
+BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f() returns(uint) { return 1; }
+			function f(uint a) returns(uint) { return a; }
+			function g() returns(uint) { return f(3, 5); }
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
+{
+	// literal 1 can be both converted to uint and uint8, so the call is ambiguous.
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint8 a) returns(uint) { return a; }
+			function f(uint a) returns(uint) { return 2*a; }
+			function g() returns(uint) { return f(1); }
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint a) returns(uint) { return 2 * a; }
+			function g() returns(uint) { var x = f; return x(7); }
+		}
+	)";
+	ETH_TEST_REQUIRE_NO_THROW(parseTextAndResolveNames(sourceCode), "Type resolving failed");
+}
+
+BOOST_AUTO_TEST_CASE(assignment_of_overloaded_function)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f() returns(uint) { return 1; }
+			function f(uint a) returns(uint) { return 2 * a; }
+			function g() returns(uint) { var x = f; return x(7); }
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(external_types_clash)
+{
+	char const* sourceCode = R"(
+		contract base {
+			enum a { X }
+			function f(a) { }
+		}
+		contract test is base {
+			function f(uint8 a) { }
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(override_changes_return_types)
+{
+	char const* sourceCode = R"(
+		contract base {
+			function f(uint a) returns (uint) { }
+		}
+		contract test is base {
+			function f(uint a) returns (uint8) { }
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(multiple_constructors)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function test(uint a) { }
+			function test() {}
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError);
+}
+
+BOOST_AUTO_TEST_CASE(equal_overload)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function test(uint a) returns (uint b) { }
+			function test(uint a) external {}
+		}
+	)";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError);
+}
+
 BOOST_AUTO_TEST_CASE(uninitialized_var)
 {
 	char const* sourceCode = R"(
@@ -1671,5 +1766,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
similarity index 99%
rename from test/SolidityNatspecJSON.cpp
rename to test/libsolidity/SolidityNatspecJSON.cpp
index 28d657357..d2c1ec186 100644
--- a/test/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -20,9 +20,7 @@
  * Unit tests for the solidity compiler JSON Interface output.
  */
 
-#if ETH_SOLIDITY
-
-#include "TestHelper.h"
+#include "../TestHelper.h"
 #include <json/json.h>
 #include <libsolidity/CompilerStack.h>
 #include <libsolidity/Exceptions.h>
@@ -539,5 +537,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 }
-
-#endif
diff --git a/test/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp
similarity index 99%
rename from test/SolidityOptimizer.cpp
rename to test/libsolidity/SolidityOptimizer.cpp
index f57380acd..af9b51467 100644
--- a/test/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -20,13 +20,11 @@
  * Tests for the Solidity optimizer.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 #include <tuple>
 #include <boost/test/unit_test.hpp>
 #include <boost/lexical_cast.hpp>
-#include <test/solidityExecutionFramework.h>
+#include <test/libsolidity/solidityExecutionFramework.h>
 #include <libevmcore/CommonSubexpressionEliminator.h>
 #include <libevmcore/ControlFlowGraph.h>
 #include <libevmcore/Assembly.h>
@@ -816,5 +814,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
similarity index 97%
rename from test/SolidityParser.cpp
rename to test/libsolidity/SolidityParser.cpp
index 7cd8efce1..cad0e1f2c 100644
--- a/test/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -20,15 +20,13 @@
  * Unit tests for the solidity parser.
  */
 
-#if ETH_SOLIDITY
-
 #include <string>
 #include <memory>
 #include <libdevcore/Log.h>
 #include <libsolidity/Scanner.h>
 #include <libsolidity/Parser.h>
 #include <libsolidity/Exceptions.h>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 
 using namespace std;
 
@@ -136,6 +134,31 @@ BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
 	BOOST_CHECK_THROW(parseText(text), ParserError);
 }
 
+BOOST_AUTO_TEST_CASE(two_exact_functions)
+{
+	char const* text = R"(
+		contract test {
+			function fun(uint a) returns(uint r) { return a; }
+			function fun(uint a) returns(uint r) { return a; }
+		}
+	)";
+	// with support of overloaded functions, during parsing,
+	// we can't determine whether they match exactly, however
+	// it will throw DeclarationError in following stage.
+	BOOST_CHECK_NO_THROW(parseText(text));
+}
+
+BOOST_AUTO_TEST_CASE(overloaded_functions)
+{
+	char const* text = R"(
+		contract test {
+			function fun(uint a) returns(uint r) { return a; }
+			function fun(uint a, uint b) returns(uint r) { return a + b; }
+		}
+	)";
+	BOOST_CHECK_NO_THROW(parseText(text));
+}
+
 BOOST_AUTO_TEST_CASE(function_natspec_documentation)
 {
 	ASTPointer<ContractDefinition> contract;
@@ -855,5 +878,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp
similarity index 99%
rename from test/SolidityScanner.cpp
rename to test/libsolidity/SolidityScanner.cpp
index 20b946ee0..8d3e53929 100644
--- a/test/SolidityScanner.cpp
+++ b/test/libsolidity/SolidityScanner.cpp
@@ -20,8 +20,6 @@
  * Unit tests for the solidity scanner.
  */
 
-#if ETH_SOLIDITY
-
 #include <libsolidity/Scanner.h>
 #include <boost/test/unit_test.hpp>
 
@@ -288,5 +286,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 } // end namespaces
-
-#endif
diff --git a/test/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
similarity index 99%
rename from test/SolidityTypes.cpp
rename to test/libsolidity/SolidityTypes.cpp
index da8b48303..6b6306479 100644
--- a/test/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -20,8 +20,6 @@
  * Unit tests for the type system of Solidity.
  */
 
-#if ETH_SOLIDITY
-
 #include <libsolidity/Types.h>
 #include <boost/test/unit_test.hpp>
 
@@ -93,5 +91,3 @@ BOOST_AUTO_TEST_SUITE_END()
 }
 }
 }
-
-#endif
diff --git a/test/solidityExecutionFramework.h b/test/libsolidity/solidityExecutionFramework.h
similarity index 99%
rename from test/solidityExecutionFramework.h
rename to test/libsolidity/solidityExecutionFramework.h
index 2134d424d..f76465f23 100644
--- a/test/solidityExecutionFramework.h
+++ b/test/libsolidity/solidityExecutionFramework.h
@@ -24,7 +24,7 @@
 
 #include <string>
 #include <tuple>
-#include "TestHelper.h"
+#include "../TestHelper.h"
 #include <libethereum/State.h>
 #include <libethereum/Executive.h>
 #include <libsolidity/CompilerStack.h>
diff --git a/test/AccountHolder.cpp b/test/libweb3jsonrpc/AccountHolder.cpp
similarity index 100%
rename from test/AccountHolder.cpp
rename to test/libweb3jsonrpc/AccountHolder.cpp
diff --git a/test/libweb3jsonrpc/CMakeLists.txt b/test/libweb3jsonrpc/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libweb3jsonrpc/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/jsonrpc.cpp b/test/libweb3jsonrpc/jsonrpc.cpp
similarity index 98%
rename from test/jsonrpc.cpp
rename to test/libweb3jsonrpc/jsonrpc.cpp
index eaa9edc45..97ba17ccf 100644
--- a/test/jsonrpc.cpp
+++ b/test/libweb3jsonrpc/jsonrpc.cpp
@@ -34,8 +34,8 @@
 #include <jsonrpccpp/server/connectors/httpserver.h>
 #include <jsonrpccpp/client/connectors/httpclient.h>
 #include <set>
-#include "JsonSpiritHeaders.h"
-#include "TestHelper.h"
+#include "../JsonSpiritHeaders.h"
+#include "../TestHelper.h"
 #include "webthreestubclient.h"
 
 BOOST_AUTO_TEST_SUITE(jsonrpc)
@@ -59,7 +59,7 @@ struct Setup
 		setup = true;
 
 		dev::p2p::NetworkPreferences nprefs(30303, std::string(), false);
-		web3 = new WebThreeDirect("Ethereum(++) tests", "", true, {"eth", "shh"}, nprefs);
+		web3 = new WebThreeDirect("++eth tests", "", true, {"eth", "shh"}, nprefs);
 		
 		web3->setIdealPeerCount(5);
 		web3->ethereum()->setForceMining(true);
diff --git a/test/webthreestubclient.h b/test/libweb3jsonrpc/webthreestubclient.h
similarity index 100%
rename from test/webthreestubclient.h
rename to test/libweb3jsonrpc/webthreestubclient.h
diff --git a/test/libwhisper/CMakeLists.txt b/test/libwhisper/CMakeLists.txt
new file mode 100644
index 000000000..3ceda13b0
--- /dev/null
+++ b/test/libwhisper/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0015 NEW)
+
+aux_source_directory(. SRCS)
+
+add_sources(${SRCS})
diff --git a/test/whisperTopic.cpp b/test/libwhisper/whisperTopic.cpp
similarity index 100%
rename from test/whisperTopic.cpp
rename to test/libwhisper/whisperTopic.cpp
diff --git a/test/randomTestFiller.json b/test/randomTestFiller.json
deleted file mode 100644
index 0712cc40f..000000000
--- a/test/randomTestFiller.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "randomVMtest": {
-        "env" : {
-            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
-            "currentNumber" : "0",
-            "currentGasLimit" : "1000000",
-            "currentDifficulty" : "256",
-            "currentTimestamp" : 1,
-            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
-        },
-        "pre" : {
-            "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
-                "balance" : "1000000000000000000",
-                "nonce" : "0",
-                "code" : "random",
-                "storage": {}
-            }
-        },
-        "exec" : {
-            "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
-            "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
-            "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
-            "value" : "1000000000000000000",
-            "data" : "",
-            "gasPrice" : "100000000000000",
-            "gas" : "10000"
-        }
-    }
-}