public Sec() {
   prep = Base64.decode("bWFpMUVONFppZWdoZXkxUXVlR2llN2ZlaTRlZWg1bmU=");
 }
  public void doFree(
      final DownloadLink downloadLink,
      final boolean resumable,
      final int maxchunks,
      final String directlinkproperty)
      throws Exception, PluginException {
    br.setFollowRedirects(false);
    String passCode = null;
    // First, bring up saved final links
    String dllink = checkDirectLink(downloadLink, directlinkproperty);
    // Second, check for streaming links on the first page
    if (dllink == null) dllink = getDllink();
    // Third, do they provide video hosting?
    if (dllink == null && VIDEOHOSTER) {
      // jwplayer - http://vdoreel.com/test/ExorcomPlayer.swf
      final Browser brv = br.cloneBrowser();
      brv.getPage(
          COOKIE_HOST
              + "/xml2/"
              + new Regex(downloadLink.getDownloadURL(), "([a-z0-9]+)$").getMatch(0)
              + ".xml");
      String a = brv.getRegex("CDATA\\[([^\\]]+={0,2})").getMatch(0);
      if (a == null || a.length() < 10) {
        logger.warning("Can't find 'a'");
        throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
      }
      try {
        Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
        /* CHECK: we should always use getBytes("UTF-8") or with wanted charset, never system charset! */
        SecretKeySpec keySpec = new SecretKeySpec("N%66=]H6".getBytes(), "DES");
        c.init(Cipher.DECRYPT_MODE, keySpec);
        /* CHECK: we should always use new String (bytes,charset) to avoid issues with system charset and utf-8 */
        dllink = new String(c.doFinal(Base64.decode(a.substring(0, a.length() - 6))));
      } catch (Throwable e) {
      }
    }
    // Fourth, continue like normal.
    if (dllink == null) {
      checkErrors(downloadLink, false, passCode);
      final Form download1 = getFormByKey("op", "download1");
      if (download1 != null) {
        download1.remove("method_premium");
        // stable is lame, issue finding input data fields correctly. eg. closes at ' quotation mark
        // - remove when jd2 goes stable!
        if (downloadLink.getName().contains("'")) {
          String fname =
              new Regex(br, "<input type=\"hidden\" name=\"fname\" value=\"([^\"]+)\">")
                  .getMatch(0);
          if (fname != null) {
            download1.put("fname", Encoding.urlEncode(fname));
          } else {
            logger.warning("Could not find 'fname'");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
        }
        // end of backward compatibility
        sendForm(download1);
        checkErrors(downloadLink, false, passCode);
        dllink = getDllink();
      }
    }
    if (dllink == null) {
      Form dlForm = br.getFormbyProperty("name", "F1");
      if (dlForm == null) throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
      // how many forms deep do you want to try.
      int repeat = 2;
      for (int i = 0; i <= repeat; i++) {
        dlForm.remove(null);
        final long timeBefore = System.currentTimeMillis();
        boolean password = false;
        boolean skipWaittime = false;
        if (new Regex(correctedBR, PASSWORDTEXT).matches()) {
          password = true;
          logger.info("The downloadlink seems to be password protected.");
        }
        // md5 can be on the subsequent pages
        if (downloadLink.getMD5Hash() == null) {
          String md5hash = new Regex(correctedBR, "<b>MD5.*?</b>.*?nowrap>(.*?)<").getMatch(0);
          if (md5hash != null) downloadLink.setMD5Hash(md5hash.trim());
        }
        /* Captcha START */
        if (correctedBR.contains(";background:#ccc;text-align")) {
          logger.info("Detected captcha method \"plaintext captchas\" for this host");
          /** Captcha method by ManiacMansion */
          final String[][] letters =
              new Regex(
                      br,
                      "<span style=\\'position:absolute;padding\\-left:(\\d+)px;padding\\-top:\\d+px;\\'>(&#\\d+;)</span>")
                  .getMatches();
          if (letters == null || letters.length == 0) {
            logger.warning("plaintext captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          final SortedMap<Integer, String> capMap = new TreeMap<Integer, String>();
          for (String[] letter : letters) {
            capMap.put(Integer.parseInt(letter[0]), Encoding.htmlDecode(letter[1]));
          }
          final StringBuilder code = new StringBuilder();
          for (String value : capMap.values()) {
            code.append(value);
          }
          dlForm.put("code", code.toString());
          logger.info(
              "Put captchacode "
                  + code.toString()
                  + " obtained by captcha metod \"plaintext captchas\" in the form.");
        } else if (correctedBR.contains("/captchas/")) {
          logger.info("Detected captcha method \"Standard captcha\" for this host");
          final String[] sitelinks = HTMLParser.getHttpLinks(br.toString(), null);
          String captchaurl = null;
          if (sitelinks == null || sitelinks.length == 0) {
            logger.warning("Standard captcha captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          for (String link : sitelinks) {
            if (link.contains("/captchas/")) {
              captchaurl = link;
              break;
            }
          }
          if (captchaurl == null) {
            logger.warning("Standard captcha captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          String code = getCaptchaCode("xfilesharingprobasic", captchaurl, downloadLink);
          dlForm.put("code", code);
          logger.info(
              "Put captchacode "
                  + code
                  + " obtained by captcha metod \"Standard captcha\" in the form.");
        } else if (new Regex(correctedBR, "(api\\.recaptcha\\.net|google\\.com/recaptcha/api/)")
            .matches()) {
          logger.info("Detected captcha method \"Re Captcha\" for this host");
          final PluginForHost recplug = JDUtilities.getPluginForHost("DirectHTTP");
          final jd.plugins.hoster.DirectHTTP.Recaptcha rc = ((DirectHTTP) recplug).getReCaptcha(br);
          final String id = new Regex(correctedBR, "\\?k=([A-Za-z0-9%_\\+\\- ]+)\"").getMatch(0);
          if (id == null) throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          rc.setId(id);
          rc.load();
          final File cf = rc.downloadCaptcha(getLocalCaptchaFile());
          final String c = getCaptchaCode(cf, downloadLink);
          dlForm.put("recaptcha_challenge_field", rc.getChallenge());
          dlForm.put("recaptcha_response_field", Encoding.urlEncode(c));
          logger.info(
              "Put captchacode "
                  + c
                  + " obtained by captcha metod \"Re Captcha\" in the form and submitted it.");
          /** wait time is often skippable for reCaptcha handling */
          skipWaittime = true;
        } else if (br.containsHTML("solvemedia\\.com/papi/")) {
          logger.info("Detected captcha method \"solvemedia\" for this host");
          final PluginForDecrypt solveplug = JDUtilities.getPluginForDecrypt("linkcrypt.ws");
          final jd.plugins.decrypter.LnkCrptWs.SolveMedia sm =
              ((jd.plugins.decrypter.LnkCrptWs) solveplug).getSolveMedia(br);
          final File cf = sm.downloadCaptcha(getLocalCaptchaFile());
          final String code = getCaptchaCode(cf, downloadLink);
          final String chid = sm.getChallenge(code);
          dlForm.put("adcopy_challenge", chid);
          dlForm.put("adcopy_response", "manual_challenge");
        }
        /* Captcha END */

        if (password) passCode = handlePassword(passCode, dlForm, downloadLink);

        if (!skipWaittime) waitTime(timeBefore, downloadLink);

        sendForm(dlForm);
        logger.info("Submitted DLForm");

        dllink = getDllink();
        if (dllink == null
            && (!br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"") || i == repeat)) {
          checkErrors(downloadLink, true, passCode);
          logger.warning("Final downloadlink (String is \"dllink\") regex didn't match!");
          break;
        } else if (dllink == null
            && br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"")) {
          dlForm = br.getFormbyProperty("name", "F1");
          continue;
        } else {
          break;
        }
      }
    }
    checkErrors(downloadLink, true, passCode);
    if (dllink == null) throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
    logger.info("Final downloadlink = " + dllink + " starting the download...");
    dl = jd.plugins.BrowserAdapter.openDownload(br, downloadLink, dllink, resumable, maxchunks);
    if (dl.getConnection().getContentType().contains("html")) {
      if (dl.getConnection().getResponseCode() == 503)
        throw new PluginException(
            LinkStatus.ERROR_HOSTER_TEMPORARILY_UNAVAILABLE,
            "Connection limit reached, please contact our support!",
            5 * 60 * 1000l);
      logger.warning("The final dllink seems not to be a file!");
      br.followConnection();
      correctBR();
      checkServerErrors();
      throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
    }
    downloadLink.setProperty(directlinkproperty, dllink);
    if (passCode != null) downloadLink.setProperty("pass", passCode);
    fixFilename(downloadLink);
    try {
      // add a download slot
      controlFree(+1);
      // start the dl
      dl.startDownload();
    } finally {
      // remove download slot
      controlFree(-1);
    }
  }