contract BurnableFreezableMintableToken is FreezableMintableToken {
    mapping (address => bool) private blocklistedAccounts;

    event Burn(address indexed owner, uint256 value);

    event AccountBlocked(address user);
    event AccountUnblocked(address user);
    event BlockedFundsDestroyed(address blockedListedUser, uint destroyedAmount);

    function transfer(address _to, uint256 _value) public override returns (bool) {
        require(!blocklistedAccounts[msg.sender], "account is blocklisted");
        super.transfer(_to, _value);
    }

    function transferFrom(address _from, address _to, uint256 _value) public override returns (bool) {
        require(!blocklistedAccounts[_from], "account is blocklisted");
        super.transferFrom(_from, _to, _value);
    }
    
    function isBlocklisted(address _maker) public view returns (bool) {
        return blocklistedAccounts[_maker];
    } 
    
    function blockAccount(address _evilUser) public onlyOwner returns (bool) {
        require(_evilUser != address(0), "address to block must not be zero address");
        blocklistedAccounts[_evilUser] = true;
        emit AccountBlocked(_evilUser);
        return true;
    }

    function unblockAccount(address _clearedUser) public onlyOwner returns (bool) {
        blocklistedAccounts[_clearedUser] = false;
        emit AccountUnblocked(_clearedUser);
        return true;
    }

    function destroyBlockedFunds(address _blockListedUser) public onlyOwner returns (bool) {
        require(blocklistedAccounts[_blockListedUser], "account must be blocklisted");
        uint dirtyFunds = balanceOf(_blockListedUser);
        _burn(_blockListedUser, dirtyFunds);
        emit BlockedFundsDestroyed(_blockListedUser, dirtyFunds);
        return true;
    }

  /**
   * @dev Burns a specific amount of tokens.
   * @param _value The amount of token to be burned.
   */
    function burn(address _owner, uint256 _value) public onlyOwner {
        _burn(_owner, _value);
    }
  
    function _burn(address _who, uint256 _value) internal {
        require(_who != address(0));
        require(_value <= balances[_who]);
        balances[_who] = balances[_who].sub(_value);
        totalSupply_ = totalSupply_.sub(_value);
        emit Burn(_who, _value);
        emit Transfer(_who, address(0), _value);
    }
}
/**
 * @title BurnableFreezableMintableToken Token
 * @dev Token that can be irreversibly burned (destroyed).
 */
function burn(address _owner, uint256 _value) public onlyOwner {
    _burn(_owner, _value);
}

/**
 * @dev Burns a specific amount of tokens.
 * @param _value The amount of token to be burned.
 */