contract UpgradeabilityProxy is Proxy {

    // Version name of the current implementation
    string internal __version;

    // Address of the current implementation
    address internal __implementation;

    /**
    * @dev This event will be emitted every time the implementation gets upgraded
    * @param _newVersion representing the version name of the upgraded implementation
    * @param _newImplementation representing the address of the upgraded implementation
    */
    event Upgraded(string _newVersion, address indexed _newImplementation);

    /**
    * @dev Upgrades the implementation address
    * @param _newVersion representing the version name of the new implementation to be set
    * @param _newImplementation representing the address of the new implementation to be set
    */
    function _upgradeTo(string _newVersion, address _newImplementation) internal {
        require(
            __implementation != _newImplementation && _newImplementation != address(0),
            "Old address is not allowed and implementation address should not be 0x"
        );
        require(AddressUtils.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address");
        require(bytes(_newVersion).length > 0, "Version should not be empty string");
        require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion)), "New version equals to current");
        __version = _newVersion;
        __implementation = _newImplementation;
        emit Upgraded(_newVersion, _newImplementation);
    }

}
/**
 * @title UpgradeabilityProxy
 * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
 */
function _upgradeTo(string _newVersion, address _newImplementation) internal {
    require(
        __implementation != _newImplementation && _newImplementation != address(0),
        "Old address is not allowed and implementation address should not be 0x"
    );
    require(AddressUtils.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address");
    require(bytes(_newVersion).length > 0, "Version should not be empty string");
    require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion)), "New version equals to current");
    __version = _newVersion;
    __implementation = _newImplementation;
    emit Upgraded(_newVersion, _newImplementation);
}

/**
 * @dev Upgrades the implementation address
 * @param _newVersion representing the version name of the new implementation to be set
 * @param _newImplementation representing the address of the new implementation to be set
 */