diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 04fc7757c..c146673a1 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -1263,7 +1263,10 @@ void Main::on_blocks_currentItemChanged()
 			s << "<br/>Nonce: <b>" << info.nonce << "</b>";
 			s << "<br/>Hash w/o nonce: <b>" << info.headerHashWithoutNonce() << "</b>";
 			s << "<br/>Difficulty: <b>" << info.difficulty << "</b>";
-			s << "<br/>Proof-of-Work: <b>" << ProofOfWork::eval(info.headerHashWithoutNonce(), info.nonce) << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b>";
+			if (info.number)
+				s << "<br/>Proof-of-Work: <b>" << ProofOfWork::eval(info.headerHashWithoutNonce(), info.nonce) << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b>";
+			else
+				s << "<br/>Proof-of-Work: <i>Phil has nothing to prove</i>";
 			s << "<br/>Parent: <b>" << info.parentHash << "</b>";
 //			s << "<br/>Bloom: <b>" << details.bloom << "</b>";
 			s << "<br/>Log Bloom: <b>" << info.logBloom << "</b>";
@@ -1280,7 +1283,7 @@ void Main::on_blocks_currentItemChanged()
 			if (info.parentHash)
 				s << "<br/>Pre: <b>" << BlockInfo(ethereum()->blockChain().block(info.parentHash)).stateRoot << "</b>";
 			else
-				s << "<br/>Pre: <i>Nothing is before the Gensesis</i>";
+				s << "<br/>Pre: <i>Nothing is before Phil</i>";
 			for (auto const& i: block[1])
 				s << "<br/>" << sha3(i.data()).abridged();// << ": <b>" << i[1].toHash<h256>() << "</b> [<b>" << i[2].toInt<u256>() << "</b> used]";
 			s << "<br/>Post: <b>" << info.stateRoot << "</b>";
@@ -1395,10 +1398,10 @@ void Main::populateDebugger(dev::bytesConstRef _r)
 		bytesConstRef lastData;
 		h256 lastHash;
 		h256 lastDataHash;
-		auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, void* voidVM, void const* voidExt)
+		auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, dev::eth::VM* voidVM, dev::eth::ExtVMFace const* voidExt)
 		{
-			dev::eth::VM& vm = *(dev::eth::VM*)voidVM;
-			dev::eth::ExtVM const& ext = *(dev::eth::ExtVM const*)voidExt;
+			dev::eth::VM& vm = *voidVM;
+			dev::eth::ExtVM const& ext = *static_cast<dev::eth::ExtVM const*>(voidExt);
 			if (ext.code != lastExtCode)
 			{
 				lastExtCode = ext.code;
diff --git a/eth/main.cpp b/eth/main.cpp
index 9485a11bf..0113fa1a5 100644
--- a/eth/main.cpp
+++ b/eth/main.cpp
@@ -630,10 +630,10 @@ int main(int argc, char** argv)
 
 						OnOpFunc oof;
 						if (format == "pretty")
-							oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, void* vvm, void const* vextVM)
+							oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
 							{
-								dev::eth::VM* vm = (VM*)vvm;
-								dev::eth::ExtVM const* ext = (ExtVM const*)vextVM;
+								dev::eth::VM* vm = vvm;
+								dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
 								f << endl << "    STACK" << endl;
 								for (auto i: vm->stack())
 									f << (h256)i << endl;
@@ -644,17 +644,17 @@ int main(int argc, char** argv)
 								f << dec << ext->depth << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << vm->gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32";
 							};
 						else if (format == "standard")
-							oof = [&](uint64_t, Instruction instr, bigint, bigint, void* vvm, void const* vextVM)
+							oof = [&](uint64_t, Instruction instr, bigint, bigint, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
 							{
-								dev::eth::VM* vm = (VM*)vvm;
-								dev::eth::ExtVM const* ext = (ExtVM const*)vextVM;
+								dev::eth::VM* vm = vvm;
+								dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
 								f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)vm->gas(), 1)) << endl;
 							};
 						else if (format == "standard+")
-							oof = [&](uint64_t, Instruction instr, bigint, bigint, void* vvm, void const* vextVM)
+							oof = [&](uint64_t, Instruction instr, bigint, bigint, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
 							{
 								dev::eth::VM* vm = (VM*)vvm;
-								dev::eth::ExtVM const* ext = (ExtVM const*)vextVM;
+								dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
 								if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE)
 									for (auto const& i: ext->state().storage(ext->myAddress))
 										f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl;
diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp
index 5f9332ad8..36726dae4 100644
--- a/libethcore/CommonEth.cpp
+++ b/libethcore/CommonEth.cpp
@@ -33,7 +33,7 @@ namespace dev
 namespace eth
 {
 
-const unsigned c_protocolVersion = 48;
+const unsigned c_protocolVersion = 49;
 const unsigned c_databaseVersion = 5;
 
 static const vector<pair<u256, string>> g_units =
diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp
index 531005fb2..6ed0a2ca6 100644
--- a/libethereum/BlockChain.cpp
+++ b/libethereum/BlockChain.cpp
@@ -145,7 +145,7 @@ void BlockChain::open(std::string _path, bool _killExisting)
 	if (!details(m_genesisHash))
 	{
 		// Insert details of genesis block.
-		m_details[m_genesisHash] = BlockDetails(0, c_genesisDifficulty, h256(), {}, h256());
+		m_details[m_genesisHash] = BlockDetails(0, c_genesisDifficulty, h256(), {});
 		auto r = m_details[m_genesisHash].rlp();
 		m_extrasDB->Put(m_writeOptions, ldb::Slice((char const*)&m_genesisHash, 32), (ldb::Slice)dev::ref(r));
 	}
@@ -303,7 +303,6 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
 		// Get total difficulty increase and update state, checking it.
 		State s(bi.coinbaseAddress, _db);
 		auto tdIncrease = s.enactOn(&_block, bi, *this);
-		auto b = s.oldBloom();
 		BlockLogBlooms blb;
 		BlockReceipts br;
 		for (unsigned i = 0; i < s.pending().size(); ++i)
@@ -320,7 +319,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
 		// All ok - insert into DB
 		{
 			WriteGuard l(x_details);
-			m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}, b);
+			m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {});
 			m_details[bi.parentHash].children.push_back(newHash);
 		}
 		{
diff --git a/libethereum/BlockDetails.cpp b/libethereum/BlockDetails.cpp
index 5a61eb037..58f37b7aa 100644
--- a/libethereum/BlockDetails.cpp
+++ b/libethereum/BlockDetails.cpp
@@ -32,10 +32,9 @@ BlockDetails::BlockDetails(RLP const& _r)
 	totalDifficulty = _r[1].toInt<u256>();
 	parent = _r[2].toHash<h256>();
 	children = _r[3].toVector<h256>();
-	bloom = _r[4].toHash<h256>();
 }
 
 bytes BlockDetails::rlp() const
 {
-	return rlpList(number, totalDifficulty, parent, children, bloom);
+	return rlpList(number, totalDifficulty, parent, children);
 }
diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h
index 0c3af5b33..2fd0d3048 100644
--- a/libethereum/BlockDetails.h
+++ b/libethereum/BlockDetails.h
@@ -40,7 +40,7 @@ namespace eth
 struct BlockDetails
 {
 	BlockDetails(): number(0), totalDifficulty(0) {}
-	BlockDetails(unsigned _n, u256 _tD, h256 _p, h256s _c, h256 _bloom): number(_n), totalDifficulty(_tD), parent(_p), children(_c), bloom(_bloom) {}
+	BlockDetails(unsigned _n, u256 _tD, h256 _p, h256s _c): number(_n), totalDifficulty(_tD), parent(_p), children(_c) {}
 	BlockDetails(RLP const& _r);
 	bytes rlp() const;
 
@@ -51,7 +51,6 @@ struct BlockDetails
 	u256 totalDifficulty;
 	h256 parent;
 	h256s children;
-	h256 bloom;
 };
 
 struct BlockLogBlooms
diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp
index 9e2f5ee07..007896d75 100644
--- a/libethereum/Executive.cpp
+++ b/libethereum/Executive.cpp
@@ -85,14 +85,6 @@ bool Executive::setup(bytesConstRef _rlp)
 	clog(StateDetail) << "Paying" << formatBalance(cost) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
 	m_s.subBalance(m_sender, cost);
 
-	if (m_ms)
-	{
-		m_ms->from = m_sender;
-		m_ms->to = m_t.receiveAddress();
-		m_ms->value = m_t.value();
-		m_ms->input = m_t.data();
-	}
-
 	if (m_t.isCreation())
 		return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender);
 	else
@@ -104,11 +96,24 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
 //	cnote << "Transferring" << formatBalance(_value) << "to receiver.";
 	m_s.addBalance(_receiveAddress, _value);
 
