contract PeraToken is PausableToken {

  string public constant name = "PERA";
  string public constant symbol = "PERA";
  uint8 public constant decimals = 8;
  uint256 public constant INITIAL_SUPPLY = 92853735500000000;

  mapping (address => bool) public frozenAccount;

  event FrozenFunds(address target, bool frozen);

  event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 _value
    );

  event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );

  constructor() public {
    totalSupply_ = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
    emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
  }

  //implemented the functionality, which checks whether a transfer goes to a contract
  function transfer(address _to, uint256 _value) public returns (bool)
  {
    require(!isContract(_to));
    require(!frozenAccount[msg.sender]);                     // Check if sender is frozen
    require(!frozenAccount[_to]);                       // Check if recipient is frozen
    return super.transfer(_to, _value);
  }

  //this function specifies the possibility of a complete data set transfer
  //the web3_batch_function explains how you use this function
  function batchTransfer(address[] _tos, uint256[] _amount) onlyOwner public whenNotPaused returns (bool success) {
    require(_tos.length == _amount.length);
    uint256 i;
    uint256 sum = 0;

    for(i = 0; i < _amount.length; i++){
        sum = sum.add(_amount[i]);
        require(_tos[i] != address(0));
    }

    require(balances[msg.sender] >= sum);

    for(i = 0; i < _tos.length; i++){
        transfer(_tos[i], _amount[i]);
    }

    return true;
  }

  //false and true as arguments for freeze
  function freezeAccount(address target, bool freeze) onlyOwner public {
        frozenAccount[target] = freeze;
        emit FrozenFunds(target, freeze);
    }

  //as mentioned in the erc223 standard you need a function that checks whether an receiving wallet address is a contract
  function isContract(address _addr) internal view returns(bool is_contract){
        uint length;
        assembly {
            //retrieve the code length/size on target address
            length := extcodesize(_addr)
        }
      return (length>0);
  }
}
function transfer(address _to, uint256 _value) public returns (bool)
{
  require(!isContract(_to));
  require(!frozenAccount[msg.sender]);                     // Check if sender is frozen
  require(!frozenAccount[_to]);                       // Check if recipient is frozen
  return super.transfer(_to, _value);
}

//implemented the functionality, which checks whether a transfer goes to a contract