function buyTokens(address beneficiary) public payable {
        require(beneficiary != address(0));
        require(validPurchase());
        require(currentStage < getStageCount());
        
        uint256 value = msg.value;
        weiRaised = weiRaised.add(value);
        uint256 limit = getStageLimit(currentStage);
        uint256 dif = 0;
        uint256 returnToSender = 0;
    
        if(weiRaised > limit){
            dif = weiRaised.sub(limit);
            value = value.sub(dif);
            
            if(currentStage == getStageCount() - 1){
                returnToSender = dif;
                weiRaised = weiRaised.sub(dif);
                dif = 0;
            }
        }
        
        mintTokens(value, beneficiary);
        
        if(dif > 0){
            currentStage = currentStage + 1;
            mintTokens(dif, beneficiary);
        }

        
        if(tokensSold == hardCap) {
            reward.setStartTime(now + 2 weeks);
        }

        
        if(returnToSender > 0) {
            msg.sender.transfer(returnToSender);
        }
    }