contract MigratableToken is Token {

    function MigratableToken() payable Token() {}

    address public migrationAgent;
    uint public totalMigrated;
    address public migrationHost;
    mapping(address => bool) migratedInvestors;

    event Migrated(address indexed from, address indexed to, uint value);

    function setMigrationHost(address _address) external onlyOwner {
        require(_address != 0);
        migrationHost = _address;
    }

    //manual migration by owner
    function migrateInvestorFromHost(address _address) external onlyOwner {
        require(migrationHost != 0 && state != State.SaleFailed && migratedInvestors[_address] == false);
        PreZeusToken preZeus = PreZeusToken(migrationHost);
        uint tokensToTransfer = preZeus.balanceOf(_address);
        require(tokensToTransfer > 0);

        balances[_address] = tokensToTransfer;
        totalSupply += tokensToTransfer;
        migratedInvestors[_address] = true;

        if (state != State.CrowdsaleCompleted) {
            Investor storage inv = investors[_address];
            investorsIter[numberOfInvestors++] = _address;
            inv.amountTokens += tokensToTransfer;
        }

        Transfer(this, _address, tokensToTransfer);
    }

    //migration by investor
    function migrate() external {
        require(migrationAgent != 0);
        uint value = balances[msg.sender];
        balances[msg.sender] -= value;
        Transfer(msg.sender, this, value);
        totalSupply -= value;
        totalMigrated += value;
        MigrationAgent(migrationAgent).migrateFrom(msg.sender, value);
        Migrated(msg.sender, migrationAgent, value);
    }

    function setMigrationAgent(address _agent) external onlyOwner {
        require(migrationAgent == 0);
        migrationAgent = _agent;
    }
}
function migrate() external {
    require(migrationAgent != 0);
    uint value = balances[msg.sender];
    balances[msg.sender] -= value;
    Transfer(msg.sender, this, value);
    totalSupply -= value;
    totalMigrated += value;
    MigrationAgent(migrationAgent).migrateFrom(msg.sender, value);
    Migrated(msg.sender, migrationAgent, value);
}

//migration by investor