diff -pruN 1.7.2-1.1/.github/FUNDING.yml 1.8-0.1/.github/FUNDING.yml
--- 1.7.2-1.1/.github/FUNDING.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.8-0.1/.github/FUNDING.yml	2025-01-11 18:08:08.000000000 +0000
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+patreon: LINUXABI
+custom: https://abi-laboratory.pro/?view=donate
diff -pruN 1.7.2-1.1/INSTALL 1.8-0.1/INSTALL
--- 1.7.2-1.1/INSTALL	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/INSTALL	2025-01-11 18:08:08.000000000 +0000
@@ -1,13 +1,13 @@
 
-Copyright (C) 2012-2016 Andrey Ponomarenko's ABI Laboratory
+Copyright (C) 2012-2025 Andrey Ponomarenko's ABI Laboratory
 All rights reserved.
 
 
 RELEASE INFORMATION
 
 Project:           Package Changes Analyzer (pkgdiff)
-Version:           1.7.2
-Date:              2016-03-18
+Version:           1.8
+Date:              2025-01-11
 
 
 This file explains how to install and setup environment
@@ -30,6 +30,7 @@ Content:
    3. GNU Wdiff
    4. GNU Awk
    5. GNU Binutils (readelf)
+   6. Perl-File-LibMagic
 
 1.1 Analysis of RPM packages
 
