public static void MergeTreeNodesRecursively(PPDataContext dbFrom, PPDataContext dbTo, TreeNode nodeFrom, TreeNode nodeTo, IProcessingCallback callback)
        {
            if (null != callback && !nodeFrom.IsDocument)
                callback.Info(string.Format("Processing branch {0}", nodeFrom.Name));

            // get thumbnail path of node to insert
            string thumbnailPath = nodeFrom.Thumbnail.File.Path(dbFrom);

            // handle childrens
            foreach (TreeNode childFrom in nodeFrom.Childrens(dbFrom))
            {
                // get thumbnail of node to insert
                thumbnailPath = childFrom.Thumbnail.File.Path(dbFrom);

                if (childFrom.IsDocument)
                {
                    Document docFrom = childFrom.Documents(dbFrom)[0];
                    string docTypeName = docFrom.DocumentType.Name;

                    if (nodeTo.HasChild(dbTo, childFrom.Name))
                    { if (null != callback) callback.Info(string.Format("Document {0} already exists...", childFrom.Name)); }
                    else
                    {
                        if (string.Equals("Parametric component", docTypeName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            if (null != callback) callback.Info(string.Format("Parametric component {0} already exists...", childFrom.Name));
                            // insert as component
                            Component compFrom = docFrom.Components[0];
                            Component compTo = Component.GetByGuid(dbTo, compFrom.Guid);
                            if (null == compTo)
                            {
                                if (null != callback) callback.Info(string.Format("Inserting component {0}...", childFrom.Name));
                                compTo = nodeTo.InsertComponent(dbTo, docFrom.File.Path(dbFrom), compFrom.Guid, childFrom.Name, childFrom.Description, thumbnailPath);

                                // parameter default values
                                Dictionary<string, double> dictNameValues = compFrom.GetParamDefaultValues();
                                if (dictNameValues.Count > 0)
                                {
                                    if (null != callback)
                                    {
                                        string sParameters = string.Empty;
                                        foreach (string defParamName in dictNameValues.Keys)
                                        {
                                            StringBuilder sb = new StringBuilder();
                                            sb.Append(defParamName);
                                            sb.Append("=");
                                            sb.Append(dictNameValues[defParamName]);
                                            sb.Append(", ");
                                            sParameters += sb.ToString();
                                        }
                                        sParameters.Trim();
                                        sParameters.Trim(',');
                                        callback.Info(string.Format("Default parameter values : {0}", sParameters));
                                    }
                                    compTo.InsertNewParamDefaultValues(dbTo, dictNameValues);
                                }
                                // majorations
                                foreach (MajorationSet mjset in compFrom.MajorationSets)
                                {
                                    // retrieve profile
                                    string profileName = mjset.CardboardProfile.Name;
                                    CardboardProfile profileTo = CardboardProfile.GetByName(dbTo, profileName);
                                    if (null == profileTo)
                                    {
                                        if (null != callback) callback.Error(string.Format("Failed to retrieve profile {0}", mjset.CardboardProfile.Name));
                                        continue;
                                    }
                                    // get majorations
                                    Dictionary<string, double> majorations = new Dictionary<string, double>();
                                    string sMajo = string.Format("prof = {0} -> ", profileName);
                                    foreach (Majoration mj in mjset.Majorations)
                                    {
                                        majorations.Add(mj.Name, mj.Value);
                                        sMajo += string.Format("{0}={1}, ", mj.Name, mj.Value);
                                    }
                                    // insert
                                    if (null != callback) callback.Info(sMajo);
                                    compTo.InsertNewMajorationSet(dbTo, profileTo.Name, majorations);
                                }
                            }
                            else
                            { if (null != callback) callback.Info(string.Format("Component with GUID {0} already exists...", compFrom.Guid)); }
                        }
                        else
                        {
                            if (null != callback) callback.Info(string.Format("Inserting document {0}...", childFrom.Name));
                            // insert as document
                            nodeTo.InsertDocument(dbTo, docFrom.File.Path(dbFrom), childFrom.Name, childFrom.Description, docTypeName, thumbnailPath);
                        }
                    }
                }
                else
                {
                    TreeNode childTo = null;
                    if (nodeTo.HasChild(dbTo, childFrom.Name))
                    {
                        if (null != callback) callback.Info(string.Format("Branch {0} already exists.Skipping...", childFrom.Name));
                        childTo = nodeTo.GetChild(dbTo, childFrom.Name);
                    }
                    else
                    {
                        if (null != callback) callback.Info(string.Format("Inserting branch {0}...", childFrom.Name));
                        childTo = nodeTo.CreateChild(dbTo, childFrom.Name, childFrom.Description, thumbnailPath);
                    }
                    MergeTreeNodesRecursively(dbFrom, dbTo, childFrom, childTo, callback);
                }
            }
        }
        public static void ClearExistingDocumentsRecursively(PPDataContext dbFrom, TreeNode nodeFrom, TreeNode nodeTo, IProcessingCallback callback)
        {
            if (null != callback && !nodeFrom.IsDocument)
                callback.Info(string.Format("Processing branch {0}", nodeFrom.Name));

            // get thumbnail path of node to insert
            string thumbnailPath = nodeFrom.Thumbnail.File.Path(dbFrom);

            // handle childrens
            foreach (TreeNode childFrom in nodeFrom.Childrens(dbFrom))
            {
                // get thumbnail of node to insert
                thumbnailPath = childFrom.Thumbnail.File.Path(dbFrom);

                if (childFrom.IsDocument)
                {
                    Document docFrom = childFrom.Documents(dbFrom)[0];
                    string docTypeName = docFrom.DocumentType.Name;

                    // delete existing document
                    // will be using new data context each time a tree node is deleted
                    // in order to avoid exceptions claiming that there is a foreign key violation
                    using (PPDataContext dbTo0 = new PPDataContext())
                    {
                        if (nodeTo.HasChild(dbTo0, childFrom.Name))
                        {
                            string documentName = childFrom.Name;
                            TreeNode childTo = nodeTo.GetChild(dbTo0, documentName);
                            if (null != childTo && childTo.IsDocument)
                            {
                                try
                                {
                                    if (null != callback) callback.Info(string.Format("Deleting tree node {0} ...", childTo.Name));
                                    childTo.Delete(dbTo0, true, callback);
                                    dbTo0.SubmitChanges();
                                }
                                catch (Exception ex)
                                {
                                    callback.Error(string.Format("Deleting document {0} failed with exception {1}", documentName, ex.Message));
                                }
                            }
                        }
                    }
                }
                else // childFrom.IsDocument
                {
                    using (PPDataContext dbTo2 = new PPDataContext())
                    {
                        TreeNode childTo = null;
                        if (nodeTo.HasChild(dbTo2, childFrom.Name))
                        {
                            if (null != callback) callback.Info(string.Format("Branch {0} already exists.Skipping...", childFrom.Name));
                            childTo = nodeTo.GetChild(dbTo2, childFrom.Name);
                            ClearExistingDocumentsRecursively(dbFrom, childFrom, childTo, callback);
                        }
                    }
                }
            }
        }
 private void InsertChildNodes(PPDataContext db, TreeInterface treeImplementation, object parentNode, TreeNode node)
 {
     // node itself
     Object object1 = treeImplementation.InsertTreeNode(parentNode, node);
     // child nodes
     List<TreeNode> childNodes = node.Childrens(db);
     foreach (TreeNode tn in childNodes)
         InsertChildNodes(db, treeImplementation, object1, tn);
 }