function doPurchase(address _owner) private preSaleActive inNormalState {
    require(!crowdsaleFinished);
    require(collected.add(msg.value) <= hardCap);
    require(totalTokens >= tokensSold + msg.value.mul(ethUsdRate).div(tokenPriceUsd));

    if (!softCapReached && collected < softCap && collected.add(msg.value) >= softCap) {
      softCapReached = true;
      SoftCapReached(softCap);
    }

    uint tokens = msg.value.mul(ethUsdRate).div(tokenPriceUsd);

    if (token.balanceOf(msg.sender) == 0) investorCount++;

    address referral = investorWhiteList.getReferralOf(msg.sender);
    uint referralBonus = 0;
    if (msg.value >= REFERRAL_MIN_LIMIT) {
      referralBonus = calculateReferralBonus(tokens);
    }

    collected = collected.add(msg.value);

    token.transfer(msg.sender, tokens);

    uint newTokensSold = tokensSold.add(tokens);

    if (referralBonus > 0 && referral != 0x0) {
      newTokensSold = newTokensSold.add(referralBonus);
    }

    tokensSold = newTokensSold;

    deposited[msg.sender] = deposited[msg.sender].add(msg.value);
    
    NewContribution(_owner, tokens, msg.value);

    if (referralBonus > 0 && referral != 0x0) {
      token.transfer(referral, referralBonus);
      NewReferralTransfer(msg.sender, referral, referralBonus);
    }
  }