diff -pruN 1.7.2-1.1/README 1.8-0.1/README
--- 1.7.2-1.1/README	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/README	1970-01-01 00:00:00.000000000 +0000
@@ -1,29 +0,0 @@
-NAME:
-  Package Changes Analyzer (pkgdiff) - a tool for visualizing changes in Linux software packages (RPM, DEB, TAR.GZ, etc). The tool is intended for Linux maintainers who are interested in ensuring compatibility of old and new versions of packages.
-  
-  Sample report: http://abi-laboratory.pro/tracker/package_diff/libssh/0.6.5/0.7.0/report.html
-  
-  The tool is developed by Andrey Ponomarenko: http://abi-laboratory.pro/
-
-INSTALL:
-  sudo make install prefix=/usr
-
-REQUIRES:
-  Perl 5
-  GNU Diff
-  GNU Wdiff
-  GNU Awk
-  GNU Binutils
-
-USAGE:
-  pkgdiff PKG1 PKG2
-
-EXAMPLE:
-  pkgdiff libssh-0.6.5.tar.xz libssh-0.7.0.tar.xz
-
-ADV. USAGE:
-  For advanced usage, see output of --help option
-
-SUGGESTS:
-  ABI Compliance Checker 1.99.1 or newer: https://github.com/lvc/abi-compliance-checker/
-  ABI Dumper 0.97 or newer: https://github.com/lvc/abi-dumper
diff -pruN 1.7.2-1.1/README.md 1.8-0.1/README.md
--- 1.7.2-1.1/README.md	1970-01-01 00:00:00.000000000 +0000
+++ 1.8-0.1/README.md	2025-01-11 18:08:08.000000000 +0000
@@ -0,0 +1,66 @@
+PkgDiff 1.8
+===========
+
+Package Changes Analyzer (pkgdiff) — a tool for visualizing changes in Linux software packages (RPM, DEB, TAR.GZ, etc).
+
+Contents
+--------
+
+1. [ About   ](#about)
+2. [ Install ](#install)
+3. [ Usage   ](#usage)
+
+About
+-----
+
+The tool is intended for Linux maintainers who are interested in ensuring compatibility of old and new versions of packages. The tool can compare directories as well (with the help of the -d option).
+
+Sample report: https://abi-laboratory.pro/tracker/package_diff/libssh/0.6.5/0.7.0/report.html
+
+The tool is developed by Andrey Ponomarenko.
+
+Install
+-------
+
+    sudo make install prefix=/usr
+
+###### Requires
+
+* Perl 5
+* GNU Diff
+* GNU Wdiff
+* GNU Awk
+* GNU Binutils
+* Perl-File-LibMagic
+
+###### Suggests
+
+* ABI Compliance Checker 1.99.1 or newer: https://github.com/lvc/abi-compliance-checker/
+* ABI Dumper 0.97 or newer: https://github.com/lvc/abi-dumper
+
+Usage
+-----
+
+    pkgdiff PKG1 PKG2 [options]
+
+###### Example
+
+    pkgdiff libssh-0.6.5.tar.xz libssh-0.7.0.tar.xz
+
+###### Compare directories
+
+    pkgdiff -d DIR1/ DIR2/ [options]
+
+###### Useful options
+
+| Option              | Meaning                                      |
+|---------------------|----------------------------------------------|
+| -c/-hide-unchanged  | Don't show unchanged files in the report     |
+| -list-added-removed | Show content of added and removed text files |
+| -skip-pattern REGEX | Don't check files matching REGEX             |
+| -tmp-dir DIR        | Use custom temp directory                    |
+| -d/-directories     | Compare directories instead of packages      |
+
+###### Adv. usage
+
+For advanced usage, see output of -help option.
diff -pruN 1.7.2-1.1/debian/changelog 1.8-0.1/debian/changelog
--- 1.7.2-1.1/debian/changelog	2022-06-14 13:16:00.000000000 +0000
+++ 1.8-0.1/debian/changelog	2025-08-24 06:32:29.000000000 +0000
@@ -1,3 +1,16 @@
+pkgdiff (1.8-0.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * New upstream version
+    Closes: #947345
+  * Point Vcs fields to Salsa
+  * Fix watch file
+  * Standards-Version: 4.7.2 (routine-update)
+  * debhelper-compat 13 (routine-update)
+  * Add debian/upstream/metadata
+
+ -- Andreas Tille <tille@debian.org>  Sun, 24 Aug 2025 08:32:29 +0200
+
 pkgdiff (1.7.2-1.1) unstable; urgency=medium
 
   * Non maintainer upload by the Reproducible Builds team.
diff -pruN 1.7.2-1.1/debian/compat 1.8-0.1/debian/compat
--- 1.7.2-1.1/debian/compat	2016-03-21 16:02:42.000000000 +0000
+++ 1.8-0.1/debian/compat	1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-9
diff -pruN 1.7.2-1.1/debian/control 1.8-0.1/debian/control
--- 1.7.2-1.1/debian/control	2016-03-22 11:52:38.000000000 +0000
+++ 1.8-0.1/debian/control	2025-08-24 06:32:29.000000000 +0000
@@ -2,11 +2,11 @@ Source: pkgdiff
 Section: devel
 Priority: optional
 Maintainer: Peter Spiess-Knafl <dev@spiessknafl.at>
-Build-Depends: debhelper (>= 9), help2man
-Standards-Version: 3.9.7
+Build-Depends: debhelper-compat (= 13), help2man
+Standards-Version: 4.7.2
+Vcs-Browser: https://salsa.debian.org/debian/pkgdiff
+Vcs-Git: https://salsa.debian.org/debian/pkgdiff.git
 Homepage: https://github.com/lvc/pkgdiff
-Vcs-Git: https://anonscm.debian.org/git/collab-maint/pkgdiff.git
-Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/pkgdiff.git/
 
 Package: pkgdiff
 Architecture: all
diff -pruN 1.7.2-1.1/debian/upstream/metadata 1.8-0.1/debian/upstream/metadata
--- 1.7.2-1.1/debian/upstream/metadata	1970-01-01 00:00:00.000000000 +0000
+++ 1.8-0.1/debian/upstream/metadata	2025-08-24 06:32:29.000000000 +0000
@@ -0,0 +1,4 @@
+---
+Bug-Database: https://github.com/lvc/pkgdiff/issues
+Repository: https://github.com/lvc/pkgdiff.git
+Repository-Browse: https://github.com/lvc/pkgdiff
diff -pruN 1.7.2-1.1/debian/watch 1.8-0.1/debian/watch
--- 1.7.2-1.1/debian/watch	2016-03-21 16:02:42.000000000 +0000
+++ 1.8-0.1/debian/watch	2025-08-24 06:32:29.000000000 +0000
@@ -1,3 +1,4 @@
-version=3
-https://github.com/lvc/pkgdiff/releases \
-.*/archive/(.+)\.tar\.gz
+version=4
+
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \
+   https://github.com/lvc/pkgdiff/tags (?:.*?/)?v?(\d[\d.]*)\.tar\.gz
diff -pruN 1.7.2-1.1/doc/Readme.html 1.8-0.1/doc/Readme.html
--- 1.7.2-1.1/doc/Readme.html	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/doc/Readme.html	1970-01-01 00:00:00.000000000 +0000
@@ -1,478 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <meta name="keywords" content="pkgdiff, rpm, deb, diff, changes" />
-  <meta name="description" content="A tool for visualizing changes in Linux software packages" />
-  <title>pkgdiff - Package Changes Analyzer</title>
-
-  <style type="text/css">
-    body {
-      margin-top: 1.0em;
-      background-color: #deeef7;
-      font-family: Helvetica, Arial, FreeSans, san-serif;
-      color: #000000;
-    }
-    #container {
-      margin: 0 auto;
-      width: 700px;
-    }
-    h1 { font-size: 3.8em; color: #211108; margin-bottom: 3px;margin-top:0px;padding-top:0px;}
-    h1 .small { font-size: 0.4em; }
-    h1 a { text-decoration: none }
-    h2 { font-size: 1.5em; color: #211108; }
-    h3 { text-align: center; color: #211108; }
-    a { color: #211108; }
-    .description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
-    .download { float: right; }
-    pre { background: #000; color: #fff; padding: 15px;}
-    hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
-    .footer { text-align:center; padding-top:30px; font-style: italic; }
-  </style>
-
-<script type="text/javascript">
-
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-19501755-2']);
-  _gaq.push(['_trackPageview']);
-
-  (function() {
-    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-  })();
-
-</script>
-
-</head>
-
-<body>
-  <a href="https://github.com/lvc/pkgdiff"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
-
-  <div id="container">
-
-    <div class="download">
-      <a href="https://github.com/lvc/pkgdiff/zipball/master">
-        <img style="border: 0;" width="90" src="https://github.com/images/modules/download/zip.png" alt="" /></a>
-      <a href="https://github.com/lvc/pkgdiff/tarball/master">
-        <img style="border: 0;" width="90" src="https://github.com/images/modules/download/tar.png" alt="" /></a>
-    </div>
-   
-    <h1><a href="https://github.com/lvc/pkgdiff">pkgdiff</a></h1>
-
-    <div class="description">
-      A tool for visualizing changes in Linux software packages
-    </div>
-
-    
-      <p>Package Changes Analyzer (pkgdiff) is a tool for visualizing changes in Linux software packages (RPM, DEB, TAR.GZ, etc). The tool is intended for Linux maintainers who are interested in ensuring compatibility of old and new versions of packages.</p>
-      
-      <p/>
-      The tool is developed by Andrey Ponomarenko: <a href='http://abi-laboratory.pro/'>http://abi-laboratory.pro/</a>
-
-<table style='border:1px solid grey;'><tr><td>
-<div>Table of Contents</div>
-<ul>
-<li><a href="#Downloads" rel="nofollow">Downloads</a></li>
-<li><a href="#License" rel="nofollow">License</a></li>
-<li><a href="#Supported_Platforms" rel="nofollow">Supported Platforms</a></li>
-<li><a href="#Dependencies" rel="nofollow">Dependencies</a></li>
-<li><a href="#Installation" rel="nofollow">Installation</a></li>
-<li><a href="#Usage" rel="nofollow">Usage</a></li>
-<li><a href="#Examples" rel="nofollow">Examples</a></li>
-<li><a href="#Adv_Usage" rel="nofollow">Adv. Usage</a></li>
-<li><a href="#Adv_Examples" rel="nofollow">Adv. Examples</a></li>
-<li><a href="#Bugs" rel="nofollow">Bugs</a></li>
-<li><a href="#Maintainers" rel="nofollow">Maintainers</a></li>
-<li><a href="#ChangeLog" rel="nofollow">Changes</a></li>
-</ul>
-</td></tr></table>
-
-<a name="Downloads"></a>
-<h2>Downloads</h2>
-<p>All releases can be downloaded from <a href="https://github.com/lvc/pkgdiff/">this page</a>.</p>
-
-<p>Latest release: <a href="https://github.com/lvc/pkgdiff/archive/1.7.2.tar.gz">pkgdiff-1.7.2.tar.gz</a></p>
-
-<p>Read-only access to the latest development version:</p>
-
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;git clone git://github.com/lvc/pkgdiff&nbsp;</code>
-
-<a name="License"></a>
-<h2>License</h2>
-<p>This program is free software. You may use, redistribute and/or modify it under the terms of the <a href="http://www.gnu.org/licenses/" rel="nofollow">GNU GPL</a></p>
-
-<a name="Supported_Platforms"></a>
-<h2>Supported Platforms</h2>
-GNU/Linux, FreeBSD, Mac OS X
-    
-<a name="Dependencies"></a>
-<h2>Dependencies</h2>
-Requires:
-<ul>
-<li>
-  <a href="http://www.perl.org/" rel="nofollow">Perl 5</a> (5.8 or newer)
-</li>
-<li>
-  <a href="http://www.gnu.org/software/diffutils/" rel="nofollow">GNU Diff</a>
-</li>
-<li>
-  <a href="http://www.gnu.org/software/wdiff/" rel="nofollow">GNU Wdiff</a>
-</li>
-<li>
-  <a href="http://www.gnu.org/software/gawk/" rel="nofollow">GNU Awk</a>
-</li>
-<li>
-  <a href="http://www.gnu.org/software/binutils/" rel="nofollow">GNU Binutils</a> (readelf)
-</li>
-<li>
-  <a href="http://rpm.org/" rel="nofollow">RPM</a> (rpm2cpio, rpm) for analysis of RPM packages
-</li>
-<li>
-  <a href="http://packages.debian.org/squeeze/dpkg" rel="nofollow">DPKG</a> (dpkg-deb, dpkg) for analysis of DEB packages
-</li>
-</ul>
-
-Suggests:
-<ul>
-<li>
-  <a href="https://github.com/lvc/abi-compliance-checker/">ABI Compliance Checker</a> (1.99.1 or newer)
-</li>
-<li>
-  <a href="https://github.com/lvc/abi-dumper/">ABI Dumper</a> (0.97 or newer)
-</li>
-</ul>
-    
-<a name="Installation"></a>
-<h2>Installation</h2>
-<p>The tool is <b>ready-to-use</b> after extracting the archive.</p>
-
-<p>You can also use a <b>Makefile</b> to install the tool into the system:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;sudo make install prefix=PREFIX [/usr, /usr/local]&nbsp;</code>
-<p>This command will install a  <code>pkgdiff</code>  program to the <code>PREFIX/bin</code> system directory and private modules into the <code>PREFIX/share</code>.</p>
-
-<a name="Usage"></a>
-<h2>Usage</h2>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff PKG1 PKG2&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/&lt;pkg&gt;/&lt;v1&gt;_to_&lt;v2&gt;/changes_report.html&nbsp;</code>
-
-<a name="Examples"></a>
-<h2>Examples</h2>
-<p>Compare 0.4.1 and 0.8.1 versions of libqb SRPM-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libqb-0.4.1-2.fc15.src.rpm libqb-0.8.1-2.fc16.src.rpm&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libqb/0.4.1_to_0.8.1/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/libqb/0.4.1_to_0.8.1/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<br/><br/>
-<p>Compare 0.10.23 and 0.10.32 versions of gstreamer TXZ-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff gstreamer-0.10.23-i486-1.txz gstreamer-0.10.32-i486-1.txz&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/gstreamer/0.10.23-i486-1_to_0.10.32-i486-1/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/gstreamer/0.10.23-i486-1_to_0.10.32-i486-1/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<br/><br/>
-<p>Compare 0.3.4 and 0.4.0 versions of libssh TAR.GZ-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libssh-0.3.4.tar.gz libssh-0.4.0.tar.gz&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libssh/0.3.4_to_0.4.0/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/libssh/0.3.4_to_0.4.0/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<br/><br/>
-<p>Compare 1.10.2 and 1.12.2 versions of cairo DEB-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libcairo2-dev_1.10.2-6.1_i386.deb libcairo2-dev_1.12.2-1_i386.deb&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libcairo2-dev/1.10.2-6.1_to_1.12.2-1/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/libcairo2-dev/1.10.2-6.1_to_1.12.2-1/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<br/><br/>
-<p>Compare 2.24.1 and 2.28.8 versions of glib RPM-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libglib2.0-devel-2.24.1.i586.rpm libglib2.0-devel-2.28.8.i586.rpm&nbsp;</code>
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libglib2.0-devel/2.24.1_to_2.28.8/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/libglib2.0-devel/2.24.1_to_2.28.8/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<a name="Adv_Usage"></a>
-<h2>Adv. Usage</h2>
-<p>For advanced usage, see output of --help option:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff --help&nbsp;</code>
-<p>If you need to analyze a group of packages then you can create an XML-descriptor of this group (OLD.xml file):</p>
-
-<div style='padding-left:20px;border:1px solid black;width:70%;'>
-  &lt;version&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;2.24.1<br/>
-  &lt;/version&gt;<br/><br/>
-
-  &lt;group&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libglib<br/>
-  &lt;/group&gt;<br/><br/>
-
-  &lt;packages&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libglib2.0-devel-2.24.1-1mdv2010.1.i586.rpm<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libglib2.0_0-2.24.1-1mdv2010.1.i586.rpm<br/>
-  &lt;/packages&gt;<br/>
-</div>
-
-<p>And then pass XML-descriptors of old and new versions of a group to the tool:</p>
-
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff OLD.xml NEW.xml&nbsp;</code>
-
-<p>The HTML report will be generated to:</p>
-
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/&lt;group&gt;/&lt;v1&gt;_to_&lt;v2&gt;/changes_report.html&nbsp;</code>
-
-<a name="Adv_Examples"></a>
-<h2>Adv. Examples</h2>
-<p>Compare 2.3.12 and 2.4.5 versions of libfreetype6 group of RPM-packages:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff 2.3.12.xml 2.4.5.xml&nbsp;</code>
-
-<p>File 2.3.12.xml:</p>
-<div style='padding-left:20px;border:1px solid black;width:70%;'>
-  &lt;version&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;2.3.12<br/>
-  &lt;/version&gt;<br/><br/>
-
-  &lt;group&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6<br/>
-  &lt;/group&gt;<br/><br/>
-
-  &lt;packages&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-2.3.12-1mdv2010.1.i586.rpm<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-devel-2.3.12-1mdv2010.1.i586.rpm<br/>
-  &lt;/packages&gt;<br/>
-</div>
-
-<p>File 2.4.5.xml:</p>
-<div style='padding-left:20px;border:1px solid black;width:70%;'>
-  &lt;version&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;2.4.5<br/>
-  &lt;/version&gt;<br/><br/>
-
-  &lt;group&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6<br/>
-  &lt;/group&gt;<br/><br/>
-
-  &lt;packages&gt;<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-2.4.5-2-mdv2011.0.i586.rpm<br/>
-      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-devel-2.4.5-2-mdv2011.0.i586.rpm<br/>
-  &lt;/packages&gt;<br/>
-</div>
-
-<p>The HTML report will be generated to:</p>
-<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libfreetype6/2.3.12_to_2.4.5/<a style='color:Blue;' href="http://lvc.github.com/pkgdiff/pkgdiff_reports/libfreetype6/2.3.12_to_2.4.5/changes_report.html">changes_report.html</a>&nbsp;</code>
-
-<a name="Bugs"></a>
-<h2>Bugs</h2>
-<p>Please post your bug reports, feature requests and questions to the <a href="https://github.com/lvc/pkgdiff/issues" rel="nofollow">issue tracker</a>.</p>
-
-<a name="Maintainers"></a>
-<h2>Maintainers</h2>
-The tool is developed by <a href="http://www.linkedin.com/pub/andrey-ponomarenko/67/366/818" rel="nofollow">Andrey Ponomarenko</a>.
-
-<a name="ChangeLog"></a>
-<h2>Changes</h2>
-
-<b>Version 1.7.2 (March 18, 2016)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Ability to download plain-text added/removed patches from the report
-    </li>
-</ul>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Do not show time stamp in the report
-    </li>
-    <li>
-        Fixed removal of tmp directory in the rfcdiff-1.41-CUSTOM.sh
-    </li>
-</ul>
-<br/>
-
-<b>Version 1.7.1 (December 11, 2015)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Added -skip-pattern option: skip checking of paths within archives matching a regex
-    </li>
-</ul>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Fixed incompatibility with the latest versions of the ABICC tool
-    </li>
-    <li>
-        Fixed comparison of the RPM/Deb packages info
-    </li>
-</ul>
-<br/>
-
-<b>Version 1.7.0 (October 18, 2015)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Added -d option: compare directories instead of packages
-    </li>
-    <li>
-        Added -list-added-removed option: show content of added/removed text files
-    </li>
-    <li>
-        Added -vnum1 and -vnum2 options: set version numbers of input packages
-    </li>
-    <li>
-        Added -title option: set name of the package in the title of the report
-    </li>
-    <li>
-        Added -skip-subarchives option: skip checking of archives inside packages
-    </li>
-</ul>
-<br/>
-
-<b>Version 1.6.4 (September 08, 2015)</b><br/>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Fixed style of the report
-    </li>
-    <li>
-        Fixed install permissions
-    </li>
-    <li>
-        Fixed errors when comparing man pages
-    </li>
-    <li>
-        Added check for wdiff
-    </li>
-    <li>
-        Simplified Makefile
-    </li>
-</ul>
-
-<br/>
-
-<b>Version 1.6.3 (November 05, 2014)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Added -hide-unchanged option: don't show unchanged files in the report
-    </li>
-    <li>
-        Show change rate in the extra info files.xml (moved, changed, renamed)
-    </li>
-    <li>
-        Check if we can remove a common prefix from files of both packages
-    </li>
-    <li>
-        Encoding of diff reports has been changed to utf-8
-    </li>
-</ul>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Fixed a problem with spaces in package name
-    </li>
-    <li>
-        Added -o option to unzip command
-    </li>
-    <li>
-        Fixed -tmp-dir option
-    </li>
-</ul>
-
-<br/>
-
-<b>Version 1.6 (June 07, 2013)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        ABI compatibility check for shared objects and kernel modules containing DWARF debugging information (in <i>-details</i> mode)
-    </li>
-    <li>
-        ABI status section in the report for debuginfo-packages
-    </li>
-    <li>
-        Suggests ABI Compliance Checker 1.99.1
-    </li>
-    <li>
-        Suggests ABI Dumper 0.97
-    </li>
-</ul>
-
-<br/>
-
-<b>Version 1.5 (April 04, 2013)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Added -extra-info option to dump extra analysis information
-    </li>
-    <li>
-        Improved identification of moved files
-    </li>
-    <li>
-        Classifying files by magic bytes
-    </li>
-    <li>
-        Compare public symbols in shared objects before detailed comparison
-    </li>
-    <li>
-        Added statistics comment line in the report
-    </li>
-    <li>
-        Support for more file types
-    </li>
-</ul>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Corrected Makefile
-    </li>
-    <li>
-        Corrected parser of package version
-    </li>
-</ul>
-
-<br/>
-
-<b>Version 1.4.1 (December 14, 2012)</b><br/>
-<b>Bug Fixes</b>
-<ul>
-    <li>
-        Corrected parser of package version
-    </li>
-    <li>
-        Opening file diffs in a separate window
-    </li>
-</ul>
-
-<br/>
-
-<b>Version 1.4 (October 25, 2012)</b><br/>
-<b>New Features</b>
-<ul>
-    <li>
-        Sorting by status, delta and file name in the report
-    </li>
-    <li>
-        New -open option to open report in the default browser
-    </li>
-    <li>
-        Printing of estimated change rate to the console
-    </li>
-    <li>
-        Simplified usage: pkgdiff PKG1 PKG2
-    </li>
-    <li>
-        Support for Mac OS X
-    </li>
-    <li>
-        Support for more file formats
-    </li>
-</ul>
-
-    <div class="footer">
-      get the source code on GitHub : <a href="https://github.com/lvc/pkgdiff">lvc/pkgdiff</a>
-    </div>
-    <div style="height:350px;"></div>
-
-  </div>
-</body>
-</html>
diff -pruN 1.7.2-1.1/doc/index.html 1.8-0.1/doc/index.html
--- 1.7.2-1.1/doc/index.html	1970-01-01 00:00:00.000000000 +0000
+++ 1.8-0.1/doc/index.html	2025-01-11 18:08:08.000000000 +0000
@@ -0,0 +1,502 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <meta name="keywords" content="pkgdiff, rpm, deb, diff, changes" />
+  <meta name="description" content="A tool for visualizing changes in Linux software packages" />
+  <title>pkgdiff - Package Changes Analyzer</title>
+
+  <style type="text/css">
+    body {
+      margin-top: 1.0em;
+      background-color: #deeef7;
+      font-family: Helvetica, Arial, FreeSans, san-serif;
+      color: #000000;
+    }
+    #container {
+      margin: 0 auto;
+      width: 700px;
+    }
+    h1 { font-size: 3.8em; color: #211108; margin-bottom: 3px;margin-top:0px;padding-top:0px;}
+    h1 .small { font-size: 0.4em; }
+    h1 a { text-decoration: none }
+    h2 { font-size: 1.5em; color: #211108; }
+    h3 { text-align: center; color: #211108; }
+    a { color: #211108; }
+    .description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
+    .download { float: right; }
+    pre { background: #000; color: #fff; padding: 15px;}
+    hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+    .footer { text-align:center; padding-top:30px; font-style: italic; }
+  </style>
+
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-19501755-2']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+</head>
+
+<body>
+  <a href="https://github.com/lvc/pkgdiff"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
+
+  <div id="container">
+
+    <div class="download">
+      <a href="https://github.com/lvc/pkgdiff/zipball/master">
+        <img style="border: 0;" width="90" src="https://github.com/images/modules/download/zip.png" alt="" /></a>
+      <a href="https://github.com/lvc/pkgdiff/tarball/master">
+        <img style="border: 0;" width="90" src="https://github.com/images/modules/download/tar.png" alt="" /></a>
+    </div>
+   
+    <h1><a href="https://github.com/lvc/pkgdiff">pkgdiff</a></h1>
+
+    <div class="description">
+      A tool for visualizing changes in Linux software packages
+    </div>
+
+    
+      <p>Package Changes Analyzer (pkgdiff) is a tool for visualizing changes in Linux software packages (RPM, DEB, TAR.GZ, etc). The tool is intended for Linux maintainers who are interested in ensuring compatibility of old and new versions of packages.</p>
+      
+      <p/>
+      The tool is developed by Andrey Ponomarenko: <a href='https://abi-laboratory.pro/'>https://abi-laboratory.pro/</a>
+
+<table style='border:1px solid grey;'><tr><td>
+<div>Table of Contents</div>
+<ul>
+<li><a href="#Downloads" rel="nofollow">Downloads</a></li>
+<li><a href="#License" rel="nofollow">License</a></li>
+<li><a href="#Supported_Platforms" rel="nofollow">Supported Platforms</a></li>
+<li><a href="#Dependencies" rel="nofollow">Dependencies</a></li>
+<li><a href="#Installation" rel="nofollow">Installation</a></li>
+<li><a href="#Usage" rel="nofollow">Usage</a></li>
+<li><a href="#Examples" rel="nofollow">Examples</a></li>
+<li><a href="#Adv_Usage" rel="nofollow">Adv. Usage</a></li>
+<li><a href="#Adv_Examples" rel="nofollow">Adv. Examples</a></li>
+<li><a href="#Bugs" rel="nofollow">Bugs</a></li>
+<li><a href="#Maintainers" rel="nofollow">Maintainers</a></li>
+<li><a href="#ChangeLog" rel="nofollow">Changes</a></li>
+</ul>
+</td></tr></table>
+
+<a name="Downloads"></a>
+<h2>Downloads</h2>
+<p>All releases can be downloaded from <a href="https://github.com/lvc/pkgdiff/releases">this page</a>.</p>
+
+<p>Latest release: <a href="https://github.com/lvc/pkgdiff/archive/1.7.2.tar.gz">pkgdiff-1.7.2.tar.gz</a></p>
+
+<p>Read-only access to the latest development version:</p>
+
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;git clone git://github.com/lvc/pkgdiff&nbsp;</code>
+
+<a name="License"></a>
+<h2>License</h2>
+<p>This program is free software. You may use, redistribute and/or modify it under the terms of the <a href="http://www.gnu.org/licenses/" rel="nofollow">GNU GPL</a></p>
+
+<a name="Supported_Platforms"></a>
+<h2>Supported Platforms</h2>
+GNU/Linux, FreeBSD, Mac OS X
+    
+<a name="Dependencies"></a>
+<h2>Dependencies</h2>
+Requires:
+<ul>
+<li>
+  <a href="http://www.perl.org/" rel="nofollow">Perl 5</a> (5.8 or newer)
+</li>
+<li>
+  <a href="http://www.gnu.org/software/diffutils/" rel="nofollow">GNU Diff</a>
+</li>
+<li>
+  <a href="http://www.gnu.org/software/wdiff/" rel="nofollow">GNU Wdiff</a>
+</li>
+<li>
+  <a href="http://www.gnu.org/software/gawk/" rel="nofollow">GNU Awk</a>
+</li>
+<li>
+  <a href="http://www.gnu.org/software/binutils/" rel="nofollow">GNU Binutils</a> (readelf)
+</li>
+<li>
+  <a href="http://rpm.org/" rel="nofollow">RPM</a> (rpm2cpio, rpm) for analysis of RPM packages
+</li>
+<li>
+  <a href="http://packages.debian.org/squeeze/dpkg" rel="nofollow">DPKG</a> (dpkg-deb, dpkg) for analysis of DEB packages
+</li>
+</ul>
+
+Suggests:
+<ul>
+<li>
+  <a href="https://github.com/lvc/abi-compliance-checker/">ABI Compliance Checker</a> (1.99.1 or newer)
+</li>
+<li>
+  <a href="https://github.com/lvc/abi-dumper/">ABI Dumper</a> (0.97 or newer)
+</li>
+</ul>
+    
+<a name="Installation"></a>
+<h2>Installation</h2>
+<p>The tool is <b>ready-to-use</b> after extracting the archive.</p>
+
+<p>You can also use a <b>Makefile</b> to install the tool into the system:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;sudo make install prefix=PREFIX [/usr, /usr/local]&nbsp;</code>
+<p>This command will install a  <code>pkgdiff</code>  program to the <code>PREFIX/bin</code> system directory and private modules into the <code>PREFIX/share</code>.</p>
+
+<a name="Usage"></a>
+<h2>Usage</h2>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff PKG1 PKG2&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/&lt;pkg&gt;/&lt;v1&gt;_to_&lt;v2&gt;/changes_report.html&nbsp;</code>
+
+<a name="Examples"></a>
+<h2>Examples</h2>
+<p>Compare 0.4.1 and 0.8.1 versions of libqb SRPM-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libqb-0.4.1-2.fc15.src.rpm libqb-0.8.1-2.fc16.src.rpm&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libqb/0.4.1_to_0.8.1/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/libqb/0.4.1_to_0.8.1/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<br/><br/>
+<p>Compare 0.10.23 and 0.10.32 versions of gstreamer TXZ-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff gstreamer-0.10.23-i486-1.txz gstreamer-0.10.32-i486-1.txz&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/gstreamer/0.10.23-i486-1_to_0.10.32-i486-1/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/gstreamer/0.10.23-i486-1_to_0.10.32-i486-1/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<br/><br/>
+<p>Compare 0.3.4 and 0.4.0 versions of libssh TAR.GZ-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libssh-0.3.4.tar.gz libssh-0.4.0.tar.gz&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libssh/0.3.4_to_0.4.0/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/libssh/0.3.4_to_0.4.0/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<br/><br/>
+<p>Compare 1.10.2 and 1.12.2 versions of cairo DEB-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libcairo2-dev_1.10.2-6.1_i386.deb libcairo2-dev_1.12.2-1_i386.deb&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libcairo2-dev/1.10.2-6.1_to_1.12.2-1/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/libcairo2-dev/1.10.2-6.1_to_1.12.2-1/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<br/><br/>
+<p>Compare 2.24.1 and 2.28.8 versions of glib RPM-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff libglib2.0-devel-2.24.1.i586.rpm libglib2.0-devel-2.28.8.i586.rpm&nbsp;</code>
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libglib2.0-devel/2.24.1_to_2.28.8/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/libglib2.0-devel/2.24.1_to_2.28.8/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<a name="Adv_Usage"></a>
+<h2>Adv. Usage</h2>
+<p>For advanced usage, see output of --help option:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff --help&nbsp;</code>
+<p>If you need to analyze a group of packages then you can create an XML-descriptor of this group (OLD.xml file):</p>
+
+<div style='padding-left:20px;border:1px solid black;width:70%;'>
+  &lt;version&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;2.24.1<br/>
+  &lt;/version&gt;<br/><br/>
+
+  &lt;group&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libglib<br/>
+  &lt;/group&gt;<br/><br/>
+
+  &lt;packages&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libglib2.0-devel-2.24.1-1mdv2010.1.i586.rpm<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libglib2.0_0-2.24.1-1mdv2010.1.i586.rpm<br/>
+  &lt;/packages&gt;<br/>
+</div>
+
+<p>And then pass XML-descriptors of old and new versions of a group to the tool:</p>
+
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff OLD.xml NEW.xml&nbsp;</code>
+
+<p>The HTML report will be generated to:</p>
+
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/&lt;group&gt;/&lt;v1&gt;_to_&lt;v2&gt;/changes_report.html&nbsp;</code>
+
+<a name="Adv_Examples"></a>
+<h2>Adv. Examples</h2>
+<p>Compare 2.3.12 and 2.4.5 versions of libfreetype6 group of RPM-packages:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff 2.3.12.xml 2.4.5.xml&nbsp;</code>
+
+<p>File 2.3.12.xml:</p>
+<div style='padding-left:20px;border:1px solid black;width:70%;'>
+  &lt;version&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;2.3.12<br/>
+  &lt;/version&gt;<br/><br/>
+
+  &lt;group&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6<br/>
+  &lt;/group&gt;<br/><br/>
+
+  &lt;packages&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-2.3.12-1mdv2010.1.i586.rpm<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-devel-2.3.12-1mdv2010.1.i586.rpm<br/>
+  &lt;/packages&gt;<br/>
+</div>
+
+<p>File 2.4.5.xml:</p>
+<div style='padding-left:20px;border:1px solid black;width:70%;'>
+  &lt;version&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;2.4.5<br/>
+  &lt;/version&gt;<br/><br/>
+
+  &lt;group&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6<br/>
+  &lt;/group&gt;<br/><br/>
+
+  &lt;packages&gt;<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-2.4.5-2-mdv2011.0.i586.rpm<br/>
+      &nbsp;&nbsp;&nbsp;&nbsp;libfreetype6-devel-2.4.5-2-mdv2011.0.i586.rpm<br/>
+  &lt;/packages&gt;<br/>
+</div>
+
+<p>The HTML report will be generated to:</p>
+<code style="border: dashed 1px gray; background-color: #f0f0f0;">&nbsp;pkgdiff_reports/libfreetype6/2.3.12_to_2.4.5/<a style='color:Blue;' href="http://lvc.github.io/pkgdiff/pkgdiff_reports/libfreetype6/2.3.12_to_2.4.5/changes_report.html">changes_report.html</a>&nbsp;</code>
+
+<a name="Bugs"></a>
+<h2>Bugs</h2>
+<p>Please post your bug reports, feature requests and questions to the <a href="https://github.com/lvc/pkgdiff/issues" rel="nofollow">issue tracker</a>.</p>
+
+<a name="Maintainers"></a>
+<h2>Maintainers</h2>
+The tool is developed by <a href="https://abi-laboratory.pro/" rel="nofollow">Andrey Ponomarenko</a>.
+
+<a name="ChangeLog"></a>
+<h2>Changes</h2>
+
+<b>Version 1.8 (January 28, 2017)</b><br/>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Fixed -d option to compare large directories
+    </li>
+    <li>
+        Added more file classes
+    </li>
+    <li>
+        5% performance improvement
+    </li>
+    <li>
+        Omit *.N suffix when determining the file format
+    </li>
+    <li>
+        Do not print warning about missed wdiff into the report
+    </li>
+    <li>
+        Increased default width of the report to 80 chars
+    </li>
+</ul>
+<br/>
+
+<b>Version 1.7.2 (March 18, 2016)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Ability to download plain-text added/removed patches from the report
+    </li>
+</ul>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Do not show time stamp in the report
+    </li>
+    <li>
+        Fixed removal of tmp directory in the rfcdiff-1.41-CUSTOM.sh
+    </li>
+</ul>
+<br/>
+
+<b>Version 1.7.1 (December 11, 2015)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Added -skip-pattern option: skip checking of paths within archives matching a regex
+    </li>
+</ul>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Fixed incompatibility with the latest versions of the ABICC tool
+    </li>
+    <li>
+        Fixed comparison of the RPM/Deb packages info
+    </li>
+</ul>
+<br/>
+
+<b>Version 1.7.0 (October 18, 2015)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Added -d option: compare directories instead of packages
+    </li>
+    <li>
+        Added -list-added-removed option: show content of added/removed text files
+    </li>
+    <li>
+        Added -vnum1 and -vnum2 options: set version numbers of input packages
+    </li>
+    <li>
+        Added -title option: set name of the package in the title of the report
+    </li>
+    <li>
+        Added -skip-subarchives option: skip checking of archives inside packages
+    </li>
+</ul>
+<br/>
+
+<b>Version 1.6.4 (September 08, 2015)</b><br/>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Fixed style of the report
+    </li>
+    <li>
+        Fixed install permissions
+    </li>
+    <li>
+        Fixed errors when comparing man pages
+    </li>
+    <li>
+        Added check for wdiff
+    </li>
+    <li>
+        Simplified Makefile
+    </li>
+</ul>
+
+<br/>
+
+<b>Version 1.6.3 (November 05, 2014)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Added -hide-unchanged option: don't show unchanged files in the report
+    </li>
+    <li>
+        Show change rate in the extra info files.xml (moved, changed, renamed)
+    </li>
+    <li>
+        Check if we can remove a common prefix from files of both packages
+    </li>
+    <li>
+        Encoding of diff reports has been changed to utf-8
+    </li>
+</ul>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Fixed a problem with spaces in package name
+    </li>
+    <li>
+        Added -o option to unzip command
+    </li>
+    <li>
+        Fixed -tmp-dir option
+    </li>
+</ul>
+
+<br/>
+
+<b>Version 1.6 (June 07, 2013)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        ABI compatibility check for shared objects and kernel modules containing DWARF debugging information (in <i>-details</i> mode)
+    </li>
+    <li>
+        ABI status section in the report for debuginfo-packages
+    </li>
+    <li>
+        Suggests ABI Compliance Checker 1.99.1
+    </li>
+    <li>
+        Suggests ABI Dumper 0.97
+    </li>
+</ul>
+
+<br/>
+
+<b>Version 1.5 (April 04, 2013)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Added -extra-info option to dump extra analysis information
+    </li>
+    <li>
+        Improved identification of moved files
+    </li>
+    <li>
+        Classifying files by magic bytes
+    </li>
+    <li>
+        Compare public symbols in shared objects before detailed comparison
+    </li>
+    <li>
+        Added statistics comment line in the report
+    </li>
+    <li>
+        Support for more file types
+    </li>
+</ul>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Corrected Makefile
+    </li>
+    <li>
+        Corrected parser of package version
+    </li>
+</ul>
+
+<br/>
+
+<b>Version 1.4.1 (December 14, 2012)</b><br/>
+<b>Bug Fixes</b>
+<ul>
+    <li>
+        Corrected parser of package version
+    </li>
+    <li>
+        Opening file diffs in a separate window
+    </li>
+</ul>
+
+<br/>
+
+<b>Version 1.4 (October 25, 2012)</b><br/>
+<b>New Features</b>
+<ul>
+    <li>
+        Sorting by status, delta and file name in the report
+    </li>
+    <li>
+        New -open option to open report in the default browser
+    </li>
+    <li>
+        Printing of estimated change rate to the console
+    </li>
+    <li>
+        Simplified usage: pkgdiff PKG1 PKG2
+    </li>
+    <li>
+        Support for Mac OS X
+    </li>
+    <li>
+        Support for more file formats
+    </li>
+</ul>
+
+    <div class="footer">
+      get the source code on GitHub : <a href="https://github.com/lvc/pkgdiff">lvc/pkgdiff</a>
+    </div>
+    <div style="height:350px;"></div>
+
+  </div>
+</body>
+</html>
diff -pruN 1.7.2-1.1/modules/FileType.xml 1.8-0.1/modules/FileType.xml
--- 1.7.2-1.1/modules/FileType.xml	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/modules/FileType.xml	2025-01-11 18:08:08.000000000 +0000
@@ -407,7 +407,7 @@
         log, log.1
     </extensions>
     <dirs>
-        logs
+        logs, log
     </dirs>
     <weight>
         40
@@ -1666,13 +1666,31 @@
 
 <type>
     <id>
-        QT_TS
+        QT_QPH
     </id>
     <summary>
         Qt Translation file
     </summary>
     <extensions>
-        ts, qph
+        qph
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        QT_MS_TS
+    </id>
+    <summary>
+        Qt Translation or MS TypeScript file
+    </summary>
+    <extensions>
+        ts
     </extensions>
     <weight>
         40
@@ -1959,6 +1977,96 @@
 
 <type>
     <id>
+        SEED7_INCLUDE
+    </id>
+    <summary>
+        Seed7 include/library
+    </summary>
+    <extensions>
+        s7i
+    </extensions>
+    <weight>
+        50
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        SEED7_PROGRAM
+    </id>
+    <summary>
+        Seed7 program
+    </summary>
+    <extensions>
+        sd7
+    </extensions>
+    <weight>
+        50
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        HASKELL_SOURCE
+    </id>
+    <summary>
+        Haskell program
+    </summary>
+    <extensions>
+        hs
+    </extensions>
+    <weight>
+        50
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        HASKELL_CABAL
+    </id>
+    <summary>
+        Haskell metadata
+    </summary>
+    <extensions>
+        cabal
+    </extensions>
+    <weight>
+        50
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        RUST
+    </id>
+    <summary>
+        Rust program
+    </summary>
+    <extensions>
+        rs
+    </extensions>
+    <weight>
+        50
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
         PASCAL
     </id>
     <summary>
@@ -2021,6 +2129,21 @@
     <weight>
         50
     </weight>
+</type>
+
+<type>
+    <id>
+        COFFEESCRIPT
+    </id>
+    <summary>
+        CoffeeScript file
+    </summary>
+    <extensions>
+        coffee
+    </extensions>
+    <weight>
+        50
+    </weight>
     <format>
         Text
     </format>
@@ -2695,7 +2818,7 @@
         Shell program
     </summary>
     <extensions>
-        sh, SH, csh, ksh, bash
+        sh, SH, csh, ksh, bash, tcsh, zsh
     </extensions>
     <weight>
         70
@@ -2877,6 +3000,9 @@
     <weight>
         40
     </weight>
+    <format>
+        Text
+    </format>
 </type>
 
 <type>
@@ -2923,7 +3049,25 @@
         Gettext file
     </summary>
     <extensions>
-        gmo, po, mo, pot
+        po, pot
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        GETTEXT_MO
+    </id>
+    <summary>
+        Gettext object
+    </summary>
+    <extensions>
+        gmo, mo
     </extensions>
     <weight>
         40
@@ -3379,6 +3523,24 @@
 
 <type>
     <id>
+        SCSS
+    </id>
+    <summary>
+        Sass CSS style sheet
+    </summary>
+    <extensions>
+        scss
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
         DATA
     </id>
     <summary>
@@ -3556,13 +3718,115 @@
 
 <type>
     <id>
+        CACHE
+    </id>
+    <summary>
+        Cache file
+    </summary>
+    <extensions>
+        cache
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        HIDDEN
+    </id>
+    <summary>
+        Hidden file
+    </summary>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        BACKUP
+    </id>
+    <summary>
+        Backup file
+    </summary>
+    <extensions>
+        bak
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        SERVICE
+    </id>
+    <summary>
+        Service file
+    </summary>
+    <extensions>
+        service
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Text
+    </format>
+</type>
+
+<type>
+    <id>
+        YUM_DB
+    </id>
+    <summary>
+        Yum DB file
+    </summary>
+    <dirs>
+        yumdb
+    </dirs>
+    <weight>
+        40
+    </weight>
+</type>
+
+<type>
+    <id>
+        FIRMWARE
+    </id>
+    <summary>
+        Firmware file
+    </summary>
+    <extensions>
+        fw
+    </extensions>
+    <weight>
+        40
+    </weight>
+    <format>
+        Binary
+    </format>
+</type>
+
+<type>
+    <id>
         CONFIGURATION
     </id>
     <summary>
         Configuration file
     </summary>
     <extensions>
-        conf, config, cfg, cnf, inf, INF, sysconf, sysconfig
+        conf, config, cfg, cnf, inf, INF, sysconf, sysconfig, rules
     </extensions>
     <names>
         Config, config
@@ -3779,7 +4043,7 @@
         tar.bz2, tbz2, tbz, tb2, tar.lzma, tlzma
         tar.lz, tlz, zip, zae, tar, lzma, gz
         jar, war, ear, xz, 7z, rar, sfx, ace
-        bz, bz2, zipx
+        bz, bz2, zipx, apk
     </extensions>
     <weight>
         10
Binary files 1.7.2-1.1/modules/Internals/Fonts/OpenSans.ttf and 1.8-0.1/modules/Internals/Fonts/OpenSans.ttf differ
Binary files 1.7.2-1.1/modules/Internals/Fonts/VeraMono.ttf and 1.8-0.1/modules/Internals/Fonts/VeraMono.ttf differ
diff -pruN 1.7.2-1.1/modules/Internals/Styles/Index.css 1.8-0.1/modules/Internals/Styles/Index.css
--- 1.7.2-1.1/modules/Internals/Styles/Index.css	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/modules/Internals/Styles/Index.css	2025-01-11 18:08:08.000000000 +0000
@@ -1,43 +1,51 @@
+@font-face {
+    font-family:"Open Sans";
+    src:url("../fonts/OpenSans.ttf") format("truetype");
+}
+
+@font-face {
+    font-family:"VeraMono";
+    src:url("../fonts/VeraMono.ttf") format("truetype");
+}
+
 body {
-    font-family:Arial, sans-serif;
+    font-family:'Open Sans', Arial, sans-serif;
     background-color:White;
     color:Black;
 }
 hr {
-    color:Black;
-    background-color:Black;
-    height:1px;
+    color:#ececec;
+    background-color:#ececec;
+    height:3px;
     border:0;
 }
 h1 {
-    margin-bottom:0px;
-    padding-bottom:0px;
     font-size:1.625em;
+    text-decoration:underline;
 }
 h2 {
-    margin-bottom:0px;
-    padding-bottom:0px;
     font-size:1.25em;
     white-space:nowrap;
+    text-decoration:underline;
 }
 table.summary {
     border-collapse:collapse;
-    border:1px outset black;
+    border:1px solid Gray;
+}
+table.summary td, table.summary th {
+    border:1px solid Gray;
+    white-space:nowrap;
 }
 table.summary th {
-    background-color:#eeeeee;
+    background-color:#EEEEEE;
     font-weight:bold;
     text-align:left;
-    font-size:0.94em;
-    white-space:nowrap;
-    border:1px inset gray;
     padding: 3px;
 }
 table.summary td {
     text-align:right;
-    white-space:nowrap;
-    border:1px inset gray;
     padding: 3px 5px 3px 5px;
+    font-family:'VeraMono', Consolas, 'DejaVu Sans Mono', 'Droid Sans Mono', Monaco, Monospace;
 }
 table.summary td.left {
     text-align:left;
@@ -47,8 +55,6 @@ table.summary th.left {
     font-weight:100;
 }
 table.summary td.f_path {
-    font-size:0.875em;
-    font-family:Consolas, 'DejaVu Sans Mono', 'Droid Sans Mono', Monaco, Monospace;
     white-space:normal;
     word-wrap:break-word;
     max-width:57em;
@@ -56,6 +62,9 @@ table.summary td.f_path {
 table.summary td.value {
     padding-left:10px;
 }
+table.highlight tr:hover {
+    background-color:#E0E0E0;
+}
 td.passed, tr.passed {
     background-color:#CCFFCC;
 }
@@ -86,5 +95,6 @@ div.p_list {
     font-size:0.69em;
 }
 .footer {
-    font-size:0.75em;
+    font-size:1.2em;
+    margin-top:23px;
 }
diff -pruN 1.7.2-1.1/modules/Internals/Styles/View.css 1.8-0.1/modules/Internals/Styles/View.css
--- 1.7.2-1.1/modules/Internals/Styles/View.css	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/modules/Internals/Styles/View.css	2025-01-11 18:08:08.000000000 +0000
@@ -1,6 +1,5 @@
 body {
     margin:0.4em;
-    font-size:0.86em;
 }
 
 .view {
@@ -10,7 +9,7 @@ body {
     background-color:White;
     word-wrap:break-word;
     background-color: #FFF;
-    max-width:41.5em;
+    max-width:100em;
     display: inline-block;
     text-align:left;
     white-space:pre-wrap;
diff -pruN 1.7.2-1.1/modules/Internals/Tools/java-dump.sh 1.8-0.1/modules/Internals/Tools/java-dump.sh
--- 1.7.2-1.1/modules/Internals/Tools/java-dump.sh	1970-01-01 00:00:00.000000000 +0000
+++ 1.8-0.1/modules/Internals/Tools/java-dump.sh	2025-01-11 18:08:08.000000000 +0000
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+function decompile {
+    # Decompile class and include private members. In preparation for the
+    # hashing below, strip references on the form #[0-9]+.
+    javap -c -p "$1" \
+        | sed '/^Compiled from /d' \
+        | sed '/^[ ]*}[ ]*$/d' \
+        | sed 's/[ ]\(#[1-9][0-9]*\)[ ,]/ /' \
+        | sed 's/[ ]\([0-9]*[:]\)//' \
+        | sed 's/[ ][ ]*/ /g' \
+        | sed '/Code:$/,/^$/s/^[ ]*\([^ ]\)/    \1/g' \
+        | sed '/Code:$/d' \
+        | sed 's/ *{$//'
+}
+
+function hash_bodies {
+    # Generate hashes of the instructions making up the method bodies; Yields
+    # more concise summaries.
+    awk '/^[  ]{0,3}[^ ]/{if (x)print x"\n";x="";}{x=(!x)?$0"\n--":x" "$0;}END{print x;}' \
+        | sed '/^--[ ]*$/d' \
+        | awk "{ if(/^--/) system(\"printf '    '; (echo '\"\$0\"' | shasum --algorithm 256)\"); else print }" \
+        | sed 's/[ ][ ]*-$//'
+}
+
+if [[ "$1" == "-s" ]]; then
+    shift 1
+    decompile "$1" | hash_bodies
+else
+    javap -c -s -p -verbose "$1"
+fi
diff -pruN 1.7.2-1.1/modules/Internals/Tools/rfcdiff-1.41-CUSTOM.sh 1.8-0.1/modules/Internals/Tools/rfcdiff-1.41-CUSTOM.sh
--- 1.7.2-1.1/modules/Internals/Tools/rfcdiff-1.41-CUSTOM.sh	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/modules/Internals/Tools/rfcdiff-1.41-CUSTOM.sh	2025-01-11 18:08:08.000000000 +0000
@@ -29,8 +29,6 @@
 #	--newcolor COLORNAME	Color for new file in hwdiff (default is "green")
 #
 #	--larger        Make difference text in hwdiff slightly larger
-#
-#	--browse	Show html output in browser
 #	
 #	--keep		Don't delete temporary workfiles
 #	
@@ -139,7 +137,7 @@ lookfor() {
     done
 }
 
-AWK=$(lookfor gawk nawk awk)
+AWK=awk
 
 # ----------------------------------------------------------------------
 # Strip headers footers and formfeeds from infile to stdout
@@ -294,9 +292,6 @@ BEGIN	{
 	   optwidth = ENVIRON["optwidth"]
 	   optnums =  ENVIRON["optnums"]
 	   optlinks = ENVIRON["optlinks"]
-	   cmdline = ENVIRON["cmdline"]
-	   gsub("--", "- -", cmdline)
-	   ENVIRON["cmdline"] = cmdline
 	   header(base1, base2)
 
 	   difflines1 = 0
@@ -314,21 +309,17 @@ function header(file1, file2) {
    }   
    printf "" \
 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> \n" \
-"<!-- Generated by rfcdiff %s: rfcdiff %s --> \n" \
 "<!-- <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional\" > -->\n" \
-"<!-- System: %s --> \n" \
-"<!-- Using awk: %s: %s --> \n" \
-"<!-- Using diff: %s: %s --> \n" \
-"<!-- Using wdiff: %s: %s --> \n" \
 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"> \n" \
 "<head> \n" \
 "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> \n" \
 "  <meta http-equiv=\"Content-Style-Type\" content=\"text/css\" /> \n" \
 "  <title>Diff: %s - %s</title> \n" \
 "  <style type=\"text/css\"> \n" \
-"    body    { font-size:16px; margin: 0.4ex; margin-right: auto; } \n" \
+"    body    { font-family: Arial, sans-serif; margin: 0.4ex; margin-right: auto; } \n" \
+"    table   { width: 100%; } \n" \
 "    tr      { } \n" \
-"    td      { white-space: pre; font-family: Consolas, \"DejaVu Sans Mono\", \"Droid Sans Mono\", Monaco, Monospace; vertical-align: top; font-size: 0.86em;} \n" \
+"    td      { white-space: pre; font-family: Consolas, \"DejaVu Sans Mono\", \"Droid Sans Mono\", Monaco, Monospace; vertical-align: top;} \n" \
 "    th      { font-size: 0.86em; } \n" \
 "    .small  { font-size: 0.6em; font-style: italic; font-family: Verdana, Helvetica, sans-serif; } \n" \
 "    .left   { background-color: #EEE; } \n" \
@@ -355,7 +346,7 @@ function header(file1, file2) {
 "<body > \n" \
 "  <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"> \n" \
 "  <tr bgcolor=\"orange\"><th></th><th>%s&nbsp;%s&nbsp;</th><th> </th><th>&nbsp;%s&nbsp;%s</th><th></th></tr> \n" \
-"", ENVIRON["version"], ENVIRON["cmdline"], ENVIRON["uname"], ENVIRON["awkbin"], ENVIRON["awkver"], ENVIRON["diffbin"], ENVIRON["diffver"], ENVIRON["wdiffbin"], ENVIRON["wdiffver"], file1, file2, prev, url1, url2, nxt;
+"", file1, file2, prev, url1, url2, nxt;
 }
 
 function worddiff(w1, w2) {
@@ -574,7 +565,7 @@ function maybebreakline(line,    width)
 		 posinfo2 = sprintf("<a name=\"part-r%s\" /><small>skipping to change at</small><em> page %s, line %s</em>", diffnum, page2, getpageline(2, linenum2, page2));
 	      }
 
-	      printf "      <tr bgcolor=\"gray\" ><td></td><th>%s</th><th> </th><th>%s</th><td></td></tr>\n", posinfo1, posinfo2;
+	      printf "      <tr bgcolor=\"#c0c0c0\" ><td></td><th>%s</th><th> </th><th>%s</th><td></td></tr>\n", posinfo1, posinfo2;
 	   }
 	}
 
@@ -613,9 +604,9 @@ END	{
 	   flush();
 	   printf("\n" \
 "     <tr><td></td><td class=\"left\"></td><td> </td><td class=\"right\"></td><td></td></tr>\n" \
-"     <tr bgcolor=\"gray\"><th colspan=\"5\" align=\"center\"><a name=\"end\">&nbsp;%s. %s change blocks.&nbsp;</a></th></tr>\n" \
-"     <tr class=\"stats\"><td></td><th><i>%s lines changed or deleted</i></th><th><i> </i></th><th><i>%s lines changed or added</i></th><td></td></tr>\n" \
-"     <tr><td colspan=\"5\" align=\"center\" class=\"small\"><br/>This html diff was produced by rfcdiff %s. The latest version is available from <a href=\"http://www.tools.ietf.org/tools/rfcdiff/\" >http://tools.ietf.org/tools/rfcdiff/</a> </td></tr>\n" \
+"     <tr bgcolor=\"#c0c0c0\"><th colspan=\"5\" align=\"center\"><a name=\"end\">&nbsp;%s. %s change block(s).&nbsp;</a></th></tr>\n" \
+"     <tr class=\"stats\"><td></td><th><i>%s line(s) changed or deleted</i></th><th><i> </i></th><th><i>%s line(s) changed or added</i></th><td></td></tr>\n" \
+"     <tr><td colspan=\"5\" align=\"center\" class=\"small\"><br/>This html diff was produced by rfcdiff %s</td></tr>\n" \
 "   </table>\n" \
 "   </body>\n" \
 "   </html>\n", diffnum?"End of changes":"No changes", difftag, diffcount1, diffcount2, ENVIRON["version"]);
@@ -732,43 +723,6 @@ extract() {
 
     ' "$2"
 }
-# ----------------------------------------------------------------------
-# Utility to start a browser
-# ----------------------------------------------------------------------
-
-browse() {
-    if   [ "$(uname)" = "Darwin" ]; then
-	open "$@"
-    else
-	browser=$(lookfor firefox phoenix MozillaFirebird mozilla opera Netscape netscape dillo)
-
-	if [ -z "$browser" ]; then
-	    echo "Couldn't find any browser, can't display $*."
-	    exit 1
-	fi
-
-	# make sure file name is absolute
-	if [ "${1#/}" = "$1" ]; then
-	    # not absolute path, add pwd
-	    arg="file://$PWD/$1"
-	else
-	    arg="file://$1"
-	fi
-
-
-	# see if a browser is running, act accordingly
-	$browser -remote "ping()" >/dev/null 2>&1
-	if [ $? -eq 0 ]; then
-	    # use running instance
-	    $browser -raise -remote "openurl($arg, new-tab)"
-	else
-	    # error exit: no running instance
-	    echo "Starting web browser."
-
-	    $browser "$arg" >/dev/null 2>&1 &
-	fi
-    fi
-}
 
 
 # ----------------------------------------------------------------------
@@ -784,7 +738,7 @@ die() {
 # ----------------------------------------------------------------------
 
 # Default values
-opthtml=1; optdiff=0; optchbars=0; optwdiff=0; optshow=0; optnowdiff=0;
+opthtml=1; optdiff=0; optchbars=0; optwdiff=0; optnowdiff=0;
 optkeep=0; optinfo=0; optwidth=0;  optnums=0;  optbody=0; optabdiff=0;
 optstrip=1; opthwdiff=0; optlinks=0;
 optoldcolour="red"; optnewcolour="green"; optlarger=""
@@ -803,7 +757,6 @@ while [ $# -gt 0 ]; do
       --ab-diff)opthtml=0; optdiff=0; optchbars=0; optwdiff=0; opthwdiff=0; optabdiff=1;;
       --rfc-editor-diff)opthtml=0; optdiff=0; optchbars=0; optwdiff=0; opthwdiff=0; optabdiff=1;;
       --version)echo -e "$basename\t$version"; exit 0;;
-      --browse) optshow=1;;
       --nowdiff)optnowdiff=1;;
       --keep)	optkeep=1;;
       --info)	optinfo=1; keyword=$2; shift;;
@@ -870,34 +823,12 @@ mkdir $workdir/1 || die "$0: Error: Fail
 mkdir $workdir/2 || die "$0: Error: Failed to create temporary directory '$workdir/2'."
 
 # ----------------------------------------------------------------------
-# If any of the files is an http or ftp URL we download it, else copy it
+# Copy files to a work directory
 # ----------------------------------------------------------------------
-
-wgetbin=$(lookfor wget)
-dowgetarg1=0
-dowgetarg2=0
-
-if [ -n "$wgetbin" ]; then
-   if [ "${1#http://}" != "$1" ]; then dowgetarg1=1; fi
-   if [ "${1#ftp://}" != "$1" ]; then dowgetarg1=1; fi
-
-   if [ "${2#http://}" != "$2" ]; then dowgetarg2=1; fi
-   if [ "${2#ftp://}" != "$2" ]; then dowgetarg2=1; fi
-fi
+cp "$1" $workdir/1/"$base1"
+cp "$2" $workdir/2/"$base2"
 
 
-if [ $dowgetarg1 -gt 0 ]; then
-   $wgetbin -nv "$1" -O $workdir/1/"$base1"
-else
-   cp "$1" $workdir/1/"$base1"
-fi
-
-if [ $dowgetarg2 -gt 0 ]; then
-   $wgetbin -nv "$2" -O $workdir/2/"$base2"
-else
-   cp "$2" $workdir/2/"$base2"
-fi
-
 # ----------------------------------------------------------------------
 # Maybe strip headers/footers from both files
 # ----------------------------------------------------------------------
@@ -964,41 +895,7 @@ fi
 # ----------------------------------------------------------------------
 if [ $optnowdiff -eq 0 ]; then
    wdiffbin=$(lookfor wdiff)
-   if [ -n "$wdiffbin" ]; then
-      wdiffver=$($wdiffbin --version 2>/dev/null | egrep "(wdiff|GNU).+[0-9]\.[0-9]")
-      if [ -z "$wdiffver" ]; then
-        wdiffbin="";
-	echo -en "\n  Found wdiff, but it reported no recognisable version."
-      fi
-   else
-      echo -en "\n  Couldn't find wdiff."
-   fi
-   if [ -z "$wdiffbin" ]; then echo " Falling back to builtin diff colouring..."; fi
    export wdiffbin
-   export wdiffver
-   #echo "Found wdiff at $wdiffbin"
-fi
-
-# ----------------------------------------------------------------------
-# Get some misc. info
-# ----------------------------------------------------------------------
-uname=$(uname -a)
-export uname
-awkbin=$AWK
-export awkbin
-awkver=$( { $AWK --version 2>/dev/null || $AWK -V 2>/dev/null; } | head -n 1)
-export awkver
-diffbin=$(lookfor diff)
-export diffbin
-diffver=$(diff --version | head -n 1)
-export diffver
-
-# ----------------------------------------------------------------------
-# Check that we don't have a broken awk
-# ----------------------------------------------------------------------
-if [ $opthtml -gt 0 -a "${uname%% *}" == "Darwin" -a "$awkver" == "awk version 20070501" ]; then
-    echo -e  "\n  Oops.  Awk version 20070501 on OS X doesn't work with rfcdiff's html mode.\n  To make rfcdiff work, you could install Gnu Awk (gawk), for instance using\n  MacPorts, http://www.macports.org/."
-    exit 1
 fi
 
 # ----------------------------------------------------------------------
@@ -1044,10 +941,6 @@ else
   cd "$origdir"; if [ -f $workdir/"$tempout" ]; then mv $workdir/"$tempout" "$outfile"; fi
 fi
 
-if [ $optshow -gt 0 ]; then
-   browse "$outfile"
-fi
-
 if [ $optkeep -eq 0 ]; then
    if [ -f $pagecache1 ]; then rm $pagecache1; fi
    if [ -f $pagecache2 ]; then rm $pagecache2; fi
diff -pruN 1.7.2-1.1/pkgdiff.pl 1.8-0.1/pkgdiff.pl
--- 1.7.2-1.1/pkgdiff.pl	2016-03-18 12:29:58.000000000 +0000
+++ 1.8-0.1/pkgdiff.pl	2025-01-11 18:08:08.000000000 +0000
@@ -1,9 +1,9 @@
 #!/usr/bin/perl
 ###########################################################################
-# PkgDiff - Package Changes Analyzer 1.7.2
+# PkgDiff - Package Changes Analyzer 1.8
 # A tool for visualizing changes in Linux software packages
 #
-# Copyright (C) 2012-2016 Andrey Ponomarenko's ABI Laboratory
+# Copyright (C) 2012-2025 Andrey Ponomarenko's ABI Laboratory
 #
 # Written by Andrey Ponomarenko
 #
@@ -13,7 +13,7 @@
 #
 # PACKAGE FORMATS
 # ===============
-#  RPM, DEB, TAR.GZ, etc.
+#  RPM, DEB, TAR.GZ, JAR, etc.
 #
 # REQUIREMENTS
 # ============
@@ -22,6 +22,7 @@
 #  GNU Wdiff
 #  GNU Awk
 #  GNU Binutils (readelf)
+#  Perl-File-LibMagic
 #  RPM (rpm, rpmbuild, rpm2cpio) for analysis of RPM-packages
 #  DPKG (dpkg, dpkg-deb) for analysis of DEB-packages
 #
@@ -42,6 +43,7 @@
 # You should have received a copy of the GNU General Public License along
 # with this program. If not, see <http://www.gnu.org/licenses/>.
 ###########################################################################
+use strict;
 use Getopt::Long;
 Getopt::Long::Configure ("posix_default", "no_ignore_case", "permute");
 use File::Path qw(mkpath rmtree);
@@ -52,14 +54,15 @@ use Cwd qw(abs_path cwd);
 use Config;
 use Fcntl;
 
-my $TOOL_VERSION = "1.7.2";
+my $TOOL_VERSION = "1.8";
 my $ORIG_DIR = cwd();
 
 # Internal modules
-my $MODULES_DIR = get_Modules();
-push(@INC, get_dirname($MODULES_DIR));
+my $MODULES_DIR = getModules();
+push(@INC, getDirname($MODULES_DIR));
 
 my $DIFF = $MODULES_DIR."/Internals/Tools/rfcdiff-1.41-CUSTOM.sh";
+my $JAVA_DUMP = $MODULES_DIR."/Internals/Tools/java-dump.sh";
 my $ACC = "abi-compliance-checker";
 my $ACC_VER = "1.99.1";
 my $ABI_DUMPER = "abi-dumper";
@@ -67,13 +70,14 @@ my $ABI_DUMPER_VER = "0.97";
 
 my ($Help, $ShowVersion, $DumpVersion, $GenerateTemplate, %Descriptor,
 $CheckUsage, $PackageManager, $OutputReportPath, $ShowDetails, $Debug,
-$SizeLimit, $QuickMode, $DiffWidth, $DiffLines, $Minimal,
+$SizeLimit, $QuickMode, $DiffWidth, $DiffLines, $Minimal, $NoWdiff,
 $IgnoreSpaceChange, $IgnoreAllSpace, $IgnoreBlankLines, $ExtraInfo,
 $CustomTmpDir, $HideUnchanged, $TargetName, $TargetTitle, %TargetVersion,
 $CompareDirs, $ListAddedRemoved, $SkipSubArchives, $LinksTarget,
-$SkipPattern);
+$SkipPattern, $AllText, $CheckByteCode, $FullMethodDiffs, $TrackUnchanged,
+$MoveStyles);
 
-my $CmdName = get_filename($0);
+my $CmdName = getFilename($0);
 
 my %ERROR_CODE = (
     # Unchanged verdict
@@ -90,11 +94,11 @@ my %ERROR_CODE = (
     "Module_Error"=>9
 );
 
-my $HomePage = "http://lvc.github.com/pkgdiff/";
+my $HomePage = "https://github.com/lvc/pkgdiff";
 
 my $ShortUsage = "Package Changes Analyzer (PkgDiff) $TOOL_VERSION
 A tool for visualizing changes in Linux software packages
-Copyright (C) 2016 Andrey Ponomarenko's ABI Laboratory
+Copyright (C) 2022 Andrey Ponomarenko's ABI Laboratory
 License: GNU GPL
 
 Usage: $CmdName PKG1 PKG2 [options]
@@ -128,9 +132,10 @@ GetOptions("h|help!" => \$Help,
   "ignore-blank-lines" => \$IgnoreBlankLines,
   "quick!" => \$QuickMode,
   "minimal!" => \$Minimal,
+  "no-wdiff!" => \$NoWdiff,
   "extra-info=s" => \$ExtraInfo,
   "tmp-dir=s" => \$CustomTmpDir,
-  "hide-unchanged!" => \$HideUnchanged,
+  "c|hide-unchanged!" => \$HideUnchanged,
   "debug!" => \$Debug,
   "v1|vnum1=s" => \$TargetVersion{1},
   "v2|vnum2=s" => \$TargetVersion{2},
@@ -140,8 +145,13 @@ GetOptions("h|help!" => \$Help,
   "list-added-removed!" => \$ListAddedRemoved,
   "skip-subarchives!" => \$SkipSubArchives,
   "skip-pattern=s" => \$SkipPattern,
-  "links-target=s" => \$LinksTarget
-) or ERR_MESSAGE();
+  "all-text!" => \$AllText,
+  "links-target=s" => \$LinksTarget,
+  "check-byte-code!" => \$CheckByteCode,
+  "full-method-diffs!" => \$FullMethodDiffs,
+  "track-unchanged!" => \$TrackUnchanged,
+  "move-styles=s" => \$MoveStyles
+) or errMsg();
 
 my $TMP_DIR = undef;
 
@@ -158,16 +168,16 @@ else {
 
 sub cleanTmp()
 {
-    foreach ("null", "error",
+    foreach my $E ("null", "error",
     "unpack", "output", "fmt",
     "content1", "content2",
     "xcontent1", "xcontent2")
     {
-        if(-f $TMP_DIR."/".$_) {
-            unlink($TMP_DIR."/".$_);
+        if(-f $TMP_DIR."/".$E) {
+            unlink($TMP_DIR."/".$E);
         }
-        elsif(-d $TMP_DIR."/".$_) {
-            rmtree($TMP_DIR."/".$_);
+        elsif(-d $TMP_DIR."/".$E) {
+            rmtree($TMP_DIR."/".$E);
         }
     }
 }
@@ -180,11 +190,11 @@ if(@ARGV)
         $Descriptor{2} = $ARGV[1];
     }
     else {
-        ERR_MESSAGE();
+        errMsg();
     }
 }
 
-sub ERR_MESSAGE()
+sub errMsg()
 {
     printMsg("INFO", "\n".$ShortUsage);
     exit($ERROR_CODE{"Error"});
@@ -193,11 +203,14 @@ sub ERR_MESSAGE()
 my $HelpMessage="
 NAME:
   Package Changes Analyzer
-  A tool for analyzing changes in Linux software packages
+  A tool for visualizing changes in Linux software packages
 
 DESCRIPTION:
-  Package Changes Analyzer (PkgDiff) is a tool for analyzing
+  Package Changes Analyzer (PkgDiff) is a tool for visualizing
   changes in Linux software packages (RPM, DEB, TAR.GZ, etc).
+  
+  The tool can compare directories as well (with the help of
+  the -d option).
 
   The tool is intended for Linux maintainers who are interested
   in ensuring compatibility of old and new versions of packages.
@@ -207,9 +220,11 @@ DESCRIPTION:
 
 USAGE:
   $CmdName PKG1 PKG2 [options]
+  $CmdName -d DIR1/ DIR2/ [options]
 
 EXAMPLES:
   $CmdName OLD.rpm NEW.rpm
+  $CmdName OLD.deb NEW.deb
   $CmdName OLD.tar.gz NEW.tar.gz
 
 ARGUMENTS:
@@ -260,7 +275,7 @@ GENERAL OPTIONS:
 
   -width WIDTH
       Width of the Visual Diff.
-      Default: 75
+      Default: 80
 
   -prelines NUM
       Size of the context in the Visual Diff.
@@ -280,6 +295,11 @@ GENERAL OPTIONS:
 
   -minimal
       Try to find a smaller set of changes.
+  
+  -no-wdiff
+      Do not use GNU Wdiff for analysis of changes.
+      This may be two times faster, but produces lower
+      quality reports.
 
 OTHER OPTIONS:
   -check-usage
@@ -300,7 +320,7 @@ OTHER OPTIONS:
   -tmp-dir DIR
       Use custom temp directory.
   
-  -hide-unchanged
+  -c|-hide-unchanged
       Don't show unchanged files in the report.
 
   -debug
@@ -320,8 +340,8 @@ OTHER OPTIONS:
   
   -links-target TARGET
       Set target attribute for links in the report:
-        _self
-        _blank (default)
+        _self (default)
+        _blank
   
   -list-added-removed
       Show content of added and removed text files.
@@ -330,10 +350,22 @@ OTHER OPTIONS:
       Skip checking of archives inside the input packages.
   
   -skip-pattern REGEX
-      Skip checking of paths within archives matching REGEX.
+      Don't check files matching REGEX.
   
   -d|-directories
       Compare directories instead of packages.
+  
+  -all-text
+      Treat all files in the archive as text files.
+
+  -check-byte-code
+      When comparing Java classes, also check for byte code changes.
+
+  -full-method-diffs
+      Perform a full diff of method bodies when -check-byte-code is specified.
+
+  -track-unchanged
+      Track unchanged files in extra info.
 
 REPORT:
     Report will be generated to:
@@ -346,7 +378,7 @@ EXIT CODES:
 MORE INFORMATION:
     ".$HomePage."\n";
 
-sub HELP_MESSAGE() {
+sub helpMsg() {
     printMsg("INFO", $HelpMessage."\n");
 }
 
@@ -377,15 +409,17 @@ my $DescriptorTemplate = "
 </descriptor>";
 
 # Settings
-my $RENAME_FILE_MATCH = 0.55;
+my $RENAME_FILE_MATCH = 0.25; # 0.55
 my $RENAME_CONTENT_MATCH = 0.85;
 my $MOVE_CONTENT_MATCH = 0.90;
 my $MOVE_DEPTH = 4;
-my $DEFAULT_WIDTH = 75;
+my $DEFAULT_WIDTH = 80;
 my $DIFF_PRE_LINES = 10;
 my $EXACT_DIFF_SIZE = 256*1024;
 my $EXACT_DIFF_RATE = 0.1;
 
+my $USE_LIBMAGIC = 0;
+
 my %Group = (
     "Count1"=>0,
     "Count2"=>0
@@ -424,6 +458,7 @@ my %DepChanges;
 my %AddedFiles;
 my %RemovedFiles;
 my %ChangedFiles;
+my %UnchangedFiles;
 my %StableFiles;
 my %RenamedFiles;
 my %RenamedFiles_R;
@@ -468,14 +503,15 @@ my %ArchiveFormats = (
     "XZ"       => ["xz"],
 
     "JAR"      => ["jar", "war",
-                   "ear"]
+                   "ear", "aar"],
+    "APK"      => ["apk"]
 );
 
 my $ARCHIVE_EXT = getArchivePattern();
 
-sub get_Modules()
+sub getModules()
 {
-    my $TOOL_DIR = get_dirname($0);
+    my $TOOL_DIR = getDirname($0);
     if(not $TOOL_DIR) {
         $TOOL_DIR = ".";
     }
@@ -503,13 +539,19 @@ sub get_Modules()
 sub readModule($$)
 {
     my ($Module, $Name) = @_;
-    my $Path = $MODULES_DIR."/Internals/$Module/".$Name;
+    my $Path = getModulePath($Module, $Name);
     if(not -f $Path) {
         exitStatus("Module_Error", "can't access \'$Path\'");
     }
     return readFile($Path);
 }
 
+sub getModulePath($$)
+{
+    my ($Module, $Name) = @_;
+    return $MODULES_DIR."/Internals/$Module/".$Name;
+}
+
 sub readBytes($)
 { # ELF: 7f454c46
     sysopen(FILE, $_[0], O_RDONLY);
@@ -728,7 +770,9 @@ sub compareFiles($$$$)
     or $Format eq "MANPAGE"
     or $Format eq "INFODOC"
     or $Format eq "SYMLINK"
-    or $Format eq "JAVA_CLASS")
+    or $Format eq "JAVA_CLASS"
+    or $Format eq "JAVASCRIPT"
+    or $Format eq "GETTEXT_MO")
     {
         my $Page1 = showFile($P1, $Format, 1);
         my $Page2 = showFile($P2, $Format, 2);
@@ -754,6 +798,7 @@ sub compareFiles($$$$)
         $Changed = 1;
         $Rate = checkDiff($P1, $P2);
     }
+    
     if($DLink or $Changed)
     {
         if($ShowDetails)
@@ -772,6 +817,7 @@ sub compareFiles($$$$)
         $RLink=~s/\A\Q$REPORT_DIR\E\///;
         return (1, $DLink, $RLink, $Rate, $Adv);
     }
+    
     return (0, "", "", 0, {});
 }
 
@@ -804,10 +850,11 @@ sub checkDiff($$)
     if($AvgSize<$EXACT_DIFF_SIZE
     and $Rate<$EXACT_DIFF_RATE)
     {
+        my $TmpFile = $TMP_DIR."/null";
         if(-T $P1)
         { # Text
             my $TDiff = $TMP_DIR."/txtdiff";
-            system("diff -Bw \"$P1\" \"$P2\" >$TDiff 2>$TMP_DIR/null");
+            qx/diff -Bw \"$P1\" \"$P2\" >$TDiff 2>$TmpFile/;
             $Rate = getRate($P1, $P2, $TDiff);
             unlink($TDiff);
         }
@@ -818,7 +865,7 @@ sub checkDiff($$)
             my $T2 = $TMP_DIR."/tmp2.txt";
             writeFile($T1, hexDump($P1));
             writeFile($T2, hexDump($P2));
-            system("diff -Bw \"$T1\" \"$T2\" >$TDiff 2>$TMP_DIR/null");
+            qx/diff -Bw \"$T1\" \"$T2\" >$TDiff 2>$TmpFile/;
             unlink($T1);
             unlink($T2);
             $Rate = getRate($P1, $P2, $TDiff);
@@ -834,8 +881,10 @@ sub checkDiff($$)
 sub showFile($$$)
 {
     my ($Path, $Format, $Version) = @_;
-    my ($Dir, $Name) = separate_path($Path);
-    my $Cmd = "";
+    my ($Dir, $Name) = sepPath($Path);
+    
+    my $Cmd = undef;
+    
     if($Format eq "MANPAGE")
     {
         $Name=~s/\.(gz|bz2|xz)\Z//;
@@ -856,9 +905,8 @@ sub showFile($$$)
         if($#Contents==0) {
             $Cmd = "cat \"$Unpack/".$Contents[0]."\"";
         }
-        else
-        {
-            return "";
+        else {
+            return undef;
         }
     }
     elsif($Format eq "SHARED_OBJECT"
@@ -880,21 +928,52 @@ sub showFile($$$)
     }
     elsif($Format eq "JAVA_CLASS")
     {
-        if(not check_Cmd("javap")) {
-            return "";
+        if(not checkCmd("javap")) {
+            return undef;
         }
         $Name=~s/\.class\Z//;
         $Name=~s/\$/./;
         $Path = $Name;
-        $Cmd = "javap \"$Path\""; # -s -c -private -verbose
+        if ($CheckByteCode) {
+            if ($FullMethodDiffs) {
+                $Cmd = "$JAVA_DUMP \"$Path\"";
+            } else {
+                $Cmd = "$JAVA_DUMP -s \"$Path\"";
+            }
+        } else {
+            $Cmd = "javap \"$Path\""; # -c -private -verbose
+        }
         chdir($Dir);
     }
+    elsif($Format eq "JAVASCRIPT")
+    {
+        if(not checkCmd("js-beautify")) {
+            return undef;
+        }
+        $Cmd = "js-beautify \"$Path\"";
+    }
+    elsif($Format eq "GETTEXT_MO")
+    {
+        if(not checkCmd("msgunfmt")) {
+            return undef;
+        }
+        $Cmd = "msgunfmt \"$Path\"";
+    }
+    else
+    { # error
+        return undef;
+    }
+    
     my $SPath = $TMP_DIR."/fmt/".$Format."/".$Version."/".$Name;
-    mkpath(get_dirname($SPath));
-    system($Cmd." >\"".$SPath."\" 2>$TMP_DIR/null");
+    mkpath(getDirname($SPath));
+    
+    my $TmpFile = $TMP_DIR."/null";
+    qx/$Cmd >"$SPath" 2>$TmpFile/;
+    
     if($Format eq "JAVA_CLASS") {
         chdir($ORIG_DIR);
     }
+    
     if($Format eq "SHARED_OBJECT"
     or $Format eq "KERNEL_MODULE"
     or $Format eq "DEBUG_INFO"
@@ -920,6 +999,7 @@ sub showFile($$$)
         $Content=~s/\s+Build ID: \w+\s+//g;
         writeFile($SPath, uniqStr($Content));
     }
+    
     return $SPath;
 }
 
@@ -952,7 +1032,7 @@ sub compareABIs($$$$$)
     my ($P1, $P2, $N1, $N2, $Path) = @_;
     
     my $Sect = `readelf -S \"$P1\" 2>\"$TMP_DIR/error\"`;
-    my $Name = get_filename($P1);
+    my $Name = getFilename($P1);
     
     if($Sect!~/\.debug_info/)
     { # No DWARF info
@@ -960,11 +1040,11 @@ sub compareABIs($$$$$)
         return ("", {});
     }
     
-    mkpath(get_dirname($Path));
+    mkpath(getDirname($Path));
     my $Adv = {};
     
     $Name=~s/\.debug\Z//;
-    printMsg("INFO", "Compare ABIs of ".$Name." (".show_number(getSize($P1)/1048576)."M) ...");
+    printMsg("INFO", "Compare ABIs of ".$Name." (".showNumber(getSize($P1)/1048576)."M) ...");
     
     $N1=~s/\A\///;
     $N2=~s/\A\///;
@@ -998,7 +1078,7 @@ sub compareABIs($$$$$)
     if($Debug)
     {
         my $DP = $REPORT_DIR."/dwarf_dumps/".$Group{"V1"}."/".$N1."-DWARF.dump";
-        mkpath(get_dirname($DP));
+        mkpath(getDirname($DP));
         move("$TMP_DIR/extra-info/debug_info", $DP);
         
         $Adv->{"DWARFDump"}{1} = $DP;
@@ -1022,7 +1102,7 @@ sub compareABIs($$$$$)
     if($Debug)
     {
         my $DP = $REPORT_DIR."/dwarf_dumps/".$Group{"V2"}."/".$N2."-DWARF.dump";
-        mkpath(get_dirname($DP));
+        mkpath(getDirname($DP));
         move("$TMP_DIR/extra-info/debug_info", $DP);
         
         $Adv->{"DWARFDump"}{2} = $DP;
@@ -1069,6 +1149,19 @@ sub compareABIs($$$$$)
     return ($Path, $Adv);
 }
 
+sub checkModule($)
+{
+    foreach my $P (@INC)
+    {
+        if(-e $P."/".$_[0])
+        {
+            return 1;
+        }
+    }
+    
+    return 0;
+}
+
 sub getSize($)
 {
     my $Path = $_[0];
@@ -1080,7 +1173,7 @@ sub getSize($)
     }
     if(-l $Path)
     { # symlinks
-        return ($Cache{"getSize"}{$Path} = length(`file -b \"$Path\"`));
+        return ($Cache{"getSize"}{$Path} = length(getType($Path)));
     }
     return ($Cache{"getSize"}{$Path} = -s $Path);
 }
@@ -1088,14 +1181,19 @@ sub getSize($)
 sub diffFiles($$$)
 {
     my ($P1, $P2, $Path) = @_;
+    
     if(not $P1 or not $P2) {
-        return "";
+        return ();
     }
-    mkpath(get_dirname($Path));
+    
+    mkpath(getDirname($Path));
+    
     my $TmpPath = $TMP_DIR."/diff";
     unlink($TmpPath);
+    
     my $Cmd = "sh $DIFF --width $DiffWidth --stdout";
     $Cmd .= " --tmpdiff \"$TmpPath\" --prelines $DiffLines";
+    
     if($IgnoreSpaceChange) {
         $Cmd .= " --ignore-space-change";
     }
@@ -1109,25 +1207,33 @@ sub diffFiles($$$)
     { # diff --minimal
         $Cmd .= " --minimal";
     }
+    if($NoWdiff) {
+        $Cmd .= " --nowdiff";
+    }
+    
     $Cmd .= " \"".$P1."\" \"".$P2."\" >\"".$Path."\" 2>$TMP_DIR/null";
     $Cmd=~s/\$/\\\$/g;
-    system($Cmd);
+    
+    qx/$Cmd/;
+    
     if(getSize($Path)<3500)
     { # may be identical
-        if(readFilePart($Path, 2)=~/The files are identical/)
+        if(readFilePart($Path, 2)=~/The files are identical/i)
         {
             unlink($Path);
-            return "";
+            return ();
         }
     }
+    
     if(getSize($Path)<3100)
     { # may be identical or non-text
         if(index(readFile($Path), "No changes")!=-1)
         {
             unlink($Path);
-            return "";
+            return ();
         }
     }
+    
     my $Rate = getRate($P1, $P2, $TmpPath);
     
     # clean space
@@ -1139,11 +1245,14 @@ sub diffFiles($$$)
 sub getRate($$$)
 {
     my ($P1, $P2, $PatchPath) = @_;
+    
     my $Size1 = getSize($P1);
     if(not $Size1) {
         return 1;
     }
+    
     my $Size2 = getSize($P2);
+    
     my $Rate = 1;
     # count removed/changed bytes
     my $Patch = readFile($PatchPath);
@@ -1163,33 +1272,39 @@ sub getRate($$$)
 sub readFilePart($$)
 {
     my ($Path, $Num) = @_;
-    return "" if(not $Path or not -f $Path);
+    
     open (FILE, $Path);
     my $Lines = "";
     foreach (1 ... $Num) {
         $Lines .= <FILE>;
     }
     close(FILE);
+    
     return $Lines;
 }
 
 sub getType($)
 {
     my $Path = $_[0];
-    if(not $Path or not -e $Path) {
-        return "";
-    }
+    
     if($Cache{"getType"}{$Path}) {
         return $Cache{"getType"}{$Path};
     }
-    return ($Cache{"getType"}{$Path} = `file -b \"$Path\"`);
+    
+    if($USE_LIBMAGIC)
+    {
+        my $Magic = File::LibMagic->new();
+        return ($Cache{"getType"}{$Path} = $Magic->describe_filename($Path));
+    }
+    
+    return ($Cache{"getType"}{$Path} = qx/file -b \"$Path\"/);
 }
 
 sub isRenamed($$$)
 {
     my ($P1, $P2, $Match) = @_;
-    my ($D1, $N1) = separate_path($P1);
-    my ($D2, $N2) = separate_path($P2);
+    my ($D1, $N1) = sepPath($P1);
+    my ($D2, $N2) = sepPath($P2);
     if($D1 ne $D2) {
         return 0;
     }
@@ -1209,8 +1324,7 @@ sub isRenamed($$$)
             }
         }
     }
-    $Match/=$RENAME_FILE_MATCH;
-    my $HL = ($L1+$L2)/$Match;
+    my $HL = ($L1+$L2)*$RENAME_FILE_MATCH/$Match;
     return (getBaseLen($N1, $N2)>=$HL);
 }
 
@@ -1219,28 +1333,31 @@ sub minNum($$)
     if($_[0]<$_[1]) {
         return $_[0];
     }
-    else {
-        return $_[1];
-    }
+    
+    return $_[1];
 }
 
-sub get_depth($) {
+sub getDepth($) {
     return ($_[0]=~tr![\/]!!);
 }
 
 sub getBaseLen($$)
 {
     my ($Str1, $Str2) = @_;
+    
     if(defined $Cache{"getBaseLen"}{$Str1}{$Str2}) {
         return $Cache{"getBaseLen"}{$Str1}{$Str2};
     }
+    
     if($Str1 eq $Str2) {
         return length($Str1);
     }
+    
     my $BLen = 0;
     my $Len1 = length($Str1);
     my $Len2 = length($Str2);
     my $Min = minNum($Len1, $Len2) - 1;
+    
     foreach my $Pos (0 .. $Min)
     {
         my $S1 = substr($Str1, $Pos, 1);
@@ -1252,6 +1369,7 @@ sub getBaseLen($$)
             last;
         }
     }
+    
     foreach my $Pos (0 .. $Min)
     {
         my $S1 = substr($Str1, $Len1-$Pos-1, 1);
@@ -1263,14 +1381,15 @@ sub getBaseLen($$)
             last;
         }
     }
+    
     return ($Cache{"getBaseLen"}{$Str1}{$Str2}=$BLen);
 }
 
 sub isMoved($$)
 {
     my ($P1, $P2) = @_;
-    my ($D1, $N1) = separate_path($P1);
-    my ($D2, $N2) = separate_path($P2);
+    my ($D1, $N1) = sepPath($P1);
+    my ($D2, $N2) = sepPath($P2);
     if($N1 eq $N2
     and $D1 ne $D2) {
         return 1;
@@ -1284,19 +1403,17 @@ sub writeExtraInfo()
     
     $FILES .= "<rate>\n    ".$RESULT{"affected"}."\n</rate>\n\n";
     
-    if(my @Added = sort {lc($a) cmp lc($b)} keys(%AddedFiles))
-    {
+    if(my @Added = sort {lc($a) cmp lc($b)} keys(%AddedFiles)) {
         $FILES .= "<added>\n    ".join("\n    ", @Added)."\n</added>\n\n";
     }
-    if(my @Removed = sort {lc($a) cmp lc($b)} keys(%RemovedFiles))
-    {
+    if(my @Removed = sort {lc($a) cmp lc($b)} keys(%RemovedFiles)) {
         $FILES .= "<removed>\n    ".join("\n    ", @Removed)."\n</removed>\n\n";
     }
     if(my @Moved = sort {lc($a) cmp lc($b)} keys(%MovedFiles))
     {
         $FILES .= "<moved>\n";
         foreach (@Moved) {
-            $FILES .= "    ".$_.";".$MovedFiles{$_}." (".show_number($ChangeRate{$_}*100)."%)\n";
+            $FILES .= "    ".$_.";".$MovedFiles{$_}.";".showNumber($ChangeRate{$_}*100)."\n";
         }
         $FILES .= "</moved>\n\n";
     }
@@ -1304,27 +1421,31 @@ sub writeExtraInfo()
     {
         $FILES .= "<renamed>\n";
         foreach (@Renamed) {
-            $FILES .= "    ".$_.";".$RenamedFiles{$_}." (".show_number($ChangeRate{$_}*100)."%)\n";
+            $FILES .= "    ".$_.";".$RenamedFiles{$_}.";".showNumber($ChangeRate{$_}*100)."\n";
         }
         $FILES .= "</renamed>\n\n";
     }
     if(my @Changed = sort {lc($a) cmp lc($b)} keys(%ChangedFiles))
     {
         foreach (0 .. $#Changed) {
-            $Changed[$_] .= " (".show_number($ChangeRate{$Changed[$_]}*100)."%)";
+            $Changed[$_] .= ";".showNumber($ChangeRate{$Changed[$_]}*100);
         }
         
         $FILES .= "<changed>\n    ".join("\n    ", @Changed)."\n</changed>\n\n";
     }
+    if ($TrackUnchanged) {
+        if(my @Unchanged = sort {lc($a) cmp lc($b)} keys(%UnchangedFiles))
+        {
+            $FILES .= "<unchanged>\n    ".join("\n    ", @Unchanged)."\n</unchanged>\n\n";
+        }
+    }
     writeFile($ExtraInfo."/files.xml", $FILES);
     
     my $SYMBOLS = "";
-    if(my @AddedSymbols = sort {lc($a) cmp lc($b)} keys(%AddedSymbols))
-    {
+    if(my @AddedSymbols = sort {lc($a) cmp lc($b)} keys(%AddedSymbols)) {
         $SYMBOLS .= "<added>\n    ".join("\n    ", @AddedSymbols)."\n</added>\n\n";
     }
-    if(my @RemovedSymbols = sort {lc($a) cmp lc($b)} keys(%RemovedSymbols))
-    {
+    if(my @RemovedSymbols = sort {lc($a) cmp lc($b)} keys(%RemovedSymbols)) {
         $SYMBOLS .= "<removed>\n    ".join("\n    ", @RemovedSymbols)."\n</removed>\n\n";
     }
     writeFile($ExtraInfo."/symbols.xml", $SYMBOLS);
@@ -1348,9 +1469,14 @@ sub skipFile($)
 
 sub detectChanges()
 {
-    mkpath($REPORT_DIR."/diffs");
-    mkpath($REPORT_DIR."/info-diffs");
-    mkpath($REPORT_DIR."/details");
+    foreach my $E ("info-diffs", "diffs") {
+        mkpath($REPORT_DIR."/".$E);
+    }
+
+    if($ShowDetails) {
+        mkpath($REPORT_DIR."/details");
+    }
+    
     foreach my $Format (keys(%FormatInfo))
     {
         %{$FileChanges{$Format}} = (
@@ -1362,34 +1488,37 @@ sub detectChanges()
             "SizeDelta"=>0
         );
     }
+    
     my (%AddedByDir, %RemovedByDir, %AddedByName,
     %RemovedByName, %AddedByPrefix, %RemovedByPrefix) = ();
+    
     foreach my $Name (sort keys(%{$PackageFiles{1}}))
     { # checking old files
         my $Format = getFormat($PackageFiles{1}{$Name});
         if(not defined $PackageFiles{2}{$Name})
         { # removed files
-            $RemovedFiles{$Name}=1;
-            $RemovedByDir{get_dirname($Name)}{$Name}=1;
-            $RemovedByName{get_filename($Name)}{$Name}=1;
-            foreach (get_Prefixes($Name, $MOVE_DEPTH)) {
+            $RemovedFiles{$Name} = 1;
+            $RemovedByDir{getDirname($Name)}{$Name} = 1;
+            $RemovedByName{getFilename($Name)}{$Name} = 1;
+            foreach (getPrefixes($Name, $MOVE_DEPTH)) {
                 $RemovedByPrefix{$_}{$Name} = 1;
             }
         }
         else {
-            $StableFiles{$Name}=1;
+            $StableFiles{$Name} = 1;
         }
     }
+    
     foreach my $Name (keys(%{$PackageFiles{2}}))
     { # checking new files
         my $Format = getFormat($PackageFiles{2}{$Name});
         if(not defined $PackageFiles{1}{$Name})
         { # added files
-            $AddedFiles{$Name}=1;
-            $AddedByDir{get_dirname($Name)}{$Name}=1;
-            $AddedByName{get_filename($Name)}{$Name}=1;
-            foreach (get_Prefixes($Name, $MOVE_DEPTH)) {
-                $AddedByPrefix{$_}{$Name}=1;
+            $AddedFiles{$Name} = 1;
+            $AddedByDir{getDirname($Name)}{$Name} = 1;
+            $AddedByName{getFilename($Name)}{$Name} = 1;
+            foreach (getPrefixes($Name, $MOVE_DEPTH)) {
+                $AddedByPrefix{$_}{$Name} = 1;
             }
         }
     }
@@ -1407,11 +1536,12 @@ sub detectChanges()
         }
         $FileChanges{$Format}{"Details"}{$Name}{"Status"} = "removed";
     }
-    foreach my $Name (sort {get_depth($b)<=>get_depth($a)} sort keys(%RemovedFiles))
+    
+    foreach my $Name (sort {getDepth($b)<=>getDepth($a)} sort keys(%RemovedFiles))
     { # checking moved files
         my $Format = getFormat($PackageFiles{1}{$Name});
         
-        my $FileName = get_filename($Name);
+        my $FileName = getFilename($Name);
         my @Removed = keys(%{$RemovedByName{$FileName}});
         my @Added = keys(%{$AddedByName{$FileName}});
         
@@ -1421,7 +1551,7 @@ sub detectChanges()
         if($#Added!=0 or $#Removed!=0)
         {
             my $Found = 0;
-            foreach my $Prefix (get_Prefixes($Name, $MOVE_DEPTH))
+            foreach my $Prefix (getPrefixes($Name, $MOVE_DEPTH))
             {
                 my @RemovedPrefix = keys(%{$RemovedByPrefix{$Prefix}});
                 my @AddedPrefix = keys(%{$AddedByPrefix{$Prefix}});
@@ -1440,6 +1570,7 @@ sub detectChanges()
                 next;
             }
         }
+        
         foreach my $File (@Added)
         {
             if($Format ne getFormat($PackageFiles{2}{$File}))
@@ -1457,6 +1588,7 @@ sub detectChanges()
             }
         }
     }
+    
     foreach my $Name (sort keys(%RemovedFiles))
     { # checking renamed files
         if(defined $MovedFiles{$Name})
@@ -1464,16 +1596,16 @@ sub detectChanges()
             next;
         }
         my $Format = getFormat($PackageFiles{1}{$Name});
-        my @Removed = keys(%{$RemovedByDir{get_dirname($Name)}});
-        my @Added = keys(%{$AddedByDir{get_dirname($Name)}});
+        my @Removed = keys(%{$RemovedByDir{getDirname($Name)}});
+        my @Added = keys(%{$AddedByDir{getDirname($Name)}});
         my $Match = 2;
         if($#Removed==0 and $#Added==0) {
             $Match *= 2;
         }
-        my $FName = get_filename($Name);
+        my $FName = getFilename($Name);
         my $Len = length($FName);
-        foreach my $File (sort {getBaseLen($FName, get_filename($b)) <=> getBaseLen($FName, get_filename($a))}
-        sort { abs(length(get_filename($a))-$Len) <=> abs(length(get_filename($b))-$Len) } @Added)
+        foreach my $File (sort {getBaseLen($FName, getFilename($b)) <=> getBaseLen($FName, getFilename($a))}
+        sort { abs(length(getFilename($a))-$Len) <=> abs(length(getFilename($b))-$Len) } @Added)
         {
             if($Format ne getFormat($PackageFiles{2}{$File}))
             { # different formats
@@ -1492,6 +1624,7 @@ sub detectChanges()
             }
         }
     }
+    
     foreach my $Name (sort (keys(%StableFiles), keys(%RenamedFiles), keys(%MovedFiles)))
     { # checking files
         my $Path = $PackageFiles{1}{$Name};
@@ -1548,11 +1681,13 @@ sub detectChanges()
             $Details{"Status"} = "unchanged";
             $Details{"Empty"} = 1;
             $Details{"Rate"} = 0;
+            $UnchangedFiles{$Name} = 1;
         }
         else
         {
             $Details{"Status"} = "unchanged";
             $Details{"Rate"} = 0;
+            $UnchangedFiles{$Name} = 1;
         }
         if($NewName = $RenamedFiles{$Name})
         { # renamed files
@@ -1588,6 +1723,7 @@ sub detectChanges()
         }
         %{$FileChanges{$Format}{"Details"}{$Name}} = %Details;
     }
+    
     foreach my $Name (keys(%AddedFiles))
     { # checking added files
         my $Path = $PackageFiles{2}{$Name};
@@ -1613,11 +1749,13 @@ sub detectChanges()
             "Size"=>0,
             "SizeDelta"=>0
         );
+        
         foreach my $Name (keys(%{$PackageDeps{1}{$Kind}}))
         {
             my $Size = length($Name);
             $DepChanges{$Kind}{"Total"} += 1;
             $DepChanges{$Kind}{"Size"} += $Size;
+            
             if(not defined($PackageDeps{2}{$Kind})
             or not defined($PackageDeps{2}{$Kind}{$Name}))
             { # removed deps
@@ -1626,6 +1764,7 @@ sub detectChanges()
                 $DepChanges{$Kind}{"SizeDelta"} += $Size;
                 next;
             }
+            
             my %Info1 = %{$PackageDeps{1}{$Kind}{$Name}};
             my %Info2 = %{$PackageDeps{2}{$Kind}{$Name}};
             if($Info1{"Op"} and $Info1{"V"}
@@ -1640,6 +1779,7 @@ sub detectChanges()
             }
         }
     }
+    
     foreach my $Kind (keys(%{$PackageDeps{2}}))
     { # added deps
         foreach my $Name (keys(%{$PackageDeps{2}{$Kind}}))
@@ -1696,8 +1836,10 @@ sub detectChanges()
     {
         my $Old = $PackageInfo{$Package}{"V1"};
         my $New = $PackageInfo{$Package}{"V2"};
+        
         my $OldSize = length($Old);
         my $NewSize = length($New);
+        
         $InfoChanges{"Total"} += 1;
         if($Old and not $New)
         {
@@ -1717,8 +1859,10 @@ sub detectChanges()
         {
             my $P1 = $TMP_DIR."/1/".$Package."-info";
             my $P2 = $TMP_DIR."/2/".$Package."-info";
+            
             writeFile($P1, $Old);
             writeFile($P2, $New);
+            
             my ($DLink, $Rate) = diffFiles($P1, $P2, getRPath("info-diffs", $Package."-info"));
             
             # clean space
@@ -1726,10 +1870,12 @@ sub detectChanges()
             rmtree($TMP_DIR."/2/");
             
             $DLink =~s/\A\Q$REPORT_DIR\E\///;
+            
             my %Details = ();
             $Details{"Status"} = "changed";
             $Details{"Rate"} = $Rate;
             $Details{"Diff"} = $DLink;
+            
             %{$InfoChanges{"Details"}{$Package}} = %Details;
             $InfoChanges{"Changed"} += 1;
             $InfoChanges{"Rate"} += $Rate;
@@ -1749,6 +1895,7 @@ sub detectChanges()
     $STAT_LINE .= "moved:".keys(%MovedFiles).";";
     $STAT_LINE .= "renamed:".keys(%RenamedFiles).";";
     $STAT_LINE .= "changed:".keys(%ChangedFiles).";";
+    $STAT_LINE .= "unchanged:".keys(%UnchangedFiles).";";
 }
 
 sub htmlSpecChars($)
@@ -1762,15 +1909,17 @@ sub htmlSpecChars($)
     return $Str;
 }
 
-sub get_Report_Usage()
+sub getReportUsage()
 {
     if(not keys(%PackageUsage)) {
         return "";
     }
+    
     my $Report = "<a name='Usage'></a>\n";
-    $Report .= "<h2>Usage Analysis</h2><hr/>\n";
-    $Report .= "<table class='summary'>\n";
+    $Report .= "<h2>Usage Analysis</h2>\n";
+    $Report .= "<table class='summary highlight'>\n";
     $Report .= "<tr><th>Package</th><th>Status</th><th>Used By</th></tr>\n";
+    
     foreach my $Package (sort keys(%PackageUsage))
     {
         my $Num = keys(%{$PackageUsage{$Package}{"UsedBy"}});
@@ -1795,18 +1944,21 @@ sub get_Report_Usage()
         $Report .= "</tr>\n";
     }
     $Report .= "</table>\n";
+    
     return $Report;
 }
 
-sub get_Report_Headers()
+sub getReportHeaders()
 {
     if(not keys(%PackageInfo)) {
         return "";
     }
+    
     my $Report = "<a name='Info'></a>\n";
-    $Report .= "<h2>Changes In Package Info</h2><hr/>\n";
-    $Report .= "<table class='summary'>\n";
+    $Report .= "<h2>Changes In Package Info</h2>\n";
+    $Report .= "<table class='summary highlight'>\n";
     $Report .= "<tr><th>Package</th><th>Status</th><th>Delta</th><th>Visual Diff</th></tr>\n";
+    
     my %Details = %{$InfoChanges{"Details"}};
     foreach my $Package (sort keys(%Details))
     {
@@ -1828,8 +1980,8 @@ sub get_Report_Headers()
             if($Status eq "changed")
             {
                 $Report .= "<td class='warning'>changed</td>\n";
-                $Report .= "<td class='value'>".show_number($Details{$Package}{"Rate"}*100)."%</td>\n";
-                $Report .= "<td><a href='".$Details{$Package}{"Diff"}."' target=\'$LinksTarget\'>diff</a></td>\n"; # style='color:Blue;'
+                $Report .= "<td class='value'>".showNumber($Details{$Package}{"Rate"}*100)."%</td>\n";
+                $Report .= "<td><a href='".encodeUrl($Details{$Package}{"Diff"})."' target=\'$LinksTarget\'>diff</a></td>\n";
             }
             else
             {
@@ -1840,10 +1992,11 @@ sub get_Report_Headers()
         $Report .= "</tr>\n";
     }
     $Report .= "</table>\n";
+    
     return $Report;
 }
 
-sub get_Report_Deps()
+sub getReportDeps()
 {
     my $Report = "<a name='Deps'></a>\n";
     foreach my $Kind (sort keys(%DepChanges))
@@ -1852,8 +2005,8 @@ sub get_Report_Deps()
         if(not @Names) {
             next;
         }
-        $Report .= "<h2>Changes In \"".ucfirst($Kind)."\" Dependencies</h2><hr/>\n";
-        $Report .= "<table class='summary'>\n";
+        $Report .= "<h2>Changes In \"".ucfirst($Kind)."\" Dependencies</h2>\n";
+        $Report .= "<table class='summary highlight'>\n";
         $Report .= "<tr><th>Name</th><th>Status</th><th>Old<br/>Version</th><th>New<br/>Version</th></tr>\n";
         foreach my $Name (sort {lc($a) cmp lc($b)} @Names)
         {
@@ -1882,7 +2035,7 @@ sub get_Report_Deps()
             if($PackageDeps{1}{$Kind}{$Name})
             {
                 my %Info1 = %{$PackageDeps{1}{$Kind}{$Name}};
-                $Report .= "<td class='value'>".htmlSpecChars(showOp($Info1{"Op"}).$Info1{"V"})."</td>\n";
+                $Report .= "<td class='value'>".showOp($Info1{"Op"}).htmlSpecChars($Info1{"V"})."</td>\n";
             }
             else {
                 $Report .= "<td></td>\n";
@@ -1890,7 +2043,7 @@ sub get_Report_Deps()
             if($PackageDeps{2}{$Kind}{$Name})
             {
                 my %Info2 = %{$PackageDeps{2}{$Kind}{$Name}};
-                $Report .= "<td class='value'>".htmlSpecChars(showOp($Info2{"Op"}).$Info2{"V"})."</td>\n";
+                $Report .= "<td class='value'>".showOp($Info2{"Op"}).htmlSpecChars($Info2{"V"})."</td>\n";
             }
             else {
                 $Report .= "<td></td>\n";
@@ -1905,11 +2058,13 @@ sub get_Report_Deps()
 sub showOp($)
 {
     my $Op = $_[0];
+
     #$Op=~s/<=/&le;/g;
     #$Op=~s/>=/&ge;/g;
+
     if($Op eq "=")
     { # do not show "="
-        $Op="";
+        $Op = "";
     }
     if($Op) {
         $Op = $Op." ";
@@ -1928,7 +2083,7 @@ sub createFileView($$$)
         return undef;
     }
     
-    my $Name = get_filename($File);
+    my $Name = getFilename($File);
     my $Content = readFile($Path);
     my $CssStyles = readModule("Styles", "View.css");
     
@@ -1942,20 +2097,20 @@ sub createFileView($$$)
     
     $Content = "<pre class='view'>".$Content."</pre>\n";
     
-    $Content = "<table cellspacing='0' cellpadding='0'>\n<tr>\n<td class='header'>\n".$Name."</td><td class='plain'><a href=\'$Name\'>plain</a></td>\n</tr>\n<tr>\n<td valign='top' colspan='2'>\n".$Content."</td>\n</tr>\n</table>\n";
-    $Content = composeHTML_Head($Name, "", "View file ".$File, $CssStyles, "")."\n<body>\n".$Content;
+    $Content = "<table cellspacing='0' cellpadding='0'>\n<tr>\n<td class='header'>\n".$Name."</td><td class='plain'><a href=\'".encodeUrl($Name)."\'>plain</a></td>\n</tr>\n<tr>\n<td valign='top' colspan='2'>\n".$Content."</td>\n</tr>\n</table>\n";
+    $Content = composeHTMLHead($Name, "", "View file ".$File, "", "", $CssStyles)."\n<body>\n".$Content;
     $Content .= "</body></html>";
     
     my $R = $Dir."/".$File."-view.html";
     writeFile($REPORT_DIR."/".$R, $Content);
     
     # plain copy
-    copy($Path, $REPORT_DIR."/".$Dir."/".get_dirname($File)."/");
+    copy($Path, $REPORT_DIR."/".$Dir."/".getDirname($File)."/");
     
     return $R;
 }
 
-sub get_Report_Files()
+sub getReportFiles()
 {
     my $Report = "";
     my $JSort = "title='sort' onclick='javascript:sort(this, 1)' style='cursor:pointer'";
@@ -1983,8 +2138,8 @@ sub get_Report_Files()
         }
         
         $Report .= "<a name='".$FormatInfo{$Format}{"Anchor"}."'></a>\n";
-        $Report .= "<h2>".$FormatInfo{$Format}{"Title"}." (".$FileChanges{$Format}{"Total"}.")</h2><hr/>\n";
-        $Report .= "<table class='summary'>\n";
+        $Report .= "<h2>".$FormatInfo{$Format}{"Title"}." (".$FileChanges{$Format}{"Total"}.")</h2>\n";
+        $Report .= "<table class='summary highlight'>\n";
         $Report .= "<tr>\n";
         $Report .= "<th $JSort>Name</th>\n";
         $Report .= "<th $JSort>Status</th>\n";
@@ -2048,16 +2203,16 @@ sub get_Report_Files()
             if(defined $ListAddedRemoved
             and $Info{"Status"}=~/added|removed/)
             {
-                my $FN = get_filename($ShowFile);
+                my $FN = getFilename($ShowFile);
                 if($Info{"Status"} eq "added")
                 {
-                    if(my $View = createFileView($File, 2, "view/added")) {
+                    if(my $View = encodeUrl(createFileView($File, 2, "view/added"))) {
                         $ShowFile=~s&(\A|/)(\Q$FN\E)\Z&$1<a href=\'$View\' target=\'$LinksTarget\' title='View file'>$2</a>&;
                     }
                 }
                 elsif($Info{"Status"} eq "removed")
                 {
-                    if(my $View = createFileView($File, 1, "view/removed")) {
+                    if(my $View = encodeUrl(createFileView($File, 1, "view/removed"))) {
                         $ShowFile=~s&(\A|/)(\Q$FN\E)\Z&$1<a href=\'$View\' target=\'$LinksTarget\' title='View file'>$2</a>&;
                     }
                 }
@@ -2090,13 +2245,13 @@ sub get_Report_Files()
             {
                 if(not $QuickMode and not $Info{"Skipped"}
                 and $Info{"Status"}=~/\A(changed|moved|renamed)\Z/) {
-                    $Report .= "<td class='value'$Join>".show_number($Info{"Rate"}*100)."%</td>\n";
+                    $Report .= "<td class='value'$Join>".showNumber($Info{"Rate"}*100)."%</td>\n";
                 }
                 else {
                     $Report .= "<td$Join></td>\n";
                 }
                 if(my $Link = $Info{"Diff"}) {
-                    $Report .= "<td$Join><a href='".$Link."' target=\'$LinksTarget\'>diff</a></td>\n"; # style='color:Blue;'
+                    $Report .= "<td$Join><a href='".encodeUrl($Link)."' target=\'$LinksTarget\'>diff</a></td>\n";
                 }
                 elsif($Info{"Empty"}) {
                     $Report .= "<td$Join></td>\n";
@@ -2111,7 +2266,7 @@ sub get_Report_Files()
                 if($ShowDetails)
                 {
                     if(my $Link = $Info{"Report"}) {
-                        $Report .= "<td$Join><a href='".$Link."' target=\'$LinksTarget\'>report</a></td>\n"; # style='color:Blue;'
+                        $Report .= "<td$Join><a href='".encodeUrl($Link)."' target=\'$LinksTarget\'>report</a></td>\n";
                     }
                     else {
                         $Report .= "<td$Join></td>\n";
@@ -2127,7 +2282,7 @@ sub get_Report_Files()
                             my $Link1 = $Info{"ABIDump"}{1};
                             my $Link2 = $Info{"ABIDump"}{2};
                             
-                            $Report .= "<td$Join><a href='".$Link1."' target=\'$LinksTarget\'>1</a>, <a href='".$Link2."' target=\'$LinksTarget\'>2</a></td>\n"; # style='color:Blue;'
+                            $Report .= "<td$Join><a href='".encodeUrl($Link1)."' target=\'$LinksTarget\'>1</a>, <a href='".encodeUrl($Link2)."' target=\'$LinksTarget\'>2</a></td>\n";
                         }
                         else {
                             $Report .= "<td$Join></td>\n";
@@ -2139,7 +2294,7 @@ sub get_Report_Files()
                                 my $Link1 = $Info{"DWARFDump"}{1};
                                 my $Link2 = $Info{"DWARFDump"}{2};
                                 
-                                $Report .= "<td$Join><a href='".$Link1."' target=\'$LinksTarget\'>1</a>, <a href='".$Link2."' target=\'$LinksTarget\'>2</a></td>\n"; # style='color:Blue;'
+                                $Report .= "<td$Join><a href='".encodeUrl($Link1)."' target=\'$LinksTarget\'>1</a>, <a href='".encodeUrl($Link2)."' target=\'$LinksTarget\'>2</a></td>\n";
                             }
                             else {
                                 $Report .= "<td$Join></td>\n";
@@ -2161,25 +2316,14 @@ sub get_Report_Files()
     return $Report;
 }
 
-sub appendFile($$)
-{
-    my ($Path, $Content) = @_;
-    return if(not $Path);
-    if(my $Dir = get_dirname($Path)) {
-        mkpath($Dir);
-    }
-    open(FILE, ">>", $Path) || die ("can't open file \'$Path\': $!\n");
-    print FILE $Content;
-    close(FILE);
-}
-
 sub writeFile($$)
 {
     my ($Path, $Content) = @_;
-    return if(not $Path);
-    if(my $Dir = get_dirname($Path)) {
+    
+    if(my $Dir = getDirname($Path)) {
         mkpath($Dir);
     }
+    
     open(FILE, ">", $Path) || die ("can't open file \'$Path\': $!\n");
     print FILE $Content;
     close(FILE);
@@ -2188,15 +2332,16 @@ sub writeFile($$)
 sub readFile($)
 {
     my $Path = $_[0];
-    return "" if(not $Path or not -f $Path);
+    
     open(FILE, "<", $Path);
     local $/ = undef;
     my $Content = <FILE>;
     close(FILE);
+    
     return $Content;
 }
 
-sub get_Prefixes($$)
+sub getPrefixes($$)
 {
     my @Parts = split(/[\/]+/, $_[0]);
     my $Prefix = $Parts[$#Parts];
@@ -2212,7 +2357,7 @@ sub get_Prefixes($$)
     return @Res;
 }
 
-sub get_filename($)
+sub getFilename($)
 { # much faster than basename() from File::Basename module
     if($_[0]=~/([^\/]+)[\/]*\Z/) {
         return $1;
@@ -2220,7 +2365,7 @@ sub get_filename($)
     return "";
 }
 
-sub get_dirname($)
+sub getDirname($)
 { # much faster than dirname() from File::Basename module
     if($_[0]=~/\A(.*?)[\/]+[^\/]*[\/]*\Z/) {
         return $1;
@@ -2228,8 +2373,8 @@ sub get_dirname($)
     return "";
 }
 
-sub separate_path($) {
-    return (get_dirname($_[0]), get_filename($_[0]));
+sub sepPath($) {
+    return (getDirname($_[0]), getFilename($_[0]));
 }
 
 sub exitStatus($$)
@@ -2256,16 +2401,21 @@ sub printMsg($$)
     }
 }
 
-sub cut_path_prefix($$)
+sub cutPathPrefix($$)
 {
     my ($Path, $Prefix) = @_;
-    return $Path if(not $Prefix);
+    
+    if(not $Prefix) {
+        return $Path;
+    }
+    
     $Prefix=~s/[\/]+\Z//;
     $Path=~s/\A\Q$Prefix\E([\/]+|\Z)//;
+    
     return $Path;
 }
 
-sub get_abs_path($)
+sub getAbsPath($)
 { # abs_path() should NOT be called for absolute inputs
   # because it can change them (symlinks)
     my $Path = $_[0];
@@ -2275,19 +2425,37 @@ sub get_abs_path($)
     return $Path;
 }
 
-sub cmd_find($;$$$$)
+sub cmdFind(@)
 {
-    my ($Path, $Type, $Name, $MaxDepth, $UseRegex) = @_;
-    return () if(not $Path or not -e $Path);
-    if(not check_Cmd("find")) {
+    if(not checkCmd("find")) {
         exitStatus("Not_Found", "can't find a \"find\" command");
     }
-    $Path = get_abs_path($Path);
+    
+    my $Path = shift(@_);
+    
+    my ($Type, $Name, $MaxDepth, $UseRegex) = ();
+    
+    if(@_) {
+        $Type = shift(@_);
+    }
+    if(@_) {
+        $Name = shift(@_);
+    }
+    if(@_) {
+        $MaxDepth = shift(@_);
+    }
+    if(@_) {
+        $UseRegex = shift(@_);
+    }
+    
+    $Path = getAbsPath($Path);
+    
     if(-d $Path and -l $Path
     and $Path!~/\/\Z/)
     { # for directories that are symlinks
-        $Path.="/";
+        $Path .= "/";
     }
+    
     my $Cmd = "find \"$Path\"";
     if($MaxDepth) {
         $Cmd .= " -maxdepth $MaxDepth";
@@ -2299,15 +2467,18 @@ sub cmd_find($;$$$$)
     { # wildcards
         $Cmd .= " -name \"$Name\"";
     }
+    
     my $Res = `$Cmd 2>\"$TMP_DIR/null\"`;
     if($?) {
         printMsg("ERROR", "problem with \'find\' utility ($?): $!");
     }
+    
     my @Files = split(/\n/, $Res);
     if($Name and $UseRegex)
     { # regex
         @Files = grep { /\A$Name\Z/ } @Files;
     }
+    
     return @Files;
 }
 
@@ -2319,8 +2490,10 @@ sub generateTemplate()
 
 sub isSCM_File($)
 { # .svn, .git, .bzr, .hg and CVS
-    my ($Dir, $Name) = separate_path($_[0]);
-    if($Dir=~/(\A|[\/\\]+)\.(svn|git|bzr|hg)([\/\\]+|\Z)/) {
+    my $Dir = getDirname($_[0]);
+    my $Name = getFilename($_[0]);
+    
+    if($Dir=~/(\A|[\/\\])\.(svn|git|bzr|hg)([\/\\]|\Z)/) {
         return uc($2);
     }
     elsif($Name=~/\A\.(git|cvs|hg).*/)
@@ -2328,10 +2501,11 @@ sub isSCM_File($)
       # .cvsignore
         return uc($1);
     }
-    elsif($Dir=~/(\A|[\/\\]+)(CVS)([\/\\]+|\Z)/) {
-        return uc($2);
+    elsif($Dir=~/(\A|[\/\\])(CVS)([\/\\]|\Z)/) {
+        return "cvs";
     }
-    return "";
+    
+    return undef;
 }
 
 sub identifyFile($$)
@@ -2352,13 +2526,13 @@ sub identifyFile($$)
     if($Type eq "Ext"
     or $Type eq "iExt")
     {
-        if($Name=~/\.(\w+\.\w+)(\.in|)\Z/i)
+        if($Name=~/\.(\w+\.\w+)(\.(in|\d+)|)\Z/i)
         { # Double extension
             if(my $ID = $FileFormat{$Type}{$1}) {
                 return $ID;
             }
         }
-        if($Name=~/\.(\w+)(\.in|)\Z/i)
+        if($Name=~/\.(\w+)(\.(in|\d+)|)\Z/i)
         { # Single extension
             if(my $ID = $FileFormat{$Type}{$1}) {
                 return $ID;
@@ -2371,37 +2545,42 @@ sub identifyFile($$)
 sub getFormat($)
 {
     my $Path = $_[0];
-    return "" if(not $Path);
+    
     if(defined $Cache{"getFormat"}{$Path}) {
         return $Cache{"getFormat"}{$Path};
     }
-    my $Format = getFormat_($Path);
+    my $Format = getFormat_I($Path);
     
     if($Format=~/\A(OTHER|INFORM|DATA|TEXT)\Z/)
     { # by directory
-        if(my $Dir = get_dirname($PathName{$Path}))
+        if(my $Dir = getDirname($PathName{$Path}))
         {
             my $ID = undef;
+            
             # by dir
-            foreach (reverse(split(/\//, $Dir)))
+            foreach my $SDir (reverse(split(/\//, $Dir)))
             {
-                if($ID = $DirFormat{$_})
+                if($ID = $DirFormat{$SDir})
                 {
                     $Format = $ID;
                     last;
                 }
             }
+            
             if(not defined $ID)
             {
                 # by subdir
-                foreach (keys(%DirFormat))
+                foreach my $SDir (keys(%DirFormat))
                 {
-                    next if(index($_, "/")==-1);
-                    if(index($Dir, $_)!=-1)
+                    if(index($SDir, "/")==-1) {
+                        next;
+                    }
+                    
+                    if(index($Dir, $SDir)!=-1)
                     {
-                        if($Dir=~/(\A|\/)\Q$_\E(\/|\Z)/)
+                        if($Dir=~/(\A|\/)\Q$SDir\E(\/|\Z)/)
                         {
-                            $Format = $DirFormat{$_};
+                            $Format = $DirFormat{$SDir};
                             last;
                         }
                     }
@@ -2456,7 +2635,7 @@ sub getFormat($)
     { # automatic
         if(my $Info = getType($Path))
         {
-            if($Info=~/compressed/i) {
+            if($Info=~/compressed|Zip archive/i) {
                 $Format = "ARCHIVE";
             }
             elsif($Info=~/data/i) {
@@ -2502,29 +2681,41 @@ sub getFormat($)
         $Format = "OTHER";
     }
     
+    if($Format eq "OTHER")
+    {
+        if($AllText) {
+            $Format = "TEXT";
+        }
+    }
+    
     return ($Cache{"getFormat"}{$Path}=$Format);
 }
 
-sub getFormat_($)
+sub getFormat_I($)
 {
     my $Path = $_[0];
-    my ($Dir, $Name) = separate_path($Path);
+    
+    my $Dir = getDirname($Path);
+    my $Name = getFilename($Path);
+    
     $Name=~s/\~\Z//g; # backup files
+    
     if(-l $Path) {
         return "SYMLINK";
     }
     elsif(-d $Path) {
         return "DIR";
     }
-    elsif(my $ID = identifyFile(get_filename($Path), "Name"))
+    elsif(my $ID = identifyFile($Name, "Name"))
     { # check by exact name (case sensitive)
         return $ID;
     }
-    elsif(my $ID2 = identifyFile(get_filename($Path), "iName"))
+    elsif(my $ID2 = identifyFile($Name, "iName"))
     { # check by exact name (case insensitive)
         return $ID2;
     }
-    elsif(my $Kind = isSCM_File($Path)) {
+    elsif($Path=~/svn|git|bzr|hg|cvs/i
+    and my $Kind = isSCM_File($Path)) {
         return $Kind;
     }
     elsif($Name!~/\.(\w+)\Z/i
@@ -2564,7 +2755,8 @@ sub getFormat_($)
     elsif((($Name=~/\.(gz|xz|lzma)\Z/i or $Name=~/\.(\d+)\Z/i)
     and $Dir=~/\/(man\d*|manpages)(\/|\Z)/)
     or ($Name=~/\.(\d+)\Z/i and $Dir=~/\/(doc|docs|src|libs|utils)(\/|\Z)/)
-    or $Name=~/\.(man)\Z/ or $Name=~/[a-z]{3,}\.(\d+)\Z/i)
+    or $Name=~/\.(man)\Z/
+    or ($Name=~/[a-z]{3,}\.(\d+)\Z/i and $Name!~/\.($ARCHIVE_EXT)\./i and $Dir!~/log/i))
     { # harmattan/manpages/uic.1
       # t1utils-1.36/t1asm.1
         return "MANPAGE";
@@ -2586,14 +2778,17 @@ sub getFormat_($)
     elsif($Name=~/\A(CMakeLists.*\.txt)\Z/i) {
         return "CMAKE";
     }
-    elsif(my $ID3 = identifyFile(get_filename($Path), "Ext"))
+    elsif(my $ID3 = identifyFile($Name, "Ext"))
     { # check by extension (case sensitive)
         return $ID3;
     }
-    elsif(my $ID4 = identifyFile(get_filename($Path), "iExt"))
+    elsif(my $ID4 = identifyFile($Name, "iExt"))
     { # check by extension (case insensitive)
         return $ID4;
     }
+    elsif(substr($Name, 0, 1) eq ".") {
+        return "HIDDEN";
+    }
     return "OTHER";
 }
 
@@ -2631,7 +2826,7 @@ sub parseTag($$)
 sub readDescriptor($$)
 {
     my ($Version, $Path) = @_;
-    return if(not -f $Path);
+    
     my $Content = readFile($Path);
     if(not $Content) {
         exitStatus("Error", "XML-descriptor is empty");
@@ -2642,13 +2837,13 @@ sub readDescriptor($$)
     $Content=~s/\/\*(.|\n)+?\*\///g;
     $Content=~s/<\!--(.|\n)+?-->//g;
     if(my $GV = parseTag(\$Content, "version")) {
-        $Group{"V$Version"} = $GV;
+        $Group{"V".$Version} = $GV;
     }
     else {
         exitStatus("Error", "version in the XML-descriptor is not specified (<version> section)");
     }
     if(my $GN = parseTag(\$Content, "group")) {
-        $Group{"Name$Version"} = $GN;
+        $Group{"Name".$Version} = $GN;
     }
     else {
         exitStatus("Error", "group name in the XML-descriptor is not specified (<group> section)");
@@ -2662,14 +2857,14 @@ sub readDescriptor($$)
             }
             if(-d $Path)
             {
-                my @Files = cmd_find($Path, "f", "*.rpm");
-                @Files = (@Files, cmd_find($Path, "f", "*.src.rpm"));
+                my @Files = cmdFind($Path, "f", "*.rpm");
+                @Files = (@Files, cmdFind($Path, "f", "*.src.rpm"));
                 if(not @Files)
                 { # search for DEBs
-                    @Files = (@Files, cmd_find($Path, "f", "*.deb"));
+                    @Files = (@Files, cmdFind($Path, "f", "*.deb"));
                 }
-                foreach (@Files) {
-                    registerPackage($_, $Version);
+                foreach my $F (@Files) {
+                    registerPackage($F, $Version);
                 }
             }
             else {
@@ -2707,9 +2902,8 @@ sub classifyPath($)
 sub skipFileCompare($$)
 {
     my ($Path, $Version) = @_;
-    return 0 if(not $Path or not $Version);
     
-    my $Name = get_filename($Path);
+    my $Name = getFilename($Path);
     if($SkipFiles{$Version}{"Name"}{$Name}) {
         return 1;
     }
@@ -2741,9 +2935,8 @@ sub sepDep($)
         $V=~s/\A[^\-\:]+\://;# cut prefix (1:)
         return ($N, $O, $V);
     }
-    else {
-        return ($Dep, "", "");
-    }
+    
+    return ($Dep, "", "");
 }
 
 sub registerPackage(@)
@@ -2754,20 +2947,7 @@ sub registerPackage(@)
         return ();
     }
     
-    if($CompareDirs)
-    {
-        if(not -d $Path) {
-            return ();
-        }
-    }
-    else
-    {
-        if(not -f $Path) {
-            return ();
-        }
-    }
-    
-    my $PkgName = get_filename($Path);
+    my $PkgName = getFilename($Path);
     my $PkgFormat = getFormat($Path);
     
     my ($CPath, $Attr) = ();
@@ -2783,10 +2963,11 @@ sub registerPackage(@)
     $TargetPackages{$Version}{$PkgName} = 1;
     $Group{"Count$Version"} += 1;
     
-    my @Files = cmd_find($CPath);
+    # search for all files
+    my @Files = cmdFind($CPath);
     foreach my $File (sort @Files)
-    { # search for all files
-        my $FName = cut_path_prefix($File, $CPath);
+    {
+        my $FName = cutPathPrefix($File, $CPath);
         if($PkgFormat eq "RPM"
         or $PkgFormat eq "DEB")
         { # files installed to the system
@@ -2794,9 +2975,9 @@ sub registerPackage(@)
         }
         elsif($PkgFormat eq "ARCHIVE")
         {
-            if($RemovePrefix{$Version})
+            if(my $RmPrefix = $RemovePrefix{$Version})
             { # cut common prefix from all files
-                $FName = cut_path_prefix($FName, $RemovePrefix{$Version});
+                $FName = cutPathPrefix($FName, $RmPrefix);
             }
         }
         if(not $FName) {
@@ -2813,20 +2994,23 @@ sub registerPackage(@)
         $PackageFiles{$Version}{$FName} = $File;
         $PathName{$File} = $FName;
         
-        if(not get_dirname($FName)
-        and getFormat($File) eq "ARCHIVE"
-        and not defined $SkipSubArchives)
+        if(not defined $CompareDirs
+        and not defined $SkipSubArchives
+        and not getDirname($FName)
+        and getFormat($File) eq "ARCHIVE")
         { # go into archives (for SRPM)
             my $SubDir = "$TMP_DIR/xcontent$Version/$FName";
             unpackArchive($File, $SubDir);
+            
             my @SubContents = listDir($SubDir);
             if($#SubContents==0 and -d $SubDir."/".$SubContents[0])
             { # libsample-x.y.z.tar.gz/libsample-x.y.z
                 $SubDir .= "/".$SubContents[0];
             }
-            foreach my $SubFile (cmd_find($SubDir))
+            
+            foreach my $SubFile (cmdFind($SubDir))
             { # search for all files in archive
-                my $SFName = cut_path_prefix($SubFile, $SubDir);
+                my $SFName = cutPathPrefix($SubFile, $SubDir);
                 if(not $SFName) {
                     next;
                 }
@@ -2842,10 +3026,13 @@ sub registerPackage(@)
             }
         }
     }
+    
     delete($PackageFiles{$Version}{"/"});
+    
     if($CheckUsage) {
         checkUsage($Attr->{"Name"});
     }
+    
     return $Attr;
 }
 
@@ -2865,43 +3052,55 @@ sub checkUsage($)
 sub listDir($)
 {
     my $Path = $_[0];
-    return () if(not $Path or not -d $Path);
+    
     opendir(my $DH, $Path);
-    return () if(not $DH);
+    
+    if(not $DH)
+    { # error
+        return ();
+    }
+    
     my @Contents = grep { $_ ne "." && $_ ne ".." } readdir($DH);
     return @Contents;
 }
 
 sub getArchiveFormat($)
 {
-    my $Pkg = get_filename($_[0]);
+    my $Pkg = getFilename($_[0]);
     foreach (sort {length($b)<=>length($a)} keys(%ArchiveFormats))
     {
         my $P = $ArchiveFormats{$_};
-        if($Pkg=~/\.($P)\Z/) {
+        if($Pkg=~/\.($P)(|\.\d+)\Z/i) {
             return $_;
         }
     }
-    return "";
+    return undef;
 }
 
 sub unpackArchive($$)
 { # TODO: tar -xf for all tar.* formats
     my ($Pkg, $OutDir) = @_;
-    mkpath($OutDir);
-    my $Cmd = "";
+    
     my $Format = getArchiveFormat($Pkg);
+    if(not $Format)
+    {
+        printMsg("ERROR", "can't determine format of archive \'".getFilename($Pkg)."\'");
+        return 1;
+    }
+    
+    my $Cmd = undef;
+    
     if($Format=~/TAR\.\w+/i or $Format eq "TAR") {
         $Cmd = "tar -xf \"$Pkg\" --directory=\"$OutDir\"";
     }
     elsif($Format eq "GZ") {
-        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && gunzip \"".get_filename($Pkg)."\"";
+        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && gunzip \"".getFilename($Pkg)."\"";
     }
     elsif($Format eq "LZMA") {
-        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && unlzma \"".get_filename($Pkg)."\"";
+        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && unlzma \"".getFilename($Pkg)."\"";
     }
     elsif($Format eq "XZ") {
-        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && unxz \"".get_filename($Pkg)."\"";
+        $Cmd = "cp -f \"$Pkg\" \"$OutDir\" && cd \"$OutDir\" && unxz \"".getFilename($Pkg)."\"";
     }
     elsif($Format eq "ZIP") {
         $Cmd = "unzip -o \"$Pkg\" -d \"$OutDir\"";
@@ -2909,10 +3108,26 @@ sub unpackArchive($$)
     elsif($Format eq "JAR") {
         $Cmd = "cd \"$OutDir\" && jar -xf \"$Pkg\"";
     }
-    else {
-        return "";
+    elsif($Format eq "APK") {
+        $Cmd = "apktool d -f -o \"$OutDir\" \"$Pkg\"";
+
+        if(not defined $SkipPattern) {
+            $SkipPattern = "apktool.yml|original\/META-INF";
+        }
+        elsif(not $SkipPattern=~m/apktool.yml|original\/META-INF/) {
+            $SkipPattern = "apktool.yml|original\/META-INF|$SkipPattern";
+        }
     }
-    system($Cmd." >$TMP_DIR/output 2>&1");
+    
+    if($Cmd)
+    {
+        mkpath($OutDir);
+        my $TmpFile = $TMP_DIR."/output";
+        qx/$Cmd >$TmpFile 2>&1/;
+        return 0;
+    }
+    
+    return 1;
 }
 
 sub readPackage($$)
@@ -2923,35 +3138,21 @@ sub readPackage($$)
         return ();
     }
     
-    if($CompareDirs)
-    {
-        if(not -d $Path) {
-            return ();
-        }
-    }
-    else
+    my $Format = getFormat($Path);
+    
+    if($CompareDirs and $Format eq "DIR")
     {
-        if(not -f $Path) {
-            return ();
-        }
+        return ($Path, {});
     }
     
     my $CDir = "$TMP_DIR/content$Version";
-    my $CPath = $CDir."/".get_filename($Path);
+    my $CPath = $CDir."/".getFilename($Path);
     
-    my %Attributes = ();
-    my $Format = getFormat($Path);
+    my %Attr = ();
     
-    if($CompareDirs and $Format eq "DIR")
-    {
-        mkpath($CDir);
-        qx/cp -fr $Path $CDir/;
-        
-        return ($CDir."/".get_filename($Path), {});
-    }
-    elsif($Format eq "DEB")
+    if($Format eq "DEB")
     { # Deb package
-        if(not check_Cmd("dpkg-deb")) {
+        if(not checkCmd("dpkg-deb")) {
             exitStatus("Not_Found", "can't find \"dpkg-deb\"");
         }
         mkpath($CPath);
@@ -2959,18 +3160,18 @@ sub readPackage($$)
         if($?) {
             exitStatus("Error", "can't extract package v$Version");
         }
-        if(not check_Cmd("dpkg")) {
+        if(not checkCmd("dpkg")) {
             exitStatus("Not_Found", "can't find \"dpkg\"");
         }
         my $Info = `dpkg -f $Path`;
         if($Info=~/Version\s*:\s*(.+)/) {
-            $Attributes{"Version"} = $1;
+            $Attr{"Version"} = $1;
         }
         if($Info=~/Package\s*:\s*(.+)/) {
-            $Attributes{"Name"} = $1;
+            $Attr{"Name"} = $1;
         }
         if($Info=~/Architecture\s*:\s*(.+)/) {
-            $Attributes{"Arch"} = $1;
+            $Attr{"Arch"} = $1;
         }
         foreach my $Kind ("Depends", "Provides")
         {
@@ -2984,16 +3185,16 @@ sub readPackage($$)
                 }
             }
         }
-        $PackageInfo{$Attributes{"Name"}}{"V$Version"} = $Info;
+        $PackageInfo{$Attr{"Name"}}{"V$Version"} = $Info;
         $Group{"Format"}{$Format} = 1;
     }
     elsif($Format eq "RPM" or $Format eq "SRPM")
     { # RPM or SRPM package
-        if(not check_Cmd("rpm"))
+        if(not checkCmd("rpm"))
         { # rpm and rpm2cpio
             exitStatus("Not_Found", "can't find \"rpm\"");
         }
-        if(not check_Cmd("cpio")) {
+        if(not checkCmd("cpio")) {
             exitStatus("Not_Found", "can't find \"cpio\"");
         }
         mkpath($CPath);
@@ -3001,10 +3202,10 @@ sub readPackage($$)
         if($?) {
             exitStatus("Error", "can't extract package v$Version");
         }
-        ($Attributes{"Version"}, $Attributes{"Release"},
-        $Attributes{"Name"}, $Attributes{"Arch"}) = split(",", queryRPM($Path, "--queryformat \%{version},\%{release},\%{name},\%{arch}"));
-        if($Attributes{"Release"}) {
-            $Attributes{"Version"} .= "-".$Attributes{"Release"};
+        ($Attr{"Version"}, $Attr{"Release"},
+        $Attr{"Name"}, $Attr{"Arch"}) = split(",", queryRPM($Path, "--queryformat \%{version},\%{release},\%{name},\%{arch}"));
+        if($Attr{"Release"}) {
+            $Attr{"Version"} .= "-".$Attr{"Release"};
         }
         foreach my $Kind ("requires", "provides", "suggests")
         {
@@ -3015,27 +3216,30 @@ sub readPackage($$)
                 $TotalDeps{$Kind." ".$N} = 1;
             }
         }
-        $PackageInfo{$Attributes{"Name"}}{"V$Version"} = queryRPM($Path, "--info");
+        $PackageInfo{$Attr{"Name"}}{"V$Version"} = queryRPM($Path, "--info");
         $Group{"Format"}{$Format} = 1;
     }
     elsif($Format eq "ARCHIVE")
     { # TAR.GZ and others
-        unpackArchive(abs_path($Path), $CPath);
-        if(my ($N, $V) = parseVersion(get_filename($Path))) {
-            ($Attributes{"Name"}, $Attributes{"Version"}) = ($N, $V);
+        if(unpackArchive(abs_path($Path), $CPath)!=0) {
+            exitStatus("Error", "can't extract package \'".getFilename($Path)."\'");
+        }
+        
+        if(my ($N, $V) = parseVersion(getFilename($Path))) {
+            ($Attr{"Name"}, $Attr{"Version"}) = ($N, $V);
         }
-        if(not $Attributes{"Version"})
+        if(not $Attr{"Version"})
         { # default version
-            $Attributes{"Version"} = $Version==1?"X":"Y";
+            $Attr{"Version"} = $Version==1?"X":"Y";
         }
-        if(not $Attributes{"Name"})
+        if(not $Attr{"Name"})
         { # default name
-            $Attributes{"Name"} = get_filename($Path);
-            $Attributes{"Name"}=~s/\.($ARCHIVE_EXT)\Z//;
+            $Attr{"Name"} = getFilename($Path);
+            $Attr{"Name"}=~s/\.($ARCHIVE_EXT)\Z//;
         }
         $Group{"Format"}{uc(getExt($Path))} = 1;
     }
-    return ($CPath, \%Attributes);
+    return ($CPath, \%Attr);
 }
 
 sub parseVersion($)
@@ -3087,30 +3291,28 @@ sub queryRPM($$)
     return `rpm -qp $Query \"$Path\" 2>$TMP_DIR/null`;
 }
 
-sub composeHTML_Head($$$$$)
+sub composeHTMLHead($$$$$$)
 {
-    my ($Title, $Keywords, $Description, $Styles, $Scripts) = @_;
+    my ($Title, $Keywords, $Description, $StylesPath, $ScriptsPath, $Styles) = @_;
     return "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
     <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">
     <head>
     <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
+    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />
     <meta name=\"keywords\" content=\"$Keywords\" />
     <meta name=\"description\" content=\"$Description\" />
     <title>
         $Title
     </title>
+    <link rel='stylesheet' type='text/css' href=\'$StylesPath\' />
+    <script type='text/javascript' src=\'$ScriptsPath\'></script>
     <style type=\"text/css\">
-    $Styles
+        $Styles
     </style>
-    <script type=\"text/javascript\" language=\"JavaScript\">
-    <!--
-    $Scripts
-    -->
-    </script>
     </head>";
 }
 
-sub get_Title()
+sub getTitle()
 {
     if($TargetTitle) {
         return $TargetTitle;
@@ -3119,39 +3321,39 @@ sub get_Title()
     return $Group{"Name"};
 }
 
-sub get_Header()
+sub getHeader()
 {
     my $Header = "";
     
     if($CompareDirs and not $TargetName)
     {
-        $Header = "Changes report between <span style='color:Blue;'>".$Group{"Name1"}."/</span> and <span style='color:Blue;'>".$Group{"Name2"}."/</span> directories";
+        $Header = "Changes report between <span style='color:Red;'>".$Group{"Name1"}."</span> and <span style='color:Red;'>".$Group{"Name2"}."</span>";
     }
     elsif($CheckMode eq "Group") {
-        $Header = "Changes report for the <span style='color:Blue;'>".get_Title()."</span> group of packages between <span style='color:Red;'>".$Group{"V1"}."</span> and <span style='color:Red;'>".$Group{"V2"}."</span> versions";
+        $Header = "Changes report for <span style='color:Blue;'>".getTitle()."</span> group of packages between <span style='color:Red;'>".$Group{"V1"}."</span> and <span style='color:Red;'>".$Group{"V2"}."</span> versions";
     }
     else
     { # single package
-        $Header = "Changes report for the <span style='color:Blue;'>".get_Title()."</span> package between <span style='color:Red;'>".$Group{"V1"}."</span> and <span style='color:Red;'>".$Group{"V2"}."</span> versions";
+        $Header = "Changes report for <span style='color:Blue;'>".getTitle()."</span> package between <span style='color:Red;'>".$Group{"V1"}."</span> and <span style='color:Red;'>".$Group{"V2"}."</span> versions";
     }
     
-    if($HideUnchanged) {
-        $Header .= " (hidden unchanged files)";
-    }
+    #if($HideUnchanged) {
+    #    $Header .= " (hidden unchanged files)";
+    #}
     
     return "<h1>".$Header."</h1>";
 }
 
-sub show_number($)
+sub showNumber($)
 {
     if($_[0])
     {
-        my $Num = cut_off_number($_[0], 2, 0);
+        my $Num = cutNumber($_[0], 2, 0);
         if($Num eq "0")
         {
             foreach my $P (3 .. 7)
             {
-                $Num = cut_off_number($_[0], $P, 1);
+                $Num = cutNumber($_[0], $P, 1);
                 if($Num ne "0") {
                     last;
                 }
@@ -3165,7 +3367,7 @@ sub show_number($)
     return $_[0];
 }
 
-sub cut_off_number($$$)
+sub cutNumber($$$)
 {
     my ($num, $digs_to_cut, $z) = @_;
     if($num!~/\./)
@@ -3191,10 +3393,10 @@ sub cut_off_number($$$)
     return $num;
 }
 
-sub get_Summary()
+sub getSummary()
 {
-    my $TestInfo = "<h2>Test Info</h2><hr/>\n";
-    $TestInfo .= "<table class='summary'>\n";
+    my $TestInfo = "<h2>Test Info</h2>\n";
+    $TestInfo .= "<table class='summary highlight'>\n";
     
     if(not $CompareDirs or $TargetName)
     {
@@ -3202,7 +3404,7 @@ sub get_Summary()
             $TestInfo .= "<tr><th class='left'>Group Name</th><td>".$Group{"Name"}."</td></tr>\n";
         }
         else {
-            $TestInfo .= "<tr><th class='left'>Package Name</th><td>".get_Title()."</td></tr>\n";
+            $TestInfo .= "<tr><th class='left'>Package Name</th><td>".getTitle()."</td></tr>\n";
         }
     }
     
@@ -3222,8 +3424,8 @@ sub get_Summary()
     }
     $TestInfo .= "</table>\n";
 
-    my $TestResults = "<h2>Test Results</h2><hr/>\n";
-    $TestResults .= "<table class='summary'>\n";
+    my $TestResults = "<h2>Test Results</h2>\n";
+    $TestResults .= "<table class='summary highlight'>\n";
     
     if(not $CompareDirs)
     {
@@ -3256,7 +3458,7 @@ sub get_Summary()
     
     my ($TotalChanged, $Total) = (0, 0);
     # Files
-    foreach my $Format (keys(%FileChanges))
+    foreach my $Format (sort keys(%FileChanges))
     {
         $TotalChanged += $FileChanges{$Format}{"SizeDelta"};
         $Total += $FileChanges{$Format}{"Size"};
@@ -3275,7 +3477,7 @@ sub get_Summary()
     if($Total) {
         $Affected = 100*$TotalChanged/$Total;
     }
-    $Affected = show_number($Affected);
+    $Affected = showNumber($Affected);
     if($Affected>=100) {
         $Affected = 100;
     }
@@ -3297,24 +3499,24 @@ sub get_Summary()
     
     if(defined $ABI_Change{"Total"})
     {
-        $TestResults .= "<h2>ABI Status</h2><hr/>\n";
-        $TestResults .= "<table class='summary'>\n";
+        $TestResults .= "<h2>ABI Status</h2>\n";
+        $TestResults .= "<table class='summary highlight'>\n";
         $TestResults .= "<tr><th class='left'>Total Objects<br/>(with debug-info)</th><td>".$ABI_Change{"Total"}."</td></tr>\n";
         my $Status = $ABI_Change{"Bin"}/$ABI_Change{"Total"};
         if($Status==100) {
             $TestResults .= "<tr><th class='left'>ABI Compatibility</th><td><span style='color:Green;'><b>100%</b></span></td></tr>\n";
         }
         else {
-            $TestResults .= "<tr><th class='left'>ABI Compatibility</th><td><span style='color:Red;'><b>".show_number(100-$Status)."%</b></span></td></tr>\n";
+            $TestResults .= "<tr><th class='left'>ABI Compatibility</th><td><span style='color:Red;'><b>".showNumber(100-$Status)."%</b></span></td></tr>\n";
         }
         $TestResults .= "</table>\n";
     }
     
-    my $FileChgs = "<a name='Files'></a><h2>Changes In Files</h2><hr/>\n";
+    my $FileChgs = "<a name='Files'></a><h2>Changes In Files</h2>\n";
     
     if(keys(%TotalFiles))
     {
-        $FileChgs .= "<table class='summary'>\n";
+        $FileChgs .= "<table class='summary highlight'>\n";
         $FileChgs .= "<tr>";
         $FileChgs .= "<th>File Type</th>";
         $FileChgs .= "<th>Total</th>";
@@ -3378,14 +3580,14 @@ sub get_Summary()
         $FileChgs .= "No files\n";
     }
     
-    return $TestInfo.$TestResults.get_Report_Headers().get_Report_Deps().$FileChgs;
+    return $TestInfo.$TestResults.getReportHeaders().getReportDeps().$FileChgs;
 }
 
-sub get_Source()
+sub getSource()
 {
     my $Packages = "<a name='Packages'></a>\n";
     my %Pkgs = map {$_=>1} (keys(%{$TargetPackages{1}}), keys(%{$TargetPackages{2}}));
-    $Packages .= "<h2>Packages (".keys(%Pkgs).")</h2><hr/>\n";
+    $Packages .= "<h2>Packages (".keys(%Pkgs).")</h2>\n";
     $Packages .= "<div class='p_list'>\n";
     foreach my $Name (sort keys(%Pkgs)) {
         $Packages .= $Name."<br/>\n";
@@ -3397,8 +3599,32 @@ sub get_Source()
 sub createReport($)
 {
     my $Path = $_[0];
-    my $CssStyles = readModule("Styles", "Index.css");
-    my $JScripts = readModule("Scripts", "Sort.js");
+
+    my $CssStyles = getModulePath("Styles", "Index.css");
+    my $JScripts = getModulePath("Scripts", "Sort.js");
+    my $VeraMono = getModulePath("Fonts", "VeraMono.ttf");
+    my $OpenSans = getModulePath("Fonts", "OpenSans.ttf");
+
+    my $StuffDir = getDirname($Path);
+    my $SuffixDir = "";
+    if($MoveStyles) {
+        $SuffixDir = $MoveStyles;
+    }
+
+    my $EmbedStyles = $StuffDir."/".$SuffixDir."css/Index.css";
+    my $EmbedJS = $StuffDir."/".$SuffixDir."js/Sort.js";
+    my $EmbedVeraMono = $StuffDir."/".$SuffixDir."fonts/VeraMono.ttf";
+    my $EmbedOpenSans = $StuffDir."/".$SuffixDir."fonts/OpenSans.ttf";
+
+    mkpath(getDirname($EmbedStyles));
+    mkpath(getDirname($EmbedJS));
+    mkpath(getDirname($EmbedVeraMono));
+
+    copy($CssStyles, $EmbedStyles);
+    copy($JScripts, $EmbedJS);
+    copy($VeraMono, $EmbedVeraMono);
+    copy($OpenSans, $EmbedOpenSans);
+
     printMsg("INFO", "creating report ...");
     
     my $Title = undef;
@@ -3411,42 +3637,39 @@ sub createReport($)
     }
     else
     {
-        $Title = get_Title().": ".$Group{"V1"}." to ".$Group{"V2"}." changes report";
-        $Keywords = get_Title().", changes, report";
+        $Title = getTitle().": ".$Group{"V1"}." to ".$Group{"V2"}." changes report";
+        $Keywords = getTitle().", changes, report";
     }
     
-    my $Header = get_Header();
+    my $Header = getHeader();
     my $Description = $Header;
     $Description=~s/<[^<>]+>//g;
     
     my $Report = $Header."\n";
-    my $MainReport = get_Report_Files();
+    my $MainReport = getReportFiles();
     
-    my $Legend = "<br/><table class='summary'>
+    my $Legend = "<table class='summary highlight'>
     <tr><td class='new' width='80px'>added</td><td class='passed' width='80px'>unchanged</td></tr>
     <tr><td class='warning'>changed</td><td class='failed'>removed</td></tr></table>\n";
     
     $Report .= $Legend;
-    $Report .= get_Summary();
+    $Report .= getSummary();
     $Report .= $MainReport;
     
     if(not $CompareDirs)
     {
-        $Report .= get_Report_Usage();
-        $Report .= get_Source();
+        $Report .= getReportUsage();
+        $Report .= getSource();
     }
     
     $Report .= "<br/><a class='top_ref' href='#Top'>to the top</a><br/>\n";
     
     $STAT_LINE = "changed:".$RESULT{"affected"}.";".$STAT_LINE."tool_version:".$TOOL_VERSION;
-    $Report = "<!-- $STAT_LINE -->\n".composeHTML_Head($Title, $Keywords, $Description, $CssStyles, $JScripts)."\n<body>\n<div><a name='Top'></a>\n".$Report;
-    $Report .= "</div>\n<br/><br/><br/><hr/>\n";
+    $Report = "<!-- $STAT_LINE -->\n".composeHTMLHead($Title, $Keywords, $Description, $SuffixDir."css/Index.css", $SuffixDir."js/Sort.js", "")."\n<body>\n<div><a name='Top'></a>\n".$Report;
+    $Report .= "</div>\n<br/><hr/>\n";
     
     # footer
-    $Report .= "<div class='footer' style='width:100%;' align='right'><i>Generated";
-    $Report .= " by <a href='".$HomePage."'>PkgDiff</a>";
-    $Report .= " $TOOL_VERSION &#160;";
-    $Report .= "</i></div><br/>\n";
+    $Report .= "<div class='footer' style='width:100%;' align='center'><a href='".$HomePage."'>github.com/lvc/pkgdiff</a></div><br/>\n";
     
     $Report .= "</body></html>";
     writeFile($Path, $Report);
@@ -3461,20 +3684,20 @@ sub createReport($)
     printMsg("INFO", "report: $Path");
 }
 
-sub check_Cmd($)
+sub checkCmd($)
 {
     my $Cmd = $_[0];
-    return "" if(not $Cmd);
-    if(defined $Cache{"check_Cmd"}{$Cmd}) {
-        return $Cache{"check_Cmd"}{$Cmd};
+    
+    if(defined $Cache{"checkCmd"}{$Cmd}) {
+        return $Cache{"checkCmd"}{$Cmd};
     }
     foreach my $Path (sort {length($a)<=>length($b)} split(/:/, $ENV{"PATH"}))
     {
         if(-x $Path."/".$Cmd) {
-            return ($Cache{"check_Cmd"}{$Cmd} = 1);
+            return ($Cache{"checkCmd"}{$Cmd} = 1);
         }
     }
-    return ($Cache{"check_Cmd"}{$Cmd} = 0);
+    return ($Cache{"checkCmd"}{$Cmd} = 0);
 }
 
 sub readFileTypes()
@@ -3580,7 +3803,7 @@ sub autoAnchor($)
     return $Anchor;
 }
 
-sub get_dumpversion($)
+sub getDumpversion($)
 {
     my $Cmd = $_[0];
     return `$Cmd -dumpversion 2>$TMP_DIR/null`;
@@ -3616,16 +3839,23 @@ sub getArchivePattern()
     return join("|", @Groups);
 }
 
+sub encodeUrl($)
+{
+    my $Url = $_[0];
+    $Url=~s/#/\%23/g;
+    return $Url;
+}
+
 sub scenario()
 {
     if($Help)
     {
-        HELP_MESSAGE();
+        helpMsg();
         exit(0);
     }
     if($ShowVersion)
     {
-        printMsg("INFO", "Package Changes Analyzer (PkgDiff) $TOOL_VERSION\nCopyright (C) 2016 Andrey Ponomarenko's ABI Laboratory\nLicense: GNU GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.");
+        printMsg("INFO", "Package Changes Analyzer (PkgDiff) $TOOL_VERSION\nCopyright (C) 2022 Andrey Ponomarenko's ABI Laboratory\nLicense: GNU GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.");
         exit(0);
     }
     if($DumpVersion)
@@ -3638,6 +3868,16 @@ sub scenario()
         generateTemplate();
         exit(0);
     }
+    
+    if(checkModule("File/LibMagic.pm"))
+    {
+        $USE_LIBMAGIC = 1;
+        require File::LibMagic;
+    }
+    else {
+        printMsg("WARNING", "perl-File-LibMagic is not installed");
+    }
+    
     if(not $DiffWidth) {
         $DiffWidth = $DEFAULT_WIDTH;
     }
@@ -3654,13 +3894,13 @@ sub scenario()
         exitStatus("Not_Found", "can't access \"$DIFF\"");
     }
     
-    if(not check_Cmd("wdiff")) {
+    if(not checkCmd("wdiff")) {
         print STDERR "WARNING: wdiff is not installed\n";
     }
     
     if(not $LinksTarget)
     {
-        $LinksTarget = "_blank";
+        $LinksTarget = "_self";
     }
     else
     {
@@ -3672,7 +3912,7 @@ sub scenario()
     
     if($ShowDetails)
     {
-        if(my $V = get_dumpversion($ACC))
+        if(my $V = getDumpversion($ACC))
         {
             if(cmpVersions($V, $ACC_VER)==-1)
             {
@@ -3686,7 +3926,7 @@ sub scenario()
             $ACC = undef;
         }
         
-        if(my $V = get_dumpversion($ABI_DUMPER))
+        if(my $V = getDumpversion($ABI_DUMPER))
         {
             if(cmpVersions($V, $ABI_DUMPER_VER)==-1)
             {
@@ -3717,6 +3957,8 @@ sub scenario()
         if(not -d $Descriptor{2}) {
             exitStatus("Access_Error", "can't access directory \'".$Descriptor{2}."\'");
         }
+        $Descriptor{1} = getAbsPath($Descriptor{1});
+        $Descriptor{2} = getAbsPath($Descriptor{2});
     }
     else
     {
@@ -3731,10 +3973,10 @@ sub scenario()
     readFileTypes();
     
     if($CompareDirs) {
-        printMsg("INFO", "reading directories ...");
+        printMsg("INFO", "Reading directories ...");
     }
     else {
-        printMsg("INFO", "reading packages ...");
+        printMsg("INFO", "Reading packages ...");
     }
     
     my $Fmt1 = getFormat($Descriptor{1});
@@ -3744,8 +3986,8 @@ sub scenario()
     
     if($CompareDirs and $Fmt1 eq "DIR")
     {
-        $RemovePrefix{1} = get_dirname($Descriptor{1});
-        $RemovePrefix{2} = get_dirname($Descriptor{2});
+        $RemovePrefix{1} = getDirname($Descriptor{1});
+        $RemovePrefix{2} = getDirname($Descriptor{2});
     }
     elsif($Fmt1 eq "ARCHIVE" and $Fmt2 eq "ARCHIVE")
     { # check if we can remove a common prefix from files of BOTH packages
@@ -3767,7 +4009,7 @@ sub scenario()
     if($CompareDirs and $Fmt1 eq "DIR")
     {
         registerPackage($Descriptor{1}, 1);
-        $Group{"Name1"} = get_filename($Descriptor{1});
+        $Group{"Name1"} = getFilename($Descriptor{1});
         if($TargetVersion{1}) {
             $Group{"V1"} = $TargetVersion{1};
         }
@@ -3800,7 +4042,7 @@ sub scenario()
     if($CompareDirs and $Fmt1 eq "DIR")
     {
         registerPackage($Descriptor{2}, 2);
-        $Group{"Name2"} = get_filename($Descriptor{2});
+        $Group{"Name2"} = getFilename($Descriptor{2});
         if($TargetVersion{2}) {
             $Group{"V2"} = $TargetVersion{2};
         }
@@ -3871,7 +4113,7 @@ sub scenario()
     if($OutputReportPath)
     { # user-defined path
         $REPORT_PATH = $OutputReportPath;
-        $REPORT_DIR = get_dirname($REPORT_PATH);
+        $REPORT_DIR = getDirname($REPORT_PATH);
         if(not $REPORT_DIR) {
             $REPORT_DIR = ".";
         }
@@ -3889,16 +4131,29 @@ sub scenario()
         $REPORT_PATH = $REPORT_DIR."/changes_report.html";
         if(-d $REPORT_DIR)
         {
-            rmtree($REPORT_DIR."/info-diffs");
-            rmtree($REPORT_DIR."/diffs");
-            rmtree($REPORT_DIR."/details");
+            foreach my $E ("info-diffs", "diffs", "details") {
+                rmtree($REPORT_DIR."/".$E);
+            }
         }
     }
-    printMsg("INFO", "comparing packages ...");
+    
+    if($CompareDirs) {
+        printMsg("INFO", "Comparing directories ...");
+    }
+    else {
+        printMsg("INFO", "Comparing packages ...");
+    }
     
     detectChanges();
     createReport($REPORT_PATH);
     
+    foreach my $E ("info-diffs", "diffs", "details")
+    {
+        if(not listDir($REPORT_DIR."/".$E)) {
+            rmtree($REPORT_DIR."/".$E);
+        }
+    }
+    
     if($ExtraInfo) {
         writeExtraInfo();
     }
@@ -3906,6 +4161,7 @@ sub scenario()
     if($CustomTmpDir) {
         cleanTmp();
     }
+    
     exit($ERROR_CODE{$RESULT{"status"}});
 }
 
