diff --git a/Sankore_3.1.pro b/Sankore_3.1.pro
index 7003f481..e6a69f4e 100644
--- a/Sankore_3.1.pro
+++ b/Sankore_3.1.pro
@@ -7,9 +7,9 @@ CONFIG += debug_and_release \
    no_include_pwd
 
 VERSION_MAJ = 1
-VERSION_MIN = 10
+VERSION_MIN = 11
 VERSION_TYPE = b # a = alpha, b = beta, r = release, other => error
-VERSION_PATCH = 01
+VERSION_PATCH = 00
 
 VERSION = "$${VERSION_MAJ}.$${VERSION_MIN}.$${VERSION_TYPE}.$${VERSION_PATCH}"
 VERSION = $$replace(VERSION, "\\.r", "")
diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp
new file mode 100644
index 00000000..7a62d39c
--- /dev/null
+++ b/src/adaptors/UBCFFSubsetAdaptor.cpp
@@ -0,0 +1,610 @@
+#include <QRegExp>
+#include <QSvgGenerator>
+#include <QSvgRenderer>
+
+#include "UBCFFSubsetAdaptor.h"
+
+
+#include "core/UBPersistenceManager.h"
+#include "document/UBDocumentProxy.h"
+#include "domain/UBItem.h"
+#include "domain/UBGraphicsPolygonItem.h"
+#include "domain/UBGraphicsStroke.h"
+
+#include "UBMetadataDcSubsetAdaptor.h"
+#include "UBThumbnailAdaptor.h"
+#include "UBSvgSubsetAdaptor.h"
+
+//enum of xmlparse status
+
+//tag names definition
+//use them everiwhere!
+static char* tElement       = "element";
+static char* tEllipse       = "ellipse";
+static char* tIwb           = "iwb";
+static char* tMeta          = "meta";
+static char* tPage          = "page";
+static char* tPageset       = "pageset";
+static char* tPolygon       = "polygon";
+static char* tRect          = "rect";
+static char* tSvg           = "svg";
+static char* tTextarea      = "textarea";
+
+//attribute names definition
+static char* aFill          = "fill";
+static char* aFillopacity   = "fill-opacity";
+static char* aX             = "x";
+static char* aY             = "y";
+static char* aWidth         = "width";
+static char* aHeight        = "height";
+static char* aStroke        = "stroke";
+static char* aStrokewidth   = "stroke-width";
+static char* aCx            = "cx";
+static char* aCy            = "cy";
+static char* aRx            = "rx";
+static char* aRy            = "ry";
+static char* aTransform     = "transform";
+static char* aViewbox       = "viewbox";
+
+UBCFFSubsetAdaptor::UBCFFSubsetAdaptor()
+{
+}
+
+bool UBCFFSubsetAdaptor::ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument)
+{
+    //TODO
+    // fill document proxy metadata
+    // create persistance manager to save data using proxy
+    // create UBCFFSubsetReader and make it parse cffSourceFolder
+    QFile file(cffSourceFile);
+
+    if (!file.open(QIODevice::ReadOnly))
+    {
+        qWarning() << "Cannot open file " << cffSourceFile << " for reading ...";
+        return false;
+    }
+
+    QByteArray data = file.readAll();
+    if (data.length() == 0)
+    {
+        qWarning() << "Either content file " << cffSourceFile << " is empty or failed to read from file";
+        file.close();
+        return false;
+    }
+
+    UBCFFSubsetReader cffReader(pDocument, data);
+    bool result =  cffReader.parse();
+    file.close();
+
+    return result;
+}
+
+UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QByteArray &content):
+    mReader(content), mProxy(proxy), currentState(NONE)
+{
+    //TODO parse
+}
+
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse()
+{
+    UBMetadataDcSubsetAdaptor::persist(mProxy);
+
+    mIndent = "";
+    if (!getTempFileName())
+        return false;
+
+    bool result = parseDoc();
+    if (result)
+        result = mProxy->pageCount() != 0;
+
+    if (QFile::exists(mTempFilePath))
+        QFile::remove(mTempFilePath);
+
+    return result;
+}
+
+int UBCFFSubsetAdaptor::UBCFFSubsetReader::PopState()
+{
+    if (stateStack.count() == 0)
+        currentState = NONE;
+    else
+        currentState = stateStack.pop();
+
+    return currentState;
+}
+
+void UBCFFSubsetAdaptor::UBCFFSubsetReader::PushState(int state)
+{
+    if (currentState != NONE)
+        stateStack.push(currentState);
+    currentState = state;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseDoc()
+{
+    while (!mReader.atEnd())
+    {
+        mReader.readNext();
+        if (mReader.isStartElement())
+        {
+            if (!parseCurrentElementStart())
+                return false;
+        }
+        else
+            if (mReader.isCharacters())
+            {
+                if (!parseCurrentElementCharacters())
+                    return false;
+            }
+        else
+                if (mReader.isEndElement())
+                {
+                    if (!parseCurrentElementEnd())
+                        return false;
+                }
+    }
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseCurrentElementStart()
+{
+    QStringRef elName = mReader.name();
+    QString log = QString("%1<%2>").arg(mIndent).arg(elName.toString());
+    qDebug() << log;
+    mIndent += " ";
+    if ( elName == tIwb)
+    {
+        if (!parseIwb())
+            return false;
+
+        PushState(IWB);
+    }
+    else
+    if ( elName == tMeta)
+    {
+        if (!parseIwbMeta())
+            return false;
+    }
+    else
+    if ( elName == tSvg)
+    {
+        if (!parseSvg())
+            return false;
+
+        PushState(SVG);
+    }
+    else
+    if ( elName == tRect)
+    {
+        if (!parseRect())
+            return false;
+    }
+    else
+    if ( elName == tEllipse)
+    {
+        if (!parseEllipse())
+            return false;
+    }
+    else
+    if ( elName == tTextarea)
+    {
+        if (!parseTextArea())
+            return false;
+    }
+    else
+    if ( elName == tPolygon)
+    {
+        if (!parsePolygon())
+            return false;
+    }
+    else
+    if ( elName == tPage)
+    {
+        if (!parsePage())
+            return false;
+
+        PushState(PAGE);
+    }
+    else
+    if ( elName == tPageset)
+    {
+        if (!parsePageSet())
+            return false;
+
+        PushState(PAGESET);
+    }
+    else
+    if ( elName == tElement)
+    {
+        if (!parseIwbElementRef())
+            return false;
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseCurrentElementCharacters()
+{
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseCurrentElementEnd()
+{
+    QStringRef elName = mReader.name();
+    mIndent.remove(0,1);
+    QString log = QString("%1</%2>").arg(mIndent).arg(elName.toString());
+    qDebug() << log;
+
+    if ( elName == tIwb)
+        PopState();
+    else
+    if ( elName == tMeta)
+    {
+    }
+    else
+    if ( elName == tSvg)
+    {
+        persistCurrentScene();
+        PopState();
+    }
+    else
+    if ( elName == tPage)
+    {
+        persistCurrentScene();
+        PopState();
+    }
+    else
+    if ( elName == tPageset)
+    {
+        PopState();
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwb()
+{
+    if (!stateStack.empty() || currentState != NONE)
+    {
+        qWarning() << "iwb content parse error, unexpected iwb tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbMeta()
+{
+    if (currentState != IWB)
+    {
+        qWarning() << "iwb content parse error, unexpected meta tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg()
+{
+    if (currentState != IWB)
+    {
+        qWarning() << "iwb content parse error, unexpected svg tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    getViewBoxDimenstions(mReader.attributes().value(aViewbox).toString());
+    mSize = QSize(mReader.attributes().value(aWidth).toString().toInt(),
+                  mReader.attributes().value(aHeight).toString().toInt());
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect()
+{
+    if (currentState != SVG && currentState != PAGE)
+    {
+        qWarning() << "iwb content parse error, unexpected rect tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    //create new scene if it's not created yet (for one page document case)
+    if (currentState == SVG && mCurrentScene == NULL)
+        createNewScene();
+
+    //fill and stroke color
+    QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString());
+    QColor strokeColor = colorFromString(mReader.attributes().value(aStroke).toString());
+    int strokeWidth = mReader.attributes().value(aStrokewidth).toString().toInt();
+
+    //rect lef top corner coordinates
+    qreal x1 = mReader.attributes().value(aX).toString().toDouble();
+    qreal y1 = mReader.attributes().value(aY).toString().toDouble();
+    //rect dimensions
+    qreal width = mReader.attributes().value(aWidth).toString().toDouble();
+    qreal height = mReader.attributes().value(aHeight).toString().toDouble();
+
+    //init svg generator with temp file
+    QSvgGenerator *generator = createSvgGenerator();
+
+    //init painter to paint to svg
+    QPainter painter;
+    painter.begin(generator);
+
+    //check if rect is rotated
+    if (mReader.attributes().hasAttribute(aTransform))
+    {
+        QTransform transform = transformFromString(mReader.attributes().value(aTransform).toString());
+        painter.setTransform(transform);
+        //change left top coordinates to correspond to transformation
+        x1 -= transform.dx();
+        y1 -= transform.dy();
+    }
+
+    painter.setBrush(QBrush(fillColor));
+    painter.fillRect(x1, y1, width, height, fillColor);
+
+    QPen pen(strokeColor);
+    pen.setWidth(strokeWidth);
+    painter.setPen(pen);
+    painter.drawRect(x1, y1, width, height);
+
+    painter.end();
+
+    //add resulting svg file to scene
+    mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName()));
+    delete generator;
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseEllipse()
+{
+    if (currentState != SVG && currentState != PAGE)
+    {
+        qWarning() << "iwb content parse error, unexpected ellipse tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    //create new scene if it's not created yet (for one page document case)
+    if (currentState == SVG && mCurrentScene == NULL)
+        createNewScene();
+
+    QSvgGenerator *generator = createSvgGenerator();
+
+    //fill and stroke color
+    QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString());
+    QColor strokeColor = colorFromString(mReader.attributes().value(aStroke).toString());
+    int strokeWidth = mReader.attributes().value(aStrokewidth).toString().toInt();
+
+    //ellipse center coordinates
+    qreal cx = mReader.attributes().value(aCx).toString().toDouble();
+    qreal cy = mReader.attributes().value(aCy).toString().toDouble();
+    //ellipse horisontal and vertical radius
+    qreal rx = mReader.attributes().value(aRx).toString().toDouble();
+    qreal ry = mReader.attributes().value(aRy).toString().toDouble();
+
+    //we should change cx and cy by rx and ry because qpainter
+    //draws ellipse by its rect coordinates
+    cx -= rx;
+    cy -= ry;
+
+    //init painter to paint to svg
+    QPainter painter;
+    painter.begin(generator);
+
+    //check if ellipse is rotated
+    if (mReader.attributes().hasAttribute(aTransform))
+    {
+        QTransform transform = transformFromString(mReader.attributes().value(aTransform).toString());
+        painter.setTransform(transform);
+        //change cx and cy to correspond to transformation
+        cx -= transform.dx();
+        cy -= transform.dy();
+    }
+
+    QPen pen(strokeColor);
+    pen.setWidth(strokeWidth);
+    painter.setPen(pen);
+    painter.setBrush(QBrush(fillColor));
+
+    painter.drawEllipse(cx, cy, rx * 2, ry * 2);
+
+    painter.end();
+
+    //add resulting svg file to scene
+    mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName()));
+    delete generator;
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea()
+{
+    if (currentState != SVG && currentState != PAGE)
+    {
+        qWarning() << "iwb content parse error, unexpected textarea tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    //create new scene if it's not created yet (for one page document case)
+    if (currentState == SVG && mCurrentScene == NULL)
+        createNewScene();
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parsePolygon()
+{
+    if (currentState != SVG && currentState != PAGE)
+    {
+        qWarning() << "iwb content parse error, unexpected polygon tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    //create new scene if it's not created yet (for one page document case)
+    if (currentState == SVG && mCurrentScene == NULL)
+        createNewScene();
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parsePage()
+{
+    if (currentState != PAGESET && currentState != SVG)
+    {
+        qWarning() << "iwb content parse error, unexpected page tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    createNewScene();
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parsePageSet()
+{
+    if (currentState != SVG)
+    {
+        qWarning() << "iwb content parse error, unexpected page tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElementRef()
+{
+    if (currentState != IWB)
+    {
+        qWarning() << "iwb content parse error, unexpected element tag at line" << mReader.lineNumber();
+        return false;
+    }
+
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene()
+{
+    mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount());
+    return true;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::persistCurrentScene()
+{
+    if (mCurrentScene != 0 && mCurrentScene->isModified())
+    {
+        UBThumbnailAdaptor::persistScene(mProxy->persistencePath(), mCurrentScene, mProxy->pageCount() - 1);
+        UBSvgSubsetAdaptor::persistScene(mProxy, mCurrentScene, mProxy->pageCount() - 1);
+
+        mCurrentScene->setModified(false);
+        mCurrentScene = 0;
+    }
+    return true;
+}
+
+QColor UBCFFSubsetAdaptor::UBCFFSubsetReader::colorFromString(const QString& clrString)
+{
+    //init regexp with pattern
+    //pattern corresponds to strings like 'rgb(1,2,3) or rgb(10%,20%,30%)'
+    QRegExp regexp("rgb\\(([0-9]+%{0,1}),([0-9]+%{0,1}),([0-9]+%{0,1})\\)");
+    if (regexp.exactMatch(clrString))
+    {
+        if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == clrString.length())
+        {
+            int r = regexp.capturedTexts().at(1).toInt();
+            if (regexp.capturedTexts().at(1).indexOf("%") != -1)
+                r = r * 255 / 100;
+            int g = regexp.capturedTexts().at(2).toInt();
+            if (regexp.capturedTexts().at(2).indexOf("%") != -1)
+                g = g * 255 / 100;
+            int b = regexp.capturedTexts().at(3).toInt();
+            if (regexp.capturedTexts().at(3).indexOf("%") != -1)
+                b = b * 255 / 100;
+            return QColor(r, g, b);
+        }
+        else
+            return QColor();
+    }
+    else
+        return QColor(clrString);
+}
+
+QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QString trString)
+{
+    //check pattern for strings like 'rotate(10)'
+    QRegExp regexp("rotate\\(([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)\\)");
+    if (regexp.exactMatch(trString))
+    {
+        if (regexp.capturedTexts().count() == 2 && regexp.capturedTexts().at(0).length() == trString.length())
+        {
+            qreal angle = regexp.capturedTexts().at(1).toDouble();
+            return QTransform().rotate(angle);
+        }
+    }
+
+    //check pattern for strings like 'rotate(10,20,20)' or 'rotate(10.1,10.2,34.2)'
+    regexp.setPattern("rotate\\(([-+]{0,1}[0-9]*\\.{0,1}[0-9]*),([-+]{0,1}[0-9]*\\.{0,1}[0-9]*),([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)\\)");
+    if (regexp.exactMatch(trString))
+    {
+        if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == trString.length())
+        {
+            qreal angle = regexp.capturedTexts().at(1).toDouble();
+            qreal dx = regexp.capturedTexts().at(2).toDouble();
+            qreal dy = regexp.capturedTexts().at(3).toDouble();
+            return QTransform().translate(dx, dy).rotate(angle);
+        }
+    }
+
+    return QTransform();
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getViewBoxDimenstions(const QString& viewBox)
+{
+    //check pattern for strings like 'rotate(10)'
+    QRegExp regexp("([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)");
+    if (regexp.exactMatch(viewBox))
+    {
+        int capturesCount = regexp.capturedTexts().count();
+        if (capturesCount == 5 && regexp.capturedTexts().at(0).length() == viewBox.length())
+        {
+            mViewBox = QRectF(0, 0, regexp.capturedTexts().at(3).toDouble(), regexp.capturedTexts().at(4).toDouble());
+            return true;
+        }
+    }
+
+    mViewBox = QRectF(0, 0, 1000, 1000);
+    return false;
+}
+
+QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator()
+{
+    QSvgGenerator* generator = new QSvgGenerator();
+    generator->setFileName(mTempFilePath);
+    generator->setSize(mSize);
+    generator->setViewBox(mViewBox);
+
+    return generator;
+}
+
+bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getTempFileName()
+{
+    int tmpNumber = 0;
+    QDir rootDir;
+    while (true)
+    {
+        mTempFilePath = QString("%1/sanksvg%2.%3")
+                .arg(rootDir.tempPath())
+                .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm"))
+                .arg(tmpNumber);
+        if (!QFile::exists(mTempFilePath))
+            return true;
+        tmpNumber++;
+        if (tmpNumber == 100000)
+        {
+            qWarning() << "Import failed. Failed to create temporary file for svg objects";
+            return false;
+        }
+    }
+
+}
diff --git a/src/adaptors/UBCFFSubsetAdaptor.h b/src/adaptors/UBCFFSubsetAdaptor.h
new file mode 100644
index 00000000..ac3d6142
--- /dev/null
+++ b/src/adaptors/UBCFFSubsetAdaptor.h
@@ -0,0 +1,86 @@
+#ifndef UBCFFSUBSETADAPTOR_H
+#define UBCFFSUBSETADAPTOR_H
+
+#include <QtXml>
+#include <QString>
+#include <QStack>
+
+class UBDocumentProxy;
+class UBGraphicsScene;
+class QSvgGenerator;
+
+class UBCFFSubsetAdaptor
+{
+public:
+    UBCFFSubsetAdaptor();
+
+    static bool ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentProxy* pDocument);
+
+private:
+    class UBCFFSubsetReader
+    {
+        //xml parse states definition
+        enum
+        {
+            NONE,
+            IWB,
+            SVG,
+            PAGESET,
+            PAGE,
+            TEXTAREA,
+            TSPAN
+        };
+
+    public:
+        UBCFFSubsetReader(UBDocumentProxy *proxy, QByteArray &content);
+
+        QXmlStreamReader mReader;
+        UBDocumentProxy *mProxy;
+
+        bool parse();
+
+    private:
+        QString mTempFilePath;
+        UBGraphicsScene *mCurrentScene;
+        QString mIndent;
+        QRectF mViewBox;
+        QSize mSize;
+
+        //methods to store current xml parse state
+        int PopState();
+        void PushState(int state);
+
+        //elements parsing methods
+        bool parseDoc();
+
+        bool parseCurrentElementStart();
+        bool parseCurrentElementCharacters();
+        bool parseCurrentElementEnd();
+
+        bool parseIwb();
+        bool parseIwbMeta();
+        bool parseSvg();
+        bool parseRect();
+        bool parseEllipse();
+        bool parseTextArea();
+        bool parsePolygon();
+        bool parsePage();
+        bool parsePageSet();
+        bool parseIwbElementRef();
+
+        bool createNewScene();
+        bool persistCurrentScene();
+
+        QStack<int> stateStack;
+        int currentState;
+
+        //helper methods
+        QColor colorFromString(const QString& clrString);
+        QTransform transformFromString(const QString trString);
+        bool getViewBoxDimenstions(const QString& viewBox);
+        QSvgGenerator* createSvgGenerator();
+        bool getTempFileName();
+    };
+};
+
+#endif // UBCFFSUBSETADAPTOR_H
diff --git a/src/adaptors/UBImportCFF.cpp b/src/adaptors/UBImportCFF.cpp
new file mode 100644
index 00000000..c79f316b
--- /dev/null
+++ b/src/adaptors/UBImportCFF.cpp
@@ -0,0 +1,306 @@
+#include <QDir>
+#include "UBImportCFF.h"
+#include "document/UBDocumentProxy.h"
+
+#include "core/UBApplication.h"
+#include "core/UBPersistenceManager.h"
+#include "core/UBDocumentManager.h"
+#include "core/memcheck.h"
+#include "core/UBPersistenceManager.h"
+
+#include "frameworks/UBFileSystemUtils.h"
+
+#include "domain/UBGraphicsPDFItem.h"
+
+#include "pdf/PDFRenderer.h"
+
+
+#include "UBCFFSubsetAdaptor.h"
+
+#include "quazip.h"
+#include "quazipfile.h"
+#include "quazipfileinfo.h"
+
+UBImportCFF::UBImportCFF(QObject *parent)
+    : UBImportAdaptor(parent)
+{
+    // NOOP
+}
+
+
+UBImportCFF::~UBImportCFF()
+{
+    // NOOP
+}
+
+
+QStringList UBImportCFF::supportedExtentions()
+{
+    return QStringList("iwb");
+}
+
+
+QString UBImportCFF::importFileFilter()
+{
+    QString filter = tr("Common File Format (");
+    QStringList formats = supportedExtentions();
+    bool isFirst = true;
+
+    foreach(QString format, formats)
+    {
+            if(isFirst)
+                    isFirst = false;
+            else
+                    filter.append(" ");
+
+        filter.append("*."+format);
+    }
+
+    filter.append(")");
+
+    return filter;
+}
+
+
+bool UBImportCFF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile)
+{
+    QFileInfo fi(pFile);
+    UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);
+
+    // first unzip the file to the correct place
+    //TODO create temporary path for iwb file content
+    QString path = QDir::tempPath();
+
+    QString documentRootFolder = expandFileToDir(pFile, path);
+        QString contentFile;
+    if (documentRootFolder.isEmpty()) //if file has failed to unzip it is probably just xml file
+        contentFile = pFile.fileName();
+    else //get path to content xml (according to iwbcff specification)
+        contentFile = documentRootFolder.append("/content.xml");
+
+    if(!contentFile.length()){
+            UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
+            return false;
+    }
+    else{
+        //TODO convert expanded CFF file content to the destination document
+        //create destination document proxy
+        //fill metadata and save
+        UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath());
+        QDir dir;
+        dir.mkdir(destDocument->persistencePath());
+
+        //try to import cff to document
+        if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument))
+        {
+            UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(destDocument->persistencePath(), pDocument);
+            UBFileSystemUtils::deleteDir(destDocument->persistencePath());
+            delete destDocument;
+            UBApplication::showMessage(tr("Import successful."));
+            return true;
+        }
+        else
+        {
+            UBFileSystemUtils::deleteDir(destDocument->persistencePath());
+            delete destDocument;
+            UBApplication::showMessage(tr("Import failed."));
+            return false;
+        }
+    }
+}
+
+QString UBImportCFF::expandFileToDir(const QFile& pZipFile, const QString& pDir)
+{
+    QuaZip zip(pZipFile.fileName());
+
+    if(!zip.open(QuaZip::mdUnzip))
+    {
+        qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError();
+        return "";
+    }
+
+    zip.setFileNameCodec("UTF-8");
+    QuaZipFileInfo info;
+    QuaZipFile file(&zip);
+
+    //create unique cff document root fodler
+    //use current date/time and temp number for folder name
+    QString documentRootFolder;
+    int tmpNumber = 0;
+    QDir rootDir;
+    while (true)
+    {
+        QString tempPath = QString("%1/sank%2.%3")
+                .arg(pDir)
+                .arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm"))
+                .arg(tmpNumber);
+        if (!rootDir.exists(tempPath))
+        {
+            documentRootFolder = tempPath;
+            break;
+        }
+        tmpNumber++;
+        if (tmpNumber == 100000)
+        {
+            qWarning() << "Import failed. Failed to create temporary directory for iwb file";
+            return "";
+        }
+    }
+
+    if (!rootDir.mkdir(documentRootFolder))
+    {
+        qWarning() << "Import failed. Couse: failed to create temp folder for cff package";
+    }
+
+    // first we search the metadata.rdf to check the document properties
+    for(bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
+    {
+        if(!zip.getCurrentFileInfo(&info))
+        {
+            qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
+            return "";
+        }
+
+        QFileInfo currentFileInfo(pDir + "/" + file.getActualFileName());
+    }
+
+
+    QFile out;
+    char c;
+    for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile())
+    {
+        if(!zip.getCurrentFileInfo(&info))
+        {
+            //TOD UB 4.3 O display error to user or use crash reporter
+            qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
+            return "";
+        }
+
+        if(!file.open(QIODevice::ReadOnly))
+        {
+            qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError();
+            return "";
+        }
+
+        if(file.getZipError()!= UNZ_OK)
+        {
+            qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError();
+            return "";
+        }
+
+        QString newFileName = documentRootFolder + "/" + file.getActualFileName();
+        QFileInfo newFileInfo(newFileName);
+        rootDir.mkpath(newFileInfo.absolutePath());
+
+        out.setFileName(newFileName);
+        out.open(QIODevice::WriteOnly);
+
+        // Slow like hell (on GNU/Linux at least), but it is not my fault.
+        // Not ZIP/UNZIP package's fault either.
+        // The slowest thing here is out.putChar(c).
+        QByteArray outFileContent = file.readAll();
+        if (out.write(outFileContent) == -1)
+        {
+            qWarning() << "Import failed. Cause: Unable to write file";
+            out.close();
+            return "";
+        }
+
+        while(file.getChar(&c))
+            out.putChar(c);
+
+        out.close();
+
+        if(file.getZipError()!=UNZ_OK)
+        {
+            qWarning() << "Import failed. Cause: " << zip.getZipError();
+            return "";
+        }
+
+        if(!file.atEnd())
+        {
+            qWarning() << "Import failed. Cause: read all but not EOF";
+            return "";
+        }
+
+        file.close();
+
+        if(file.getZipError()!=UNZ_OK)
+        {
+            qWarning() << "Import failed. Cause: file.close(): " <<  file.getZipError();
+            return "";
+        }
+
+    }
+
+    zip.close();
+
+    if(zip.getZipError()!=UNZ_OK)
+    {
+      qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError();
+      return "";
+    }
+
+
+    return documentRootFolder;
+}
+
+
+UBDocumentProxy* UBImportCFF::importFile(const QFile& pFile, const QString& pGroup)
+{
+    Q_UNUSED(pGroup); // group is defined in the imported file
+
+    QFileInfo fi(pFile);
+    UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);
+
+    // first unzip the file to the correct place
+    //TODO create temporary path for iwb file content
+    QString path = QDir::tempPath();
+
+    QString documentRootFolder = expandFileToDir(pFile, path);
+    QString contentFile;
+    if (documentRootFolder.isEmpty())
+        //if file has failed to umzip it is probably just xml file
+        contentFile = pFile.fileName();
+    else
+        //get path to content xml
+        contentFile = QString("%1/content.xml").arg(documentRootFolder);
+
+    if(!contentFile.length()){
+            UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
+            return 0;
+    }
+    else{
+        //create destination document proxy
+        //fill metadata and save
+        UBDocumentProxy* destDocument = new UBDocumentProxy(UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath());
+        QDir dir;
+        dir.mkdir(destDocument->persistencePath());
+        if (pGroup.length() > 0)
+            destDocument->setMetaData(UBSettings::documentGroupName, pGroup);
+        if (fi.baseName() > 0)
+            destDocument->setMetaData(UBSettings::documentName, fi.baseName());
+
+        destDocument->setMetaData(UBSettings::documentVersion, UBSettings::currentFileVersion);
+        destDocument->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime()));
+
+        UBDocumentProxy* newDocument = NULL;
+        //try to import cff to document
+        if (UBCFFSubsetAdaptor::ConvertCFFFileToUbz(contentFile, destDocument))
+        {
+            newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(destDocument->persistencePath());
+            UBApplication::showMessage(tr("Import successful."));
+        }
+        else
+        {
+            UBFileSystemUtils::deleteDir(destDocument->persistencePath());
+            UBApplication::showMessage(tr("Import failed."));
+        }
+        delete destDocument;
+
+        if (documentRootFolder.length() != 0)
+            UBFileSystemUtils::deleteDir(documentRootFolder);
+        return newDocument;
+    }
+}
+
diff --git a/src/adaptors/UBImportCFF.h b/src/adaptors/UBImportCFF.h
new file mode 100644
index 00000000..a7de5414
--- /dev/null
+++ b/src/adaptors/UBImportCFF.h
@@ -0,0 +1,30 @@
+#ifndef UBIMPORTCFF_H
+#define UBIMPORTCFF_H
+
+#include <QtGui>
+#include "UBImportAdaptor.h"
+
+class UBDocumentProxy;
+
+class UBImportCFF : public UBImportAdaptor
+{
+    Q_OBJECT;
+
+    public:
+        UBImportCFF(QObject *parent = 0);
+        virtual ~UBImportCFF();
+
+        virtual QStringList supportedExtentions();
+        virtual QString importFileFilter();
+
+        virtual bool addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile);
+
+        //base class method override
+        virtual UBDocumentProxy* importFile(const QFile& pFile, const QString& pGroup);
+
+    private:
+
+        virtual QString expandFileToDir(const QFile& pZipFile, const QString& pDir);
+};
+
+#endif // UBIMPORTCFF_H
diff --git a/src/adaptors/adaptors.pri b/src/adaptors/adaptors.pri
index 8404364d..7dd7104e 100644
--- a/src/adaptors/adaptors.pri
+++ b/src/adaptors/adaptors.pri
@@ -1,55 +1,59 @@
-
-HEADERS      += src/adaptors/UBExportAdaptor.h\
-                src/adaptors/UBExportPDF.h \
-                src/adaptors/UBExportFullPDF.h \
-                src/adaptors/UBExportDocument.h \
-                src/adaptors/UBSvgSubsetAdaptor.h \
-                src/adaptors/UBMetadataDcSubsetAdaptor.h \
-                src/adaptors/UBImportAdaptor.h \
-                src/adaptors/UBImportDocument.h \
-                src/adaptors/UBThumbnailAdaptor.h \
-                src/adaptors/UBImportPDF.h \
-                src/adaptors/UBImportImage.h \
-                src/adaptors/UBIniFileParser.h \
-                src/adaptors/UBExportWeb.h \
-                src/adaptors/UBWebPublisher.h
-
-HEADERS      += src/adaptors/publishing/UBDocumentPublisher.h \
-                src/adaptors/publishing/UBCapturePublisher.h \
-                src/adaptors/publishing/UBAbstractPublisher.h \
-                src/adaptors/publishing/UBSvgSubsetRasterizer.h
-               
-HEADERS      += src/adaptors/voting/UBAbstractVotingSystem.h
-
-
-SOURCES      += src/adaptors/UBExportAdaptor.cpp\
-                src/adaptors/UBExportPDF.cpp \
-                src/adaptors/UBExportFullPDF.cpp \
-                src/adaptors/UBExportDocument.cpp \
-                src/adaptors/UBSvgSubsetAdaptor.cpp \
-                src/adaptors/UBMetadataDcSubsetAdaptor.cpp \
-                src/adaptors/UBImportAdaptor.cpp \
-                src/adaptors/UBImportDocument.cpp \
-                src/adaptors/UBThumbnailAdaptor.cpp \
-                src/adaptors/UBImportPDF.cpp \
-                src/adaptors/UBImportImage.cpp \
-                src/adaptors/UBIniFileParser.cpp \
-                src/adaptors/UBExportWeb.cpp \
-                src/adaptors/UBWebPublisher.cpp
-
-SOURCES      += src/adaptors/publishing/UBDocumentPublisher.cpp \
-                src/adaptors/publishing/UBCapturePublisher.cpp \
-                src/adaptors/publishing/UBAbstractPublisher.cpp \
-                src/adaptors/publishing/UBSvgSubsetRasterizer.cpp
-                
-SOURCES      += src/adaptors/voting/UBAbstractVotingSystem.cpp   
-
-
-win32 {
-
-    SOURCES  += src/adaptors/voting/UBReply2005VotingSystem.cpp \
-                src/adaptors/voting/UBReplyWRS970VotingSystem.cpp
-
-    HEADERS  += src/adaptors/voting/UBReply2005VotingSystem.h \
-                src/adaptors/voting/UBReplyWRS970VotingSystem.h
-}            
+
+HEADERS      += src/adaptors/UBExportAdaptor.h\
+                src/adaptors/UBExportPDF.h \
+                src/adaptors/UBExportFullPDF.h \
+                src/adaptors/UBExportDocument.h \
+                src/adaptors/UBSvgSubsetAdaptor.h \
+                src/adaptors/UBMetadataDcSubsetAdaptor.h \
+                src/adaptors/UBImportAdaptor.h \
+                src/adaptors/UBImportDocument.h \
+                src/adaptors/UBThumbnailAdaptor.h \
+                src/adaptors/UBImportPDF.h \
+                src/adaptors/UBImportImage.h \
+                src/adaptors/UBIniFileParser.h \
+                src/adaptors/UBExportWeb.h \
+                src/adaptors/UBWebPublisher.h \
+                src/adaptors/UBImportCFF.h \
+                src/adaptors/UBCFFSubsetAdaptor.h
+
+HEADERS      += src/adaptors/publishing/UBDocumentPublisher.h \
+                src/adaptors/publishing/UBCapturePublisher.h \
+                src/adaptors/publishing/UBAbstractPublisher.h \
+                src/adaptors/publishing/UBSvgSubsetRasterizer.h
+               
+HEADERS      += src/adaptors/voting/UBAbstractVotingSystem.h
+
+
+SOURCES      += src/adaptors/UBExportAdaptor.cpp\
+                src/adaptors/UBExportPDF.cpp \
+                src/adaptors/UBExportFullPDF.cpp \
+                src/adaptors/UBExportDocument.cpp \
+                src/adaptors/UBSvgSubsetAdaptor.cpp \
+                src/adaptors/UBMetadataDcSubsetAdaptor.cpp \
+                src/adaptors/UBImportAdaptor.cpp \
+                src/adaptors/UBImportDocument.cpp \
+                src/adaptors/UBThumbnailAdaptor.cpp \
+                src/adaptors/UBImportPDF.cpp \
+                src/adaptors/UBImportImage.cpp \
+                src/adaptors/UBIniFileParser.cpp \
+                src/adaptors/UBExportWeb.cpp \
+                src/adaptors/UBWebPublisher.cpp \
+                src/adaptors/UBImportCFF.cpp \
+                src/adaptors/UBCFFSubsetAdaptor.cpp
+
+SOURCES      += src/adaptors/publishing/UBDocumentPublisher.cpp \
+                src/adaptors/publishing/UBCapturePublisher.cpp \
+                src/adaptors/publishing/UBAbstractPublisher.cpp \
+                src/adaptors/publishing/UBSvgSubsetRasterizer.cpp
+                
+SOURCES      += src/adaptors/voting/UBAbstractVotingSystem.cpp   
+
+
+win32 {
+
+    SOURCES  += src/adaptors/voting/UBReply2005VotingSystem.cpp \
+                src/adaptors/voting/UBReplyWRS970VotingSystem.cpp
+
+    HEADERS  += src/adaptors/voting/UBReply2005VotingSystem.h \
+                src/adaptors/voting/UBReplyWRS970VotingSystem.h
+}            
diff --git a/src/core/UBApplication.cpp b/src/core/UBApplication.cpp
index bddfc5c3..b1942ce1 100644
--- a/src/core/UBApplication.cpp
+++ b/src/core/UBApplication.cpp
@@ -268,11 +268,6 @@ int UBApplication::exec(const QString& pFileToImport)
     connect(mainWindow->actionCopy, SIGNAL(triggered()), applicationController, SLOT(actionCopy()));
     connect(mainWindow->actionPaste, SIGNAL(triggered()), applicationController, SLOT(actionPaste()));
 
-//#ifndef __ppc__
-//    // this cause a problem on MACX/PPC (see https://trac.assembla.com/uniboard/ticket/862)
-//    installEventFilter(new UBIdleTimer(this));
-//#endif
-
     applicationController->initScreenLayout();
     boardController->setupLayout();
 
diff --git a/src/core/UBDocumentManager.cpp b/src/core/UBDocumentManager.cpp
index 2ae42abd..331c2475 100644
--- a/src/core/UBDocumentManager.cpp
+++ b/src/core/UBDocumentManager.cpp
@@ -25,6 +25,7 @@
 #include "adaptors/UBImportDocument.h"
 #include "adaptors/UBImportPDF.h"
 #include "adaptors/UBImportImage.h"
+#include "adaptors/UBImportCFF.h"
 
 #include "domain/UBGraphicsScene.h"
 #include "domain/UBGraphicsSvgItem.h"
@@ -75,6 +76,8 @@ UBDocumentManager::UBDocumentManager(QObject *parent)
     mImportAdaptors.append(pdfImport);
     UBImportImage* imageImport = new UBImportImage(this);
     mImportAdaptors.append(imageImport);
+    UBImportCFF* cffImport = new UBImportCFF(this);
+    mImportAdaptors.append(cffImport);
 }
 
 
diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp
index 867f3064..e84c6031 100644
--- a/src/core/UBPreferencesController.cpp
+++ b/src/core/UBPreferencesController.cpp
@@ -65,7 +65,6 @@ UBPreferencesController::UBPreferencesController(QWidget *parent)
     , mMarkerProperties(0)
 {
     mPreferencesWindow = new UBPreferencesDialog(this,parent, Qt::Dialog);
-    //    mPreferencesWindow = new QDialog(parent, Qt::Dialog);
     mPreferencesUI = new Ui::preferencesDialog();  // deleted in
     mPreferencesUI->setupUi(mPreferencesWindow);
     connect(mPreferencesUI->Username_textBox, SIGNAL(editingFinished()), this, SLOT(onCommunityUsernameChanged()));