function calculateInternalTokensAmount(
        uint256 _amountInUSD,
        uint256 _collectedUSD,
        uint256 _soldTokens
    ) internal view returns (uint256, uint256) {

        uint256 newCollectedUSD = _collectedUSD;
        uint256 newSoldTokens = _soldTokens;
        for (uint i = 0; i < tiers.length; i++) {
            Tier storage tier = tiers[i];
            if (tier.maxAmount > newCollectedUSD || tier.maxAmount == 0) {
                if (newCollectedUSD + _amountInUSD > tier.maxAmount && tier.maxAmount != 0) {
                    uint256 diffInUSD = tier.maxAmount.sub(newCollectedUSD);
                    newCollectedUSD = newCollectedUSD.add(diffInUSD);
                    _amountInUSD = _amountInUSD.sub(diffInUSD);
                    newSoldTokens = newSoldTokens.add(diffInUSD.div(10 ** 3).div(tier.price));
                } else {
                    newSoldTokens = newSoldTokens.add(_amountInUSD.div(10 ** 3).div(tier.price));
                    newCollectedUSD = newCollectedUSD.add(_amountInUSD);
                    _amountInUSD = 0;
                }
            }
            if (_amountInUSD == 0) {
                break;
            }
        }
        uint256 tokensAmount = newSoldTokens.sub(_soldTokens);

        if (_soldTokens.add(tokensAmount) <= maxTokenSupply) {
            return (tokensAmount, newCollectedUSD.sub(_collectedUSD));
        }
        return (0, 0);
    }