Index: /packaging/Makefile.packages
===================================================================
--- /packaging/Makefile.packages	(revision 724)
+++ /packaging/Makefile.packages	(revision 725)
@@ -47,5 +47,7 @@
 	$(QT_BUILD)/CHANGES.OS2
 
+#
 # Runtime archive
+#
 
 pkg.lib.runtime.PATH   		= $(WPI_ROOT)/pkg.lib.runtime
@@ -85,8 +87,15 @@
 wpi.lib.PATH 		= $(OUT_ROOT)/qt-lib-$(QT_VER_FULL).wpi
 wpi.lib.SCRIPT      = $(WPI_ROOT)/lib.wis
-wpi.lib.PACKAGES 	= pkg.lib.runtime=1 pkg.lib.instutils=2 pkg.lib.plugins=3 \
-                      pkg.lib.translations=4 pkg.lib.systray=5 pkg.readme=6
-
+wpi.lib.PACKAGES 	= \
+	pkg.lib.runtime=1 \
+	pkg.lib.instutils=2 \
+	pkg.lib.plugins=3 \
+	pkg.lib.translations=4 \
+	pkg.lib.systray=5 \
+	pkg.readme=6
+
+#
 # Development archive
+#
 
 # @todo QtDsgn4.dll and QtDsgC4.dll must be taken from $(QT_INSTALL)
@@ -118,8 +127,13 @@
 wpi.dev.PATH 		= $(OUT_ROOT)/qt-dev-$(QT_VER_FULL).wpi
 wpi.dev.SCRIPT      = $(WPI_ROOT)/dev.wis
-wpi.dev.PACKAGES 	= pkg.dev.libraries=1 pkg.dev.runtime=2 \
-                      pkg.dev.translations=3 pkg.readme=4
-
+wpi.dev.PACKAGES 	= \
+	pkg.dev.libraries=1 \
+	pkg.dev.runtime=2 \
+    pkg.dev.translations=3 \
+	pkg.readme=4
+
+#
 # Examples archive
+#
 
 pkg.examples.demos.PATH		= $(WPI_ROOT)/pkg.examples.demos
@@ -136,13 +150,17 @@
 
 # @todo add examples.example-plugins
-# @todo install qtdemo in bin/ when its' ready
+# @todo install qtdemo in bin/ when it's ready
 
 wpi.examples.PATH 		= $(OUT_ROOT)/qt-examples-$(QT_VER_FULL).wpi
 wpi.examples.SCRIPT		= $(WPI_ROOT)/examples.wis
-wpi.examples.PACKAGES 	= pkg.examples.demos=1 pkg.examples.demo-plugins=2 \
-						  pkg.examples.examples=3 \
-						  pkg.readme=4
-
+wpi.examples.PACKAGES 	= \
+	pkg.examples.demos=1 \
+	pkg.examples.demo-plugins=2 \
+	pkg.examples.examples=3 \
+	pkg.readme=4
+
+#
 # Summary
+#
 
 WPIS = wpi.lib wpi.dev wpi.examples
@@ -162,5 +180,5 @@
 _DIRS_ += $(1)
 $$(eval $$(call EnsureDir,$(dir $(1:%/=%))))
-$$(shell if not exist $(subst /,\,$(1:%/=%)) mkdir $(subst /,\,$(1:%/=%)) >nul 2>&1)
+$$(shell if not exist "$(subst /,\,$(1:%/=%))" mkdir "$(subst /,\,$(1:%/=%))" >nul 2>&1)
 endif
 endif
@@ -169,5 +187,5 @@
 
 # Generate rules to copy one file.
-# @param $(1)	Stem whose file is to copy.
+# @param $(1)	Stem which file is to copy.
 # @param $(2)	File name in format src[->tgt].
 define GenFileCopyRule
@@ -208,4 +226,6 @@
 $$(foreach file,$$($(1).SOURCES),$$(eval $$(call GenFileCopyRule,$(1),$$(file))))
 $(1): $$($(1).TARGETS)
+clean-$(1):
+	if exist "$($(1).PATH)" deltree.cmd "$(subst /,\,$($(1).PATH))" /Y /S
 endif
 endef
@@ -226,7 +246,11 @@
 $(eval $(1).PACKAGES :=)
 $(foreach pkg,$($(1)._PACKAGES),$(eval $(call GenWpiRuleHelper,$(1),$(pkg))))
-$(1): $($(1).PACKAGES) $($(1).SCRIPT)
+# generate WPI target (depends on clean to make sure the removed files are not packed)
+$(1): clean-$(1) $($(1).PACKAGES) $($(1).SCRIPT)
 	-del $(subst /,\,$($(1).PATH))
 	$(WIC) $($(1).PATH) -a $($(1)._PACKAGES_CMD) -s $($(1).SCRIPT)
