Index: /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.py
===================================================================
--- /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.py	(revision 372)
+++ /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.py	(revision 373)
@@ -35,24 +35,45 @@
             yield item
 
-        for brain in self.catalog(**self.query):
+        exported = []
+
+        results = list(self.catalog(**self.query))
+        results.sort(key=lambda x: x.getPath())
+        for brain in results:
+            # discussion items are get catalogued too
+            # we need to skip them
+            if brain.Type == 'Discussion Item':
+                continue
+
             path = brain.getPath()
-            # path == '/plone/folder'
-            container_path = path[:path.rfind('/')]
-            # container_path == '/plone'
+
+            # folderish objects are tried to export twice:
+            # when their contained items are exported and when they are
+            # returned in catalog search results
+            if path in exported:
+                continue
+            exported.append(path)
+
+            container_path = path.rsplit('/', 1)[0]
             contained = self.getContained(container_path)
-            if contained:
+            if contained and container_path not in exported:
+                exported.append(container_path)
                 yield {
-                    '_path': '/'.join(path.split('/')[2:-1]),
-                    '_entries': contained,
+                    self.pathkey: '/'.join(path.split('/')[2:-1]),
+                    self.entrieskey: contained,
                 }
             item = {
-                '_path': '/'.join(path.split('/')[2:]),
+                self.pathkey: '/'.join(path.split('/')[2:]),
             }
+            if brain.is_folderish:
+                contained = self.getContained(path)
+                if contained:
+                    item[self.entrieskey] = contained
+
             yield item
 
     def getContained(self, path):
-        """ path is '/plone/folder'
+        """ Return list of (object_id, portal_type) for objects that are returned by catalog
+            and contained in folder with given 'path'.
         """
-        # check if this is right
         results = []
         raw_results = self.catalog(path=path, **self.query)
Index: /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.txt
===================================================================
--- /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.txt	(revision 372)
+++ /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/catalogsource.txt	(revision 373)
@@ -7,10 +7,10 @@
 Catalog source section has next options:
   - ``path-key' (default ``_path``) - key where object path is stored
-  - ``entries-key`` (default ``_entries``) - key data for manifest section
+  - ``entries-key`` (default ``_entries``) - key where data for manifest section
      is stored (tuple of contained items)
 
 All other options are assumed to be catalog query parameters, option name
 corresponds to index and its value is value for search or string representation
-of record object. Record object is a dictionary, which items are separeted by 
+of record object. Record object is a dictionary, which items are separeted by
 ``;`` and key is separeted from value with ``=``.
 
@@ -38,5 +38,5 @@
 ... [catalogsource]
 ... blueprint = quintagroup.transmogrifier.catalogsource
-... modified = query = 2008/11/02 12:00:00 GMT+0; range = min
+... modified = query = 2008-11-02T12:00:00Z; range = min
 ... 
 ... [printer]
@@ -45,7 +45,7 @@
 >>> registerConfig(u'quintagroup.transmogrifier.tests.catalogsource',
 ...                catalogsource)
->>> transmogrifier(u'quintagroup.transmogrifier.tests.catalogsource')
-{'_entries': (('folder1', 'Folder'),), '_path': ''}
-{'_path': 'folder1'}
+>>> transmogrifier(u'quintagroup.transmogrifier.tests.catalogsource') #doctest: +REPORT_NDIFF
+{'_entries': (('document4', 'Document'), ('folder1', 'Folder')), '_path': ''}
+{'_path': 'document4'}
 {'_entries': (('document2', 'Document'),), '_path': 'folder1'}
 {'_path': 'folder1/document2'}
Index: /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/patches.py
===================================================================
--- /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/patches.py	(revision 372)
+++ /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/patches.py	(revision 373)
@@ -12,5 +12,4 @@
     """
     mod_time = time.time()
-
     if subdir is not None:
         elements = subdir.split('/')
@@ -23,4 +22,5 @@
                 info = TarInfo(dirname)
                 info.size = 0
+                info.mode = 509
                 info.mtime = mod_time
                 info.type = DIRTYPE
@@ -33,4 +33,5 @@
     info = TarInfo( filename )
     info.size = len( text )
+    info.mode = 436
     info.mtime = mod_time
     self._archive.addfile( info, stream )
Index: /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/tests.py
===================================================================
--- /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/tests.py	(revision 372)
+++ /quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/tests.py	(revision 373)
@@ -16,6 +16,4 @@
 import quintagroup.transmogrifier
 from quintagroup.transmogrifier.xslt import stylesheet_registry
-
-# Doctest support
 
 class DataPrinter(object):
@@ -809,4 +807,8 @@
             return self['portal_type']
 
+        @property
+        def is_folderish(self):
+            return self['portal_type'] == 'Folder' and True or False
+
     class MockPortal(dict):
         #implements(IFolderish)
@@ -816,10 +818,10 @@
             res = []
             for obj in self.content:
-                matched = False
+                matched = True
                 for index, query in kw.items():
                     if index not in obj:
-                        continue
-                    matched = True
-                    if index == 'modified':
+                        matched = False
+                        break
+                    if matched and index == 'modified':
                         if isinstance(query, dict):
                             value = query['query']
@@ -853,14 +855,15 @@
     portal = MockPortal()
     doc1 = MockContent(path='/plone/document1', portal_type='Document',
-        modified='2008/11/01 12:00:00 GMT+0')
+        modified='2008-11-01T12:00:00Z')
     folder1 = MockContent(path='/plone/folder1', portal_type='Folder',
-        modified='2008/11/02 12:00:00 GMT+0')
+        modified='2008-11-04T12:00:00Z')
     doc2 = MockContent(path='/plone/folder1/document2', portal_type='Document',
-        modified='2008/11/03 12:00:00 GMT+0')
+        modified='2008-11-02T12:00:00Z')
     doc3 = MockContent(path='/plone/folder1/document3', portal_type='Document',
-        modified='2008/11/01 12:00:00 GMT+0')
-    portal.content = (doc1, folder1, doc2, doc3)
-    #portal['document4'] = MockContent(path='/plone/document4', portal_type='Document',
-        #modified='2008/11/04 12:00:00 GMT+0')
+        modified='2008-11-01T12:00:00Z')
+    doc4 = MockContent(path='/plone/document4', portal_type='Document',
+        modified='2008-11-03T12:00:00Z')
+    # items are sorted on their modification date
+    portal.content = (doc1, doc3, doc2, doc4, folder1)
 
     test.globs['plone'] = portal
