contract MinterRole {
    
    using Roles for Roles.Role;

    Roles.Role private _minters;

    /**
     * @notice Fired when a new role is added.
     */
    event MinterAdded(address indexed account);

    /**
     * @notice Fired when a new role is added.
     */
    event MinterRemoved(address indexed account);

    /**
     * @dev The role is granted to the deployer.
     */
    constructor () internal {
        _addMinter(msg.sender);
    }

    /**
     * @dev Callers must have the role.
     */
    modifier onlyMinter() {
        require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role");
        _;
    }

    /**
     * @dev The role is removed for the caller.    
     */
    function renounceMinter() public {
        _removeMinter(msg.sender);
    }

    /**
     * @dev Checks if @param account has the role.
     */
    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    /**
     * @dev Assigns the role to @param account.
     */
    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    /**
     * @dev Removes the role from @param account.
     */
    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }

}
/**
 * @title Minter Role
 * @dev Follows the openzeppelin's guidelines of working with roles.
 * @dev Derived contracts must implement the `addMinter` and the `removeMinter` functions.
 */
function _removeMinter(address account) internal {
    _minters.remove(account);
    emit MinterRemoved(account);
}

/**
 * @dev Removes the role from @param account.
 */