interface INonfungiblePositionManager {

    /**
     * @notice The struct to mint a position
     * @member token0 The address of the token0 for a specific pool
     * @member token1 The address of the token1 for a specific pool
     * @member fee The fee associated with the pool
     * @member tickLower The lower end of the tick range for the position
     * @member tickUpper The higher end of the tick range for the position
     * @member amount0Desired The desired amount of token0 to be spent
     * @member amount1Desired The desired amount of token1 to be spent
     * @member amount0Min The minimum amount of token0 to spend, which serves as a slippage check
     * @member amount1Min The minimum amount of token1 to spend, which serves as a slippage check
     * @member recipient The account that should receive the tokens
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

    /**
     * @notice The struct to increase liquidity of a position
     * @member tokenId The ID of the token for which liquidity is being increased
     * @member amount0Desired The desired amount of token0 to be spent
     * @member amount1Desired The desired amount of token1 to be spent
     * @member amount0Min The minimum amount of token0 to spend, which serves as a slippage check
     * @member amount1Min The minimum amount of token1 to spend, which serves as a slippage check
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    /**
     * @notice The struct to decrease liquidity of a position
     * @member tokenId The ID of the token for which liquidity is being decreased
     * @member liquidity The amount by which liquidity will be decreased
     * @member amount0Min The minimum amount of token0 that should be accounted for the burned liquidity
     * @member amount1Min The minimum amount of token1 that should be accounted for the burned liquidity
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    /**
     * @notice The struct to decrease liquidity of a position
     * @member tokenId The ID of the NFT for which tokens are being collected
     * @member recipient The account that should receive the tokens
     * @member amount0Min The minimum amount of token0 that should be accounted for the burned liquidity
     * @member amount1Min The minimum amount of token1 that should be accounted for the burned liquidity
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    /// @notice Creates a new position wrapped in a NFT
    /// @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized
    /// a method does not exist, i.e. the pool is assumed to be initialized.
    /// @param params The params necessary to mint a position, encoded as `MintParams` in calldata
    /// @return tokenId The ID of the token that represents the minted position
    /// @return liquidity The amount of liquidity for this position
    /// @return amount0 The amount of token0
    /// @return amount1 The amount of token1
    function mint(MintParams calldata params)
        external
        payable
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    /// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`
    /// @param params The params necessary to increase liquidity of a position,
    /// encoded as `IncreaseLiquidityParams` in calldata
    /// @return liquidity The new liquidity amount as a result of the increase
    /// @return amount0 The amount of token0 to acheive resulting liquidity
    /// @return amount1 The amount of token1 to acheive resulting liquidity
    function increaseLiquidity(IncreaseLiquidityParams calldata params)
        external
        payable
        returns (
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    /// @notice Decreases the amount of liquidity in a position and accounts it to the position
    /// @param params The params necessary to decrease liquidity of a position
    /// @return amount0 The amount of token0 accounted to the position's tokens owed
    /// @return amount1 The amount of token1 accounted to the position's tokens owed
    function decreaseLiquidity(DecreaseLiquidityParams calldata params)
        external
        payable
        returns (uint256 amount0, uint256 amount1);

    /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
    /// @param params The params necessary to collect fee
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collect(CollectParams calldata params)
        external
        payable
        returns (uint256 amount0, uint256 amount1);

    /// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens
    /// must be collected first.
    /// @param tokenId The ID of the token that is being burned
    function burn(uint256 tokenId) external payable;

    /// @notice Returns the position information associated with a given token ID.
    /// @dev Throws if the token ID is not valid.
    /// @param tokenId The ID of the token that represents the position
    /// @return nonce The nonce for permits
    /// @return operator The address that is approved for spending
    /// @return token0 The address of the token0 for a specific pool
    /// @return token1 The address of the token1 for a specific pool
    /// @return fee The fee associated with the pool
    /// @return tickLower The lower end of the tick range for the position
    /// @return tickUpper The higher end of the tick range for the position
    /// @return liquidity The liquidity of the position
    /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
    /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
    /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
    /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
    function positions(uint256 tokenId)
        external
        view
        returns (
            uint96 nonce,
            address operator,
            address token0,
            address token1,
            uint24 fee,
            int24 tickLower,
            int24 tickUpper,
            uint128 liquidity,
            uint256 feeGrowthInside0LastX128,
            uint256 feeGrowthInside1LastX128,
            uint128 tokensOwed0,
            uint128 tokensOwed1
        );
}
/// Imported from Uniswap V3
function increaseLiquidity(IncreaseLiquidityParams calldata params)
    external
    payable
    returns (
        uint128 liquidity,
        uint256 amount0,
        uint256 amount1
    );

/// @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`
/// @param params The params necessary to increase liquidity of a position,
/// encoded as `IncreaseLiquidityParams` in calldata
/// @return liquidity The new liquidity amount as a result of the increase
/// @return amount0 The amount of token0 to acheive resulting liquidity
/// @return amount1 The amount of token1 to acheive resulting liquidity