contract TokenFactory {
    using AddressUtil for address;
    using StringUtil for string;
    mapping(bytes10 => address) public tokens;
    address   public tokenRegistry;
    event TokenCreated(
        address indexed addr,
        string  name,
        string  symbol,
        uint8   decimals,
        uint    totalSupply,
        address firstHolder
    );
    /// @dev Disable default function.
    function () payable public
    {
        revert();
    }
    /// @dev Initialize TokenRegistry address.
    ///      This method shall be called immediately upon deployment.
    function initialize(address _tokenRegistry)
        public
    {
        require(tokenRegistry == 0x0 && _tokenRegistry.isContract());
        tokenRegistry = _tokenRegistry;
    }
    /// @dev Deploy an ERC20 token contract, register it with TokenRegistry,
    ///      and returns the new token's address.
    /// @param name The name of the token
    /// @param symbol The symbol of the token.
    /// @param decimals The decimals of the token.
    /// @param totalSupply The total supply of the token.
    function createToken(
        string  name,
        string  symbol,
        uint8   decimals,
        uint    totalSupply
        )
        public
        returns (address addr)
    {
        require(tokenRegistry != 0x0);
        require(symbol.checkStringLength(3, 10));
        bytes10 symbolBytes = symbol.stringToBytes10();
        require(tokens[symbolBytes] == 0x0);
        ERC20Token token = new ERC20Token(
            name,
            symbol,
            decimals,
            totalSupply,
            tx.origin
        );
        addr = address(token);
        TokenRegistry(tokenRegistry).registerMintedToken(addr, symbol);
        tokens[symbolBytes] = addr;
        emit TokenCreated(
            addr,
            name,
            symbol,
            decimals,
            totalSupply,
            tx.origin
        );
    }
}
/// @title ERC20 Token Mint
/// @dev This contract deploys ERC20 token contract and registered the contract
///      so the token can be traded with Loopring Protocol.
/// @author Kongliang Zhong - <kongliang@loopring.org>,
/// @author Daniel Wang - <daniel@loopring.org>.
function () payable public
{
    revert();
}

/// @dev Disable default function.