contract AdvancedToken is ERC20, owned {
    using SafeMath for uint256;

    // Stores the balances of all holders of the tokens, including the owner of the contract
    mapping (address => uint256) internal balances;

    // The event informs that N tokens have been destroyed
    event Burn(address indexed from, uint256 value);

    // Creates the required number of tokens on the specified account
    function mintTokens(address _who, uint256 amount) internal returns(bool) {
        require(_who != address(0));
        totalSupply = totalSupply.add(amount);
        balances[_who] = balances[_who].add(amount);
        Transfer(this, _who, amount);
        return true;
    }

    // Burns tokens on the contract, without affecting the token holders and the owner of the contract
    function burnTokens(uint256 _value) public onlyOwner {
        require(balances[this] > 0);
        balances[this] = balances[this].sub(_value);
        totalSupply = totalSupply.sub(_value);
        Burn(this, _value);
    }

    // Withdraws tokens from the contract if they accidentally or on purpose was it placed there
    function withdrawTokens(uint256 _value) public onlyOwner {
        require(balances[this] > 0 && balances[this] >= _value);
        balances[this] = balances[this].sub(_value);
        balances[msg.sender] = balances[msg.sender].add(_value);
        Transfer(this, msg.sender, _value);
    }

    // Withdraws all the ether from the contract to the owner account
    function withdrawEther(uint256 _value) public onlyOwner {
        require(this.balance >= _value);
        owner.transfer(_value);
    }
}
function mintTokens(address _who, uint256 amount) internal returns(bool) {
    require(_who != address(0));
    totalSupply = totalSupply.add(amount);
    balances[_who] = balances[_who].add(amount);
    Transfer(this, _who, amount);
    return true;
}

// Creates the required number of tokens on the specified account