private YouTubeSig getYouTubeSig(String html5playerUrl) {
    // concurrency issues are not important in this point
    YouTubeSig sig = null;
    if (!YT_SIG_MAP.containsKey(html5playerUrl)) {
      String jscode = "";
      try {
        html5playerUrl = html5playerUrl.replace("\\", "");
        HttpClient httpClient = HttpClientFactory.getInstance(HttpClientFactory.HttpContext.SEARCH);
        jscode = httpClient.get(html5playerUrl);
        sig = new YouTubeSig(jscode);
        YT_SIG_MAP.put(html5playerUrl, sig);
      } catch (Throwable t) {
        LOG.error("Could not getYouTubeSig", t);
        LOG.error("jscode:\n" + jscode);
      }
    } else {
      // cache hit, it worked with this url.
      sig = YT_SIG_MAP.get(html5playerUrl);
    }

    return sig;
  }
  private List<LinkInfo> extractLinksFromDashManifest(
      String dashManifestUrl,
      YouTubeSig ytSig,
      String filename,
      Date date,
      String videoId,
      String userName,
      String channelName,
      ThumbnailLinks thumbnailLinks)
      throws IOException, ParserConfigurationException, SAXException {
    dashManifestUrl = dashManifestUrl.replace("\\/", "/");
    Pattern p = Pattern.compile("/s/([a-fA-F0-9\\.]+)/");
    Matcher m = p.matcher(dashManifestUrl);
    if (m.find()) {
      String sig = m.group(1);
      String signature = ytSig.calc(sig);

      dashManifestUrl =
          dashManifestUrl.replaceAll("/s/([a-fA-F0-9\\.]+)/", "/signature/" + signature + "/");
    } else if (dashManifestUrl.contains("/signature/")) {
      // dashManifestUrl as it is, empty block to review
    } else {
      return Collections.emptyList();
    }

    HttpClient httpClient = HttpClientFactory.getInstance(HttpClientFactory.HttpContext.SEARCH);
    String dashDoc = httpClient.get(dashManifestUrl);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new InputSource(new StringReader(dashDoc)));

    NodeList nodes = doc.getElementsByTagName("BaseURL");

    List<LinkInfo> infos = new ArrayList<LinkInfo>();

    for (int i = 0; i < nodes.getLength(); i++) {
      Node item = nodes.item(i);
      String url = item.getTextContent();
      int contentLength = -1;
      try {
        contentLength = Integer.parseInt(item.getAttributes().item(0).getTextContent());
      } catch (Throwable e) {
        // ignore
      }
      int fmt = Integer.parseInt(new Regex(url, "itag=(\\d+)").getMatch(0));

      Format format = FORMATS.get(fmt);
      if (format == null) {
        continue;
      }

      LinkInfo info =
          new LinkInfo(
              url,
              fmt,
              filename,
              contentLength,
              date,
              videoId,
              userName,
              channelName,
              thumbnailLinks,
              format);
      infos.add(info);
    }

    return infos;
  }