internal static string SprCompileFn(string strText, PwListItem li)
        {
            if (string.IsNullOrEmpty(strText))
            {
                return(string.Empty);
            }

            string str = null;

            while (str == null)
            {
                try
                {
                    SprContext ctx = MainForm.GetEntryListSprContext(li.Entry,
                                                                     Program.MainForm.DocumentManager.SafeFindContainerOf(
                                                                         li.Entry));
                    str = SprEngine.Compile(strText, ctx);
                }
                catch (InvalidOperationException) { }             // Probably collection changed
                catch (NullReferenceException) { }                // Objects disposed already
                catch (Exception) { Debug.Assert(false); }
            }

            if (Program.Config.MainWindow.EntryListShowDerefDataAndRefs && (str != strText))
            {
                str += " - " + strText;
            }

            return(StrUtil.MultiToSingleLine(str));
        }
        internal static string SprCompileFn(string strText, PwListItem li)
        {
            string strCmp = null;

            while (strCmp == null)
            {
                try
                {
                    strCmp = SprEngine.Compile(strText, MainForm.GetEntryListSprContext(
                                                   li.Entry, Program.MainForm.DocumentManager.SafeFindContainerOf(
                                                       li.Entry)));
                }
                catch (InvalidOperationException) { }             // Probably collection changed
                catch (NullReferenceException) { }                // Objects disposed already
                catch (Exception) { Debug.Assert(false); }
            }

            if (strCmp == strText)
            {
                return(strText);
            }

            return(Program.Config.MainWindow.EntryListShowDerefDataAndRefs ?
                   (strCmp + " - " + strText) : strCmp);
        }
        public void Queue(string strText, PwListItem li, int iIndexHint,
                          int iSubItem, PwTextUpdateDelegate f)
        {
            if (strText == null)
            {
                Debug.Assert(false); return;
            }
            if (li == null)
            {
                Debug.Assert(false); return;
            }
            if (iSubItem < 0)
            {
                Debug.Assert(false); return;
            }
            if (f == null)
            {
                Debug.Assert(false); return;
            }

            LviUpdInfo state = new LviUpdInfo();

            state.ListView           = m_lv;
            state.UpdateID           = unchecked ((li.ListViewItemID << 6) + iSubItem);
            state.Text               = strText;
            state.ListItem           = li;
            state.IndexHint          = ((iIndexHint >= 0) ? iIndexHint : 0);
            state.SubItem            = iSubItem;
            state.Function           = f;
            state.ListEditSyncObject = m_objListEditSync;
            state.ValidIDsSyncObject = m_objValidIDsSync;
            state.ValidIDs           = m_dValidIDs;

            lock (m_objValidIDsSync)
            {
                Debug.Assert(!m_dValidIDs.ContainsKey(state.UpdateID));
                m_dValidIDs[state.UpdateID] = true;
            }

            try
            {
                if (!ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateItemFn),
                                                  state))
                {
                    throw new InvalidOperationException();
                }
            }
            catch (Exception)
            {
                Debug.Assert(false);
                lock (m_objValidIDsSync) { m_dValidIDs.Remove(state.UpdateID); }
            }
        }
        private static void SetItemText(string strText, LviUpdInfo lui)
        {
            try             // Avoid cross-thread exceptions
            {
                long lTargetID  = lui.ListItem.ListViewItemID;
                int  iIndexHint = lui.IndexHint;

                lock (lui.ListEditSyncObject)
                {
                    ListView.ListViewItemCollection lvic = lui.ListView.Items;
                    int nCount = lvic.Count;

                    // for(int i = 0; i < nCount; ++i)
                    for (int i = nCount; i > 0; --i)
                    {
                        int          j   = ((iIndexHint + i) % nCount);
                        ListViewItem lvi = lvic[j];

                        PwListItem li = (lvi.Tag as PwListItem);
                        if (li == null)
                        {
                            Debug.Assert(false); continue;
                        }

                        if (li.ListViewItemID != lTargetID)
                        {
                            continue;
                        }

                        lvi.SubItems[lui.SubItem].Text = strText;
                        break;
                    }
                }
            }
            catch (Exception) { Debug.Assert(false); }
        }
		/// <summary>
		/// Create or set an entry list view item.
		/// </summary>
		/// <param name="pe">Entry.</param>
		/// <param name="lviTarget">If <c>null</c>, a new list view item is
		/// created and added to the list (a group is created if necessary).
		/// If not <c>null</c>, the properties are stored in this item (no
		/// list view group is created and the list view item is not added
		/// to the list).</param>
		/// <returns>Created or modified list view item.</returns>
		private ListViewItem SetListEntry(PwEntry pe, ListViewItem lviTarget)
		{
			if(pe == null) { Debug.Assert(false); return null; }

			ListViewItem lvi = (lviTarget ?? new ListViewItem());

			PwListItem pli = new PwListItem(pe);
			if(lviTarget == null) lvi.Tag = pli; // Lock below (when adding it)
			else
			{
				lock(m_asyncListUpdate.ListEditSyncObject) { lvi.Tag = pli; }
			}

			int iIndexHint = ((lviTarget != null) ? lviTarget.Index :
				m_lvEntries.Items.Count);

			if(pe.Expires && (pe.ExpiryTime <= m_dtCachedNow))
			{
				lvi.ImageIndex = (int)PwIcon.Expired;
				if(m_fontExpired != null) lvi.Font = m_fontExpired;
			}
			else // Not expired
			{
				// Reset font, if item was expired previously (i.e. has expired font)
				if((lviTarget != null) && (lvi.ImageIndex == (int)PwIcon.Expired))
					lvi.Font = m_lvEntries.Font;

				if(pe.CustomIconUuid.Equals(PwUuid.Zero))
					lvi.ImageIndex = (int)pe.IconId;
				else
					lvi.ImageIndex = (int)PwIcon.Count +
						m_docMgr.ActiveDatabase.GetCustomIconIndex(pe.CustomIconUuid);
			}

			if(m_bEntryGrouping && (lviTarget == null))
			{
				PwGroup pgContainer = pe.ParentGroup;
				PwGroup pgLast = ((m_lvgLastEntryGroup != null) ?
					(PwGroup)m_lvgLastEntryGroup.Tag : null);

				Debug.Assert(pgContainer != null);
				if(pgContainer != null)
				{
					if(pgContainer != pgLast)
					{
						m_lvgLastEntryGroup = new ListViewGroup(
							pgContainer.GetFullPath(" - ", false));
						m_lvgLastEntryGroup.Tag = pgContainer;

						m_lvEntries.Groups.Add(m_lvgLastEntryGroup);
					}

					lvi.Group = m_lvgLastEntryGroup;
				}
			}

			if(!pe.ForegroundColor.IsEmpty)
				lvi.ForeColor = pe.ForegroundColor;
			else if(lviTarget != null) lvi.ForeColor = m_lvEntries.ForeColor;
			else { Debug.Assert(UIUtil.ColorsEqual(lvi.ForeColor, m_lvEntries.ForeColor)); }

			if(!pe.BackgroundColor.IsEmpty)
				lvi.BackColor = pe.BackgroundColor;
			// else if(Program.Config.MainWindow.EntryListAlternatingBgColors &&
			//	((m_lvEntries.Items.Count & 1) == 1))
			//	lvi.BackColor = m_clrAlternateItemBgColor;
			else if(lviTarget != null) lvi.BackColor = m_lvEntries.BackColor;
			else { Debug.Assert(UIUtil.ColorsEqual(lvi.BackColor, m_lvEntries.BackColor)); }

			bool bAsync;

			// m_bOnlyTans &= PwDefs.IsTanEntry(pe);
			if(m_bShowTanIndices && m_bOnlyTans)
			{
				string strIndex = pe.Strings.ReadSafe(PwDefs.TanIndexField);

				// KPF 1151
				if(Program.Config.MainWindow.EntryListShowDerefData &&
					SprEngine.MightDeref(strIndex))
					strIndex = AsyncPwListUpdate.SprCompileFn(strIndex, pli);

				if(strIndex.Length > 0) lvi.Text = strIndex;
				else lvi.Text = PwDefs.TanTitle;
			}
			else
			{
				string strMain = GetEntryFieldEx(pe, 0, true, out bAsync);
				lvi.Text = strMain;
				if(bAsync)
					m_asyncListUpdate.Queue(strMain, pli, iIndexHint, 0,
						AsyncPwListUpdate.SprCompileFn);
			}

			int nColumns = m_lvEntries.Columns.Count;
			if(lviTarget == null)
			{
				for(int iColumn = 1; iColumn < nColumns; ++iColumn)
				{
					string strSub = GetEntryFieldEx(pe, iColumn, true, out bAsync);
					lvi.SubItems.Add(strSub);
					if(bAsync)
						m_asyncListUpdate.Queue(strSub, pli, iIndexHint, iColumn,
							AsyncPwListUpdate.SprCompileFn);
				}
			}
			else
			{
				int nSubItems = lvi.SubItems.Count;
				for(int iColumn = 1; iColumn < nColumns; ++iColumn)
				{
					string strSub = GetEntryFieldEx(pe, iColumn, true, out bAsync);

					if(iColumn < nSubItems) lvi.SubItems[iColumn].Text = strSub;
					else lvi.SubItems.Add(strSub);

					if(bAsync)
						m_asyncListUpdate.Queue(strSub, pli, iIndexHint, iColumn,
							AsyncPwListUpdate.SprCompileFn);
				}

				Debug.Assert(lvi.SubItems.Count == nColumns);
			}

			if(lviTarget == null)
			{
				lock(m_asyncListUpdate.ListEditSyncObject)
				{
					m_lvEntries.Items.Add(lvi);
				}
			}
			return lvi;
		}
		private string GetEntryFieldEx(PwEntry pe, int iColumnID,
			bool bFormatForDisplay, out bool bRequestAsync)
		{
			List<AceColumn> l = Program.Config.MainWindow.EntryListColumns;
			if((iColumnID < 0) || (iColumnID >= l.Count))
			{
				Debug.Assert(false);
				bRequestAsync = false;
				return string.Empty;
			}

			AceColumn col = l[iColumnID];
			if(bFormatForDisplay && col.HideWithAsterisks)
			{
				bRequestAsync = false;
				return PwDefs.HiddenPassword;
			}

			string str;
			switch(col.Type)
			{
				case AceColumnType.Title: str = pe.Strings.ReadSafe(PwDefs.TitleField); break;
				case AceColumnType.UserName: str = pe.Strings.ReadSafe(PwDefs.UserNameField); break;
				case AceColumnType.Password: str = pe.Strings.ReadSafe(PwDefs.PasswordField); break;
				case AceColumnType.Url: str = pe.Strings.ReadSafe(PwDefs.UrlField); break;
				case AceColumnType.Notes:
					if(!bFormatForDisplay) str = pe.Strings.ReadSafe(PwDefs.NotesField);
					else str = StrUtil.MultiToSingleLine(pe.Strings.ReadSafe(PwDefs.NotesField));
					break;
				case AceColumnType.CreationTime: str = TimeUtil.ToDisplayString(pe.CreationTime); break;
				case AceColumnType.LastModificationTime: str = TimeUtil.ToDisplayString(pe.LastModificationTime); break;
				case AceColumnType.LastAccessTime: str = TimeUtil.ToDisplayString(pe.LastAccessTime); break;
				case AceColumnType.ExpiryTime:
					if(pe.Expires) str = TimeUtil.ToDisplayString(pe.ExpiryTime);
					else str = m_strNeverExpiresText;
					break;
				case AceColumnType.Uuid: str = pe.Uuid.ToHexString(); break;
				case AceColumnType.Attachment: str = pe.Binaries.KeysToString(); break;
				case AceColumnType.CustomString:
					if(!bFormatForDisplay) str = pe.Strings.ReadSafe(col.CustomName);
					else str = StrUtil.MultiToSingleLine(pe.Strings.ReadSafe(col.CustomName));
					break;
				case AceColumnType.PluginExt:
					if(!bFormatForDisplay) str = Program.ColumnProviderPool.GetCellData(col.CustomName, pe);
					else str = StrUtil.MultiToSingleLine(Program.ColumnProviderPool.GetCellData(col.CustomName, pe));
					break;
				case AceColumnType.OverrideUrl: str = pe.OverrideUrl; break;
				case AceColumnType.Tags:
					str = StrUtil.TagsToString(pe.Tags, true);
					break;
				case AceColumnType.ExpiryTimeDateOnly:
					if(pe.Expires) str = TimeUtil.ToDisplayStringDateOnly(pe.ExpiryTime);
					else str = m_strNeverExpiresText;
					break;
				case AceColumnType.Size:
					str = StrUtil.FormatDataSizeKB(pe.GetSize());
					break;
				case AceColumnType.HistoryCount:
					str = pe.History.UCount.ToString();
					break;
				case AceColumnType.AttachmentCount:
					uint uc = pe.Binaries.UCount;
					str = ((uc > 0) ? uc.ToString() : string.Empty);
					break;
				default: Debug.Assert(false); str = string.Empty; break;
			}

			if(Program.Config.MainWindow.EntryListShowDerefData)
			{
				switch(col.Type)
				{
					case AceColumnType.Title:
					case AceColumnType.UserName:
					case AceColumnType.Password:
					case AceColumnType.Url:
					case AceColumnType.Notes:
					case AceColumnType.CustomString:
						bRequestAsync = SprEngine.MightDeref(str);
						break;
					default: bRequestAsync = false; break;
				}

				if(!Program.Config.MainWindow.EntryListShowDerefDataAsync &&
					bRequestAsync)
				{
					PwListItem pli = new PwListItem(pe);
					str = AsyncPwListUpdate.SprCompileFn(str, pli);
					bRequestAsync = false;
				}
			}
			else bRequestAsync = false;

			return str;
		}
		internal static string SprCompileFn(string strText, PwListItem li)
		{
			string strCmp = null;
			while(strCmp == null)
			{
				try
				{
					strCmp = SprEngine.Compile(strText, MainForm.GetEntryListSprContext(
						li.Entry, Program.MainForm.DocumentManager.SafeFindContainerOf(
						li.Entry)));
				}
				catch(InvalidOperationException) { } // Probably collection changed
				catch(NullReferenceException) { } // Objects disposed already
				catch(Exception) { Debug.Assert(false); }
			}

			if(strCmp == strText) return strText;

			return (Program.Config.MainWindow.EntryListShowDerefDataAndRefs ?
				(strCmp + " - " + strText) : strCmp);
		}
		public void Queue(string strText, PwListItem li, int iIndexHint,
			int iSubItem, PwTextUpdateDelegate f)
		{
			if(strText == null) { Debug.Assert(false); return; }
			if(li == null) { Debug.Assert(false); return; }
			if(iSubItem < 0) { Debug.Assert(false); return; }
			if(f == null) { Debug.Assert(false); return; }

			LviUpdInfo state = new LviUpdInfo();
			state.ListView = m_lv;
			state.UpdateID = unchecked((li.ListViewItemID << 6) + iSubItem);
			state.Text = strText;
			state.ListItem = li;
			state.IndexHint = ((iIndexHint >= 0) ? iIndexHint : 0);
			state.SubItem = iSubItem;
			state.Function = f;
			state.ListEditSyncObject = m_objListEditSync;
			state.ValidIDsSyncObject = m_objValidIDsSync;
			state.ValidIDs = m_dValidIDs;

			lock(m_objValidIDsSync)
			{
				Debug.Assert(!m_dValidIDs.ContainsKey(state.UpdateID));
				m_dValidIDs[state.UpdateID] = true;
			}

			try
			{
				if(!ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateItemFn),
					state)) throw new InvalidOperationException();
			}
			catch(Exception)
			{
				Debug.Assert(false);
				lock(m_objValidIDsSync) { m_dValidIDs.Remove(state.UpdateID); }
			}
		}
            // Ported from KeePass Mainform_functions SetListEntry
            internal static ListViewItem InsertListEntryOLD(PwEntry pe, int iIndex)
            {
                // Adapted variables
                DateTime m_dtCachedNow = DateTime.Now;
                Font m_fontExpired = FontUtil.CreateFont(m_lvEntries.Font, FontStyle.Strikeout);
                bool m_bEntryGrouping = m_lvEntries.ShowGroups;
                bool m_bShowTanIndices = Program.Config.MainWindow.TanView.ShowIndices;
                bool bSubEntries = Program.Config.MainWindow.ShowEntriesOfSubGroups;
                ListViewGroup m_lvgLastEntryGroup = null;
                foreach (ListViewGroup lvg in m_lvEntries.Groups)
                {
                    if ((lvg.Tag as PwGroup) == pe.ParentGroup)
                        m_lvgLastEntryGroup = lvg;
                }
                PwGroup pg = (Program.MainForm.GetSelectedGroup());
                PwObjectList<PwEntry> pwlSource = ((pg != null) ? pg.GetEntries(bSubEntries) : new PwObjectList<PwEntry>());
                bool m_bOnlyTans = ListContainsOnlyTans(pwlSource);

                ListViewItem lviTarget = null;
                Color m_clrAlternateItemBgColor = UIUtil.GetAlternateColor(m_lvEntries.BackColor);

                if (pe == null) { Debug.Assert(false); return null; }

                ListViewItem lvi = (lviTarget ?? new ListViewItem());
                PwListItem pli = new PwListItem(pe);
                lvi.Tag = pli;

                //lvi.BeginUpdate();

                if (pe.Expires && (pe.ExpiryTime <= m_dtCachedNow))
                {
                    lvi.ImageIndex = (int)PwIcon.Expired;
                    if (m_fontExpired != null) lvi.Font = m_fontExpired;
                }
                else // Not expired
                {
                    // Reset font, if item was expired previously (i.e. has expired font)
                    if ((lviTarget != null) && (lvi.ImageIndex == (int)PwIcon.Expired))
                        lvi.Font = m_lvEntries.Font;

                    if (pe.CustomIconUuid.EqualsValue(PwUuid.Zero))
                        lvi.ImageIndex = (int)pe.IconId;
                    else
                        lvi.ImageIndex = (int)PwIcon.Count +
                            m_host.MainWindow.DocumentManager.ActiveDatabase.GetCustomIconIndex(pe.CustomIconUuid);
                }

                if (m_bEntryGrouping && (lviTarget == null))
                {
                    PwGroup pgContainer = pe.ParentGroup;
                    PwGroup pgLast = ((m_lvgLastEntryGroup != null) ?
                        (PwGroup)m_lvgLastEntryGroup.Tag : null);

                    Debug.Assert(pgContainer != null);
                    if (pgContainer != null)
                    {
                        if (pgContainer != pgLast)
                        {
                            m_lvgLastEntryGroup = new ListViewGroup(
                                pgContainer.GetFullPath());
                            m_lvgLastEntryGroup.Tag = pgContainer;

                            m_lvEntries.Groups.Add(m_lvgLastEntryGroup);
                        }

                        lvi.Group = m_lvgLastEntryGroup;
                    }
                }

                if (!pe.ForegroundColor.IsEmpty)
                    lvi.ForeColor = pe.ForegroundColor;
                else if (lviTarget != null) lvi.ForeColor = m_lvEntries.ForeColor;
                else { Debug.Assert(UIUtil.ColorsEqual(lvi.ForeColor, m_lvEntries.ForeColor)); }

                if (!pe.BackgroundColor.IsEmpty)
                    lvi.BackColor = pe.BackgroundColor;
                // else if(Program.Config.MainWindow.EntryListAlternatingBgColors &&
                //	((m_lvEntries.Items.Count & 1) == 1))
                //	lvi.BackColor = m_clrAlternateItemBgColor;
                else if (lviTarget != null) lvi.BackColor = m_lvEntries.BackColor;
                else { Debug.Assert(UIUtil.ColorsEqual(lvi.BackColor, m_lvEntries.BackColor)); }

                // m_bOnlyTans &= PwDefs.IsTanEntry(pe);
                if (m_bShowTanIndices && m_bOnlyTans)
                {
                    string strIndex = pe.Strings.ReadSafe(PwDefs.TanIndexField);

                    if (strIndex.Length > 0) lvi.Text = strIndex;
                    else lvi.Text = PwDefs.TanTitle;
                }
                else lvi.Text = GetEntryFieldEx(pe, 0, true);

                int nColumns = m_lvEntries.Columns.Count;
                if (lviTarget == null)
                {
                    for (int iColumn = 1; iColumn < nColumns; ++iColumn)
                        lvi.SubItems.Add(GetEntryFieldEx(pe, iColumn, true));
                }
                else
                {
                    int nSubItems = lvi.SubItems.Count;
                    for (int iColumn = 1; iColumn < nColumns; ++iColumn)
                    {
                        string strSub = GetEntryFieldEx(pe, iColumn, true);
                        if (iColumn < nSubItems) lvi.SubItems[iColumn].Text = strSub;
                        else lvi.SubItems.Add(strSub);
                    }

                    Debug.Assert(lvi.SubItems.Count == nColumns);
                }

                //if (lviTarget == null) m_lvEntries.Items.Add(lvi);
                if (lviTarget == null) m_lvEntries.Items.Insert(iIndex, lvi);

                UIUtil.SetAlternatingBgColors(m_lvEntries, m_clrAlternateItemBgColor,
                    Program.Config.MainWindow.EntryListAlternatingBgColors);

                //lvi.EndUpdate();

                return lvi;
            }