 					'total'
 				] when x.superpage_summary[f] isnt undefined
 			return x
-		'prefs': guard_ret (x) ->
+
+		# We type cast the number values in a given *prefs* object
+		# except if it is an *ilsevent* object.
+		'prefs': guard_ilsevent (x) ->
 			(x[p] = Number x[p]) for p in [
 				'opac.hits_per_page'
 				'opac.default_search_location'
 				'opac.default_search_depth'
 			] when x[p]
 			return x
-	}
+
+	# ***
+	# Define a public function to 'flatten' a given tree of objects.
+	# *opac_visible* objects are returned in a list.
+	# > FIXME: this could be integrated into *ret_types()* as another type cast operation,
+	@flatten_tree = (o) ->
+
+		_flatten_tree = (os) ->
+			a = []
+			$.each os, (n, o) ->
+				return [] unless o.opac_visible
+				a.push o
+				(a.push v) for k, v of _flatten_tree o.children if o.children
+				delete o.children
+			return a
+
+		# We need to deep-copy the object,
+		# otherwise the version in the cache will be modified.
+		_flatten_tree $.extend true, {}, [o]
 
 
-	typemap = {
-		'':        identity
+
+	# ***
+	# We define a helper object for use by the public *fieldmap* function
+	# to cast data types for client use.
+	# We have to guard against casting only null values.
+	typemap =
+		'':        (x) -> x
 		'fm':      guard_null (x) => if typeof x is 'object' then @fieldmap x else x
 		'number':  guard_null Number
 		'string':  guard_null String
 
-		# Use Date objects to represent dates in the app.
+		# > We will use Date objects to represent dates in the client.
 		# For the most part though,
 		# dates are displayed to the user as strings,
 		# and possibly modified by the user as strings

			if x.__c then _fieldmap(x.__c, x.__p) else {}



	maptype = {
		'':        identity
		'fm':      guard_null (x, cls) => if typeof x is 'object' then @mapfield { cls:x } else x
		'number':  guard_null Number
		'string':  guard_null String
		'date':    identity
		'boolean': (x) -> if x then 't' else 'f'
	}

	# The reverse operation of fieldmap(),
	# Map to an array of values from an object using a map between position indices and field names.
	#	xs                 = [{        mapname:        {'a':1, 'b':2, 'c':3 } }]
	#	fmclasses          =  {        mapname:        ['a',   'b',   'c'   ] }
	#	ys = mapfield(xs)  # [{ '__c': mapname, '__p': [    1,     2,     3 ] }]
	@mapfield = (xs) ->

		a = []
		for m, o of xs
			map = m
			if (ts = fm_datatypes[m])?
				for name, n in fmclasses[m]
					a[n] = if t = ts[name] then maptype[t] o[name], m else o[name]
			else
				for name, n in fmclasses[m]
					a[n] = o[name]

		{ '__c': map, '__p': a }


	# Input fm.flatten_tree( array, [flag] )
	#	fm.flatten_tree( array ) : return the visible children in the tree
	#	fm.flatten_tree( array, flag ): return the complete tree
	@flatten_tree = (o) ->

		_flatten_tree = (os) ->
			a = []
			$.each os, (n, o) ->
				return [] unless o.opac_visible
				a.push o
				(a.push v) for k, v of _flatten_tree o.children if o.children
				delete o.children
			return a

		# We need to deep copy the object
		# otherwise the version in the cache will be modified.
		_flatten_tree $.extend true, {}, [o]

	return @

				when 't', '1' then true
				when 'f', '0' then false
				else !!x


	# ***
	# Define a function to convert a class hint
	# and an array of property values into an object.
	# The function uses *fmclasses*,
	# a mapping between position indices and field names.
	# If we find an empty array or object, we will simply return it.
	_fieldmap = (c, p) ->
		o = {}
		if (ts = fm_datatypes[c])?
			for name, n in fmclasses[c]
				o[name] = if t = ts[name] then typemap[t] p[n] else p[n]
		else
			for name, n in fmclasses[c]
				o[name] = p[n]
		return o

	# Define the public version of *_fieldmap()*.
	# It will handle the case in which the input array could be inside an array,
	# The conversion is shown by the following ASCII diagrams.
	#
	# 	x                 =  { '__c': classhint, '__p': [    1,     2,     3 ] }
	# 	fmclasses         =  {        classhint:        ['a',   'b',   'c'   ] }
	# 	y = fieldmap(x)  //  {                           'a':1, 'b':2, 'c':3   }
	#
	# 	xs                = [{ '__c': classhint, '__p': [    1,     2,     3 ] }]
	# 	fmclasses         =  {        classhint:        ['a',   'b',   'c'   ] }
	# 	ys = fieldmap(x) // [{                           'a':1, 'b':2, 'c':3   }]
	#
	@fieldmap = (x) ->
		if $.isArray x
			return x unless x.length
			_fieldmap(a.__c, a.__p) for a in x when a.__c
