function buyTokens(address beneficiary) public payable {
    uint256 weiAmount = msg.value;
    _preValidatePurchase(beneficiary, weiAmount);

    
    uint256 tokens = _getTokenAmount(weiAmount);

    
    _accrueBonusTokens(beneficiary, tokens, weiAmount);

    
    _weiRaised = _weiRaised.add(weiAmount);

    _processPurchase(beneficiary, tokens);
    emit TokensPurchased(
      msg.sender,
      beneficiary,
      weiAmount,
      tokens
    );

    if (_weiRaised >= softCap) _forwardFunds();

    ledger[msg.sender] = ledger[msg.sender].add(msg.value);
  }