contract UAXCoinAccounts is UAXCoinOwnable {
    using SafeMath for uint256;

    mapping(address => uint256) private _nonces;
    mapping (address => uint256) private _balances;
    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    UAXCoinController private _ctrl;

    mapping (address => bool) private _whitelist;
    mapping (address => bool) private _frozen;

    /**
     * @dev Indicates that some accounts may be frozen
     */
    bool private _hasFrozenAccounts;

    /**
     * @dev Number of frozen accounts
     */
    uint16 private _frozenCount;

    /**
     * @dev Initial values
     */
    constructor() public {
    }

    /**
     * @dev Modifier for methods that should be called only from the controller contract
     */
    modifier onlyController {
        require(msg.sender == address(_ctrl), "Ownable: not a controller");
        _;
    }

    /**
     * @dev Move tokens from one address to another
     */
    function transfer(address from, address to, uint256 value ) external onlyController {
        _balances[from] = _balances[from].sub(value);
        _balances[to] = _balances[to].add(value);
    }

    /**
     * @dev Move tokens from one address to two other addresses (e.g. send with fee collection)
     */
    function transferToTwo(address from, address to1, address to2, uint256 value1, uint256 value2) external onlyController {
        uint256 value = value1.add(value2);
        _balances[from] = _balances[from].sub(value);
        _balances[to1] = _balances[to1].add(value1);
        _balances[to2] = _balances[to2].add(value2);
    }

    /**
     * @dev Add a value to balance and totalSupply
     */
    function addBalanceAndTotalSupply(address owner, uint256 value) external onlyController {
        _balances[owner] = _balances[owner].add(value);
        _totalSupply = _totalSupply.add(value);
    }

    /**
     * @dev Add a value to balance and totalSupply
     */
    function subBalanceAndTotalSupply(address owner, uint256 value) external onlyController {
        _balances[owner] = _balances[owner].sub(value);
        _totalSupply = _totalSupply.sub(value);
    }

    /**
     * @dev Set allowance value
     */
    function setAllowance(address owner, address spender, uint256 allowance) external onlyController {
        _allowances[owner][spender] = allowance;
    }

    /**
     * @dev Sets account as whitelisted one
     */
    function addToWhitelist(address account) external onlyController {
        _whitelist[account] = true;
    }

    /**
     * @dev Sets account as not-whitelisted one
     */
    function removeFromWhiteList(address account) external onlyController {
        _whitelist[account] = false;
    }

    function nonce(address account) external onlyController view returns (uint256) {
        return _nonces[account];
    }

    function setNonce(address account, uint256 _nonce) external onlyController {
        _nonces[account] = _nonce;
    }
    /**
     * @dev Returns true for frozen accounts
     */
    function isFrozen(address account) external view onlyController returns(bool) {
        return _frozen[account];
    }

    /**
     * @dev Returns true if any of given accounts are frozen
     */
    function anyFrozen(address account1, address account2) external view onlyController returns(bool) {
        return _frozen[account1] || _frozen[account2];
    }

    /**
     * @dev Sets new controller contract address
     */
    function setController(UAXCoinController ctrl) public onlyOwner {
        _ctrl = ctrl;
    }

    /**
     * @dev See `IERC20.totalSupply`.
     */
    function totalSupply() public view onlyController returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See `IERC20.balanceOf`.
     */
    function balanceOf(address account) public view onlyController returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See `IERC20.allowance`.
     */
    function allowance(address owner, address spender) public view onlyController returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev Returns true for whitelisted accounts
     */
    function isWhitelisted(address account) public view onlyController returns(bool) {
        return _whitelist[account];
    }

    /**
     * @dev Returns true for whitelisted accounts
     */
    function bothWhitelisted(address account1, address account2) public view onlyController returns(bool) {
        return _whitelist[account1] && _whitelist[account2];
    }

    /**
     * @dev Sets account as frozen one
     */
    function freeze(address account) public onlyController {
        if (!_frozen[account]) {
            _frozenCount++;
            _frozen[account] = true;
            _hasFrozenAccounts = true;
        }
    }

    /**
     * @dev Sets account as unfrozen one
     */
    function unfreeze(address account) public onlyController {
        if (_frozen[account]) {
            _frozenCount--;
            _frozen[account] = false;
            _hasFrozenAccounts = (_frozenCount > 0);
        }
    }

    /**
     * @dev Returns true if there were frozen accounts
     */
    function hasFrozen() public view returns(bool) {
        return _hasFrozenAccounts;
    }
}
/**
 * @dev Token accounts contract.
 */
function anyFrozen(address account1, address account2) external view onlyController returns(bool) {
    return _frozen[account1] || _frozen[account2];
}

/**
 * @dev Returns true if any of given accounts are frozen
 */