function buy (address _address, uint _value, uint _time) internal returns(bool){
    uint8 currentPhase = getCurrentPhase(_time);
    require (currentPhase != 0);
    uint tokensToSend = calculateTokensWithBonus(_value);

    ethCollected = ethCollected.add(_value);
    tokensSold = tokensSold.add(tokensToSend);

    if (currentPhase == 1){
      require (preIcoTokensSold.add(tokensToSend) <= PRE_ICO_MAX_CAP);
      
      preIcoTokensSold = preIcoTokensSold.add(tokensToSend);

      distributionAddress.transfer(address(this).balance.sub(oraclizeBalance));
    }else{
      contributorsBalances[_address] = contributorsBalances[_address].add(_value);

      if(tokensSold >= ICO_MIN_CAP){
        if(!areTokensSended){
          token.icoSucceed();
          areTokensSended = true;
        }
        distributionAddress.transfer(address(this).balance.sub(oraclizeBalance));
      }
    }

    emit OnSuccessfullyBuy(_address,_value,true, tokensToSend);
    token.sendCrowdsaleTokens(_address, tokensToSend);
    return true;
  }