function _redeemTokens(TDS.Storage storage s, uint tokensToRedeem) external {
        require(s.state == TDS.State.Live || s.state == TDS.State.Settled);
        require(tokensToRedeem > 0);

        if (s.state == TDS.State.Live) {
            require(msg.sender == s.externalAddresses.sponsor || msg.sender == s.externalAddresses.apDelegate);
            s._remarginInternal();
            require(s.state == TDS.State.Live);
        }

        ExpandedIERC20 thisErc20Token = ExpandedIERC20(address(this));

        uint initialSupply = _totalSupply();
        require(initialSupply > 0);

        _pullAuthorizedTokens(thisErc20Token, tokensToRedeem);
        thisErc20Token.burn(tokensToRedeem);
        emit TokensRedeemed(s.fixedParameters.symbol, tokensToRedeem);

        
        
        uint tokenPercentage = tokensToRedeem.mul(UINT_FP_SCALING_FACTOR).div(initialSupply);
        uint tokenMargin = _takePercentage(_safeUintCast(s.longBalance), tokenPercentage);

        s.longBalance = s.longBalance.sub(_safeIntCast(tokenMargin));
        assert(s.longBalance >= 0);
        s.nav = _computeNavForTokens(s.currentTokenState.tokenPrice, _totalSupply());

        s._sendMargin(tokenMargin);
    }