function buyTokens() public payable onlyWhitelisted {
        
        require(enabled);
        require(block.timestamp >= startTimestamp && block.timestamp <= endTimestamp);
        require(msg.value >= minValue);
        require(buyAmounts[msg.sender] < maxPerAddress);
        require(accumulatedAmount.add(accumulatedAmountExternal) < maxTotal);

        uint256 buyAmount;
        uint256 refundAmount;
        (buyAmount, refundAmount) = _calculateAmounts(msg.sender, msg.value);

        if (buyAmounts[msg.sender] == 0) {
            addresses.push(msg.sender);
        }

        accumulatedAmount = accumulatedAmount.add(buyAmount);
        buyAmounts[msg.sender] = buyAmounts[msg.sender].add(buyAmount);
        msg.sender.transfer(refundAmount);
        emit BuyTokens(msg.sender, buyAmount, refundAmount, buyAmount.mul(exchangeRate));
    }