diff -uNr fwbuilder-2.1.8/build_num fwbuilder-2.1.9/build_num
--- fwbuilder-2.1.8/build_num	2006-12-03 17:44:24.000000000 +0100
+++ fwbuilder-2.1.9/build_num	2007-02-11 04:39:09.000000000 +0100
@@ -1 +1 @@
-#define BUILD_NUM 190
+#define BUILD_NUM 215
diff -uNr fwbuilder-2.1.8/configure fwbuilder-2.1.9/configure
--- fwbuilder-2.1.8/configure	2006-12-03 17:44:28.000000000 +0100
+++ fwbuilder-2.1.9/configure	2007-02-11 04:39:13.000000000 +0100
@@ -5928,6 +5928,20 @@
     DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
     ;;
 
+  *-*-kfreebsd*)
+    OS=FreeBSD
+    OS_FREEBSD=1
+    if test -f /etc/debian_version ; then
+       DISTRO=Debian
+    else
+       DISTRO="Unknown"
+    fi
+    MANDIR="${PREFIX}/share/man/"
+    echo "$as_me:$LINENO: result: $DISTRO GNU/kFreeBSD" >&5
+echo "${ECHO_T}$DISTRO GNU/kFreeBSD" >&6
+    DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
+    ;;
+
   *-*-linux*)
     DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
     OS=Linux
diff -uNr fwbuilder-2.1.8/configure.in fwbuilder-2.1.9/configure.in
--- fwbuilder-2.1.8/configure.in	2006-09-06 05:53:35.000000000 +0200
+++ fwbuilder-2.1.9/configure.in	2007-02-10 23:41:00.000000000 +0100
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.63 2006/09/06 03:53:35 vkurland Exp $
+dnl $Id: configure.in,v 1.64 2007/02/10 22:41:00 vkurland Exp $
 
 AC_INIT(src/gui/main.cpp)
 AC_CANONICAL_SYSTEM
@@ -309,6 +309,19 @@
     DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
     ;;
 
+  *-*-kfreebsd*)
+    OS=FreeBSD
+    OS_FREEBSD=1
+    if test -f /etc/debian_version ; then
+       DISTRO=Debian
+    else
+       DISTRO="Unknown"
+    fi
+    MANDIR="${PREFIX}/share/man/"
+    AC_MSG_RESULT($DISTRO GNU/kFreeBSD)
+    DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
+    ;;
+
   *-*-linux*)
     DEFAULT_RES_DIR="${PREFIX}/share/fwbuilder${FWB_MAJOR_VERSION}${FWB_MINOR_VERSION}"
     OS=Linux
diff -uNr fwbuilder-2.1.8/doc/ChangeLog fwbuilder-2.1.9/doc/ChangeLog
--- fwbuilder-2.1.8/doc/ChangeLog	2006-12-03 17:42:24.000000000 +0100
+++ fwbuilder-2.1.9/doc/ChangeLog	2007-02-10 23:49:08.000000000 +0100
@@ -1,3 +1,210 @@
+2007-02-10  vadim  <vadim@vk.crocodile.org>
+
+	* v2.1.9 release
+	
+	* main.cpp (tty_raw): bug #1650369: "[patch] please add support
+	for GNU/kFreeBSD". Applied patch to make code compile on kFreeBSD.
+
+2007-02-03  vadim  <vadim@vk.crocodile.org>
+
+	* listOfLibraries.cpp (list): fixed bug #1620284: "conflict when
+	adding library to Preferences/Libraries". When the user tried to
+	add a library to the list in Preferemces/Libraries when a data
+	file with the same object library was loaded, the GUI detected the
+	conflict and showed error dialog.
+
+	* FWWindow.cpp (FWWindow::fileCompare): New feature: new operation
+	"Tools/Find Conflicting Objects in Two Data Files". This operation
+	inspects two data files (either .fwb or .fwl) and finds
+	conflicting objects. Conflicting objects have the same internal ID
+	but different attributes. Two data files can not be merged, or one
+	imported into another, if they contain such objects. This
+	operation also helps identify changes made to objects in two
+	copies of the same data file. This operation does not find objects
+	present in one file but not in the other, such objects present no
+	problem for merge or import operations. This operation works with
+	two external files, neither of which needs to be opened in the
+	program. Currently opened data file is not affected by this
+	operation and objects in the tree do not change. In the process of
+	this operation user is presented with series of dialogs showing
+	conflicting objects side by side. In the end the program can
+	generate report and write it to a text file.
+
+2007-01-30  vadim  <vadim@vk.crocodile.org>
+
+	* instDialog.cpp (instDialog::initiateCopy): more for the bug
+	#1617501:"Install fails after compile". Making sure we always
+	strip directory path from the file name if user specified full
+	path for the policy file in the "Output file name" input field in
+	the "Compiler" tab of firewall object dialog. Need to strip path
+	when macro "%FWSCRIPT%" is substituted in installation scriptlets
+	and in some other places.
+
+2007-01-15  vadim  <vadim@vk.crocodile.org>
+
+	* OSConfigurator_linux24.cpp (linux24::printRunTimeWrappers): 
+	fixed bug (no num.): data files used for run-time AddressTable
+	objects can have empty lines, the script should skip them.
+
+2007-01-14  vadim  <vadim@vk.crocodile.org>
+
+	* iptAdvancedDialog.cpp (iptAdvancedDialog::iptAdvancedDialog):
+	more for bug #1618381: "CLASSIFY/MARK are non-terminating".
+	Emulation of the terminating behavior for Classify and Tag actions
+	is now controlled by a global option in the "Compiler" tab of the
+	firewall properties dialog. This means emulation can be turned on
+	and off for all rules that might require it at once. It is
+	impossible to mix such rules with terminating and non-termninating
+	behavior. The reason for this is that shadowing detection
+	algorithm can only work with either terminating or non-terminating
+	rules, not with the mix. Hopefully this is the last change made
+	for this bug.
+
+	* PolicyCompiler_ipt.cpp (ipt::getAddressTableVarName): fixed bug
+	#1632054: "Runtime AddressObjects FAIL to load if "Name:" contains
+	"."". Compiler checks if the name of the run-time AddressTable
+	object contains characters that have special meaning in sheel and
+	relaces them with '_' when it generates the name of the temporary
+	shell variable.
+
+	* PolicyCompiler_ipt.cpp (splitNonTerminatingTargets): update for
+	bug #1618381: "CLASSIFY/MARK are non-terminating". Adding iptables
+	rule with target ACCEPT to make Tag and Classify rules
+	terminating. This is controlled by checkbox in the action dialog
+	for actions Classify and Tag. Default setting is off.
+
+2007-01-09  vadim  <vadim@vk.crocodile.org>
+
+	* FWWindow.cpp (FWWindow::scheduleRuleSetRedraw): fixed bug (no
+	num.): GUI used show fanthom 'Policy', 'NAT' and 'Routing' tabs
+	when user deleted objects from the Deleted Objects library,
+	provided some of these objects were previously deleted firewalls.
+
+2007-01-07  vadim  <vadim@vk.crocodile.org>
+
+	* GroupObjectDialog.cpp (GroupObjectDialog::dropped): fixed bug
+	#1624577: "group window doesn't stay open on multiple-adds". Using
+	special flag to tell ObjectTreeView that it should ignore
+	MouseReleaseEvent it gets after d&d operation, so it wont switch
+	object in the editor panel. Note the bug triggered only on Mac OS
+	X.
+
+	* FWWindow.cpp (FWWindow::FWWindow): "Apply" and "Close" buttons
+	in the objct editor panel should be of fixed size horizontally
+
+2007-01-06  vadim  <vadim@vk.crocodile.org>
+
+	* instDialog.cpp (instDialog::testFirewall): fixed bug
+	#1617501:"Install fails after compile". The GUI got confused when
+	user enter full path to the policy file in the "Output file name"
+	input field in the "Compiler" tab of firewall object dialog.
+
+	* SimpleTextEditor.cpp (SimpleTextEditor::loadFromFile): fixed bug
+	1619930: "Prolog tab's ScriptEditor's import fails to overwrite"
+
+	* OSConfigurator_linux24.cpp (linux24::printRunTimeWrappers):
+	fixed bug #1628989: "run-time-loaded rules don't accept ";" as
+	line comment"
+
+	* RuleOptionsDialog.cpp (RuleOptionsDialog::changed): fixed bug
+	#1620206: "RuleOptions' "Apply" button greyed-out until menu
+	selection"
+
+	* SimpleTextEditor.cpp (SimpleTextEditor::SimpleTextEditor): fixed
+	bug #1619842: "prolog "script editor" opens behind other windows"
+
+	* RuleSetView.cpp (RuleSetView::removeRule): fixed bug #1629521:
+	"can't delete empty chain/policy tab"
+
+	* instOptionsDialog.cpp (instOptionsDialog::hidePIXOptions):
+	installOptionsDialog was too large and did not fit on some laptop
+	screens. Doing tricks to make sure the dialog properly resized
+	after unused GUI elements are hidden.
+	
+
+2007-01-04  vadim  <vadim@vk.crocodile.org>
+
+	* PolicyCompiler.cpp (DetectShadowingForNonTerminatingRules::processNext):
+	(API change)
+	fixed bug #1618381: "CLASSIFY/MARK are non-terminating". Non-terminating
+	rules shadow each other "backwards", that is more general rule
+	shadows other rules _above_ it. Added flag 'reverse' to the method
+	find_more_general_rule and added new rule processor
+	DetectShadowingForNonTerminatingRules that finds such cases of
+	'reverse' shadowing. Using it for rules in the mangle table for iptables.
+
+	
+	* PolicyCompiler_ipt.cpp (finalizeChain::processNext): working on
+	bug #1618381
+
+	 * For action Branch with option to add branching rule to the
+	 mangle table: we now generate rules in PREROUTING, POSTROUTING,
+	 INPUT, OUTPUT and FORWARD chains. This is because some targets
+	 can only work in PREROUTING or POSTROUTING chains but we do not
+	 know what rules will user put in the branch. So we need to branch
+	 in all chains
+
+	 * For rules in mangle table with direction set to Inbound or
+	 Outbound force chain to PREROUTING or POSTROUTING respectively
+	 early. This eliminates duplicates such as the same rule in
+	 PREROUTING and INPUT chains. Also since most (all?) targets that
+	 require mangle table go into either PREROUTING or POSTROUTING
+	 chains, it should be enough to use these two chains.
+
+2007-01-01  vadim  <vadim@vk.crocodile.org>
+
+
+	* ActionsDialog.cpp (ActionsDialog::setRule),
+	PolicyCompiler_ipt.cpp (splitNonTerminatingTargets::processNext):
+	working on bug #1618381: "CLASSIFY/MARK are
+	non-terminating". Converting non-terminating targets MARK and
+	CLASSIFY into equivalent of terminating targets using intermediate
+	chain and "-g" option to pass control to it. Added a checkbox to
+	the rule options dialog for action Classify for this, by default
+	this feature is off.
+	
+
+2006-12-27  vadim  <vadim@vk.crocodile.org>
+
+	* Compiler.cpp (Compiler::expandGroupsInRuleElement): fixed bug
+	#1620925: "compile-time AddressTable object with empty file".
+	Compile-time AddressTable object that uses file with no addresses
+	should be treated as an empty group according to the "Ignore empty
+	groups" option. Changes are made as follows:
+
+	 - Compiler::expandGroupsInRuleElement does not call
+	s->setAnyElement(); to set rule element to 'any' before adding
+	addresses from the group. This means that if group is empty, rule
+	element remains empty (not even 'any', just with no children,
+	i.e. with size()==0).  Note that AddressTable::loadFromSource()
+	leaves AddressTable object empty if the file does not have any
+	addresses.
+
+	 - Compiler::emptyGroupsInRE specifically checks for run-time
+	MultiAddress objects and skips them so they wont be treated as
+	empty groups (since they are indeed empty). Compile-time
+	MultiAddress objects are treated as groups and algorithm that
+	depends on option 'ignore empty groups' is executed for both empty
+	regular groups and empty compile-time MultiAddress objects.
+
+	* PolicyCompiler_ipt_optimizer.cpp (optimize1::optimizeForRuleElement):
+	fixed bug #1623113: 'connlimit fails in compiled "address table" rules'
+	Module connlimit can only be used in iptables rules matching TCP services.
+	Such iptables commands have "-p tcp" and/or "-m tcp" options. If
+	a rule in fwbuilder uses TCP Service and connlimit option and has
+	multiple objects in src and dst, optimizer used to split it to minimize 
+	matches. It however preserved connlimit option in all subrules,
+	even though some of them did not have TCP service after the split. This
+	lead to generation of incorrect iptables commands.
+	
+	* PolicyCompiler_ipt.cpp (Branching::expandBranch): fixed bug
+	#1623338: "Can not disable rules in a branch". Compiler for
+	iptables ignored flag 'disabled' on rules in a branch.
+
+2006-12-26  vadim  <vadim@vk.crocodile.org>
+
+	* VERSION (FWB_MICRO_VERSION): set version to 2.1.9
+
 2006-12-03  vadim  <vadim@vk.crocodile.org>
 
 	* v2.1.8 released
diff -uNr fwbuilder-2.1.8/fwbuilder2.spec fwbuilder-2.1.9/fwbuilder2.spec
--- fwbuilder-2.1.8/fwbuilder2.spec	2006-12-03 17:44:36.000000000 +0100
+++ fwbuilder-2.1.9/fwbuilder2.spec	2007-02-11 04:39:22.000000000 +0100
@@ -1,6 +1,6 @@
 
 %define name    fwbuilder
-%define version 2.1.8
+%define version 2.1.9
 %define release 1
 %define BUILD_VERSION 21
 
@@ -24,8 +24,9 @@
 
 Buildroot:      %{_tmppath}/%{name}-%{version}-root
 
-Requires:      libfwbuilder = 2.1.8
-BuildRequires: libfwbuilder-devel = 2.1.8
+Requires:      libfwbuilder = 2.1.9
+BuildRequires: libfwbuilder-devel = 2.1.9
+BuildRequires: libxml2-devel, libxslt-devel
 %if "%_vendor" == "redhat"
 BuildRequires: qt-devel
 %else
diff -uNr fwbuilder-2.1.8/po/POmakefile fwbuilder-2.1.9/po/POmakefile
--- fwbuilder-2.1.8/po/POmakefile	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/po/POmakefile	2007-02-11 04:39:19.000000000 +0100
@@ -94,7 +94,7 @@
 STRIP = @STRIP@
 UIC = @UIC@
 USE_NLS = yes
-VERSION = 2.1.8
+VERSION = 2.1.9
 X_CFLAGS = @X_CFLAGS@
 X_EXTRA_LIBS = @X_EXTRA_LIBS@
 X_LIBS = @X_LIBS@
diff -uNr fwbuilder-2.1.8/qmake.inc fwbuilder-2.1.9/qmake.inc
--- fwbuilder-2.1.8/qmake.inc	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/qmake.inc	2007-02-11 04:39:18.000000000 +0100
@@ -17,7 +17,7 @@
     OBJECTS_DIR = .obj
 
 	PREFIX                  = /usr/local
-	DOCDIR                  = /usr/local/share/doc/fwbuilder-2.1.8
+	DOCDIR                  = /usr/local/share/doc/fwbuilder-2.1.9
 	MANDIR                  = /usr/local/share/man/
 	LIBS_FWCOMPILER         = -pthread -lfwcompiler -lfwbuilder -lxslt -lxml2 -lz -lnetsnmp -lelf -lm -lssl -lcrypto
 	LIBS_FWBUILDER          = -pthread -lfwbuilder -lxslt -lxml2 -lz -lnetsnmp -lelf -lm -lssl -lcrypto
diff -uNr fwbuilder-2.1.8/src/gui/ActionsDialog.cpp fwbuilder-2.1.9/src/gui/ActionsDialog.cpp
--- fwbuilder-2.1.8/src/gui/ActionsDialog.cpp	2006-10-24 05:43:24.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ActionsDialog.cpp	2007-01-15 05:37:51.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Illiya Yalovoy <yalovoy@gmail.com>
 
-  $Id: ActionsDialog.cpp,v 1.23 2006/10/24 03:43:24 vkurland Exp $
+  $Id: ActionsDialog.cpp,v 1.28 2007/01/15 04:37:51 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -134,7 +134,7 @@
 
     if (editor=="BranchChain" || editor=="BranchAnchor")
     {
-        mw->setPolicyBranchTabName(rule);
+        mw->setPolicyBranchTabName(rule->getBranch());
     }
 
     if (useDummyNetPipe->isChecked())
@@ -210,10 +210,35 @@
         useDummyNetQueue->setChecked(1);
     }
 
+    if (platform=="iptables")
+    {
+        classify_txt_1->show();
+        classify_terminating->show();
+        tag_txt_1->show();
+        tag_terminating->show();
+
+        if (firewall->getOptionsObject()->getBool ("classify_mark_terminating"))
+        {
+            classify_terminating->setText(tr("Emulation is currently ON, rule will be terminating") );
+            tag_terminating->setText(tr("Emulation is currently ON, rule will be terminating") );
+        } else
+        {
+            classify_terminating->setText(tr("Emulation is currently OFF, rule will be non-terminating") );
+            tag_terminating->setText(tr("Emulation is currently OFF, rule will be non-terminating") );
+        }
+
+    } else
+    {
+        classify_txt_1->hide();
+        classify_terminating->hide();
+        tag_txt_1->hide();
+        tag_terminating->hide();
+    }
+
     data.clear();
 
     data.registerOption ( ipt_mark_connections, ropt , "ipt_mark_connections");
-    data.registerOption ( ipt_mark_prerouting,  ropt , "ipt_mark_prerouting");
+    data.registerOption ( ipt_mark_prerouting , ropt , "ipt_mark_prerouting");
     data.registerOption ( accountingvalue_str , ropt , "rule_name_accounting");
     data.registerOption ( usePortNum          , ropt , "ipfw_pipe_queue_num");
     data.registerOption ( divertPortNum       , ropt , "ipfw_pipe_port_num");
diff -uNr fwbuilder-2.1.8/src/gui/actionsdialog_q.ui fwbuilder-2.1.9/src/gui/actionsdialog_q.ui
--- fwbuilder-2.1.8/src/gui/actionsdialog_q.ui	2006-09-13 17:46:46.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/actionsdialog_q.ui	2007-01-15 05:37:51.000000000 +0100
@@ -8,8 +8,8 @@
         <rect>
             <x>0</x>
             <y>0</y>
-            <width>562</width>
-            <height>255</height>
+            <width>697</width>
+            <height>356</height>
         </rect>
     </property>
     <property name="caption">
@@ -307,41 +307,7 @@
                                     <property name="name">
                                         <cstring>unnamed</cstring>
                                     </property>
-                                    <spacer row="4" column="0">
-                                        <property name="name">
-                                            <cstring>spacer31</cstring>
-                                        </property>
-                                        <property name="orientation">
-                                            <enum>Vertical</enum>
-                                        </property>
-                                        <property name="sizeType">
-                                            <enum>Expanding</enum>
-                                        </property>
-                                        <property name="sizeHint">
-                                            <size>
-                                                <width>20</width>
-                                                <height>20</height>
-                                            </size>
-                                        </property>
-                                    </spacer>
-                                    <spacer row="0" column="0">
-                                        <property name="name">
-                                            <cstring>spacer30</cstring>
-                                        </property>
-                                        <property name="orientation">
-                                            <enum>Vertical</enum>
-                                        </property>
-                                        <property name="sizeType">
-                                            <enum>Expanding</enum>
-                                        </property>
-                                        <property name="sizeHint">
-                                            <size>
-                                                <width>20</width>
-                                                <height>20</height>
-                                            </size>
-                                        </property>
-                                    </spacer>
-                                    <widget class="QLayoutWidget" row="1" column="0">
+                                    <widget class="QLayoutWidget" row="0" column="0">
                                         <property name="name">
                                             <cstring>layout3</cstring>
                                         </property>
@@ -398,7 +364,7 @@
                                             </spacer>
                                         </hbox>
                                     </widget>
-                                    <widget class="QCheckBox" row="2" column="0">
+                                    <widget class="QCheckBox" row="1" column="0">
                                         <property name="name">
                                             <cstring>ipt_mark_connections</cstring>
                                         </property>
@@ -409,7 +375,7 @@
                                             <string>Requires CONNMARK target</string>
                                         </property>
                                     </widget>
-                                    <widget class="QCheckBox" row="3" column="0">
+                                    <widget class="QCheckBox" row="2" column="0">
                                         <property name="name">
                                             <cstring>ipt_mark_prerouting</cstring>
                                         </property>
@@ -417,6 +383,45 @@
                                             <string>Mark packets in PREROUTING chain</string>
                                         </property>
                                     </widget>
+                                    <spacer row="5" column="0">
+                                        <property name="name">
+                                            <cstring>spacer31</cstring>
+                                        </property>
+                                        <property name="orientation">
+                                            <enum>Vertical</enum>
+                                        </property>
+                                        <property name="sizeType">
+                                            <enum>Expanding</enum>
+                                        </property>
+                                        <property name="sizeHint">
+                                            <size>
+                                                <width>20</width>
+                                                <height>20</height>
+                                            </size>
+                                        </property>
+                                    </spacer>
+                                    <widget class="QLabel" row="3" column="0">
+                                        <property name="name">
+                                            <cstring>tag_txt_1</cstring>
+                                        </property>
+                                        <property name="text">
+                                            <string>Note: this action translates into MARK target for iptables. Normally this target is non-terminating, that is, other rules with Classify or Tag actions belog this one will process the same packet. However, Firewall Builder can emulate terminating behavior for this action. Option in the "compiler" tab of the firewall object properties dialog activates emulation.</string>
+                                        </property>
+                                        <property name="alignment">
+                                            <set>WordBreak|AlignVCenter</set>
+                                        </property>
+                                    </widget>
+                                    <widget class="QLabel" row="4" column="0">
+                                        <property name="name">
+                                            <cstring>tag_terminating</cstring>
+                                        </property>
+                                        <property name="text">
+                                            <string>Emulation is currently ON, the rule will be terminating</string>
+                                        </property>
+                                        <property name="alignment">
+                                            <set>AlignCenter</set>
+                                        </property>
+                                    </widget>
                                 </grid>
                             </widget>
                             <widget class="QWidget">
@@ -667,28 +672,11 @@
                                 <attribute name="id">
                                     <number>7</number>
                                 </attribute>
-                                <vbox>
+                                <grid>
                                     <property name="name">
                                         <cstring>unnamed</cstring>
                                     </property>
-                                    <spacer>
-                                        <property name="name">
-                                            <cstring>spacer5</cstring>
-                                        </property>
-                                        <property name="orientation">
-                                            <enum>Vertical</enum>
-                                        </property>
-                                        <property name="sizeType">
-                                            <enum>Expanding</enum>
-                                        </property>
-                                        <property name="sizeHint">
-                                            <size>
-                                                <width>20</width>
-                                                <height>21</height>
-                                            </size>
-                                        </property>
-                                    </spacer>
-                                    <widget class="QLabel">
+                                    <widget class="QLabel" row="0" column="0">
                                         <property name="name">
                                             <cstring>textLabel2_3</cstring>
                                         </property>
@@ -696,14 +684,25 @@
                                             <string>Classify string:</string>
                                         </property>
                                     </widget>
-                                    <widget class="QLineEdit">
+                                    <widget class="QLineEdit" row="1" column="0">
                                         <property name="name">
                                             <cstring>classify_str</cstring>
                                         </property>
                                     </widget>
-                                    <spacer>
+                                    <widget class="QLabel" row="2" column="0">
                                         <property name="name">
-                                            <cstring>spacer6</cstring>
+                                            <cstring>classify_txt_1</cstring>
+                                        </property>
+                                        <property name="text">
+                                            <string>Note:  CLASSIFY target in iptables is non-terminating, that is other rules with Classify or Mark target below this will process the same packet. However, Firewall Builder can emulate terminating behavior for this action. Emulation is activated by an option in the "compiler" tab of the firewall object properties dialog.</string>
+                                        </property>
+                                        <property name="alignment">
+                                            <set>WordBreak|AlignVCenter</set>
+                                        </property>
+                                    </widget>
+                                    <spacer row="4" column="0">
+                                        <property name="name">
+                                            <cstring>spacer31_2</cstring>
                                         </property>
                                         <property name="orientation">
                                             <enum>Vertical</enum>
