private static void formatNavPointsLineBreaks(File navigationFile, String encoding)
      throws IOException {

    BufferedReader br =
        new BufferedReader(new InputStreamReader(new FileInputStream(navigationFile), encoding));

    File tmpOutputFile = new File(navigationFile.getAbsolutePath() + "_tmp");
    BufferedWriter bw =
        new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpOutputFile), encoding));

    String line = br.readLine();

    StringBuffer sBuffer = new StringBuffer();
    if (FilesetRegex.getInstance()
        .matches(FilesetRegex.getInstance().FILE_NCC, navigationFile.getName())) {
      // handle ncc
      boolean isInsideNavPoint = false;
      while (line != null) {
        String l = line.toLowerCase();

        if ((l.indexOf("<h") != -1 && (l.indexOf("<html") == -1) && l.indexOf("<head") == -1)
            || l.indexOf("<span") != -1) {
          isInsideNavPoint = true;
        } else if (l.indexOf("</h") != -1 || l.indexOf("</span") != -1) {
          isInsideNavPoint = false;
        }

        if (isInsideNavPoint) {
          sBuffer.append(line.trim());
          if (!l.trim().endsWith(">")) {
            sBuffer.append(" ");
          }
        } else {
          sBuffer.append(line.trim());
          sBuffer.append("\r\n");
          bw.write(sBuffer.toString());
          sBuffer.setLength(0);
        }
        line = br.readLine();
      } // move to the next line in the ncc

    } else {
      // handle non ncc documents
      while (line != null) {
        sBuffer.append(line);
        sBuffer.append("\r\n");

        line = br.readLine();
        bw.write(sBuffer.toString());
        sBuffer.setLength(0);
      } // move to the next line in the full text
    }

    br.close();
    // BufferedWriter bw = new BufferedWriter(new FileWriter(navigationFile));
    // bw.write(sBuffer.toString());
    bw.flush();
    bw.close();
    FileUtils.copy(tmpOutputFile, navigationFile);
    tmpOutputFile.delete();
  }
  private static void formatPlexTalkAttributesOrder(File file, String encoding) throws IOException {

    try {
      BufferedReader br =
          new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));

      File tempOutputFile = new File(file.getAbsolutePath() + "__tmp");
      BufferedWriter bw =
          new BufferedWriter(
              new OutputStreamWriter(new FileOutputStream(tempOutputFile), encoding));

      String line = br.readLine();
      StringBuffer elemStringBuffer = new StringBuffer();

      boolean elementComplete = false;
      boolean buildingElement = false;
      while (line != null) {
        String trimmedLine = line.trim();
        // 1. RETRIEVE A meta OR audio ELEMENT
        if ((trimmedLine.startsWith("<meta") || trimmedLine.startsWith("<audio"))
            && trimmedLine.endsWith("/>")) {
          // a line with a complete meta or audio element
          elemStringBuffer.append(line);
          elementComplete = true;
        } else if ((trimmedLine.startsWith("<meta") || trimmedLine.startsWith("<audio"))
            && !trimmedLine.endsWith("/>")) {
          // a line that starts meta or audio element
          elemStringBuffer.append(line + " ");
          buildingElement = true;
          line = br.readLine();
          continue;

        } else if (buildingElement) {
          elemStringBuffer.append(trimmedLine);
          if (trimmedLine.endsWith("/>")) {
            // a line that ends meta or audio element
            elementComplete = true;
            buildingElement = false;
          } else {
            // a line with a mid part of meta or audio element
            elemStringBuffer.append(" ");
            line = br.readLine();
            continue;
          }
        }
        // 2. MOVE THE audio/@src OR meta/@name ATTRIBUTE TO THE FIRST POSITION
        if (elementComplete) {
          int srcAttStart = elemStringBuffer.indexOf("src=");
          int nameAttrStart = elemStringBuffer.indexOf("name=");
          int attrStart = -1;
          if (srcAttStart != -1) {
            attrStart = srcAttStart;
          } else if (nameAttrStart != -1) {
            attrStart = nameAttrStart;
          }
          if (attrStart != -1) {

            String attrElemTrail = elemStringBuffer.substring(attrStart);
            int attrLength = attrElemTrail.indexOf(" ");
            if (attrLength == -1) {
              attrLength = attrElemTrail.indexOf("/>");
            }
            String attr = elemStringBuffer.substring(attrStart, attrStart + attrLength);

            elemStringBuffer.delete(attrStart, attrStart + attrLength);

            int newAttrstart = 0;
            int metaIndex = elemStringBuffer.indexOf("<meta");
            int audioIndex = elemStringBuffer.indexOf("<audio");
            if (metaIndex != -1) {
              newAttrstart = metaIndex + "<meta".length() + 1;
            } else if (audioIndex != -1) {
              newAttrstart = audioIndex + "<audio".length() + 1;
            }
            elemStringBuffer.insert(newAttrstart, attr + " ");
          }
          String element = elemStringBuffer.toString();
          bw.write(element + "\r\n");

          elemStringBuffer.setLength(0);
          elementComplete = false;
        } else if (!buildingElement) {
          bw.write(line + "\r\n");
        }

        line = br.readLine();
      } // move to the next line

      br.close();
      bw.flush();
      bw.close();
      FileUtils.copy(tempOutputFile, file);
      tempOutputFile.delete();
    } catch (IOException ioe) {
      throw ioe;
    }
  }
  protected boolean execute(Map<String, String> parameters) throws TransformerRunException {
    String inputXML = parameters.remove("xml");
    String factory = parameters.remove("factory");
    String out = parameters.remove("out");
    String copyReferring = parameters.remove("copyReferring");

    URL xsltURL = Stylesheets.get("dtbook2xhtml.xsl");
    File inFile = FilenameOrFileURI.toFile(inputXML);

    /*
     * Check if the doc is compound
     */
    try {
      NamespaceReporter nsr = new NamespaceReporter(inFile.toURI().toURL());
      if (nsr.getNamespaceURIs().contains(Namespaces.MATHML_NS_URI)) {
        this.sendMessage(
            i18n("CONTAINS_MATHML"), MessageEvent.Type.INFO, MessageEvent.Cause.SYSTEM);
        parameters.put("svg_mathml", "true");
      }

      if (nsr.getNamespaceURIs().contains(Namespaces.SVG_NS_URI)) {
        this.sendMessage(i18n("CONTAINS_SVG"), MessageEvent.Type.INFO, MessageEvent.Cause.SYSTEM);
        parameters.put("svg_mathml", "true");
      }
    } catch (Exception e) {
      this.sendMessage(
          i18n("ERROR", e.getMessage()), MessageEvent.Type.ERROR, MessageEvent.Cause.SYSTEM);
    }

    try {
      File outFile = FilenameOrFileURI.toFile(out);
      FileUtils.createDirectory(outFile.getParentFile());

      if ("true".equals(copyReferring)) {
        EFile eInFile = new EFile(inFile);
        String outFileName;
        Directory folder;
        if (outFile.isDirectory()) {
          folder = new Directory(outFile);
          outFileName = eInFile.getNameMinusExtension() + ".html";
        } else {
          folder = new Directory(outFile.getParentFile());
          outFileName = outFile.getName();
        }

        if (inFile.getParentFile().getCanonicalPath().equals(folder.getCanonicalPath())) {
          throw new TransformerRunException(i18n("INPUT_OUTPUT_SAME"));
        }
        Fileset fileset = this.buildFileSet(new File(inputXML));
        if (!parameters.containsKey("css_path")) {
          parameters.put("css_path", "default.css");
        }
        Map<String, Object> xslParams = new HashMap<String, Object>();
        xslParams.putAll(parameters);
        Stylesheet.apply(
            inputXML,
            xsltURL,
            new File(folder, outFileName).toString(),
            factory,
            xslParams,
            CatalogEntityResolver.getInstance());

        URL url2 = Css.get(Css.DocumentType.D202_XHTML);
        folder.writeToFile(parameters.get("css_path"), url2.openStream());

        for (Iterator<FilesetFile> it = fileset.getLocalMembers().iterator(); it.hasNext(); ) {
          FilesetFile fsf = it.next();
          if (fsf instanceof ImageFile) {
            FileUtils.copyChild(fsf.getFile(), folder, inFile.getParentFile());
          }
        }
      } else {
        Map<String, Object> xslParams = new HashMap<String, Object>();
        xslParams.putAll(parameters);
        Stylesheet.apply(
            inputXML, xsltURL, out, factory, xslParams, CatalogEntityResolver.getInstance());
      }

      if (parameters.containsKey("svg_mathml")) {
        // some post-xslt namespace cleanup.
        Map<String, Object> domConfigMap =
            LSParserPool.getInstance().getDefaultPropertyMap(Boolean.FALSE);
        domConfigMap.put("resource-resolver", CatalogEntityResolver.getInstance());
        LSParser parser = LSParserPool.getInstance().acquire(domConfigMap);
        DOMConfiguration domConfig = parser.getDomConfig();
        domConfig.setParameter("error-handler", this);
        Document doc = parser.parseURI(outFile.toURI().toString());

        SimpleNamespaceContext snc = new SimpleNamespaceContext();
        snc.declareNamespace("m", Namespaces.MATHML_NS_URI);
        NodeList math = XPathUtils.selectNodes(doc.getDocumentElement(), "//m:*", snc);
        for (int i = 0; i < math.getLength(); i++) {
          try {
            Node m = math.item(i);
            m.setPrefix("");
            if (m.getLocalName().equals("math")) {
              m.getAttributes().removeNamedItem("xmlns:dtbook");
              m.getAttributes().removeNamedItem("xmlns:m");
              Node c = m.getAttributes().getNamedItem("xmlns");
              c.setNodeValue(Namespaces.MATHML_NS_URI);
            }
          } catch (Exception e) {
            this.sendMessage(e.getMessage(), MessageEvent.Type.ERROR);
          }
        }

        Map<String, Object> props = new HashMap<String, Object>();
        props.put(
            "namespaces", Boolean.FALSE); // temp because of attributeNS bug(?) in Xerces DOM3LS				
        props.put("error-handler", this);
        // props.put("format-pretty-print", Boolean.TRUE);
        Serializer.serialize(doc, outFile, "utf-8", props);
      }

    } catch (XSLTException e) {
      throw new TransformerRunException(e.getMessage(), e);
    } catch (CatalogExceptionNotRecoverable e) {
      throw new TransformerRunException(e.getMessage(), e);
    } catch (FilesetFatalException e) {
      throw new TransformerRunException(e.getMessage(), e);
    } catch (IOException e) {
      throw new TransformerRunException(e.getMessage(), e);
    }

    return true;
  }