bool Why3Translator::visit(ContractDefinition const& _contract)
{
	if (m_seenContract)
		error(_contract, "More than one contract not supported.");
	m_seenContract = true;
	m_currentContract.contract = &_contract;
	if (_contract.isLibrary())
		error(_contract, "Libraries not supported.");

	addLine("module Contract_" + _contract.name());
	indent();
	addLine("use import int.Int");
	addLine("use import ref.Ref");
	addLine("use import map.Map");
	addLine("use import array.Array");
	addLine("use import int.ComputerDivision");
	addLine("use import mach.int.Unsigned");
	addLine("use import UInt256");
	addLine("exception Revert");
	addLine("exception Return");

	if (_contract.stateVariables().empty())
		addLine("type state = ()");
	else
	{
		addLine("type state = {");
		indent();
		m_currentContract.stateVariables = _contract.stateVariables();
		for (VariableDeclaration const* variable: m_currentContract.stateVariables)
		{
			string varType;
			try
			{
				varType = toFormalType(*variable->annotation().type);
			}
			catch (NoFormalType &err)
			{
				string const* typeNamePtr = boost::get_error_info<errinfo_noFormalTypeFrom>(err);
				string typeName = typeNamePtr ? " \"" + *typeNamePtr + "\"" : "";
				fatalError(*variable, "Type" + typeName + " not supported for state variable.");
			}
			addLine("mutable _" + variable->name() + ": " + varType);
		}
		unindent();
		addLine("}");
	}

	addLine("type account = {");
	indent();
	addLine("mutable balance: uint256;");
	addLine("storage: state");
	unindent();
	addLine("}");

	addLine("val external_call (this: account): bool");
	indent();
	addLine("ensures { result = false -> this = (old this) }");
	addLine("writes { this }");
	addSourceFromDocStrings(m_currentContract.contract->annotation());
	unindent();

	if (!_contract.baseContracts().empty())
		error(*_contract.baseContracts().front(), "Inheritance not supported.");
	if (!_contract.definedStructs().empty())
		error(*_contract.definedStructs().front(), "User-defined types not supported.");
	if (!_contract.definedEnums().empty())
		error(*_contract.definedEnums().front(), "User-defined types not supported.");
	if (!_contract.events().empty())
		error(*_contract.events().front(), "Events not supported.");
	if (!_contract.functionModifiers().empty())
		error(*_contract.functionModifiers().front(), "Modifiers not supported.");

	ASTNode::listAccept(_contract.definedFunctions(), *this);

	return false;
}
bool ASTPrinter::visit(ContractDefinition const& _node)
{
	writeLine("ContractDefinition \"" + _node.name() + "\"");
	printSourcePart(_node);
	return goDeeper();
}