@@ -714,11 +713,22 @@
                                         <property name="sizeHint">
                                             <size>
                                                 <width>20</width>
-                                                <height>31</height>
+                                                <height>20</height>
                                             </size>
                                         </property>
                                     </spacer>
-                                </vbox>
+                                    <widget class="QLabel" row="3" column="0">
+                                        <property name="name">
+                                            <cstring>classify_terminating</cstring>
+                                        </property>
+                                        <property name="text">
+                                            <string>Emulation is currently ON, rule will be terminating</string>
+                                        </property>
+                                        <property name="alignment">
+                                            <set>AlignCenter</set>
+                                        </property>
+                                    </widget>
+                                </grid>
                             </widget>
                             <widget class="QWidget">
                                 <property name="name">
diff -uNr fwbuilder-2.1.8/src/gui/findobjectwidget_q.ui fwbuilder-2.1.9/src/gui/findobjectwidget_q.ui
--- fwbuilder-2.1.8/src/gui/findobjectwidget_q.ui	2006-11-21 03:40:49.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/findobjectwidget_q.ui	2007-02-11 04:37:36.000000000 +0100
@@ -272,29 +272,9 @@
                 <property name="name">
                     <cstring>unnamed</cstring>
                 </property>
-                <widget class="FWObjectDropArea" row="0" column="1" rowspan="2" colspan="1">
-                    <property name="name">
-                        <cstring>findDropArea</cstring>
-                    </property>
-                    <property name="sizePolicy">
-                        <sizepolicy>
-                            <hsizetype>0</hsizetype>
-                            <vsizetype>0</vsizetype>
-                            <horstretch>0</horstretch>
-                            <verstretch>0</verstretch>
-                        </sizepolicy>
-                    </property>
-                    <property name="minimumSize">
-                        <size>
-                            <width>100</width>
-                            <height>80</height>
-                        </size>
-                    </property>
-                    <property name="font">
-                        <font>
-                        </font>
-                    </property>
-                </widget>
+                <property name="spacing">
+                    <number>2</number>
+                </property>
                 <widget class="QComboBox" row="1" column="0">
                     <property name="name">
                         <cstring>findAttr</cstring>
@@ -341,7 +321,47 @@
                         </font>
                     </property>
                 </widget>
-                <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+                <widget class="FWObjectDropArea" row="0" column="2" rowspan="2" colspan="1">
+                    <property name="name">
+                        <cstring>findDropArea</cstring>
+                    </property>
+                    <property name="sizePolicy">
+                        <sizepolicy>
+                            <hsizetype>0</hsizetype>
+                            <vsizetype>0</vsizetype>
+                            <horstretch>0</horstretch>
+                            <verstretch>0</verstretch>
+                        </sizepolicy>
+                    </property>
+                    <property name="minimumSize">
+                        <size>
+                            <width>100</width>
+                            <height>80</height>
+                        </size>
+                    </property>
+                    <property name="font">
+                        <font>
+                        </font>
+                    </property>
+                </widget>
+                <spacer row="0" column="1">
+                    <property name="name">
+                        <cstring>spacer5</cstring>
+                    </property>
+                    <property name="orientation">
+                        <enum>Horizontal</enum>
+                    </property>
+                    <property name="sizeType">
+                        <enum>Fixed</enum>
+                    </property>
+                    <property name="sizeHint">
+                        <size>
+                            <width>20</width>
+                            <height>20</height>
+                        </size>
+                    </property>
+                </spacer>
+                <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="3">
                     <property name="name">
                         <cstring>useRegexp</cstring>
                     </property>
diff -uNr fwbuilder-2.1.8/src/gui/FWBMainWindow_q.ui fwbuilder-2.1.9/src/gui/FWBMainWindow_q.ui
--- fwbuilder-2.1.8/src/gui/FWBMainWindow_q.ui	2006-08-21 17:34:53.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/FWBMainWindow_q.ui	2007-02-04 04:58:59.000000000 +0100
@@ -53,6 +53,14 @@
             <property name="name">
                 <cstring>frame13</cstring>
             </property>
+            <property name="sizePolicy">
+                <sizepolicy>
+                    <hsizetype>3</hsizetype>
+                    <vsizetype>5</vsizetype>
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                </sizepolicy>
+            </property>
             <property name="frameShape">
                 <enum>StyledPanel</enum>
             </property>
@@ -249,6 +257,14 @@
                         <property name="name">
                             <cstring>rightFrame</cstring>
                         </property>
+                        <property name="sizePolicy">
+                            <sizepolicy>
+                                <hsizetype>0</hsizetype>
+                                <vsizetype>5</vsizetype>
+                                <horstretch>0</horstretch>
+                                <verstretch>0</verstretch>
+                            </sizepolicy>
+                        </property>
                         <property name="frameShape">
                             <enum>NoFrame</enum>
                         </property>
@@ -493,7 +509,7 @@
                                                 </property>
                                                 <property name="sizePolicy">
                                                     <sizepolicy>
-                                                        <hsizetype>1</hsizetype>
+                                                        <hsizetype>0</hsizetype>
                                                         <vsizetype>0</vsizetype>
                                                         <horstretch>0</horstretch>
                                                         <verstretch>0</verstretch>
@@ -501,7 +517,7 @@
                                                 </property>
                                                 <property name="minimumSize">
                                                     <size>
-                                                        <width>50</width>
+                                                        <width>0</width>
                                                         <height>0</height>
                                                     </size>
                                                 </property>
@@ -515,7 +531,7 @@
                                                 </property>
                                                 <property name="sizePolicy">
                                                     <sizepolicy>
-                                                        <hsizetype>1</hsizetype>
+                                                        <hsizetype>0</hsizetype>
                                                         <vsizetype>0</vsizetype>
                                                         <horstretch>0</horstretch>
                                                         <verstretch>0</verstretch>
@@ -630,6 +646,7 @@
         <action name="installAction"/>
     </item>
     <item text="Tools" name="Tools">
+        <action name="fileCompareAction"/>
         <action name="DiscoveryDruidAction"/>
     </item>
     <item text="&amp;Help" name="helpMenu">
@@ -1304,7 +1321,7 @@
             <string>Commit</string>
         </property>
         <property name="menuText">
-            <string>C&amp;ommit</string>
+            <string>Co&amp;mmit</string>
         </property>
         <property name="statusTip">
             <string>Commit Opened File to RCS and Continue Editing</string>
@@ -1354,6 +1371,17 @@
             <string>new item</string>
         </property>
     </action>
+    <action>
+        <property name="name">
+            <cstring>fileCompareAction</cstring>
+        </property>
+        <property name="text">
+            <string>Find Conflicting Objects in Two Files</string>
+        </property>
+        <property name="menuText">
+            <string>Find Conflicting Objects in Two Files</string>
+        </property>
+    </action>
 </actions>
 <connections>
     <connection>
@@ -1609,6 +1637,12 @@
         <slot>removeRule()</slot>
     </connection>
     <connection>
+        <sender>ruleSets</sender>
+        <signal>currentChanged(QWidget*)</signal>
+        <receiver>FWBMainWindow_q</receiver>
+        <slot>ruleSetTabChanged(QWidget*)</slot>
+    </connection>
+    <connection>
         <sender>toolbarFileNew</sender>
         <signal>activated()</signal>
         <receiver>FWBMainWindow_q</receiver>
@@ -1627,10 +1661,10 @@
         <slot>fileSave()</slot>
     </connection>
     <connection>
-        <sender>ruleSets</sender>
-        <signal>currentChanged(QWidget*)</signal>
+        <sender>fileCompareAction</sender>
+        <signal>activated()</signal>
         <receiver>FWBMainWindow_q</receiver>
-        <slot>ruleSetTabChanged(QWidget*)</slot>
+        <slot>fileCompare()</slot>
     </connection>
 </connections>
 <includes>
@@ -1687,6 +1721,7 @@
     <slot>showNextSearchResult()</slot>
     <slot>closeAuxiliaryPanel()</slot>
     <slot>ruleSetTabChanged(QWidget*)</slot>
+    <slot>fileCompare()</slot>
 </slots>
 <functions>
     <function access="private" specifier="non virtual">init()</function>
diff -uNr fwbuilder-2.1.8/src/gui/FWBMainWindow_q.ui.h fwbuilder-2.1.9/src/gui/FWBMainWindow_q.ui.h
--- fwbuilder-2.1.8/src/gui/FWBMainWindow_q.ui.h	2006-06-08 08:00:43.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/FWBMainWindow_q.ui.h	2007-02-04 04:58:59.000000000 +0100
@@ -310,4 +310,9 @@
 void FWBMainWindow_q::ruleSetTabChanged(QWidget*)
 {
 
+}
+
+void FWBMainWindow_q::fileCompare()
+{
+
 }
\ Kein Zeilenumbruch am Dateiende.
diff -uNr fwbuilder-2.1.8/src/gui/FWObjectPropertiesFactory.cpp fwbuilder-2.1.9/src/gui/FWObjectPropertiesFactory.cpp
--- fwbuilder-2.1.8/src/gui/FWObjectPropertiesFactory.cpp	2006-10-24 05:43:25.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/FWObjectPropertiesFactory.cpp	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: FWObjectPropertiesFactory.cpp,v 1.50 2006/10/24 03:43:25 vkurland Exp $
+  $Id: FWObjectPropertiesFactory.cpp,v 1.51 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -31,6 +31,7 @@
 #include <qobject.h>
 #include <qtextstream.h>
 #include <qdatetime.h>
+#include <qregexp.h>
 
 #include "FWObjectPropertiesFactory.h"
 #include "platforms.h"
@@ -203,11 +204,28 @@
 }
 
 
+QString FWObjectPropertiesFactory::stripHTML(const QString &str)
+{
+    // note that str may contain multiple lines
+    // separated by <br> and/or '\n'
+
+    QRegExp htmltag1 = QRegExp("<[^>]+>");
+    QRegExp htmltag2 = QRegExp("</[^>]+>");
+    QRegExp htmltd   = QRegExp("</td><td>");
+
+    QString res = str;
+    res = res.replace(htmltd,": ");
+    res = res.remove(htmltag1);
+    res = res.remove(htmltag2);
+    return res;
+}
+
 
 QString FWObjectPropertiesFactory::getObjectPropertiesDetailed(FWObject *obj,
                                                                bool showPath,
                                                                bool tooltip,
-                                                               bool accentName)
+                                                               bool accentName,
+                                                               bool richText)
 {
     QString str;
 
@@ -240,18 +258,18 @@
 
         if (IPv4::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str +=  Address::cast(obj)->getAddress().toString().c_str();
             str += "/";
             str += Address::cast(obj)->getNetmask().toString().c_str();
 
         } else if (physAddress::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += physAddress::cast(obj)->getPhysAddress().c_str();
         } else if (DNSName::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += QObject::tr("<b>DNS record:</b>");
             str += MultiAddress::cast(obj)->getSourceName().c_str();
             str += "<br>\n";
@@ -259,7 +277,7 @@
 
         } else if (AddressTable::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += QObject::tr("<b>Table file:</b>");
             str += MultiAddress::cast(obj)->getSourceName().c_str();
             str += "<br>\n";
@@ -267,14 +285,14 @@
             
         } else if (AddressRange::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             AddressRange *ar=AddressRange::cast(obj);
             str += ar->getRangeStart().toString().c_str();
             str += " - ";
             str += ar->getRangeEnd().toString().c_str();
         } else if (Host::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
 
             str +=  Address::cast(obj)->getAddress().toString().c_str() ;
 
@@ -288,7 +306,7 @@
 
         } else if (Network::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             Network *n=Network::cast(obj);
             str += n->getAddress().toString().c_str();
             str += "/";
@@ -296,7 +314,7 @@
 
         } else if (Group::cast(obj)!=NULL)   // just any group
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             Group *g=Group::cast(obj);
             str += QObject::tr("%1 objects<br>\n").arg(g->size());
             int n = 0;
@@ -344,7 +362,7 @@
             
                
 
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += "<table cellspacing=\"0\" cellpadding=\"0\">";
             str += QString("<tr><td>Platform:</td><td>") +
                 platform + "</td></tr>\n";
@@ -382,7 +400,7 @@
             
             if (q!="") str += " (" + q + ")";
             str += "<br>\n";
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
 
             physAddress *paddr=(Interface::cast(obj))->getPhysicalAddress();
             if (paddr!=NULL) 
@@ -395,7 +413,7 @@
         } else if (CustomService::isA(obj))
         {
 
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
 
             CustomService *s = dynamic_cast<CustomService*>(obj);
             bool first=true;
@@ -419,12 +437,12 @@
 
         } else if (IPService::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += QObject::tr("protocol ") + obj->getStr("protocol_num").c_str();
 
         } else if (ICMPService::isA(obj))
         {
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += QObject::tr("type: ") + obj->getStr("type").c_str()
                 + "  "
                 + QObject::tr("code: ") + obj->getStr("code").c_str();
@@ -438,11 +456,11 @@
             dps=obj->getInt("dst_range_start");
             dpe=obj->getInt("dst_range_end");
 
-            if (showPath && !tooltip) str += path + "<br>\n";
+            if (showPath && !tooltip) str += "<b>Path: </b>" + path + "<br>\n";
             str += "<table cellspacing=\"0\" cellpadding=\"0\">";
-            str += QString("<tr><td>source port range</td><td>%1:%2</td></tr>")
+            str += QString("<tr><td>source port range</td><td>%1:%2</td></tr>\n")
                 .arg(sps).arg(spe);
-            str += QString("<tr><td>destination port range</td><td>%1:%2</td></tr>")
+            str += QString("<tr><td>destination port range</td><td>%1:%2</td></tr>\n")
                 .arg(dps).arg(dpe);
             str += "</table>";
         } else if (TagService::isA(obj)) 
@@ -457,7 +475,9 @@
         cerr << ex.toString() << endl;
     }
 
-    return str;
+    if (richText) return str;
+
+    return FWObjectPropertiesFactory::stripHTML(str);
 }
 
 /*
diff -uNr fwbuilder-2.1.8/src/gui/FWObjectPropertiesFactory.h fwbuilder-2.1.9/src/gui/FWObjectPropertiesFactory.h
--- fwbuilder-2.1.8/src/gui/FWObjectPropertiesFactory.h	2006-02-19 08:49:48.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/FWObjectPropertiesFactory.h	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: FWObjectPropertiesFactory.h,v 1.9 2006/02/19 07:49:48 vkurland Exp $
+  $Id: FWObjectPropertiesFactory.h,v 1.10 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -47,11 +47,15 @@
     static QString getObjectPropertiesDetailed(libfwbuilder::FWObject *obj,
                                                bool showPath=false,
                                                bool tooltip=false,
-                                               bool accentName=true);
+                                               bool accentName=true,
+                                               bool richText=true);
     static QString getRuleActionProperties(libfwbuilder::PolicyRule *rule); 
     static QString getRuleActionPropertiesRich(libfwbuilder::PolicyRule *rule); 
     static QString getPolicyRuleOptions(libfwbuilder::Rule *rule);
     static QString getNATRuleOptions(libfwbuilder::Rule *rule);
+
+    static QString stripHTML(const QString &str);
+
 };
 
 #endif
diff -uNr fwbuilder-2.1.8/src/gui/FWWindow.cpp fwbuilder-2.1.9/src/gui/FWWindow.cpp
--- fwbuilder-2.1.8/src/gui/FWWindow.cpp	2006-11-10 06:24:48.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/FWWindow.cpp	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: FWWindow.cpp,v 1.212 2006/11/10 05:24:48 vkurland Exp $
+  $Id: FWWindow.cpp,v 1.215 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -143,6 +143,7 @@
 #include <qwidgetstack.h>
 #include <qlistbox.h>
 #include <qeventloop.h>
+#include <qtextstream.h>
 
 using namespace libfwbuilder;
 using namespace std;
@@ -393,10 +394,9 @@
     return true;
 }
 
-QString FWWindow::chooseNewFileName(const QString &fname,
-                                    bool checkPresence,const QString &title)
+QString FWWindow::getDestDir(const QString &fname)
 {
-    QString destdir;
+    QString destdir = "";
 
     if (st->getWDir().isEmpty())
     {
@@ -414,12 +414,22 @@
         } else
         {
             if (QFileInfo(fname).isDir()) destdir=fname;
-            else                      destdir = fname.left( fname.findRev('/',-1) );
+            else
+                destdir = fname.left( fname.findRev('/',-1) );
         }
     } else
     {
         destdir=st->getWDir();
     }
+    return destdir;
+}
+
+
+
+QString FWWindow::chooseNewFileName(const QString &fname,
+                                    bool checkPresence,const QString &title)
+{
+    QString destdir = getDestDir(fname);
 
     QString fn = QFileDialog::getSaveFileName( destdir,
        tr( "FWB Files (*.fwb);;All Files (*)" ),
@@ -1315,6 +1325,7 @@
         FWObject *dobj = ndb->findInIndex(FWObjectDatabase::getDeletedObjectsId());
         if (dobj) ndb->remove(dobj, false);
 
+#if 0
         list<FWObject*> newLibs;
         newLibs= ndb->getByType(Library::TYPENAME);
 
@@ -1349,7 +1360,7 @@
             for (list<FWObject*>::iterator i=duplicateLibs.begin(); i!=duplicateLibs.end(); i++)
                 ndb->remove(*i,false);
         }
-
+#endif
         MergeConflictRes mcr(this);
         db()->merge(ndb, &mcr);
 
@@ -1385,6 +1396,154 @@
 //    addOnLibs->add( fname.latin1() );
 }
 
+
+void FWWindow::fileCompare()
+{
+    fd->reset();   // fd : find dialog
+
+    QMessageBox initial_question( "Firewall Builder",
+                    tr("This operation inspects two data files (either .fwb or .fwl) and finds conflicting objects. Conflicting objects have the same internal ID but different attributes. Two data files can not be merged, or one imported into another, if they contain such objects. This operation also helps identify changes made to objects in two copies of the same data file.<br><br>This operation does not find objects present in one file but not in the other, such objects present no problem for merge or import operations.<br><br>This operation works with two external files, neither of which needs to be opened in the program. Currently opened data file is not affected by this operation and objects in the tree do not change.<br><br>Do you want to proceed ?"),
+                    QMessageBox::Information,
+                    QMessageBox::Yes | QMessageBox::Default,
+                    QMessageBox::No,
+                    QMessageBox::Escape );
+
+    initial_question.setTextFormat( Qt::RichText );
+    if (initial_question.exec() != QMessageBox::Yes) return;
+
+
+    QString fname1 = QFileDialog::getOpenFileName( st->getWDir(), 
+       "Firewall Builder 2 files (*.fwb);;FWB Library Files (*.fwl);;All Files (*)",
+                          this, 0,
+                          tr("Choose the first file") );
+
+    if (fname1.isEmpty()) return;   // Cancel
+
+    QString fname2 = QFileDialog::getOpenFileName( st->getWDir(), 
+       "Firewall Builder 2 files (*.fwb);;FWB Library Files (*.fwl);;All Files (*)",
+                          this, 0,
+                          tr("Choose the second file") );
+
+    if (fname2.isEmpty()) return;   // Cancel
+
+    MessageBoxUpgradePredicate upgrade_predicate;
+
+    FWObjectDatabase *db1;
+    FWObjectDatabase *db2;
+    FWObject *dobj;
+
+    try
+    {
+        db1 = new FWObjectDatabase();
+        db1->load(fname1,  &upgrade_predicate,  librespath);
+
+        dobj = db1->findInIndex(FWObjectDatabase::getDeletedObjectsId());
+        if (dobj) db1->remove(dobj, false);
+    } catch(FWException &ex)
+    {
+        QMessageBox::warning(
+            this,"Firewall Builder", 
+            tr("Error loading file %1:\n%2").
+                 arg(fname1).arg(ex.toString().c_str()),
+            tr("&Continue"), QString::null,QString::null,
+            0, 1 );
+        return;
+    }
+
+    try
+    {
+        db2 = new FWObjectDatabase();
+        db2->load(fname2,  &upgrade_predicate,  librespath);
+
+        dobj = db2->findInIndex(FWObjectDatabase::getDeletedObjectsId());
+        if (dobj) db2->remove(dobj, false);
+    } catch(FWException &ex)
+    {
+        QMessageBox::warning(
+            this,"Firewall Builder", 
+            tr("Error loading file %1:\n%2").
+                 arg(fname2).arg(ex.toString().c_str()),
+            tr("&Continue"), QString::null,QString::null,
+            0, 1 );
+        return;
+    }
+
+    try
+    {
+        // CompareObjectsDialog is just like ObjConflictResolutionDialog
+        // except it always returns 'accepted' and keeps record
+        // of all object differences so we can print report in the end
+
+        CompareObjectsDialog cod(this);
+        db1->merge(db2, &cod);
+        list<QString> report = cod.getReport();
+
+        delete db1;
+        delete db2;
+
+        ostringstream str;
+        str << cod.getNumberOfConflicts();
+
+        QMessageBox mb( "Firewall Builder",
+                        tr("Total number of conflicting objects: %1.\nDo you want to generate report?").arg(str.str()),
+                        QMessageBox::Information,
+                        QMessageBox::Yes | QMessageBox::Default,
+                        QMessageBox::No,
+                        QMessageBox::Escape );
+
+        if (mb.exec()== QMessageBox::Yes)
+        {
+            // save report to a file
+
+            QString destdir = getDestDir(fname1);
+
+            QString fn = QFileDialog::getSaveFileName( destdir,
+                           tr( "TXT Files (*.txt);;All Files (*)" ),
+                           this, 0,
+                           tr("Choose name and location for the report file"));
+
+            if (fwbdebug)
+                qDebug( QString("Saving report to %1").arg(fn) );
+
+            if (fn.isEmpty() ) return ;   // Cancel
+
+            if (fn.findRev(".txt",-1,false)==-1)
+            {
+                fn+=".txt";
+            }
+
+            QFile report_file(fn);
+            if (report_file.open(IO_WriteOnly))
+            {
+                QTextStream report_stream(&report_file);
+                for (list<QString>::iterator i=report.begin(); i!=report.end(); ++i)
+                {
+                    report_stream << *i;
+                }
+                report_file.close();
+            } else 
+            {
+                QMessageBox::critical(
+                    this,"Firewall Builder", 
+                    tr("Can not open report file for writing. File '%1'").arg(fn),
+                    tr("&Continue"), QString::null,QString::null,
+                    0, 1 );
+            }
+            
+        }
+
+    } catch(FWException &ex)
+    {
+        QMessageBox::warning(
+            this,"Firewall Builder", 
+            tr("Unexpected error comparing files %1 and %2:\n%3").
+                 arg(fname1).arg(fname2).arg(ex.toString().c_str()),
+            tr("&Continue"), QString::null,QString::null,
+            0, 1 );
+    }
+
+}
+
 void FWWindow::findExternalRefs(FWObject *lib,
                                        FWObject *root,
                                        list<FWReference*> &extRefs)
@@ -1820,10 +1979,10 @@
     if (visibleFirewall==fw)  visibleFirewall=NULL;
 }
 
-void FWWindow::setPolicyBranchTabName(PolicyRule *rule)
+void FWWindow::setPolicyBranchTabName(RuleSet *subset)
 {
-    RuleSet *subset = rule->getBranch();
-    assert(subset);
+    assert(subset!=NULL);
+    PolicyRule *rule = PolicyRule::cast(subset->getParent());
     RuleSetView *rsv = ruleSetViews[subset];
     assert(rsv);
     FWOptions *ropt = rule->getOptionsObject();
@@ -1831,8 +1990,11 @@
     ruleSets->changeTab(rsv, tr("Policy/%1").arg(branchName) );
 }
 
-void FWWindow::addPolicyBranchTab(PolicyRule *rule)
+void FWWindow::addPolicyBranchTab(RuleSet *subset)
 {
+    assert(subset!=NULL);
+
+    PolicyRule *rule = PolicyRule::cast(subset->getParent());
     FWOptions *ropt = rule->getOptionsObject();
     QString branchName = ropt->getStr("branch_name").c_str();
 
@@ -1841,33 +2003,30 @@
     QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput,1000);
     if (fwbdebug)  qDebug("FWWindow::reopenFirewall()   adding branch tab");
 
-    Policy *subset = Policy::cast(rule->getBranch());
-    if (subset==NULL)
-    {
-        subset = new Policy();
-        rule->add(subset);
-    }
+//    if (subset==NULL)
+//    {
+//        subset = new Policy();
+//        rule->add(subset);
+//    }
     if (ruleSetViews.count(subset)==0)
     {
-        RuleSetView *rsv;
-        ruleSets->addTab(rsv=new PolicyView(subset,NULL),
-                         "Branch"); // temporary name
+        RuleSetView *rsv = new PolicyView(Policy::cast(subset),NULL);
+        ruleSets->addTab(rsv,"Branch"); // temporary name
         ruleSetViews[subset]=rsv;
     }
-    setPolicyBranchTabName(rule);
+    setPolicyBranchTabName(subset);
 
     for (FWObject::iterator i=subset->begin(); i!=subset->end(); i++)
     {
         PolicyRule *srule = PolicyRule::cast(*i);
         if (srule->getAction() == PolicyRule::Branch)
-            addPolicyBranchTab(srule);
+            addPolicyBranchTab(srule->getBranch());
     }
 
 }
 
-void FWWindow::removePolicyBranchTab(PolicyRule *rule)
+void FWWindow::removePolicyBranchTab(RuleSet *subset)
 {
-    RuleSet *subset = rule->getBranch();
     if (subset==NULL) return;
     RuleSetView *rsv = ruleSetViews[subset];
     assert(rsv);
@@ -1877,8 +2036,11 @@
 
 void FWWindow::scheduleRuleSetRedraw()
 {
-    ruleSetRedrawPending = true;
-    QTimer::singleShot( 0, this, SLOT(redrawRuleSets()) );
+    if (!ruleSetRedrawPending)
+    {
+        ruleSetRedrawPending = true;
+        QTimer::singleShot( 0, this, SLOT(redrawRuleSets()) );
+    }
 }
 
 void FWWindow::redrawRuleSets()
@@ -1927,7 +2089,7 @@
     {
         PolicyRule *rule = PolicyRule::cast(*i);
         if (rule->getAction() == PolicyRule::Branch)
-            addPolicyBranchTab(rule);
+            addPolicyBranchTab(rule->getBranch());
     }
 
 // let the GUI process events to display new tab(s)
@@ -2424,7 +2586,7 @@
 void FWWindow::ruleSetTabChanged(QWidget* w)
 {
     if (fwbdebug)
-        qDebug("FWWindow::ruleSetTabChanged:  w=%x ruleSetTabIndex=%d changingTabs=%d",
+        qDebug("FWWindow::ruleSetTabChanged:  w=%p ruleSetTabIndex=%d changingTabs=%d",
                w,ruleSetTabIndex,changingTabs);
 
     if (changingTabs) return;
diff -uNr fwbuilder-2.1.8/src/gui/FWWindow.h fwbuilder-2.1.9/src/gui/FWWindow.h
--- fwbuilder-2.1.8/src/gui/FWWindow.h	2006-09-11 02:41:09.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/FWWindow.h	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: FWWindow.h,v 1.77 2006/09/11 00:41:09 vkurland Exp $
+  $Id: FWWindow.h,v 1.79 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -111,6 +111,7 @@
      virtual void fileExit();
      virtual void fileProp();
      virtual void fileAddToRCS();
+     virtual void fileCompare();
      virtual void editCopy();
      virtual void editCut();
      virtual void editDelete();
@@ -216,9 +217,9 @@
     RuleSetView* getRuleSetViews(libfwbuilder::FWObject *o) 
     {return ruleSetViews[o];};
 
-    void addPolicyBranchTab(libfwbuilder::PolicyRule *rule);
-    void removePolicyBranchTab(libfwbuilder::PolicyRule *rule);
-    void setPolicyBranchTabName(libfwbuilder::PolicyRule *rule);
+    void addPolicyBranchTab(libfwbuilder::RuleSet *subset);
+    void removePolicyBranchTab(libfwbuilder::RuleSet *subset);
+    void setPolicyBranchTabName(libfwbuilder::RuleSet *subset);
 
     /**
      * panel that wants to open an object in the editor
@@ -243,6 +244,17 @@
 
     void scheduleRuleSetRedraw();
 
+    // semi-intelligent way to guess most appropriate
+    // destination directory for various file save or file open
+    // operations. If working directory is configured in
+    // preferences, then getDestDir returns that. If it is not
+    // configured and file name is given on the command line,
+    // directory where that file is located is returned. If
+    // parameter filename is empty, then current directory
+    // is returned (however on windows and mac userDataDir is returned)
+
+    QString getDestDir(const QString &filename);
+
  protected:
 
     virtual void showEvent( QShowEvent *ev);
diff -uNr fwbuilder-2.1.8/src/gui/GroupObjectDialog.cpp fwbuilder-2.1.9/src/gui/GroupObjectDialog.cpp
--- fwbuilder-2.1.8/src/gui/GroupObjectDialog.cpp	2006-10-22 06:39:36.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/GroupObjectDialog.cpp	2007-01-08 04:24:48.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: GroupObjectDialog.cpp,v 1.54 2006/10/22 04:39:36 vkurland Exp $
+  $Id: GroupObjectDialog.cpp,v 1.57 2007/01/08 03:24:48 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -39,6 +39,7 @@
 #include "ObjectManipulator.h"
 #include "FWObjectDrag.h"
 #include "FWObjectClipboard.h"
+#include "ObjectTreeView.h"
 
 #include "fwbuilder/Library.h"
 #include "fwbuilder/Group.h"
@@ -624,13 +625,24 @@
 
 void GroupObjectDialog::dropped(QDropEvent *ev)
 {
+    if (fwbdebug) qDebug("GroupObjectDialog::dropped");
+
     list<FWObject*> ol;
     if (FWObjectDrag::decode(ev, ol))
     {
         if (ol.size()==0) return;
         for (list<FWObject*>::iterator i=ol.begin(); i!=ol.end(); ++i)
             insertObject( *i );
+        if (fwbdebug) qDebug("GroupObjectDialog::dropped  ev->acceptAction()");
+        ev->acceptAction();
+
+        // see comment in ObjectTreeView.cpp explaining the purpose of
+        // flag process_mouse_release_event
+        ObjectTreeView *otv = om->getCurrentObjectTree();
+        otv->ignoreNextMouseReleaseEvent();
+
     }
+    if (fwbdebug) qDebug("GroupObjectDialog::dropped  done");
 }
 
 void GroupObjectDialog::iconContextMenu(QIconViewItem *itm,const QPoint &p)
diff -uNr fwbuilder-2.1.8/src/gui/instBatchOptionsDialog.cpp fwbuilder-2.1.9/src/gui/instBatchOptionsDialog.cpp
--- fwbuilder-2.1.8/src/gui/instBatchOptionsDialog.cpp	2006-08-28 08:03:10.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instBatchOptionsDialog.cpp	2007-01-06 09:24:57.000000000 +0100
@@ -2,11 +2,11 @@
 
                           Firewall Builder
 
-                 Copyright (C) 2003 NetCitadel, LLC
+                 Copyright (C) 2006 NetCitadel, LLC
 
   Author:  Illiya Yalovoy <yalovoy@gmail.com>
 
-  $Id: instBatchOptionsDialog.cpp,v 1.3 2006/08/28 06:03:10 vkurland Exp $
+  $Id: instBatchOptionsDialog.cpp,v 1.4 2007/01/06 08:24:57 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -31,10 +31,6 @@
 
 #include "instBatchOptionsDialog.h"
 
-#include "fwbuilder/Library.h"
-#include "fwbuilder/FWException.h"
-#include "fwbuilder/Firewall.h"
-
 #include <qstring.h>
 #include <qlineedit.h>
 #include <qlabel.h>
@@ -44,7 +40,7 @@
 using namespace std;
 using namespace libfwbuilder;
 
-instBatchOptionsDialog::instBatchOptionsDialog(QWidget *parent) : instOptionsDialog_q(parent)
+instBatchOptionsDialog::instBatchOptionsDialog(QWidget *parent) : instOptionsDialog(parent)
 {
     dialogTitleLine->setText(QString("<p align=\"center\"><b><font size=\"+2\">")+
                              tr("Batch install options")+
@@ -55,24 +51,3 @@
     
 }
 
-void instBatchOptionsDialog::applyChanges()
-{
-    hide();
-}
-
-void instBatchOptionsDialog::discardChanges()
-{
-    hide();
-}
-
-QString instBatchOptionsDialog::getUName() { return uname->text(); }
-QString instBatchOptionsDialog::getPWD()   { return pwd->text();   }
-QString instBatchOptionsDialog::getEPWD()  { return epwd->text();  }
-
-void instBatchOptionsDialog::closeEvent(QCloseEvent *e)
-{
-    if (fwbdebug)
-        qDebug("instBatchOptionsDialog::closeEvent  got close event: %p",e);
-    hide();
-}
-
diff -uNr fwbuilder-2.1.8/src/gui/instBatchOptionsDialog.h fwbuilder-2.1.9/src/gui/instBatchOptionsDialog.h
--- fwbuilder-2.1.8/src/gui/instBatchOptionsDialog.h	2006-04-13 18:18:52.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instBatchOptionsDialog.h	2007-01-06 09:24:57.000000000 +0100
@@ -2,11 +2,11 @@
 
                           Firewall Builder
 
-                 Copyright (C) 2003 NetCitadel, LLC
+                 Copyright (C) 2006 NetCitadel, LLC
 
   Author:  Illiya Yalovoy <yalovoy@gmail.com>
 
-  $Id: instBatchOptionsDialog.h,v 1.1 2006/04/13 16:18:52 vkurland Exp $
+  $Id: instBatchOptionsDialog.h,v 1.2 2007/01/06 08:24:57 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -28,37 +28,16 @@
 #define __INSTBATCHOPTIONSDIALOG_H_
 
 #include "config.h"
-#include <instoptionsdialog_q.h>
+#include <instOptionsDialog.h>
 
-#include "fwbuilder/FWObject.h"
-#include "fwbuilder/Resources.h"
-
-
-
-class instBatchOptionsDialog : public instOptionsDialog_q
+class instBatchOptionsDialog : public instOptionsDialog
 {
     Q_OBJECT
  private:
  
  public:
     instBatchOptionsDialog(QWidget *parent);
-    virtual void closeEvent(QCloseEvent *e);
-    QString getUName();
-    QString getPWD();
-    QString getEPWD();
 
-
-public slots:
-    virtual void applyChanges();
-    virtual void discardChanges();
-    
- signals:
-/**
- * This signal is emitted from closeEvent, ObjectEditor connects
- * to this signal to make checks before the object editor can be closed
- * and to store its position on the screen
- */
-   // void close_sign(QCloseEvent *e);
     
 };
 
