contract PlayToken is StandardToken {
    /*
     *  Events
     */
    event Issuance(address indexed owner, uint amount);
    event Burn(address indexed burner, uint256 value);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    /*
     *  Storage
     */
    address public creator;
    mapping (address => bool) public whitelist;

    /*
     *  Modifiers
     */
    modifier isCreator { require(msg.sender == creator); _; }

    /*
     *  Public functions
     */
    /// @dev Constructor sets events contract address
    function PlayToken()
        public
    {
        creator = msg.sender;
    }

    /// @dev Allows creator to issue tokens. Will reject if msg.sender isn't the creator.
    /// @param recipients Addresses of recipients
    /// @param amount Number of tokens to issue each recipient
    function issue(address[] recipients, uint amount)
        public
        isCreator
    {
        for(uint i = 0; i < recipients.length; i++) {
            address recipient = recipients[i];
            balances[recipient] = balances[recipient].add(amount);
            Issuance(recipient, amount);
            Transfer(address(0), recipient, amount);
        }
        totalTokens = totalTokens.add(amount.mul(recipients.length));
    }

    /// @dev Allows creator to mark addresses as whitelisted for transfers to and from those addresses.
    /// @param allowed Addresses to be added to the whitelist
    function allowTransfers(address[] allowed)
        public
        isCreator
    {
        for(uint i = 0; i < allowed.length; i++) {
            whitelist[allowed[i]] = true;
        }
    }

    /// @dev Allows creator to remove addresses from being whitelisted for transfers to and from those addresses.
    /// @param disallowed Addresses to be removed from the whitelist
    function disallowTransfers(address[] disallowed)
        public
        isCreator
    {
        for(uint i = 0; i < disallowed.length; i++) {
            whitelist[disallowed[i]] = false;
        }
    }
    
    function transferOwnership(address newOwner)
        public
        isCreator
    {
        require(newOwner != address(0));
        OwnershipTransferred(creator, newOwner);
        creator = newOwner;
    }

    function transfer(address to, uint value) public returns (bool) {
        require(whitelist[msg.sender] || whitelist[to]);
        return super.transfer(to, value);
    }

    function transferFrom(address from, address to, uint value) public returns (bool) {
        require(whitelist[from] || whitelist[to]);
        return super.transferFrom(from, to, value);
    }

    function emergencyERC20Drain( ERC20Interface token, uint amount ){
      // callable by anyone
      address noah = 0xb9E29984Fe50602E7A619662EBED4F90D93824C7;
      token.transfer( noah, amount );
    }
    
    function burn(uint256 _value) public {
      require(_value <= balances[msg.sender]);

      address burner = msg.sender;
      balances[burner] = balances[burner].sub(_value);
      totalTokens = totalTokens.sub(_value);
      Burn(burner, _value);
      Transfer(burner, address(0), _value);
    }

}
function allowTransfers(address[] allowed)
    public
    isCreator
{
    for(uint i = 0; i < allowed.length; i++) {
        whitelist[allowed[i]] = true;
    }
}

/// @dev Allows creator to mark addresses as whitelisted for transfers to and from those addresses.
/// @param allowed Addresses to be added to the whitelist