/**
   * Verifies license version 2 signature.
   *
   * @param key Public key.
   * @param lic License version 2.
   * @return {@code true} if signature was verified, {@code false} - otherwise.
   * @throws GeneralSecurityException If any exception occurs while verifying.
   */
  public static boolean verifySignatureV2(PublicKey key, GridLicenseV2 lic)
      throws GeneralSecurityException {
    assert key != null;
    assert lic != null;

    byte[] data = getDataV2ForSign(lic);
    byte[] sign = U.hexString2ByteArray(lic.getSignature());

    return verifySignature(SIGN_ALG, PRV, key, data, sign);
  }
  /**
   * Gets license version 2 data for sign.
   *
   * @param lic GridGain license version 2.
   * @return Data for sign.
   */
  public static byte[] getDataV2ForSign(GridLicenseV2 lic) {
    assert lic != null;

    try {
      return new SB()
          .a(lic.getVersion())
          .a(lic.getId())
          .a(lic.getIssueDate() != null ? U.format(lic.getIssueDate(), DATE_PTRN) : "")
          .a(lic.getIssueOrganization())
          .a(lic.getUserOrganization())
          .a(lic.getUserWww())
          .a(lic.getUserEmail())
          .a(lic.getUserName())
          .a(lic.getLicenseNote())
          .a(lic.getVersionRegexp())
          .a(lic.getType())
          .a(lic.getExpireDate() != null ? U.format(lic.getExpireDate(), DATE_PTRN) : "")
          .a(lic.getMeteringKey1())
          .a(lic.getMeteringKey2())
          .a(lic.getMaxCpus())
          .a(lic.getMaxComputers())
          .a(lic.getMaxNodes())
          .a(lic.getMaxUpTime())
          .toString()
          .getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new GridRuntimeException(e);
    }
  }