contract UpgradableToken is PlatformToken {

    // The next contract where the tokens will be migrated
    UpgradeAgent public upgradeAgent;
    uint256 public totalSupplyUpgraded;
    bool public upgrading = false;

    event UpgradeBalance(address who, uint256 amount);
    event UpgradeAllowance(address owner, address spender, uint256 amount);
    event UpgradePendingExchange(address owner, uint256 value);
    event UpgradeStateChange(bool state);


    /**
     * @dev Modifier to make a function callable only when the contract is upgrading
     */
    modifier whenUpgrading() {
        require(upgrading);
        _;
    }

    /**
     * @dev Function that allows the `owner` to set the upgrade agent
     */
    function setUpgradeAgent(address addr) onlyOwner public {
        upgradeAgent = UpgradeAgent(addr);
    }

    /**
     * @dev called by the owner when token is paused, triggers upgrading state
     */
    function startUpgrading() onlyOwner whenPaused public {
        upgrading = true;
        UpgradeStateChange(true);
    }

    /**
     * @dev called by the owner then token is paused and upgrading, returns to a non-upgrading state
     */
    function stopUpgrading() onlyOwner whenPaused whenUpgrading public {
        upgrading = false;
        UpgradeStateChange(false);
    }

    /**
     * @dev Allows anybody to upgrade tokens from these contract to the new one
     */
    function upgradeBalanceOf(address who) whenUpgrading public {
        uint256 value = balances[who];
        require (value != 0);
        balances[who] = 0;
        totalSupply = totalSupply.sub(value);
        totalSupplyUpgraded = totalSupplyUpgraded.add(value);
        upgradeAgent.upgradeBalance(who, value);
        UpgradeBalance(who, value);
    }

    /**
     * @dev Allows anybody to upgrade allowances from these contract to the new one
     */
    function upgradeAllowance(address _owner, address _spender) whenUpgrading public {
        uint256 value = allowed[_owner][_spender];
        require (value != 0);
        allowed[_owner][_spender] = 0;
        upgradeAgent.upgradeAllowance(_owner, _spender, value);
        UpgradeAllowance(_owner, _spender, value);
    }

}
/**
 * @title UpgradableToken
 * @dev Allows users to transfers their tokens to a new contract when the token is paused and upgrading 
 * It is like a guard for unexpected situations 
 */
function setUpgradeAgent(address addr) onlyOwner public {
    upgradeAgent = UpgradeAgent(addr);
}

/**
 * @dev Function that allows the `owner` to set the upgrade agent
 */