contract Ownable {
	event OwnershipTransferStarted(address indexed owner, address indexed pendingOwner);
	event OwnershipTransferCancelled(address indexed owner, address indexed pendingOwner);
	event OwnershipTransferFinished(address indexed oldOwner, address indexed newOwner);

	address public owner;
	address public pendingOwner;

	constructor(address _owner) public {
		require(_owner != address(0), "Contract must have an owner.");
		owner = _owner;
	}

	/// @notice a function modifier that ensures the modified function can only be called by the owner of the contract.
	modifier onlyOwner() {
		require(msg.sender == owner, "Only the owner may call this method.");
		_;
	}

	/// @notice starts the transfer of ownership to a new owner.
	/// @param _pendingOwner the address to which ownership should be transferred.
	function startOwnershipTransfer(address _pendingOwner) external onlyOwner {
		require(_pendingOwner != address(0), "Contract must have an owner.");
		// we want to ensure that we get a cancelled or finished event for every ownership transfer, so if a transfer is in progres we first cancel it
		if (pendingOwner != address(0)) {
			cancelOwnershipTransfer();
		}
		pendingOwner = _pendingOwner;
		emit OwnershipTransferStarted(owner, pendingOwner);
	}

	/// @notice cancel an in progress ownership transfer.
	/// @dev cancellation should not be depended on to cancel a transfer to a malicious address.  it's intended purpose is only to cancel transfer to an address that is unable or unwilling to accept the transfer
	function cancelOwnershipTransfer() public onlyOwner {
		require(pendingOwner != address(0), "There is no pending transfer to be cancelled.");
		address _pendingOwner = pendingOwner;
		pendingOwner = address(0);
		emit OwnershipTransferCancelled(owner, _pendingOwner);
	}

	/// @notice called by the pending owner as part of the two-step ownership transfer process to accept ownership of the contract.
	function acceptOwnership() external {
		require(msg.sender == pendingOwner, "Only the pending owner can call this method.");
		address _oldOwner = owner;
		owner = pendingOwner;
		pendingOwner = address(0);
		emit OwnershipTransferFinished(_oldOwner, owner);
	}
}
/// @notice An Ownable contract is one that has a single address that has elevated control over the contract's operations.  Ownership can be transferred between users as a two-step process, one to initiate the transfer and two to receive the transfer.  This two-step process ensures that ownership cannot accidentally be given to an address that cannot operate the contract.
function startOwnershipTransfer(address _pendingOwner) external onlyOwner {
		require(_pendingOwner != address(0), "Contract must have an owner.");
		// we want to ensure that we get a cancelled or finished event for every ownership transfer, so if a transfer is in progres we first cancel it
		if (pendingOwner != address(0)) {
			cancelOwnershipTransfer();
		}
		pendingOwner = _pendingOwner;
		emit OwnershipTransferStarted(owner, pendingOwner);
	}
/// @notice starts the transfer of ownership to a new owner.
/// @param _pendingOwner the address to which ownership should be transferred.