# -------------------------------------------------------
# File: "SearchCmd.test"
#                        Created: 2004-09-07 15:43:09
#              Last modification: 2009-03-12 08:41:40
# Author: Bernard Desgraupes
# e-mail: <bdesgraupes@users.sourceforge.net.fr>
# www: <http://tcladdressbook.sourceforge.net>
# (c) Copyright: Bernard Desgraupes, 2004-2009
# All rights reserved.
# This software is free software with BSD licence.
# Versions history: see the Changes.Log file.
# 
# Test suite for the Tcl [addressbook search] command defined 
# in the Tcladdressbook extension.
# 
# -------------------------------------------------------

source [file join [file dir [info script]] TclABCommonTests.tcl]

namespace eval ::addressbook::test {
	namespace import ::tcltest::*

	# Numeric value search
	# ====================
	
	test AddressbookSearch-1-1 {Search == date} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set birthday to 1st January 2000
		addressbook set $PersonID Modification 946728000
		set found [addressbook search Modification == 946728000]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"
		
	test AddressbookSearch-1-2 {Search == numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags == $flags]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"
		
	test AddressbookSearch-1-3 {Search == numeric value, only IDs} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set birthday to 1st January 2000
		addressbook set $PersonID ABPersonFlags 12345
		# Caveat: the result is a list
		set found [addressbook search -ids ABPersonFlags == 12345]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"
		
