#include <boost/test/unit_test.hpp>
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"

#include "../Node.h"
#include <iostream>
#include "treemanager/MOTreeManager.h"
#include "MockDataStorage.h"
#include <syncml/core/Item.h>
#include "Common.h"
#include "Errors.h"
#include "commontypes.h"

//const std::string S_root;
//const std::string S_workingDirectory("MockMOTree");

using namespace NS_DM_Client;
namespace fs = boost::filesystem;

BOOST_AUTO_TEST_CASE(AddNodeAndRollback)
{
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
 	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("AddNodeAndRollback/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_NotFound);
	BOOST_CHECK(S_treeManager->Get("AddNodeAndRollback/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddNodeAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(AddNodeAndCommit)
{
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddNodeAndCommit/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("AddNodeAndCommit/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Commit() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodeAndCommit/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodeAndCommit/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddNodeAndCommit").c_str());
}

BOOST_AUTO_TEST_CASE(AddSeparateNodeAndStartTransactionAndAddNodeAndRollback)
{

 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddSeparateNodeAndStartTransactionAndAddNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Add("AddSeparateNodeAndStartTransactionAndAddNodeAndRollback/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddSeparateNodeAndStartTransactionAndAddNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddSeparateNodeAndStartTransactionAndAddNodeAndRollback/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddSeparateNodeAndStartTransactionAndAddNodeAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(AddSeparateNodeAndStartTransactionAndAddNodeAndCommit)
{
 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddSeparateNodeAndStartTransactionAndAddNodeAndCommit/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Add("AddSeparateNodeAndStartTransactionAndAddNodeAndCommit/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Commit() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddSeparateNodeAndStartTransactionAndAddNodeAndCommit/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddSeparateNodeAndStartTransactionAndAddNodeAndCommit/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddSeparateNodeAndStartTransactionAndAddNodeAndCommit").c_str());
}

BOOST_AUTO_TEST_CASE(DeleteLeafNodeAndRollback)
{
 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("DeleteLeafNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Delete("DeleteLeafNodeAndRollback/Root/InteriorSubNode/LeafNode1") == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->Get("DeleteLeafNodeAndRollback/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/DeleteLeafNodeAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(DeleteParentNodeWithChildsAndRollback)
{
 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode1/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode1/LeafNode2", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/LeafNode2", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/InteriorSubSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/InteriorSubSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Delete("DeleteParentNodeWithChildsAndRollback/Root") == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode1/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode1/LeafNode2", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/LeafNode2", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/InteriorSubSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Get("DeleteParentNodeWithChildsAndRollback/Root/InteriorSubNode2/InteriorSubSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/DeleteParentNodeWithChildsAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(ReplaceNodeValueAndRollback)
{
 	Funambol::Item Item;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	Item.setMeta(&meta);
	Funambol::ComplexData cdata("original value");
 	Item.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("ReplaceNodeValueAndRollback/Root/InteriorSubNode1/LeafNode1", Item) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

    Funambol::ComplexData new_data("replaced value");
    Item.setData(&new_data);

 	BOOST_CHECK(S_treeManager->Replace("ReplaceNodeValueAndRollback/Root/InteriorSubNode1/LeafNode1", Item) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Get("ReplaceNodeValueAndRollback/Root/InteriorSubNode1/LeafNode1", Item) == NS_DM_Client::e_Ok);

    String val = Item.getData()->getData();
 	BOOST_CHECK(val.compare("original value") == 0);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/ReplaceNodeValueAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(ReplacePropertyValueAndRollback)
{
 	Funambol::Item Item;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	Item.setMeta(&meta);
	Funambol::ComplexData cdata("some data");
 	Item.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("ReplacePropertyValueAndRollback/Root/InteriorSubNode1/LeafNode1", Item) == NS_DM_Client::e_Ok);

    String prop_name = "ACL";
    String prop_value = "Get=*";

 	BOOST_CHECK(S_treeManager->ReplacePropertyValue(
 	    "ReplacePropertyValueAndRollback/Root/InteriorSubNode1/LeafNode1", prop_name, prop_value) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

    prop_value = "Get=www.test.com";

 	BOOST_CHECK(S_treeManager->ReplacePropertyValue(
 	    "ReplacePropertyValueAndRollback/Root/InteriorSubNode1/LeafNode1", prop_name, prop_value) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->GetPropertyValue(
 	    "ReplacePropertyValueAndRollback/Root/InteriorSubNode1/LeafNode1", prop_name, prop_value) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(prop_value.compare("Get=*") == 0);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/ReplacePropertyValueAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(CopyExistingLeafNodeToExistingDestinationAndRollback)
{
 	Funambol::Item Item;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	Item.setMeta(&meta);
	Funambol::ComplexData cdata("source value");
 	Item.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/sourceNode", Item) == NS_DM_Client::e_Ok);

    Funambol::ComplexData new_data("original value");
    Item.setData(&new_data);

 	BOOST_CHECK(S_treeManager->Add("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/destNode", Item) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Copy("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/sourceNode",
 	    "CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/destNode") == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Get("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/destNode", Item) == NS_DM_Client::e_Ok);

    String val = Item.getData()->getData();
 	BOOST_CHECK(val.compare("original value") == 0);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/CopyExistingLeafNodeToExistingDestinationAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(CopyExistingLeafNodeToNotExistingDestinationAndRollback)
{
 	Funambol::Item Item;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	Item.setMeta(&meta);
	Funambol::ComplexData cdata("source value");
 	Item.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/sourceNode", Item) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Copy("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode1/sourceNode",
 	    "CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode2/destNode") == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Get("CopyExistingLeafNodeToExistingDestinationAndRollback/Root/InteriorSubNode2/destNode", Item) == NS_DM_Client::e_NotFound);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/CopyExistingLeafNodeToExistingDestinationAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(CopyInteriorNodeAndRollback)
{
	NS_DM_Client::Node root("CopyInteriorNodeAndRollback/RootNode", S_dataStorage);
	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + "CopyInteriorNodeAndRollback/RootNode", fs::native);

	root.SetProperty(NS_DM_Client::e_format, "node");
	root.SetProperty(NS_DM_Client::e_type, "node");
	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*");
	BOOST_CHECK(fs::exists(root_path));

	// add childs
	URI uri = "CopyInteriorNodeAndRollback/RootNode/Node1/Node2/SourceNode";
	Funambol::Item sourceItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	sourceItem.setMeta(&meta);
	std::string oldContent("Some data");
	Funambol::ComplexData cdata(oldContent.c_str());
	sourceItem.setData(&cdata);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "CopyInteriorNodeAndRollback/RootNode/Subnode/Node1/SourceNode";
	Funambol::ComplexData cdata2(oldContent.c_str());
	sourceItem.setData(&cdata2);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "CopyInteriorNodeAndRollback/RootNode/Subnode/Node2/SourceNode2";
	Funambol::ComplexData cdata3(oldContent.c_str());
	sourceItem.setData(&cdata3);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "CopyInteriorNodeAndRollback/RootNode/Subnode/LeafNode";
	Funambol::ComplexData cdata4(oldContent.c_str());
	sourceItem.setData(&cdata4);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Copy("CopyInteriorNodeAndRollback/RootNode", "CopyInteriorNodeAndRollback/copy_dest"));

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->Get("CopyInteriorNodeAndRollback/copy_dest", sourceItem) == NS_DM_Client::e_NotFound);

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/CopyInteriorNodeAndRollback/RootNode").c_str());
}

BOOST_AUTO_TEST_CASE(ReplaceNamePropertyOfNodeAndRollback)
{
	NS_DM_Client::Node root("ReplaceNamePropertyOfNodeAndRollback/RootNode", S_dataStorage);
	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + "ReplaceNamePropertyOfNodeAndRollback/RootNode", fs::native);

	root.SetProperty(NS_DM_Client::e_format, "node");
	root.SetProperty(NS_DM_Client::e_type, "node");
	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*");
	BOOST_CHECK(fs::exists(root_path));

	// add childs
	URI uri = "ReplaceNamePropertyOfNodeAndRollback/RootNode/Node1/Node2/SourceNode";
	Funambol::Item sourceItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	sourceItem.setMeta(&meta);
	std::string oldContent("Some data");
	Funambol::ComplexData cdata1(oldContent.c_str());
	sourceItem.setData(&cdata1);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "ReplaceNamePropertyOfNodeAndRollback/RootNode/Subnode/Node1/SourceNode";
	Funambol::ComplexData cdata2(oldContent.c_str());
	sourceItem.setData(&cdata2);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "ReplaceNamePropertyOfNodeAndRollback/RootNode/Subnode/Node2/SourceNode2";
	Funambol::ComplexData cdata3(oldContent.c_str());
	sourceItem.setData(&cdata3);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	uri = "ReplaceNamePropertyOfNodeAndRollback/RootNode/Subnode/LeafNode";
	Funambol::ComplexData cdata4(oldContent.c_str());
	sourceItem.setData(&cdata4);
	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Add(uri, sourceItem));

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);

	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->ReplacePropertyValue("ReplaceNamePropertyOfNodeAndRollback/RootNode", "Name", "ReplacedNode"));

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok);

	BOOST_CHECK(NS_DM_Client::e_Ok == S_treeManager->Get("ReplaceNamePropertyOfNodeAndRollback/RootNode/Subnode/Node2/SourceNode2", sourceItem));

    fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/ReplaceNamePropertyOfNodeAndRollback").c_str());
}

BOOST_AUTO_TEST_CASE(AddNodesAndRollbackInDeepTransaction)
{
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction

 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
 	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok); // in this place added items bust be rollbacked (deleted)
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_NotFound);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndRollbackInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);


	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddNodesAndRollbackInDeepTransaction").c_str());
}

