diff --git a/common.pri b/common.pri
index 121fc2f..6154dbc 100644
--- a/common.pri
+++ b/common.pri
@@ -1,6 +1,6 @@
 CONFIG += build_translations
 CONFIG += zint
-
+CONFIG += qjsengine
 greaterThan(QT_MAJOR_VERSION, 4) {
     QT += uitools
 }
@@ -68,11 +68,15 @@ TRANSLATIONS_PATH = $$PWD/translations
 
 greaterThan(QT_MAJOR_VERSION, 4) {
     DEFINES+=HAVE_QT5
-    QT+= printsupport widgets
+    QT+= printsupport widgets qml
     contains(QT,uitools){
         message(uitools)
         DEFINES += HAVE_UI_LOADER
     }
+    contains(CONFIG, qjsengine){
+        message(qjsengine)
+        DEFINES += USE_QJSENGINE
+    }
 }
 
 lessThan(QT_MAJOR_VERSION, 5){
diff --git a/demo_r1/mainwindow.cpp b/demo_r1/mainwindow.cpp
index d695a4e..c459715 100644
--- a/demo_r1/mainwindow.cpp
+++ b/demo_r1/mainwindow.cpp
@@ -95,8 +95,8 @@ MainWindow::MainWindow(QWidget *parent) :
     report->dataManager()->addModel("string_list",stringListModel,true);
     QStringList strList;
     strList<<"value1"<<"value2";
-    QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList);
-    report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value);
+    //QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList);
+    //report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value);
 
 
 }
diff --git a/include/lrglobal.h b/include/lrglobal.h
index 3b8aa7d..421f8d7 100644
--- a/include/lrglobal.h
+++ b/include/lrglobal.h
@@ -42,6 +42,13 @@
 #  define LIMEREPORT_EXPORT   /**/
 #endif
 
+#ifdef USE_QJSENGINE
+//#include <QJSEngine>
+#include <QQmlEngine>
+#else
+#include <QScriptEngine>
+#endif
+
 namespace LimeReport {
 
 #ifdef __GNUC__
@@ -91,6 +98,7 @@ namespace Const{
     const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
     const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
     const int SCENE_MARGIN = 50;
+    const QString FUNCTION_MANAGER_NAME = "LimeReport";
 }
     QString extractClassName(QString className);
     QString escapeSimbols(const QString& value);
@@ -130,6 +138,20 @@ namespace Const{
     typedef QStyleOptionViewItem StyleOptionViewItem;
 #endif
 
+#ifdef USE_QJSENGINE
+    typedef QQmlEngine ScriptEngineType;
+    typedef QJSValue ScriptValueType;
+    template <typename T>
+    static inline QJSValue getCppOwnedJSValue(QJSEngine &e, T *p)
+    {
+        QJSValue res = e.newQObject(p);
+        QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership);
+        return res;
+    }
+#else
+    typedef QScriptEngine ScriptEngineType;
+    typedef QScriptValue ScriptValueType;
+#endif
 
 } // namespace LimeReport
 
diff --git a/include/lrreportengine.h b/include/lrreportengine.h
index dbbb2a8..9bd87b5 100644
--- a/include/lrreportengine.h
+++ b/include/lrreportengine.h
@@ -33,6 +33,7 @@
 #include <QObject>
 #include <QSettings>
 #include <QPrintDialog>
+//#include <QJSEngine>
 
 #include "lrglobal.h"
 #include "lrdatasourcemanagerintf.h"
diff --git a/include/lrscriptenginemanagerintf.h b/include/lrscriptenginemanagerintf.h
index d7662ff..4c2767a 100644
--- a/include/lrscriptenginemanagerintf.h
+++ b/include/lrscriptenginemanagerintf.h
@@ -30,15 +30,19 @@
 #ifndef LRSCRIPTENGINEMANAGERINTF_H
 #define LRSCRIPTENGINEMANAGERINTF_H
 
-#include <QtScript/QScriptEngine>
+//#include <QJSEngine>
+#include "lrglobal.h"
 
 namespace LimeReport{
 
+
 class IScriptEngineManager{
 public:
-    virtual QScriptEngine* scriptEngine() = 0;
-    virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function,
+    virtual ScriptEngineType* scriptEngine() = 0;
+#ifndef USE_QJSENGINE
+    virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function,
                              const QString& category="", const QString& description="") = 0;
+#endif
     virtual bool addFunction(const QString &name, const QString& script,
                              const QString &category="", const QString &description="") = 0;
     virtual const QString& lastError() const = 0;
@@ -46,4 +50,5 @@ public:
 };
 
 } //namespace LimeReport
+
 #endif // LRSCRIPTENGINEMANAGERINTF_H
diff --git a/limereport/items/lrtextitemeditor.cpp b/limereport/items/lrtextitemeditor.cpp
index e2b6778..cba99ff 100644
--- a/limereport/items/lrtextitemeditor.cpp
+++ b/limereport/items/lrtextitemeditor.cpp
@@ -133,7 +133,7 @@ void TextItemEditor::initUI()
         ui->tabWidget->setVisible(false);
     }
 
-    foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescriber()) {
+    foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescribers()) {
         dataWords<<functionDesc.name;
     }
 
diff --git a/limereport/lrglobal.h b/limereport/lrglobal.h
index 3b8aa7d..421f8d7 100644
--- a/limereport/lrglobal.h
+++ b/limereport/lrglobal.h
@@ -42,6 +42,13 @@
 #  define LIMEREPORT_EXPORT   /**/
 #endif
 