-	if (m_s.addressHasCode(_receiveAddress))
+	auto it = !(_receiveAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_receiveAddress) : State::precompiled().end();
+	if (it != State::precompiled().end())
+	{
+		bigint g = it->second.gas(_data);
+		if (_gas < g)
+		{
+			m_endGas = 0;
+			return false;
+		}
+		m_endGas = (u256)(_gas - g);
+		it->second.exec(_data, bytesRef());
+		return true;
+	}
+	else if (m_s.addressHasCode(_receiveAddress))
 	{
 		m_vm = VMFactory::create(_gas);
 		bytes const& c = m_s.code(_receiveAddress);
-		m_ext.reset(new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_ms));
+		m_ext.reset(new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c));
 	}
 	else
 		m_endGas = _gas;
@@ -126,16 +131,16 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
 
 	// Execute _init.
 	m_vm = VMFactory::create(_gas);
-	m_ext.reset(new ExtVM(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_ms));
+	m_ext.reset(new ExtVM(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init));
 	return _init.empty();
 }
 
 OnOpFunc Executive::simpleTrace()
 {
-	return [](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, void* voidVM, void const* voidExt)
+	return [](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, VM* voidVM, ExtVMFace const* voidExt)
 	{
-		ExtVM const& ext = *(ExtVM const*)voidExt;
-		VM& vm = *(VM*)voidVM;
+		ExtVM const& ext = *static_cast<ExtVM const*>(voidExt);
+		VM& vm = *voidVM;
 
 		ostringstream o;
 		o << endl << "    STACK" << endl;
@@ -156,16 +161,16 @@ bool Executive::go(OnOpFunc const& _onOp)
 	{
 		boost::timer t;
 		auto sgas = m_vm->gas();
-		bool revert = false;
 		try
 		{
 			m_out = m_vm->go(*m_ext, _onOp);
-			if (m_ext)
-			{
-				m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds);
-				m_logs = m_ext->sub.logs;
-			}
 			m_endGas = m_vm->gas();
+			m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds);
+			m_logs = m_ext->sub.logs;
+			if (m_out.size() * c_createDataGas <= m_endGas)
+				m_endGas -= m_out.size() * c_createDataGas;
+			else
+				m_out.reset();
 		}
 		catch (StepsDone const&)
 		{
@@ -175,7 +180,16 @@ bool Executive::go(OnOpFunc const& _onOp)
 		{
 			clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e);
 			m_endGas = 0;//m_vm->gas();
-			revert = true;
+
+			// Write state out only in the case of a non-excepted transaction.
+			m_ext->revert();
+
+			// Explicitly delete a newly created address - this will still be in the reverted state.
+/*			if (m_newAddress)
+			{
+				m_s.m_cache.erase(m_newAddress);
+				m_newAddress = Address();
+			}*/
 		}
 		catch (Exception const& _e)
 		{
@@ -188,18 +202,6 @@ bool Executive::go(OnOpFunc const& _onOp)
 			cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what();
 		}
 		cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas);
-
-		// Write state out only in the case of a non-excepted transaction.
-		if (revert)
-		{
-			m_ext->revert();
-			// Explicitly delete a newly created address - this will still be in the reverted state.
-			if (m_newAddress)
-			{
-				m_s.m_cache.erase(m_newAddress);
-				m_newAddress = Address();
-			}
-		}
 	}
 	return true;
 }
@@ -211,9 +213,11 @@ u256 Executive::gas() const
 
 void Executive::finalize(OnOpFunc const&)
 {
-	if (m_t.isCreation() && m_newAddress && m_out.size())
-		// non-reverted creation - put code in place.
+	if (m_t.isCreation() && !m_ext->sub.suicides.count(m_newAddress))
+	{
+		// creation - put code in place.
 		m_s.m_cache[m_newAddress].setCode(m_out);
+	}
 
 //	cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")";
 	m_s.addBalance(m_sender, m_endGas * m_t.gasPrice());
@@ -222,9 +226,6 @@ void Executive::finalize(OnOpFunc const&)
 //	cnote << "Transferring" << formatBalance(gasSpent) << "to miner.";
 	m_s.addBalance(m_s.m_currentBlock.coinbaseAddress, feesEarned);
 
-	if (m_ms)
-		m_ms->output = m_out.toBytes();
-
 	// Suicides...
 	if (m_ext)
 		for (auto a: m_ext->sub.suicides)
diff --git a/libethereum/Executive.h b/libethereum/Executive.h
index f2ee6a77d..9e47bbfbf 100644
--- a/libethereum/Executive.h
+++ b/libethereum/Executive.h
@@ -42,7 +42,7 @@ struct VMTraceChannel: public LogChannel { static const char* name() { return "E
 class Executive
 {
 public:
-	Executive(State& _s, Manifest* o_ms = nullptr): m_s(_s), m_ms(o_ms) {}
+	Executive(State& _s): m_s(_s) {}
 	~Executive() = default;
 	Executive(Executive const&) = delete;
 	void operator=(Executive) = delete;
@@ -72,7 +72,6 @@ private:
 	State& m_s;
 	std::unique_ptr<ExtVM> m_ext;
 	std::unique_ptr<VMFace> m_vm;
-	Manifest* m_ms = nullptr;
 	bytesConstRef m_out;
 	Address m_newAddress;
 
diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h
index 24ce618ed..ad1045d3f 100644
--- a/libethereum/ExtVM.h
+++ b/libethereum/ExtVM.h
@@ -39,8 +39,8 @@ class ExtVM: public ExtVMFace
 {
 public:
 	/// Full constructor.
-	ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, Manifest* o_ms, unsigned _depth = 0):
-		ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache), m_ms(o_ms)
+	ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, unsigned _depth = 0):
+		ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache)
 	{
 		m_s.ensureCached(_myAddress, true, true);
 	}
@@ -49,7 +49,7 @@ public:
 	virtual u256 store(u256 _n) override final { return m_s.storage(myAddress, _n); }
 
 	/// Write a value in storage.
-	virtual void setStore(u256 _n, u256 _v) override final { m_s.setStorage(myAddress, _n, _v); if (m_ms) m_ms->altered.push_back(_n); }
+	virtual void setStore(u256 _n, u256 _v) override final { m_s.setStorage(myAddress, _n, _v); }
 
 	/// Read address's code.
 	virtual bytes const& codeAt(Address _a) override final { return m_s.code(_a); }
@@ -59,23 +59,13 @@ public:
 	{
 		// Increment associated nonce for sender.
 		m_s.noteSending(myAddress);
-		if (m_ms)
-			m_ms->internal.resize(m_ms->internal.size() + 1);
-		auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &sub, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, depth + 1);
-		if (m_ms && !m_ms->internal.back().from)
-			m_ms->internal.pop_back();
-		return ret;
+		return m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &sub, _onOp, depth + 1);
 	}
 
 	/// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller.
 	virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final
 	{
-		if (m_ms)
-			m_ms->internal.resize(m_ms->internal.size() + 1);
-		auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &sub, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, depth + 1);
-		if (m_ms && !m_ms->internal.back().from)
-			m_ms->internal.pop_back();
-		return ret;
+		return m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &sub, _onOp, depth + 1);
 	}
 
 	/// Read address's balance.
@@ -96,14 +86,13 @@ public:
 
 	/// Revert any changes made (by any of the other calls).
 	/// @TODO check call site for the parent manifest being discarded.
-	virtual void revert() override final { if (m_ms) *m_ms = Manifest(); m_s.m_cache = m_origCache; }
+	virtual void revert() override final { m_s.m_cache = m_origCache; }
 
 	State& state() const { return m_s; }
 
 private:
 	State& m_s;										///< A reference to the base state.
 	std::map<Address, Account> m_origCache;			///< The cache of the address states (i.e. the externalities) as-was prior to the execution.
-	Manifest* m_ms;
 };
 
 }
