public static boolean hasFullLicence() {
    if (featman == null) {
      // Debug.out("featman null");
      Set<String> featuresInstalled = UtilitiesImpl.getFeaturesInstalled();
      return featuresInstalled.contains("dvdburn");
    }

    boolean full = false;
    FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn");
    // if any of the feature details are still valid, we have a full
    for (FeatureDetails fd : featureDetails) {
      int state = fd.getLicence().getState();
      if (state == Licence.LS_CANCELLED || state == Licence.LS_REVOKED) {
        continue;
      }
      long now = SystemTime.getCurrentTime();
      Long lValidUntil = (Long) fd.getProperty(FeatureDetails.PR_VALID_UNTIL);
      if (lValidUntil != null && lValidUntil.longValue() >= now) {
        full = true;
        break;
      }
      Long lValidOfflineUntil = (Long) fd.getProperty(FeatureDetails.PR_OFFLINE_VALID_UNTIL);
      if (lValidOfflineUntil != null && lValidOfflineUntil.longValue() >= now) {
        full = true;
        break;
      }
    }

    return full;
  }
  public static void openStreamPlusWindow(final String referal) {
    String msgidPrefix;
    String buttonID;
    long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryTimeStamp();
    if (plusExpiryTimeStamp < 0 || plusExpiryTimeStamp >= SystemTime.getCurrentTime()) {
      msgidPrefix = "dlg.stream.plus.";
      buttonID = "Button.upgrade";
    } else {
      buttonID = "Button.renew";
      msgidPrefix = "dlg.stream.plus.renew.";
      if (!MessageText.keyExistsForDefaultLocale(msgidPrefix + "text")) {
        msgidPrefix = "dlg.stream.plus.";
      }
    }
    final String f_msgidPrefix = msgidPrefix;
    final VuzeMessageBox box =
        new VuzeMessageBox(
            MessageText.getString(msgidPrefix + "title"),
            MessageText.getString(msgidPrefix + "text"),
            new String[] {
              MessageText.getString(buttonID), MessageText.getString("Button.cancel"),
            },
            0);
    box.setButtonVals(new Integer[] {BUTTON_UPGRADE, SWT.CANCEL});

    box.setSubTitle(MessageText.getString(msgidPrefix + "subtitle"));
    box.addResourceBundle(
        FeatureManagerUI.class, SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_streamplus");
    box.setIconResource("image.header.streamplus");

    box.setListener(
        new VuzeMessageBoxListener() {
          public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
            SWTSkin skin = soExtra.getSkin();
            skin.createSkinObject("dlg.stream.plus", "dlg.stream.plus", soExtra);
            SWTSkinObject soSubText = skin.getSkinObject("trial-info", soExtra);
            if (soSubText instanceof SWTSkinObjectText) {
              ((SWTSkinObjectText) soSubText).setTextID(f_msgidPrefix + "subtext");
            }
          }
        });

    box.open(
        new UserPrompterResultListener() {
          public void prompterClosed(int result) {
            if (result == BUTTON_UPGRADE) {
              SBC_PlusFTUX.setSourceRef("dlg-stream" + (referal == null ? "" : "-" + referal));

              MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
              mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
            }
          }
        });
  }
 public static boolean hasFullLicence() {
   if (featman == null) {
     // Debug.out("featman null");
     Set<String> featuresInstalled = UtilitiesImpl.getFeaturesInstalled();
     return featuresInstalled.contains("dvdburn");
   }
   licenceDetails fullFeatureDetails = getFullFeatureDetails();
   long now = SystemTime.getCurrentTime();
   return fullFeatureDetails != null
       && fullFeatureDetails.expiry > now
       && fullFeatureDetails.displayedExpiry > now;
 }
  public static licenceDetails getFullFeatureDetails() {
    if (featman == null) {
      Debug.out("featman null");
      return null;
    }

    FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn");
    // if any of the feature details are still valid, we have a full
    for (FeatureDetails fd : featureDetails) {
      long now = SystemTime.getCurrentTime();
      Long lValidUntil = (Long) fd.getProperty(FeatureDetails.PR_VALID_UNTIL);
      if (lValidUntil != null && lValidUntil.longValue() >= now) {
        return new licenceDetails(
            lValidUntil.longValue(), fd.getLicence().getKey(), fd.getLicence().getState());
      }
      Long lValidOfflineUntil = (Long) fd.getProperty(FeatureDetails.PR_OFFLINE_VALID_UNTIL);
      if (lValidOfflineUntil != null && lValidOfflineUntil.longValue() >= now) {
        return new licenceDetails(
            lValidOfflineUntil.longValue(), fd.getLicence().getKey(), fd.getLicence().getState());
      }
    }

    Licence bestLicence = null;
    Licence[] licences = featman.getLicences();
    for (Licence licence : licences) {
      FeatureDetails[] details = licence.getFeatures();
      boolean isTrial = false;
      for (FeatureDetails fd : details) {
        Object property = fd.getProperty(FeatureDetails.PR_IS_TRIAL);
        if ((property instanceof Number) && ((Number) property).intValue() == 1) {
          isTrial = true;
          break;
        }
      }
      if (isTrial) {
        continue;
      }
      int state = licence.getState();
      if (state == Licence.LS_AUTHENTICATED) {
        bestLicence = licence;
        break;
      } else {
        bestLicence = licence;
      }
    }

    if (bestLicence != null) {
      return new licenceDetails(0, bestLicence.getKey(), bestLicence.getState());
    }

    return null;
  }
  public static String appendFeatureManagerURLParams(String url) {
    long remainingUses = FeatureManagerUI.getRemaining();
    long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryDisplayTimeStamp();
    String plusRenewalCode = FeatureManagerUI.getPlusRenewalCode();

    String newURL = url + (url.contains("?") ? "&" : "?");
    newURL += "mode=" + FeatureManagerUI.getMode();
    if (plusExpiryTimeStamp != 0) {
      newURL += "&remaining_plus=" + (plusExpiryTimeStamp - SystemTime.getCurrentTime());
    }
    newURL += "&remaining=" + remainingUses;
    if (plusRenewalCode != null) {
      newURL += "&renewal_code=" + plusRenewalCode;
    }

    return newURL;
  }
  public static licenceDetails getFullFeatureDetails() {
    if (featman == null) {
      Debug.out("featman null");
      return null;
    }

    TreeMap<Long, Object[]> mapOrder = new TreeMap<Long, Object[]>(Collections.reverseOrder());
    FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn");
    // if any of the feature details are still valid, we have a full
    for (FeatureDetails fd : featureDetails) {
      Licence licence = fd.getLicence();
      int state = licence.getState();
      if (state == Licence.LS_ACTIVATION_DENIED) {
        mapOrder.put(-1L, new Object[] {licence, Long.valueOf(0)});
        continue;
      } else if (state == Licence.LS_CANCELLED) {
        mapOrder.put(-2L, new Object[] {licence, Long.valueOf(0)});
        continue;
      } else if (state == Licence.LS_INVALID_KEY) {
        mapOrder.put(-3L, new Object[] {licence, Long.valueOf(0)});
        continue;
      } else if (state == Licence.LS_REVOKED) {
        mapOrder.put(-4L, new Object[] {licence, Long.valueOf(0)});
        continue;
      } else if (state == Licence.LS_PENDING_AUTHENTICATION) {
        mapOrder.put(-6L, new Object[] {licence, Long.valueOf(0)});
        continue;
      }

      long now = SystemTime.getCurrentTime();
      Long lValidUntil = (Long) fd.getProperty(FeatureDetails.PR_VALID_UNTIL);
      Long lValidOfflineUntil = (Long) fd.getProperty(FeatureDetails.PR_OFFLINE_VALID_UNTIL);

      if (lValidUntil == null && lValidOfflineUntil == null) {
        continue;
      }

      long minValidUntil = -1;
      long maxValidUntil = -1;
      if (lValidUntil != null) {
        minValidUntil = maxValidUntil = lValidUntil.longValue();
        if (minValidUntil < now) {
          mapOrder.put(minValidUntil, new Object[] {licence, Long.valueOf(minValidUntil)});
          continue;
        }
      }
      if (lValidOfflineUntil != null) {
        long validOfflineUntil = lValidOfflineUntil.longValue();
        if (validOfflineUntil < now) {
          mapOrder.put(validOfflineUntil, new Object[] {licence, Long.valueOf(maxValidUntil)});
          continue;
        }
        if (maxValidUntil == -1 || validOfflineUntil > maxValidUntil) {
          maxValidUntil = validOfflineUntil;
        }
      }

      mapOrder.put(maxValidUntil, new Object[] {licence, minValidUntil});
    }

    if (mapOrder.size() == 0) {
      return null;
    }

    Long firstKey = mapOrder.firstKey();
    Object[] objects = mapOrder.get(firstKey);
    Licence licence = (Licence) objects[0];
    return new licenceDetails(firstKey.longValue(), ((Long) objects[1]).longValue(), licence);
  }