diff -uNr fwbuilder-2.1.8/src/gui/instDialog.cpp fwbuilder-2.1.9/src/gui/instDialog.cpp
--- fwbuilder-2.1.8/src/gui/instDialog.cpp	2006-10-21 08:19:36.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instDialog.cpp	2007-01-30 17:48:10.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: instDialog.cpp,v 1.95 2006/10/21 06:19:36 vkurland Exp $
+  $Id: instDialog.cpp,v 1.99 2007/01/30 16:48:10 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -49,6 +49,7 @@
 #include <qapplication.h>
 #include <qeventloop.h>
 #include <qfile.h>
+#include <qdir.h>
 #include <qmessagebox.h>
 #include <qspinbox.h>
 #include <qgroupbox.h>
@@ -224,86 +225,68 @@
 
     QString platform=cnf.fwobj->getStr("platform").c_str();
 
+    dlg->uname->setFocus();
+    dlg->uname->setText( cnf.user );
+    dlg->incr->setChecked( cnf.incremental );
+    dlg->test->setChecked( cnf.dry_run );
+    dlg->backupConfigFile->setText( cnf.backup_file );
+    dlg->saveDiff->setChecked( cnf.save_diff );
+    dlg->saveStandby->setChecked( cnf.saveStandby );
+    dlg->altAddress->setText( cnf.maddr );
+    dlg->quiet->setChecked( cnf.quiet );
+    dlg->verbose->setChecked( cnf.verbose );
+    dlg->stripComments->setChecked( cnf.stripComments );
+    dlg->compressScript->setChecked( cnf.compressScript );
+    dlg->copyFWB->setChecked( cnf.copyFWB );
+    dlg->testRun->setChecked( cnf.testRun );
+    dlg->rollback->setChecked( cnf.rollback );
+    dlg->rollbackTime->setValue( cnf.rollbackTime );
+
+    bool f = dlg->testRun->isChecked();
+    if (cnf.fwobj->getStr("host_OS")=="pix_os" || cnf.fwobj->getStr("host_OS")=="fwsm_os")
+    {
+        dlg->rollback->setChecked( false );
+        f=false;
+    }
+
+    dlg->rollback->setEnabled(f);
+    dlg->rollbackTime->setEnabled(f);
+    dlg->rollbackTimeUnit->setEnabled(f);
+    
+    QSize pix_options_frame_size = dlg->PIXgroupBox->sizeHint();
+
     cnf.rollbackTimeUnit=
         Resources::getTargetOptionStr(cnf.fwobj->getStr("host_OS"),
                                       "activation/timeout_units").c_str();
     if ((platform!="pix" && platform!="fwsm" && !batchInstall->isChecked()) ||
         (!fPix && batchInstall->isChecked()) )
     {
-        dlg->incr->hide();
-        dlg->test->hide();
-        dlg->saveDiff->hide();
-        dlg->saveStandby->hide();
-        dlg->backupConfigFile->hide();
-        dlg->backupConfigFileLbl->hide();
-        dlg->epwd->hide();
-        dlg->epwdLbl->hide();
-
-        dlg->PIXgroupBox->hide();
-    } else
-    {
-// if PIX or FWSM:
-        dlg->copyFWB->hide();
-
-        dlg->incr->show();
-        dlg->test->show();
-        dlg->saveDiff->show();
-        dlg->saveStandby->show();
-        dlg->backupConfigFile->show();
-        dlg->backupConfigFileLbl->show();
-        dlg->epwd->show();
-        dlg->epwdLbl->show();
-
-        dlg->PIXgroupBox->show();
+        dlg->hidePIXOptions();
     }
 
 /* hide anyway, diff does not work for pix 6.3(3) */
+    //dlg->hideOption( dlg->saveDiff );
     dlg->saveDiff->hide();
 
     //progressBar->hide();
-    dlg->stripComments->hide();
-    dlg->compressScript->hide();
-
-   //if (platform=="pix" || platform=="fwsm")
-   //{
-   //    progressBar->show();
-   //    stripComments->show();
-   //}
-
-    if (cnf.fwobj->getStr("host_OS")=="linksys")
-    {
-        dlg->compressScript->show();
-    }
+    //dlg->hideOption( dlg->stripComments );
+    dlg->stripComments->hide(); 
+    //dlg->compressScript->hide();
 
+    //if (platform=="pix" || platform=="fwsm")
+    //{
+    //    progressBar->show();
+    //    stripComments->show();
+    //}
 
-   dlg->uname->setFocus();
-   dlg->uname->setText( cnf.user );
-   dlg->incr->setChecked( cnf.incremental );
-   dlg->test->setChecked( cnf.dry_run );
-   dlg->backupConfigFile->setText( cnf.backup_file );
-   dlg->saveDiff->setChecked( cnf.save_diff );
-   dlg->saveStandby->setChecked( cnf.saveStandby );
-   dlg->altAddress->setText( cnf.maddr );
-   dlg->quiet->setChecked( cnf.quiet );
-   dlg->verbose->setChecked( cnf.verbose );
-   dlg->stripComments->setChecked( cnf.stripComments );
-   dlg->compressScript->setChecked( cnf.compressScript );
-   dlg->copyFWB->setChecked( cnf.copyFWB );
-   dlg->testRun->setChecked( cnf.testRun );
-   dlg->rollback->setChecked( cnf.rollback );
-   dlg->rollbackTime->setValue( cnf.rollbackTime );
-
-    bool f = dlg->testRun->isChecked();
-    if (cnf.fwobj->getStr("host_OS")=="pix_os" || cnf.fwobj->getStr("host_OS")=="fwsm_os")
+    if (cnf.fwobj->getStr("host_OS")!="linksys")
     {
-        dlg->rollback->setChecked( false );
-        f=false;
+        dlg->compressScript->hide();
+        //dlg->hideOption( dlg->compressScript );
     }
 
-    dlg->rollback->setEnabled(f);
-    dlg->rollbackTime->setEnabled(f);
-    dlg->rollbackTimeUnit->setEnabled(f);
-    
+    //dlg->adjustSize();
+    //dlg->setFixedHeight( dlg->minimumSizeHint().height() );
 
 /* we initialize these in FWBSettings constructor on Unix, but do not
  * do it on Windows since there is no standard ssh package there. User
@@ -639,6 +622,11 @@
     lastPage=indexOf( currentPage() );
 }
 
+QString instDialog::getFullPath(instConf &cnf, const QString &file )
+{
+    if (QDir::isRelativePath(file)) return cnf.wdir + "/" + file;
+    else return file;
+}
 
 bool instDialog::doInstallPage()
 {
@@ -724,7 +712,8 @@
         }
 /* read manifest from the conf file */
 
-        QFile cf(  cnf.wdir+"/"+cnf.conffile );
+        QString conffile_path = getFullPath(cnf,cnf.conffile);
+        QFile cf( conffile_path  );
         if (cf.open( IO_ReadOnly ) )
         {
             QTextStream stream(&cf);
@@ -753,7 +742,7 @@
         } else
         {
             QMessageBox::critical(this, "Firewall Builder",
-                 tr("File %1 not found.").arg(cnf.wdir+"/"+cnf.conffile),
+                 tr("File %1 not found.").arg(conffile_path),
                                   tr("&Continue") );
             return false;
         }
@@ -904,8 +893,20 @@
 /* replace macros in activation command:
  *
  * %FWSCRIPT%, %FWDIR%, %FWBPROMPT%, %RBTIMEOUT%
+ *
+ * check if cnf.conffile is a full path. If it is, strip the path part
+ * and use only the file name for %FWSCRIPT%
  */
-    cmd.replace("%FWSCRIPT%",cnf.conffile);
+    QString clean_conffile = cnf.conffile.section(QDir::separator(),-1);
+    if (fwbdebug)
+    {
+        qDebug("Macro substitutions:");
+        qDebug(QString("  cnf.conffile=%1").arg(cnf.conffile));
+        qDebug(QString("  %%FWSCRIPT%%=%1").arg(clean_conffile));
+        qDebug(QString("  %%FWDIR%%=%1").arg(cnf.fwdir));
+    }
+
+    cmd.replace("%FWSCRIPT%",clean_conffile);
     cmd.replace("%FWDIR%",cnf.fwdir);
     cmd.replace("%FWBPROMPT%",fwb_prompt);
 
@@ -934,16 +935,16 @@
     
     std::ifstream   *wfile;
 
-    QString ff = cnf.wdir+"/"+file;
+    QString file_with_path = getFullPath(cnf,file);
 
-    wfile = new ifstream(ff.latin1());
+    wfile = new ifstream(file_with_path.latin1());
     if ( ! *wfile)
     {
-        ff = file;  // .fwb file path already includes wdir
-        wfile = new ifstream(ff.latin1());
+        file_with_path = file;  // .fwb file path already includes wdir
+        wfile = new ifstream(file_with_path.latin1());
         if ( ! *wfile)
         {
-            addToLog(QObject::tr("Can not open file %1").arg(ff));
+            addToLog(QObject::tr("Can not open file %1").arg(file_with_path));
             delete wfile;
             return;
         }
@@ -1018,16 +1019,28 @@
 /* replace macros in activation command:
  *
  * %FWSCRIPT%, %FWDIR%, %FWBPROMPT%, %RBTIMEOUT%
+ *
+ * check if cnf.conffile is a full path. If it is, strip the path part
+ * and use only the file name for %FWSCRIPT%
  */
+    QString clean_conffile = cnf.conffile.section(QDir::separator(),-1);
+    if (fwbdebug)
+    {
+        qDebug("Macro substitutions:");
+        qDebug(QString("  cnf.conffile=%1").arg(cnf.conffile));
+        qDebug(QString("  %%FWSCRIPT%%=%1").arg(clean_conffile));
+        qDebug(QString("  %%FWDIR%%=%1").arg(cnf.fwdir));
+    }
+
     cmd.replace("\n","");
-    cmd.replace("%FWSCRIPT%",file);
+    cmd.replace("%FWSCRIPT%",clean_conffile);
     cmd.replace("%FWDIR%",cnf.fwdir);
     cmd.replace("%FWBPROMPT%",fwb_prompt);
 
     args.push_back(cmd);
         
     addToLog( tr("\nCopying %1 -> %2:%3\n")
-                .arg(cnf.wdir+"/"+file).arg(cnf.maddr).arg(cnf.fwdir) );
+                .arg(file_with_path).arg(cnf.maddr).arg(cnf.fwdir) );
 
     if (cnf.verbose) displayCommand(args);
 
@@ -1393,7 +1406,11 @@
     if (ofname.isEmpty()) ofname = QString(fw->getName().c_str()) + ".fw";
 
     QString fwfname = getFileDir( mw->getRCS()->getFileName() ) + "/" + ofname;
-    if ( !QFile::exists(fwfname) )
+
+/* bug #1617501: "Install fails after compile". Check ofname, just in
+ * case user put full path name for the output script name in options
+ */
+    if ( !QFile::exists(fwfname) && !QFile::exists(ofname))
     {
 /* need to recompile */
         addToLog(tr("Firewall isn't compiled."));
@@ -1401,6 +1418,7 @@
         return false;
     }
     
+
     args.clear();
     
    
diff -uNr fwbuilder-2.1.8/src/gui/instDialog.h fwbuilder-2.1.9/src/gui/instDialog.h
--- fwbuilder-2.1.8/src/gui/instDialog.h	2006-09-16 09:00:53.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instDialog.h	2007-01-30 17:48:10.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: instDialog.h,v 1.32 2006/09/16 07:00:53 vkurland Exp $
+  $Id: instDialog.h,v 1.34 2007/01/30 16:48:10 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -101,29 +101,29 @@
 
     std::map<libfwbuilder::Firewall *, t_procMess>    processedFirewalls;
 
-    t_fwList    firewalls;
-    t_fwList    opList;
+    t_fwList      firewalls;
+    t_fwList      opList;
 
-    t_fwList::iterator    opListIterator;
+    t_fwList::iterator   opListIterator;
 
-    t_listMap opListMapping;
-    t_tableMap compileMapping;
-    t_tableMap installMapping;
+    t_listMap            opListMapping;
+    t_tableMap           compileMapping;
+    t_tableMap           installMapping;
     
-    QStringList args;
+    QStringList          args;
         
-    QTextEdit    *currentLog;
-    QButton      *currentSaveButton;
-    QButton      *currentStopButton;
-    QProgressBar *currentProgressBar;
-    QProgressBar *currentFirewallsBar;
-    QLabel       *currentLabel;
-    QLabel       *currentFWLabel;
-    QString     currentSearchString;
+    QTextEdit           *currentLog;
+    QButton             *currentSaveButton;
+    QButton             *currentStopButton;
+    QProgressBar        *currentProgressBar;
+    QProgressBar        *currentFirewallsBar;
+    QLabel              *currentLabel;
+    QLabel              *currentFWLabel;
+    QString              currentSearchString;
     
-    BatchOperation operation;
+    BatchOperation       operation;
     instOptionsDialog_q *dlg;
-    QString        pendingLogLine;
+    QString              pendingLogLine;
 
     int progress;
     int totalRules;
@@ -182,6 +182,9 @@
     virtual void prepareInstConf(libfwbuilder::Firewall *fw);
     virtual void storeInstallerOptions();
     virtual void findFirewalls();
+
+    QString getFullPath(instConf &cnf, const QString &file );
+
  protected slots:
      void processExited();
      void installerFinished();
diff -uNr fwbuilder-2.1.8/src/gui/instOptionsDialog.cpp fwbuilder-2.1.9/src/gui/instOptionsDialog.cpp
--- fwbuilder-2.1.8/src/gui/instOptionsDialog.cpp	2006-04-13 18:18:52.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instOptionsDialog.cpp	2007-01-06 09:24:57.000000000 +0100
@@ -2,11 +2,11 @@
 
                           Firewall Builder
 
-                 Copyright (C) 2003 NetCitadel, LLC
+                 Copyright (C) 2006 NetCitadel, LLC
 
   Author:  Illiya Yalovoy <yalovoy@gmail.com>
 
