contract Superuser is Ownable, RBAC {
  string public constant ROLE_SUPERUSER = "superuser";

  constructor () public {
    addRole(msg.sender, ROLE_SUPERUSER);
  }

  /**
   * @dev Throws if called by any account that's not a superuser.
   */
  modifier onlySuperuser() {
    checkRole(msg.sender, ROLE_SUPERUSER);
    _;
  }

  modifier onlyOwnerOrSuperuser() {
    require(msg.sender == owner || isSuperuser(msg.sender));
    _;
  }

  /**
   * @dev getter to determine if address has superuser role
   */
  function isSuperuser(address _addr)
    public
    view
    returns (bool)
  {
    return hasRole(_addr, ROLE_SUPERUSER);
  }

  /**
   * @dev Allows the current superuser to transfer his role to a newSuperuser.
   * @param _newSuperuser The address to transfer ownership to.
   */
  function transferSuperuser(address _newSuperuser) public onlySuperuser {
    require(_newSuperuser != address(0));
    removeRole(msg.sender, ROLE_SUPERUSER);
    addRole(_newSuperuser, ROLE_SUPERUSER);
  }

  /**
   * @dev Allows the current superuser or owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwnerOrSuperuser {
    _transferOwnership(_newOwner);
  }
}
/**
 * @title Superuser
 * @dev The Superuser contract defines a single superuser who can transfer the ownership 
 * of a contract to a new address, even if he is not the owner. 
 * A superuser can transfer his role to a new address. 
 */
function transferSuperuser(address _newSuperuser) public onlySuperuser {
  require(_newSuperuser != address(0));
  removeRole(msg.sender, ROLE_SUPERUSER);
  addRole(_newSuperuser, ROLE_SUPERUSER);
}

/**
 * @dev Allows the current superuser to transfer his role to a newSuperuser.
 * @param _newSuperuser The address to transfer ownership to.
 */