ListItemEditor(EditAction editAction, ListItem listItem, ObservableList <ListContentType> contentTypes, ListContentType contentType)
        {
            this.editAction = editAction;
            ContentTypes    = contentTypes;
            ContentType     = contentType;


            switch (editAction.EditMode)
            {
            case EditMode.Edit:
                Title = string.Format("Edit item {0}", listItem.ID);
                break;

            case EditMode.Copy:
                Title = string.Format("Copy item {0}", listItem.ID);
                break;

            case EditMode.AddItem:
                Title = "Add new item";
                break;

            case EditMode.AddFolder:
                Title = "Add new folder";
                break;
            }

            ListItem          = listItem;
            window.Value.Data = this;
            window.Value.Show();
            disposable = ListItem.Advise(Notify);
        }
        internal static async void Show(EditAction editAction)
        {
            ListItem listItem = null;
            ObservableList <ListContentType> affectedContentTypes = null;
            ListContentType contentType = null;

            if (await LazyWindow.ShowWaiting(
                    async delegate(CancellationToken cancellationToken)
            {
                switch (editAction.EditMode)
                {
                case EditMode.Edit:
                    listItem = await editAction.ListItem.ParentList.GetItemById(editAction.ListItem.ID, cancellationToken);
                    break;

                case EditMode.Copy:
                    listItem = await editAction.ListItem.ParentList.GetItemById(editAction.ListItem.ID, cancellationToken);
                    break;

                case EditMode.AddItem:
                    listItem = editAction.TargetList.Add(FileSystemObjectType.File);
                    listItem.MoveTo(editAction.TargetFolder);
                    break;

                case EditMode.AddFolder:
                    listItem = editAction.TargetList.Add(FileSystemObjectType.Folder);
                    listItem.MoveTo(editAction.TargetFolder);
                    break;

                default:
                    throw new ApplicationException("Unexpected");
                }

                ObservableList <ListContentType> contentTypes = await editAction.TargetList.ContentTypes.GetAsync(cancellationToken);
                affectedContentTypes = new ObservableList <ListContentType>();
                foreach (ListContentType hit in contentTypes)
                {
                    if (hit.ID.StartsWith(BuiltInContentTypeIds.Folder) == (listItem.FileSystemObjectType == FileSystemObjectType.Folder))
                    {
                        affectedContentTypes.Add(hit);
                        if (hit.ID == listItem.ContentTypeId)
                        {
                            contentType = hit;
                        }
                    }
                }
                if (contentType == null && affectedContentTypes.Count != 0)
                {
                    contentType = affectedContentTypes[0];
                    listItem.ContentTypeId = contentType.ID;
                }

                contentType.NotNull("Unknown content type");

                if (editAction.EditMode == EditMode.Copy)
                {
                    ContentTypeDetail contentTypeDetail = await contentType.Detail.GetAsync(cancellationToken);
                    ListItem newListItem = listItem.ParentList.Add(listItem.FileSystemObjectType);
                    newListItem.ContentTypeId = listItem.ContentTypeId;
                    for (int i = 0; i < contentTypeDetail.Fields.Count; i++)
                    {
                        Field field = contentTypeDetail.Fields[i];
                        if (field.ShowInEditForm && !field.ReadOnly)
                        {
                            newListItem[field] = listItem[field];
                        }
                    }
                    newListItem.MoveTo(editAction.TargetFolder);
                    listItem.Dispose();
                    listItem = newListItem;
                }
            }))
            {
                new ListItemEditor(editAction, listItem, affectedContentTypes, contentType);
            }
            else
            {
                listItem?.Dispose();
            }
        }