-  $Id: instOptionsDialog.cpp,v 1.1 2006/04/13 16:18:52 vkurland Exp $
+  $Id: instOptionsDialog.cpp,v 1.2 2007/01/06 08:24:57 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -31,12 +31,12 @@
 
 #include "instOptionsDialog.h"
 
-#include "fwbuilder/Library.h"
-#include "fwbuilder/FWException.h"
-#include "fwbuilder/Firewall.h"
-
 #include <qstring.h>
 #include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
 
 #include <stdlib.h>
 
@@ -44,6 +44,12 @@
 using namespace libfwbuilder;
 
     
+instOptionsDialog::instOptionsDialog(QWidget *parent) : instOptionsDialog_q(parent)
+{
+    delta_y = 0;
+    setSizeGripEnabled(false);
+    resize( 600, 600 );
+}
 
 void instOptionsDialog::applyChanges()
 {
@@ -59,6 +65,29 @@
 QString instOptionsDialog::getPWD()   { return pwd->text();   }
 QString instOptionsDialog::getEPWD()  { return epwd->text();  }
 
+void instOptionsDialog::hidePIXOptions()
+{
+    QLayout *l = layout();
+    int m = l->spacing();
+
+    delta_y += incr->height() + m;                  incr->hide();
+    delta_y += test->height() + m;                  test->hide();
+    //delta_y += saveDiff->height() + m;              saveDiff->hide();
+    delta_y += saveStandby->height() + m;           saveStandby->hide();
+    delta_y += backupConfigFile->height() + m;      backupConfigFile->hide();
+    delta_y += backupConfigFileLbl->height() + m;   backupConfigFileLbl->hide();
+    delta_y += epwd->height() + m;                  epwd->hide();
+    delta_y += epwdLbl->height() + m;               epwdLbl->hide();
+
+    PIXgroupBox->hide();
+}
+
+void instOptionsDialog::hideOption(QWidget *w)
+{
+    delta_y += w->height();
+    w->hide();
+}
+
 void instOptionsDialog::closeEvent(QCloseEvent *e)
 {
     if (fwbdebug)
@@ -66,3 +95,27 @@
     hide();
 }
 
+QSize instOptionsDialog::sizeHint() const
+{
+    QSize sh = QDialog::sizeHint();
+    sh.setHeight( sh.height() - ((delta_y)?(delta_y+20):0) );
+    if (fwbdebug)
+    {
+        qDebug(QString("instOptionsDialog::sizeHint:  w=%1 h=%2").arg(sh.width()).arg(sh.height()));
+        qDebug(QString("delta_y=%1").arg(delta_y));
+    }
+    return sh;
+}
+
+QSize instOptionsDialog::minimumSizeHint() const
+{
+    QSize sh = QDialog::minimumSizeHint();
+    sh.setHeight( sh.height() - ((delta_y)?(delta_y+20):0) );
+    if (fwbdebug)
+    {
+        qDebug(QString("instOptionsDialog::minimumSizeHint:  w=%1 h=%2").arg(sh.width()).arg(sh.height()));
+        qDebug(QString("delta_y=%1").arg(delta_y));
+    }
+    return sh;
+}
+
diff -uNr fwbuilder-2.1.8/src/gui/instOptionsDialog.h fwbuilder-2.1.9/src/gui/instOptionsDialog.h
--- fwbuilder-2.1.8/src/gui/instOptionsDialog.h	2006-04-13 18:18:52.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instOptionsDialog.h	2007-01-06 09:24:57.000000000 +0100
@@ -2,11 +2,11 @@
 
                           Firewall Builder
 
-                 Copyright (C) 2003 NetCitadel, LLC
+                 Copyright (C) 2006 NetCitadel, LLC
 
   Author:  Illiya Yalovoy <yalovoy@gmail.com>
 
-  $Id: instOptionsDialog.h,v 1.1 2006/04/13 16:18:52 vkurland Exp $
+  $Id: instOptionsDialog.h,v 1.2 2007/01/06 08:24:57 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -30,23 +30,25 @@
 #include "config.h"
 #include <instoptionsdialog_q.h>
 
-#include "fwbuilder/FWObject.h"
-#include "fwbuilder/Resources.h"
-
-
-
 class instOptionsDialog : public instOptionsDialog_q
 {
     Q_OBJECT
  private:
- 
+    int delta_y;
+
  public:
-    instOptionsDialog(QWidget *parent) : instOptionsDialog_q(parent){};
+    instOptionsDialog(QWidget *parent);
     virtual void closeEvent(QCloseEvent *e);
+
     QString getUName();
     QString getPWD();
     QString getEPWD();
 
+    virtual QSize sizeHint() const;
+    virtual QSize minimumSizeHint() const;
+
+    virtual void hidePIXOptions();
+    virtual void hideOption(QWidget *w);
 
 public slots:
     virtual void applyChanges();
diff -uNr fwbuilder-2.1.8/src/gui/instoptionsdialog_q.ui fwbuilder-2.1.9/src/gui/instoptionsdialog_q.ui
--- fwbuilder-2.1.8/src/gui/instoptionsdialog_q.ui	2006-10-24 06:05:57.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/instoptionsdialog_q.ui	2007-01-06 09:24:57.000000000 +0100
@@ -8,13 +8,37 @@
         <rect>
             <x>0</x>
             <y>0</y>
-            <width>592</width>
-            <height>834</height>
+            <width>589</width>
+            <height>793</height>
         </rect>
     </property>
+    <property name="sizePolicy">
+        <sizepolicy>
+            <hsizetype>5</hsizetype>
+            <vsizetype>0</vsizetype>
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+        </sizepolicy>
+    </property>
+    <property name="maximumSize">
+        <size>
+            <width>32767</width>
+            <height>32767</height>
+        </size>
+    </property>
+    <property name="font">
+        <font>
+        </font>
+    </property>
     <property name="caption">
         <string>Install options</string>
     </property>
+    <property name="focusPolicy">
+        <enum>StrongFocus</enum>
+    </property>
+    <property name="sizeGripEnabled">
+        <bool>false</bool>
+    </property>
     <vbox>
         <property name="name">
             <cstring>unnamed</cstring>
@@ -65,7 +89,7 @@
             <property name="sizePolicy">
                 <sizepolicy>
                     <hsizetype>5</hsizetype>
-                    <vsizetype>1</vsizetype>
+                    <vsizetype>0</vsizetype>
                     <horstretch>0</horstretch>
                     <verstretch>0</verstretch>
                 </sizepolicy>
@@ -76,11 +100,11 @@
             <property name="frameShadow">
                 <enum>Plain</enum>
             </property>
-            <grid>
+            <vbox>
                 <property name="name">
                     <cstring>unnamed</cstring>
                 </property>
-                <widget class="QLabel" row="0" column="0">
+                <widget class="QLabel">
                     <property name="name">
                         <cstring>textLabel6</cstring>
                     </property>
@@ -88,7 +112,7 @@
                         <string>Enter authentication information below and click 'Next'</string>
                     </property>
                 </widget>
-                <widget class="QLayoutWidget" row="1" column="0">
+                <widget class="QLayoutWidget">
                     <property name="name">
                         <cstring>layout7</cstring>
                     </property>
@@ -168,10 +192,18 @@
                         </spacer>
                     </hbox>
                 </widget>
-                <widget class="QGroupBox" row="2" column="0">
+                <widget class="QGroupBox">
                     <property name="name">
                         <cstring>PIXgroupBox</cstring>
                     </property>
+                    <property name="sizePolicy">
+                        <sizepolicy>
+                            <hsizetype>5</hsizetype>
+                            <vsizetype>0</vsizetype>
+                            <horstretch>0</horstretch>
+                            <verstretch>0</verstretch>
+                        </sizepolicy>
+                    </property>
                     <property name="frameShape">
                         <enum>Box</enum>
                     </property>
@@ -275,7 +307,7 @@
                         </widget>
                     </grid>
                 </widget>
-                <widget class="QLayoutWidget" row="3" column="0">
+                <widget class="QLayoutWidget">
                     <property name="name">
                         <cstring>layout9</cstring>
                     </property>
@@ -309,27 +341,82 @@
                         </widget>
                     </grid>
                 </widget>
-                <spacer row="6" column="0">
+                <widget class="QFrame">
                     <property name="name">
-                        <cstring>spacer36</cstring>
+                        <cstring>frame13</cstring>
                     </property>
-                    <property name="orientation">
-                        <enum>Vertical</enum>
+                    <property name="sizePolicy">
+                        <sizepolicy>
+                            <hsizetype>5</hsizetype>
+                            <vsizetype>0</vsizetype>
+                            <horstretch>0</horstretch>
+                            <verstretch>0</verstretch>
+                        </sizepolicy>
                     </property>
-                    <property name="sizeType">
-                        <enum>Expanding</enum>
+                    <property name="frameShape">
+                        <enum>Box</enum>
                     </property>
-                    <property name="sizeHint">
-                        <size>
-                            <width>20</width>
-                            <height>30</height>
-                        </size>
+                    <property name="frameShadow">
+                        <enum>Plain</enum>
                     </property>
-                </spacer>
-                <widget class="QFrame" row="5" column="0">
+                    <grid>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <widget class="QCheckBox" row="0" column="0">
+                            <property name="name">
+                                <cstring>quiet</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Quiet install: do not print anything as commands are executed on the firewall</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="1" column="0">
+                            <property name="name">
+                                <cstring>verbose</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Verbose: print all commands as they are executed on the firewall</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="2" column="0">
+                            <property name="name">
+                                <cstring>stripComments</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Remove comments from configuration</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="3" column="0">
+                            <property name="name">
+                                <cstring>compressScript</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Compress script</string>
+                            </property>
+                        </widget>
+                        <widget class="QCheckBox" row="4" column="0">
+                            <property name="name">
+                                <cstring>copyFWB</cstring>
+                            </property>
+                            <property name="text">
+                                <string>Store a copy of fwb file on the firewall</string>
+                            </property>
+                        </widget>
+                    </grid>
+                </widget>
+                <widget class="QFrame">
                     <property name="name">
                         <cstring>frame5</cstring>
                     </property>
+                    <property name="sizePolicy">
+                        <sizepolicy>
+                            <hsizetype>5</hsizetype>
+                            <vsizetype>0</vsizetype>
+                            <horstretch>0</horstretch>
+                            <verstretch>0</verstretch>
+                        </sizepolicy>
+                    </property>
                     <property name="frameShape">
                         <enum>Box</enum>
                     </property>
@@ -439,71 +526,7 @@
                         </spacer>
                     </grid>
                 </widget>
-                <widget class="QFrame" row="4" column="0">
-                    <property name="name">
-                        <cstring>frame13</cstring>
-                    </property>
-                    <property name="sizePolicy">
-                        <sizepolicy>
-                            <hsizetype>5</hsizetype>
-                            <vsizetype>5</vsizetype>
-                            <horstretch>0</horstretch>
-                            <verstretch>0</verstretch>
-                        </sizepolicy>
-                    </property>
-                    <property name="frameShape">
-                        <enum>Box</enum>
-                    </property>
-                    <property name="frameShadow">
-                        <enum>Plain</enum>
-                    </property>
-                    <grid>
-                        <property name="name">
-                            <cstring>unnamed</cstring>
-                        </property>
-                        <widget class="QCheckBox" row="0" column="0">
-                            <property name="name">
-                                <cstring>quiet</cstring>
-                            </property>
-                            <property name="text">
-                                <string>Quiet install: do not print anything as commands are executed on the firewall</string>
-                            </property>
-                        </widget>
-                        <widget class="QCheckBox" row="1" column="0">
-                            <property name="name">
-                                <cstring>verbose</cstring>
-                            </property>
-                            <property name="text">
-                                <string>Verbose: print all commands as they are executed on the firewall</string>
-                            </property>
-                        </widget>
-                        <widget class="QCheckBox" row="2" column="0">
-                            <property name="name">
-                                <cstring>stripComments</cstring>
-                            </property>
-                            <property name="text">
-                                <string>Remove comments from configuration</string>
-                            </property>
-                        </widget>
-                        <widget class="QCheckBox" row="3" column="0">
-                            <property name="name">
-                                <cstring>compressScript</cstring>
-                            </property>
-                            <property name="text">
-                                <string>Compress script</string>
-                            </property>
-                        </widget>
-                        <widget class="QCheckBox" row="4" column="0">
-                            <property name="name">
-                                <cstring>copyFWB</cstring>
-                            </property>
-                            <property name="text">
-                                <string>Store a copy of fwb file on the firewall</string>
-                            </property>
-                        </widget>
-                    </grid>
-                </widget>
-            </grid>
+            </vbox>
         </widget>
         <widget class="QLayoutWidget">
             <property name="name">
@@ -588,6 +611,10 @@
     <tabstop>okButton</tabstop>
     <tabstop>cancelButton</tabstop>
 </tabstops>
+<functions>
+    <function>hidePIXOptions()</function>
+    <function>hideOption(QWidget *w)</function>
+</functions>
 <pixmapinproject/>
 <layoutdefaults spacing="6" margin="11"/>
 </UI>
diff -uNr fwbuilder-2.1.8/src/gui/ipfAdvancedDialog.cpp fwbuilder-2.1.9/src/gui/ipfAdvancedDialog.cpp
--- fwbuilder-2.1.8/src/gui/ipfAdvancedDialog.cpp	2006-04-11 06:26:26.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ipfAdvancedDialog.cpp	2007-01-06 23:03:25.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ipfAdvancedDialog.cpp,v 1.15 2006/04/11 04:26:26 vkurland Exp $
+  $Id: ipfAdvancedDialog.cpp,v 1.16 2007/01/06 22:03:25 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -163,7 +163,8 @@
 
 void ipfAdvancedDialog::editProlog()
 {
-    SimpleTextEditor edt( prolog_script->text(),
+    SimpleTextEditor edt(this,
+                         prolog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         prolog_script->setText( edt.text() );
@@ -171,7 +172,8 @@
 
 void ipfAdvancedDialog::editEpilog()
 {
-    SimpleTextEditor edt( epilog_script->text(),
+    SimpleTextEditor edt(this,
+                         epilog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         epilog_script->setText( edt.text() );
diff -uNr fwbuilder-2.1.8/src/gui/ipfwAdvancedDialog.cpp fwbuilder-2.1.9/src/gui/ipfwAdvancedDialog.cpp
--- fwbuilder-2.1.8/src/gui/ipfwAdvancedDialog.cpp	2006-10-07 08:16:54.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ipfwAdvancedDialog.cpp	2007-01-06 23:03:25.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ipfwAdvancedDialog.cpp,v 1.12 2006/10/07 06:16:54 vkurland Exp $
+  $Id: ipfwAdvancedDialog.cpp,v 1.13 2007/01/06 22:03:25 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -139,7 +139,8 @@
 
 void ipfwAdvancedDialog::editProlog()
 {
-    SimpleTextEditor edt( prolog_script->text(),
+    SimpleTextEditor edt(this,
+                         prolog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         prolog_script->setText( edt.text() );
@@ -147,7 +148,8 @@
 
 void ipfwAdvancedDialog::editEpilog()
 {
-    SimpleTextEditor edt( epilog_script->text(),
+    SimpleTextEditor edt(this,
+                         epilog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         epilog_script->setText( edt.text() );
diff -uNr fwbuilder-2.1.8/src/gui/iptAdvancedDialog.cpp fwbuilder-2.1.9/src/gui/iptAdvancedDialog.cpp
--- fwbuilder-2.1.8/src/gui/iptAdvancedDialog.cpp	2006-03-16 06:38:14.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/iptAdvancedDialog.cpp	2007-01-15 05:37:52.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: iptAdvancedDialog.cpp,v 1.26 2006/03/16 05:38:14 vkurland Exp $
+  $Id: iptAdvancedDialog.cpp,v 1.28 2007/01/15 04:37:52 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -94,40 +94,43 @@
     logLimitSuffix->insertStringList(getScreenNames(slm));
     data.registerOption( logLimitSuffix,   fwoptions,  "limit_suffix", slm); 
     
-    data.registerOption(logLimitVal,          fwoptions, "limit_value"                          );
-    data.registerOption(logAll,               fwoptions, "log_all"                              );
-    data.registerOption(compiler,             fwoptions, "compiler"                             );
-    data.registerOption(compilerArgs,         fwoptions, "cmdline"                              );
-    data.registerOption(outputFileName,       fwoptions, "output_file"                          );
-    data.registerOption(assumeFwIsPartOfAny,  fwoptions, "firewall_is_part_of_any_and_networks" );
-    data.registerOption(acceptSessions,       fwoptions, "accept_new_tcp_with_no_syn"           );
-    data.registerOption(dropInvalid,          fwoptions, "drop_invalid"                         );
-    data.registerOption(logInvalid,           fwoptions, "log_invalid"                          );
-    data.registerOption(acceptESTBeforeFirst, fwoptions, "accept_established"                   );
-    data.registerOption(bridge,               fwoptions, "bridging_fw"                          );
-    data.registerOption(shadowing,            fwoptions, "check_shading"                        );
-    data.registerOption(emptyGroups,          fwoptions, "ignore_empty_groups"                  );
-    data.registerOption(localNAT,             fwoptions, "local_nat"                            );
-    data.registerOption(clampMSStoMTU,        fwoptions, "clamp_mss_to_mtu"                     );
+    data.registerOption(logLimitVal,          fwoptions, "limit_value");
+    data.registerOption(logAll,               fwoptions, "log_all");
+    data.registerOption(compiler,             fwoptions, "compiler");
+    data.registerOption(compilerArgs,         fwoptions, "cmdline");
+    data.registerOption(outputFileName,       fwoptions, "output_file");
+    data.registerOption(assumeFwIsPartOfAny,  fwoptions, "firewall_is_part_of_any_and_networks");
+    data.registerOption(acceptSessions,       fwoptions, "accept_new_tcp_with_no_syn");
+    data.registerOption(dropInvalid,          fwoptions, "drop_invalid");
+    data.registerOption(logInvalid,           fwoptions, "log_invalid");
+    data.registerOption(acceptESTBeforeFirst, fwoptions, "accept_established");
+    data.registerOption(bridge,               fwoptions, "bridging_fw");
+    data.registerOption(shadowing,            fwoptions, "check_shading");
+    data.registerOption(emptyGroups,          fwoptions, "ignore_empty_groups");
+    data.registerOption(localNAT,             fwoptions, "local_nat");
+    data.registerOption(clampMSStoMTU,        fwoptions, "clamp_mss_to_mtu");
+    data.registerOption(makeTagClassifyTerminating,
+                                              fwoptions, "classify_mark_terminating");
 
     slm=getActionsOnReject( obj->getStr("platform").c_str() );
     actionOnReject->clear();
     actionOnReject->insertStringList(getScreenNames(slm));
-    data.registerOption( actionOnReject,   fwoptions,"action_on_reject", slm); 
+    data.registerOption( actionOnReject,      fwoptions,"action_on_reject", slm); 
     
-    data.registerOption(mgmt_ssh    ,fwoptions, "mgmt_ssh"    );
-    data.registerOption(mgmt_addr    ,fwoptions, "mgmt_addr"    );
-    data.registerOption(addVirtualsforNAT    ,fwoptions, "manage_virtual_addr"    );
-    data.registerOption(configureInterfaces    ,fwoptions, "configure_interfaces"    );
-    data.registerOption(iptDebug    ,fwoptions, "debug"    );
-    data.registerOption(verifyInterfaces    ,fwoptions, "verify_interfaces"    );
-    data.registerOption(loadModules    ,fwoptions, "load_modules"    );
-    data.registerOption(iptablesRestoreActivation    ,fwoptions, "use_iptables_restore"    );
-    data.registerOption(ipt_fw_dir    ,fwoptions, "firewall_dir"    );
-    data.registerOption(ipt_user    ,fwoptions, "admUser"    );
-    data.registerOption(altAddress    ,fwoptions, "altAddress"    );
-    data.registerOption(sshArgs    ,fwoptions, "sshArgs"    );
-    data.registerOption(activationCmd    ,fwoptions, "activationCmd"    );
+    data.registerOption(mgmt_ssh,             fwoptions, "mgmt_ssh"    );
+    data.registerOption(mgmt_addr,            fwoptions, "mgmt_addr"    );
+    data.registerOption(addVirtualsforNAT,    fwoptions, "manage_virtual_addr"    );
+    data.registerOption(configureInterfaces,  fwoptions, "configure_interfaces"    );
+    data.registerOption(iptDebug,             fwoptions, "debug"    );
+    data.registerOption(verifyInterfaces,     fwoptions, "verify_interfaces"    );
+    data.registerOption(loadModules,          fwoptions, "load_modules"    );
+    data.registerOption(iptablesRestoreActivation,
+                                              fwoptions, "use_iptables_restore"    );
+    data.registerOption(ipt_fw_dir,           fwoptions, "firewall_dir"    );
+    data.registerOption(ipt_user,             fwoptions, "admUser"    );
+    data.registerOption(altAddress,           fwoptions, "altAddress"    );
+    data.registerOption(sshArgs,              fwoptions, "sshArgs"    );
+    data.registerOption(activationCmd,        fwoptions, "activationCmd"    );
 
 
     PolicyInstallScript *pis   = mgmt->getPolicyInstallScript();
@@ -212,7 +215,8 @@
 
 void iptAdvancedDialog::editProlog()
 {
-    SimpleTextEditor edt( prolog_script->text(),
+    SimpleTextEditor edt(this,
+                         prolog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         prolog_script->setText( edt.text() );
@@ -220,7 +224,8 @@
 
 void iptAdvancedDialog::editEpilog()
 {
-    SimpleTextEditor edt( epilog_script->text(),
+    SimpleTextEditor edt(this,
+                         epilog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         epilog_script->setText( edt.text() );
diff -uNr fwbuilder-2.1.8/src/gui/iptadvanceddialog_q.ui fwbuilder-2.1.9/src/gui/iptadvanceddialog_q.ui
--- fwbuilder-2.1.8/src/gui/iptadvanceddialog_q.ui	2006-06-01 08:26:53.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/iptadvanceddialog_q.ui	2007-01-15 05:37:52.000000000 +0100
@@ -12,7 +12,7 @@
             <x>0</x>
             <y>0</y>
             <width>677</width>
-            <height>660</height>
+            <height>699</height>
         </rect>
     </property>
     <property name="sizePolicy">
@@ -139,51 +139,7 @@
                             <set>AlignVCenter|AlignRight</set>
                         </property>
                     </widget>
-                    <spacer row="16" column="1">
-                        <property name="name">
-                            <cstring>spacer26</cstring>
-                        </property>
-                        <property name="orientation">
-                            <enum>Vertical</enum>
-                        </property>
-                        <property name="sizeType">
-                            <enum>Expanding</enum>
-                        </property>
-                        <property name="sizeHint">
-                            <size>
-                                <width>20</width>
-                                <height>20</height>
-                            </size>
-                        </property>
-                    </spacer>
-                    <spacer row="15" column="0">
-                        <property name="name">
-                            <cstring>spacer10_3</cstring>
-                        </property>
-                        <property name="orientation">
-                            <enum>Horizontal</enum>
-                        </property>
-                        <property name="sizeType">
-                            <enum>Fixed</enum>
-                        </property>
-                        <property name="sizeHint">
-                            <size>
-                                <width>30</width>
-                                <height>50</height>
-                            </size>
-                        </property>
-                    </spacer>
-                    <widget class="QCheckBox" row="15" column="1" rowspan="1" colspan="2">
-                        <property name="name">
-                            <cstring>mgmt_ssh</cstring>
-                        </property>
-                        <property name="text">
-                            <string>Always permit ssh access from
-the management workstation
-with this address:</string>
-                        </property>
-                    </widget>
-                    <widget class="QCheckBox" row="6" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="6" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>acceptESTBeforeFirst</cstring>
                         </property>
@@ -199,7 +155,7 @@
                             <string>Accept ESTABLISHED and RELATED packets before the first rule</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="8" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="8" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>bridge</cstring>
                         </property>
@@ -232,7 +188,7 @@
                             </size>
                         </property>
                     </spacer>
-                    <widget class="QCheckBox" row="9" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="9" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>shadowing</cstring>
                         </property>
@@ -248,7 +204,7 @@
                             <string>Detect shadowing in policy rules</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="4" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="4" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>assumeFwIsPartOfAny</cstring>
                         </property>
@@ -264,7 +220,7 @@
                             <string>Assume firewall is part of 'any'</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="5" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="5" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>acceptSessions</cstring>
                         </property>
@@ -280,23 +236,7 @@
                             <string>Accept TCP sessions opened prior to firewall restart</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="12" column="1" rowspan="1" colspan="5">
-                        <property name="name">
-                            <cstring>clampMSStoMTU</cstring>
-                        </property>
-                        <property name="sizePolicy">
-                            <sizepolicy>
-                                <hsizetype>1</hsizetype>
-                                <vsizetype>0</vsizetype>
-                                <horstretch>0</horstretch>
-                                <verstretch>0</verstretch>
-                            </sizepolicy>
-                        </property>
-                        <property name="text">
-                            <string>Clamp MSS to MTU</string>
-                        </property>
-                    </widget>
-                    <widget class="QCheckBox" row="11" column="1" rowspan="1" colspan="5">
+                    <widget class="QCheckBox" row="11" column="1" rowspan="1" colspan="4">
                         <property name="name">
                             <cstring>localNAT</cstring>
                         </property>
@@ -312,22 +252,6 @@
                             <string>Enable support for NAT of locally originated connections</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="10" column="1" rowspan="1" colspan="5">
-                        <property name="name">
-                            <cstring>emptyGroups</cstring>
-                        </property>
-                        <property name="sizePolicy">
-                            <sizepolicy>
-                                <hsizetype>1</hsizetype>
-                                <vsizetype>0</vsizetype>
-                                <horstretch>0</horstretch>
-                                <verstretch>0</verstretch>
-                            </sizepolicy>
-                        </property>
-                        <property name="text">
-                            <string>Ignore empty groups in rules</string>
-                        </property>
-                    </widget>
                     <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
                         <property name="name">
                             <cstring>compilerLabel</cstring>
@@ -358,9 +282,40 @@
                             <set>WordBreak|AlignVCenter</set>
                         </property>
                     </widget>
-                    <spacer row="13" column="5">
+                    <widget class="Line" row="3" column="0" rowspan="1" colspan="5">
                         <property name="name">
-                            <cstring>spacer30</cstring>
+                            <cstring>line4_2</cstring>
+                        </property>
+                        <property name="frameShape">
+                            <enum>HLine</enum>
+                        </property>
+                        <property name="frameShadow">
+                            <enum>Sunken</enum>
+                        </property>
+                        <property name="orientation">
+                            <enum>Horizontal</enum>
+                        </property>
+                    </widget>
+                    <widget class="QCheckBox" row="7" column="1" rowspan="1" colspan="2">
+                        <property name="name">
+                            <cstring>dropInvalid</cstring>
+                        </property>
+                        <property name="text">
+                            <string>Drop packets that are associated with
+no known connection</string>
+                        </property>
+                    </widget>
+                    <widget class="QCheckBox" row="7" column="3">
+                        <property name="name">
+                            <cstring>logInvalid</cstring>
+                        </property>
+                        <property name="text">
+                            <string>and log them</string>
+                        </property>
+                    </widget>
+                    <spacer row="7" column="4">
+                        <property name="name">
+                            <cstring>spacer83</cstring>
                         </property>
                         <property name="orientation">
                             <enum>Horizontal</enum>
@@ -370,41 +325,110 @@
                         </property>
                         <property name="sizeHint">
                             <size>
-                                <width>72</width>
+                                <width>80</width>
                                 <height>20</height>
                             </size>
                         </property>
                     </spacer>
-                    <widget class="QComboBox" row="13" column="2" rowspan="1" colspan="3">
+                    <widget class="QLineEdit" row="2" column="3" rowspan="1" colspan="2">
                         <property name="name">
-                            <cstring>actionOnReject</cstring>
+                            <cstring>outputFileName</cstring>
+                        </property>
+                        <property name="maximumSize">
+                            <size>
+                                <width>32767</width>
+                                <height>32767</height>
+                            </size>
                         </property>
                     </widget>
-                    <widget class="QLabel" row="13" column="1">
+                    <widget class="QLineEdit" row="1" column="3" rowspan="1" colspan="2">
                         <property name="name">
-                            <cstring>textLabel9</cstring>
+                            <cstring>compilerArgs</cstring>
                         </property>
-                        <property name="text">
-                            <string>Default action on 'Reject':</string>
+                        <property name="maximumSize">
+                            <size>
+                                <width>32767</width>
+                                <height>32767</height>
+                            </size>
                         </property>
                     </widget>
-                    <widget class="Line" row="14" column="0" rowspan="1" colspan="6">
+                    <widget class="QLineEdit" row="0" column="3" rowspan="1" colspan="2">
                         <property name="name">
-                            <cstring>line4</cstring>
+                            <cstring>compiler</cstring>
                         </property>
-                        <property name="frameShape">
-                            <enum>HLine</enum>
+                        <property name="maximumSize">
+                            <size>
+                                <width>32767</width>
+                                <height>32767</height>
+                            </size>
                         </property>
-                        <property name="frameShadow">
-                            <enum>Sunken</enum>
+                    </widget>
+                    <spacer row="17" column="1">
+                        <property name="name">
+                            <cstring>spacer26</cstring>
+                        </property>
+                        <property name="orientation">
+                            <enum>Vertical</enum>
+                        </property>
+                        <property name="sizeType">
+                            <enum>Expanding</enum>
+                        </property>
+                        <property name="sizeHint">
+                            <size>
+                                <width>20</width>
+                                <height>20</height>
+                            </size>
+                        </property>
+                    </spacer>
+                    <widget class="QCheckBox" row="16" column="1" rowspan="1" colspan="2">
+                        <property name="name">
+                            <cstring>mgmt_ssh</cstring>
+                        </property>
+                        <property name="text">
+                            <string>Always permit ssh access from
+the management workstation
+with this address:</string>
+                        </property>
+                    </widget>
+                    <spacer row="16" column="0">
+                        <property name="name">
+                            <cstring>spacer10_3</cstring>
                         </property>
                         <property name="orientation">
                             <enum>Horizontal</enum>
                         </property>
+                        <property name="sizeType">
+                            <enum>Fixed</enum>
+                        </property>
+                        <property name="sizeHint">
+                            <size>
+                                <width>30</width>
+                                <height>50</height>
+                            </size>
+                        </property>
+                    </spacer>
+                    <widget class="QLineEdit" row="16" column="3" rowspan="1" colspan="2">
+                        <property name="name">
+                            <cstring>mgmt_addr</cstring>
+                        </property>
+                        <property name="sizePolicy">
+                            <sizepolicy>
+                                <hsizetype>7</hsizetype>
+                                <vsizetype>0</vsizetype>
+                                <horstretch>0</horstretch>
+                                <verstretch>0</verstretch>
+                            </sizepolicy>
+                        </property>
+                        <property name="maximumSize">
+                            <size>
+                                <width>32767</width>
+                                <height>32767</height>
+                            </size>
+                        </property>
                     </widget>
-                    <widget class="Line" row="3" column="0" rowspan="1" colspan="6">
+                    <widget class="Line" row="15" column="0" rowspan="1" colspan="5">
                         <property name="name">
-                            <cstring>line4_2</cstring>
+                            <cstring>line4</cstring>
                         </property>
                         <property name="frameShape">
                             <enum>HLine</enum>
@@ -416,26 +440,22 @@
                             <enum>Horizontal</enum>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="7" column="1" rowspan="1" colspan="3">
+                    <widget class="QLabel" row="14" column="1">
                         <property name="name">
-                            <cstring>dropInvalid</cstring>
+                            <cstring>textLabel9</cstring>
                         </property>
                         <property name="text">
-                            <string>Drop packets that are associated with
-no known connection</string>
+                            <string>Default action on 'Reject':</string>
                         </property>
                     </widget>
-                    <widget class="QCheckBox" row="7" column="4">
+                    <widget class="QComboBox" row="14" column="2" rowspan="1" colspan="2">
                         <property name="name">
-                            <cstring>logInvalid</cstring>
-                        </property>
-                        <property name="text">
-                            <string>and log them</string>
+                            <cstring>actionOnReject</cstring>
                         </property>
                     </widget>
-                    <spacer row="7" column="5">
+                    <spacer row="14" column="4">
                         <property name="name">
-                            <cstring>spacer83</cstring>
+                            <cstring>spacer30</cstring>
                         </property>
                         <property name="orientation">
                             <enum>Horizontal</enum>
@@ -445,61 +465,49 @@
                         </property>
                         <property name="sizeHint">
                             <size>
-                                <width>80</width>
+                                <width>72</width>
                                 <height>20</height>
                             </size>
                         </property>
                     </spacer>
-                    <widget class="QLineEdit" row="15" column="3" rowspan="1" colspan="3">
+                    <widget class="QCheckBox" row="12" column="1" rowspan="1" colspan="4">
                         <property name="name">
-                            <cstring>mgmt_addr</cstring>
+                            <cstring>clampMSStoMTU</cstring>
                         </property>
                         <property name="sizePolicy">
                             <sizepolicy>
-                                <hsizetype>7</hsizetype>
+                                <hsizetype>1</hsizetype>
                                 <vsizetype>0</vsizetype>
                                 <horstretch>0</horstretch>
                                 <verstretch>0</verstretch>
                             </sizepolicy>
                         </property>
-                        <property name="maximumSize">
-                            <size>
-                                <width>32767</width>
-                                <height>32767</height>
-                            </size>
+                        <property name="text">
+                            <string>Clamp MSS to MTU</string>
                         </property>
                     </widget>
-                    <widget class="QLineEdit" row="2" column="3" rowspan="1" colspan="3">
+                    <widget class="QCheckBox" row="10" column="1" rowspan="1" colspan="4">
                         <property name="name">
-                            <cstring>outputFileName</cstring>
-                        </property>
-                        <property name="maximumSize">
-                            <size>
-                                <width>32767</width>
-                                <height>32767</height>
-                            </size>
+                            <cstring>emptyGroups</cstring>
                         </property>
-                    </widget>
-                    <widget class="QLineEdit" row="1" column="3" rowspan="1" colspan="3">
-                        <property name="name">
-                            <cstring>compilerArgs</cstring>
+                        <property name="sizePolicy">
+                            <sizepolicy>
+                                <hsizetype>1</hsizetype>
+                                <vsizetype>0</vsizetype>
+                                <horstretch>0</horstretch>
+                                <verstretch>0</verstretch>
+                            </sizepolicy>
                         </property>
-                        <property name="maximumSize">
-                            <size>
-                                <width>32767</width>
-                                <height>32767</height>
-                            </size>
+                        <property name="text">
+                            <string>Ignore empty groups in rules</string>
                         </property>
                     </widget>
-                    <widget class="QLineEdit" row="0" column="3" rowspan="1" colspan="3">
+                    <widget class="QCheckBox" row="13" column="1" rowspan="1" colspan="4">
                         <property name="name">
-                            <cstring>compiler</cstring>
+                            <cstring>makeTagClassifyTerminating</cstring>
                         </property>
-                        <property name="maximumSize">
-                            <size>
-                                <width>32767</width>
-                                <height>32767</height>
-                            </size>
+                        <property name="text">
+                            <string>Make Tag and Classify actions terminating</string>
                         </property>
                     </widget>
                 </grid>
diff -uNr fwbuilder-2.1.8/src/gui/listOfLibraries.cpp fwbuilder-2.1.9/src/gui/listOfLibraries.cpp
--- fwbuilder-2.1.8/src/gui/listOfLibraries.cpp	2006-11-09 17:13:21.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/listOfLibraries.cpp	2007-02-04 05:20:26.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: listOfLibraries.cpp,v 1.19 2006/11/09 16:13:21 vkurland Exp $
+  $Id: listOfLibraries.cpp,v 1.20 2007/02/04 04:20:26 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -193,6 +193,9 @@
     if (id.isEmpty()) return end();
     if (name.isEmpty()) return end();
 
+#if 0
+    // commented out for bug #1620284
+    //
 /*
  *  mw is NULL at this point if this method is called to preload
  *  libraries on startup
@@ -213,6 +216,7 @@
             0, 1 );
         return end();
     }
+#endif
 
     if (id == STANDARD_LIB) return end();
     if (id == DELETED_LIB)  return end();
diff -uNr fwbuilder-2.1.8/src/gui/main.cpp fwbuilder-2.1.9/src/gui/main.cpp
--- fwbuilder-2.1.8/src/gui/main.cpp	2006-10-22 20:20:04.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/main.cpp	2007-02-10 23:41:00.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: main.cpp,v 1.118 2006/10/22 18:20:04 vkurland Exp $
+  $Id: main.cpp,v 1.119 2007/02/10 22:41:00 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -232,7 +232,6 @@
 
 static struct termios save_termios;
 static int            ttysavefd = -1;
-static enum { RESET, RAW, CBREAK } ttystate = RESET;
 
 int tty_raw(int fd)
 {
@@ -263,7 +262,6 @@
         exit(1);
     }
 
-    ttystate = RAW;
     ttysavefd = fd;
     return 0;
 }
diff -uNr fwbuilder-2.1.8/src/gui/ObjConflictResolutionDialog.cpp fwbuilder-2.1.9/src/gui/ObjConflictResolutionDialog.cpp
--- fwbuilder-2.1.8/src/gui/ObjConflictResolutionDialog.cpp	2004-11-13 08:31:27.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/ObjConflictResolutionDialog.cpp	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjConflictResolutionDialog.cpp,v 1.18 2004/11/13 07:31:27 vkurland Exp $
+  $Id: ObjConflictResolutionDialog.cpp,v 1.19 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -43,8 +43,11 @@
 #include <qtextbrowser.h>
 #include <qcheckbox.h>
 #include <qpushbutton.h>
+#include <qmap.h>
 
 #include <iostream>
+#include <sstream>
+#include <iomanip>
 
 using namespace std;
 using namespace libfwbuilder;
@@ -57,7 +60,12 @@
     alwaysNew    =false;
     dlgIcon->setPixmap( QMessageBox::standardIcon( QMessageBox::Warning ) );
 
+    defaultLeftButtonText = tr("Keep current object");
+    defaultRightButtonText = tr("Replace with this object");
+
     if (st->haveGeometry(this)) st->restoreGeometry(this);
+
+    richText = true;
 }
 
 ObjConflictResolutionDialog::~ObjConflictResolutionDialog()
@@ -65,17 +73,30 @@
     saveGeometry();
 }
 
+QString ObjConflictResolutionDialog::makeBold(const QString &str)
+{
+    QString bold   = (richText)?QString("<b>"):"";
+    QString unbold = (richText)?QString("</b>"):"";
+    return QString("%1%2%3").arg(bold).arg(str).arg(unbold);
+}
+
 int ObjConflictResolutionDialog::run(    FWObject *o1,
                                          FWObject *o2)
 {
-    if (alwaysCurrent) return QDialog::Rejected;
-    if (alwaysNew)     return QDialog::Accepted;
+
+    // fill in dialogs even though the user might have
+    // checked checkbox that makes  decision without
+    // them having to click a button. This is so that
+    // classes that inherit from ObjConflictResolutionDialog
+    // can use data collected in this method. Particularly 
+    // CompareObjectsDialog::run needs it
+    
 
     QString leftBtnTxt, rightBtnTxt;
     bool    leftCB,  rightCB, leftBtn, rightBtn;
 
-    leftBtnTxt  = tr("Keep current object");
-    rightBtnTxt = tr("Replace with this object");
+    leftBtnTxt  = defaultLeftButtonText;
+    rightBtnTxt = defaultRightButtonText;
     leftCB=rightCB=leftBtn=rightBtn=true;
 
     QString p1, p2;
@@ -93,7 +114,7 @@
          * here either. It is unclear how to solve this problem
          * correctly. Defer to the user. */
 
-        p1=tr("Object <b>'%1'</b> has been deleted").arg(o1->getName().c_str());
+        p1=tr("Object '%1' has been deleted").arg(makeBold(o1->getName().c_str()));
         rightBtnTxt = tr("Delete");
         leftCB  = rightCB = leftBtn = false;
     } else
@@ -117,7 +138,7 @@
 
         return QDialog::Rejected;
 
-        p2=tr("Object <b>'%1'</b> has been deleted").arg(o2->getName().c_str());
+        p2=tr("Object '%1' has been deleted").arg(makeBold(o2->getName().c_str()));
         leftBtnTxt = tr("Delete");
         leftCB  = rightCB = rightBtn = false;
     } else
@@ -141,17 +162,32 @@
     QString f1= FWObjectDatabase::cast(o1->getRoot())->getFileName().c_str();
     QString f2= FWObjectDatabase::cast(o2->getRoot())->getFileName().c_str();
 
-    if (f1.isEmpty()) f1=tr("Object <b>'%1'</b> in the objects tree")
-                          .arg(o1->getName().c_str());
-    else f1=tr("Object <b>'%1'</b> in file %2").arg(o1->getName().c_str()).arg(f1);
+    current_filename = f1;
+    new_filename = f2;
+
+    current_objname = o1->getName().c_str();
+    new_objname = o2->getName().c_str();
+
+    current_properties = p1;
+    new_properties = p2;
+
+
+    if (f1.isEmpty())
+        f1=tr("Object '%1' in the objects tree").arg(makeBold(o1->getName().c_str()));
+    else
+        f1=tr("Object '%1' in file %2").arg(makeBold(o1->getName().c_str())).arg(f1);
+
+    f2=tr("Object '%1' in file %2").arg(makeBold(o2->getName().c_str())).arg(f2);
 
-    f2=tr("Object <b>'%1'</b> in file %2").arg(o2->getName().c_str()).arg(f2);
 
     currentObjLbl->setText(f1);
     newObjLbl->setText(f2);
     
     currentObj->clear();
+    currentObj->setTextFormat(Qt::RichText);
+
     newObj->clear();
+    newObj->setTextFormat(Qt::RichText);
 
     QString s;
     s="<a name=\"top\">\n";
@@ -172,6 +208,10 @@
     newObj->append( s );
     newObj->scrollToAnchor("top");
 
+
+    if (alwaysCurrent) return QDialog::Rejected;
+    if (alwaysNew)     return QDialog::Accepted;
+
     return QDialog::exec();
 }
 
@@ -237,3 +277,225 @@
 
     QDialog::reject();
 }
+
+// ################################################################
+
+CompareObjectsDialog::CompareObjectsDialog(QWidget *p) :
+    ObjConflictResolutionDialog(p)
+{
+    richText = false;
+    num_conflicts = 0;
+    column_width[0] = 30;
+    column_width[1] = 30;
+    column_width[2] = 30;
+    column_width[3] = 30;
+
+    currentAll->hide();
+    useCurrentObj->hide();
+
+    defaultLeftButtonText = "";
+    defaultRightButtonText = tr("Next");
+
+    dialogHeading->setText( tr("The following two objects have the same internal ID but different attributes:") );
+    newAll->setText( tr("Skip the rest but build report") );
+
+    clearReport();
+
+    // Note : these keys match strings generated by
+    // FWObjectPropertyFactory::getObjectPropertiesDetailed
+    // That is, getObjectPropertiesDetailed generates text like this:
+    //
+    //  Library: TestLibrary
+    //  Object Id: id3F3D04676
+    //  Object Type: Firewall
+    //  Object Name: guardian
+    //
+    // Keys in report_attributes must match strings before ':' exactly
+
+    report_attributes.push_back("Name");
+    report_attributes.push_back("Library");
+    report_attributes.push_back("Object Id");
+    report_attributes.push_back("Object Type");
+    report_attributes.push_back("Object Name");
+    report_attributes.push_back("Path");
+
+}
+
+void CompareObjectsDialog::writeColumn(ostringstream &sstr,
+                                       int column_num,
+                                       const QString &txt)
+{
+    int col_width = column_width[column_num];
+
+    sstr << txt.latin1() << setw(col_width-txt.length()) << setfill(' ') << ' ';
+}
+
+int CompareObjectsDialog::run(FWObject *o1,FWObject *o2)
+{
+    ostringstream str;
+
+    int res = ObjConflictResolutionDialog::run(o1,o2);
+
+    if (fwbdebug)
+        qDebug(QString("left side: %1 paragraphs, %2 lines in paragraph 0").
+               arg(currentObj->paragraphs()).arg(currentObj->linesOfParagraph(0)));
+
+
+/*
+    currentObj->setTextFormat(Qt::PlainText);
+    QString l_text = currentObj->text(0);
+    // QTextEdit returns whole paragraph as one line
+    // Since we enforce PlainText, all html formatting
+    // is lost and individual lines are glued together
+    // with some character that prints as '?'
+    // Could be chr(0) ?
+
+    if (fwbdebug) qDebug("%s",l_text.ascii());
+
+    newObj->setTextFormat(Qt::PlainText);
+    QString r_text = newObj->text(0);
+
+    if (fwbdebug) qDebug("%s",r_text.ascii());
+
+    str << l_text << endl;
+    str << r_text << endl;
+    str << endl;
+*/
+
+    num_conflicts++;
+
+    QString prop1 = FWObjectPropertiesFactory::stripHTML(current_properties);
+    QString prop2 = FWObjectPropertiesFactory::stripHTML(new_properties);
+
+
+    QStringList proplist1 = QStringList::split("\n",prop1);
+    QStringList proplist2 = QStringList::split("\n",prop2);
+
+    QMap<QString,QString> propdict1;
+    QMap<QString,QString> propdict2;
+
+    int n = 0;
+    QStringList::Iterator i1 = proplist1.begin();
+    for ( ; i1!=proplist1.end(); ++i1,++n)
+    {
+        ostringstream tstr;
+        tstr << "key_" << n;
+
+        QString k = (*i1).section(':',0,0).stripWhiteSpace();
+        QString v = (*i1).section(':',1).stripWhiteSpace();
+        if (v=="") 
+        {
+            v = k;
+            k = tstr.str().c_str();
+        }
+
+        if (fwbdebug) qDebug(QString("proplist1:    k='%1'  v='%2'").arg(k).arg(v));
+
+        propdict1[k] = v;
+    }
+
+    n = 0;
+    QStringList::Iterator i2 = proplist2.begin();
+    for ( ; i2!=proplist2.end(); ++i2,++n)
+    {
+        ostringstream tstr;
+        tstr << "key_" << n;
+
+        QString k = (*i2).section(':',0,0).stripWhiteSpace();
+        QString v = (*i2).section(':',1).stripWhiteSpace();
+        if (v=="")
+        {
+            v = k;
+            k = tstr.str().c_str();
+        }
+
+        if (fwbdebug) qDebug(QString("proplist2:    k='%1'  v='%2'").arg(k).arg(v));
+
+        propdict2[k] = v;
+    }
+
+    
+    QStringList::Iterator i3 = report_attributes.begin();
+    for ( ; i3!=report_attributes.end(); ++i3)
+    {
+        QString attr = *i3;
+
+        if (fwbdebug) qDebug(QString("report_attributes:    attr=%1  ").arg(attr));
+
+        if (!propdict1.contains(attr) || !propdict2.contains(attr)) continue;
+
+        writeColumn(str, 1, attr);
+        writeColumn(str, 2, propdict1[attr]);
+        writeColumn(str, 3, propdict2[attr]);
+        str << endl;
+
+        propdict1[attr] = "";
+        propdict2[attr] = "";
+    }
+
+    QMap<QString,QString>::Iterator mi1 = propdict1.begin();
+    for ( ; mi1!=propdict1.end(); ++mi1)
+    {
+        QString key = mi1.key();
+        QString val = mi1.data();
+
+        if (fwbdebug) qDebug(QString("propdict1:    key=%1  val=%2").arg(key).arg(val));
+
+        if (val=="") continue;
+
+        if (key.startsWith("key_"))  writeColumn(str, 1, " ");
+        else                         writeColumn(str, 1, key);
+        if (propdict1.contains(key)) writeColumn(str, 2, propdict1[key]);
+        else                         writeColumn(str, 2, " ");
+        if (propdict2.contains(key)) writeColumn(str, 3, propdict2[key]);
+        else                         writeColumn(str, 3, " ");
+        str << endl;
+
+        propdict1[key] = "";
+        propdict2[key] = "";
+    }
+
+    QMap<QString,QString>::Iterator mi2 = propdict2.begin();
+    for ( ; mi2!=propdict2.end(); ++mi2)
+    {
+        QString key = mi2.key();
+        QString val = mi2.data();
+
+        if (fwbdebug) qDebug(QString("propdict2:    key=%1  val=%2").arg(key).arg(val));
+
+        if (val=="") continue;
+
+        if (key.startsWith("key_"))  writeColumn(str, 1, " ");
+        else                         writeColumn(str, 1, key);
+        if (propdict1.contains(key)) writeColumn(str, 2, propdict1[key]);
+        else                         writeColumn(str, 2, " ");
+        if (propdict2.contains(key)) writeColumn(str, 3, propdict2[key]);
+        else                         writeColumn(str, 3, " ");
+        str << endl;
+    }
+
+    str << setw(78) << setfill('-') << '-' << endl;
+    
+    report.push_back( QString(str.str()) );
+
+    return res;
+}
+
+void CompareObjectsDialog::clearReport()
+{
+    report.clear();
+}
+
+list<QString> CompareObjectsDialog::getReport()
+{
+    ostringstream str;
+
+    str << "File 1:  " << current_filename.latin1() << endl;
+    str << "File 2:  " << new_filename.latin1() << endl;
+    str << setw(78) << setfill('-') << '-' << endl;
+
+    report.push_front( QString(str.str()) );
+
+    return report;
+}
+
diff -uNr fwbuilder-2.1.8/src/gui/ObjConflictResolutionDialog.h fwbuilder-2.1.9/src/gui/ObjConflictResolutionDialog.h
--- fwbuilder-2.1.8/src/gui/ObjConflictResolutionDialog.h	2004-06-29 08:59:01.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ObjConflictResolutionDialog.h	2007-02-04 04:58:59.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjConflictResolutionDialog.h,v 1.7 2004/06/29 06:59:01 vkurland Exp $
+  $Id: ObjConflictResolutionDialog.h,v 1.8 2007/02/04 03:58:59 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -31,6 +31,8 @@
 
 #include "fwbuilder/FWObjectDatabase.h"
 
+#include <sstream>
+
 namespace libfwbuilder {
     class FWObject;
 };
@@ -42,14 +44,29 @@
     bool alwaysCurrent;
     bool alwaysNew;
 
-    void saveGeometry();
-    
+protected:
+
+    QString current_filename;
+    QString new_filename;
+    QString current_objname;
+    QString new_objname;
+    QString current_properties;
+    QString new_properties;
+
+    QString defaultLeftButtonText;
+    QString defaultRightButtonText;
+
+    bool    richText;
+
+    void     saveGeometry();
+    QString  makeBold(const QString &str);
+
 public:
     ObjConflictResolutionDialog(QWidget *parent);
     virtual ~ObjConflictResolutionDialog();
 
-    int run( libfwbuilder::FWObject *o1,
-             libfwbuilder::FWObject *o2);
+    virtual int run( libfwbuilder::FWObject *o1,
+                     libfwbuilder::FWObject *o2);
 
 public slots:
     virtual void closeEvent(QCloseEvent *e);
@@ -76,4 +93,36 @@
 };
 
 
+class CompareObjectsDialog :
+    public libfwbuilder::FWObjectDatabase::ConflictResolutionPredicate,
+    ObjConflictResolutionDialog
+{
+    std::list<QString> report;
+    QStringList        report_attributes;
+    int                num_conflicts;
+    int                column_width[];
+    
+    void writeColumn(std::ostringstream &sstr,
+                     int column_num,
+                     const QString &txt);
+
+
+public:
+    CompareObjectsDialog(QWidget *p);
+    
+    virtual int run( libfwbuilder::FWObject *o1,
+                     libfwbuilder::FWObject *o2);
+
+    void clearReport();
+    std::list<QString> getReport();
+    int  getNumberOfConflicts() { return num_conflicts; }
+
+    
+    virtual bool askUser(libfwbuilder::FWObject *o1,libfwbuilder::FWObject *o2)
+    {
+        run(o1,o2);
+        return QDialog::Accepted;
+    }
+};
+
 #endif
diff -uNr fwbuilder-2.1.8/src/gui/objconflictresolutiondialog_q.ui fwbuilder-2.1.9/src/gui/objconflictresolutiondialog_q.ui
--- fwbuilder-2.1.8/src/gui/objconflictresolutiondialog_q.ui	2004-07-11 08:43:10.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/objconflictresolutiondialog_q.ui	2007-02-04 04:58:59.000000000 +0100
@@ -8,8 +8,8 @@
         <rect>
             <x>0</x>
             <y>0</y>
-            <width>688</width>
-            <height>378</height>
+            <width>850</width>
+            <height>436</height>
         </rect>
     </property>
     <property name="caption">
@@ -40,7 +40,7 @@
         </widget>
         <widget class="QLabel" row="0" column="1">
             <property name="name">
-                <cstring>textLabel1</cstring>
+                <cstring>dialogHeading</cstring>
             </property>
             <property name="sizePolicy">
                 <sizepolicy>
@@ -87,6 +87,14 @@
                         <property name="name">
                             <cstring>groupBox1</cstring>
                         </property>
+                        <property name="sizePolicy">
+                            <sizepolicy>
+                                <hsizetype>5</hsizetype>
+                                <vsizetype>7</vsizetype>
+                                <horstretch>0</horstretch>
+                                <verstretch>0</verstretch>
+                            </sizepolicy>
+                        </property>
                         <property name="title">
                             <string></string>
                         </property>
@@ -160,6 +168,14 @@
                         <property name="name">
                             <cstring>groupBox1_2</cstring>
                         </property>
+                        <property name="sizePolicy">
+                            <sizepolicy>
+                                <hsizetype>5</hsizetype>
+                                <vsizetype>7</vsizetype>
+                                <horstretch>0</horstretch>
+                                <verstretch>0</verstretch>
+                            </sizepolicy>
+                        </property>
                         <property name="title">
                             <string></string>
                         </property>
diff -uNr fwbuilder-2.1.8/src/gui/ObjectManipulator.cpp fwbuilder-2.1.9/src/gui/ObjectManipulator.cpp
--- fwbuilder-2.1.8/src/gui/ObjectManipulator.cpp	2006-10-22 20:20:04.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ObjectManipulator.cpp	2007-01-10 07:28:51.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjectManipulator.cpp,v 1.159 2006/10/22 18:20:04 vkurland Exp $
+  $Id: ObjectManipulator.cpp,v 1.161 2007/01/10 06:28:51 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -130,7 +130,7 @@
     {
         QListViewItem *itm = otv->itemAt( p );
         if (itm==NULL) return;
-        ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(itm);
+        ObjectTreeViewItem *otvi = dynamic_cast<ObjectTreeViewItem*>(itm);
         assert(otvi);
         FWObject *obj=otvi->getFWObject();
         QRect     cr =otv->itemRect(itm);
@@ -147,7 +147,7 @@
     treeHeight   = -1;
     currentObj   = NULL;
     active       = false;
-    currentTreeView=NULL;
+    current_tree_view=NULL;
 
 //    setFocusPolicy( QWidget::StrongFocus  );
 
@@ -782,6 +782,22 @@
     }
 }
 
+void ObjectManipulator::switchingTrees(QWidget* w)
+{
+    ObjectTreeView *new_otv = dynamic_cast<ObjectTreeView*>(w);
+
+    if (fwbdebug)
+        qDebug("ObjectManipulator::switchingTrees  current_otv=%p  new_otv=%p",
+               (void*)(current_tree_view),(void*)(new_otv));
+
+    assert(new_otv);
+
+    if (current_tree_view!=NULL) current_tree_view->becomingHidden();
+    new_otv->becomingVisible();
+    current_tree_view = new_otv;
+
+}
+
 void ObjectManipulator::makeNameUnique(FWObject* parent,FWObject* obj)
 {
     int      suffix=1;
@@ -1822,8 +1838,8 @@
     try
     {
         if (fwbdebug)
-            qDebug("ObjectManipulator::delObj  delete obj %p %s",
-                   obj,obj->getName().c_str());
+            qDebug("ObjectManipulator::delObj  delete obj %p %s openobj=%d",
+                   obj,obj->getName().c_str(),openobj);
 
         FWObject *parent=obj->getParent();
         FWObject *delObjLib = mw->db()->findInIndex( DELETED_LIB );
@@ -1866,7 +1882,7 @@
                 mw->deleteFirewall( *i );
         }
 
-        if (isfw) mw->deleteFirewall(obj);
+        if (isfw && !isDelObj) mw->deleteFirewall(obj);
 
 
 //        removeObjectFromTreeView(obj);
@@ -1901,7 +1917,7 @@
 
         if (openobj)
         {
-            if (isfw)
+            if (isfw && !isDelObj)
             {
                 std::list<Firewall*> fwlist;
                 findAllFirewalls(fwlist);
@@ -2161,8 +2177,15 @@
 
 void ObjectManipulator::showObjectInTree(ObjectTreeViewItem *otvi)
 {
+    if (fwbdebug) qDebug("ObjectManipulator::showObjectInTree");
     if (otvi==NULL) return;
-    widgetStack->raiseWidget( currentTreeView=otvi->getTree() );
+
+    ObjectTreeView* otv = otvi->getTree();
+
+    if (fwbdebug) qDebug("ObjectManipulator::showObjectInTree  current_tree_view=%p  new_otv=%p",current_tree_view,otv);
+
+    widgetStack->raiseWidget( otv );
+
     otvi->getTree()->clearSelection();
     otvi->getTree()->ensureItemVisible( otvi );
     otvi->getTree()->setCurrentItem( otvi );
@@ -2242,7 +2265,7 @@
 
 ObjectTreeView* ObjectManipulator::getCurrentObjectTree()
 {
-    return currentTreeView;
+    return current_tree_view;
 }
 
 void ObjectManipulator::openLib(FWObject *obj)
diff -uNr fwbuilder-2.1.8/src/gui/ObjectManipulator.h fwbuilder-2.1.9/src/gui/ObjectManipulator.h
--- fwbuilder-2.1.8/src/gui/ObjectManipulator.h	2006-10-15 23:43:55.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ObjectManipulator.h	2007-01-08 03:11:48.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjectManipulator.h,v 1.57 2006/10/15 21:43:55 vkurland Exp $
+  $Id: ObjectManipulator.h,v 1.58 2007/01/08 02:11:48 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -83,7 +83,7 @@
     int cacheHits;
 
     libfwbuilder::FWObject                        *currentObj;
-    ObjectTreeView                                *currentTreeView;
+    ObjectTreeView                                *current_tree_view;
     
     int                                            treeWidth;
     int                                            treeHeight;
@@ -124,6 +124,7 @@
 
 public slots:
      virtual void libChanged(int l);
+     virtual void switchingTrees(QWidget* w);
 
      void selectionChanged();
 
@@ -146,6 +147,7 @@
      
      void contextMenu(QListViewItem *item, const QPoint &pos, int col);
 
+     
      libfwbuilder::FWObject* createObject(const QString &objType,
                                           const QString &objName,
                                           libfwbuilder::FWObject *copyFrom=NULL);
diff -uNr fwbuilder-2.1.8/src/gui/objectmanipulator_q.ui fwbuilder-2.1.9/src/gui/objectmanipulator_q.ui
--- fwbuilder-2.1.8/src/gui/objectmanipulator_q.ui	2006-01-21 21:05:39.000000000 +0100
+++ fwbuilder-2.1.9/src/gui/objectmanipulator_q.ui	2007-01-08 03:11:48.000000000 +0100
@@ -190,6 +190,12 @@
         <receiver>ObjectManipulator_q</receiver>
         <slot>newObject()</slot>
     </connection>
+    <connection>
+        <sender>widgetStack</sender>
+        <signal>aboutToShow(QWidget*)</signal>
+        <receiver>ObjectManipulator_q</receiver>
+        <slot>switchingTrees(QWidget*)</slot>
+    </connection>
 </connections>
 <slots>
     <slot>search( const QString &amp; )</slot>
@@ -199,6 +205,8 @@
     <slot>libChanged(int)</slot>
     <slot>lockObject()</slot>
     <slot>unlockObject()</slot>
+    <slot>switchingTrees(QWidget*)</slot>
+    <slot>newSlot()</slot>
 </slots>
 <pixmapinproject/>
 <layoutdefaults spacing="6" margin="11"/>
diff -uNr fwbuilder-2.1.8/src/gui/ObjectTreeView.cpp fwbuilder-2.1.9/src/gui/ObjectTreeView.cpp
--- fwbuilder-2.1.8/src/gui/ObjectTreeView.cpp	2006-10-22 20:20:04.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ObjectTreeView.cpp	2007-01-08 04:24:48.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjectTreeView.cpp,v 1.37 2006/10/22 18:20:04 vkurland Exp $
+  $Id: ObjectTreeView.cpp,v 1.39 2007/01/08 03:24:48 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -76,6 +76,24 @@
     expandOrCollapse = false;
     Lockable = false;
     Unlockable = false;
+    visible = false;
+    /*
+     * note about process_mouse_release_event
+     *
+     * we use mouseReleaseEvent event to switch object opened in the
+     * editor panel (i.e. we open new object when mouse button is
+     * released rather than when it is pressed). This allows us to
+     * start drag without switching object in the editor. The problem
+     * is that mouseReleaseEvent is received in this widget after the
+     * d&d ends with a drop somewhere else, which triggers call to
+     * contentsMouseReleaseEvent which switches object in the
+     * editor. This is undesired when the editor shows a group and we
+     * try to drag and drop an object into that group. Flag
+     * process_mouse_release_event is used to suppress object
+     * switching when contentsMouseReleaseEvent is called after
+     * successfull drop.
+     */
+    process_mouse_release_event = true;
 
     connect( this, SIGNAL(currentChanged(QListViewItem*)),
              this, SLOT(currentChanged(QListViewItem*)) );
@@ -251,13 +269,12 @@
  */
 QDragObject* ObjectTreeView::dragObject()
 {
-    if (fwbdebug)
-        qDebug("ObjectTreeView::dragObject");
+    if (fwbdebug) qDebug("ObjectTreeView::dragObject");
 
     QListViewItem *ovi = currentItem();
     ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(ovi);
 
-    FWObject *obj = getCurrentObject();
+    FWObject *current_obj = getCurrentObject();
 
 /* can't drag system folders 
 
@@ -271,7 +288,7 @@
     if (FWBTree::isSystem(obj)) return NULL;
 */
     QString icn =
-        Resources::global_res->getObjResourceStr(obj, "icon-ref").c_str();
+        Resources::global_res->getObjResourceStr(current_obj, "icon-ref").c_str();
 
     vector<FWObject*> so = getSimplifiedSelection();
 
@@ -315,9 +332,46 @@
                          QPoint( pm.rect().width() / 2,
                                  pm.rect().height() / 2 ) );
 
-// lets try to always reset selection
-    setSelected(otvi,false);
-    resetSelection();
+/*
+ * This fragment returns selection in the tree back to the object that
+ * was selected before drag operation has started. This help in the
+ * following case:
+ *
+ *  - open a group for editing (group is selected in the tree)
+ *  - left-click on another object in the tree, start dragging it
+ *
+ * at this point selection in the tree returns to the group, so when
+ * user finishes d&d operation, the selection in the tree is consisten
+ * with object currently opened in the editor panel.
+ *
+ * There is a problem with this however. If user wants to put an
+ * object from a different library into the group, they have to switch
+ * to that library before doing d&d. When they switch, ObjectTree
+ * shown in the left panel becomes different from the tree in which
+ * the group is located. When d&d finishes, the ObjectTree object
+ * receives contentsMouseReleaseEvent event. Since it is not the right
+ * tree object, it can not properly restore selection and choses an
+ * object that was previously opened in that tree, which in turn
+ * changes the object opened in the editor panel. To make things
+ * worse, this event is only delivered to the tree object on Mac OS X.
+ *
+ * 
+ */
+    if (fwbdebug) qDebug("ObjectTreeView::dragObject()  this=%p visible=%d",
+                         this,visible);
+
+    FWObject *edit_obj = oe->getOpened();
+
+    if (oe->isVisible() && 
+        dragobj.size()==1 &&
+        edit_obj!=NULL &&
+        current_obj->getLibrary()==edit_obj->getLibrary() )
+    {
+        if (fwbdebug) qDebug("ObjectTreeView::dragObject() reset selection");
+        setSelected(otvi,false);
+        resetSelection();
+    }
+
 #if 0
     /*
      * need to reset selection if:
@@ -488,6 +542,7 @@
         qDebug("ObjectTreeView::contentsMousePressEvent");
 
     second_click = false;
+    process_mouse_release_event = true;
 
     if (fwbdebug)
     {
@@ -516,14 +571,38 @@
  * on a single click.
  *
  * uncomment the line that starts timer for mode #1.
+ *
+ *
+ * we use mouseReleaseEvent event to switch object opened in the
+ * editor panel (i.e. we open new object when mouse button is released
+ * rather than when it is pressed). This allows us to start drag
+ * without switching object in the editor. The problem is that
+ * mouseReleaseEvent is received in this widget after the d&d ends
+ * with a drop somewhere else, which triggers call to
+ * contentsMouseReleaseEvent which switches object in the editor. This
+ * is undesired when the editor shows a group and we try to drag and
+ * drop an object into that group. Flag process_mouse_release_event is
+ * used to suppress object switching when contentsMouseReleaseEvent is
+ * called after successfull drop.
+ *
  */
 void ObjectTreeView::contentsMouseReleaseEvent( QMouseEvent *e )
 {
     if (fwbdebug)
-        qDebug("ObjectTreeView::contentsMouseReleaseEvent 1");
+        qDebug("ObjectTreeView::contentsMouseReleaseEvent 1 this=%p  process_mouse_release_event=%d",
+               this,process_mouse_release_event);
 
     QListView::contentsMouseReleaseEvent(e);
 
+
+    if (!process_mouse_release_event)
+    {
+        // just do not switch object in the editor, otherwise
+        // process this event as usual
+        process_mouse_release_event = true;
+        return;
+    }
+
     if (fwbdebug)
         qDebug("ObjectTreeView::contentsMouseReleaseEvent 2 selectedObjects.size()=%d getCurrentObject()=%p current object %s",
                selectedObjects.size(),
diff -uNr fwbuilder-2.1.8/src/gui/ObjectTreeView.h fwbuilder-2.1.9/src/gui/ObjectTreeView.h
--- fwbuilder-2.1.8/src/gui/ObjectTreeView.h	2006-09-15 07:48:21.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ObjectTreeView.h	2007-01-08 04:37:53.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: ObjectTreeView.h,v 1.19 2006/09/15 05:48:21 vkurland Exp $
+  $Id: ObjectTreeView.h,v 1.22 2007/01/08 03:37:53 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -52,6 +52,10 @@
     bool             Lockable;
     bool             Unlockable;
 
+    bool             visible;
+
+    bool             process_mouse_release_event;
+
     std::vector<libfwbuilder::FWObject*>          selectedObjects;
         
  protected:
@@ -92,7 +96,10 @@
     void editCurrentObject();
 
     void clearLastSelected();
-    
+
+    void becomingVisible() { visible=true; }
+    void becomingHidden()  { visible=false; }
+
 /* Under some circumstances, user may select several host or fw
  * objects so that their children objects are selected as well
  * (e.g. when shift-click is used). "Delete objects" or "group
@@ -103,6 +110,8 @@
  * actions.
  */
     std::vector<libfwbuilder::FWObject*> getSimplifiedSelection();
+
+    void ignoreNextMouseReleaseEvent() { process_mouse_release_event = false; }
     
  public slots:
 
diff -uNr fwbuilder-2.1.8/src/gui/pfAdvancedDialog.cpp fwbuilder-2.1.9/src/gui/pfAdvancedDialog.cpp
--- fwbuilder-2.1.8/src/gui/pfAdvancedDialog.cpp	2006-09-29 01:36:29.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/pfAdvancedDialog.cpp	2007-01-06 23:03:25.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: pfAdvancedDialog.cpp,v 1.20 2006/09/28 23:36:29 vkurland Exp $
+  $Id: pfAdvancedDialog.cpp,v 1.21 2007/01/06 22:03:25 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -260,7 +260,8 @@
 
 void pfAdvancedDialog::editProlog()
 {
-    SimpleTextEditor edt( prolog_script->text(),
+    SimpleTextEditor edt(this,
+                         prolog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         prolog_script->setText( edt.text() );
@@ -268,7 +269,8 @@
 
 void pfAdvancedDialog::editEpilog()
 {
-    SimpleTextEditor edt( epilog_script->text(),
+    SimpleTextEditor edt(this,
+                         epilog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         epilog_script->setText( edt.text() );
diff -uNr fwbuilder-2.1.8/src/gui/pixAdvancedDialog.cpp fwbuilder-2.1.9/src/gui/pixAdvancedDialog.cpp
--- fwbuilder-2.1.8/src/gui/pixAdvancedDialog.cpp	2006-10-21 08:35:12.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/pixAdvancedDialog.cpp	2007-01-06 23:03:25.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: pixAdvancedDialog.cpp,v 1.29 2006/10/21 06:35:12 vkurland Exp $
+  $Id: pixAdvancedDialog.cpp,v 1.30 2007/01/06 22:03:25 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -781,7 +781,8 @@
 
 void pixAdvancedDialog::editProlog()
 {
-    SimpleTextEditor edt( pix_prolog_script->text(),
+    SimpleTextEditor edt(this,
+                         pix_prolog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         pix_prolog_script->setText( edt.text() );
@@ -789,7 +790,8 @@
 
 void pixAdvancedDialog::editEpilog()
 {
-    SimpleTextEditor edt( pix_epilog_script->text(),
+    SimpleTextEditor edt(this,
+                         pix_epilog_script->text(),
                           true, tr( "Script Editor" ) );
     if ( edt.exec() == QDialog::Accepted )
         pix_epilog_script->setText( edt.text() );
diff -uNr fwbuilder-2.1.8/src/gui/PrefsDialog.cpp fwbuilder-2.1.9/src/gui/PrefsDialog.cpp
--- fwbuilder-2.1.8/src/gui/PrefsDialog.cpp	2006-10-22 06:39:36.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/PrefsDialog.cpp	2007-02-04 05:20:26.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: PrefsDialog.cpp,v 1.28 2006/10/22 04:39:36 vkurland Exp $
+  $Id: PrefsDialog.cpp,v 1.29 2007/02/04 04:20:26 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -262,11 +262,14 @@
 
                 i->load = !i->load;
 
+#if 0
+// commented out for bug #1620284
                 if (i->load)
                 {
                     mw->loadLibrary( i->path.latin1() );
                     om->loadObjects();
                 }
+#endif
                 break;
             }
         }
@@ -301,8 +304,10 @@
         }
         itm->setPixmap(1, pm);
 
-        mw->loadLibrary( i->path.latin1() );
-        om->loadObjects();
+        // commented out for bug #1620284
+        //
+        //mw->loadLibrary( i->path.latin1() );
+        //om->loadObjects();
     }
 }
 
diff -uNr fwbuilder-2.1.8/src/gui/ruleoptionsdialog_q.ui fwbuilder-2.1.9/src/gui/ruleoptionsdialog_q.ui
--- fwbuilder-2.1.8/src/gui/ruleoptionsdialog_q.ui	2006-09-17 20:58:13.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/ruleoptionsdialog_q.ui	2007-01-07 01:36:45.000000000 +0100
@@ -2169,7 +2169,7 @@
     </connection>
     <connection>
         <sender>ipt_logPrefix</sender>
-        <signal>selectionChanged()</signal>
+        <signal>textChanged(const QString&amp;)</signal>
         <receiver>RuleOptionsDialog_q</receiver>
         <slot>changed()</slot>
     </connection>
diff -uNr fwbuilder-2.1.8/src/gui/RuleSetView.cpp fwbuilder-2.1.9/src/gui/RuleSetView.cpp
--- fwbuilder-2.1.8/src/gui/RuleSetView.cpp	2006-10-29 00:53:50.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/RuleSetView.cpp	2007-01-08 16:24:53.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: RuleSetView.cpp,v 1.155 2006/10/28 22:53:50 vkurland Exp $
+  $Id: RuleSetView.cpp,v 1.157 2007/01/08 15:24:53 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -1816,10 +1816,14 @@
     {
         PolicyRule *rule = PolicyRule::cast( ruleIndex[currentRow()] );
         PolicyRule::Action old_act=rule->getAction();
+        RuleSet *subset = NULL;
+        if (old_act==PolicyRule::Branch)
+            subset = rule->getBranch();
+
         if (act!=old_act)
         {
             if (old_act==PolicyRule::Branch)
-                mw->removePolicyBranchTab(rule);
+                mw->removePolicyBranchTab( subset );
 
             rule->setAction( act );
             if (!changingRules)
@@ -1900,6 +1904,7 @@
     if (fwbdebug) qDebug("Firewall changed: changeActionToRoute"); 
     changeAction( PolicyRule::Route );
 }
+
 void RuleSetView::changeActionToBranch()
 {
     if (!isTreeReadWrite(this,ruleset)) return;
@@ -1909,27 +1914,33 @@
         if (fwbdebug) qDebug("Firewall action: changeActionToBranch"); 
         changeAction( PolicyRule::Branch );
 
-        PolicyRule *rule = PolicyRule::cast( ruleIndex[currentRow()] );
-        FWOptions *ropt = rule->getOptionsObject();
+        addRuleBranch( PolicyRule::cast( ruleIndex[currentRow()] ) );
+    }
+}
 
-        QString branchName = ropt->getStr("branch_name").c_str();
-        if (branchName.isEmpty())
-        {
-            QString bn = QString("rule%1_branch").arg(rule->getPosition());
-            ropt->setStr("branch_name",bn.ascii());
-        }
-        RuleSet *subset = rule->getBranch();
-        if (subset==NULL)
-        {
-            // can change action only for the policy rule, therefore
-            // branch can only be a Policy (i.e. can not be NAT)
-            subset = new Policy();
-            rule->add(subset);
-        }
-        mw->addPolicyBranchTab(rule);
+void RuleSetView::addRuleBranch(PolicyRule *rule)
+{
+    if (fwbdebug) qDebug("RuleSetView::addRuleBranch"); 
+
+    FWOptions *ropt = rule->getOptionsObject();
+    QString branchName = ropt->getStr("branch_name").c_str();
+    if (branchName.isEmpty())
+    {
+        QString bn = QString("rule%1_branch").arg(rule->getPosition());
+        ropt->setStr("branch_name",bn.ascii());
     }
+    RuleSet *subset = rule->getBranch();
+    if (subset==NULL)
+    {
+        // can change action only for the policy rule, therefore
+        // branch can only be a Policy (i.e. can not be NAT)
+        subset = new Policy();
+        rule->add(subset);
+    }
+    mw->addPolicyBranchTab(subset);
 }
 
+
 void RuleSetView::changeDitection(PolicyRule::Direction dir)
 {
     if (!isTreeReadWrite(this,ruleset)) return;
@@ -2674,8 +2685,24 @@
         for (int rn=lastSelectedRule; rn>=firstSelectedRule; --rn)
         {
             if (oe->isVisible() && oe->getOpened()==ruleIndex[rn]) oe->close();
+
+            bool delete_branch_tab = false;
+            PolicyRule *r = PolicyRule::cast( ruleIndex[rn] );
+            RuleSet *subset = NULL;
+            if (r)
+            {
+                if (r->getAction()==PolicyRule::Branch)
+                {
+                    subset = r->getBranch();
+                    delete_branch_tab = true;
+                }
+            }
+
             if ( ruleset->deleteRule(rn) )
             {
+                if (delete_branch_tab)
+                    mw->removePolicyBranchTab( subset );
+
                 int lastN=ruleIndex.size()-1;
                 ruleIndex.erase(rn);
 
@@ -2781,11 +2808,13 @@
         qDebug(QString("RuleSetView::insertRule: r->direction=%1")
                .arg(PolicyRule::cast(r)->getDirectionAsString().c_str()));
 
-    if (Policy::cast(ruleset) || InterfacePolicy::cast(ruleset))
+    PolicyRule *newrule_as_policy_rule = PolicyRule::cast(newrule);
+
+    if (newrule_as_policy_rule)
     {
-        PolicyRule::cast(newrule)->setLogging(supports_logging);
-        PolicyRule::cast(newrule)->setAction(PolicyRule::Deny);
-        PolicyRule::cast(newrule)->setDirection(PolicyRule::Both);
+        newrule_as_policy_rule->setLogging(supports_logging);
+        newrule_as_policy_rule->setAction(PolicyRule::Deny);
+        newrule_as_policy_rule->setDirection(PolicyRule::Both);
     }
 
     if (r!=NULL)  copyRuleContent(newrule,Rule::cast(r));
@@ -2803,6 +2832,10 @@
     for (int i=ruleIndex.size(); i>=pos; --i)
         setRuleNumber(i, Rule::cast(ruleIndex[i]));
 
+    if (newrule_as_policy_rule!=NULL &&
+        newrule_as_policy_rule->getAction()==PolicyRule::Branch )
+        addRuleBranch( newrule_as_policy_rule );
+
     dirtyRows[pos]=1;
 ////    adjustRow(pos);
 
diff -uNr fwbuilder-2.1.8/src/gui/RuleSetView.h fwbuilder-2.1.9/src/gui/RuleSetView.h
--- fwbuilder-2.1.8/src/gui/RuleSetView.h	2006-08-30 08:39:37.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/RuleSetView.h	2007-01-06 22:35:05.000000000 +0100
@@ -202,6 +202,8 @@
     virtual void adjustRow( int row );
     virtual void adjustColumn( int col );
 
+    void addRuleBranch(libfwbuilder::PolicyRule *rule);
+    
     bool isDirection (int col);
     bool isAction    (int col);
     bool isOptions   (int col);
diff -uNr fwbuilder-2.1.8/src/gui/SimpleTextEditor.cpp fwbuilder-2.1.9/src/gui/SimpleTextEditor.cpp
--- fwbuilder-2.1.8/src/gui/SimpleTextEditor.cpp	2004-06-02 08:40:52.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/SimpleTextEditor.cpp	2007-01-07 02:00:30.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: SimpleTextEditor.cpp,v 1.4 2004/06/02 06:40:52 vkurland Exp $
+  $Id: SimpleTextEditor.cpp,v 1.6 2007/01/07 01:00:30 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -40,9 +40,10 @@
 
 using namespace std;
 
-SimpleTextEditor::SimpleTextEditor(const QString &txt,
+SimpleTextEditor::SimpleTextEditor(QWidget *parent,
+                                   const QString &txt,
                                    bool enableLoadFromFile,
-                                   const QString &title)
+                                   const QString &title) : SimpleTextEditor_q(parent)
 {
     if (enableLoadFromFile) inputFromFileButton->show();
     else                    inputFromFileButton->hide();
@@ -67,7 +68,7 @@
     {
         QString filename = QFileDialog::getOpenFileName( st->getWDir(),
                                                          NULL,  this, NULL,
-                                                         tr("Choose file that contains PIX commands") );
+                                                         tr("Choose file") );
         if (filename!="")
         {
            ifstream ifile(filename.latin1());
@@ -80,6 +81,7 @@
                return;
            }
 
+           editor->clear();
            char buf[1024];
            while (ifile.getline(buf,1024))
            {
diff -uNr fwbuilder-2.1.8/src/gui/SimpleTextEditor.h fwbuilder-2.1.9/src/gui/SimpleTextEditor.h
--- fwbuilder-2.1.8/src/gui/SimpleTextEditor.h	2004-06-02 08:40:52.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/SimpleTextEditor.h	2007-01-06 23:03:25.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: SimpleTextEditor.h,v 1.3 2004/06/02 06:40:52 vkurland Exp $
+  $Id: SimpleTextEditor.h,v 1.4 2007/01/06 22:03:25 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -35,7 +35,8 @@
 
  public:
 
-    SimpleTextEditor(const QString &txt,
+    SimpleTextEditor(QWidget *parent,
+                     const QString &txt,
                      bool enableLoadFromFile=true,
                      const QString &title="");
 
diff -uNr fwbuilder-2.1.8/src/gui/simpletexteditor_q.ui fwbuilder-2.1.9/src/gui/simpletexteditor_q.ui
--- fwbuilder-2.1.8/src/gui/simpletexteditor_q.ui	2006-10-24 06:05:58.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/simpletexteditor_q.ui	2007-01-06 22:44:49.000000000 +0100
@@ -18,6 +18,9 @@
     <property name="caption">
         <string>Script Editor</string>
     </property>
+    <property name="focusPolicy">
+        <enum>StrongFocus</enum>
+    </property>
     <grid>
         <property name="name">
             <cstring>unnamed</cstring>
diff -uNr fwbuilder-2.1.8/src/gui/simpletextview_q.ui fwbuilder-2.1.9/src/gui/simpletextview_q.ui
--- fwbuilder-2.1.8/src/gui/simpletextview_q.ui	2006-06-14 07:16:45.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/simpletextview_q.ui	2007-01-06 22:44:49.000000000 +0100
@@ -15,6 +15,9 @@
     <property name="caption">
         <string>Text viewer</string>
     </property>
+    <property name="focusPolicy">
+        <enum>StrongFocus</enum>
+    </property>
     <vbox>
         <property name="name">
             <cstring>unnamed</cstring>
@@ -46,7 +49,6 @@
                     </property>
                     <property name="font">
                         <font>
-                            <pointsize>14</pointsize>
                             <bold>1</bold>
                         </font>
                     </property>
diff -uNr fwbuilder-2.1.8/src/gui/SSHUnx.cpp fwbuilder-2.1.9/src/gui/SSHUnx.cpp
--- fwbuilder-2.1.8/src/gui/SSHUnx.cpp	2006-09-17 07:15:50.000000000 +0200
+++ fwbuilder-2.1.9/src/gui/SSHUnx.cpp	2007-01-30 18:01:50.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@fwbuilder.org
 
-  $Id: SSHUnx.cpp,v 1.18 2006/09/17 05:15:50 vkurland Exp $
+  $Id: SSHUnx.cpp,v 1.19 2007/01/30 17:01:50 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -89,6 +89,9 @@
     {
         if ( stdoutBuffer.findRev(*i,-1)!=-1 )
         {
+            if (fwbdebug)
+                qDebug(QString("SSHUnx::stateMachine: detected an error: '%1'").arg(*i));
+
             emit printStdout_sign( tr("\n*** Fatal error :") );
             emit printStdout_sign( stdoutBuffer+"\n" );
             stdoutBuffer="";
diff -uNr fwbuilder-2.1.8/src/ipt/MangleTableCompiler_ipt.cpp fwbuilder-2.1.9/src/ipt/MangleTableCompiler_ipt.cpp
--- fwbuilder-2.1.8/src/ipt/MangleTableCompiler_ipt.cpp	2006-09-09 07:05:00.000000000 +0200
+++ fwbuilder-2.1.9/src/ipt/MangleTableCompiler_ipt.cpp	2007-01-05 07:47:05.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: MangleTableCompiler_ipt.cpp,v 1.7 2006/09/09 05:05:00 vkurland Exp $
+  $Id: MangleTableCompiler_ipt.cpp,v 1.8 2007/01/05 06:47:05 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -65,13 +65,27 @@
     if (rule->getAction() == PolicyRule::Branch &&
         ruleopt->getBool("ipt_branch_in_mangle"))
     {
-        PolicyRule* r = 
-            PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+        PolicyRule* r;
+
+        // this is a branching rule for mangle table. Need to put it
+        // into PREROUTING and POSTROUTING chains as well because some
+        // targets that work with mangle table can only go into these
+        // chains, yet we do not know what kind of rules will user
+        // place in the branch
+
+        r = PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
         compiler->temp_ruleset->add(r);
         r->duplicate(rule);
         r->setStr("ipt_chain","PREROUTING");
         tmp_queue.push_back(r);
 
+
+        r = PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+        compiler->temp_ruleset->add(r);
+        r->duplicate(rule);
+        r->setStr("ipt_chain","POSTROUTING");
+        tmp_queue.push_back(r);
+
         tmp_queue.push_back(rule);
     }
 
diff -uNr fwbuilder-2.1.8/src/ipt/NATCompiler_ipt.cpp fwbuilder-2.1.9/src/ipt/NATCompiler_ipt.cpp
--- fwbuilder-2.1.8/src/ipt/NATCompiler_ipt.cpp	2006-09-11 02:41:09.000000000 +0200
+++ fwbuilder-2.1.9/src/ipt/NATCompiler_ipt.cpp	2007-01-15 02:21:58.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: NATCompiler_ipt.cpp,v 1.25 2006/09/11 00:41:09 vkurland Exp $
+  $Id: NATCompiler_ipt.cpp,v 1.26 2007/01/15 01:21:58 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -94,8 +94,12 @@
     ostringstream  ostr;
     string name=at->getName();
     string::size_type p1;
-    while ( (p1=name.find(" "))!=string::npos)
-        name=name.replace(p1,1,"_");
+    char *bad_shell_chars = " !#$&*()-+=\\|{}[]?<>,.";
+    for (char *cptr=bad_shell_chars; *cptr; cptr++)
+    {
+        while ( (p1=name.find(*cptr))!=string::npos)
+            name=name.replace(p1,1,"_");
+    }
     ostr << "at_" << name;
     return ostr.str();
 }
diff -uNr fwbuilder-2.1.8/src/ipt/OSConfigurator_linux24.cpp fwbuilder-2.1.9/src/ipt/OSConfigurator_linux24.cpp
--- fwbuilder-2.1.8/src/ipt/OSConfigurator_linux24.cpp	2006-05-17 00:39:59.000000000 +0200
+++ fwbuilder-2.1.9/src/ipt/OSConfigurator_linux24.cpp	2007-01-16 06:26:54.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: OSConfigurator_linux24.cpp,v 1.35 2006/05/16 22:39:59 vkurland Exp $
+  $Id: OSConfigurator_linux24.cpp,v 1.38 2007/01/16 05:26:54 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -425,7 +425,7 @@
     
     output << "check_file() {"                             << endl;
     output << "  test -r \"$2\" || {"                      << endl;
-    output << "    echo \"Can not find file '$2' referenced by AddressTable object '$1'\"" << endl;
+    output << "    echo \"Can not find file $2 referenced by AddressTable object $1\"" << endl;
     output << "    exit 1"                                 << endl;
     output << "  }"                                        << endl;
     output << "}"                                          << endl;
@@ -654,7 +654,7 @@
         p2=command_line.find(" ",p1);
         string at_var= command_line.substr(p1+1,p2-p1-1);  // skip '$'
         string atfile = rule->getStr("address_table_file");
-        ext_command_line << "grep -Ev '^#' " << atfile << " | ";
+        ext_command_line << "grep -Ev '^#|^;|^\\s*$' " << atfile << " | ";
         ext_command_line << "while read L ; do" << endl;
         ext_command_line << "  set $L; " << at_var << "=$1; ";
         ext_command_line << command_line;
diff -uNr fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt.cpp fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt.cpp
--- fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt.cpp	2006-11-10 06:24:48.000000000 +0100
+++ fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt.cpp	2007-01-15 05:37:52.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: PolicyCompiler_ipt.cpp,v 1.56 2006/11/10 05:24:48 vkurland Exp $
+  $Id: PolicyCompiler_ipt.cpp,v 1.64 2007/01/15 04:37:52 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -89,8 +89,12 @@
     ostringstream  ostr;
     string name=at->getName();
     string::size_type p1;
-    while ( (p1=name.find(" "))!=string::npos)
-        name=name.replace(p1,1,"_");
+    char *bad_shell_chars = " !#$&*()-+=\\|{}[]?<>,.";
+    for (char *cptr=bad_shell_chars; *cptr; cptr++)
+    {
+        while ( (p1=name.find(*cptr))!=string::npos)
+            name=name.replace(p1,1,"_");
+    }
     ostr << "at_" << name;
     return ostr.str();
 }
@@ -453,6 +457,88 @@
 }
 #endif
 
+
+/*
+ * This rule processor converts non-terminating targets CLASSIFY and
+ * MARK to terminating targets (equivalent) by splitting the rule and
+ * adding one more rule with target ACCEPT.
+ *
+ * Call this rule processor at the very end of the chain when all
+ * splits are done and target is set via "ipt_target"
+ */
+bool  PolicyCompiler_ipt::splitNonTerminatingTargets::processNext()
+{
+    PolicyRule *rule=getNext(); if (rule==NULL) return false;
+    string tgt = rule->getStr("ipt_target");
+    FWOptions      *ruleopt = rule->getOptionsObject();
+    
+    if (compiler->fw->getOptionsObject()->getBool("classify_mark_terminating") &&
+        !ruleopt->getBool("already_terminating_target") &&
+        (tgt=="CLASSIFY" || tgt=="MARK"))
+    {
+        RuleElementSrc *nsrc;
+        RuleElementDst *ndst;
+        RuleElementSrv *nsrv;
+        RuleElementItf *nitfre;
+        PolicyRule     *r, *r2;
+
+        string this_chain = rule->getStr("ipt_chain");
+        string new_chain  = this_chain;
+
+        nsrc = rule->getSrc();
+        ndst = rule->getDst();
+        nsrv = rule->getSrv();
+        nitfre = rule->getItf();
+
+        if (!nsrc->isAny() ||
+            !ndst->isAny() ||
+            !nsrv->isAny() ||
+            !nitfre->isAny())
+        {
+            new_chain   =PolicyCompiler_ipt::getNewTmpChainName(rule);
+            r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r);
+            r->duplicate(rule);
+            r->setStr("subrule_suffix","ntt");
+            r->setStr("ipt_target",new_chain);
+            tmp_queue.push_back(r);
+        }
+
+        r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+        compiler->temp_ruleset->add(r);
+        r->duplicate(rule);
+        nsrc = r->getSrc();   nsrc->reset();
+        ndst = r->getDst();   ndst->reset();
+        nsrv = r->getSrv();   nsrv->reset();
+        nitfre = r->getItf(); nitfre->reset();
+        r->setInterfaceId("");
+        ruleopt = r->getOptionsObject();
+        ruleopt->setInt("limit_value",-1);
+        ruleopt->setInt("limit_value",-1);
+        ruleopt->setInt("connlimit_value",-1);
+        ruleopt->setInt("hashlimit_value",-1);
+        ruleopt->setBool("stateless",true);
+        r->setLogging(false);
+	r->setStr("ipt_chain",new_chain);
+        r->setStr("upstream_rule_chain",this_chain);
+        tmp_queue.push_back(r);
+
+        r2= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+        compiler->temp_ruleset->add(r2);
+        r2->duplicate(r);
+        r2->setAction(PolicyRule::Accept);
+        r2->setStr("ipt_target","ACCEPT");
+        ruleopt = r2->getOptionsObject();
+        ruleopt->setBool("stateless",true);
+        tmp_queue.push_back(r2);
+
+        return true;
+    }
+
+    tmp_queue.push_back(rule);
+    return true;
+}
+
 // this version just splits rule so that each elementary rule is associated
 // with one interface.
 
@@ -523,6 +609,8 @@
         for (FWObject::iterator i=subset->begin(); i!=subset->end(); i++)
         {
             PolicyRule *r = PolicyRule::cast(*i);
+            if (r->isDisabled()) continue;
+
             RuleElementItf *itfre=r->getItf();   assert(itfre);
 
             if (itfre->isAny())
@@ -626,6 +714,9 @@
  * CLASSIFY only works in mangle table in POSTROUTING chain.
  * the man page does not mention this, but module documentation
  * in p-o-m says so.
+ *
+ * per bug #1618329: "Wrong in-code comment" this comment is incorrect,
+ * CLASSIFY target is valid in POSTROUTING, OUTPUT and FORWARD chains.
  */
 bool PolicyCompiler_ipt::dropMangleTableRules::processNext()
 {
@@ -1353,7 +1444,38 @@
     return true;
 }
 
+bool PolicyCompiler_ipt::setChainForMangle::processNext()
+{
+    PolicyCompiler_ipt *ipt_comp=dynamic_cast<PolicyCompiler_ipt*>(compiler);
+    PolicyRule *rule=getNext(); if (rule==NULL) return false;
+
+    if (ipt_comp->my_table=="mangle" && rule->getStr("ipt_chain")=="")
+    {
+        if (rule->getDirection()==PolicyRule::Inbound)
+            rule->setStr("ipt_chain","PREROUTING");
+
+        if (rule->getDirection()==PolicyRule::Outbound)
+            rule->setStr("ipt_chain","POSTROUTING");
+    }
+
+    tmp_queue.push_back(rule);
+    return true;
+}
 
+/*
+ * couple of special cases for rules with action Tag
+ *
+ * option 'ipt_mark_connections' means we need to generate two rules:
+ * one with target MARK and another with target CONNMARK. We place
+ * these two new rules in a separate chain.
+ *
+ * if global option 'classify_mark_terminating' is also on, we place third rule in
+ * the same chain, this time with action ACCEPT.
+ *
+ * Note that if option 'ipt_mark_connections' is off, we do not process
+ * classify_mark_terminating option here. It will be processed later in 
+ * splitNonTerminatingTargets
+ */
 bool PolicyCompiler_ipt::splitIfTagAndConnmark::processNext()
 {
     PolicyRule *rule=getNext(); if (rule==NULL) return false;
@@ -1365,12 +1487,16 @@
     RuleElementDst      *ndst;
     RuleElementSrv      *nsrv;
     RuleElementInterval *nint;
-    
+    bool                 make_terminating = compiler->fw->getOptionsObject()->getBool("classify_mark_terminating");
+
     if (rule->getAction() == PolicyRule::Tag &&
         ruleopt->getBool("ipt_mark_connections"))
     {
 	PolicyRule *r, *r1;
 
+        if (make_terminating)
+            ruleopt->setBool("already_terminating_target",true);
+
         string this_chain  =rule->getStr("ipt_chain");
 	string new_chain=PolicyCompiler_ipt::getNewChainName(rule,rule_iface);
 
@@ -1382,6 +1508,9 @@
         r->setAction(PolicyRule::Continue);
 	r->setLogging(false);
         ruleopt =r->getOptionsObject();
+        if (make_terminating)
+            ruleopt->setBool("already_terminating_target",true);
+
 	tmp_queue.push_back(r);
 
 	r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
@@ -1400,6 +1529,9 @@
 	ndst=r->getDst();   ndst->reset();
 	nsrv=r->getSrv();   nsrv->reset();
 	if ( (nint=r->getWhen())!=NULL )  nint->reset();
+        if (make_terminating)
+            ruleopt->setBool("already_terminating_target",true);
+
 	tmp_queue.push_back(r);
 
 	r1= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
@@ -1410,8 +1542,22 @@
         r1->setLogging(false);
         ruleopt =r1->getOptionsObject();
         ruleopt->setStr("CONNMARK_arg","--save-mark");
+        if (make_terminating)
+            ruleopt->setBool("already_terminating_target",true);
+
 	tmp_queue.push_back(r1);
 
+        if (make_terminating)
+        {
+            r1= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r1);
+            r1->duplicate(r);
+            r1->setStr("ipt_target","ACCEPT");
+            r1->setAction(PolicyRule::Accept);
+            r1->setLogging(false);
+            tmp_queue.push_back(r1);
+        }
+
         ipt_comp->have_connmark = true;
 
     } else
@@ -1427,23 +1573,31 @@
 
     RuleElementItf *itfre=rule->getItf();   assert(itfre);
 
-    if ( !itfre->isAny() &&
-         rule->getDirection()==PolicyRule::Both )
-//        rule->getAction() != PolicyRule::Classify)
+    if ( !itfre->isAny() && rule->getDirection()==PolicyRule::Both)
     {
 	PolicyRule *r;
 
-	r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
-	compiler->temp_ruleset->add(r);
-	r->duplicate(rule);
-	r->setDirection( PolicyRule::Inbound );
-	tmp_queue.push_back(r);
+        // If this rule has been assigned to chain POSTROUTING,
+        // direction 'inbound' does not make sense for it.
+        if (rule->getStr("ipt_chain") != "POSTROUTING")
+        {
+            r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r);
+            r->duplicate(rule);
+            r->setDirection( PolicyRule::Inbound );
+            tmp_queue.push_back(r);
+        }
 
-	r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
-	compiler->temp_ruleset->add(r);
-	r->duplicate(rule);
-	r->setDirection( PolicyRule::Outbound );
-	tmp_queue.push_back(r);
+        // If this rule has been assigned to chain PREROUTING,
+        // direction 'Outbound' does not make sense for it.
+        if (rule->getStr("ipt_chain") != "PREROUTING")
+        {
+            r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r);
+            r->duplicate(rule);
+            r->setDirection( PolicyRule::Outbound );
+            tmp_queue.push_back(r);
+        }
     } else
 	tmp_queue.push_back(rule);
 
@@ -1703,14 +1857,9 @@
 
 bool PolicyCompiler_ipt::splitIfSrcAny::processNext()
 {
+    PolicyCompiler_ipt *ipt_comp=dynamic_cast<PolicyCompiler_ipt*>(compiler);
     PolicyRule *rule=getNext(); if (rule==NULL) return false;
 
-    if (rule->getAction() == PolicyRule::Classify)
-    {
-	tmp_queue.push_back(rule);
-	return true;
-    }
-
 //    FWOptions *fwopt    = compiler->getCachedFwOpt();
     FWOptions  *ruleopt = rule->getOptionsObject();
 /* commented to fix bug #1112470
@@ -1752,6 +1901,21 @@
         r->setStr("ipt_chain","OUTPUT");
         r->setDirection( PolicyRule::Outbound );
         tmp_queue.push_back(r);
+
+        // if this rule is for mangle table, need to put it into
+        // POSTROUTING chain as well because some targets that
+        // work with mangle table can only go into POSTROUTING chain
+        // such as CLASSIFY
+        if (ipt_comp->my_table=="mangle" && rule->getAction()==PolicyRule::Classify)
+        {
+            r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r);
+            r->duplicate(rule);
+            r->setStr("ipt_chain","POSTROUTING");
+            r->setDirection( PolicyRule::Outbound );
+            tmp_queue.push_back(r);
+        }
+
     }
     tmp_queue.push_back(rule);  // add old rule anyway
 
@@ -1760,14 +1924,9 @@
 
 bool PolicyCompiler_ipt::splitIfDstAny::processNext()
 {
+    PolicyCompiler_ipt *ipt_comp=dynamic_cast<PolicyCompiler_ipt*>(compiler);
     PolicyRule *rule=getNext(); if (rule==NULL) return false;
 
-    if (rule->getAction() == PolicyRule::Classify)
-    {
-	tmp_queue.push_back(rule);
-	return true;
-    }
-
 //    FWOptions *fwopt = compiler->getCachedFwOpt();
     FWOptions  *ruleopt = rule->getOptionsObject();
 /* commented to fix bug #1112470
@@ -1808,6 +1967,21 @@
 	r->setStr("ipt_chain","INPUT");
 	r->setDirection( PolicyRule::Inbound );
 	tmp_queue.push_back(r);
+
+        // if this rule is for mangle table, need to put it into
+        // POSTROUTING chain as well because some targets that
+        // work with mangle table can only go into POSTROUTING chain
+        // such as CLASSIFY
+        if (ipt_comp->my_table=="mangle" && rule->getAction()==PolicyRule::Classify)
+        {
+            r= PolicyRule::cast(compiler->dbcopy->create(PolicyRule::TYPENAME) );
+            compiler->temp_ruleset->add(r);
+            r->duplicate(rule);
+            r->setStr("ipt_chain","PREROUTING");
+            r->setDirection( PolicyRule::Inbound );
+            tmp_queue.push_back(r);
+        }
+
     }
     tmp_queue.push_back(rule); // add old rule in any case
 
@@ -2556,48 +2730,67 @@
 
     rule->setStr("ipt_chain","FORWARD");
 
+    if (ipt_comp->my_table=="mangle")
+    {
+        switch ( rule->getDirection() ) 
+        {
+        case PolicyRule::Inbound:
+            rule->setStr("ipt_chain","PREROUTING");
+            break;
+        case PolicyRule::Outbound:
+            rule->setStr("ipt_chain","POSTROUTING");
+            break;
+        default:
+            rule->setStr("ipt_chain","FORWARD");
+            break;
+        }
+    } else
+    {
+
 //    RuleElementSrc *srcrel=rule->getSrc();
-    Address        *src   =compiler->getFirstSrc(rule);  assert(src);
+      Address        *src   =compiler->getFirstSrc(rule);  assert(src);
 //    RuleElementDst *dstrel=rule->getDst();
-    Address        *dst   =compiler->getFirstDst(rule);  assert(dst);
+      Address        *dst   =compiler->getFirstDst(rule);  assert(dst);
 
-    bool b,m;
+      bool b,m;
 /* 
  * do not check for broadcasts and multicasts in bridging firewall because
  * they should go to FORWARD chain 
  */
-    b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") );
+      b=m= !( compiler->getCachedFwOpt()->getBool("bridging_fw") );
 
-    switch ( rule->getDirection() ) 
-    {
-    case PolicyRule::Inbound:
+      switch ( rule->getDirection() ) 
+      {
+      case PolicyRule::Inbound:
 /* if direction is "Inbound", chain can never be OUTPUT, but could be FORWARD */
-        if (!dst->isAny() && ipt_comp->complexMatch(dst,ipt_comp->fw,b,m))
-            rule->setStr("ipt_chain","INPUT");
+          if (!dst->isAny() && ipt_comp->complexMatch(dst,ipt_comp->fw,b,m))
+              rule->setStr("ipt_chain","INPUT");
 
-        break;
+          break;
 
-    case PolicyRule::Outbound:
+      case PolicyRule::Outbound:
 /* if direction is "Outbound", chain can never be INPUT, but could be FORWARD */
-        if (!src->isAny() && ipt_comp->complexMatch(src,ipt_comp->fw,b,m))
-            rule->setStr("ipt_chain","OUTPUT");
+          if (!src->isAny() && ipt_comp->complexMatch(src,ipt_comp->fw,b,m))
+              rule->setStr("ipt_chain","OUTPUT");
 
-        break;
+          break;
 
-    default:
+      default:
 
 /* direction == Both */
-        if (!dst->isAny() && ipt_comp->complexMatch(dst,ipt_comp->fw,b,m)) 
-        {
-            rule->setStr("ipt_chain","INPUT");
-            break;
-        }
-        if (!src->isAny() && ipt_comp->complexMatch(src,ipt_comp->fw,b,m)) 
-        {
-            rule->setStr("ipt_chain","OUTPUT");
-            break;
-        }
+          if (!dst->isAny() && ipt_comp->complexMatch(dst,ipt_comp->fw,b,m)) 
+          {
+              rule->setStr("ipt_chain","INPUT");
+              break;
+          }
+          if (!src->isAny() && ipt_comp->complexMatch(src,ipt_comp->fw,b,m)) 
+          {
+              rule->setStr("ipt_chain","OUTPUT");
+              break;
+          }
+      }
     }
+
 /*
  * bug #1040599: "unnecessary FORWARD rules".
  * If we haven't decided on INPUT/OUTPUT chain, it stays FORWARD.
@@ -3356,7 +3549,21 @@
             add( new ExpandMultipleAddressesInSRC("expand objects with multiple addresses in SRC" ) );
             add( new ExpandMultipleAddressesInDST("expand objects with multiple addresses in DST" ) );
             add( new ConvertToAtomic("convert to atomic rules"            ) );
-            add( new DetectShadowing("Detect shadowing"                   ) );
+
+/*
+ * This assumes that all rules that go into the mangle table are
+ * non-terminating. This is not necessarily correct because
+ * non-termination is really an attribute of the target. However
+ * targets that we support that go into mangle table (CLASSIFY and
+ * MARK) are indeed non-terminating.
+ */
+
+            
+            if (my_table=="mangle" && !fw->getOptionsObject()->getBool("classify_mark_terminating"))
+                add( new DetectShadowingForNonTerminatingRules("Detect shadowing for non-terminating rules" ) );
+            else
+                add( new DetectShadowing("Detect shadowing"                   ) );
+
             add( new simplePrintProgress(                                 ) );
 
             runRuleProcessors();
@@ -3377,8 +3584,12 @@
 
         add( new Route(           "process route rules"                   ) );
         add( new storeAction(     "store original action of this rule"    ) );
+
+// *** call  setChainIfTagInPrerouting BEFORE splitIfIfaceAndDirectionBoth ! ***
         add( new setChainIfTagInPrerouting("handle Tag in PREROUTING chain") );
         add( new splitIfTagAndConnmark( "handle Tag in combination with CONNMARK"));
+        add( new setChainForMangle(        "set chain for other rules in mangle table") );
+
         add( new Logging1(        "check global logging override option"  ) );
         add( new ItfNegation(     "process negation in Itf"  ) );
 
@@ -3387,6 +3598,8 @@
         add( new decideOnChainForClassify("assign chain if action is Classify") );
 
         add( new InterfaceAndDirection("fill in interface and direction"  ) );
+
+// if an action requires chain POSTROUTING (e.g. Classify), set chain BEFORE calling splitIfIfaceAndDirectionBoth
         add( new splitIfIfaceAndDirectionBoth( "split interface rule with direction 'both'") );
 
         if (check_for_recursive_groups)
@@ -3539,6 +3752,9 @@
         add( new optimize2(        "optimization 2"                        ) );
         add( new accounting(       "Accounting"                            ) );
         add( new prepareForMultiport("prepare for multiport"               ) );
+
+        add( new splitNonTerminatingTargets( "split rules using non-terminating targets" ) );
+
         add( new ConvertToAtomicForAddresses("convert to atomic rules by address elements") );
 
         add( new checkForZeroAddr(   "check for zero addresses"            ) );
@@ -3593,28 +3809,32 @@
 
         str << endl;
 
-        string src=" ";
-        string dst=" ";
+        ostringstream src;
+        ostringstream dst;
         string srv=" ";
         string time=" ";
         string itf=" ";
 
-        if (srcrel->getNeg()) src="!";
-        if (dstrel->getNeg()) dst="!";
-        if (srvrel->getNeg()) srv="!";
-        if (intrel->getNeg()) time="!";
-        if (itfrel->getNeg()) itf="!";
+        if (srcrel->getNeg()) src << "!";
+        if (dstrel->getNeg()) dst << "!";
+        if (srvrel->getNeg()) srv  = "!";
+        if (intrel->getNeg()) time = "!";
+        if (itfrel->getNeg()) itf  = "!";
 
         if (i1!=srcrel->end()) {
             FWObject *o=*i1;
             if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
-            src+=o->getName();
+            src << o->getName();
+            if (Group::cast(o)!=NULL)
+                src << "[" << o->size() << "]";
         }
 
         if (i2!=dstrel->end()) {
             FWObject *o=*i2;
             if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
-            dst+=o->getName();
+            dst << o->getName();
+            if (Group::cast(o)!=NULL)
+                dst << "[" << o->size() << "]";
         }
 
         if (i3!=srvrel->end()) {
@@ -3643,11 +3863,11 @@
         
         str <<  setw(15-w)  << setfill(' ') << " ";
 
-        str <<  setw(18) << setfill(' ') << src.c_str();
-        str <<  setw(18) << setfill(' ') << dst.c_str();
+        str <<  setw(18) << setfill(' ') << src.str();
+        str <<  setw(18) << setfill(' ') << dst.str();
         str <<  setw(12) << setfill(' ') << srv.c_str();
         str <<  setw(10) << setfill(' ') << time.c_str();
-        str <<  setw(8) << setfill(' ') << itf.c_str();
+        str <<  setw(8)  << setfill(' ') << itf.c_str();
 
         if (no==0)
         {
diff -uNr fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt.h fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt.h
--- fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt.h	2006-11-10 06:24:48.000000000 +0100
+++ fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt.h	2007-01-05 07:47:06.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: PolicyCompiler_ipt.h,v 1.25 2006/11/10 05:24:48 vkurland Exp $
+  $Id: PolicyCompiler_ipt.h,v 1.27 2007/01/05 06:47:06 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -301,6 +301,12 @@
         DECLARE_POLICY_RULE_PROCESSOR(setChainIfTagInPrerouting);
 
 	/**
+	 * set chain for mangle table
+	 */
+        DECLARE_POLICY_RULE_PROCESSOR(setChainForMangle);
+
+        
+	/**
 	 * split rule if action is Tag and connmark option is activated
 	 */
         DECLARE_POLICY_RULE_PROCESSOR(splitIfTagAndConnmark);
@@ -557,6 +563,13 @@
          */
         DECLARE_POLICY_RULE_PROCESSOR(decideOnChainForClassify);
 
+        /**
+         * find non-terminating targets (such as MARK and
+         * CLASSIFY). Put such rule in a separate chain and pass
+         * control to it using "-g"
+         */
+        DECLARE_POLICY_RULE_PROCESSOR(splitNonTerminatingTargets);
+
 	/**
 	 * decides what chain this rule should go to if it has not
 	 * been decided in decideOnChainIfFW
diff -uNr fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt_optimizer.cpp fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt_optimizer.cpp
--- fwbuilder-2.1.8/src/ipt/PolicyCompiler_ipt_optimizer.cpp	2006-09-09 07:05:01.000000000 +0200
+++ fwbuilder-2.1.9/src/ipt/PolicyCompiler_ipt_optimizer.cpp	2006-12-28 07:00:23.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: PolicyCompiler_ipt_optimizer.cpp,v 1.9 2006/09/09 05:05:01 vkurland Exp $
+  $Id: PolicyCompiler_ipt_optimizer.cpp,v 1.10 2006/12/28 06:00:23 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -87,16 +87,18 @@
             } else
             {
                RuleElement *re=RuleElement::cast(rule->getFirstByType((*i)->getTypeName()));
+/* 
+ * put "any tcp" service back in srv field if it was originally some
+ * tcp service. This is needed because we may need to produce
+ * --reject-with tcp-reset if the action is reject and we need to
+ * reject with TCP RST.
+ */
+
                if (RuleElementSrv::isA(re) &&
-                   rule->getAction()==PolicyRule::Reject &&
+                   r->getAction()==PolicyRule::Reject &&
                    ipt_comp->isActionOnRejectTCPRST(r))
                {
                    Service  *srv= compiler->getFirstSrv(r);
-/* need to put "any tcp" service back in srv field if it was
- * originally some tcp service. this is needed because we may need to
- * produce --reject-with tcp-reset if the action is reject and we need
- * to reject with TCP RST
- */
                    if (TCPService::isA(srv))
                    {
                        re->clearChildren();
@@ -119,9 +121,12 @@
     }
     r->setStr("ipt_target",new_chain);
     tmp_queue.push_back(r);
+
     FWOptions *ruleopt=rule->getOptionsObject();
     ruleopt->setBool("stateless",true);
     ruleopt->setInt("limit_value",-1);
+    ruleopt->setInt("connlimit_value",-1);
+    ruleopt->setInt("hashlimit_value",-1);
     rule->setStr("ipt_chain",new_chain);
     rule->setBool("force_state_check",false);
     rule->setStr("upstream_rule_chain",this_chain);
diff -uNr fwbuilder-2.1.8/src/ipt/PolicyCompiler_PrintRule.cpp fwbuilder-2.1.9/src/ipt/PolicyCompiler_PrintRule.cpp
--- fwbuilder-2.1.8/src/ipt/PolicyCompiler_PrintRule.cpp	2006-11-10 06:47:26.000000000 +0100
+++ fwbuilder-2.1.9/src/ipt/PolicyCompiler_PrintRule.cpp	2007-01-15 02:21:58.000000000 +0100
@@ -6,7 +6,7 @@
 
   Author:  Vadim Kurland     vadim@vk.crocodile.org
 
-  $Id: PolicyCompiler_PrintRule.cpp,v 1.31 2006/11/10 05:47:26 vkurland Exp $
+  $Id: PolicyCompiler_PrintRule.cpp,v 1.33 2007/01/15 01:21:58 vkurland Exp $
 
   This program is free software which we release under the GNU General Public
   License. You may redistribute and/or modify this program under the terms
@@ -256,7 +256,7 @@
 
     if ( compiler->getCachedFwOpt()->getBool("use_ULOG") &&
          target=="LOG") target="ULOG";
-    
+
     ostr << " -j " << target << " ";
 
     if (target=="REJECT")
diff -uNr fwbuilder-2.1.8/src/res/objects_init.xml fwbuilder-2.1.9/src/res/objects_init.xml
--- fwbuilder-2.1.8/src/res/objects_init.xml	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/src/res/objects_init.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE FWObjectDatabase SYSTEM "fwbuilder.dtd">
-<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="2.1.8" id="root">
+<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="2.1.9" id="root">
   <Library color="#d4f8ff" comment="Standard objects" id="syslib000" name="Standard" ro="True">
     <AnyNetwork comment="Any Network" id="sysid0" name="Any" address="0.0.0.0" netmask="0.0.0.0"/>
     <AnyIPService comment="Any IP Service" id="sysid1" name="Any" protocol_num="0"/>
diff -uNr fwbuilder-2.1.8/src/res/os/freebsd.xml fwbuilder-2.1.9/src/res/os/freebsd.xml
--- fwbuilder-2.1.8/src/res/os/freebsd.xml	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/freebsd.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="freebsd">
       <description>FreeBSD</description>
       <family>freebsd</family>
diff -uNr fwbuilder-2.1.8/src/res/os/fwsm_os.xml fwbuilder-2.1.9/src/res/os/fwsm_os.xml
--- fwbuilder-2.1.8/src/res/os/fwsm_os.xml	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/fwsm_os.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8-1">
+<FWBuilderResources version="2.1.9-1">
     <Target name="pix_os">
       <description>Cisco FWSM</description>
       <compiler>fwb_pix</compiler>
diff -uNr fwbuilder-2.1.8/src/res/os/linksys.xml fwbuilder-2.1.9/src/res/os/linksys.xml
--- fwbuilder-2.1.8/src/res/os/linksys.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/linksys.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="linksys">
       <description>Linksys/Sveasoft</description>
       <family>linux24</family>
diff -uNr fwbuilder-2.1.8/src/res/os/linux24.xml fwbuilder-2.1.9/src/res/os/linux24.xml
--- fwbuilder-2.1.8/src/res/os/linux24.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/linux24.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="linux24">
       <description>Linux 2.4/2.6</description>
       <family>linux24</family>
diff -uNr fwbuilder-2.1.8/src/res/os/macosx.xml fwbuilder-2.1.9/src/res/os/macosx.xml
--- fwbuilder-2.1.8/src/res/os/macosx.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/macosx.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="macosx">
       <description>Mac OS X</description>
       <family>macosx</family>
diff -uNr fwbuilder-2.1.8/src/res/os/openbsd.xml fwbuilder-2.1.9/src/res/os/openbsd.xml
--- fwbuilder-2.1.8/src/res/os/openbsd.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/openbsd.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="openbsd">
       <description>OpenBSD</description>
       <family>openbsd</family>
diff -uNr fwbuilder-2.1.8/src/res/os/pix_os.xml fwbuilder-2.1.9/src/res/os/pix_os.xml
--- fwbuilder-2.1.8/src/res/os/pix_os.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/pix_os.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8-1">
+<FWBuilderResources version="2.1.9-1">
     <Target name="pix_os">
       <description>Cisco PIX</description>
       <compiler>fwb_pix</compiler>
diff -uNr fwbuilder-2.1.8/src/res/os/solaris.xml fwbuilder-2.1.9/src/res/os/solaris.xml
--- fwbuilder-2.1.8/src/res/os/solaris.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/solaris.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="solaris">
       <description>Solaris</description>
       <family>solaris</family>
diff -uNr fwbuilder-2.1.8/src/res/os/unknown_os.xml fwbuilder-2.1.9/src/res/os/unknown_os.xml
--- fwbuilder-2.1.8/src/res/os/unknown_os.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/os/unknown_os.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?> <!-- -*- mode: xml; -*- -->
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="unknown_os">
       <description>Unknown</description>
       <family>unknown</family>
diff -uNr fwbuilder-2.1.8/src/res/platform/fwsm.xml fwbuilder-2.1.9/src/res/platform/fwsm.xml
--- fwbuilder-2.1.8/src/res/platform/fwsm.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/fwsm.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8-1">
+<FWBuilderResources version="2.1.9-1">
     <Target name="FWSM">
       <description>FWSM</description>
       <compiler>fwb_pix</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/ipfw.xml fwbuilder-2.1.9/src/res/platform/ipfw.xml
--- fwbuilder-2.1.8/src/res/platform/ipfw.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/ipfw.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="ipfw">
       <description>ipfw</description>
       <compiler>fwb_ipfw</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/ipf.xml fwbuilder-2.1.9/src/res/platform/ipf.xml
--- fwbuilder-2.1.8/src/res/platform/ipf.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/ipf.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="ipf">
       <description>ipfilter</description>
       <compiler>fwb_ipf</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/iptables.xml fwbuilder-2.1.9/src/res/platform/iptables.xml
--- fwbuilder-2.1.8/src/res/platform/iptables.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/iptables.xml	2007-02-11 04:39:20.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="iptables">
       <description>iptables</description>
       <compiler>fwb_ipt</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/pf.xml fwbuilder-2.1.9/src/res/platform/pf.xml
--- fwbuilder-2.1.8/src/res/platform/pf.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/pf.xml	2007-02-11 04:39:20.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="pf">
       <description>PF</description>
       <compiler>fwb_pf</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/pix.xml fwbuilder-2.1.9/src/res/platform/pix.xml
--- fwbuilder-2.1.8/src/res/platform/pix.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/pix.xml	2007-02-11 04:39:20.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8-1">
+<FWBuilderResources version="2.1.9-1">
     <Target name="pix">
       <description>PIX</description>
       <compiler>fwb_pix</compiler>
diff -uNr fwbuilder-2.1.8/src/res/platform/unknown.xml fwbuilder-2.1.9/src/res/platform/unknown.xml
--- fwbuilder-2.1.8/src/res/platform/unknown.xml	2006-12-03 17:44:34.000000000 +0100
+++ fwbuilder-2.1.9/src/res/platform/unknown.xml	2007-02-11 04:39:20.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
     <Target name="unknown">
       <description>Unknown</description>
       <compiler></compiler>
diff -uNr fwbuilder-2.1.8/src/res/resources.xml fwbuilder-2.1.9/src/res/resources.xml
--- fwbuilder-2.1.8/src/res/resources.xml	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/src/res/resources.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<FWBuilderResources version="2.1.8">
+<FWBuilderResources version="2.1.9">
   <Paths>
     <Icndir>@PACKAGE_PIXMAPS_DIR@</Icndir>
   </Paths>
diff -uNr fwbuilder-2.1.8/src/res/templates.xml fwbuilder-2.1.9/src/res/templates.xml
--- fwbuilder-2.1.8/src/res/templates.xml	2006-12-03 17:44:33.000000000 +0100
+++ fwbuilder-2.1.9/src/res/templates.xml	2007-02-11 04:39:19.000000000 +0100
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE FWObjectDatabase SYSTEM "fwbuilder.dtd">
-<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="2.1.8" lastModified="1146716506" id="root">
+<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="2.1.9" lastModified="1146716506" id="root">
   <Library color="#ffb4b4" comment="Template objects that can be used to generate typical firewall configurations" id="syslib100" name="Firewall Templates" ro="True">
     <ObjectGroup id="id4070BB9B" name="Objects">
       <ObjectGroup id="id4070BB9B_og_ats_1" name="Address Tables"/>
diff -uNr fwbuilder-2.1.8/VERSION fwbuilder-2.1.9/VERSION
--- fwbuilder-2.1.8/VERSION	2006-12-03 17:42:24.000000000 +0100
+++ fwbuilder-2.1.9/VERSION	2007-02-10 23:49:08.000000000 +0100
@@ -1,10 +1,10 @@
 #-*- mode: shell-script; tab-width: 4; -*-
-# $Id: VERSION,v 1.36 2006/12/03 16:42:24 vkurland Exp $
+# $Id: VERSION,v 1.38 2007/02/10 22:49:08 vkurland Exp $
 
 
 FWB_MAJOR_VERSION=2
 FWB_MINOR_VERSION=1
-FWB_MICRO_VERSION=8
+FWB_MICRO_VERSION=9
 VERSION=$FWB_MAJOR_VERSION.$FWB_MINOR_VERSION.$FWB_MICRO_VERSION
 
 #
@@ -21,7 +21,7 @@
 
 BETA="no"
 
-REQUIRED_LIBFWBUILDER_VERSION="2.1.8"
+REQUIRED_LIBFWBUILDER_VERSION="2.1.9"
 
 # current (or major) version number of the library so file
 #
diff -uNr fwbuilder-2.1.8/VERSION.h fwbuilder-2.1.9/VERSION.h
--- fwbuilder-2.1.8/VERSION.h	2006-12-03 17:44:28.000000000 +0100
+++ fwbuilder-2.1.9/VERSION.h	2007-02-11 04:39:14.000000000 +0100
@@ -1,2 +1,2 @@
-#define VERSION      "2.1.8"
+#define VERSION      "2.1.9"
 #define RELEASE_NUM  "1"
