contract TokenL is Pausable, BlockedToken {
    using SafeMath for uint256;

    string public constant name = "Imigize";
    string public constant symbol = "IMGZ";
    uint8 public constant decimals = 18;

    uint256 public totalSupply;

    mapping(address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    mapping (address => bool) public unpausedWallet;

    bool public mintingFinished = false;

    uint256 public totalMigrated;
    address public migrationAgent;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    event Mint(address indexed to, uint256 amount);
    event MintFinished();

    event Migrate(address indexed _from, address indexed _to, uint256 _value);

    modifier canMint() {
        require(!mintingFinished);
        _;
    }

    function TokenL() public{
        owner = 0x0;
    }

    function setOwner() public{
        require(owner == 0x0);
        owner = msg.sender;
    }

    // Balance of the specified address
    function balanceOf(address _owner) public constant returns (uint256 balance) {
        return balances[_owner];
    }


    // Transfer of tokens from one account to another
    function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
        uint256 available = balances[msg.sender].sub(valueBlocked(msg.sender));
        require(_value <= available);
        require (_value > 0);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

    // Returns the number of tokens that _owner trusted to spend from his account _spender
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }

    // Trust _sender and spend _value tokens from your account
    function approve(address _spender, uint256 _value) public returns (bool) {

        // To change the approve amount you first have to reduce the addresses
        //  allowance to zero by calling `approve(_spender, 0)` if it is not
        //  already 0 to mitigate the race condition described here:
        //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
        require((_value == 0) || (allowed[msg.sender][_spender] == 0));

        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    // Transfer of tokens from the trusted address _from to the address _to in the number _value
    function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {

        uint256 available = balances[_from].sub(valueBlocked(_from));
        require(_value <= available);

        var _allowance = allowed[_from][msg.sender];

        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // require (_value <= _allowance);

        require (_value > 0);

        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = _allowance.sub(_value);
        Transfer(_from, _to, _value);
        return true;
    }

    // Issue new tokens to the address _to in the amount _amount. Available to the owner of the contract (contract Crowdsale)
    function mint(address _to, uint256 _amount) public onlyOwner canMint returns (bool) {
        totalSupply = totalSupply.add(_amount);
        balances[_to] = balances[_to].add(_amount);
        Mint(_to, _amount);
        Transfer(0x0, _to, _amount);
        return true;
    }

    // Stop the release of tokens. This is not possible to cancel. Available to the owner of the contract.
    function finishMinting() public onlyOwner returns (bool) {
    	mintingFinished = true;
        MintFinished();
        return true;
    }

    // Redefinition of the method of the returning status of the "Exchange pause".
    // Never for the owner of an unpaused wallet.
    function paused() public constant returns(bool) {
        return super.paused() && !unpausedWallet[msg.sender];
    }

    // Add a wallet ignoring the "Exchange pause". Available to the owner of the contract.
    function addUnpausedWallet(address _wallet) public onlyOwner {
        unpausedWallet[_wallet] = true;
    }

    // Remove the wallet ignoring the "Exchange pause". Available to the owner of the contract.
    function delUnpausedWallet(address _wallet) public onlyOwner {
        unpausedWallet[_wallet] = false;
    }

    // Enable the transfer of current tokens to others. Only 1 time. Disabling this is not possible.
    // Available to the owner of the contract.
    function setMigrationAgent(address _migrationAgent) public onlyOwner {
        require(migrationAgent == 0x0);
        migrationAgent = _migrationAgent;
    }

    function migrateAll(address[] _holders) public onlyOwner {
        require(migrationAgent != 0x0);
        uint256 total = 0;
        uint256 value;
        for(uint i = 0; i < _holders.length; i++){
            value = balances[_holders[i]];
            if(value > 0){
                balances[_holders[i]] = 0;
                total = total.add(value);
                MigrationAgent(migrationAgent).migrateFrom(_holders[i], value);
                Migrate(_holders[i],migrationAgent,value);
            }
            totalSupply = totalSupply.sub(total);
            totalMigrated = totalMigrated.add(total);
        }
    }

    function migration(address _holder) internal {
        require(migrationAgent != 0x0);
        uint256 value = balances[_holder];
        require(value > 0);
        balances[_holder] = 0;
        totalSupply = totalSupply.sub(value);
        totalMigrated = totalMigrated.add(value);
        MigrationAgent(migrationAgent).migrateFrom(_holder, value);
        Migrate(_holder,migrationAgent,value);

    }

    // Reissue your tokens.
    function migrate() public
    {
        migration(msg.sender);
    }
}
// (A2)
// Contract token
function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {

        uint256 available = balances[_from].sub(valueBlocked(_from));
        require(_value <= available);

        var _allowance = allowed[_from][msg.sender];

        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // require (_value <= _allowance);

        require (_value > 0);

        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = _allowance.sub(_value);
        Transfer(_from, _to, _value);
        return true;
    }
// Transfer of tokens from the trusted address _from to the address _to in the number _value