+#ifdef USE_QJSENGINE
+//#include <QJSEngine>
+#include <QQmlEngine>
+#else
+#include <QScriptEngine>
+#endif
+
 namespace LimeReport {
 
 #ifdef __GNUC__
@@ -91,6 +98,7 @@ namespace Const{
     const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
     const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
     const int SCENE_MARGIN = 50;
+    const QString FUNCTION_MANAGER_NAME = "LimeReport";
 }
     QString extractClassName(QString className);
     QString escapeSimbols(const QString& value);
@@ -130,6 +138,20 @@ namespace Const{
     typedef QStyleOptionViewItem StyleOptionViewItem;
 #endif
 
+#ifdef USE_QJSENGINE
+    typedef QQmlEngine ScriptEngineType;
+    typedef QJSValue ScriptValueType;
+    template <typename T>
+    static inline QJSValue getCppOwnedJSValue(QJSEngine &e, T *p)
+    {
+        QJSValue res = e.newQObject(p);
+        QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership);
+        return res;
+    }
+#else
+    typedef QScriptEngine ScriptEngineType;
+    typedef QScriptValue ScriptValueType;
+#endif
 
 } // namespace LimeReport
 
diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp
index fb7ee7c..d4b4fa2 100644
--- a/limereport/lrreportengine.cpp
+++ b/limereport/lrreportengine.cpp
@@ -874,7 +874,7 @@ IDataSourceManager *ReportEngine::dataManager()
     return d->dataManagerIntf();
 }
 
-IScriptEngineManager* ReportEngine::scriptManager()
+IScriptEngineManager *ReportEngine::scriptManager()
 {
     Q_D(ReportEngine);
     return d->scriptManagerIntf();
diff --git a/limereport/lrreportengine.h b/limereport/lrreportengine.h
index dbbb2a8..9bd87b5 100644
--- a/limereport/lrreportengine.h
+++ b/limereport/lrreportengine.h
@@ -33,6 +33,7 @@
 #include <QObject>
 #include <QSettings>
 #include <QPrintDialog>
+//#include <QJSEngine>
 
 #include "lrglobal.h"
 #include "lrdatasourcemanagerintf.h"
diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp
index 11c3ae0..4092f82 100644
--- a/limereport/lrreportrender.cpp
+++ b/limereport/lrreportrender.cpp
@@ -167,17 +167,29 @@ void ReportRender::setScriptContext(ScriptEngineContext* scriptContext)
 
 bool ReportRender::runInitScript(){
     if (m_scriptEngineContext){
-        QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine();
+        ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
+#ifndef USE_QJSENGINE
         engine->pushContext();
-        QScriptValue res = engine->evaluate(m_scriptEngineContext->initScript());
+#endif
+        ScriptValueType res = engine->evaluate(m_scriptEngineContext->initScript());
         if (res.isBool()) return res.toBool();
+#ifdef  USE_QJSENGINE
+        if (res.isError()){
+            QMessageBox::critical(0,tr("Error"),
+                QString("Line %1: %2 ").arg(res.property("lineNumber").toString())
+                                       .arg(res.toString())
+            );
+            return false;
+        }
+#else
         if (engine->hasUncaughtException()) {
             QMessageBox::critical(0,tr("Error"),
                 QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber())
                                        .arg(engine->uncaughtException().toString())
             );
             return false;
-        }
+        }    
+#endif
     }
     return true;
 }
@@ -269,8 +281,9 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
             renderBand(tearOffBand, 0, StartNewPageAsNeeded);
 
         savePage(true);
-
+#ifndef USE_QJSENGINE
         ScriptEngineManager::instance().scriptEngine()->popContext();
+#endif
     }
 }
 
@@ -314,11 +327,24 @@ void ReportRender::initVariables()
 }
 
 #ifdef HAVE_UI_LOADER
+
+#ifdef USE_QJSENGINE
+void registerChildObjects(ScriptEngineType* se, ScriptValueType* sv){
+    foreach(QObject* obj, sv->toQObject()->children()){
+        ScriptValueType child = se->newQObject(obj);
+        sv->setProperty(obj->objectName(),child);
+        registerChildObjects(se, &child);
+    }
+}
+#endif
 void ReportRender::initDialogs(){
     if (m_scriptEngineContext){
-        QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
+        ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
         foreach(DialogDescriber::Ptr dialog, m_scriptEngineContext->dialogsDescriber()){
-            QScriptValue sv = se->newQObject(m_scriptEngineContext->getDialog(dialog->name()));
+            ScriptValueType sv = se->newQObject(m_scriptEngineContext->getDialog(dialog->name()));
+#ifdef USE_QJSENGINE
+            registerChildObjects(se,&sv);
+#endif
             se->globalObject().setProperty(dialog->name(),sv);
         }
     }
@@ -1249,18 +1275,26 @@ void ReportRender::baseDesignIntfToScript(BaseDesignIntf *item)
         if (item->metaObject()->indexOfSignal("afterRender()")!=-1)
             item->disconnect(SIGNAL(afterRender()));
 
-        QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine();
-        QScriptValue sItem = engine->globalObject().property(item->patternName());
+        ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
+
+#ifdef USE_QJSENGINE
+        //sItem = engine->newQObject(item);
+        ScriptValueType sItem = getCppOwnedJSValue(*engine, item);
+        engine->globalObject().setProperty(item->patternName(), sItem);
+#else
+        ScriptValueType sItem = engine->globalObject().property(item->patternName());
         if (sItem.isValid()){
             engine->newQObject(sItem, item);
         } else {
             sItem = engine->newQObject(item);
             engine->globalObject().setProperty(item->patternName(),sItem);
         }
+#endif
         foreach(BaseDesignIntf* child, item->childBaseItems()){
             baseDesignIntfToScript(child);
         }
     }
+
 }
 
 }
diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp
index f69283b..dab7272 100644
--- a/limereport/lrscriptenginemanager.cpp
+++ b/limereport/lrscriptenginemanager.cpp
@@ -181,7 +181,7 @@ void ScriptEngineModel::updateModel()
     beginResetModel();
     m_rootNode->clear();
     QMap<QString,ScriptEngineNode*> categories;