+# clean WPI target
+clean-$(1): $(foreach pkg,$($(1).PACKAGES),clean-$(pkg))
+# helpers
 $(foreach pkg,$($(1).PACKAGES),$(eval $(pkg).TARGETS :=))
 $(foreach pkg,$($(1).PACKAGES),$(eval $(call GenPkgRule,$(pkg))))
Index: /packaging/deltree.cmd
===================================================================
--- /packaging/deltree.cmd	(revision 725)
+++ /packaging/deltree.cmd	(revision 725)
@@ -0,0 +1,128 @@
+/* REXX tipa */
+
+signal on halt
+
+if (RxFuncQuery('SysLoadFuncs')) then do
+  call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
+  call SysLoadFuncs
+end
+
+parse arg args
+
+if( args == '' ) then do
+    say
+    say 'DELTREE v0.2 (c) ruki'
+    say 'Deltree deletes ALL subdirs and files in a directory.'
+    say
+    say 'Usage: deltree <directory> [mask] [/Y] [/S]'
+    say
+    say 'If a mask is specified only files (and no directories)'
+    say 'that match it will be deleted. /Y suppresses the query,'
+    say '/S suppresses the output of filenames being deleted.'
+    say
+    exit -2
+end   
+
+dirname = ''
+mask = ''
+noquery = 0
+G.bequiet = 0
+
+args = normalize_quotes( args )
+argn = 0
+do while( args \= '' )
+    parse var args ar args
+    ar = denormalize_quotes( ar )
+    if( left( ar, 1 ) == '/' ) then do
+        parse upper var ar '/'ar
+        select
+            when ar == 'Y' then noquery = 1
+            when ar == 'S' then G.bequiet = 1
+            otherwise nop
+        end
+        iterate
+    end
+    argn = argn + 1
+    select
+        when argn == 1 then dirname = ar
+        when argn == 2 then mask = ar
+        otherwise nop
+    end
+end
+
+curdir = directory()
+dir = directory( dirname )
+if( dir == '' ) then do
+    if( \G.bequiet ) then 
+        say '0D0A'x||'Directory "'dirname'" does not exist.'||'0D0A'x
+    exit 0
+end
+dirname = dir
+call directory curdir
+
+if( \noquery ) then do
+    qstr = '0D0A'x||'Sure to delete'
+    if( mask == '' ) then qstr = qstr' the directory "'dirname'" including ALL files and subdirs?'
+    else qstr = qstr' ALL files matching "'mask'" recursively in the directory "'dirname'"?'
+    if( query( qstr' [Y/N]', 'YN') \= 'Y' ) then exit 0
+end
+
+G.cdir = 0
+G.cfile = 0
+
+if( \G.bequiet ) then say '0D0A'x||'Deleting:'||'0D0A'x
+call deldir dirname, mask
+if( \G.bequiet ) then say '0D0A'x||G.cdir' directories, 'G.cfile' files have been deleted.'||'0D0A'x
+exit 0
+
+deldir: procedure expose G.
+    parse arg dir, mask
+    call SysFileTree dir'\*', 'dirs.', 'DO'
+    call SysFileTree dir'\'mask, 'files.', 'FO'
+    do i = 1 to files.0
+        if( \G.bequiet ) then say files.i
+        rc = SysFileDelete( files.i )
+        if( rc \= 0 ) then call error rc, files.i
+        G.cfile = G.cfile + 1
+    end
+    do i = 1 to dirs.0
+        call deldir dirs.i, mask
+    end
+    if( mask == '' ) then do
+        if( \G.bequiet ) then say '['dir']'
+        rc = SysRmDir( dir )
+        if( rc \= 0 ) then call error rc, dir
+        G.cdir = G.cdir + 1
+    end
+    return
+
+error: procedure
+    parse arg rc, file
+    say '0D0A'x||'Error 'rc' deleting "'file'". Aborted.'||'0D0A'x
+    exit rc
+
+query: procedure
+    parse arg str, keys
+    call charout, str
+    do until( verify( ch, keys )==0 )
+        parse upper value SysGetKey( 'NOECHO' ) with ch
+    end
+    say ch
+    return ch
+
+/* replaces spaces within quotes with 0x00 and removes them */
+normalize_quotes: procedure 
+    parse arg str
+    rstr = ''
+    do while( str \= '' )
+        parse var str head'"'qstr'"'str
+        rstr = rstr||head||translate( qstr, '00'x, '20'x )
+    end
+    return rstr
+
+denormalize_quotes: procedure
+    return translate( arg(1), '20'x, '00'x )
+
+halt:
+    say '0D0A0D0A'x||'Aborted.'
+    exit -1
