function sellTokens(address _beneficiary, uint _weiAmount, uint timestamp) 
    inState(State.Active) internal returns(uint)
  {
    uint beneficiaryTokens;
    uint extraTokens;
    uint totalTokens;
    uint refererTokens;
    address refererAddress;
    (totalTokens, beneficiaryTokens, extraTokens, refererTokens, refererAddress) = calculateEthAmount(
      _beneficiary, 
      _weiAmount, 
      timestamp, 
      token.totalSupply());

    require(validPurchase(_beneficiary,   
                          _weiAmount, 
                          beneficiaryTokens,
                          extraTokens,
                          totalTokens,
                          timestamp));

    weiRaised = weiRaised.add(_weiAmount); 
    beneficiaryInvest[_beneficiary] = beneficiaryInvest[_beneficiary].add(_weiAmount);
    shipTokens(_beneficiary, beneficiaryTokens);     
    EthBuy(msg.sender,             
                  _beneficiary, 
                  _weiAmount, 
                  beneficiaryTokens);
    ShipTokens(_beneficiary, beneficiaryTokens);

    if (isExtraDistribution) {            
      shipTokens(extraTokensHolder, extraTokens);
      ShipTokens(extraTokensHolder, extraTokens);
    }

    if (isPersonalBonuses) {
      PersonalBonusRecord storage record = personalBonuses[_beneficiary];
      if (record.refererAddress != address(0) && record.refererBonus > 0) {
        shipTokens(record.refererAddress, refererTokens);
        ShipTokens(record.refererAddress, refererTokens);
      }
    }

    soldTokens = soldTokens.add(totalTokens);
    return beneficiaryTokens;
  }