docs: public static boolean validateLicense(LicenseApi licenseApi, int numberOfNodes, DrRoleType replicationRole,
              StartAction startAction)
      {
          // Delay the handling of an invalid license file until here so
          // that the leader can terminate the full cluster.
          if (licenseApi == null) {
              hostLog.fatal("VoltDB license is not valid.");
              return false;
          }
  
          // do some extra initialization here
          if (!licenseApi.secondaryInitialization()) {
              return false;
          }
  
          Calendar now = GregorianCalendar.getInstance();
          SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy");
          String expiresStr = sdf.format(licenseApi.expires().getTime());
          boolean valid = true;
  
          // make it really expire tomorrow to deal with timezone whiners
          Calendar yesterday = GregorianCalendar.getInstance();
          yesterday.add(Calendar.DATE, -1);
  
          if (yesterday.after(licenseApi.expires())) {
              if (licenseApi.hardExpiration()) {
                  if (licenseApi.isAnyKindOfTrial()) {
                      hostLog.fatal("VoltDB trial license expired on " + expiresStr + ".");
                  }
                  else {
                      hostLog.fatal("VoltDB license expired on " + expiresStr + ".");
                  }
                  hostLog.fatal("Please contact sales@voltdb.com to request a new license.");
                  return false;
              }
              else {
                  // Expired commercial licenses are allowed but generate log messages.
                  hostLog.error("Warning, VoltDB commercial license expired on " + expiresStr + ".");
                  valid = false;
              }
          }
  
          // enforce DR replication constraint
          if (licenseApi.isDrReplicationAllowed() == false) {
              if (replicationRole != DrRoleType.NONE) {
                  hostLog.fatal("Warning, VoltDB license does not allow use of DR replication.");
                  return false;
              }
          } else if (licenseApi.isDrActiveActiveAllowed() == false) {
              if (replicationRole == DrRoleType.XDCR) {
                  hostLog.fatal("Warning, VoltDB license does not allow use of XDCR.");
                  return false;
              }
          }
  
          // check node count
          if (licenseApi.maxHostcount() < numberOfNodes) {
              hostLog.fatal("Attempting to " + (startAction.doesJoin() ? "join" : "start") + " with too many nodes ("
                      + numberOfNodes + "). " + "Current license only supports " + licenseApi.maxHostcount()
                      + ". Please contact VoltDB at info@voltdb.com.");
              return false;
          }
  
          // If this is a commercial license, and there is less than or equal to 30 days until expiration,
          // issue a "days remaining" warning message.
          long diff = licenseApi.expires().getTimeInMillis() - now.getTimeInMillis();
          // The original license is only a whole data (no minutes/millis).
          // There should thus be no issue with daylight savings time,
          // but just in case, if the diff is a negative number, round up to zero.
          if (diff < 0) {
              diff = 0;
          }
          long diffDays = diff / (24 * 60 * 60 * 1000);
  
          // print out trial success message
          if (licenseApi.isAnyKindOfTrial()) {
              consoleLog.info("Starting VoltDB with trial license. License expires on " + expiresStr + " (" + diffDays + " days remaining).");
              return true;
          }
  
          if (licenseApi.isAWSMarketplace()) {
              return true;
          }
  
          // print out a warning within a month for other licenses
          if ((diff > 0) && (diff <= 30))
          {
              String msg = "Warning: VoltDB license expires in " + diffDays + " day(s).";
              consoleLog.info(msg);
          }
  
          // this gets printed even if there are non-fatal problems, so it
          // injects the word "invalid" to make it clear this is the case
          String msg = String.format("Starting VoltDB with %scommercial license. " +
                                     "License for %d nodes expires on %s.",
                                     (valid ? "" : "invalid "),
                                     licenseApi.maxHostcount(),
                                     expiresStr);
          consoleLog.info(msg);
  
          return true;
      }