contract AirdropAndAffiliateCrowdsale is MintedCrowdsale {
  uint256 public valueAirDrop;
  uint256 public referrerBonus1;
  uint256 public referrerBonus2;
  mapping (address => uint8) public payedAddress;
  mapping (address => address) public referrers;
  constructor(uint256 _valueAirDrop, uint256 _referrerBonus1, uint256 _referrerBonus2) public {
    valueAirDrop = _valueAirDrop;
	referrerBonus1 = _referrerBonus1;
	referrerBonus2 = _referrerBonus2;
  }
  function bytesToAddress(bytes source) internal pure returns(address) {
    uint result;
    uint mul = 1;
    for(uint i = 20; i > 0; i--) {
      result += uint8(source[i-1])*mul;
      mul = mul*256;
    }
    return address(result);
  }  
  /**
   * @dev Overrides delivery by minting tokens upon purchase.
   * @param _beneficiary Token purchaser
   * @param _tokenAmount Number of tokens to be minted
   */
  function _deliverTokens(
    address _beneficiary,
    uint256 _tokenAmount
  )
    internal
  {
    address referer1;
    uint256 refererTokens1;
    address referer2;
    uint256 refererTokens2;	
    if (_tokenAmount != 0){ 
	  super._deliverTokens(_beneficiary, _tokenAmount);
      //require(MintableToken(token).mint(_beneficiary, _tokenAmount));
    }
	else{
	  require(payedAddress[_beneficiary] == 0);
      payedAddress[_beneficiary] = 1;  	  
	  super._deliverTokens(_beneficiary, valueAirDrop);
	  _tokenAmount = valueAirDrop;
	}
    //referral system
	if(msg.data.length == 20) {	  
      referer1 = bytesToAddress(bytes(msg.data));
	  referrers[_beneficiary] = referer1;
      if(referer1 != _beneficiary){
	    //add tokens to the referrer1
        refererTokens1 = _tokenAmount.mul(referrerBonus1).div(100);
	    super._deliverTokens(referer1, refererTokens1);
	    referer2 = referrers[referer1];
	    if(referer2 != address(0)){
	      refererTokens2 = _tokenAmount.mul(referrerBonus2).div(100);
	      super._deliverTokens(referer2, refererTokens2);
	    }
	  }
    }	
  }
}
/**
 * @title AirdropAndAffiliateCrowdsale
 * @dev Extension of AirdropAndAffiliateCrowdsale contract
 */
function _deliverTokens(
    address _beneficiary,
    uint256 _tokenAmount
  )
    internal
  {
    address referer1;
    uint256 refererTokens1;
    address referer2;
    uint256 refererTokens2;	
    if (_tokenAmount != 0){ 
	  super._deliverTokens(_beneficiary, _tokenAmount);
      //require(MintableToken(token).mint(_beneficiary, _tokenAmount));
    }
	else{
	  require(payedAddress[_beneficiary] == 0);
      payedAddress[_beneficiary] = 1;  	  
	  super._deliverTokens(_beneficiary, valueAirDrop);
	  _tokenAmount = valueAirDrop;
	}
    //referral system
	if(msg.data.length == 20) {	  
      referer1 = bytesToAddress(bytes(msg.data));
	  referrers[_beneficiary] = referer1;
      if(referer1 != _beneficiary){
	    //add tokens to the referrer1
        refererTokens1 = _tokenAmount.mul(referrerBonus1).div(100);
	    super._deliverTokens(referer1, refererTokens1);
	    referer2 = referrers[referer1];
	    if(referer2 != address(0)){
	      refererTokens2 = _tokenAmount.mul(referrerBonus2).div(100);
	      super._deliverTokens(referer2, refererTokens2);
	    }
	  }
    }	
  }
/**
 * @dev Overrides delivery by minting tokens upon purchase.
 * @param _beneficiary Token purchaser
 * @param _tokenAmount Number of tokens to be minted
 */