/// <summary>
 /// Registers the specified plugin item in the plugin tree.
 /// </summary>
 /// <param name="itemMetadata">Metadata structure of the item to register.</param>
 /// <returns><c>true</c>, if the plugin item could be registered, <c>false</c>,
 /// if the item already existed and <see cref="PluginItemMetadata.IsRedundant"/> is specified.</returns>
 /// <exception cref="ArgumentException">If there is already an item registered at the registration
 /// location and the <see cref="PluginItemMetadata.IsRedundant"/> flag is not set.</exception>
 internal bool RegisterItem(PluginItemMetadata itemMetadata)
 {
     lock (_syncObj)
     {
         IRegistryNode node = GetRegistryNode(itemMetadata.RegistrationLocation, true);
         itemMetadata.PluginRuntime = this;
         if (node.Items != null && node.Items.ContainsKey(itemMetadata.Id))
         {
             if (itemMetadata.IsRedundant)
             {
                 PluginItemRegistration itemRegistration = (PluginItemRegistration)node.Items[itemMetadata.Id];
                 itemRegistration.AdditionalRedundantItemsMetadata.Add(itemMetadata);
                 return(false);
             }
             else
             {
                 throw new ArgumentException(string.Format("At location '{0}', a plugin item with id '{1}' is already registered",
                                                           itemMetadata.RegistrationLocation, itemMetadata.Id));
             }
         }
         PluginItemRegistration resultItemRegistration = new PluginItemRegistration(itemMetadata);
         node.AddItem(itemMetadata.Id, resultItemRegistration);
         _itemRegistrations.Add(itemMetadata, resultItemRegistration);
     }
     return(true);
 }
        /// <summary>
        /// Returns all plugin item change listeners for the given <paramref name="location"/>.
        /// </summary>
        /// <param name="location">Location to return the listeners for.</param>
        /// <param name="createOnNotExist">If set to <c>true</c>, the plugin tree node will be created, if it doesn't exist.</param>
        /// <remarks>
        /// The plugin manager's synchronization object must be locked when this method is called.
        /// </remarks>
        protected static ICollection <IItemRegistrationChangeListener> GetListenersForLocation(string location, bool createOnNotExist)
        {
            IRegistryNode node = GetRegistryNode(location, createOnNotExist);

            if (node == null)
            {
                return(null);
            }
            object resultObj;

            if (node.Items != null && node.Items.TryGetValue(ITEMCHANGELISTENER_ID, out resultObj))
            {
                return((ICollection <IItemRegistrationChangeListener>)resultObj);
            }
            if (createOnNotExist)
            {
                ICollection <IItemRegistrationChangeListener> result = new List <IItemRegistrationChangeListener>();
                node.AddItem(ITEMCHANGELISTENER_ID, result);
                return(result);
            }
            return(null);
        }