contract AssetAdapterWithFees is Ownable, AssetAdapter {

    uint16 public feeThousandthsPercent;
    uint256 public minFeeAmount;

    constructor(uint16 _feeThousandthsPercent, uint256 _minFeeAmount) public {
        require(_feeThousandthsPercent < (1 << 16), "fee % too high");
        require(_minFeeAmount <= (1 << 255), "minFeeAmount too high");
        feeThousandthsPercent = _feeThousandthsPercent;
        minFeeAmount = _minFeeAmount;
    }

    function rawAccumulateFee(bytes memory assetData, uint256 _amount) internal;

    function accumulateFee(bytes memory assetData) internal {
        rawAccumulateFee(assetData, getFee(getAmount(assetData)));
    }

    function withdrawFees(
        bytes calldata assetData,
        address payable _to
    ) external /*onlyOwner*/ returns (bool success);  // solium-disable-line indentation

    function getFee(uint256 _amount) internal view returns (uint256) {
        uint256 fee = _amount * feeThousandthsPercent / 100000;
        return fee < minFeeAmount
            ? minFeeAmount
            : fee;
    }

    function getAmountWithFee(bytes memory assetData) internal view returns (uint256) {
        uint256 baseAmount = getAmount(assetData);
        return baseAmount + getFee(baseAmount);
    }

    function lockAssetWithFee(
        bytes memory assetData,
        address payable _from
    ) internal returns (bool success) {
        return rawLockAsset(getAmountWithFee(assetData), _from);
    }

    function sendAssetWithFee(
        bytes memory assetData,
        address payable _to
    ) internal returns (bool success) {
        return rawSendAsset(assetData, getAmountWithFee(assetData), _to);
    }

    function sendAssetKeepingFee(
        bytes memory assetData,
        address payable _to
    ) internal returns (bool success) {
        bool result = rawSendAsset(assetData, getAmount(assetData), _to);
        if (result) accumulateFee(assetData);
        return result;
    }

}
function getFee(uint256 _amount) internal view returns (uint256) {
    uint256 fee = _amount * feeThousandthsPercent / 100000;
    return fee < minFeeAmount
        ? minFeeAmount
        : fee;
}

// solium-disable-line indentation