public EntryItemViewModel(Entry entry, TreeViewItemViewModel parent, ManifestEditorViewModel editor, Descriptor descriptor)
			: base(parent)
		{
			if (entry == null)
				throw new ArgumentNullException("entry", "entry is null.");
			if (parent == null)
				throw new ArgumentNullException("parent", "parent is null.");
			if (editor == null)
				throw new ArgumentNullException("editor", "editor is null.");
			if (descriptor == null)
				throw new ArgumentNullException("descriptor", "descriptor is null.");


			_descriptor = descriptor;
			Entry = entry;
			_editor = editor;
			_entryEditor = new EntryEditorViewModel(entry, editor);
		    TreeItemLabel = entry.Name;
		    _entryEditor.PropertyChanged += (_, args) => { if (args.PropertyName == "Name") TreeItemLabel = entry.Name; };
			_collection = parent as IEntryItemCollection;
			if (_collection != null)
			{
				MenuItems = new List<MenuItemViewModel> { new MenuItemViewModel("Remove CI", new DelegateCommand(DoRemove), null) };
			}
			IsExpanded = true;
		}
	    private void DoAdd(Descriptor descriptor)
	    {
	        var entry = new Entry {Type = descriptor.Type};
	        entry.Name = string.Format("New {0}", entry.Type);
	        var item = new EntryItemViewModel(entry, this, _editor, descriptor) {IsSelected = true};
	        Children.Add(item);
	        _editor.CurrentItemEditor = item.ItemEditor;
	    }
        public SetOfCIViewModel(ManifestEditorViewModel m, DescriptorProperty pd, Entry entry) : base(m, pd, entry)
        {
            var entryProperty = GetEntryProperty();
            var ciSet = (entryProperty == null ? new HashSet<string>() : entryProperty.GetSetOfCI());

            CiRefs = new ObservableCollection<string>(ciSet);
            if (CiRefs.Count == 0) { CiRefs.Add(NO_CIS); }
        }
        public ListOfCIViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
            :base(manifestEditor, propertyDescriptor, entry)
        {
            var entryProperty = GetEntryProperty();
            var ciSet = (entryProperty == null ? new List<string>{ SetOfCIViewModel.NO_CIS } : entryProperty.GetListOfCI());

            CiRefs = new ObservableCollection<string>(ciSet);
            SelectedCIIndex = -1;
        }
		public ListOrSetOfStringEditorViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
			: base(manifestEditor, propertyDescriptor, entry)
		{
			var property = GetEntryProperty();
		    if (property == null) return;

		    var items = property.GetListofStringValue();
		    if (items.Count > 0)
		    {
		        Value = string.Join(Environment.NewLine, items);
		    }
		}
		public IntegerPropertyEntryEditorViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
			: base(manifestEditor, propertyDescriptor, entry)
		{
			var property = GetEntryProperty();
		    if (property == null) { return; }

		    var intValue = property.GetIntValue();
		    if (intValue.HasValue)
		    {
		        _stringValue = intValue.Value.ToString(CultureInfo.InvariantCulture);
		    }
		}
 public BooleanPropertyEntryEditorViewModel(ManifestEditorViewModel manifestEditor,
                                            DescriptorProperty propertyDescriptor, Entry entry)
     : base(manifestEditor, propertyDescriptor, entry)
 {
     AvailableValues = new List<KeyValuePair<string, bool?>>
         {
             new KeyValuePair<string, bool?>(Resources.PROPERTY_BOOL_TRUE, true),
             new KeyValuePair<string, bool?>(Resources.PROPERTY_BOOL_FALSE, false),
             new KeyValuePair<string, bool?>(Resources.PROPERTY_BOOL_ND, null)
         };
     EntryProperty property = GetEntryProperty();
     if (property != null)
     {
         Value = property.GetBoolValue();
     }
 }
		public StringPropertyEntryEditorViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
			: base(manifestEditor, propertyDescriptor, entry)
		{

			var property = GetEntryProperty();

			if (property != null)
			{
				Value = property.GetStringValue() ?? string.Empty;
			}
			else
			{
				if (propertyDescriptor != null && propertyDescriptor.DefaultValue != null)
				{
					Value = propertyDescriptor.DefaultValue;
				}
			}
		}
        public EnumPropertyEntryEditorViewModel(ManifestEditorViewModel manifestEditor,
                                                DescriptorProperty propertyDescriptor, Entry entry)
            : base(manifestEditor, propertyDescriptor, entry)
        {
            var values = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>(Resources.PROPERTY_ENUM_ND, null)
                };

            values.AddRange(propertyDescriptor.EnumValues.Select(_ => new KeyValuePair<string, string>(_, _)));

            AvailableValues = values;

            EntryProperty property = GetEntryProperty();
            if (property != null)
            {
                Value = property.GetEnumValue();
            }
        }
		public MapStringStringEditorViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
			: base(manifestEditor, propertyDescriptor, entry)
		{
			Items = new ObservableCollection<MapStringOfStringItemViewModel>();
		}
		protected PropertyEntryEditorViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
		{
			ManifestEditor = manifestEditor;
			PropertyDescriptor = propertyDescriptor;
			Entry = entry;
		}
 public CIReferenceViewModel(ManifestEditorViewModel manifestEditor, DescriptorProperty propertyDescriptor, Entry entry)
     : base(manifestEditor, propertyDescriptor, entry)
 {
     var entryProperty = GetEntryProperty();
     ReferencedCI = entryProperty == null ? "" : entryProperty.GetCIReferenceValue();
 }
        internal static Entry Load(XElement xmlElement)
        {
            var result = new Entry
                {
                    Type = xmlElement.Name.ToString(),
                    Name = xmlElement.Attribute("name").Value
                };

            var pathAttribute = xmlElement.Attribute("file");
            if (pathAttribute != null)
            {
                result.Path = pathAttribute.Value;
            }

            var p = from property in xmlElement.Elements()
                    select new EntryProperty(property);

            result.Properties.AddRange(p);

            return result;
        }
		/// <summary>
		/// Initializes a new instance of the EntryEditorViewModel class.
		/// </summary>
		public EntryEditorViewModel(Entry entry, ManifestEditorViewModel manifestEditor)
		{
			Entry = entry;
			_manifestEditor = manifestEditor;

		    Descriptor = _manifestEditor.GetDescriptor(entry.Type, true);
            if (Descriptor == null)
            {
                IsEditable = false;
				Categories = new List<PropertyEntryCategoryEditorViewModel>();
                return;
            }

			IsArtifact = Descriptor.Interfaces.Contains("udm.DeployableArtifact");

			var categoryQuery = from p in Descriptor.Properties
								where !p.Hidden
								orderby p.Category ascending
								let categoryName = p.Category ?? "Common"
								let propertyViewModel = GetPropertyEditor(p)
								where propertyViewModel != null
								group propertyViewModel by categoryName into category
								select new PropertyEntryCategoryEditorViewModel(category.Key, category);

			Categories = categoryQuery.ToList();
			CurrentViewedCategory = Categories[0];

			IsEditable = true;
		}