/// <summary>
        /// Event handler method for SelectionChanged event.
        /// This method will check that the selection reported by event is the same with the actual Revit selection
        /// and print the current selection in the log file.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">Event arguments that contains the event data.</param>
        private void SelectionChangedHandler(Object sender, SelectionChangedEventArgs args)
        {
            // The document associated with the event.
            Document doc = args.GetDocument();

            //Check if Revit selection matches the selection reported by the event
            UIDocument        uidoc             = new UIDocument(doc);
            IList <Reference> currentSelection  = uidoc.Selection.GetReferences();
            IList <Reference> reportedSelection = args.GetReferences();

            if (!currentSelection.All(i => null != reportedSelection.FirstOrDefault(r => r.EqualTo(i))))
            {
                LogManager.WriteLog("Error: Current selection is different from the selection reported by the selectionchanged event");
            }

            var currentSelectedElementIds  = uidoc.Selection.GetElementIds();
            var reportedSelectedElementIds = args.GetSelectedElements();

            if (!currentSelectedElementIds.All(i => null != reportedSelectedElementIds.FirstOrDefault(r => r == i)))
            {
                LogManager.WriteLog("Error: Current selected ElementIds is different from the one reported by the selectionchanged event");
            }

            // write to log file.
            LogManager.WriteLog(args.GetInfo());

            if (InfoWindow != null)
            {
                InfoWindow.RevitUIApp_SelectionChanged(sender, args);
            }
        }
        /// <summary>
        /// Get SelectionChangedEvent information
        /// </summary>
        /// <param name="args">Event arguments that contains the event data.</param>
        /// <param name="doc">document in which the event occurs.</param>
        public static string GetInfo(this SelectionChangedEventArgs args)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine();

            Document doc = args.GetDocument();

            sb.AppendLine("[Event] " + GetEventName(args.GetType()) + ": " + TitleNoExt(doc.Title));


            IList <Reference> refs = args.GetReferences();

            sb.AppendLine("Selection Count:" + refs.Count);

            foreach (var aRef in refs)
            {
                //foreach (PropertyInfo pi in aRef.GetType().GetProperties())
                //{
                //   Trace.WriteLine(pi.Name + ":" + pi.GetValue(aRef, null)?.ToString());
                //}

                switch (aRef.ElementReferenceType)
                {
                case ElementReferenceType.REFERENCE_TYPE_NONE:
                {
                    sb.AppendFormat("The reference is to an element. ElementId:{0}.", aRef.ElementId);
                    if (aRef.LinkedElementId != ElementId.InvalidElementId)
                    {
                        sb.AppendFormat("LinkedElementId:{0}", aRef.LinkedElementId);
                    }
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_LINEAR:
                {
                    sb.AppendFormat("The reference is to a curve or edge. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_SURFACE:
                {
                    sb.AppendFormat("The reference is to a face or face region. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_FOREIGN:
                {
                    sb.AppendFormat("The reference is to geometry or elements in linked Revit file. LinkedElementId:{0}.", aRef.LinkedElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_INSTANCE:
                {
                    sb.AppendFormat("The reference is an instance of a symbol. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_CUT_EDGE:
                {
                    sb.AppendFormat("The reference is to a face that was cut. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_MESH:
                {
                    sb.AppendFormat("The reference is to a mesh. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                case ElementReferenceType.REFERENCE_TYPE_SUBELEMENT:
                {
                    sb.AppendFormat("The reference is to a subelement. ElementId:{0}.", aRef.ElementId);
                    break;
                }

                default:
                {
                    sb.Append("Unknown reference type.");
                    break;
                }
                }


                Element elem = doc.GetElement(aRef.ElementId);
                if (elem != null)
                {
                    sb.AppendFormat(" Name:{0}.", elem.Name);
                }

                sb.AppendLine();
            }

            return(sb.ToString());
        }