contract PausableToken is StandardToken{

  event TokensAreLocked(address _from, uint256 _timeout);
  event Paused(address account);
  event Unpaused(address account);

  bool private _paused = false; 
  mapping (address => uint256) lockups;

  

  /**
   * @return true if the contract is paused, false otherwise.
   */
  function paused() public view returns(bool) {
    return _paused;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!_paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(_paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only if tokens are not locked
   */
  modifier ifNotLocked(address _from){
        if (lockups[_from] != 0) {
            require(now >= lockups[_from]);
        }
        _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() public onlyOwner whenNotPaused {
    _paused = true;
    emit Paused(msg.sender);
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() public onlyOwner whenPaused {
    _paused = false;
    emit Unpaused(msg.sender);
  }
    

    
 /**
 * @dev function to lock tokens utill a given block.timestamp
 * @param _holders array of adress to lock the tokens from
 * @param _timeouts array of timestamps untill which tokens are blocked
 * NOTE: _holders[i] gets _timeouts[i]
 */
 function lockTokens(address[] _holders, uint256[] _timeouts) public onlyOwner {
     require(_holders.length == _timeouts.length);
     require(_holders.length < 255);

     for (uint8 i = 0; i < _holders.length; i++) {
        address holder = _holders[i];
        uint256 timeout = _timeouts[i];

        // make sure lockup period can not be overwritten
        require(lockups[holder] == 0);

        lockups[holder] = timeout;
        emit TokensAreLocked(holder, timeout);
     }
 }


  function transfer(address _to, uint256 _value) public whenNotPaused ifNotLocked(msg.sender)  returns (bool)
  {
    return super.transfer(_to, _value);
  }

  function transferFrom(address _from,address _to,uint256 _value)public whenNotPaused ifNotLocked(_from) returns (bool)
  {
    return super.transferFrom(_from, _to, _value);
  }

  function approve(
    address _spender,
    uint256 _value
  )
    public
    whenNotPaused
    returns (bool)
  {
    return super.approve(_spender, _value);
  }

  function increaseApproval(
    address _spender,
    uint _addedValue
  )
    public
    whenNotPaused
    returns (bool success)
  {
    return super.increaseApproval(_spender, _addedValue);
  }


  function decreaseApproval(
    address _spender,
    uint _subtractedValue
  )
    public
    whenNotPaused
    returns (bool success)
  {
    return super.decreaseApproval(_spender, _subtractedValue);
  }
  
}
//taken from OpenZeppelin in August 2018, added Locking functionalities
function lockTokens(address[] _holders, uint256[] _timeouts) public onlyOwner {
    require(_holders.length == _timeouts.length);
    require(_holders.length < 255);

    for (uint8 i = 0; i < _holders.length; i++) {
       address holder = _holders[i];
       uint256 timeout = _timeouts[i];

       // make sure lockup period can not be overwritten
       require(lockups[holder] == 0);

       lockups[holder] = timeout;
       emit TokensAreLocked(holder, timeout);
    }
}

/**
 * @dev function to lock tokens utill a given block.timestamp
 * @param _holders array of adress to lock the tokens from
 * @param _timeouts array of timestamps untill which tokens are blocked
 * NOTE: _holders[i] gets _timeouts[i]
 */