Index: quintagroup.transmogrify.simpleblog2quills/trunk/README.txt
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/README.txt	(revision 1487)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/README.txt	(revision 1490)
@@ -1,3 +1,3 @@
-quintagroup.transmogrifier.simpleblog2quills
+quintagroup.transmogrify.simpleblog2quills
 ============================================
 
@@ -26,5 +26,5 @@
     problem with absolute links, because site URL isn't known. To make it possible
     to fix absolute links please edit export configuration file 'export.cfg',
-    which is located in 'quintagroup/transmogrifier/simpleblog2quills' folder.
+    which is located in 'quintagroup.transmogrify.simpleblog2quills' folder.
     Find in that file line that starts with "site-urls = " and change values
     that come after it to your site URL.
@@ -34,5 +34,5 @@
     Quills_ or QuillsEnabled_ plone product is required. When migrating blog to 
     QuillsEnabled please edit import configuration file 'import.cfg' located in
-    'quintagroup/transmogrifier/simpleblog2quills' folder (comments in that file 
+    'quintagroup.transmogrify.simpleblog2quills' folder (comments in that file 
     will guide you through necessary modifications) and install this product in
     QuickInstaller (this will enable 'Large Folder' content type and change 
@@ -46,5 +46,5 @@
     Run next command:
 
-    bin/instance test -s quintagroup.transmogrifier.simpleblog2quills \
+    bin/instance test -s quintagroup.transmogrify.simpleblog2quills \
         -m test_import
 
Index: quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt	(revision 1487)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt	(revision 1490)
@@ -1,7 +1,7 @@
-Changelog for quintagroup.transmogrifier.simpleblog2quills
+Changelog for quintagroup.transmogrify.simpleblog2quills
 
     (name of developer listed in brackets)
 
-quintagroup.transmogrifier.simpleblog2quills - 0.1 Unreleased
+quintagroup.transmogrify.simpleblog2quills - 0.1 Unreleased
 
     - Initial package structure.
Index: quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt	(revision 1487)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt	(revision 1490)
@@ -1,18 +1,18 @@
-quintagroup.transmogrifier.simpleblog2quills Installation
+quintagroup.transmogrify.simpleblog2quills Installation
 ==========================
 
-To install quintagroup.transmogrifier.simpleblog2quills into the global Python environment (or a workingenv),
+To install quintagroup.transmogrify.simpleblog2quills into the global Python environment (or a workingenv),
 using a traditional Zope 2 instance, you can do this:
 
  * When you're reading this you have probably already run 
-   ``easy_install quintagroup.transmogrifier.simpleblog2quills``. Find out how to install setuptools
+   ``easy_install quintagroup.transmogrify.simpleblog2quills``. Find out how to install setuptools
    (and EasyInstall) here:
    http://peak.telecommunity.com/DevCenter/EasyInstall
 
- * Create a file called ``quintagroup.transmogrifier.simpleblog2quills-configure.zcml`` in the
+ * Create a file called ``quintagroup.transmogrify.simpleblog2quills-configure.zcml`` in the
    ``/path/to/instance/etc/package-includes`` directory.  The file
    should only contain this::
 
-       <include package="quintagroup.transmogrifier.simpleblog2quills" />
+       <include package="quintagroup.transmogrify.simpleblog2quills" />
 
 
@@ -20,5 +20,5 @@
 recipe to manage your project, you can do this:
 
- * Add ``quintagroup.transmogrifier.simpleblog2quills`` to the list of eggs to install, e.g.:
+ * Add ``quintagroup.transmogrify.simpleblog2quills`` to the list of eggs to install, e.g.:
  
     [buildout]
@@ -26,5 +26,5 @@
     eggs =
         ...
-        quintagroup.transmogrifier.simpleblog2quills
+        quintagroup.transmogrify.simpleblog2quills
         
   * Tell the plone.recipe.zope2instance recipe to install a ZCML slug:
@@ -34,5 +34,5 @@
     ...
     zcml =
-        quintagroup.transmogrifier.simpleblog2quills
+        quintagroup.transmogrify.simpleblog2quills
         
   * Re-run buildout, e.g. with:
Index: quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt	(revision 1487)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt	(revision 1490)
@@ -1,3 +1,3 @@
-  quintagroup.transmogrifier.simpleblog2quills is copyright Quintagroup
+  quintagroup.transmogrify.simpleblog2quills is copyright Quintagroup
 
   This program is free software; you can redistribute it and/or modify
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py	(revision 1490)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py	(revision 1490)
@@ -0,0 +1,21 @@
+# register our extension profile if we have GenericSetup (Plone 2.5 or later)
+try:
+    # if we have GenericSetup product we don't need to register steps in python
+    import os
+    from Products.GenericSetup import EXTENSION
+    from Products.GenericSetup import profile_registry
+    from Products.CMFPlone.interfaces import IPloneSiteRoot
+
+    profile_path = os.path.join(os.path.split(__file__)[0], 'profiles/default')
+    profile_registry.registerProfile(
+        name="default",
+        title="quintagroup.transmogrify.simpleblog2quills (enables Large Plone Folder)",
+        description="Extension profile for applying settings needed to migrate blog.",
+        path=profile_path,
+        product="quintagroup.transmogrify.simpleblog2quills", # this is required
+        profile_type=EXTENSION,
+        for_=IPloneSiteRoot
+    )
+
+except ImportError:
+    pass
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py	(revision 1490)
@@ -0,0 +1,80 @@
+from zope.interface import classProvides, implements
+from zope import event
+
+from collective.transmogrifier.interfaces import ISectionBlueprint
+from collective.transmogrifier.interfaces import ISection
+from collective.transmogrifier.utils import defaultMatcher
+
+from Products.CMFCore import utils
+from Products.CMFCore.WorkflowCore import WorkflowException
+
+try:
+    from zope.interface import alsoProvides
+    from quills.core.interfaces.enabled import IWeblogEnhanced, IPossibleWeblog
+    from Products.QuillsEnabled.activation import WeblogActivationEvent
+except ImportError:
+    # this try: ... except: ... clause is needed for this package to work on 
+    # plone 2.1, because zcml:condition attribute in zcml doesn't work
+    pass
+
+from quintagroup.transmogrify.simpleblog2quills.adapters import IMAGE_FOLDER
+
+class BlogActivatorSection(object):
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.transmogrifier = transmogrifier
+        self.context = transmogrifier.context
+        self.wftool = utils.getToolByName(self.context, 'portal_workflow')
+
+        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+        self.flagkey = options.get('flag-key', '_old_type').strip()
+        self.previous = previous
+
+    def __iter__(self):
+        for item in self.previous:
+            pathkey = self.pathkey(*item.keys())[0]
+
+            if not pathkey:
+                yield item; continue
+
+            type_ = item.get(self.flagkey, None)
+            newtype = item.get('_type', None)
+            if type_ != 'Blog' and newtype != 'Large Plone Folder':
+                yield item; continue
+
+            path = item[pathkey]
+            if type_ is None and newtype == 'Large Plone Folder':
+                parts = path.rsplit('/', 1)
+                if len(parts) == 2:
+                    parent, id_ = parts
+                else:
+                    yield item; continue
+                if id_ != IMAGE_FOLDER:
+                    yield item; continue
+
+            obj = self.context.unrestrictedTraverse(path, None)
+            if obj is None:         # path doesn't exist
+                yield item; continue
+
+            if type_ == 'Blog' and newtype == 'Large Plone Folder':
+                # mark as blog
+                if not IWeblogEnhanced.providedBy(obj) and \
+                    IPossibleWeblog.providedBy(obj):
+                    alsoProvides(obj, IWeblogEnhanced)
+                    event.notify(WeblogActivationEvent(obj))
+            elif type_ is None and newtype == 'Large Plone Folder':
+                # pulish 'images' subfolder
+                parent = self.context.unrestrictedTraverse(parent, None)
+                if IWeblogEnhanced.providedBy(parent) :
+                    try:
+                        self.wftool.doActionFor(obj, 'publish')
+                    except WorkflowException:
+                        pass
+
+            yield item
+
+        # reindex provided interfaces
+        catalog = utils.getToolByName(self.context, 'portal_catalog')
+        catalog.reindexIndex('object_provides', None)
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py	(revision 1490)
@@ -0,0 +1,377 @@
+import re
+from xml.dom import minidom
+from types import ListType
+from types import TupleType
+
+from zope.interface import implements, classProvides
+from zope.app.annotation.interfaces import IAnnotations
+
+from Products.CMFPlone.Portal import PloneSite
+from Products.CMFCore import utils
+
+from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
+from collective.transmogrifier.utils import defaultMatcher
+
+from quintagroup.transmogrifier.interfaces import IExportDataCorrector, IImportDataCorrector
+from quintagroup.transmogrifier.adapters.exporting import ReferenceExporter
+from quintagroup.transmogrifier.manifest import ManifestExporterSection
+from quintagroup.transmogrifier.logger import VALIDATIONKEY
+
+from quintagroup.transmogrify.simpleblog2quills.interfaces import IExportItemManipulator, IBlog
+
+# URL of the site, where blog is located (this is needed to fix links in entries)
+SITE_URLS = []
+IMAGE_FOLDER = 'images'
+IMAGE_FOLDER_TYPE = 'Large Plone Folder'
+# this registries are needed to avoid loosing images with equal ids
+IMAGE_IDS = []
+IMAGE_PATHS = {}
+
+class BlogManifest(object):
+    implements(IExportDataCorrector)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, data):
+        # flag that indicated whether 'images' folder must added to manifest
+        need_to_add = True
+
+        doc = minidom.parseString(data['data'])
+        root = doc.documentElement
+        for child in root.getElementsByTagName('record'):
+            if child.getAttribute('type') not in  ('BlogEntry', 'BlogFolder'):
+                root.removeChild(child)
+            elif str(child.firstChild.nodeValue.strip()) == IMAGE_FOLDER:
+                # blog already contains object with IMAGE_FOLDER id
+                need_to_add = False
+
+        if need_to_add:
+            folder = doc.createElement('record')
+            folder.setAttribute('type', IMAGE_FOLDER_TYPE)
+            folder.appendChild(doc.createTextNode(IMAGE_FOLDER))
+            root.appendChild(folder)
+
+        data['data'] = doc.toxml('utf-8')
+        return data
+
+class BlogFolderManifest(object):
+    implements(IExportDataCorrector)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, data):
+        doc = minidom.parseString(data['data'])
+        root = doc.documentElement
+        for child in root.getElementsByTagName('record'):
+            if child.getAttribute('type') not in  ('BlogEntry', 'BlogFolder'):
+                root.removeChild(child)
+        data['data'] = doc.toxml('utf-8')
+        return data
+
+class BlogEntryManifest(object):
+    implements(IExportItemManipulator)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, item, **kw):
+        # remove manifest data from item - content contained in BlogEntry isn't exported
+        if '_files' in item and 'manifest' in item['_files']:
+            del item['_files']['manifest']
+        return item
+
+def recurseToInterface(item, ifaces):
+    """Recurse up the aq_chain until an object providing `iface' is found,
+    and return that.
+    """
+    if not isinstance(ifaces, (ListType, TupleType)):
+        ifaces = [ifaces]
+    parent = item.aq_parent
+    for iface in ifaces:
+        if iface.providedBy(item):
+            return item
+    for iface in ifaces:
+        if iface.providedBy(parent):
+            return parent
+    if isinstance(parent, PloneSite):
+        # Stop when we get to the portal root.
+        return None
+    return recurseToInterface(parent, ifaces)
+
+def getUniqueId(image_id):
+    """ Generate id that is unique in IMAGE_IDS registry.
+    """
+    if '.' in image_id:
+        name, ext = image_id.rsplit('.', 1)
+        ext = '.' + ext
+    else:
+        name, ext = image_id, ''
+    if image_id in IMAGE_IDS:
+        c = 1
+        new_id = name + str(c) + ext
+        while new_id in IMAGE_IDS:
+            c += 1
+            new_id = name + str(c) + ext
+        image_id = new_id
+
+    return image_id
+
+class BlogEntryExporter(ReferenceExporter):
+    implements(IExportDataCorrector)
+
+    SRC = re.compile(r'src="([^"]+)"')
+
+    def __init__(self, context):
+        self.context = context
+        self.portal_url = utils.getToolByName(self.context, 'portal_url')
+        self.portal = self.portal_url.getPortalObject()
+
+    def __call__(self, data):
+        data = super(BlogEntryExporter, self).__call__(data)
+        doc = minidom.parseString(data['data'])
+        try:
+            elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'body'][0]
+        except IndexError:
+            return data
+
+        text = elem.firstChild.nodeValue
+        urls = self.SRC.findall(text)
+        blog = recurseToInterface(self.context, IBlog)
+        blog_path = blog.getPhysicalPath()
+        context_path = self.context.getPhysicalPath()
+        for url in urls:
+            url = str(url)
+            image_id = url.rsplit('/', 1)[-1]
+            # skip links with illegal url schema
+            if '://' in url and not url.startswith('http://'):
+                continue
+            # convert all all links to relative
+            if url.startswith('http://'):
+                for site in SITE_URLS:
+                    if url.startswith(site):
+                        # check whether image is stored in blog
+                        relative_url = url[len(site):]
+                        relative_url = relative_url.strip('/')
+                        # if link is broken we'll get an AttributeError
+                        try:
+                            image = self.portal.unrestrictedTraverse(relative_url)
+                        except AttributeError:
+                            break
+                        in_blog = recurseToInterface(image, IBlog) is not None and True or False
+                        if in_blog:
+                            image_id = self.fixImageId(image, image_id, blog_path)
+                            level = len(context_path) - len(blog_path) - 1
+                            new_url = '/'.join(['..' for i in range(level)])
+                            new_url = '/'.join((new_url, IMAGE_FOLDER, image_id))
+                            text = text.replace(url, new_url, 1)
+                        else:
+                            # find how many levels self.context is under portal root
+                            level = len(context_path) - 3
+                            new_url = '/'.join(['..' for i in range(level)])
+                            new_url  = new_url + '/' + relative_url
+                            text = text.replace(url, new_url, 1)
+                        break
+            else:
+                if url.startswith('/'):
+                    # if link is broken we'll get an AttributeError
+                    try:
+                        image = self.portal.unrestrictedTraverse(url.strip('/'))
+                    except AttributeError:
+                        continue
+                else:
+                    # if link is broken we'll get an AttributeError
+                    try:
+                        image = self.context.unrestrictedTraverse(url)
+                    except AttributeError:
+                        continue
+                in_blog = recurseToInterface(image, IBlog) is not None and True or False
+                if in_blog:
+                    image_id = self.fixImageId(image, image_id, blog_path)
+                    level = len(context_path) - len(blog_path) - 1
+                    new_url = '/'.join(['..' for i in range(level)])
+                    new_url = '/'.join([new_url, IMAGE_FOLDER, image_id])
+                    text = text.replace(url, new_url, 1)
+                elif url.startswith('../'):
+                    # remove '../' from the start of string
+                    new_url = url[3:]
+                    text = text.replace(url, new_url, 1)
+                elif url.startswith('/'):
+                    # these links didn't work so rewrite them with '..'
+                    # find how many levels self.context is under portal root
+                    level = len(context_path) - 3
+                    new_url = '/'.join(['..' for i in range(level)])
+                    new_url  = new_url + url
+                    text = text.replace(url, new_url, 1)
+
+        elem.firstChild.nodeValue = text
+        data['data'] = doc.toxml('utf-8')
+        return data
+
+    def fixImageId(self, image, image_id, blog_path):
+        """ Check whether image is good or generate new if it's bad.
+        """
+        image_path = '/'.join(image.getPhysicalPath())
+        if image_id in IMAGE_IDS and image_path not in IMAGE_PATHS:
+            image_id = getUniqueId(image_id)
+        if image_id not in IMAGE_IDS:
+            IMAGE_IDS.append(image_id)
+            IMAGE_PATHS[image_path] = '/'.join(blog_path[2:] + (IMAGE_FOLDER, image_id))
+
+        return image_id
+
+class PathRewriter(object):
+    implements(IExportItemManipulator)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, item, **kw):
+        pathkey = kw.get('path')
+        if pathkey is None:
+            return item
+
+        path = item[pathkey]
+        blog = recurseToInterface(self.context, IBlog)
+        if blog is None:
+            return item
+
+        blog_path = blog.getPhysicalPath()
+        full_path = '/'.join(self.context.getPhysicalPath())
+        image_id = path.rsplit('/', 1)[-1]
+        modified = False
+
+        if full_path in IMAGE_PATHS:
+            new_path = IMAGE_PATHS[full_path]
+        else:
+            unique_id = getUniqueId(image_id)
+            modified = image_id != unique_id
+            new_path = '/'.join(blog_path[2:] + (IMAGE_FOLDER, unique_id))
+
+            IMAGE_IDS.append(image_id)
+            IMAGE_PATHS[full_path] = new_path
+
+        # change item's path
+        item[pathkey] = new_path
+        item['_oldpath'] = path
+
+        # now we need to fix object id in .marshall.xml
+        if modified:
+            if '_files' in item and 'marshall' in item['_files']:
+                doc = minidom.parseString(item['_files']['marshall']['data'])
+                elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'id'][0]
+                elem.firstChild.nodeValue = '\n\t\t%s\n\t' % unique_id
+                item['_files']['marshall']['data'] = doc.toxml('utf-8')
+
+        return item
+
+class ImageFolderSection(object):
+    """ This section will generate manifest files for image folders in blog.
+    """
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.previous = previous
+        self.transmogrifier = transmogrifier
+
+        self.flagkey = defaultMatcher(options, 'old-path-key', name, 'oldpath')
+        self.typekey = defaultMatcher(options, 'type-key', name, 'type')
+        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+
+
+        site_urls = options.get('site-urls', '')
+        site_urls = filter(None, [i.strip() for i in site_urls.splitlines()])
+        for i in site_urls:
+            SITE_URLS.append(i)
+
+        self.anno = IAnnotations(transmogrifier)
+
+    def __iter__(self):
+        folders = {}
+
+        # safely get logging storage
+        if VALIDATIONKEY in self.anno:
+            log_storage = self.anno[VALIDATIONKEY]
+        else:
+            log_storage = None
+
+        for item in self.previous:
+            item_keys = item.keys()
+            pathkey = self.pathkey(*item_keys)[0]
+            typekey = self.typekey(*item_keys)[0]
+            oldpathkey = self.flagkey(*item_keys)[0]
+
+            # collect data about images moved to folders
+            if pathkey and typekey and oldpathkey:
+                path = item[pathkey]
+                old_path = item[oldpathkey]
+                type_ = item[typekey]
+                folder_path, image_id = path.rsplit('/', 1)
+                folders.setdefault(folder_path, []).append((image_id, type_))
+
+                # update logging data (path) for this item
+                if log_storage and log_storage[-1] == old_path:
+                    log_storage.pop()
+                    log_storage.append(path)
+
+            yield item
+
+        # generate manifests for those image folders
+        items = []
+        for folder, entries in folders.items():
+            items.append({'_entries': entries, pathkey: folder})
+        exporter = ManifestExporterSection(self.transmogrifier, 'manifest', {'blueprint': 'manifest'}, iter(items))
+        for item in exporter:
+            yield item
+
+        # clean registries
+        while IMAGE_IDS: IMAGE_IDS.pop()
+        while SITE_URLS: SITE_URLS.pop()
+        IMAGE_PATHS.clear()
+
+class WorkflowImporter(object):
+    """ This adapter tries to convert all possible workflow histories to 
+        simple_publication_workflow history.
+    """
+    implements(IImportDataCorrector)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, data):
+        doc = minidom.parseString(data['data'])
+        wh = [i for i in doc.getElementsByTagName('cmf:workflow')]
+        if not wh:
+            # we don't have such workflow history
+            return data
+
+        wh = wh[0]
+        workflow_id = wh.getAttribute('id')
+        if workflow_id == 'simple_publication_workflow':
+            return data
+        wh.setAttribute('id', 'simple_publication_workflow')
+        if workflow_id == 'simpleblog_workflow':
+            self.fixSimpleBlogWorkflow(wh)
+        else:
+            self.fixWorkflow(wh)
+
+        data['data'] = doc.toxml('utf-8')
+        return data
+
+    def fixSimpleBlogWorkflow(self, wh):
+        for history in wh.getElementsByTagName('cmf:history'):
+            for var in history.getElementsByTagName('cmf:var'):
+                id_ = var.getAttribute('id')
+                value = var.getAttribute('value')
+                if id_ == 'review_state' and value == 'draft':
+                    var.setAttribute('value', 'private')
+
+    def fixWorkflow(self, wh):
+        for history in wh.getElementsByTagName('cmf:history'):
+            for var in history.getElementsByTagName('cmf:var'):
+                id_ = var.getAttribute('id')
+                value = var.getAttribute('value')
+                if id_ == 'review_state' and value == 'visible':
+                    var.setAttribute('value', 'published')
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl	(revision 1490)
@@ -0,0 +1,51 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='displayMode'" />
+        <xsl:when test="@name='displayItems'" />
+        <xsl:when test="@name='categories'" />
+        <xsl:when test="@name='allowTrackback'" />
+        <xsl:when test="@name='adminEmail'" />
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Folder</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl	(revision 1490)
@@ -0,0 +1,95 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- do some special with 'cmf:workflow_history' element -->
+                    <xsl:when test="name()='cmf:workflow_history'">
+                        <xsl:copy select=".">
+                            <xsl:apply-templates select="cmf:workflow" />
+                        </xsl:copy>
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='displayMode'" />
+        <xsl:when test="@name='displayItems'" />
+        <xsl:when test="@name='categories'" />
+        <xsl:when test="@name='allowTrackback'" />
+        <xsl:when test="@name='adminEmail'" />
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Large Plone Folder</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:workflow">
+    <xsl:copy select=".">
+        <!-- rename 'id' attribute -->
+        <xsl:attribute name="id">simple_publication_workflow</xsl:attribute>
+        <xsl:for-each select="*|text()">
+            <xsl:choose>
+                <!-- do some special with 'cmf:workflow_history' element -->
+                <xsl:when test="name()='cmf:history'">
+                    <xsl:copy select=".">
+                        <xsl:apply-templates select="cmf:var" />
+                    </xsl:copy>
+                </xsl:when>
+                <!-- copy all other elements -->
+                <xsl:otherwise>
+                    <xsl:copy-of select="."/>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:for-each>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:var">
+    <xsl:choose>
+        <xsl:when test="@value='visible'">
+            <xsl:copy select=".">
+                <xsl:attribute name="id">review_state</xsl:attribute>
+                <xsl:attribute name="type">str</xsl:attribute>
+                <xsl:attribute name="value">published</xsl:attribute>
+                <xsl:value-of select="." />
+            </xsl:copy>
+        </xsl:when>
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl	(revision 1490)
@@ -0,0 +1,51 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='displayMode'" />
+        <xsl:when test="@name='displayItems'" />
+        <xsl:when test="@name='categories'" />
+        <xsl:when test="@name='allowTrackback'" />
+        <xsl:when test="@name='adminEmail'" />
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Weblog</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl	(revision 1490)
@@ -0,0 +1,106 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/"
+     xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- do some special with 'cmf:workflow_history' element -->
+                    <xsl:when test="name()='cmf:workflow_history'">
+                        <xsl:copy select=".">
+                            <xsl:apply-templates select="cmf:workflow" />
+                        </xsl:copy>
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='alwaysOnTop'" />
+        <xsl:when test="@name='sendTrackBackURLs'" />
+        <!-- change field's name attribute from 'body' to 'text' -->
+        <xsl:when test="@name='body'">
+            <xsl:copy select=".">
+                <xsl:attribute name="name">text</xsl:attribute>
+                <xsl:value-of select="." />
+            </xsl:copy>
+        </xsl:when>
+        <!-- change field's name attribute form 'categories' to 'subject' -->
+        <xsl:when test="@name='categories'">
+            <dc:subject>
+                <xsl:value-of select="."/>
+            </dc:subject>
+        </xsl:when>
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Document</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:workflow">
+    <xsl:copy select=".">
+        <!-- rename 'id' attribute -->
+        <xsl:attribute name="id">simple_publication_workflow</xsl:attribute>
+        <xsl:for-each select="*|text()">
+            <xsl:choose>
+                <!-- do some special with 'cmf:workflow_history' element -->
+                <xsl:when test="name()='cmf:history'">
+                    <xsl:copy select=".">
+                        <xsl:apply-templates select="cmf:var" />
+                    </xsl:copy>
+                </xsl:when>
+                <!-- copy all other elements -->
+                <xsl:otherwise>
+                    <xsl:copy-of select="."/>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:for-each>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:var">
+    <xsl:choose>
+        <xsl:when test="@value='draft'">
+            <xsl:copy select=".">
+                <xsl:attribute name="id">review_state</xsl:attribute>
+                <xsl:attribute name="type">str</xsl:attribute>
+                <xsl:attribute name="value">private</xsl:attribute>
+                <xsl:value-of select="." />
+            </xsl:copy>
+        </xsl:when>
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl	(revision 1490)
@@ -0,0 +1,76 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/"
+     xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- do some special with 'cmf:workflow_history' element -->
+                    <xsl:when test="name()='cmf:workflow_history'">
+                        <xsl:copy select=".">
+                            <xsl:apply-templates select="cmf:workflow" />
+                        </xsl:copy>
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='alwaysOnTop'" />
+        <xsl:when test="@name='sendTrackBackURLs'" />
+        <!-- change field's name attribute from 'body' to 'text' -->
+        <xsl:when test="@name='body'">
+            <xsl:copy select=".">
+                <xsl:attribute name="name">text</xsl:attribute>
+                <xsl:value-of select="." />
+            </xsl:copy>
+        </xsl:when>
+        <!-- change field's name attribute form 'categories' to 'subject' -->
+        <xsl:when test="@name='categories'">
+            <dc:subject>
+                <xsl:value-of select="."/>
+            </dc:subject>
+        </xsl:when>
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>WeblogEntry</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:workflow">
+    <xsl:copy select=".">
+        <!-- rename 'id' attribute -->
+        <xsl:attribute name="id">plone_workflow</xsl:attribute>
+        <xsl:copy-of select="cmf:history"/>
+    </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl	(revision 1490)
@@ -0,0 +1,48 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='existingCats'" />
+        <xsl:when test="@name='categories'" />
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Folder</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl	(revision 1490)
@@ -0,0 +1,92 @@
+<xsl:stylesheet version="1.0" 
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+     xmlns:at="http://plone.org/ns/archetypes/"
+     xmlns:cmf="http://cmf.zope.org/namespaces/default/">
+
+<xsl:template match="/">
+    <xsl:for-each select="*">
+        <!-- matched 'metadata' element and we copy it -->
+        <xsl:copy select=".">
+            <xsl:for-each select="*|text()">
+                <xsl:choose>
+                    <!-- do some special with 'field' elements -->
+                    <xsl:when test="name()='field'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- change value of 'cmf:type' attribute -->
+                    <xsl:when test="name()='cmf:type'">
+                        <xsl:apply-templates select="." />
+                    </xsl:when>
+                    <!-- do some special with 'cmf:workflow_history' element -->
+                    <xsl:when test="name()='cmf:workflow_history'">
+                        <xsl:copy select=".">
+                            <xsl:apply-templates select="cmf:workflow" />
+                        </xsl:copy>
+                    </xsl:when>
+                    <!-- copy all other elements -->
+                    <xsl:otherwise>
+                        <xsl:copy-of select="."/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:for-each>
+        </xsl:copy>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="at:field">
+    <xsl:choose>
+        <!-- next fields are omitted -->
+        <xsl:when test="@name='existingCats'" />
+        <xsl:when test="@name='categories'" />
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="cmf:type">
+    <xsl:copy select=".">
+        <xsl:text>Large Plone Folder</xsl:text>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:workflow">
+    <xsl:copy select=".">
+        <!-- rename 'id' attribute -->
+        <xsl:attribute name="id">simple_publication_workflow</xsl:attribute>
+        <xsl:for-each select="*|text()">
+            <xsl:choose>
+                <!-- do some special with 'cmf:workflow_history' element -->
+                <xsl:when test="name()='cmf:history'">
+                    <xsl:copy select=".">
+                        <xsl:apply-templates select="cmf:var" />
+                    </xsl:copy>
+                </xsl:when>
+                <!-- copy all other elements -->
+                <xsl:otherwise>
+                    <xsl:copy-of select="."/>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:for-each>
+    </xsl:copy>
+</xsl:template>
+
+<xsl:template match="cmf:var">
+    <xsl:choose>
+        <xsl:when test="@value='visible'">
+            <xsl:copy select=".">
+                <xsl:attribute name="id">review_state</xsl:attribute>
+                <xsl:attribute name="type">str</xsl:attribute>
+                <xsl:attribute name="value">published</xsl:attribute>
+                <xsl:value-of select="." />
+            </xsl:copy>
+        </xsl:when>
+        <!-- copy all other elements -->
+        <xsl:otherwise>
+            <xsl:copy-of select="."/>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml	(revision 1490)
@@ -0,0 +1,166 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    xmlns:zcml="http://namespaces.zope.org/zcml"
+    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier"
+    i18n_domain="quintagroup.transmogrify.simpleblog2quills">
+
+    <include package="quintagroup.transmogrifier" />
+    <include package="quintagroup.transmogrifier" file="meta.zcml" />
+
+    <utility
+        component=".itemmanipulator.ItemManipulatorSection"
+        name="quintagroup.transmogrifier.itemmanipulator"
+        provides="collective.transmogrifier.interfaces.ISectionBlueprint"
+        />
+
+    <configure zcml:condition="installed Products.SimpleBlog">
+
+        <utility
+            component=".adapters.ImageFolderSection"
+            name="quintagroup.transmogrify.simpleblog2quills.imagefolder"
+            provides="collective.transmogrifier.interfaces.ISectionBlueprint"
+            />
+
+        <!-- In Plone 2.1 overrides.zcml isn't loaded, but conflicting configuration
+             actions wouldn't raise error on startup - the latest directive will
+             override previous -->
+        <transmogrifier:registerConfig
+            name="export"
+            title="Export pipeline configuration"
+            description="Customized for SimpleBlog/Quills content types content export pipeline."
+            configuration="export.cfg"
+            />
+
+        <!-- mark blog and blog entry objects so we can register export adapters for them -->
+
+        <five:implements
+            class="Products.SimpleBlog.content.Blog"
+            interface=".interfaces.IBlog"
+            />
+
+        <five:implements
+            class="Products.SimpleBlog.content.BlogFolder"
+            interface=".interfaces.IBlogFolder"
+            />
+
+        <five:implements
+            class="Products.SimpleBlog.content.BlogEntry"
+            interface=".interfaces.IBlogEntry"
+            />
+
+        <five:implements
+            class="Products.ATContentTypes.content.file.ATFile"
+            interface="quintagroup.transmogrifier.interfaces.IATFile"
+            />
+
+        <five:implements
+            class="Products.ATContentTypes.content.image.ATImage"
+            interface="quintagroup.transmogrifier.interfaces.IATImage"
+            />
+
+        <!-- 'datacorrector' section adapters -->
+        <adapter
+            for=".interfaces.IBlog"
+            provides="quintagroup.transmogrifier.interfaces.IExportDataCorrector"
+            factory=".adapters.BlogManifest"
+            name="manifest"
+            />
+
+        <adapter
+            for=".interfaces.IBlogFolder"
+            provides="quintagroup.transmogrifier.interfaces.IExportDataCorrector"
+            factory=".adapters.BlogFolderManifest"
+            name="manifest"
+            />
+
+        <adapter
+            for=".interfaces.IBlogEntry"
+            provides="quintagroup.transmogrifier.interfaces.IExportDataCorrector"
+            factory=".adapters.BlogEntryExporter"
+            name="marshall"
+            />
+
+        <!-- 'itemmanipulator' section adapter -->
+        <adapter
+            for=".interfaces.IBlogEntry"
+            provides=".interfaces.IExportItemManipulator"
+            factory=".adapters.BlogEntryManifest"
+            />
+
+        <adapter
+            for="quintagroup.transmogrifier.interfaces.IATFile"
+            provides=".interfaces.IExportItemManipulator"
+            factory=".adapters.PathRewriter"
+            />
+
+        <adapter
+            for="quintagroup.transmogrifier.interfaces.IATImage"
+            provides=".interfaces.IExportItemManipulator"
+            factory=".adapters.PathRewriter"
+            />
+
+    </configure>
+
+    <!-- next is for importing -->
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="Blog"
+        to="Weblog"
+        file="blog-weblog.xsl"
+        />
+
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="BlogEntry"
+        to="WeblogEntry"
+        file="blogentry-weblogentry.xsl"
+        />
+
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="BlogFolder"
+        to="Folder"
+        file="blogfolder-folder.xsl"
+        />
+
+    <!-- next stylesheets are used when migrating to QuillsEnabled -->
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="Blog"
+        to="Large Plone Folder"
+        file="blog-largefolder.xsl"
+        />
+
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="BlogFolder"
+        to="Large Plone Folder"
+        file="blogfolder-largefolder.xsl"
+        />
+
+    <transmogrifier:stylesheet
+        source="marshall"
+        from="BlogEntry"
+        to="Document"
+        file="blogentry-document.xsl"
+        />
+
+    <adapter
+        for="quintagroup.transmogrify.simpleblog2quills.interfaces.IBaseObject"
+        provides="quintagroup.transmogrifier.interfaces.IImportDataCorrector"
+        factory=".adapters.WorkflowImporter"
+        name="marshall"
+        />
+
+    <configure zcml:condition="installed Products.QuillsEnabled">
+
+        <utility
+            component=".activator.BlogActivatorSection"
+            name="quintagroup.transmogrify.simpleblog2quills.activator"
+            provides="collective.transmogrifier.interfaces.ISectionBlueprint"
+            />
+
+    </configure>
+
+</configure>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg	(revision 1490)
@@ -0,0 +1,65 @@
+[transmogrifier]
+pipeline =
+    sitewalker
+    condition
+    manifestexporter
+    fileexporter
+    marshaller
+    propertiesexporter
+    commentsexporter
+    datacorrector
+    itemmanipulator
+    imagefolder
+    writer
+    EXPORTING
+
+[sitewalker]
+blueprint = quintagroup.transmogrifier.sitewalker
+excluded-types =
+    ATAudio
+    TrackBack
+
+[condition]
+blueprint = collective.transmogrifier.sections.condition
+condition = python:not bool([i for i in ('Members', 'news', 'events') if item['_path'].startswith(i)])
+
+[manifestexporter]
+blueprint = quintagroup.transmogrifier.manifestexporter
+
+[fileexporter]
+blueprint = quintagroup.transmogrifier.fileexporter
+
+[marshaller]
+blueprint = quintagroup.transmogrifier.marshaller
+
+[propertiesexporter]
+blueprint = quintagroup.transmogrifier.propertiesexporter
+exclude = title
+
+[commentsexporter]
+blueprint = quintagroup.transmogrifier.commentsexporter
+
+[datacorrector]
+blueprint = quintagroup.transmogrifier.datacorrector
+sources =
+    manifest
+    marshall
+
+[itemmanipulator]
+blueprint = quintagroup.transmogrifier.itemmanipulator
+type = export
+
+# in this section you must write you site URL
+[imagefolder]
+blueprint = quintagroup.transmogrify.simpleblog2quills.imagefolder
+site-urls =
+
+[writer]
+blueprint = quintagroup.transmogrifier.writer
+prefix = structure
+
+[EXPORTING]
+blueprint = quintagroup.transmogrifier.logger
+keys = 
+    _type
+    _path
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg	(revision 1490)
@@ -0,0 +1,44 @@
+[transmogrifier]
+pipeline =
+    reader
+    manifestimporter
+    substitution
+    constructor
+    xslt
+    datacorrector
+    fileimporter
+    demarshaller
+    referencesimporter
+    propertiesimporter
+    commentsimporter
+    activator
+    IMPORTING
+include = quintagroup.transmogrifier:import.cfg
+
+# don't yield items that are in manifest, but don't exists in import context
+[manifestimporter]
+enable-source-behaviour = false
+
+# this section depends on what blogging product you use - Quills or QuillsEnabled
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+
+# next options is for Quills (comment them if you are using QuillsEnabled)
+# Blog = Weblog
+# BlogFolder = Folder
+# BlogEntry = WeblogEntry
+
+# next is for QuillsEnabled (uncomment them if you are using QuillsEnabled)
+Blog = Large Plone Folder
+BlogFolder = Large Plone Folder
+BlogEntry = Document
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+source = marshall
+from-key = _old_type
+to-key = _type
+
+[activator]
+blueprint = quintagroup.transmogrify.simpleblog2quills.activator
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py	(revision 1490)
@@ -0,0 +1,37 @@
+from zope.interface import Interface
+
+class IBlog(Interface):
+    """ Marker interface for SimpleBlog blog object.
+    """
+
+class IBlogFolder(Interface):
+    """ Marker interface for SimpleBlog blog folder object.
+    """
+
+class IBlogEntry(Interface):
+    """ Marker interface for SimpleBlog blog entry object.
+    """
+
+class IItemManipulator(Interface):
+    """ Interface for adapters that are looked up in 'itemmanipulator' 
+        pipeline section.
+    """
+
+    def __call__(item, **kw):
+        """ Do something with a pipeline item and return it.
+            kw - dictionary with extra arguments, for example some useful keys
+                in item (pathkey, ...)
+        """
+
+class IExportItemManipulator(IItemManipulator):
+    """ Exporting adapter.
+    """
+
+class IImportItemManipulator(IItemManipulator):
+    """ Importing adapter
+    """
+
+try:
+    from Products.Archetypes.interfaces import IBaseObject
+except ImportError:
+    from plone.app.transmogrifier.interfaces import IBaseObject
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py	(revision 1490)
@@ -0,0 +1,47 @@
+from zope.interface import classProvides, implements
+from zope.component import queryAdapter
+
+from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
+from collective.transmogrifier.utils import defaultMatcher
+
+from quintagroup.transmogrify.simpleblog2quills.interfaces import \
+    IItemManipulator, IExportItemManipulator, IImportItemManipulator
+
+class ItemManipulatorSection(object):
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.previous = previous
+        self.context = transmogrifier.context
+
+        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+
+        # 'type' options specifies adapter interface
+        type_ = options.get('type', 'general')
+        if type_ == 'general':
+            self.interface = IItemManipulator
+        elif type_ == 'export':
+            self.interface = IExportItemManipulator
+        elif type_ == 'import':
+            self.interface = IImportItemManipulator
+        else:
+            self.interface = None
+
+    def __iter__(self):
+        for item in self.previous:
+            pathkey = self.pathkey(*item.keys())[0]
+
+            if not (pathkey and self.interface is not None):
+                yield item; continue
+
+            path = item[pathkey]
+            obj = self.context.unrestrictedTraverse(path, None)
+            if obj is None:         # path doesn't exist
+                yield item; continue
+
+            adapter = queryAdapter(obj, self.interface, name='')
+            if adapter:
+                item = adapter(item, path=pathkey)
+
+            yield item
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml	(revision 1490)
@@ -0,0 +1,12 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
+
+    <transmogrifier:registerConfig
+        name="import"
+        title="Import pipeline configuration"
+        description="Customized for SimpleBlog/Quills content types content import pipeline."
+        configuration="import.cfg"
+        />
+
+</configure>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml	(revision 1490)
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<metadata>
+  <version>0.1</version>
+</metadata>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml	(revision 1490)
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<object name="Large Plone Folder"
+   meta_type="Factory-based Type Information with dynamic views"
+   i18n:domain="plone" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="global_allow">True</property>
+</object>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py	(revision 1490)
@@ -0,0 +1,1 @@
+# i'm a package
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py	(revision 1490)
@@ -0,0 +1,43 @@
+import os.path
+
+from zope.interface import classProvides, implements
+
+from collective.transmogrifier.interfaces import ISectionBlueprint, ISection
+
+class Source(object):
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.previous = previous
+        self.source = options.get('source', '').strip()
+        self.allow_empty = options.get('allow-empty-items', '').strip() == 'yes' and True or False
+        items_source = options.get('items', '').strip()
+        self.items = []
+        for line in items_source.splitlines():
+            self.items.append([i.strip() for i in line.split(';')])
+
+    def __iter__(self):
+        for item in self.previous:
+            yield item
+
+        for path, type_, fname in self.items:
+            if not fname.startswith('/'):
+                fname = os.path.join(os.path.dirname(__file__), fname)
+            try:
+                fp = file(fname)
+                data = fp.read()
+                fp.close()
+            except IOError, e:
+                if self.allow_empty:
+                    yield dict(_type=type_, _path=path)
+                continue
+
+            item = dict(
+                _type=type_,
+                _path=path,
+                _files={
+                    self.source: {'data': data}
+                }
+            )
+            yield item
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml	(revision 1490)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Test Blog
+    </dc:title>
+    <dc:description>
+        This is test blog.
+    </dc:description>
+    <xmp:CreateDate>
+        2005-08-29T11:32:01Z
+    </xmp:CreateDate>
+    <xmp:ModifyDate>
+        2006-04-26T11:04:31Z
+    </xmp:ModifyDate>
+    <field name="id">
+        blog
+    </field>
+    <field name="displayMode">
+        descriptionOnly
+    </field>
+    <field name="displayItems">
+        15
+    </field>
+    <field name="categories">
+        Zope
+    </field>
+    <field name="categories">
+        Plone
+    </field>
+    <field name="tags">
+        Python
+    </field>
+    <field name="tags">
+        Testing
+    </field>
+    <field name="tagsEnabled">
+        True
+    </field>
+    <cmf:type>
+        Blog
+    </cmf:type>
+</metadata>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml	(revision 1490)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Blog folder
+    </dc:title>
+    <dc:description>
+        Folder in blog.
+    </dc:description>
+    <xmp:ModifyDate>
+        2005-11-04T11:31:06Z
+    </xmp:ModifyDate>
+    <field name="id">
+        folder
+    </field>
+    <field name="existingCats">
+        &lt;ul&gt;&lt;li&gt;Zope&lt;/li&gt;&lt;li&gt;Plone&lt;/li&gt;
+    </field>
+    <cmf:type>
+        BlogFolder
+    </cmf:type>
+</metadata>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml	(revision 1490)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Root entry
+    </dc:title>
+    <dc:description>
+        This entry was created in root of blog.
+    </dc:description>
+    <xmp:ModifyDate>
+        2007-11-14T10:32:11Z
+    </xmp:ModifyDate>
+    <field name="id">
+        root-entry
+    </field>
+    <field name="body">
+        &lt;p&gt;We are testing importing of blog entry.&lt;/p&gt;
+    </field>
+    <field name="categories">
+        Plone
+    </field>
+    <field name="categories">
+        Zope
+    </field>
+    <cmf:type>
+        BlogEntry
+    </cmf:type>
+    <cmf:workflow_history>
+        <cmf:workflow id="simpleblog_workflow">
+            <cmf:history>
+                <cmf:var id="action" type="None" value="None"/>
+                <cmf:var id="actor" type="str" value="admin"/>
+                <cmf:var id="comments" type="str" value=""/>
+                <cmf:var id="review_state" type="str" value="draft"/>
+                <cmf:var id="time" type="date" value="2007-11-06 05:25:51"/>
+            </cmf:history>
+            <cmf:history>
+                <cmf:var id="action" type="str" value="publish"/>
+                <cmf:var id="actor" type="str" value="admin"/>
+                <cmf:var id="comments" type="str" value=""/>
+                <cmf:var id="review_state" type="str" value="published"/>
+                <cmf:var id="time" type="date" value="2007-11-14 04:32:11"/>
+            </cmf:history>
+        </cmf:workflow>
+    </cmf:workflow_history>
+    <cmf:security>
+        <cmf:local_role role="Owner" user_id="admin"/>
+    </cmf:security>
+</metadata>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt	(revision 1490)
@@ -0,0 +1,53 @@
+Test source section
+===================
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+...     source
+...     printer
+... 
+... [source]
+... blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+... source = marshall
+... items =
+...     not-existing;       Document;   not-existing-path
+...     not-existing;       File;       /not/existing/absolute/path
+...     plone-blog;         Blog;       blog.xml
+... 
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrify.simpleblog2quills.tests.source', source)
+>>> transmogrifier(u'quintagroup.transmogrify.simpleblog2quills.tests.source') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
+
+Now we are testing ``allow-empty-items`` option:
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+...     source
+...     printer
+... 
+... [source]
+... blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+... allow-empty-items = yes
+... source = marshall
+... items =
+...     not-existing;       Document;   not-existing-path
+...     not-existing;       File;       /not/existing/absolute/path
+...     plone-blog;         Blog;       blog.xml
+... 
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrify.simpleblog2quills.tests.source-with-empties', source)
+>>> transmogrifier(u'quintagroup.transmogrify.simpleblog2quills.tests.source-with-empties') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_type': 'Document', '_path': 'not-existing'}
+{'_type': 'File', '_path': 'not-existing'}
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py	(revision 1490)
@@ -0,0 +1,23 @@
+import unittest
+
+from zope.testing import doctest, cleanup
+
+from Products.Five import zcml
+
+from collective.transmogrifier.tests import tearDown
+from quintagroup.transmogrifier.tests import sectionsSetUp
+
+import quintagroup.transmogrify.simpleblog2quills.tests
+
+def sourceSetUp(test):
+    sectionsSetUp(test)
+    zcml.load_config('test_import.zcml', quintagroup.transmogrify.simpleblog2quills.tests)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTests((
+        doctest.DocFileSuite(
+            'source.txt',
+            setUp=sourceSetUp, tearDown=tearDown),
+    ))
+    return suite
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg	(revision 1490)
@@ -0,0 +1,34 @@
+[transmogrifier]
+pipeline =
+    source
+    substitution
+    constructor
+    xslt
+    datacorrector
+    demarshaller
+    referencesimporter
+include = quintagroup.transmogrifier:import.cfg
+
+[source]
+blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+source = marshall
+allow-empty-items = yes
+items =
+#   path;                        type;       file
+    blog;                        Blog;       blog.xml
+    blog/root-entry;             BlogEntry;  root_entry.xml
+    blog/folder;                 BlogFolder; folder.xml
+    blog/folder/folder-entry;    BlogEntry;  folder_entry.xml
+
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+Blog = Weblog
+BlogEntry = WeblogEntry
+BlogFolder = Folder
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+source = marshall
+from-key = _old_type
+to-key = _type
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py	(revision 1490)
@@ -0,0 +1,87 @@
+import unittest
+import os.path
+
+import transaction
+
+from Products.Five import zcml
+from Products.Five import fiveconfigure
+from Testing import ZopeTestCase as ztc
+
+from Products.PloneTestCase import PloneTestCase as ptc
+from Products.PloneTestCase.layer import onsetup
+
+from collective.transmogrifier.interfaces import ITransmogrifier
+
+ztc.installProduct('Quills')
+ztc.installProduct('fatsyndication')
+
+@onsetup
+def setup_product():
+    fiveconfigure.debug_mode = True
+    import Products.Five
+    zcml.load_config('configure.zcml', Products.Five)
+    import quintagroup.transmogrify.simpleblog2quills
+    zcml.load_config('configure.zcml', quintagroup.transmogrify.simpleblog2quills)
+    import quintagroup.transmogrify.simpleblog2quills.tests
+    zcml.load_config('test_import.zcml', quintagroup.transmogrify.simpleblog2quills.tests)
+    # this is needed because 'importStep' unknown directive error is raised somewhere
+    import Products.GenericSetup
+    zcml.load_config('meta.zcml', Products.GenericSetup)
+    import Products.Quills
+    zcml.load_config('configure.zcml', Products.Quills)
+    fiveconfigure.debug_mode = False
+
+setup_product()
+ptc.setupPloneSite(products=['Quills'])
+
+class TestImport(ptc.PloneTestCase):
+    """ Test importing of PloneFormGen content.
+    """
+
+    def afterSetUp(self):
+        self.addProduct('Quills')
+        if 'blog' not in self.portal:
+            # run transmogrifier pipeline
+            transmogrifier = ITransmogrifier(self.portal)
+            transmogrifier('test_import')
+
+    def beforeTearDown(self):
+        transaction.commit()
+
+    def test_site_structure(self):
+        self.failIf('blog' not in self.portal)
+        self.failIf('root-entry' not in self.portal.blog)
+        self.failIf('folder' not in self.portal.blog)
+        self.failIf('folder-entry' not in self.portal.blog.folder)
+
+    def test_blog(self):
+        blog = self.portal['blog']
+
+        self.assertEqual(blog.getPortalTypeName(), 'Weblog')
+        self.assertEqual(blog['title'], 'Test Blog')
+        self.assertEqual(blog.Description(), 'This is test blog.')
+
+    def test_blog_entry(self):
+        entry = self.portal['blog']['root-entry']
+
+        self.assertEqual(entry.getPortalTypeName(), 'WeblogEntry')
+        self.assertEqual(entry['title'], 'Root entry')
+        self.assertEqual(entry.Description(), 'This entry was created in root of blog.')
+        self.assertEqual(entry.getText(), '<p>We are testing importing of blog entry.</p>')
+        self.assertEqual(entry.Subject(), ('Plone', 'Zope'))
+        self.assertEqual(entry.modified().HTML4(), '2007-11-14T10:32:11Z')
+        # now workflow of WeblogEntry is assumed to be 'plone_workflow'
+        # but it must be configured in type configuration
+        self.failIf('plone_workflow' not in entry.workflow_history)
+
+    def test_blog_folder(self):
+        folder = self.portal['blog']['folder']
+
+        self.assertEqual(folder.getPortalTypeName(), 'Folder')
+        self.assertEqual(folder['title'], 'Blog folder')
+        self.assertEqual(folder.Description(), 'Folder in blog.')
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestImport))
+    return suite
Index: quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml	(revision 1490)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml	(revision 1490)
@@ -0,0 +1,17 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
+
+    <utility
+        component=".base.Source"
+        name="quintagroup.transmogrify.simpleblog2quills.tests.source"
+        />
+
+    <transmogrifier:registerConfig
+        name="test_import"
+        title="Import pipeline configuration"
+        description="Customized for SimpleBlog/Quills content types content import pipeline."
+        configuration="test_import.cfg"
+        />
+
+</configure>
Index: quintagroup.transmogrify.simpleblog2quills/trunk/setup.py
===================================================================
--- quintagroup.transmogrify.simpleblog2quills/trunk/setup.py	(revision 1487)
+++ quintagroup.transmogrify.simpleblog2quills/trunk/setup.py	(revision 1490)
@@ -4,5 +4,5 @@
 version = '0.1'
 
-setup(name='quintagroup.transmogrifier.simpleblog2quills',
+setup(name='quintagroup.transmogrify.simpleblog2quills',
       version=version,
       description="Configuration of collective.transmogrifier pipeline for migrating SimpleBlog content to Quills content",
@@ -20,5 +20,5 @@
       license='GPL',
       packages=find_packages(exclude=['ez_setup']),
-      namespace_packages=['quintagroup', 'quintagroup.transmogrifier'],
+      namespace_packages=['quintagroup', 'quintagroup.transmogrify'],
       include_package_data=True,
       zip_safe=False,
