contract TokenProxy is StandardToken, BurnableToken {

    ERC20Basic public TOKEN;

    mapping(address => address) private gates;


    event GateOpened(address indexed gate, address indexed user);

    event Mint(address indexed to, uint256 amount);

    function TokenProxy(ERC20Basic _token) public {
        TOKEN = _token;
    }

    function getGateAddress(address _user) external view returns (address) {
        return gates[_user];
    }

    /// Create a new migration Gate for the User.
    function openGate() external {
        address user = msg.sender;

        // Do not allow creating more than one Gate per User.
        require(gates[user] == 0);

        // Create new Gate.
        address gate = new Gate(TOKEN, this);

        // Remember User - Gate relationship.
        gates[user] = gate;

        emit GateOpened(gate, user);
    }

    function transferFromGate() external {
        address user = msg.sender;

        address gate = gates[user];

        // Make sure the User's Gate exists.
        require(gate != 0);

        uint256 value = TOKEN.balanceOf(gate);

        Gate(gate).transferToProxy(value);

        // Handle the information about the amount of migrated tokens.
        // This is a trusted information becase it comes from the Gate.
        totalSupply_ += value;
        balances[user] += value;

        emit Mint(user, value);
    }

    function withdraw(uint256 _value) external {
        withdrawTo(_value, msg.sender);
    }

    function withdrawTo(uint256 _value, address _destination) public {
        require(_value > 0 && _destination != address(0));
        burn(_value);
        TOKEN.transfer(_destination, _value);
    }
}
function openGate() external {
    address user = msg.sender;

    // Do not allow creating more than one Gate per User.
    require(gates[user] == 0);

    // Create new Gate.
    address gate = new Gate(TOKEN, this);

    // Remember User - Gate relationship.
    gates[user] = gate;

    emit GateOpened(gate, user);
}

/// Create a new migration Gate for the User.