contract INCXSecondStrategicSale is CappedCrowdsale, FinalizableCrowdsale, WhitelistedCrowdsale, IndividualCapCrowdsale, MintedCrowdsale {
  event Refund(address indexed purchaser, uint256 tokens, uint256 weiReturned);
  event TokensReturned(address indexed owner, uint256 tokens);
  event EtherDepositedForRefund(address indexed sender,uint256 weiDeposited);
  event EtherWithdrawn(address indexed wallet,uint256 weiWithdrawn);

  function INCXSecondStrategicSale(uint256 _openingTime, uint256 _closingTime, uint256 _rate, address _wallet, uint256 _cap, INCXToken _token, uint256 _minAmount, uint256 _maxAmount)
    public
    Crowdsale(_rate, _wallet, _token)
    CappedCrowdsale(_cap)
    TimedCrowdsale(_openingTime, _closingTime)
    IndividualCapCrowdsale(_minAmount, _maxAmount)
  {
  }

  /**
   * @dev Transfer ownership of token back to wallet
   */
  function finalization() internal {
    Ownable(token).transferOwnership(wallet);    
  }

  function isOpen() public view returns (bool) {
    return now >= openingTime;
  }

  /**
   * @dev Deposit ether with smart contract to allow refunds
   */
  function depositEtherForRefund() external payable {
    emit EtherDepositedForRefund(msg.sender, msg.value);
  }

  /**
   * @dev Allow withdraw funds from smart contract
   */
  function withdraw() public onlyOwner {
    uint256 returnAmount = this.balance;
    wallet.transfer(returnAmount);
    emit EtherWithdrawn(wallet, returnAmount);
  }

  /**
   * @dev Set the new rate
   * @param _rate New rate amount
   */
  function setRate(uint256 _rate) public onlyOwner {
    require(_rate > 0);
    rate = _rate;
  }

  /**
   * @dev This method refunds all the contribution that _purchaser has done
   * @param _purchaser Token purchaser asking for refund
   */
  function refund(address _purchaser) public onlyOwner {
    uint256 amountToRefund = contributions[_purchaser];
    require(amountToRefund > 0);
    require(weiRaised >= amountToRefund);
    require(address(this).balance >= amountToRefund);
    contributions[_purchaser] = 0;
    uint256 _tokens = _getTokenAmount(amountToRefund);
    weiRaised = weiRaised.sub(amountToRefund);
    _purchaser.transfer(amountToRefund);
    emit Refund(_purchaser, _tokens, amountToRefund);
  }
}
/**
 * @title INCXSecondStrategicSale
 * @dev This smart contract administers strategic sale of incx token. It has following features:
 * - There is a cap to how much ether can be raised
 * - There is a time limit in which the tokens can be bought
 * - Only whitelisted ethereum addresses can contribute (to enforce KYC)
 * - There is a minimum ether limit on individual contribution per transaction
 * - There is a maximum ether limit on total individual contribution
 * - Rate can be changed
 */
function withdraw() public onlyOwner {
  uint256 returnAmount = this.balance;
  wallet.transfer(returnAmount);
  emit EtherWithdrawn(wallet, returnAmount);
}

/**
 * @dev Allow withdraw funds from smart contract
 */