	test AddressbookSearch-1-4 {Search < numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags < $flags]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-5 {Search <= numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags <= $flags]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-6 {Search > numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags > $flags]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-7 {Search >= numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags >= $flags]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-8 {Search != numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search ABPersonFlags != $flags]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-9 {Search != numeric value, only IDs} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search -ids ABPersonFlags != $flags]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-1-10 {Search ^= numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search -ids ABPersonFlags ^= $flags]
	} -cleanup {
	} -returnCodes error \
	  -result "prefix matching not applicable for numeric properties"

	test AddressbookSearch-1-11 {Search =$ numeric value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set flags value
		set flags 12345
		addressbook set $PersonID ABPersonFlags $flags
		# Caveat: the result is a list
		set found [addressbook search -ids ABPersonFlags =$ $flags]
	} -cleanup {
	} -returnCodes error \
	  -result "suffix matching not applicable for numeric properties"


	# String value search in Person records
	# =====================================
	
	test AddressbookSearch-2-1 {Search == string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set found [addressbook search Last == $PersonName]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-2 {Search == string value, only IDs} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set found [addressbook search -ids Last == $PersonName]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-3 {Search == string value, case insensitive} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set found [addressbook search -nocase Last == [string tolower $PersonName]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-4 {Search != string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set found [addressbook search -ids Last != $PersonName]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-5 {Search != string value, case insensitive} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set found [addressbook search -ids -nocase Last != [string tolower $PersonName]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-6 {Search > string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search -ids Last > $SubName]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-7 {Search > string value, case insensitive} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search -ids -nocase Last > [string tolower $SubName]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-8 {Search < string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search Last < $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "< and <= not applicable for string properties"

	test AddressbookSearch-2-9 {Search <= string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search Last <= $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "< and <= not applicable for string properties"

	test AddressbookSearch-2-10 {Search !< string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search Last !< $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "!< not applicable for string properties"

	test AddressbookSearch-2-11 {Non matching prefix string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search -ids Last ^= $SubName]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-12 {Matching prefix string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 0 4]
		set found [addressbook search -ids Last ^= $SubName]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-13 {Matching prefix string value, case insensitive} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 0 4]
		set found [addressbook search -ids -nocase Last ^= [string tolower $SubName]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-14 {Non matching suffix string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName 5 10]
		set found [addressbook search -ids Last =$ $SubName]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-15 {Matching suffix string value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName end-10 end]
		set found [addressbook search -ids Last =$ $SubName]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-2-16 {Matching suffix string value, case insensitive} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set SubName [string range $PersonName end-10 end]
		set found [addressbook search -ids -nocase Last =$ [string tolower $SubName]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"


	# Important note: this is broken on Leopard. When a date is set as a
	# birthday the AB API systematically changes it and adjusts it on
	# '12:00:00 CET' on the same day. For instance:
	# 	ÇÈ set now [clock seconds]
	# 	1236862265
	# 	ÇÈ clock format $now
	# 	Thu Mar 12 13:51:05 CET 2009
	# 	ÇÈ addressbook set $PersonID Birthday $now
	# 	1236862265
	# 	ÇÈ set birthdate [addressbook set $PersonID Birthday]
	# 	1236855600
	# 	ÇÈ clock format $birthdate
	# 	Thu Mar 12 12:00:00 CET 2009 
	test AddressbookSearch-2-17 {Search == birthday} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# Set birthday to 1st January 2000
		addressbook set $PersonID Birthday 946728000
		set found [addressbook search Birthday == 946728000]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "0"
	
	# This test fails. Not clear why: the AB API seems to be failing to
	# find a record by binary data.
	test AddressbookSearch-2-18 {Search == data} -setup {
	} -body {
		catch {addressbook property add -persons TclAB_BinData Data}
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set binVar "\x00\x01\x02\x03"
		addressbook set $PersonID TclAB_BinData $binVar
		set found [addressbook search -ids TclAB_BinData == $binVar]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"
	
	test AddressbookSearch-2-19 {Search == real} -setup {
	} -body {
		catch {addressbook property add -persons TclAB_RealValue Real}
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set piVal "3.141592653"
		addressbook set $PersonID TclAB_RealValue $piVal
		set found [addressbook search -ids TclAB_RealValue == $piVal]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"
		
	# String value search in Group records
	# ====================================
	
	test AddressbookSearch-3-1 {Search == string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set found [addressbook search -groups GroupName == $GroupName]
		return [expr {[list $GroupID $GroupName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-2 {Search == string value, only IDs} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set found [addressbook search -groups -ids GroupName == $GroupName]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-3 {Search == string value, case insensitive} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set found [addressbook search -groups -nocase GroupName == [string tolower $GroupName]]
		return [expr {[list $GroupID $GroupName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-4 {Search != string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set found [addressbook search -groups -ids GroupName != $GroupName]
		return [expr {$GroupID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-5 {Search != string value, case insensitive} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set found [addressbook search -groups -ids -nocase GroupName != [string tolower $GroupName]]
		return [expr {$GroupID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-6 {Search > string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups -ids GroupName > $SubName]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-7 {Search > string value, case insensitive} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups -ids -nocase GroupName > [string tolower $SubName]]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-8 {Search < string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups GroupName < $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "< and <= not applicable for string properties"

	test AddressbookSearch-3-9 {Search <= string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups GroupName <= $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "< and <= not applicable for string properties"

	test AddressbookSearch-3-10 {Search !< string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups GroupName !< $SubName]
	} -cleanup {
	} -returnCodes error \
	  -result "!< not applicable for string properties"

	test AddressbookSearch-3-11 {Non matching prefix string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups -ids GroupName ^= $SubName]
		return [expr {$GroupID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-12 {Matching prefix string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 0 4]
		set found [addressbook search -groups -ids GroupName ^= $SubName]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-13 {Matching prefix string value, case insensitive} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 0 4]
		set found [addressbook search -groups -ids -nocase GroupName ^= [string tolower $SubName]]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-14 {Non matching suffix string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName 5 10]
		set found [addressbook search -groups -ids GroupName =$ $SubName]
		return [expr {$GroupID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-15 {Matching suffix string value} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName end-10 end]
		set found [addressbook search -groups -ids GroupName =$ $SubName]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-3-16 {Matching suffix string value, case insensitive} -setup {
	} -body {
		set GroupName "TclABSearchTestGroup[incr GroupNum]"
		set GroupID [addressbook create group $GroupName]
		set SubName [string range $GroupName end-10 end]
		set found [addressbook search -groups -ids -nocase GroupName =$ [string tolower $SubName]]
		return [expr {$GroupID in $found}]
	} -cleanup {
	} -result "1"


	# String multivalue search
	# ========================
	
	test AddressbookSearch-4-1 {Search == multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set found [addressbook search Phone == [list home $homePhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-2 {Search == multistring value, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set found [addressbook search Phone == [list "" $homePhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-3 {Search != multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set found [addressbook search Phone != [list home $homePhone]]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-4 {Search != multistring value, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		# Put homePhone in both fields
		keylset phonesList home $homePhone work $homePhone
		addressbook set $PersonID Phone $phonesList
		set found [addressbook search Phone != [list "" $homePhone]]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-5 {Search >= multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone 5 10]
		set found [addressbook search Phone >= [list home $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-6 {Search >= multistring value, any label} -setup {
	} -body {
		set PersonName1 "TclABSearchTestPerson[incr PersonNum]"
		set PersonID1 [addressbook create person $PersonName1]
		set PersonName2 "TclABSearchTestPerson[incr PersonNum]"
		set PersonID2 [addressbook create person $PersonName2]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList1 home $homePhone
		keylset phonesList2 work $workPhone
		addressbook set $PersonID1 Phone $phonesList1
		addressbook set $PersonID2 Phone $phonesList2
		set SubPhone "05"
		set found [addressbook search -ids Phone >= [list "" $SubPhone]]
		return [expr {$PersonID1 in $found && $PersonID2 in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-7 {Search !> multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone 5 10]
		set found [addressbook search Phone !> [list home $SubPhone]]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-8 {Search !> multistring value, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone "01"
		# Look for records which do not contain "01" in any Phone entry:
		# this is the meaning of the empty label. This record should not be
		# in the list since it _does_ contain "01" in one of its Phone
		# entries.
		set found [addressbook search Phone !> [list "" $SubPhone]]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-9 {Search !> multistring value, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone "00"
		# Look for records which do not contain "00" in any Phone entry:
		# this is the meaning of the empty label. This record should be in
		# the list since it _doesn't_ contain "00" in any of its Phone
		# entries.
		set found [addressbook search Phone !> [list "" $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-10 {Search ^= multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone 0 5]
		set found [addressbook search Phone ^= [list home $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-11 {Search ^= multistring value, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone 0 5]
		set found [addressbook search Phone ^= [list "" $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-12 {Search =$ multistring value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone end-5 end]
		set found [addressbook search Phone =$ [list "home" $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-13 {Search =$ multistring value, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone [string range $homePhone end-5 end]
		set found [addressbook search Phone =$ [list "" $SubPhone]]
		return [expr {[list $PersonID $PersonName] in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-4-14 {Search =$ multistring value, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homePhone "01 02 03 04 05"
		set workPhone "05 06 07 08 09"
		keylset phonesList home $homePhone work $workPhone
		addressbook set $PersonID Phone $phonesList
		set SubPhone "00"
		set found [addressbook search Phone =$ [list "" $SubPhone]]
		return [expr {[list $PersonID $PersonName] ni $found}]
	} -cleanup {
	} -result "1"

	# String multivalue case-insensitive search
	# =========================================
	
	test AddressbookSearch-5-1 {Search == multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set found [addressbook search -ids -nocase Email == [list home [string tolower $homeEmail]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-2 {Search == multistring value, -nocase, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set found [addressbook search -ids -nocase Email == [list "" [string tolower $homeEmail]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-3 {Search != multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set found [addressbook search -ids -nocase Email != [list home [string tolower $homeEmail]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-4 {Search != multistring value, -nocase, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		# Put homeEmail in both fields
		keylset emailsList home $homeEmail work $homeEmail
		addressbook set $PersonID Email $emailsList
		set found [addressbook search -ids -nocase Email != [list "" [string tolower $homeEmail]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-5 {Search >= multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail 5 10]]
		set found [addressbook search -ids -nocase Email >= [list home $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-6 {Search >= multistring value, -nocase, any label} -setup {
	} -body {
		set PersonName1 "TclABSearchTestPerson[incr PersonNum]"
		set PersonID1 [addressbook create person $PersonName1]
		set PersonName2 "TclABSearchTestPerson[incr PersonNum]"
		set PersonID2 [addressbook create person $PersonName2]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList1 home $homeEmail
		keylset emailsList2 work $workEmail
		addressbook set $PersonID1 Email $emailsList1
		addressbook set $PersonID2 Email $emailsList2
		set SubEmail ".ORG"
		set found [addressbook search -ids -nocase -ids Email >= [list "" $SubEmail]]
		return [expr {$PersonID1 in $found && $PersonID2 in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-7 {Search !> multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail 5 10]]
		set found [addressbook search -ids -nocase Email !> [list home $SubEmail]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-8 {Search !> multistring value, -nocase, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail ".ORG"
		# Look for records which do not contain ".ORG" in any Email entry:
		# this is the meaning of the empty label. This record should not be
		# in the list since it _does_ contain ".org" in one of its Email
		# entries.
		set found [addressbook search -ids -nocase Email !> [list "" $SubEmail]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-9 {Search !> multistring value, -nocase, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail ".COM"
		# Look for records which do not contain ".COM" in any Email entry:
		# this is the meaning of the empty label. This record should be in
		# the list since it _doesn't_ contain ".COM" in any of its Email
		# entries.
		set found [addressbook search -ids -nocase Email !> [list "" $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-10 {Search ^= multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail 0 5]]
		set found [addressbook search -ids -nocase Email ^= [list home $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-11 {Search ^= multistring value, -nocase, any label} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail 0 5]]
		set found [addressbook search -ids -nocase Email ^= [list "" $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-12 {Search =$ multistring value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail end-5 end]]
		set found [addressbook search -ids -nocase Email =$ [list "home" $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-13 {Search =$ multistring value, -nocase, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail [string toupper [string range $homeEmail end-5 end]]
		set found [addressbook search -ids -nocase Email =$ [list "" $SubEmail]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-5-14 {Search =$ multistring value, -nocase, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		set homeEmail "$PersonName@home.org"
		set workEmail "$PersonName@work.org"
		keylset emailsList home $homeEmail work $workEmail
		addressbook set $PersonID Email $emailsList
		set SubEmail ".COM"
		set found [addressbook search -ids -nocase Email =$ [list "" $SubEmail]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	
	# Multidictionary search
	# ======================
	
	test AddressbookSearch-6-1 {Search == multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address == [list "home" [list City "Paris"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"
	
	test AddressbookSearch-6-2 {Search == multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address == [list "home" [list City "PARIS"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-3 {Search == multidict value, any key} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address == [list "home" [list "" "Paris"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-4 {Search == multidict value, any label, any key, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address == [list "" [list "" "Paris"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-5 {Search == multidict value, any label, any key, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address == [list "" [list "" "Madrid"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-6 {Search != multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address != [list "home" [list City "Paris"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-7 {Search != multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address != [list "home" [list City "PARIS"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"
	
	test AddressbookSearch-6-8 {Search != multidict value, any key} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address != [list "home" [list "" "Paris"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-9 {Search != multidict value, any key, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address != [list "home" [list "" "Paris"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-10 {Search != multidict value, any key, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address != [list "" [list "" "Madrid"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-12 {Search != multidict value, -nocase, any key, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address != [list "" [list "" "PARIS"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-13 {Search > multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address > [list "work" [list City "ondo"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-14 {Search > multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address > [list "work" [list City "ONDO"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-15 {Search > multidict value, any key} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address > [list "work" [list "" "ondo"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-16 {Search > multidict value, any key, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address > [list "" [list "" "ondo"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-17 {Search > multidict value, any key, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address > [list "" [list "" "xyz"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-18 {Search !> multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address !> [list "work" [list City "ondo"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-19 {Search !> multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address !> [list "work" [list City "ONDO"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-20 {Search !> multidict value, any key} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address !> [list "work" [list "" "ondo"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-21 {Search !> multidict value, any key, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address !> [list "" [list "" "ondo"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-22 {Search !> multidict value, any key, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address !> [list "" [list "" "xyz"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-23 {Search ^= multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address ^= [list "home" [list City "Par"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-24 {Search ^= multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address ^= [list "home" [list City "PAR"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-25 {Search ^= multidict value, any key} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address ^= [list "home" [list "" "Par"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-26 {Search ^= multidict value, any key, any label, success} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address ^= [list "" [list "" "Par"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"
	
	test AddressbookSearch-6-27 {Search ^= multidict value, any key, any label, failure} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address ^= [list "" [list "" "Mad"]]]
		return [expr {$PersonID ni $found}]
	} -cleanup {
	} -result "1"
	
	test AddressbookSearch-6-28 {Search =$ multidict value} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids Address =$ [list "work" [list City "don"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	test AddressbookSearch-6-29 {Search =$ multidict value, -nocase} -setup {
	} -body {
		set PersonName "TclABSearchTestPerson[incr PersonNum]"
		set PersonID [addressbook create person $PersonName]
		# This is a multi dictionary value
		keylset homeAddr City Paris Zip 75000 CountryCode fr
		set homeDict [list home $homeAddr]
		keylset workAddr City London Zip W2C CountryCode en
		set workDict [list work $workAddr]
		addressbook set $PersonID Address [list $homeDict $workDict]
		set found [addressbook search -ids -nocase Address =$ [list "work" [list City "DON"]]]
		return [expr {$PersonID in $found}]
	} -cleanup {
	} -result "1"

	# Usage string
	# ============
	test AddressbookSearch-7-1 {Usage string for wrong num args} -setup {
	} -body {
		addressbook search -ids -nocase
	} -cleanup {
	} -returnCodes error \
	  -result "wrong # args: should be \"addressbook search ?(-groups|-persons)? ?-ids? ?-nocase? property op value\""

	# Cleanup
	::tcltest::cleanupTests
}

namespace delete ::addressbook::test

