function buyTokens(address beneficiary) public payable {
      bool validPurchase = beneficiary != 0x0 && msg.value != 0 && !isBlacklisted[msg.sender];
      uint256 currentTokensAmount = availableTokens();
      
      require(isActive() && validPurchase);
      investmentsOf[msg.sender] = investmentsOf[msg.sender].add(msg.value);
      uint256 boughtTokens;
      uint256 refundAmount = 0;

      
      uint256[2] memory tokensAndRefund = calcMultiStage();
      boughtTokens = tokensAndRefund[0];
      refundAmount = tokensAndRefund[1];
      
      require(boughtTokens <= currentTokensAmount);

      totalSold = totalSold.add(boughtTokens); 

      if(soldOnStage >= stageCap()) {
        toNextStage();
      }

      rewardToken.transfer(beneficiary, boughtTokens);

      if (refundAmount > 0)
          refundMoney(refundAmount);

      withdrawFunds(this.balance);
    }