diff --git a/libethereum/Manifest.cpp b/libethereum/Manifest.cpp
index 9e6d2f651..e69de29bb 100644
--- a/libethereum/Manifest.cpp
+++ b/libethereum/Manifest.cpp
@@ -1,46 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Manifest.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Manifest.h"
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-Manifest::Manifest(bytesConstRef _r)
-{
-	RLP r(_r);
-	from = r[0].toHash<Address>();
-	to = r[1].toHash<Address>();
-	value = r[2].toInt<u256>();
-	altered = r[3].toVector<u256>();
-	input = r[4].toBytes();
-	output = r[5].toBytes();
-	for (auto const& i: r[6])
-		internal.emplace_back(i.data());
-}
-
-void Manifest::streamRLP(RLPStream& _s) const
-{
-	_s.appendList(7) << from << to << value << altered << input << output;
-	_s.appendList(internal.size());
-	for (auto const& i: internal)
-		i.streamRLP(_s);
-}
diff --git a/libethereum/Manifest.h b/libethereum/Manifest.h
index e0e512c92..e69de29bb 100644
--- a/libethereum/Manifest.h
+++ b/libethereum/Manifest.h
@@ -1,73 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Manifest.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <iostream>
-#include <sstream>
-#include <libdevcore/RLP.h>
-#include <libethcore/CommonEth.h>
-
-namespace dev
-{
-namespace eth
-{
-
-struct Manifest;
-using Manifests = std::vector<Manifest>;
-
-/**
- * @brief A record of the state-interaction of a transaction/call/create.
- */
-struct Manifest
-{
-	Manifest() {}
-	Manifest(bytesConstRef _r);
-	void streamRLP(RLPStream& _s) const;
-
-	h256 bloom() const { h256 ret = from.bloom() | to.bloom(); for (auto const& i: internal) ret |= i.bloom(); for (auto const& i: altered) ret |= h256(i).bloom(); return ret; }
-
-	std::string toString(unsigned _indent = 0) const
-	{
-		std::ostringstream oss;
-		oss << std::string(_indent * 3, ' ') << from << " -> " << to << " [" << value << "]: {";
-		if (internal.size())
-		{
-			oss << std::endl;
-			for (auto const& m: internal)
-				oss << m.toString(_indent + 1) << std::endl;
-			oss << std::string(_indent * 3, ' ');
-		}
-		oss << "} I:" << toHex(input) << "; O:" << toHex(output);
-		return oss.str();
-	}
-
-	Address from;
-	Address to;
-	u256 value;
-	u256s altered;
-	bytes input;
-	bytes output;
-	Manifests internal;
-};
-
-}
-}
diff --git a/libethereum/MessageFilter.cpp b/libethereum/MessageFilter.cpp
index 0519fe28b..f44587620 100644
--- a/libethereum/MessageFilter.cpp
+++ b/libethereum/MessageFilter.cpp
@@ -27,131 +27,6 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
-void MessageFilter::streamRLP(RLPStream& _s) const
-{
-	_s.appendList(8) << m_from << m_to << m_stateAltered << m_altered << m_earliest << m_latest << m_max << m_skip;
-}
-
-h256 MessageFilter::sha3() const
-{
-	RLPStream s;
-	streamRLP(s);
-	return dev::sha3(s.out());
-}
-
-bool MessageFilter::matches(h256 _bloom) const
-{
-	auto have = [=](Address const& a) { return _bloom.contains(a.bloom()); };
-	if (m_from.size())
-	{
-		for (auto i: m_from)
-			if (have(i))
-				goto OK1;
-		return false;
-	}
-	OK1:
-	if (m_to.size())
-	{
-		for (auto i: m_to)
-			if (have(i))
-				goto OK2;
-		return false;
-	}
-	OK2:
-	if (m_stateAltered.size() || m_altered.size())
-	{
-		for (auto i: m_altered)
-			if (have(i))
-				goto OK3;
-		for (auto i: m_stateAltered)
-			if (have(i.first) && _bloom.contains(h256(i.second).bloom()))
-				goto OK3;
-		return false;
-	}
-	OK3:
-	return true;
-}
-
-bool MessageFilter::matches(State const& _s, unsigned _i) const
-{
-	h256 b = _s.changesFromPending(_i).bloom();
-	if (!matches(b))
-		return false;
-
-	Transaction t = _s.pending()[_i];
-	if (!m_to.empty() && !m_to.count(t.receiveAddress()))
-		return false;
-	if (!m_from.empty() && !m_from.count(t.sender()))
-		return false;
-	if (m_stateAltered.empty() && m_altered.empty())
-		return true;
-	StateDiff d = _s.pendingDiff(_i);
-	if (!m_altered.empty())
-	{
-		for (auto const& s: m_altered)
-			if (d.accounts.count(s))
-				return true;
-		return false;
-	}
-	if (!m_stateAltered.empty())
-	{
-		for (auto const& s: m_stateAltered)
-			if (d.accounts.count(s.first) && d.accounts.at(s.first).storage.count(s.second))
-				return true;
-		return false;
-	}
-	return true;
-}
-
-PastMessages MessageFilter::matches(Manifest const& _m, unsigned _i) const
-{
-	PastMessages ret;
-	matches(_m, vector<unsigned>(1, _i), _m.from, PastMessages(), ret);
-	return ret;
-}
-
-bool MessageFilter::matches(Manifest const& _m, vector<unsigned> _p, Address _o, PastMessages _limbo, PastMessages& o_ret) const
-{
-	bool ret;
-
-	if ((m_from.empty() || m_from.count(_m.from)) && (m_to.empty() || m_to.count(_m.to)))
-		_limbo.push_back(PastMessage(_m, _p, _o));
-
-	// Handle limbos, by checking against all addresses in alteration.
-	bool alters = m_altered.empty() && m_stateAltered.empty();
-	alters = alters || m_altered.count(_m.from) || m_altered.count(_m.to);
-
-	if (!alters)
-		for (auto const& i: _m.altered)
-			if (m_altered.count(_m.to) || m_stateAltered.count(make_pair(_m.to, i)))
-			{
-				alters = true;
-				break;
-			}
-	// If we do alter stuff,
-	if (alters)
-	{
-		o_ret += _limbo;
-		_limbo.clear();
-		ret = true;
-	}
-
-	_p.push_back(0);
-	for (auto const& m: _m.internal)
-	{
-		if (matches(m, _p, _o, _limbo, o_ret))
-		{
-			_limbo.clear();
-			ret = true;
-		}
-		_p.back()++;
-	}
-
-	return ret;
-}
-
-
-
 void LogFilter::streamRLP(RLPStream& _s) const
 {
 	_s.appendList(6) << m_addresses << m_topics << m_earliest << m_latest << m_max << m_skip;
diff --git a/libethereum/MessageFilter.h b/libethereum/MessageFilter.h
index 482c68ef6..e2c26d214 100644
--- a/libethereum/MessageFilter.h
+++ b/libethereum/MessageFilter.h
@@ -24,7 +24,6 @@
 #include <libdevcore/Common.h>
 #include <libdevcore/RLP.h>
 #include <libethcore/CommonEth.h>
-#include "PastMessage.h"
 #include "TransactionReceipt.h"
 
 namespace dev
@@ -32,47 +31,8 @@ namespace dev
 namespace eth
 {
 
-struct Manifest;
 class State;
 
-class MessageFilter
-{
-public:
-	MessageFilter(int _earliest = 0, int _latest = -1, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {}
-
-	void streamRLP(RLPStream& _s) const;
-	h256 sha3() const;
-
-	int earliest() const { return m_earliest; }
-	int latest() const { return m_latest; }
-	unsigned max() const { return m_max; }
-	unsigned skip() const { return m_skip; }
-	bool matches(h256 _bloom) const;
-	bool matches(State const& _s, unsigned _i) const;
-	PastMessages matches(Manifest const& _m, unsigned _i) const;
-
-	MessageFilter from(Address _a) { m_from.insert(_a); return *this; }
-	MessageFilter to(Address _a) { m_to.insert(_a); return *this; }
-	MessageFilter altered(Address _a, u256 _l) { m_stateAltered.insert(std::make_pair(_a, _l)); return *this; }
-	MessageFilter altered(Address _a) { m_altered.insert(_a); return *this; }
-	MessageFilter withMax(unsigned _m) { m_max = _m; return *this; }
-	MessageFilter withSkip(unsigned _m) { m_skip = _m; return *this; }
-	MessageFilter withEarliest(int _e) { m_earliest = _e; return *this; }
-	MessageFilter withLatest(int _e) { m_latest = _e; return *this; }
-
-private:
-	bool matches(Manifest const& _m, std::vector<unsigned> _p, Address _o, PastMessages _limbo, PastMessages& o_ret) const;
-
-	std::set<Address> m_from;
-	std::set<Address> m_to;
-	std::set<std::pair<Address, u256>> m_stateAltered;
-	std::set<Address> m_altered;
-	int m_earliest = 0;
-	int m_latest = -1;
-	unsigned m_max;
-	unsigned m_skip;
-};
-
 class LogFilter
 {
 public:
diff --git a/libethereum/PastMessage.cpp b/libethereum/PastMessage.cpp
index d81ae672c..e69de29bb 100644
--- a/libethereum/PastMessage.cpp
+++ b/libethereum/PastMessage.cpp
@@ -1,28 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file PastMessage.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "PastMessage.h"
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-#pragma GCC diagnostic ignored "-Wunused-variable"
-namespace { char dummy; };
diff --git a/libethereum/PastMessage.h b/libethereum/PastMessage.h
index 6446eff5a..e69de29bb 100644
--- a/libethereum/PastMessage.h
+++ b/libethereum/PastMessage.h
@@ -1,56 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file PastMessage.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libdevcore/Common.h>
-#include <libethcore/CommonEth.h>
-#include "Manifest.h"
-
-namespace dev
-{
-namespace eth
-{
-
-struct PastMessage
-{
-	PastMessage(Manifest const& _m, std::vector<unsigned> _path, Address _o): to(_m.to), from(_m.from), value(_m.value), input(_m.input), output(_m.output), path(_path), origin(_o) {}
-
-	PastMessage& polish(h256 _b, u256 _ts, unsigned _n, Address _coinbase) { block = _b; timestamp = _ts; number = _n; coinbase = _coinbase; return *this; }
-
-	Address to;					///< The receiving address of the transaction. Address() in the case of a creation.
-	Address from;				///< The receiving address of the transaction. Address() in the case of a creation.
-	u256 value;					///< The value associated with the call.
-	bytes input;				///< The data associated with the message, or the initialiser if it's a creation transaction.
-	bytes output;				///< The data returned by the message, or the body code if it's a creation transaction.
-
-	std::vector<unsigned> path;	///< Call path into the block transaction. size() is always > 0. First item is the transaction index in the block.
-	Address origin;				///< Originating sender of the transaction.
-	Address coinbase;			///< Block coinbase.
-	h256 block;					///< Block hash.
-	u256 timestamp;				///< Block timestamp.
-	unsigned number;			///< Block number.
-};
-
-typedef std::vector<PastMessage> PastMessages;
-
-}
-}
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 539cb55f0..d36d2f530 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -90,9 +90,9 @@ void ripemd160Code(bytesConstRef _in, bytesRef _out)
 
 const std::map<unsigned, PrecompiledAddress> State::c_precompiled =
 {
-	{ 1, { 500, ecrecoverCode }},
-	{ 2, { 100, sha256Code }},
-	{ 3, { 100, ripemd160Code }}
+	{ 1, { [](bytesConstRef) -> bigint { return (bigint)500; }, ecrecoverCode }},
+	{ 2, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, sha256Code }},
+	{ 3, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, ripemd160Code }}
 };
 
 OverlayDB State::openDB(std::string _path, bool _killExisting)
@@ -792,14 +792,6 @@ bool State::amIJustParanoid(BlockChain const& _bc)
 	return false;
 }
 
-h256 State::oldBloom() const
-{
-	h256 ret = m_currentBlock.coinbaseAddress.bloom();
-	for (auto const& i: m_receipts)
-		ret |= i.changes().bloom();
-	return ret;
-}
-
 LogBloom State::logBloom() const
 {
 	LogBloom ret;
@@ -1127,9 +1119,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
 	auto h = rootHash();
 #endif
 
-	Manifest ms;
-
-	Executive e(*this, &ms);
+	Executive e(*this);
 	e.setup(_rlp);
 
 	u256 startGasUsed = gasUsed();
@@ -1179,12 +1169,12 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
 
 	// Add to the user-originated transactions that we've executed.
 	m_transactions.push_back(e.t());
-	m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs(), ms));
+	m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs()));
 	m_transactionSet.insert(e.t().sha3());
 	return e.gasUsed();
 }
 
-bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, SubState* o_sub, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
+bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, SubState* o_sub, OnOpFunc const& _onOp, unsigned _level)
 {
 	if (!_originAddress)
 		_originAddress = _senderAddress;
@@ -1192,81 +1182,63 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
 //	cnote << "Transferring" << formatBalance(_value) << "to receiver.";
 	addBalance(_receiveAddress, _value);
 
-	if (o_ms)
-	{
-		o_ms->from = _senderAddress;
-		o_ms->to = _receiveAddress;
-		o_ms->value = _value;
-		o_ms->input = _data.toBytes();
-	}
-
 	auto it = !(_codeAddress & ~h160(0xffffffff)) ? c_precompiled.find((unsigned)(u160)_codeAddress) : c_precompiled.end();
 	if (it != c_precompiled.end())
 	{
-		if (*_gas < it->second.gas)
+		bigint g = it->second.gas(_data);
+		if (*_gas < g)
 		{
 			*_gas = 0;
 			return false;
 		}
 
-		*_gas -= it->second.gas;
+		*_gas -= (u256)g;
 		it->second.exec(_data, _out);
 	}
 	else if (addressHasCode(_codeAddress))
 	{
 		auto vm = VMFactory::create(*_gas);
-		ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level);
-		bool revert = false;
-
+		ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), _level);
 		try
 		{
 			auto out = vm->go(evm, _onOp);
 			memcpy(_out.data(), out.data(), std::min(out.size(), _out.size()));
 			if (o_sub)
 				*o_sub += evm.sub;
-			if (o_ms)
-				o_ms->output = out.toBytes();
 			*_gas = vm->gas();
+			// Write state out only in the case of a non-excepted transaction.
+			return true;
 		}
 		catch (VMException const& _e)
 		{
 			clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e);
-			revert = true;
+			evm.revert();
 			*_gas = 0;
+			return false;
 		}
 		catch (Exception const& _e)
 		{
 			cwarn << "Unexpected exception in VM: " << diagnostic_information(_e) << ". This is exceptionally bad.";
 			// TODO: use fallback known-safe VM.
+			// AUDIT: THIS SHOULD NEVER HAPPEN! PROVE IT!
+			throw;
 		}
 		catch (std::exception const& _e)
 		{
 			cwarn << "Unexpected exception in VM: " << _e.what() << ". This is exceptionally bad.";
 			// TODO: use fallback known-safe VM.
+			// AUDIT: THIS SHOULD NEVER HAPPEN! PROVE IT!
+			throw;
 		}
-
-		// Write state out only in the case of a non-excepted transaction.
-		if (revert)
-			evm.revert();
-
-		return !revert;
 	}
 	return true;
 }
 
-h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, SubState* o_sub, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
+h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, SubState* o_sub, OnOpFunc const& _onOp, unsigned _level)
 {
 	if (!_origin)
 		_origin = _sender;
 
-	if (o_ms)
-	{
-		o_ms->from = _sender;
-		o_ms->to = Address();
-		o_ms->value = _endowment;
-		o_ms->input = _code.toBytes();
-	}
-
 	Address newAddress = right160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1)));
 
 	// Set up new account...
@@ -1274,50 +1246,44 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
 
 	// Execute init code.
 	auto vm = VMFactory::create(*_gas);
-	ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, o_ms, _level);
-	bool revert = false;
+	ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, _level);
 	bytesConstRef out;
 
 	try
 	{
 		out = vm->go(evm, _onOp);
-		if (o_ms)
-			o_ms->output = out.toBytes();
 		if (o_sub)
 			*o_sub += evm.sub;
 		*_gas = vm->gas();
+
+		if (out.size() * c_createDataGas <= *_gas)
+			*_gas -= out.size() * c_createDataGas;
+		else
+			out.reset();
+
+		// Set code.
+		if (!evm.sub.suicides.count(newAddress))
+			m_cache[newAddress].setCode(out);
 	}
 	catch (VMException const& _e)
 	{
 		clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e);
-		revert = true;
+		evm.revert();
 		*_gas = 0;
 	}
 	catch (Exception const& _e)
 	{
 		// TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does.
 		cwarn << "Unexpected exception in VM. There may be a bug in this implementation. " << diagnostic_information(_e);
+		throw;
 	}
 	catch (std::exception const& _e)
 	{
 		// TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does.
 		cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what();
+		throw;
 	}
 
-	// TODO: CHECK: AUDIT: IS THIS CORRECT?! (esp. given account created prior to revertion init.)
-
-	// Write state out only in the case of a non-out-of-gas transaction.
-	if (revert)
-	{
-		evm.revert();
-		m_cache.erase(newAddress);
-		newAddress = Address();
-	}
-	else
-		// Set code.
-		if (addressInUse(newAddress))
-			m_cache[newAddress].setCode(out);
-
 	return newAddress;
 }
 
diff --git a/libethereum/State.h b/libethereum/State.h
index 5fcfa1cf7..10d73f671 100644
--- a/libethereum/State.h
+++ b/libethereum/State.h
@@ -54,7 +54,7 @@ struct StateDetail: public LogChannel { static const char* name() { return "/S/"
 
 struct PrecompiledAddress
 {
-	unsigned gas;
+	std::function<bigint(bytesConstRef)> gas;
 	std::function<void(bytesConstRef, bytesRef)> exec;
 };
 
@@ -210,15 +210,6 @@ public:
 	/// Get the list of pending transactions.
 	Transactions const& pending() const { return m_transactions; }
 
-	/// Get the list of pending transactions. TODO: PoC-7: KILL
-	Manifest changesFromPending(unsigned _i) const { return m_receipts[_i].changes(); }
-
-	/// Get the bloom filter of all changes happened in the block. TODO: PoC-7: KILL
-	h256 oldBloom() const;
-
-	/// Get the bloom filter of a particular transaction that happened in the block. TODO: PoC-7: KILL
-	h256 oldBloom(unsigned _i) const { return m_receipts[_i].changes().bloom(); }
-
 	/// Get the transaction receipt for the transaction of the given index.
 	TransactionReceipt const& receipt(unsigned _i) const { return m_receipts[_i]; }
 
@@ -258,6 +249,9 @@ public:
 	/// the block since all state changes are ultimately reversed.
 	void cleanup(bool _fullCommit);
 
+	/// Info on precompiled contract accounts baked into the protocol.
+	static std::map<unsigned, PrecompiledAddress> const& precompiled() { return c_precompiled; }
+
 private:
 	/// Undo the changes to the state for committing to mine.
 	void uncommitToMine();
@@ -282,12 +276,12 @@ private:
 	// We assume all instrinsic fees are paid up before this point.
 
 	/// Execute a contract-creation transaction.
-	h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), SubState* o_sub = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
+	h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), SubState* o_sub = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
 
 	/// Execute a call.
 	/// @a _gas points to the amount of gas to use for the call, and will lower it accordingly.
 	/// @returns false if the call ran out of gas before completion. true otherwise.
