proc listDiff {l1 l2 {icase {}} {except {}} } {

#	Diff 2 Tcl lists
#	if icase exists it means "ignore case"
#	if except exists, it's a list of diff values to ignore

#	if you feed this routine lists containing dups you may
#	get unexpected results

#	what we return:  a count of differences
#			 a list of differences

#	return 0 if equal -- good

	if {$icase != ""} {set icase 1} else {set icase 0}

	if {$icase} {
		set l1 [string tolower $l1]
		set l2 [string tolower $l2]
	}

      	if {[cequal $l1 $l2]} {
              return [list 0 {}]
      	}

#	If you have got this far then you know they are not identical

	set diff ""
	set dc 0
	set nc 0

#	assume these are simple lists, no hugely long text fields.

	set ll1 [llength $l1]
	set ll2 [llength $l2]

	lassign [intersect3 $l1 $l2] l1o common l2o

	set llc [llength $common]
	set ll1o [llength $l1o]
	set ll2o [llength $l2o]

#	if ll1o, then ll1 contains stuff not in ll2
#	if ll2o  then ll2 contains stuff not in ll1

	if {$ll1o || $ll2o} {
		return [list [expr $ll1o + $ll2o] $l1o $l2o]
	}

	if {($llc != $ll1) || ($llc != $ll2)} {
#		there must be dups somewhere but no diff elements
		set l1d ""
		set l2d ""
		if {$llc != $ll1} {
			set l1d dups
		}
		if {$llc != $ll2} {
			set l2d dups
		}
		return [list 0 $l1d $l2d]
	}

#	there are no diff elements but the order must be diff

	return [list 0 ord ord]


}
