function buyTokens(address beneficiary, uint amountWei) internal {
        require(beneficiary != 0x0);

        
        uint totalSupply = token.totalSupply();

        
        uint actualRate = getRate(amountWei);
        uint rateScale = getRateScale();

        require(validPurchase(amountWei, actualRate, totalSupply));

        
        uint tokens = amountWei.mul(actualRate).div(rateScale);

        
        uint change = 0;

        
        if (tokens.add(totalSupply) > hardCap) {
            
            uint maxTokens = hardCap.sub(totalSupply);
            uint realAmount = maxTokens.mul(rateScale).div(actualRate);

            
            tokens = realAmount.mul(actualRate).div(rateScale);
            change = amountWei - realAmount;
            amountWei = realAmount;
        }

        
        weiRaised = weiRaised.add(amountWei);
        soldTokens = soldTokens.add(tokens);

        token.mint(beneficiary, tokens);
        TokenPurchase(msg.sender, beneficiary, amountWei, tokens);

        if (change != 0) {
            msg.sender.transfer(change);
        }
        forwardFunds(amountWei);
    }