-    foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescriber()){
+    foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescribers()){
         ScriptEngineNode* categ;
         QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY";
         if (categories.contains(categoryName)){
@@ -196,141 +196,141 @@ void ScriptEngineModel::updateModel()
     endResetModel();
 }
 
-QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){    
-    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
-    DataSourceManager* dm = sm->dataManager();
-    QString band = pcontext->argument(0).toString();
-    QScriptValue res;
-    QString varName = QLatin1String("line_")+band.toLower();
-    if (dm->variable(varName).isValid()){
-        res=pengine->newVariant(dm->variable(varName));
-    } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band));
-    return res;
-}
+//QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){
+//    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
+//    DataSourceManager* dm = sm->dataManager();
+//    QString band = pcontext->argument(0).toString();
+//    QScriptValue res;
+//    QString varName = QLatin1String("line_")+band.toLower();
+//    if (dm->variable(varName).isValid()){
+//        res=pengine->newVariant(dm->variable(varName));
+//    } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band));
+//    return res;
+//}
 
-QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){
+//QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){
 
-    QString name = pcontext->argument(0).toString();
-    QVariant value = pcontext->argument(1).toVariant();
+//    QString name = pcontext->argument(0).toString();
+//    QVariant value = pcontext->argument(1).toVariant();
 
-    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
-    DataSourceManager* dm = sm->dataManager();
+//    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
+//    DataSourceManager* dm = sm->dataManager();
 
-    dm->changeVariable(name,value);
-    return QScriptValue();
-}
+//    dm->changeVariable(name,value);
+//    return QScriptValue();
+//}
 
-QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){
+//QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){
 
-    QString name = pcontext->argument(0).toString();
+//    QString name = pcontext->argument(0).toString();
 
-    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
-    DataSourceManager* dm = sm->dataManager();
-    QScriptValue res = pengine->newVariant(dm->variable(name));
+//    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
+//    DataSourceManager* dm = sm->dataManager();
+//    QScriptValue res = pengine->newVariant(dm->variable(name));
 
-    return res;
-}
+//    return res;
+//}
 
-QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){
+//QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){
 
-    QString name = pcontext->argument(0).toString();
+//    QString name = pcontext->argument(0).toString();
 
-    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
-    DataSourceManager* dm = sm->dataManager();
-    QScriptValue res = pengine->newVariant(dm->fieldData(name));
+//    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
+//    DataSourceManager* dm = sm->dataManager();
+//    QScriptValue res = pengine->newVariant(dm->fieldData(name));
 
-    return res;
-}
+//    return res;
+//}
 
-QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f';
-    int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2;
-    QString locale = (pcontext->argumentCount()>3)?pcontext->argument(3).toString():"";
-    QScriptValue res = (locale.isEmpty())?pengine->newVariant(QString::number(value.toDouble(),format,precision)):
-                                          pengine->newVariant(QLocale(locale).toString(value.toDouble(),format,precision));
-    return res;
-}
-#if QT_VERSION>0x040800
-QScriptValue currencyFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    QString locale = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().name();
-    return pengine->newVariant(QLocale(locale).toCurrencyString(value.toDouble()));
-}
+//QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f';
+//    int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2;
+//    QString locale = (pcontext->argumentCount()>3)?pcontext->argument(3).toString():"";
+//    QScriptValue res = (locale.isEmpty())?pengine->newVariant(QString::number(value.toDouble(),format,precision)):
+//                                          pengine->newVariant(QLocale(locale).toString(value.toDouble(),format,precision));
+//    return res;
+//}
+//#if QT_VERSION>0x040800
+//QScriptValue currencyFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    QString locale = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().name();
+//    return pengine->newVariant(QLocale(locale).toCurrencyString(value.toDouble()));
+//}
 
-QScriptValue currencyUSBasedFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    QString CurrencySymbol = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().currencySymbol();
-    // Format it using USA locale
-    QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble());
-    // Replace currency symbol if necesarry
-    if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol);
-    return pengine->newVariant(vTempStr);
-}
-#endif
-QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy";
-    QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format));
-    return res;
-}
+//QScriptValue currencyUSBasedFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    QString CurrencySymbol = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().currencySymbol();
+//    // Format it using USA locale
+//    QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble());
+//    // Replace currency symbol if necesarry
+//    if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol);
+//    return pengine->newVariant(vTempStr);
+//}
+//#endif
+//QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy";
+//    QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format));
+//    return res;
+//}
 
-QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm";
-    QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format));
-    return res;
-}
+//QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm";
+//    QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format));
+//    return res;
+//}
 
-QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){
-    QVariant value = pcontext->argument(0).toVariant();
-    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm";
-    QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format));
-    return res;
-}
+//QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){
+//    QVariant value = pcontext->argument(0).toVariant();
+//    QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm";
+//    QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format));
+//    return res;
+//}
 
-QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){
-    return pengine->newVariant(QDateTime::currentDateTime());
-}
+//QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){
+//    return pengine->newVariant(QDateTime::currentDateTime());
+//}
 
-QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){
-    return pengine->newVariant(QDate::currentDate());
-}
+//QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){
+//    return pengine->newVariant(QDate::currentDate());
+//}
 
-QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){
+//QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){
 
-    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
-    DataSourceManager* dm = sm->dataManager();
+//    ScriptEngineManager* sm = qscriptvalue_cast<ScriptEngineManager*>(pcontext->callee().data());
+//    DataSourceManager* dm = sm->dataManager();
 
-    QString expression;
-    QString band;
+//    QString expression;
+//    QString band;
 
-    if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){
-        expression = " ";
-        band = pcontext->argument(0).toString();
-    } else {
-        expression = dm->getExpression(pcontext->argument(0).toString());
-        band = pcontext->argument(1).toString();
-    }
+//    if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){
+//        expression = " ";
+//        band = pcontext->argument(0).toString();
+//    } else {
+//        expression = dm->getExpression(pcontext->argument(0).toString());
+//        band = pcontext->argument(1).toString();
+//    }
 