-	bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), SubState* o_sub = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
+	bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), SubState* o_sub = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
 
 	/// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock).
 	void resetCurrent();
diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h
index e24c224e7..b990459d9 100644
--- a/libethereum/TransactionReceipt.h
+++ b/libethereum/TransactionReceipt.h
@@ -38,9 +38,7 @@ class TransactionReceipt
 {
 public:
 	TransactionReceipt(bytesConstRef _rlp) { RLP r(_rlp); m_stateRoot = (h256)r[0]; m_gasUsed = (u256)r[1]; m_bloom = (LogBloom)r[2]; for (auto const& i: r[3]) m_log.emplace_back(i); }
-	TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log, Manifest const& _ms): m_stateRoot(_root), m_gasUsed(_gasUsed), m_bloom(eth::bloom(_log)), m_log(_log), m_changes(_ms) {}
-
-	Manifest const& changes() const { return m_changes; }
+	TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log): m_stateRoot(_root), m_gasUsed(_gasUsed), m_bloom(eth::bloom(_log)), m_log(_log) {}
 
 	h256 const& stateRoot() const { return m_stateRoot; }
 	u256 const& gasUsed() const { return m_gasUsed; }
@@ -62,8 +60,6 @@ private:
 	u256 m_gasUsed;
 	LogBloom m_bloom;
 	LogEntries m_log;
-
-	Manifest m_changes;	///< TODO: PoC-7: KILL
 };
 
 using TransactionReceipts = std::vector<TransactionReceipt>;
diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h
index 52798cd89..24c7dfcda 100644
--- a/libevm/ExtVMFace.h
+++ b/libevm/ExtVMFace.h
@@ -85,7 +85,10 @@ struct SubState
 	}
 };
 
