contract LockableToken is StandardToken, ReentrancyGuard {
  struct LockedBalance {
    address owner;
    uint256 value;
    uint256 releaseTime;
  }

  mapping (uint => LockedBalance) public lockedBalances;
  uint public lockedBalanceCount;

  event TransferLockedToken(address indexed from, address indexed to, uint256 value, uint256 releaseTime);
  event ReleaseLockedBalance(address indexed owner, uint256 value, uint256 releaseTime);

  /**
  * @dev transfer and lock token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  * @param _releaseTime The time to be locked.
  */
  function transferLockedToken(address _to, uint256 _value, uint256 _releaseTime) public whenNotPaused nonReentrant returns (bool) {
    require(_releaseTime > now);
    //require(_releaseTime.sub(1 years) < now);
    balances[msg.sender] = balances[msg.sender].sub(_value);
    lockedBalances[lockedBalanceCount] = LockedBalance({owner: _to, value: _value, releaseTime: _releaseTime});
    lockedBalanceCount++;
    emit TransferLockedToken(msg.sender, _to, _value, _releaseTime);
    return true;
  }

  /**
  * @dev Gets the locked balance of the specified address.
  * @param _owner The address to query the the locked balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function lockedBalanceOf(address _owner) public constant returns (uint256 value) {
    for (uint i = 0; i < lockedBalanceCount; i++) {
      LockedBalance storage lockedBalance = lockedBalances[i];
      if (_owner == lockedBalance.owner) {
        value = value.add(lockedBalance.value);
      }
    }
    return value;
  }

  /**
  * @dev Release the locked balance if its releaseTime arrived.
  * @return An uint256 representing the amount.
  */
  function releaseLockedBalance() public whenNotPaused returns (uint256 releaseAmount) {
    uint index = 0;
    while (index < lockedBalanceCount) {
      if (now >= lockedBalances[index].releaseTime) {
        releaseAmount += lockedBalances[index].value;
        unlockBalanceByIndex(index);
      } else {
        index++;
      }
    }
    return releaseAmount;
  }

  function unlockBalanceByIndex(uint index) internal {
    LockedBalance storage lockedBalance = lockedBalances[index];
    balances[lockedBalance.owner] = balances[lockedBalance.owner].add(lockedBalance.value);
    emit ReleaseLockedBalance(lockedBalance.owner, lockedBalance.value, lockedBalance.releaseTime);
    lockedBalances[index] = lockedBalances[lockedBalanceCount - 1];
    delete lockedBalances[lockedBalanceCount - 1];
    lockedBalanceCount--;
  }
}
function lockedBalanceOf(address _owner) public constant returns (uint256 value) {
  for (uint i = 0; i < lockedBalanceCount; i++) {
    LockedBalance storage lockedBalance = lockedBalances[i];
    if (_owner == lockedBalance.owner) {
      value = value.add(lockedBalance.value);
    }
  }
  return value;
}

/**
 * @dev Gets the locked balance of the specified address.
 * @param _owner The address to query the the locked balance of.
 * @return An uint256 representing the amount owned by the passed address.
 */