 			if x.__c then _fieldmap(x.__c, x.__p) else {}
 
 
-
-	maptype = {
-		'':        identity
+	# ***
+	# We define the converse of *typemap*,
+	# a helper object for use by *mapfield()*
+	# to cast data types for server use.
+	# We have to guard against only null types.
+	maptype =
+		'':        (x) -> x
 		'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
+		'date':    (x) -> x
 		'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 ] }]
+	# The reverse operation of *fieldmap()*,
+	# ie, convert a given object to an array of values.
+	# The function uses *fmclasses*, a mapping between position indices and field names.
+	# The conversion is shown by the following ASCII diagram.
+	#
+	# 	xs                 = [{        classhint:        {'a':1, 'b':2, 'c':3 } }]
+	# 	fmclasses          =  {        classhint:        ['a',   'b',   'c'   ] }
+	# 	ys = mapfield(xs) // [{ '__c': classhint, '__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]
+		p = []
+		for c, o of xs
+			class_hint = c
+			if (ts = fm_datatypes[c])?
+				for name, n in fmclasses[c]
+					p[n] = if t = ts[name] then maptype[t] o[name], c 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]
+				for name, n in fmclasses[c]
+					p[n] = o[name]
+		__c: class_hint, __p: p
 
 	return @
+

# fieldmapper.coffee
#
# Field mapping functions:
#
# These turn the raw data returned by the server into objects which are easily
# manipulated, and back again.

# Synchronously load dependents that are not jModules.
jMod.include 'dojo.fieldmapper.fmall', 'eg.fm_datatypes'

module 'eg.fieldmapper', ->
	that = @

	identity = (x) -> x

	# Sometimes a value in a fieldmapped object is null. If so, we don't
	# want to cast it, because we don't want a value of, e.g., "null"
	guard_null = (fn) -> (x) -> if x? then fn.apply @, arguments else x

	# We don't want to try to cast an error object
	guard_ret = (fn) ->

		guard_null (x) ->
			if typeof x is 'object' and (x.ilsevent isnt undefined or (x[0] and x[0].ilsevent isnt undefined))
				return x
			else
				return fn.apply @, arguments

	@ret_types = {
		'number': guard_ret Number
		'string': guard_ret String
		'search': guard_ret (x) ->
			(x[f] = Number x[f]) for f in [
				'count'
				'superpage_size'

				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