-using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, void/*VM*/*, void/*ExtVM*/ const*)>;
+class ExtVMFace;
+class VM;
+
+using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>;
 
 /**
  * @brief Interface and null implementation of the class for specifying VM externalities.
@@ -146,7 +149,7 @@ public:
 	u256 value;					///< Value (in Wei) that was passed to this address.
 	u256 gasPrice;				///< Price of gas (that we already paid).
 	bytesConstRef data;			///< Current input data.
-	bytes code;			///< Current code that is executing.
+	bytes code;					///< Current code that is executing.
 	BlockInfo previousBlock;	///< The previous block's information.
 	BlockInfo currentBlock;		///< The current block's information.
 	SubState sub;				///< Sub-band VM state (suicides, refund counter, logs).
diff --git a/libevm/FeeStructure.cpp b/libevm/FeeStructure.cpp
index 3e957118e..94eb956af 100644
--- a/libevm/FeeStructure.cpp
+++ b/libevm/FeeStructure.cpp
@@ -27,12 +27,14 @@ using namespace dev::eth;
 
 u256 const dev::eth::c_stepGas = 1;
 u256 const dev::eth::c_balanceGas = 20;
-u256 const dev::eth::c_sha3Gas = 20;
+u256 const dev::eth::c_sha3Gas = 10;
+u256 const dev::eth::c_sha3WordGas = 10;
 u256 const dev::eth::c_sloadGas = 20;
 u256 const dev::eth::c_sstoreSetGas = 300;
 u256 const dev::eth::c_sstoreResetGas = 100;
 u256 const dev::eth::c_sstoreRefundGas = 100;
 u256 const dev::eth::c_createGas = 100;
+u256 const dev::eth::c_createDataGas = 5;
 u256 const dev::eth::c_callGas = 20;
 u256 const dev::eth::c_expGas = 1;
 u256 const dev::eth::c_expByteGas = 1;
diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h
index 3fb8175e6..8ef384265 100644
--- a/libevm/FeeStructure.h
+++ b/libevm/FeeStructure.h
@@ -31,11 +31,13 @@ namespace eth
 extern u256 const c_stepGas;			///< Once per operation, except for SSTORE, SLOAD, BALANCE, SHA3, CREATE, CALL.
 extern u256 const c_balanceGas;			///< Once per BALANCE operation.
 extern u256 const c_sha3Gas;			///< Once per SHA3 operation.
+extern u256 const c_sha3WordGas;
 extern u256 const c_sloadGas;			///< Once per SLOAD operation.
 extern u256 const c_sstoreSetGas;		///< Once per SSTORE operation if the zeroness changes from zero.
 extern u256 const c_sstoreResetGas;		///< Once per SSTORE operation if the zeroness doesn't change.
 extern u256 const c_sstoreRefundGas;	///< Refunded gas, once per SSTORE operation if the zeroness changes to zero.
 extern u256 const c_createGas;			///< Once per CREATE operation & contract-creation transaction.
+extern u256 const c_createDataGas;
 extern u256 const c_callGas;			///< Once per CALL operation & message call transaction.
 extern u256 const c_expGas;				///< Once per EXP instuction.
 extern u256 const c_expByteGas;			///< Times ceil(log256(exponent)) for the EXP instruction.
diff --git a/libevm/VM.h b/libevm/VM.h
index c427802f6..6f3229920 100644
--- a/libevm/VM.h
+++ b/libevm/VM.h
@@ -175,7 +175,7 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st
 			break;
 		case Instruction::SHA3:
 			require(2);
-			runGas = c_sha3Gas;
+			runGas = c_sha3Gas + (m_stack[m_stack.size() - 2] + 31) / 32 * c_sha3WordGas;
 			newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]);
 			break;
 		case Instruction::CALLDATACOPY:
diff --git a/liblll/CompilerState.cpp b/liblll/CompilerState.cpp
index c3dc2dda3..63351bc4c 100644
--- a/liblll/CompilerState.cpp
+++ b/liblll/CompilerState.cpp
@@ -72,6 +72,11 @@ void CompilerState::populateStandard()
 	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
 	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
 	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
+	"(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
+	"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
+	"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
+	"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
+	"(def 'ripemd160 (val) { [0]:val (ripemd160 0 32) })"
 	"}";
 	CodeFragment::compile(s, *this);
 }
diff --git a/libsolidity/AST.h b/libsolidity/AST.h
index 0faea3fb9..19c4b4275 100644
--- a/libsolidity/AST.h
+++ b/libsolidity/AST.h
@@ -156,13 +156,15 @@ class ContractDefinition: public Declaration
 public:
 	ContractDefinition(Location const& _location,
 					   ASTPointer<ASTString> const& _name,
+					   ASTPointer<ASTString> const& _documentation,
 					   std::vector<ASTPointer<StructDefinition>> const& _definedStructs,
 					   std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables,
 					   std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions):
 		Declaration(_location, _name),
 		m_definedStructs(_definedStructs),
 		m_stateVariables(_stateVariables),
-		m_definedFunctions(_definedFunctions)
+		m_definedFunctions(_definedFunctions),
+		m_documentation(_documentation)
 	{}
 
 	virtual void accept(ASTVisitor& _visitor) override;
@@ -172,6 +174,10 @@ public:
 	std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() const { return m_stateVariables; }
 	std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() const { return m_definedFunctions; }
 
+	/// @return A shared pointer of an ASTString.
+	/// Can contain a nullptr in which case indicates absence of documentation
+	ASTPointer<ASTString> const& getDocumentation() const { return m_documentation; }
+
 	/// Returns the functions that make up the calling interface in the intended order.
 	std::vector<FunctionDefinition const*> getInterfaceFunctions() const;
 
@@ -179,6 +185,7 @@ private:
 	std::vector<ASTPointer<StructDefinition>> m_definedStructs;
 	std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
 	std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
+	ASTPointer<ASTString> m_documentation;
 };
 
 class StructDefinition: public Declaration
diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp
index c3e62cad0..f26088afa 100644
--- a/libsolidity/InterfaceHandler.cpp
+++ b/libsolidity/InterfaceHandler.cpp
@@ -75,7 +75,7 @@ std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(ContractDefi
 		if (strPtr)
 		{
 			resetUser();
-			parseDocString(*strPtr);
+			parseDocString(*strPtr, CommentOwner::FUNCTION);
 			if (!m_notice.empty())
 			{// since @notice is the only user tag if missing function should not appear
 				user["notice"] = Json::Value(m_notice);
@@ -95,6 +95,20 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(ContractDefin
 	Json::Value doc;
 	Json::Value methods(Json::objectValue);
 
+	auto contractDoc = _contractDef.getDocumentation();
+	if (contractDoc)
+	{
+		m_contractAuthor.clear();
+		m_title.clear();
+		parseDocString(*contractDoc, CommentOwner::CONTRACT);
+
+		if (!m_contractAuthor.empty())
+			doc["author"] = m_contractAuthor;
+
+		if (!m_title.empty())
+			doc["title"] = m_title;
+	}
+
 	for (FunctionDefinition const* f: _contractDef.getInterfaceFunctions())
 	{
 		Json::Value method;
@@ -102,16 +116,21 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(ContractDefin
 		if (strPtr)
 		{
 			resetDev();
-			parseDocString(*strPtr);
+			parseDocString(*strPtr, CommentOwner::FUNCTION);
 
 			if (!m_dev.empty())
 				method["details"] = Json::Value(m_dev);
+
+			if (!m_author.empty())
+				method["author"] = m_author;
+
 			Json::Value params(Json::objectValue);
 			for (auto const& pair: m_params)
 				params[pair.first] = pair.second;
 
 			if (!m_params.empty())
 				method["params"] = params;
+
 			if (!m_return.empty())
 				method["return"] = m_return;
 
@@ -133,6 +152,7 @@ void InterfaceHandler::resetUser()
 void InterfaceHandler::resetDev()
 {
 	m_dev.clear();
+	m_author.clear();
 	m_return.clear();
 	m_params.clear();
 }
@@ -193,10 +213,12 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con
 
 std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_iterator _pos,
 														  std::string::const_iterator _end,
-														  std::string const& _tag)
+														  std::string const& _tag,
+														  CommentOwner _owner)
 {
 	// LTODO: need to check for @(start of a tag) between here and the end of line
-	//      for all cases
+	// for all cases. Also somehow automate list of acceptable tags for each
+	// language construct since current way does not scale well.
 	if (m_lastTag == DocTagType::NONE || _tag != "")
 	{
 		if (_tag == "dev")
@@ -205,37 +227,77 @@ std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_ite
 			return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
 		else if (_tag == "return")
 			return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
+		else if (_tag == "author")
+		{
+			if (_owner == CommentOwner::CONTRACT)
+				return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR);
+			else if (_owner == CommentOwner::FUNCTION)
+				return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR);
+			else
+				// LTODO: for now this else makes no sense but later comments will go to more language constructs
+				BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag is legal only for contracts"));
+		}
+		else if (_tag == "title")
+		{
+			if (_owner == CommentOwner::CONTRACT)
+				return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE);
+			else
+				// LTODO: Unknown tag, throw some form of warning and not just an exception
+				BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag is legal only for contracts"));
+		}
 		else if (_tag == "param")
 			return parseDocTagParam(_pos, _end);
 		else
-		{
 			// LTODO: Unknown tag, throw some form of warning and not just an exception
 			BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("Unknown tag " + _tag + " encountered"));
-		}
 	}
 	else
-		return appendDocTag(_pos, _end);
+		return appendDocTag(_pos, _end, _owner);
 }
 
 std::string::const_iterator InterfaceHandler::appendDocTag(std::string::const_iterator _pos,
-														   std::string::const_iterator _end)
+														   std::string::const_iterator _end,
+														   CommentOwner _owner)
 {
 	switch (m_lastTag)
 	{
-		case DocTagType::DEV:
-			m_dev += " ";
-			return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
-		case DocTagType::NOTICE:
-			m_notice += " ";
-			return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
-		case DocTagType::RETURN:
-			m_return += " ";
-			return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
-		case DocTagType::PARAM:
-			return appendDocTagParam(_pos, _end);
-		default:
-			BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Illegal documentation tag type"));
-			break;
+	case DocTagType::DEV:
+		m_dev += " ";
+		return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
+	case DocTagType::NOTICE:
+		m_notice += " ";
+		return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
+	case DocTagType::RETURN:
+		m_return += " ";
+		return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
+	case DocTagType::AUTHOR:
+		if (_owner == CommentOwner::CONTRACT)
+		{
+			m_contractAuthor += " ";
+			return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR);
+		}
+		else if (_owner == CommentOwner::FUNCTION)
+		{
+			m_author += " ";
+			return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR);
+		}
+		else
+			// LTODO: Unknown tag, throw some form of warning and not just an exception
+			BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag in illegal comment"));
+	case DocTagType::TITLE:
+		if (_owner == CommentOwner::CONTRACT)
+		{
+			m_title += " ";
+			return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE);
+		}
+		else
+			// LTODO: Unknown tag, throw some form of warning and not just an exception
+			BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag in illegal comment"));
+	case DocTagType::PARAM:
+		return appendDocTagParam(_pos, _end);
+	default:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Illegal documentation tag type"));
+		break;
 	}
 }
 
@@ -247,7 +309,7 @@ static inline std::string::const_iterator getFirstSpaceOrNl(std::string::const_i
 	return (spacePos < nlPos) ? spacePos : nlPos;
 }
 
-void InterfaceHandler::parseDocString(std::string const& _string)
+void InterfaceHandler::parseDocString(std::string const& _string, CommentOwner _owner)
 {
 	auto currPos = _string.begin();
 	auto end = _string.end();
@@ -265,10 +327,10 @@ void InterfaceHandler::parseDocString(std::string const& _string)
 				BOOST_THROW_EXCEPTION(DocstringParsingError() <<
 									  errinfo_comment("End of tag " + std::string(tagPos, tagNameEndPos) + "not found"));
 
-			currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos));
+			currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos), _owner);
 		}
 		else if (m_lastTag != DocTagType::NONE) // continuation of the previous tag
-			currPos = appendDocTag(currPos + 1, end);
+			currPos = appendDocTag(currPos + 1, end, _owner);
 		else if (currPos != end) // skip the line if a newline was found
 			currPos = nlPos + 1;
 	}
diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h
index e6be9e6a7..d71345b96 100644
--- a/libsolidity/InterfaceHandler.h
+++ b/libsolidity/InterfaceHandler.h
@@ -45,7 +45,15 @@ enum class DocTagType: uint8_t
 	DEV,
 	NOTICE,
 	PARAM,
-	RETURN
+	RETURN,
+	AUTHOR,
+	TITLE
+};
+
+enum class CommentOwner
+{
+	CONTRACT,
+	FUNCTION
 };
 
 class InterfaceHandler
@@ -89,12 +97,14 @@ private:
 												 std::string::const_iterator _end);
 	std::string::const_iterator appendDocTagParam(std::string::const_iterator _pos,
 												  std::string::const_iterator _end);
-	void parseDocString(std::string const& _string);
+	void parseDocString(std::string const& _string, CommentOwner _owner);
 	std::string::const_iterator appendDocTag(std::string::const_iterator _pos,
-											 std::string::const_iterator _end);
+											 std::string::const_iterator _end,
+											 CommentOwner _owner);
 	std::string::const_iterator parseDocTag(std::string::const_iterator _pos,
 											std::string::const_iterator _end,
-											std::string const& _tag);
+											std::string const& _tag,
+											CommentOwner _owner);
 
 	Json::StyledWriter m_writer;
 
@@ -103,6 +113,9 @@ private:
 	std::string m_notice;
 	std::string m_dev;
 	std::string m_return;
+	std::string m_contractAuthor;
+	std::string m_author;
+	std::string m_title;
 	std::vector<std::pair<std::string, std::string>> m_params;
 };
 
diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp
index ddab489b6..b678b2fc0 100644
--- a/libsolidity/Parser.cpp
+++ b/libsolidity/Parser.cpp
@@ -112,6 +112,9 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
 ASTPointer<ContractDefinition> Parser::parseContractDefinition()
 {
 	ASTNodeFactory nodeFactory(*this);
+	ASTPointer<ASTString> docstring;
+	if (m_scanner->getCurrentCommentLiteral() != "")
+		docstring = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
 	expectToken(Token::CONTRACT);
 	ASTPointer<ASTString> name = expectIdentifierToken();
 	expectToken(Token::LBRACE);
@@ -146,7 +149,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
 	}
 	nodeFactory.markEndPosition();
 	expectToken(Token::RBRACE);
-	return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
+	return nodeFactory.createNode<ContractDefinition>(name, docstring, structs, stateVariables, functions);
 }
 
 ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
diff --git a/libsolidity/Types.h b/libsolidity/Types.h
index 887a1ee16..dd89f311d 100644
--- a/libsolidity/Types.h
+++ b/libsolidity/Types.h
@@ -184,6 +184,7 @@ private:
 class BoolType: public Type
 {
 public:
+	BoolType() {}
 	virtual Category getCategory() const { return Category::BOOL; }
 	virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
 	virtual bool acceptsBinaryOperator(Token::Value _operator) const override
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index d3dd39459..6ace332f7 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -255,7 +255,22 @@ bool CommandLineInterface::processInput()
 	}
 	else
 		for (string const& infile: m_args["input-file"].as<vector<string>>())
+		{
+			auto path = boost::filesystem::path(infile);
+			if (!boost::filesystem::exists(path))
+			{
+				cout << "Skipping non existant input file \"" << infile << "\"" << endl;
+				continue;
+			}
+
+			if (!boost::filesystem::is_regular_file(path))
+			{
+				cout << "\"" << infile << "\" is not a valid file. Skipping" << endl;
+				continue;
+			}
+
 			m_sourceCodes[infile] = asString(dev::contents(infile));
+		}
 
 	try
 	{
diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp
index 3c2bb0814..3c77492a5 100644
--- a/test/solidityEndToEndTest.cpp
+++ b/test/solidityEndToEndTest.cpp
@@ -24,137 +24,18 @@
 #include <string>
 #include <tuple>
 #include <boost/test/unit_test.hpp>
-#include <libethereum/State.h>
-#include <libethereum/Executive.h>
-#include <libsolidity/CompilerStack.h>
 #include <libdevcrypto/SHA3.h>
+#include <test/solidityExecutionFramework.h>
 
 using namespace std;
 
 namespace dev
 {
-/// Provides additional overloads for toBigEndian to encode arguments and return values.
-inline bytes toBigEndian(byte _value) { return bytes({_value}); }
-inline bytes toBigEndian(bool _value) { return bytes({byte(_value)}); }
-
 namespace solidity
 {
 namespace test
 {
 
-class ExecutionFramework
-{
-public:
-	ExecutionFramework() { g_logVerbosity = 0; }
-
-	bytes const& compileAndRun(string const& _sourceCode, u256 const& _value = 0, string const& _contractName = "")
-	{
-		dev::solidity::CompilerStack compiler;
-		compiler.compile(_sourceCode);
-		bytes code = compiler.getBytecode(_contractName);
-		sendMessage(code, true, _value);
-		BOOST_REQUIRE(!m_output.empty());
-		return m_output;
-	}
-
-	bytes const& callContractFunction(byte _index, bytes const& _data = bytes(), u256 const& _value = 0)
-	{
-		sendMessage(bytes(1, _index) + _data, false, _value);
-		return m_output;
-	}
-
-	template <class... Args>
-	bytes const& callContractFunction(byte _index, Args const&... _arguments)
-	{
-		return callContractFunction(_index, argsToBigEndian(_arguments...));
-	}
-
-	template <class CppFunction, class... Args>
-	void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments)
-	{
-		bytes solidityResult = callContractFunction(_index, _arguments...);
-		bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
-		BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
-							"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult));
-	}
-
-	template <class CppFunction, class... Args>
-	void testSolidityAgainstCppOnRange(byte _index, CppFunction const& _cppFunction,
-									   u256 const& _rangeStart, u256 const& _rangeEnd)
-	{
-		for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)
-		{
-			bytes solidityResult = callContractFunction(_index, argument);
-			bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
-			BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
-								"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult) +
-								"\nArgument: " + toHex(toBigEndian(argument)));
-		}
-	}
-
-private:
-	template <class FirstArg, class... Args>
-	bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const
-	{
-		return toBigEndian(_firstArg) + argsToBigEndian(_followingArgs...);
-	}
-
-	bytes argsToBigEndian() const { return bytes(); }
-
-	template <class CppFunction, class... Args>
-	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
-	-> typename enable_if<is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
-	{
-		_cppFunction(_arguments...);
-		return bytes();
-	}
-	template <class CppFunction, class... Args>
-	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
-	-> typename enable_if<!is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
-	{
-		return toBigEndian(_cppFunction(_arguments...));
-	}
-
-	void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
-	{
-		m_state.addBalance(m_sender, _value); // just in case
-		eth::Executive executive(m_state);
-		eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec())
-										 : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec());
-		bytes transactionRLP = t.rlp();
-		try
-		{
-			// this will throw since the transaction is invalid, but it should nevertheless store the transaction
-			executive.setup(&transactionRLP);
-		}
-		catch (...) {}
-		if (_isCreation)
-		{
-			BOOST_REQUIRE(!executive.create(m_sender, _value, m_gasPrice, m_gas, &_data, m_sender));
-			m_contractAddress = executive.newAddress();
-			BOOST_REQUIRE(m_contractAddress);
-			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
-		}
-		else
-		{
-			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
-			BOOST_REQUIRE(!executive.call(m_contractAddress, m_sender, _value, m_gasPrice, &_data, m_gas, m_sender));
-		}
-		BOOST_REQUIRE(executive.go());
-		m_state.noteSending(m_sender);
-		executive.finalize();
-		m_output = executive.out().toVector();
-	}
-
-protected:
-	Address m_sender;
-	Address m_contractAddress;
-	eth::State m_state;
-	u256 const m_gasPrice = 100 * eth::szabo;
-	u256 const m_gas = 1000000;
-	bytes m_output;
-};
-
 BOOST_FIXTURE_TEST_SUITE(SolidityCompilerEndToEndTest, ExecutionFramework)
 
 BOOST_AUTO_TEST_CASE(smoke_test)
diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h
new file mode 100644
index 000000000..9d40e8a46
--- /dev/null
+++ b/test/solidityExecutionFramework.h
@@ -0,0 +1,161 @@
+
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Framework for executing Solidity contracts and testing them against C++ implementation.
+ */
+
+#pragma once
+
+#include <string>
+#include <tuple>
+#include <boost/test/unit_test.hpp>
+#include <libethereum/State.h>
+#include <libethereum/Executive.h>
+#include <libsolidity/CompilerStack.h>
+
+namespace dev
+{
+/// Provides additional overloads for toBigEndian to encode arguments and return values.
+inline bytes toBigEndian(byte _value) { return bytes({_value}); }
+inline bytes toBigEndian(bool _value) { return bytes({byte(_value)}); }
+
+namespace solidity
+{
+namespace test
+{
+
+class ExecutionFramework
+{
+public:
+	ExecutionFramework() { g_logVerbosity = 0; }
+
+	bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "")
+	{
+		dev::solidity::CompilerStack compiler;
+		compiler.compile(_sourceCode, m_optimize);
+		bytes code = compiler.getBytecode(_contractName);
+		sendMessage(code, true, _value);
+		BOOST_REQUIRE(!m_output.empty());
+		return m_output;
+	}
+
+	bytes const& callContractFunction(byte _index, bytes const& _data = bytes(), u256 const& _value = 0)
+	{
+		sendMessage(bytes(1, _index) + _data, false, _value);
+		return m_output;
+	}
+
+	template <class... Args>
+	bytes const& callContractFunction(byte _index, Args const&... _arguments)
+	{
+		return callContractFunction(_index, argsToBigEndian(_arguments...));
+	}
+
+	template <class CppFunction, class... Args>
+	void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments)
+	{
+		bytes solidityResult = callContractFunction(_index, _arguments...);
+		bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
+		BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
+							"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult));
+	}
+
+	template <class CppFunction, class... Args>
+	void testSolidityAgainstCppOnRange(byte _index, CppFunction const& _cppFunction,
+									   u256 const& _rangeStart, u256 const& _rangeEnd)
+	{
+		for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)
+		{
+			bytes solidityResult = callContractFunction(_index, argument);
+			bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
+			BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
+								"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult) +
+								"\nArgument: " + toHex(toBigEndian(argument)));
+		}
+	}
+
+private:
+	template <class FirstArg, class... Args>
+	bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const
+	{
+		return toBigEndian(_firstArg) + argsToBigEndian(_followingArgs...);
+	}
+
+	bytes argsToBigEndian() const { return bytes(); }
+
+	template <class CppFunction, class... Args>
+	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
+	-> typename std::enable_if<std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
+	{
+		_cppFunction(_arguments...);
+		return bytes();
+	}
+	template <class CppFunction, class... Args>
+	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
+	-> typename std::enable_if<!std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
+	{
+		return toBigEndian(_cppFunction(_arguments...));
+	}
+
+	void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
+	{
+		m_state.addBalance(m_sender, _value); // just in case
+		eth::Executive executive(m_state);
+		eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec())
+										 : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec());
+		bytes transactionRLP = t.rlp();
+		try
+		{
+			// this will throw since the transaction is invalid, but it should nevertheless store the transaction
+			executive.setup(&transactionRLP);
+		}
+		catch (...) {}
+		if (_isCreation)
+		{
+			BOOST_REQUIRE(!executive.create(m_sender, _value, m_gasPrice, m_gas, &_data, m_sender));
+			m_contractAddress = executive.newAddress();
+			BOOST_REQUIRE(m_contractAddress);
+			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
+		}
+		else
+		{
+			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
+			BOOST_REQUIRE(!executive.call(m_contractAddress, m_sender, _value, m_gasPrice, &_data, m_gas, m_sender));
+		}
+		BOOST_REQUIRE(executive.go());
+		m_state.noteSending(m_sender);
+		executive.finalize();
+		m_output = executive.out().toVector();
+	}
+
+protected:
+	bool m_optimize = false;
+	Address m_sender;
+	Address m_contractAddress;
+	eth::State m_state;
+	u256 const m_gasPrice = 100 * eth::szabo;
+	u256 const m_gas = 1000000;
+	bytes m_output;
+};
+
+}
+}
+} // end namespaces
+
diff --git a/test/solidityNatspecJSON.cpp b/test/solidityNatspecJSON.cpp
index f1795fe1c..641bb82ab 100644
--- a/test/solidityNatspecJSON.cpp
+++ b/test/solidityNatspecJSON.cpp
@@ -22,6 +22,7 @@
 
 #include <boost/test/unit_test.hpp>
 #include <libsolidity/CompilerStack.h>