BOOST_AUTO_TEST_CASE(AddNodesAndCommitInDeepTransactionWithFinalRollback)
{
 	Funambol::Item newItem;
	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType("text/plain");
	newItem.setMeta(&meta);
 	Funambol::ComplexData cdata("some value");
 	newItem.setData(&cdata);

 	BOOST_CHECK(S_treeManager->Add("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Add("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction
	BOOST_CHECK(S_treeManager->StartTransaction() == NS_DM_Client::e_Ok); // deep transaction

 	BOOST_CHECK(S_treeManager->Delete("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1") == NS_DM_Client::e_Ok);
 	BOOST_CHECK(S_treeManager->Delete("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2") == NS_DM_Client::e_Ok);

 	BOOST_CHECK(S_treeManager->Commit() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_NotFound);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);

 	BOOST_CHECK(S_treeManager->Commit() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_NotFound);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);

 	BOOST_CHECK(S_treeManager->Commit() == NS_DM_Client::e_Ok); // no action - we are in deep transaction
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_NotFound);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_NotFound);

 	BOOST_CHECK(S_treeManager->Rollback() == NS_DM_Client::e_Ok); // in this place deleted items bust be rollbacked
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode1", newItem) == NS_DM_Client::e_Ok);
	BOOST_CHECK(S_treeManager->Get("AddNodesAndCommitInDeepTransaction/Root/InteriorSubNode/LeafNode2", newItem) == NS_DM_Client::e_Ok);

	fs::remove_all(String(NS_DM_Client::NS_DataStorage::GetBasePath() +
        (String)"/" + c_testProfile + "/AddNodesAndCommitInDeepTransaction").c_str());
}