-    QScriptValue res;
-    GroupFunction* gf = dm->groupFunction(functionName,expression,band);
-    if (gf){
-        if (gf->isValid()){
-            res=pengine->newVariant(gf->calculate());
-        }else{
-            res=pengine->newVariant(gf->error());
-        }
-    }
-    else {
-        res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName)));
-    }
-    return res;
-}
+//    QScriptValue res;
+//    GroupFunction* gf = dm->groupFunction(functionName,expression,band);
+//    if (gf){
+//        if (gf->isValid()){
+//            res=pengine->newVariant(gf->calculate());
+//        }else{
+//            res=pengine->newVariant(gf->error());
+//        }
+//    }
+//    else {
+//        res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName)));
+//    }
+//    return res;
+//}
 
-QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){
-    return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine);
-}
+//QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){
+//    return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine);
+//}
 
 ScriptEngineManager::~ScriptEngineManager()
 {
@@ -359,6 +359,44 @@ void ScriptEngineManager::deleteFunction(const QString &functionsName)
     }
 }
 
+bool ScriptEngineManager::addFunction(const JSFunctionDesc &functionDescriber)
+{
+    ScriptValueType functionManager = scriptEngine()->globalObject().property(functionDescriber.managerName());
+#ifdef USE_QJSENGINE
+    if (functionManager.isUndefined()){
+#else
+    if (!functionManager.isValid()){
+#endif
+        functionManager = scriptEngine()->newQObject(functionDescriber.manager());
+        scriptEngine()->globalObject().setProperty(
+                    functionDescriber.managerName(),
+                    functionManager
+        );
+    }
+
+    if (functionManager.toQObject() == functionDescriber.manager()){
+        ScriptValueType checkWrapper = scriptEngine()->evaluate(functionDescriber.scriptWrapper());
+        if (!checkWrapper.isError()){
+            ScriptFunctionDesc funct;
+            funct.name = functionDescriber.name();
+            funct.description = functionDescriber.description();
+            funct.category = functionDescriber.category();
+            funct.type = ScriptFunctionDesc::Native;
+            m_functions.append(funct);
+            if (m_model)
+                m_model->updateModel();
+            return true;
+        } else {
+            m_lastError = checkWrapper.toString();
+            return false;
+        }
+    } else {
+        m_lastError = tr("Function manger with name \"%1\" already exists !");
+        return false;
+    }
+
+}
+
 bool ScriptEngineManager::containsFunction(const QString& functionName){
     foreach (ScriptFunctionDesc funct, m_functions) {
         if (funct.name.compare(functionName)== 0){
@@ -368,7 +406,8 @@ bool ScriptEngineManager::containsFunction(const QString& functionName){
     return false;
 }
 
-bool ScriptEngineManager::addFunction(const QString& name,
+#ifndef USE_QJSENGINE
+Q_DECL_DEPRECATED bool ScriptEngineManager::addFunction(const QString& name,
                                               QScriptEngine::FunctionSignature function,
                                               const QString& category,
                                               const QString& description)
@@ -391,23 +430,23 @@ bool ScriptEngineManager::addFunction(const QString& name,
         return false;
     }
 }
+#endif
 
 bool ScriptEngineManager::addFunction(const QString& name, const QString& script, const QString& category, const QString& description)
 {
-    QScriptSyntaxCheckResult cr = m_scriptEngine->checkSyntax(script);
-    if (cr.state() == QScriptSyntaxCheckResult::Valid){
+    ScriptValueType functionValue = m_scriptEngine->evaluate(script);
+    if (!functionValue.isError()){
         ScriptFunctionDesc funct;
-        funct.scriptValue = m_scriptEngine->evaluate(script);
+        funct.scriptValue = functionValue;
         funct.name =  name;
         funct.category = category;
         funct.description = description;
         funct.type = ScriptFunctionDesc::Script;
-        funct.scriptValue.setData(m_scriptEngine->toScriptValue(this));
         m_functions.append(funct);
         m_model->updateModel();        
         return true;
     } else {
-        m_lastError = cr.errorMessage();
+        m_lastError = functionValue.toString();
         return false;
     }
 }
@@ -426,12 +465,19 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
         m_dataManager =  dataManager;
         if (m_dataManager){
             foreach(QString func, m_dataManager->groupFunctionNames()){
-                if (isFunctionExists(func)) deleteFunction(func);
-                addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("Value")+"\",\""+tr("BandName")+"\")");
-            }
-            foreach(ScriptFunctionDesc func, m_functions){
-                if (func.type==ScriptFunctionDesc::Native)
-                    m_scriptEngine->globalObject().setProperty(func.name,func.scriptValue);
+                JSFunctionDesc describer(
+                    func,
+                    "GROUP FUNCTIONS",
+                    func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")",
+                    LimeReport::Const::FUNCTION_MANAGER_NAME,
+                    m_functionManager,
+                    QString("function %1(fieldName,bandName){\
+                            return %2.calcGroupFunction(\"%1\",fieldName,bandName);}"
+                    ).arg(func)
+                     .arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                );
+                addFunction(describer);
+
             }
         }
     }
@@ -543,16 +589,24 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue,
         if (ScriptEngineManager::instance().dataManager()!=dataManager())
             ScriptEngineManager::instance().setDataManager(dataManager());
 
-        QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
+        ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
 
         if (reportItem){
-            QScriptValue svThis =  se->globalObject().property("THIS");
+
+            ScriptValueType svThis;
+
+#ifdef USE_QJSENGINE
+            svThis = getCppOwnedJSValue(*se, reportItem);
+            se->globalObject().setProperty("THIS",svThis);
+#else
+            svThis = se->globalObject().property("THIS");
             if (svThis.isValid()){
-                se->newQObject(svThis, this);
+                se->newQObject(svThis, reportItem);
             } else {
-                svThis = se->newQObject(this);
+                svThis = se->newQObject(reportItem);
                 se->globalObject().setProperty("THIS",svThis);
             }
+#endif
         }
 
         ScriptExtractor scriptExtractor(context);
@@ -560,16 +614,26 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue,
             for(int i=0; i<scriptExtractor.count();++i){
                 QString scriptBody = expandDataFields(scriptExtractor.bodyAt(i),EscapeSymbols, varValue, reportItem);
                 scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
-                QScriptValue value = se->evaluate(scriptBody);
+                ScriptValueType value = se->evaluate(scriptBody);
+#ifdef USE_QJSENGINE
+                if (!value.isError()){
+                    varValue = value.toVariant();
+                    context.replace(scriptExtractor.scriptAt(i),value.toString());
+                } else {
+                    context.replace(scriptExtractor.scriptAt(i),value.toString());
+                }
+#else
                 if (!se->hasUncaughtException()) {
                     varValue = value.toVariant();
                     context.replace(scriptExtractor.scriptAt(i),value.toString());
                 } else {
                     context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString());
                 }
+#endif
             }
         }
     }
