/// <summary>
        /// Construct a graph of tree view nodes, following the
        /// hierarchical organization of descendants beneath a top-level object
        /// </summary>
        /// <param name="oTarg">the top-level object the tree will model</param>
        /// <param name="nodParent">the top-level tree node, to associate with <paramref name="oTarg"/></param>
        private void FillTree(IObject oTarg, TreeNode nodParent)
        {
            var tvNew = new TreeNode(oTarg.Name);
            if (nodParent == null)
                _treeView.Nodes.Add(tvNew);
            else
                nodParent.Nodes.Add(tvNew);

            for (int i = 0; i < oTarg.PropertyCount; ++i)
            {
                IProperty pNext = oTarg.GetProperty(i);
                tvNew.Nodes.Add(pNext.Name + " = " + pNext.Value);
            }

            for (int i = 0; i < oTarg.ChildCount; ++i)
                FillTree(oTarg.GetChild(i), tvNew);
        }
        /// <summary>
        /// Copy another object's properties and children
        /// into this object
        /// </summary>
        /// <param name="oSource">The object to be copied</param>
        private void CopyFrom(IObject oSource)
        {
            for (int i = 0; i < oSource.PropertyCount; ++i)
            {
                IProperty pNext = oSource.GetProperty(i);
                if (PropertyExists(pNext.Name))
                    SetPropertyValue(pNext.Name, pNext.Value);
                else
                    AddProperty(pNext.Name, pNext.Value);
            }

            for (int i = 0; i < oSource.ChildCount; ++i)
            {
                AddChild(new SimpleObject(oSource.GetChild(i)));
            }
        }