public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Application app = commandData.Application.Application;

            string famFilePath1 = FilesWorker.GetFamilyFileByUser("Главное семейство");

            if (string.IsNullOrEmpty(famFilePath1))
            {
                return(Result.Cancelled);
            }
            Document famdoc1 = app.OpenDocumentFile(famFilePath1);

            string famFilePath2 = FilesWorker.GetFamilyFileByUser("Семейство для сравнения");

            if (string.IsNullOrEmpty(famFilePath2))
            {
                return(Result.Cancelled);
            }
            Document famdoc2 = app.OpenDocumentFile(famFilePath2);

            //try to fix ids shift through a new blank document
            //FamilyInfo fi1 = GetFamInfoByBlankProjectDocument(famFilePath1, app);
            //FamilyInfo fi2 = GetFamInfoByBlankProjectDocument(famFilePath2, app);

            FamilyInfo fi1 = new FamilyInfo(famdoc1);
            FamilyInfo fi2 = new FamilyInfo(famdoc2);

            fi2.ApplyIdOffset(fi1);

            //first time I think that all ids moves to constant distance... naive me
            //int idOffset = famdoc2.OwnerFamily.Id.IntegerValue - famdoc1.OwnerFamily.Id.IntegerValue;
            //int idOffset = fi2.List_RefPlanes.First().Id - fi1.List_RefPlanes.First().Id;



            famdoc1.Close(false);
            famdoc2.Close(false);

            string xml1 = fi1.SerializeToXml();
            string xml2 = fi2.SerializeToXml();

            //the most interesting thing is doing in another solution, look at https://github.com/Tereami/XmlComparer
            string result = XmlComparer.Comparer.CompareXmls(xml1, xml2);



            FormResult form = new FormResult(result);

            form.ShowDialog();


            return(Result.Succeeded);
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Autodesk.Revit.ApplicationServices.Application app =
                commandData.Application.Application;

            string familyPath  = "";
            string libraryPath = "";

            using (FormCheckNestedFamily form = new FormCheckNestedFamily())
            {
                if (form.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return(Result.Cancelled);
                }
                familyPath  = form.FamilyPath;
                libraryPath = form.LibraryPath;
            }

            Document myFamDoc = app.OpenDocumentFile(familyPath);
            //int myFamDocOwnerFamilyId = myFamDoc.OwnerFamily.Id.IntegerValue; ;
            FamilyInfo fi1  = new FamilyInfo(myFamDoc);
            string     xml1 = fi1.SerializeToXml();

            myFamDoc.Close(false);

            string familyTitle = System.IO.Path.GetFileNameWithoutExtension(familyPath);

            Dictionary <string, List <string> > library = FilesWorker.GetFamiliesLibrary(app, libraryPath);

            //search parent families that includes my family
            List <string> parentFams = new List <string>();

            foreach (KeyValuePair <string, List <string> > kvp in library)
            {
                foreach (string fam in kvp.Value)
                {
                    if (fam.Equals(familyTitle))
                    {
                        parentFams.Add(kvp.Key);
                    }
                }
            }

            //open that parent families and check version of family as nested
            Dictionary <string, string> log = new Dictionary <string, string>();

            foreach (string parentFamFile in parentFams)
            {
                Document      parentfamDoc = app.OpenDocumentFile(parentFamFile);
                List <Family> nestedFams   = new FilteredElementCollector(parentfamDoc)
                                             .OfClass(typeof(Family))
                                             .Cast <Family>()
                                             .Where(i => i.Name == familyTitle)
                                             .ToList();
                if (nestedFams.Count == 0)
                {
                    throw new Exception("Не удалось найти " + familyTitle + " в семействе " + parentFamFile);
                }

                Document nestedFamForChecking = parentfamDoc.EditFamily(nestedFams.First());


                FamilyInfo fi2 = new FamilyInfo(nestedFamForChecking);
                //int idOffset = nestedFamForChecking.OwnerFamily.Id.IntegerValue - myFamDocOwnerFamilyId;
                fi2.ApplyIdOffset(fi1);

                string xml2 = fi2.SerializeToXml();
                nestedFamForChecking.Close(false);
                parentfamDoc.Close(false);

                string compareResult = XmlComparer.Comparer.CompareXmls(xml1, xml2);
                if (string.IsNullOrEmpty(compareResult))
                {
                    compareResult = "IDENTITY!";
                }
                log.Add(parentFamFile, compareResult);
            }

            using (FormResultNestedFamily formResult = new FormResultNestedFamily(familyTitle, log))
            {
                formResult.ShowDialog();
            }



            return(Result.Succeeded);
        }