+
     return context;
 }
 
@@ -583,14 +647,18 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){
         if (ScriptEngineManager::instance().dataManager()!=dataManager())
             ScriptEngineManager::instance().setDataManager(dataManager());
 
-        QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
+        ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
 
         ScriptExtractor scriptExtractor(script);
         if (scriptExtractor.parse()){
             QString scriptBody = expandDataFields(scriptExtractor.bodyAt(0),EscapeSymbols, varValue, 0);
             scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
-            QScriptValue value = se->evaluate(scriptBody);
+            ScriptValueType value = se->evaluate(scriptBody);
+#ifdef USE_QJSENGINE
+            if (!value.isError()){
+#else
             if (!se->hasUncaughtException()) {
+#endif
                 return value.toVariant();
             }
         }
@@ -603,29 +671,243 @@ void ScriptEngineManager::updateModel()
 
 }
 
+bool ScriptEngineManager::createLineFunction()
+{
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("SYSTEM");
+    fd.setName("line");
+    fd.setDescription("line(\""+tr("BandName")+"\")");
+    fd.setScriptWrapper(QString("function line(bandName){ return %1.line(bandName);}").arg(LimeReport::Const::FUNCTION_MANAGER_NAME));
+
+    return addFunction(fd);
+
+}
+
+bool ScriptEngineManager::createNumberFomatFunction()
+{
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("NUMBER");
+    fd.setName("numberFormat");
+    fd.setDescription("numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+
+                      tr("Precision")+"\",\""+
+                      tr("Locale")+"\")"
+                      );
+    fd.setScriptWrapper(QString("function numberFormat(value, format, precision, locale){"
+                                " if(typeof(format)==='undefined') format = \"f\"; "
+                                " if(typeof(precision)==='undefined') precision=2; "
+                                " if(typeof(locale)==='undefined') locale=\"\"; "
+                                "return %1.numberFormat(value,format,precision,locale);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createDateFormatFunction(){
+//    addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("DATE&TIME");
+    fd.setName("dateFormat");
+    fd.setDescription("dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    fd.setScriptWrapper(QString("function dateFormat(value, format){"
+                                " if(typeof(format)==='undefined') format = \"dd.MM.yyyy\"; "
+                                "return %1.dateFormat(value,format);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createTimeFormatFunction(){
+//    addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("DATE&TIME");
+    fd.setName("timeFormat");
+    fd.setDescription("timeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    fd.setScriptWrapper(QString("function timeFormat(value, format){"
+                                " if(typeof(format)==='undefined') format = \"hh:mm\"; "
+                                "return %1.timeFormat(value,format);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createDateTimeFormatFunction(){
+//    addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("DATE&TIME");
+    fd.setName("dateTimeFormat");
+    fd.setDescription("dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+    fd.setScriptWrapper(QString("function dateTimeFormat(value, format){"
+                                " if(typeof(format)==='undefined') format = \"dd.MM.yyyy hh:mm\"; "
+                                "return %1.dateTimeFormat(value,format);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createDateFunction(){
+//    addFunction("date",date,"DATE&TIME","date()");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("DATE&TIME");
+    fd.setName("date");
+    fd.setDescription("date()");
+    fd.setScriptWrapper(QString("function date(){"
+                                "return %1.date();}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+
+bool ScriptEngineManager::createNowFunction(){
+//    addFunction("now",now,"DATE&TIME","now()");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("DATE&TIME");
+    fd.setName("now");
+    fd.setDescription("now()");
+    fd.setScriptWrapper(QString("function now(){"
+                                "return %1.now();}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createCurrencyFormatFunction(){
+//    addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("NUMBER");
+    fd.setName("currencyFormat");
+    fd.setDescription("currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
+    fd.setScriptWrapper(QString("function currencyFormat(value, locale){"
+                                " if(typeof(locale)==='undefined') locale = \"\"; "
+                                "return %1.currencyFormat(value,locale);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createCurrencyUSBasedFormatFunction(){
+//    addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("NUMBER");
+    fd.setName("currencyUSBasedFormat");
+    fd.setDescription("currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
+    fd.setScriptWrapper(QString("function currencyUSBasedFormat(value, currencySymbol){"
+                                " if(typeof(currencySymbol)==='undefined') currencySymbol = \"\"; "
+                                "return %1.currencyFormat(value,currencySymbol);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createSetVariableFunction(){
+//    addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
+    JSFunctionDesc fd;
+
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("GENERAL");
+    fd.setName("setVariable");
+    fd.setDescription("setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
+    fd.setScriptWrapper(QString("function setVariable(name, value){"
+                                "return %1.setVariable(name,value);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createGetVariableFunction()
+{
+    JSFunctionDesc fd;
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("GENERAL");
+    fd.setName("getVariable");
+    fd.setDescription("getVariable(\""+tr("Name")+"\")");
+    fd.setScriptWrapper(QString("function getVariable(name){"
+                                "return %1.getVariable(name);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
+bool ScriptEngineManager::createGetFieldFunction()
+{
+    JSFunctionDesc fd;
+    fd.setManager(m_functionManager);
+    fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
+    fd.setCategory("GENERAL");
+    fd.setName("getField");
+    fd.setDescription("getField(\""+tr("Name")+"\")");
+    fd.setScriptWrapper(QString("function getField(name){"
+                                "return %1.getField(name);}"
+                               ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
+                        );
+    return addFunction(fd);
+}
+
 ScriptEngineManager::ScriptEngineManager()
     :m_model(0), m_dataManager(0)
 {
-    m_scriptEngine = new QScriptEngine;
+    m_scriptEngine = new ScriptEngineType;
+    m_functionManager = new ScriptFunctionsManager(this);
+    m_functionManager->setScriptEngineManager(this);
 
-    //addFunction("dateToStr",dateToStr,"DATE", "dateToStr(\"value\",\"format\")");
-    addFunction("line",line,"SYSTEM", "line(\""+tr("BandName")+"\")");
-    addFunction("numberFormat",numberFormat,"NUMBER", "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+
-                tr("Precision")+"\",\""+
-                tr("Locale")+"\")");
-    addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
-    addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
-    addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
-    addFunction("date",date,"DATE&TIME","date()");
-    addFunction("now",now,"DATE&TIME","now()");
+    createLineFunction();
+    createNumberFomatFunction();
+    createDateFormatFunction();
+    createTimeFormatFunction();
+    createDateTimeFormatFunction();
+    createDateFunction();
+    createNowFunction();
 #if QT_VERSION>0x040800
-    addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
-    addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
+    createCurrencyFormatFunction();
+    createCurrencyUSBasedFormatFunction();
 #endif
-    addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
-    addFunction("getVariable", getVariable, "GENERAL", "getVariable(\""+tr("Name")+"\")");
-    addFunction("getField", getField, "GENERAL", "getField(\""+tr("Name")+"\")");
+    createSetVariableFunction();
+    createGetFieldFunction();
+    createGetVariableFunction();
 
+//    addFunction("line",line,"SYSTEM", "line(\""+tr("BandName")+"\")");
+//    addFunction("numberFormat",numberFormat,"NUMBER", "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+
+//                tr("Precision")+"\",\""+
+//                tr("Locale")+"\")");
+
+//    addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+//    addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+//    addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
+//    addFunction("date",date,"DATE&TIME","date()");
+//    addFunction("now",now,"DATE&TIME","now()");
+//    addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
+//    addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
+//    addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
+#ifndef USE_QJSENGINE
     QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor);
     m_scriptEngine->globalObject().setProperty("QColor", colorCtor);
 
@@ -633,7 +915,7 @@ ScriptEngineManager::ScriptEngineManager()
     m_scriptEngine->setDefaultPrototype(qMetaTypeId<QFont>(), fontProto);
     QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto);
     m_scriptEngine->globalObject().setProperty("QFont", fontConstructor);
-
+#endif
 //    foreach(QString func, dataManager()->groupFunctionNames()){
 //        addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")");
 //    }
@@ -947,5 +1229,203 @@ DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArr
     return res;
 }
 
+QString JSFunctionDesc::name() const
+{
+    return m_name;
+}
+
+void JSFunctionDesc::setName(const QString &name)
+{
+    m_name = name;
+}
+
+QString JSFunctionDesc::category() const
+{
+    return m_category;
+}
+
+void JSFunctionDesc::setCategory(const QString &category)
+{
+    m_category = category;
+}
+
+QString JSFunctionDesc::description() const
+{
+    return m_description;
+}
+
+void JSFunctionDesc::setDescription(const QString &description)
+{
+    m_description = description;
+}
+
+QString JSFunctionDesc::managerName() const
+{
+    return m_managerName;
+}
+
+void JSFunctionDesc::setManagerName(const QString &managerName)
+{
+    m_managerName = managerName;
+}
+
+QObject *JSFunctionDesc::manager() const
+{
+    return m_manager;
+}
+
+void JSFunctionDesc::setManager(QObject *manager)
+{
+    m_manager = manager;
+}
+
+QString JSFunctionDesc::scriptWrapper() const
+{
+    return m_scriptWrapper;
+}
+
+void JSFunctionDesc::setScriptWrapper(const QString &scriptWrapper)
+{
+    m_scriptWrapper = scriptWrapper;
+}
+
+QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName)
+{
+    if (m_scriptEngineManager->dataManager()){
+        QString expression = "";
+        if (name.compare("COUNT",Qt::CaseInsensitive) == 0){
+            expression = " ";
+        } else {
+            expression = m_scriptEngineManager->dataManager()->getExpression(expressionID);
+        }
+
+        GroupFunction* gf =  m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName);
+        if (gf){
+            if (gf->isValid()){
+                return gf->calculate();
+            }else{
+                return gf->error();
+            }
+        }
+        else {
+            return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name));
+        }
+    } else {
+        return QString(QObject::tr("Datasource manager not found"));
+    }
+}
+
+QVariant ScriptFunctionsManager::line(const QString &bandName)
+{
+    QString varName = QLatin1String("line_")+bandName.toLower();
+    QVariant res;
+    if (scriptEngineManager()->dataManager()->variable(varName).isValid()){
+        res=scriptEngineManager()->dataManager()->variable(varName);
+    } else res=QString("Variable line for band %1 not found").arg(bandName);
+    return res;
+}
+
+QVariant ScriptFunctionsManager::numberFormat(QVariant value, const char &format, int precision, const QString& locale)
+{
+    return (locale.isEmpty())?QString::number(value.toDouble(),format,precision):
+                              QLocale(locale).toString(value.toDouble(),format,precision);
+}
+
+QVariant ScriptFunctionsManager::dateFormat(QVariant value, const QString &format)
+{
+    return QLocale().toString(value.toDate(),format);
+}
+
+QVariant ScriptFunctionsManager::timeFormat(QVariant value, const QString &format)
+{
+    return QLocale().toString(value.toTime(),format);
+}
+
+QVariant ScriptFunctionsManager::dateTimeFormat(QVariant value, const QString &format)
+{
+    return QLocale().toString(value.toDateTime(),format);
+}
+
+QVariant ScriptFunctionsManager::date()
+{
+    return QDate::currentDate();
+}
+
+QVariant ScriptFunctionsManager::now()
+{
+    return QDateTime::currentDateTime();
+}
+
+QVariant ScriptFunctionsManager::currencyFormat(QVariant value, const QString &locale)
+{
+    QString l = (!locale.isEmpty())?locale:QLocale::system().name();
+    return QLocale(l).toCurrencyString(value.toDouble());
+}
+
+QVariant ScriptFunctionsManager::currencyUSBasedFormat(QVariant value, const QString &currencySymbol)
+{
+    QString CurrencySymbol = (!currencySymbol.isEmpty())?currencySymbol:QLocale::system().currencySymbol();
+    // Format it using USA locale
+    QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble());
+    // Replace currency symbol if necesarry
+    if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol);
+    return vTempStr;
+}
+
+void ScriptFunctionsManager::setVariable(const QString &name, QVariant value)
+{
+    DataSourceManager* dm = scriptEngineManager()->dataManager();
+    dm->changeVariable(name,value);
+}
+
+QVariant ScriptFunctionsManager::getVariable(const QString &name)
+{
+    DataSourceManager* dm = scriptEngineManager()->dataManager();
+    return dm->variable(name);
+}
+
+QVariant ScriptFunctionsManager::getField(const QString &field)
+{
+    DataSourceManager* dm = scriptEngineManager()->dataManager();
+    return dm->fieldData(field);
+}
+
+#ifdef USE_QJSENGINE
+QFont ScriptFunctionsManager::font(const QString &family, int pointSize, bool bold, bool italic, bool underLine)
+{
+    QFont result (family, pointSize);
+    result.setBold(bold);
+    result.setItalic(italic);
+    result.setUnderline(underLine);
+    return result;
+}
+#endif
+QFont ScriptFunctionsManager::font(QVariantMap params){
+    if (!params.contains("family")){
+        return QFont();
+    } else {
+        QFont result(params.value("family").toString());
+        if (params.contains("pointSize"))
+            result.setPointSize(params.value("pointSize").toInt());
+        if (params.contains("bold"))
+            result.setBold(params.value("bold").toBool());
+        if (params.contains("italic"))
+            result.setItalic(params.value("italic").toBool());
+        if (params.contains("underline"))
+            result.setUnderline(params.value("underline").toBool());
+        return result;
+    }
+}
+
+ScriptEngineManager *ScriptFunctionsManager::scriptEngineManager() const
+{
+    return m_scriptEngineManager;
+}
+
+void ScriptFunctionsManager::setScriptEngineManager(ScriptEngineManager *scriptEngineManager)
+{
+    m_scriptEngineManager = scriptEngineManager;
+}
+
 } //namespace LimeReport
 
diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h
index 545580b..726013b 100644
--- a/limereport/lrscriptenginemanager.h
+++ b/limereport/lrscriptenginemanager.h
@@ -39,11 +39,15 @@
 #include <QScriptable>
 #include <QFont>
 
+
+//#include <QJSEngine>
+
 #ifdef HAVE_UI_LOADER
 #include <QDialog>
 #endif
 
 #include "base/lrsingleton.h"
+#include "lrglobal.h"
 #include "lrscriptenginemanagerintf.h"
 #include "lrcollection.h"
 
@@ -53,7 +57,7 @@ class DataSourceManager;
 
 struct ScriptFunctionDesc{
     enum FuncType {Native,Script};
-    QScriptValue scriptValue;
+    ScriptValueType scriptValue;
     QString name;
     QString description;
     QString category;
@@ -169,22 +173,93 @@ private:
     QString m_initScript;
 };
 
+class JSFunctionDesc{
+public:
+    JSFunctionDesc(){}
+    JSFunctionDesc(const QString& functionName,
+                   const QString& functionCategory,
+                   const QString& functionDescription,
+                   const QString& functionManagerName,
+                   QObject* functionManger,
+                   const QString& functionScriptWrapper
+                   ): m_name(functionName), m_category(functionCategory), m_description(functionDescription),
+                      m_managerName(functionManagerName), m_manager(functionManger), m_scriptWrapper(functionScriptWrapper)
+    {}
+    QString name() const;
+    void setName(const QString &name);
+
+    QString category() const;
+    void setCategory(const QString &category);
+
+    QString description() const;
+    void setDescription(const QString &description);
+
+    QString managerName() const;
+    void setManagerName(const QString &managerName);
+
+    QObject *manager() const;
+    void setManager(QObject *manager);
+
+    QString scriptWrapper() const;
+    void setScriptWrapper(const QString &scriptWrapper);
+
+private:
+    QString  m_name;
+    QString  m_category;
+    QString  m_description;
+    QString  m_managerName;
+    QObject* m_manager;
+    QString  m_scriptWrapper;
+};
+
+class ScriptFunctionsManager : public QObject{
+    Q_OBJECT
+public:
+    explicit ScriptFunctionsManager(QObject* parent = 0):QObject(parent){}
+    Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName);
+    Q_INVOKABLE QVariant line(const QString& bandName);
+    Q_INVOKABLE QVariant numberFormat(QVariant value, const char &format, int precision, const QString &locale);
+    Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format);
+    Q_INVOKABLE QVariant timeFormat(QVariant value, const QString& format);
+    Q_INVOKABLE QVariant dateTimeFormat(QVariant value, const QString& format);
+    Q_INVOKABLE QVariant date();
+    Q_INVOKABLE QVariant now();
+    Q_INVOKABLE QVariant currencyFormat(QVariant value, const QString& locale);
+    Q_INVOKABLE QVariant currencyUSBasedFormat(QVariant value, const QString& currencySymbol);
+    Q_INVOKABLE void     setVariable(const QString& name, QVariant value);
+    Q_INVOKABLE QVariant getVariable(const QString& name);
+    Q_INVOKABLE QVariant getField(const QString& field);
+    Q_INVOKABLE QVariant color(const QString& color){ return  QColor(color);}        
+#ifdef USE_QJSENGINE
+    Q_INVOKABLE QFont font(const QString& family, int pointSize = -1, bool bold = false, bool italic = false, bool underLine = false);
+#endif
+    Q_INVOKABLE QFont font(QVariantMap params);
+    ScriptEngineManager *scriptEngineManager() const;
+    void setScriptEngineManager(ScriptEngineManager *scriptEngineManager);
+    static QColor createQColor(const QString& color){ return QColor(color);}
+private:
+    ScriptEngineManager* m_scriptEngineManager;
+};
+
 class ScriptEngineManager : public QObject, public Singleton<ScriptEngineManager>, public IScriptEngineManager
 {    
     Q_OBJECT
 public:
-    QScriptEngine* scriptEngine(){return m_scriptEngine;}
-    ~ScriptEngineManager();
     friend class Singleton<ScriptEngineManager>;
+    ScriptEngineType* scriptEngine(){return m_scriptEngine;}
+    ~ScriptEngineManager();
     bool isFunctionExists(const QString& functionName) const;
     void deleteFunction(const QString& functionsName);
-    bool addFunction(const QString& name, QScriptEngine::FunctionSignature function,
-                             const QString& category="", const QString& description="");
+
+    bool addFunction(const JSFunctionDesc& functionsDescriber);
+#ifndef USE_QJSENGINE
+    bool addFunction(const QString &name, QScriptEngine::FunctionSignature function, const QString &category, const QString &description);
+#endif
     bool addFunction(const QString &name, const QString& script,
                              const QString &category="", const QString &description="");
     const QString& lastError() const {return m_lastError;}
     QStringList functionsNames();
-    const QList<ScriptFunctionDesc>& functionsDescriber(){return m_functions;}
+    const QList<ScriptFunctionDesc>& functionsDescribers(){return m_functions;}
     ScriptEngineModel* model(){return m_model;}
     void setContext(ScriptEngineContext* context){m_context=context;}
     DataSourceManager* dataManager() const {return m_dataManager;}
@@ -200,14 +275,27 @@ protected:
     bool containsFunction(const QString &functionName);
 private:
     Q_DISABLE_COPY(ScriptEngineManager)
+    bool createLineFunction();
+    bool createNumberFomatFunction();
+    bool createDateFormatFunction();
+    bool createTimeFormatFunction();
+    bool createDateTimeFormatFunction();
+    bool createDateFunction();
+    bool createNowFunction();
+    bool createCurrencyFormatFunction();
+    bool createCurrencyUSBasedFormatFunction();
+    bool createSetVariableFunction();
+    bool createGetVariableFunction();
+    bool createGetFieldFunction();
 private:
     ScriptEngineManager();
-    QScriptEngine*  m_scriptEngine;
+    ScriptEngineType*  m_scriptEngine;
     QString m_lastError;
     QList<ScriptFunctionDesc> m_functions;
     ScriptEngineModel* m_model;
     ScriptEngineContext* m_context;
     DataSourceManager* m_dataManager;
+    ScriptFunctionsManager* m_functionManager;
 };
 
 class ScriptExtractor
diff --git a/limereport/lrscriptenginemanagerintf.h b/limereport/lrscriptenginemanagerintf.h
index d7662ff..4c2767a 100644
--- a/limereport/lrscriptenginemanagerintf.h
+++ b/limereport/lrscriptenginemanagerintf.h
@@ -30,15 +30,19 @@
 #ifndef LRSCRIPTENGINEMANAGERINTF_H
 #define LRSCRIPTENGINEMANAGERINTF_H
 
-#include <QtScript/QScriptEngine>
+//#include <QJSEngine>
+#include "lrglobal.h"
 
 namespace LimeReport{
 
+
 class IScriptEngineManager{
 public:
-    virtual QScriptEngine* scriptEngine() = 0;
-    virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function,
+    virtual ScriptEngineType* scriptEngine() = 0;
+#ifndef USE_QJSENGINE
+    virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function,
                              const QString& category="", const QString& description="") = 0;
+#endif
     virtual bool addFunction(const QString &name, const QString& script,
                              const QString &category="", const QString &description="") = 0;
     virtual const QString& lastError() const = 0;
@@ -46,4 +50,5 @@ public:
 };
 
 } //namespace LimeReport
+
 #endif // LRSCRIPTENGINEMANAGERINTF_H
diff --git a/limereport/scriptbrowser/lrscriptbrowser.cpp b/limereport/scriptbrowser/lrscriptbrowser.cpp
index 5f90bf3..8e6dcc3 100644
--- a/limereport/scriptbrowser/lrscriptbrowser.cpp
+++ b/limereport/scriptbrowser/lrscriptbrowser.cpp
@@ -67,7 +67,7 @@ void ScriptBrowser::updateFunctionTree()
     ui->twFunctions->clear();
     ScriptEngineManager* sm = reportEditor()->scriptManager();
     QMap<QString,QTreeWidgetItem*> categ;
-    foreach(ScriptFunctionDesc fd, sm->functionsDescriber()){
+    foreach(ScriptFunctionDesc fd, sm->functionsDescribers()){
         QString functionCategory = (fd.category!="") ? fd.category : tr("NO CATEGORY");
         if (categ.contains(functionCategory)){
             QTreeWidgetItem* item = new QTreeWidgetItem(categ.value(fd.category),QStringList(fd.name));