private bool CommitOptions() { options.CheckMode = radioButtonOffline.Checked ? Options.CheckModeType.Offline : Options.CheckModeType.Online; options.HIBPFileName = textBoxFileName.Text; options.ColumnName = textBoxColumnName.Text; options.SecureText = textBoxSecureText.Text; options.InsecureText = textBoxInsecureText.Text; options.BreachCountDetails = checkBoxBreachCountDetails.Checked; options.WarningDialog = checkBoxWarningDialog.Checked; options.WarningDialogText = textBoxWarningDialog.Text; var standardFields = PwDefs.GetStandardFields(); foreach (string key in standardFields) { if (key == options.ColumnName) { MessageBox.Show("Column name conflicts with KeePass columns", " Invalid column name", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } ext.SaveOptions(options); return(true); }
private void FieldAction(ToolStripMenuItem Item, string FieldName, FIELD_ACTION action) { if (Item == null) { return; } PwEntry Entry = (PwEntry)Item.Tag; if (Entry == null) { return; } SetLastOne(Item); if (FieldName == PwDefs.PasswordField && PwDefs.IsTanEntry(Entry)) { Entry.ExpiryTime = DateTime.Now; Entry.Expires = true; Host.MainWindow.RefreshEntriesList(); Host.MainWindow.UpdateUI(false, null, false, null, false, null, true); } if (action == FIELD_ACTION.CLIPBOARD_COPY) { ClipboardUtil.CopyAndMinimize(Entry.Strings.GetSafe(FieldName), true, Program.Config.MainWindow.MinimizeAfterClipboardCopy ? Host.MainWindow : null, Entry, Host.MainWindow.DocumentManager.ActiveDatabase); Host.MainWindow.StartClipboardCountdown(); } else if (action == FIELD_ACTION.DRAG_DROP) { Item.DoDragDrop(Entry.Strings.ReadSafe(FieldName), DragDropEffects.Copy); } }
protected virtual void OnEntryChanged(EventArgs e) { if (Entry == null) { ClearObjects(); } else { var rows = new List <RowObject>(); // First, the standard fields, where present, in the standard order AddFieldIfNotEmpty(rows, PwDefs.TitleField); AddFieldIfNotEmpty(rows, PwDefs.UserNameField); AddFieldIfNotEmpty(rows, PwDefs.PasswordField); AddFieldIfNotEmpty(rows, PwDefs.UrlField); // Then, all custom strings rows.AddRange(from kvp in Entry.Strings where !PwDefs.IsStandardField(kvp.Key) && !IsExcludedField(kvp.Key) select new RowObject(kvp)); // Finally, an empty "add new" row rows.Add(RowObject.CreateInsertionRow()); SetRows(rows); } AllowCreateHistoryNow = true; // Whenever the entry is replaced, it counts as not having been edited yet (so the first edit is always given a history backup) }
protected override void DeleteFieldCommand(RowObject rowObject) { CreateHistoryEntry(); if (PwDefs.IsStandardField(rowObject.FieldName)) { var blankValue = new ProtectedString(rowObject.Value.IsProtected, new byte[0]); Entry.Strings.Set(rowObject.FieldName, blankValue); if (mOptions.HideEmptyFields) { RemoveObject(rowObject); } else { rowObject.Value = blankValue; RefreshObject(rowObject); } } else { Entry.Strings.Remove(rowObject.FieldName); RemoveObject(rowObject); } OnModified(EventArgs.Empty); }
private void buttonOK_Click(object sender, EventArgs e) { options.HIBPFileName = textBoxFileName.Text; options.ColumnName = textBoxColumnName.Text; options.SecureText = textBoxSecureText.Text; options.InsecureText = textBoxInsecureText.Text; options.BreachCountDetails = checkBoxBreachCountDetails.Checked; options.WarningDialog = checkBoxWarningDialog.Checked; options.WarningDialogText = textBoxWarningDialog.Text; var standardFields = PwDefs.GetStandardFields(); foreach (string key in standardFields) { if (key == options.ColumnName) { MessageBox.Show("Column name conflicts with KeePass columns", " Invalid column name", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } ext.SaveOptions(options); this.Close(); }
private static void MsAppend(PwEntry pe, string strFieldName, string[] vLine, int iIndex, PwDatabase pdContext) { if (iIndex >= vLine.Length) { Debug.Assert(false); return; } string strValue = vLine[iIndex]; if (string.IsNullOrEmpty(strValue)) { return; } strValue = strValue.Replace("\\r\\n", "\\n"); strValue = strValue.Replace("\\r", "\\n"); if (PwDefs.IsStandardField(strFieldName) && (strFieldName != PwDefs.NotesField)) { while (strValue.EndsWith("\\n")) { strValue = strValue.Substring(0, strValue.Length - 2); } strValue = strValue.Replace("\\n", ", "); } else { strValue = strValue.Replace("\\n", MessageService.NewLine); } ImportUtil.AppendToField(pe, strFieldName, strValue, pdContext); }
protected override void ValidateFieldName(CellEditEventArgs e, string newValue) { base.ValidateFieldName(e, newValue); if (PwDefs.IsStandardField(newValue)) { ReportValidationFailure(e.Control, KPRes.FieldNameInvalid); e.Cancel = true; return; } var rowObject = (RowObject)e.RowObject; IEnumerable <PwEntry> entriesWithField; if (rowObject.IsInsertionRow) { entriesWithField = Entries; } else { entriesWithField = Entries.Where(entry => entry.Strings.Exists(rowObject.FieldName)); } // Disallow the field name if it already exists on any of the entries which have that field foreach (var entry in entriesWithField) { if (entry.Strings.Exists(newValue)) { ReportValidationFailure(e.Control, KPRes.FieldNameExistsAlready); e.Cancel = true; return; } } }
private static void ReadCustomField(XmlNode xmlNode, PwEntry pe) { string strName = string.Empty, strValue = string.Empty; foreach (XmlNode xmlChild in xmlNode) { if (xmlChild.Name == ElemCustomFieldName) { strName = XmlUtil.SafeInnerText(xmlChild); } else if (xmlChild.Name == ElemCustomFieldValue) { strValue = XmlUtil.SafeInnerText(xmlChild); } // else { } // Field 'VISIBLE' } if ((strName.Length == 0) || PwDefs.IsStandardField(strName)) { pe.Strings.Set(Guid.NewGuid().ToString(), new ProtectedString(false, strValue)); } else { pe.Strings.Set(strName, new ProtectedString(false, strValue)); } }
public int CompareEntries(PwEntry x, PwEntry y) { String nameX = x.Strings.ReadSafe(PwDefs.TitleField); String nameY = y.Strings.ReadSafe(PwDefs.TitleField); if (nameX.ToLower() != nameY.ToLower()) { return(String.Compare(nameX, nameY, StringComparison.CurrentCultureIgnoreCase)); } else { if (PwDefs.IsTanEntry(x) && PwDefs.IsTanEntry(y)) { //compare the user name fields (=TAN index) String userX = x.Strings.ReadSafe(PwDefs.UserNameField); String userY = y.Strings.ReadSafe(PwDefs.UserNameField); if (userX != userY) { try { return(int.Parse(userX).CompareTo(int.Parse(userY))); } catch (Exception) { //ignore } return(String.Compare(userX, userY, StringComparison.CurrentCultureIgnoreCase)); } } //use creation time for non-tan entries: return(x.CreationTime.CompareTo(y.CreationTime)); } }
/// <summary> /// Test whether an entry is a TAN entry and if so, expire it, provided /// that the option for expiring TANs on use is enabled. /// </summary> /// <param name="pe">Entry.</param> /// <returns>If the entry has been modified, the return value is /// <c>true</c>, otherwise <c>false</c>.</returns> public static bool ExpireTanEntryIfOption(PwEntry pe, PwDatabase pdContext) { if (pe == null) { throw new ArgumentNullException("pe"); } // pdContext may be null if (!PwDefs.IsTanEntry(pe)) { return(false); // No assert } if (Program.Config.Defaults.TanExpiresOnUse) { pe.ExpiryTime = DateTime.Now; pe.Expires = true; pe.Touch(true); if (pdContext != null) { pdContext.Modified = true; } return(true); } return(false); }
private bool ValidateStringNameEx(string str) { if (str == null) { Debug.Assert(false); return(false); } if (PwDefs.IsStandardField(str)) { return(false); } if (str.Length <= 0) { return(false); } char[] vInvalidChars = new char[] { '{', '}' }; if (str.IndexOfAny(vInvalidChars) >= 0) { return(false); } string strStart = (m_strStringName != null) ? m_strStringName : string.Empty; if (!strStart.Equals(str) && m_vStringDict.Exists(str)) { return(false); } // See ValidateStringName return(true); }
public static string CreateSummaryList(PwGroup pgSubGroups, PwEntry[] vEntries) { int nMaxEntries = 10; string strSummary = string.Empty; if (pgSubGroups != null) { PwObjectList <PwGroup> vGroups = pgSubGroups.GetGroups(true); if (vGroups.UCount > 0) { StringBuilder sbGroups = new StringBuilder(); sbGroups.Append("- "); uint uToList = Math.Min(3U, vGroups.UCount); for (uint u = 0; u < uToList; ++u) { if (sbGroups.Length > 2) { sbGroups.Append(", "); } sbGroups.Append(vGroups.GetAt(u).Name); } if (uToList < vGroups.UCount) { sbGroups.Append(", ..."); } strSummary += sbGroups.ToString(); // New line below nMaxEntries -= 2; } } int nSummaryShow = Math.Min(nMaxEntries, vEntries.Length); if (nSummaryShow == (vEntries.Length - 1)) { --nSummaryShow; // Plural msg } for (int iSumEnum = 0; iSumEnum < nSummaryShow; ++iSumEnum) { if (strSummary.Length > 0) { strSummary += MessageService.NewLine; } PwEntry pe = vEntries[iSumEnum]; strSummary += ("- " + StrUtil.CompactString3Dots( pe.Strings.ReadSafe(PwDefs.TitleField), 39)); if (PwDefs.IsTanEntry(pe)) { string strTanIdx = pe.Strings.ReadSafe(PwDefs.UserNameField); if (!string.IsNullOrEmpty(strTanIdx)) { strSummary += (@" (#" + strTanIdx + @")"); } } } return(strSummary); }
bool MakeAccessibleForKeyboard(PwEntryOutput entry, string searchUrl) { #if EXCLUDE_KEYBOARD return(false); #else bool hasData = false; Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder(); String[] keys = { PwDefs.UserNameField, PwDefs.PasswordField, PwDefs.UrlField, PwDefs.NotesField, PwDefs.TitleField }; int[] resIds = { Resource.String.entry_user_name, Resource.String.entry_password, Resource.String.entry_url, Resource.String.entry_comment, Resource.String.entry_title }; //add standard fields: int i = 0; foreach (string key in keys) { String value = entry.OutputStrings.ReadSafe(key); if (value.Length > 0) { kbdataBuilder.AddString(key, GetString(resIds[i]), value); hasData = true; } i++; } //add additional fields: foreach (var pair in entry.OutputStrings) { var key = pair.Key; var value = pair.Value.ReadString(); if (!PwDefs.IsStandardField(key)) { kbdataBuilder.AddString(pair.Key, pair.Key, value); hasData = true; } } kbdataBuilder.Commit(); Keepass2android.Kbbridge.KeyboardData.EntryName = entry.OutputStrings.ReadSafe(PwDefs.TitleField); Keepass2android.Kbbridge.KeyboardData.EntryId = entry.Uuid.ToHexString(); if (hasData) { Keepass2android.Autofill.AutoFillService.NotifyNewData(searchUrl); } return(hasData); #endif }
public ProtectedCustomFieldDictionaryBuffer(List <KeyValuePair <String, ProtectedString> > entryStrings) : base(entryStrings.Count) { foreach (var kvp in entryStrings) { System.Diagnostics.Debug.Assert(!PwDefs.IsStandardField(kvp.Key)); AddStringField(kvp.Key, kvp.Value, null); } }
private void MultiApplyStrings() { ProtectedString psCue = MultipleValuesEx.CueProtectedString; EnsureStandardStrings(); for (int i = 0; i < m_v.Length; ++i) { PwEntry pe = m_v[i]; foreach (KeyValuePair <string, ProtectedString> kvpM in m_peM.Strings) { ProtectedString ps = pe.Strings.Get(kvpM.Key); bool bProt = kvpM.Value.IsProtected; bool bMultiProt; this.MultiStringProt.TryGetValue(kvpM.Key, out bMultiProt); if (bMultiProt && (ps != null)) { bProt = ps.IsProtected; } if (kvpM.Value.Equals(psCue, false)) { if ((ps != null) && (ps.IsProtected != bProt)) { PrepareMod(i); pe.Strings.Set(kvpM.Key, ps.WithProtection(bProt)); } } else if (kvpM.Value.IsEmpty && (ps == null) && PwDefs.IsStandardField(kvpM.Key)) { // Do not create the string } else { if ((ps == null) || !ps.Equals(kvpM.Value, false) || (ps.IsProtected != bProt)) { PrepareMod(i); pe.Strings.Set(kvpM.Key, kvpM.Value.WithProtection(bProt)); } } } List <string> lKeys = pe.Strings.GetKeys(); foreach (string strKey in lKeys) { if (!m_peM.Strings.Exists(strKey)) { PrepareMod(i); pe.Strings.Remove(strKey); } } } }
private void PopulateExtraStrings() { ViewGroup extraGroup = (ViewGroup)FindViewById(Resource.Id.extra_strings); foreach (var pair in Entry.Strings.Where(pair => !PwDefs.IsStandardField(pair.Key)).OrderBy(pair => pair.Key)) { var stringView = CreateExtraSection(pair.Key, pair.Value.ReadString(), pair.Value.IsProtected); extraGroup.AddView(stringView.View); } }
public static void AppendToField(PwEntry pe, string strName, string strValue, PwDatabase pdContext, string strSeparator, bool bOnlyIfNotDup) { if (pe == null) { Debug.Assert(false); return; } if (string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; } if (strValue == null) { Debug.Assert(false); strValue = string.Empty; } if (strSeparator == null) { if (PwDefs.IsStandardField(strName) && (strName != PwDefs.NotesField)) { strSeparator = ", "; } else { strSeparator = MessageService.NewLine; } } ProtectedString psPrev = pe.Strings.Get(strName); if ((psPrev == null) || psPrev.IsEmpty) { MemoryProtectionConfig mpc = ((pdContext != null) ? pdContext.MemoryProtection : new MemoryProtectionConfig()); bool bProtect = mpc.GetProtection(strName); pe.Strings.Set(strName, new ProtectedString(bProtect, strValue)); } else if (strValue.Length != 0) { bool bAppend = true; if (bOnlyIfNotDup) { ProtectedString psValue = new ProtectedString(false, strValue); bAppend = !psPrev.Equals(psValue, false); } if (bAppend) { pe.Strings.Set(strName, psPrev + (strSeparator + strValue)); } } }
private void EnsureStandardStrings() { foreach (string strKey in PwDefs.GetStandardFields()) { if (!m_peM.Strings.Exists(strKey)) { m_peM.Strings.Set(strKey, (m_pd.MemoryProtection.GetProtection( strKey) ? ProtectedString.EmptyEx : ProtectedString.Empty)); } // Standard string protections are normalized while // loading/saving the database file this.MultiStringProt[strKey] = true; } }
public static void ExpireTanEntry(PwEntry pe) { if (pe == null) { throw new ArgumentNullException("pe"); } Debug.Assert(PwDefs.IsTanEntry(pe)); if (Program.Config.Defaults.TanExpiresOnUse) { pe.ExpiryTime = DateTime.Now; pe.Expires = true; pe.Touch(true); } }
// Ported from KeePass because it is private private static bool ListContainsOnlyTans(PwObjectList <PwEntry> vEntries) { if (vEntries == null) { Debug.Assert(false); return(true); } foreach (PwEntry pe in vEntries) { if (!PwDefs.IsTanEntry(pe)) { return(false); } } return(true); }
private bool ValidateStringName() { string str = m_cmbStringName.Text; string strStart = (m_strStringName != null) ? m_strStringName : string.Empty; char[] vInvalidChars = new char[] { '{', '}' }; if (PwDefs.IsStandardField(str)) { m_lblValidationInfo.Text = KPRes.FieldNameInvalid; m_cmbStringName.BackColor = AppDefs.ColorEditError; m_btnOK.Enabled = false; return(false); } else if (str.Length <= 0) { m_lblValidationInfo.Text = KPRes.FieldNamePrompt; m_cmbStringName.ResetBackColor(); m_btnOK.Enabled = false; return(false); } else if (str.IndexOfAny(vInvalidChars) >= 0) { m_lblValidationInfo.Text = KPRes.FieldNameInvalid; m_cmbStringName.BackColor = AppDefs.ColorEditError; m_btnOK.Enabled = false; return(false); } else if (!strStart.Equals(str) && m_vStringDict.Exists(str)) { m_lblValidationInfo.Text = KPRes.FieldNameExistsAlready; m_cmbStringName.BackColor = AppDefs.ColorEditError; m_btnOK.Enabled = false; return(false); } else { m_lblValidationInfo.Text = string.Empty; m_cmbStringName.ResetBackColor(); m_btnOK.Enabled = true; } // See ValidateStringNameEx return(true); }
private static string FillEntryStrings(string str, SprContext ctx, uint uRecursionLevel) { List <string> vKeys = ctx.Entry.Strings.GetKeys(); // Ensure that all standard field names are in the list // (this is required in order to replace the standard placeholders // even if the corresponding standard field isn't present in // the entry) List <string> vStdNames = PwDefs.GetStandardFields(); foreach (string strStdField in vStdNames) { if (!vKeys.Contains(strStdField)) { vKeys.Add(strStdField); } } // Do not directly enumerate the strings in ctx.Entry.Strings, // because strings might change during the Spr compilation foreach (string strField in vKeys) { string strKey = (PwDefs.IsStandardField(strField) ? (@"{" + strField + @"}") : (@"{" + PwDefs.AutoTypeStringPrefix + strField + @"}")); if (!ctx.ForcePlainTextPasswords && strKey.Equals(@"{" + PwDefs.PasswordField + @"}", StrUtil.CaseIgnoreCmp) && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) { str = SprEngine.FillIfExists(str, strKey, new ProtectedString( false, PwDefs.HiddenPassword), ctx, uRecursionLevel); continue; } // Use GetSafe because the field doesn't necessarily exist // (might be a standard field that has been added above) str = SprEngine.FillIfExists(str, strKey, ctx.Entry.Strings.GetSafe( strField), ctx, uRecursionLevel); } return(str); }
public override bool IsVisible(string fieldKey) { if (fieldKey == EtmTemplateUuid) { return(false); } if (fieldKey == PwDefs.TitleField) { return(true); } if ((fieldKey.StartsWith("@") || (PwDefs.IsStandardField(fieldKey)))) { return(!String.IsNullOrEmpty(GetFieldValue(fieldKey)) || _templateEntry.Strings.Exists(EtmTitle + fieldKey)); } return(true); }
private bool CommitOptions() { options.CheckMode = radioButtonOffline.Checked ? Options.CheckModeType.Offline : radioButtonOnline.Checked ? Options.CheckModeType.Online : Options.CheckModeType.BloomFilter; options.HIBPFileName = textBoxFileName.Text; options.ColumnName = textBoxColumnName.Text; options.SecureText = textBoxSecureText.Text; options.InsecureText = textBoxInsecureText.Text; options.ExcludedText = textBoxExcludedText.Text; options.BreachCountDetails = checkBoxBreachCountDetails.Checked; options.ExcludeRecycleBin = checkBoxExcludeRecycleBin.Checked; options.ExcludeExpired = checkBoxExcludeExpired.Checked; options.WarningDialog = checkBoxWarningDialog.Checked; options.AutoCheck = checkBoxAutoCheck.Checked; options.WarningDialogText = textBoxWarningDialog.Text; bool bloomFilterChanged = (options.BloomFilter != textBoxBloomFilter.Text); options.BloomFilter = textBoxBloomFilter.Text; var standardFields = PwDefs.GetStandardFields(); foreach (string key in standardFields) { if (key == options.ColumnName) { MessageBox.Show("Column name conflicts with KeePass columns", " Invalid column name", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } if (bloomFilterChanged) { ext.Prov.BloomFilter = null; } ext.SaveOptions(options); return true; }
/// <summary> /// Test whether an entry is a TAN entry and if so, expire it, provided /// that the option for expiring TANs on use is enabled. /// </summary> /// <param name="pe">Entry.</param> /// <returns>If the entry has been modified, the return value is /// <c>true</c>, otherwise <c>false</c>.</returns> public static bool ExpireTanEntryIfOption(PwEntry pe) { if (pe == null) { throw new ArgumentNullException("pe"); } if (!PwDefs.IsTanEntry(pe)) { return(false); // No assert } if (Program.Config.Defaults.TanExpiresOnUse) { pe.ExpiryTime = DateTime.Now; pe.Expires = true; pe.Touch(true); return(true); } return(false); }
private static void EnsureStandardFieldsExist(PwDatabase pd) { List <string> l = PwDefs.GetStandardFields(); EntryHandler eh = delegate(PwEntry pe) { foreach (string strName in l) { ProtectedString ps = pe.Strings.Get(strName); if (ps == null) { pe.Strings.Set(strName, new ProtectedString( pd.MemoryProtection.GetProtection(strName), string.Empty)); } } return(true); }; pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); }
protected override void OnCellEditStarting(CellEditEventArgs e) { base.OnCellEditStarting(e); var rowObject = (RowObject)e.RowObject; // Disallow editing of standard field names if (e.Column == mFieldNames) { if (rowObject.FieldName != null && PwDefs.IsStandardField(rowObject.FieldName)) { e.Cancel = true; } } // Disallow editing of the insertion row value if (e.Column == mFieldValues && rowObject.IsInsertionRow) { e.Cancel = true; } }
protected override void DeleteFieldCommand(RowObject rowObject) { var isStandardField = PwDefs.IsStandardField(rowObject.FieldName); var entriesWithField = Entries.Where(entry => entry.Strings.Exists(rowObject.FieldName)).ToArray(); if (ConfirmOperationOnAllEntries(String.Format(Properties.Resources.MultipleEntryFieldDeleteQuestion, rowObject.DisplayName), KPRes.Delete, entriesWithField)) { var blankValue = new ProtectedString(rowObject.Value.IsProtected, new byte[0]); // ProtectedStrings are immutable, so OK to assign the same one to all entries var createBackups = AllowCreateHistoryNow; foreach (var entry in entriesWithField) { if (createBackups) { entry.CreateBackup(Database); } if (isStandardField) { entry.Strings.Set(rowObject.FieldName, blankValue); } else { entry.Strings.Remove(rowObject.FieldName); } } if (isStandardField) { rowObject.Value = blankValue; RefreshObject(rowObject); } else { RemoveObject(rowObject); } } OnModified(EventArgs.Empty); }
// Get all user defined strings internal static List <string> GetListEntriesUserStrings(PwGroup pwg) { List <string> strl = new List <string>(); // Add all known pwentry strings foreach (PwEntry pe in pwg.GetEntries(true)) { foreach (KeyValuePair <string, ProtectedString> pstr in pe.Strings) { if (!strl.Contains(pstr.Key)) { if (!PwDefs.IsStandardField(pstr.Key)) { strl.Add(pstr.Key); } } } } strl.Sort(); return(strl); }
/// <summary> /// Gets an ordered list of fields to search for the term /// </summary> /// <param name="entry"></param> /// <returns></returns> private IEnumerable <string> GetFieldsToSearch(PwEntry entry) { var fieldsToSearch = new List <String>((int)entry.Strings.UCount); if (mSearchTitle) { fieldsToSearch.Add(PwDefs.TitleField); } if (mSearchUserName) { fieldsToSearch.Add(PwDefs.UserNameField); } if (mSearchUrl) { fieldsToSearch.Add(PwDefs.UrlField); } if (mSearchNotes) { fieldsToSearch.Add(PwDefs.NotesField); } if (mSearchCustomFields) { foreach (var stringEntry in entry.Strings) { if (!stringEntry.Value.IsProtected && !PwDefs.IsStandardField(stringEntry.Key)) { fieldsToSearch.Add(stringEntry.Key); } } } if (mSearchTags) { fieldsToSearch.Add(AutoTypeSearchExt.TagsVirtualFieldName); } return(fieldsToSearch); }