contract AdminManager {
    event ChangeOwner(address _oldOwner, address _newOwner);
    event SetAdmin(address _address, bool _isAdmin);
    //constract's owner
    address public owner;
    //constract's admins. permission less than owner
    mapping(address=>bool) public admins;

    /**
     * constructor
     */
    constructor() public {
        owner = msg.sender;
    }

    /**
     * modifier for some action only owner can do
     */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    /**
     * modifier for some action only admin or owner can do
     */
    modifier onlyAdmins() {
        require(msg.sender == owner || admins[msg.sender]);
        _;
    }

    /**
     * change this constract's owner
     */
    function changeOwner(address _newOwner) public onlyOwner {
        require(_newOwner != address(0));
        emit ChangeOwner(owner, _newOwner);
        owner = _newOwner;
    }

    /**
     * add or delete admin
     */
    function setAdmin(address _address, bool _isAdmin) public onlyOwner {
        emit SetAdmin(_address, _isAdmin);
        if(!_isAdmin){
            delete admins[_address];
        }else{
            admins[_address] = true;
        }
    }
}
/**
 * admin manager
 */
function changeOwner(address _newOwner) public onlyOwner {
        require(_newOwner != address(0));
        emit ChangeOwner(owner, _newOwner);
        owner = _newOwner;
    }
/**
 * change this constract's owner
 */