+#include <libsolidity/Exceptions.h>
 #include <jsonrpc/json/json.h>
 #include <libdevcore/Exceptions.h>
 
@@ -393,6 +394,93 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return)
 	checkNatspec(sourceCode, natspec, false);
 }
 
+BOOST_AUTO_TEST_CASE(dev_contract_no_doc)
+{
+	char const* sourceCode = "contract test {\n"
+	"  /// @dev Mul function\n"
+	"  function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
+	"}\n";
+
+	char const* natspec = "{"
+	"    \"methods\":{"
+	"        \"mul\":{ \n"
+	"            \"details\": \"Mul function\"\n"
+	"        }\n"
+	"    }\n"
+	"}";
+
+	checkNatspec(sourceCode, natspec, false);
+}
+
+BOOST_AUTO_TEST_CASE(dev_contract_doc)
+{
+	char const* sourceCode = " /// @author Lefteris\n"
+	" /// @title Just a test contract\n"
+	"contract test {\n"
+	"  /// @dev Mul function\n"
+	"  function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
+	"}\n";
+
+	char const* natspec = "{"
+	"    \"author\": \"Lefteris\","
+	"    \"title\": \"Just a test contract\","
+	"    \"methods\":{"
+	"        \"mul\":{ \n"
+	"            \"details\": \"Mul function\"\n"
+	"        }\n"
+	"    }\n"
+	"}";
+
+	checkNatspec(sourceCode, natspec, false);
+}
+
+BOOST_AUTO_TEST_CASE(dev_author_at_function)
+{
+	char const* sourceCode = " /// @author Lefteris\n"
+	" /// @title Just a test contract\n"
+	"contract test {\n"
+	"  /// @dev Mul function\n"
+	"  /// @author John Doe\n"
+	"  function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
+	"}\n";
+
+	char const* natspec = "{"
+	"    \"author\": \"Lefteris\","
+	"    \"title\": \"Just a test contract\","
+	"    \"methods\":{"
+	"        \"mul\":{ \n"
+	"            \"details\": \"Mul function\",\n"
+	"            \"author\": \"John Doe\",\n"
+	"        }\n"
+	"    }\n"
+	"}";
+
+	checkNatspec(sourceCode, natspec, false);
+}
+
+BOOST_AUTO_TEST_CASE(dev_title_at_function_error)
+{
+	char const* sourceCode = " /// @author Lefteris\n"
+	" /// @title Just a test contract\n"
+	"contract test {\n"
+	"  /// @dev Mul function\n"
+	"  /// @title I really should not be here\n"
+	"  function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
+	"}\n";
+
+	char const* natspec = "{"
+	"    \"author\": \"Lefteris\","
+	"    \"title\": \"Just a test contract\","
+	"    \"methods\":{"
+	"        \"mul\":{ \n"
+	"            \"details\": \"Mul function\"\n"
+	"        }\n"
+	"    }\n"
+	"}";
+
+	BOOST_CHECK_THROW(checkNatspec(sourceCode, natspec, false), DocstringParsingError);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 }
diff --git a/test/solidityOptimizerTest.cpp b/test/solidityOptimizerTest.cpp
new file mode 100644
index 000000000..f8d3b552c
--- /dev/null
+++ b/test/solidityOptimizerTest.cpp
@@ -0,0 +1,131 @@
+
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Tests for the Solidity optimizer.
+ */
+
+#include <string>
+#include <tuple>
+#include <boost/test/unit_test.hpp>
+#include <boost/lexical_cast.hpp>
+#include <test/solidityExecutionFramework.h>
+
+using namespace std;
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+class OptimizerTestFramework: public ExecutionFramework
+{
+public:
+	OptimizerTestFramework() { }
+	/// Compiles the source code with and without optimizing.
+	void compileBothVersions(unsigned _expectedSizeDecrease, std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "") {
+		m_optimize = false;
+		bytes nonOptimizedBytecode = compileAndRun(_sourceCode, _value, _contractName);
+		m_nonOptimizedContract = m_contractAddress;
+		m_optimize = true;
+		bytes optimizedBytecode = compileAndRun(_sourceCode, _value, _contractName);
+		int sizeDiff = nonOptimizedBytecode.size() - optimizedBytecode.size();
+		BOOST_CHECK_MESSAGE(sizeDiff >= _expectedSizeDecrease, "Bytecode did only shrink by "
+							+ boost::lexical_cast<string>(sizeDiff) + " bytes, expected: "
+							+ boost::lexical_cast<string>(_expectedSizeDecrease));
+		m_optimizedContract = m_contractAddress;
+	}
+
+	template <class... Args>
+	void compareVersions(byte _index, Args const&... _arguments)
+	{
+		m_contractAddress = m_nonOptimizedContract;
+		bytes nonOptimizedOutput = callContractFunction(_index, _arguments...);
+		m_contractAddress = m_optimizedContract;
+		bytes optimizedOutput = callContractFunction(_index, _arguments...);
+		BOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, "Computed values do not match."
+							"\nNon-Optimized: " + toHex(nonOptimizedOutput) +
+							"\nOptimized:     " + toHex(optimizedOutput));
+	}
+
+protected:
+	Address m_optimizedContract;
+	Address m_nonOptimizedContract;
+};
+
+BOOST_FIXTURE_TEST_SUITE(SolidityOptimizerTest, OptimizerTestFramework)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint a) returns (uint b) {
+				return a;
+			}
+		})";
+	compileBothVersions(4, sourceCode);
+	compareVersions(0, u256(7));
+}
+
+BOOST_AUTO_TEST_CASE(large_integers)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f() returns (uint a, uint b) {
+				a = 0x234234872642837426347000000;
+				b = 0x110000000000000000000000002;
+			}
+		})";
+	compileBothVersions(28, sourceCode);
+	compareVersions(0);
+}
+
+BOOST_AUTO_TEST_CASE(invariants)
+{
+	char const* sourceCode = R"(
+		contract test {
+			function f(uint a) returns (uint b) {
+				return (((a + (1 - 1)) ^ 0) | 0) & (uint(0) - 1);
+			}
+		})";
+	compileBothVersions(19, sourceCode);
+	compareVersions(0, u256(0x12334664));
+}
+
+BOOST_AUTO_TEST_CASE(unused_expressions)
+{
+	char const* sourceCode = R"(
+		contract test {
+			uint data;
+			function f() returns (uint a, uint b) {
+				10 + 20;
+				data;
+			}
+		})";
+	compileBothVersions(11, sourceCode);
+	compareVersions(0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+} // end namespaces
diff --git a/test/vm.cpp b/test/vm.cpp
index 02cee0a05..d8e85383c 100644
--- a/test/vm.cpp
+++ b/test/vm.cpp
@@ -243,10 +243,11 @@ void FakeExtVM::importCallCreates(mArray& _callcreates)
 
 eth::OnOpFunc FakeExtVM::simpleTrace()
 {
-	return [](uint64_t steps, eth::Instruction inst, bigint newMemSize, bigint gasCost, void* voidVM, void const* voidExt)
+
+	return [](uint64_t steps, eth::Instruction inst, bigint newMemSize, bigint gasCost, dev::eth::VM* voidVM, dev::eth::ExtVMFace const* voidExt)
 	{
-		FakeExtVM const& ext = *(FakeExtVM const*)voidExt;
-		eth::VM& vm = *(eth::VM*)voidVM;
+		FakeExtVM const& ext = *static_cast<FakeExtVM const*>(voidExt);
+		eth::VM& vm = *voidVM;
 
 		std::ostringstream o;
 		o << std::endl << "    STACK" << std::endl;
diff --git a/test/vm.h b/test/vm.h
index a52a02e31..3d4b88d54 100644
--- a/test/vm.h
+++ b/test/vm.h
@@ -80,9 +80,6 @@ public:
 	bytes thisTxData;
 	bytes thisTxCode;
 	u256 gas;
-
-private:
-	eth::Manifest m_ms;
 };