contract DVXToken is Pausable, StandardToken, BlackList {
    string public name = "Derivex";
    string public symbol = "DVX";
    uint8 public decimals = 18;
    uint256 public init_Supply = 1000000000 * 10 ** 18;
    address public upgradedAddress;
    bool public deprecated;

    constructor() public {
        totalSupply_ = init_Supply;
        balances[msg.sender] = totalSupply_;
        deprecated = false;
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
        require(!isBlackListed[msg.sender]);
        require(!isBlackListed[_to]);
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value);
        } else {
            return super.transfer(_to, _value);
        }
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
        require(!isBlackListed[msg.sender]);
        require(!isBlackListed[_from]);
        require(!isBlackListed[_to]);
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value);
        } else {
            return super.transferFrom(_from, _to, _value);
        }
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function approve(address _spender, uint256 _value) public returns (bool) {
        require(!isBlackListed[msg.sender]);
        require(!isBlackListed[_spender]);
        if (deprecated) {
            return UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value);
        } else {
            return super.approve(_spender, _value);
        }
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function allowance(address _owner, address _spender) public view  returns (uint256) {
        if (deprecated) {
            return StandardToken(upgradedAddress).allowance(_owner, _spender);
        } else {
            return super.allowance(_owner, _spender);
        }
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function increaseApproval(address _spender, uint256 _addedValue) public returns (bool) {
        if (deprecated) {
            return StandardToken(upgradedAddress).increaseApproval(_spender, _addedValue);
        } else {
            return super.increaseApproval(_spender, _addedValue);
        }
    }
    
    // Forward ERC20 methods to upgraded contract if this one is deprecated
    function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool) {
        if (deprecated) {
            return StandardToken(upgradedAddress).increaseApproval(_spender, _subtractedValue);
        } else {
            return super.decreaseApproval(_spender, _subtractedValue);
        }
    }
    
    // deprecate current contract in favour of a new one
    function deprecate(address _upgradedAddress) public onlyOwner {
        deprecated = true;
        upgradedAddress = _upgradedAddress;
        emit Deprecate(_upgradedAddress);
    }
    
    // Called when contract is deprecated
    event Deprecate(address newAddress);
}
function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool) {
        if (deprecated) {
            return StandardToken(upgradedAddress).increaseApproval(_spender, _subtractedValue);
        } else {
            return super.decreaseApproval(_spender, _subtractedValue);
        }
    }
// Forward ERC20 methods to upgraded contract if this one is deprecated