diff --git a/Mac/Lib/toolbox/aepack.py b/Mac/Lib/toolbox/aepack.py
new file mode 100644
index 0000000..8c9def7
--- /dev/null
+++ b/Mac/Lib/toolbox/aepack.py
@@ -0,0 +1,356 @@
+"""Tools for use in AppleEvent clients and servers:
+conversion between AE types and python types
+
+pack(x) converts a Python object to an AEDesc object
+unpack(desc) does the reverse
+coerce(x, wanted_sample) coerces a python object to another python object
+"""
+
+#
+# This code was originally written by Guido, and modified/extended by Jack
+# to include the various types that were missing. The reference used is
+# Apple Event Registry, chapter 9.
+#
+
+import struct
+import string
+import types
+from string import strip
+from types import *
+import AE
+from AppleEvents import *
+from AERegistry import *
+from AEObjects import *
+import MacOS
+import macfs
+import StringIO
+import aetypes
+from aetypes import mkenum, mktype
+
+# These ones seem to be missing from AppleEvents
+# (they're in AERegistry.h)
+
+#typeColorTable = 'clrt'
+#typeDrawingArea = 'cdrw'
+#typePixelMap = 'cpix'
+#typePixelMapMinus = 'tpmm'
+#typeRotation = 'trot'
+#typeTextStyles = 'tsty'
+#typeStyledText = 'STXT'
+#typeAEText = 'tTXT'
+#typeEnumeration = 'enum'
+
+#
+# Some AE types are immedeately coerced into something
+# we like better (and which is equivalent)
+#
+unpacker_coercions = {
+	typeComp : typeExtended,
+	typeColorTable : typeAEList,
+	typeDrawingArea : typeAERecord,
+	typeFixed : typeExtended,
+	typeFloat : typeExtended,
+	typePixelMap : typeAERecord,
+	typeRotation : typeAERecord,
+	typeStyledText : typeAERecord,
+	typeTextStyles : typeAERecord,
+};
+
+#
+# Some python types we need in the packer:
+#
+AEDescType = type(AE.AECreateDesc('TEXT', ''))
+_sample_fss = macfs.FSSpec(':')
+_sample_alias = _sample_fss.NewAliasMinimal()
+FSSType = type(_sample_fss)
+AliasType = type(_sample_alias)
+
+def pack(x, forcetype = None):
+	"""Pack a python object into an AE descriptor"""
+	
+	if forcetype:
+		if type(x) is StringType:
+			return AE.AECreateDesc(forcetype, x)
+		else:
+			return pack(x).AECoerceDesc(forcetype)
+			
+	if x == None:
+		return AE.AECreateDesc('null', '')
+		
+	t = type(x)
+	if t == AEDescType:
+		return x
+	if t == FSSType:
+		return AE.AECreateDesc('fss ', x.data)
+	if t == AliasType:
+		return AE.AECreateDesc('alis', x.data)
+	if t == IntType:
+		return AE.AECreateDesc('long', struct.pack('l', x))
+	if t == FloatType:
+		#
+		# XXXX (note by Guido) Weird thing -- Think C's "double" is 10 bytes, but
+		# struct.pack('d') return 12 bytes (and struct.unpack requires
+		# them, too).  The first 2 bytes seem to be repeated...
+		# Probably an alignment problem
+		# XXXX (note by Jack) haven't checked this under MW
+		#
+		return AE.AECreateDesc('exte', struct.pack('d', x)[2:])
+	if t == StringType:
+		return AE.AECreateDesc('TEXT', x)
+	if t == ListType:
+		list = AE.AECreateList('', 0)
+		for item in x:
+			list.AEPutDesc(0, pack(item))
+		return list
+	if t == DictionaryType:
+		record = AE.AECreateList('', 1)
+		for key, value in x.items():
+			record.AEPutParamDesc(key, pack(value))
+		return record
+	if t == InstanceType and hasattr(x, '__aepack__'):
+		return x.__aepack__()
+	return AE.AECreateDesc('TEXT', repr(x)) # Copout
+
+def unpack(desc):
+	"""Unpack an AE descriptor to a python object"""
+	t = desc.type
+	
+	if unpacker_coercions.has_key(t):
+		desc = desc.AECoerceDesc(unpacker_coercions[t])
+	
+	if t == typeAEList:
+		l = []
+		for i in range(desc.AECountItems()):
+			keyword, item = desc.AEGetNthDesc(i+1, '****')
+			l.append(unpack(item))
+		return l
+	if t == typeAERecord:
+		d = {}
+		for i in range(desc.AECountItems()):
+			keyword, item = desc.AEGetNthDesc(i+1, '****')
+			d[keyword] = unpack(item)
+		return d
+	if t == typeAEText:
+		record = desc.AECoerceDesc('reco')
+		return mkaetext(unpack(record))
+	if t == typeAlias:
+		return macfs.RawAlias(desc.data)
+	# typeAppleEvent returned as unknown
+	if t == typeBoolean:
+		return struct.unpack('b', desc.data)[0]
+	if t == typeChar:
+		return desc.data
+	# typeColorTable coerced to typeAEList
+	# typeComp coerced to extended
+	# typeData returned as unknown
+	# typeDrawingArea coerced to typeAERecord
+	if t == typeEnumeration:
+		return mkenum(desc.data)
+	# typeEPS returned as unknown
+	if t == typeExtended:
+		data = desc.data
+		# XXX See corresponding note for pack()
+		return struct.unpack('d', data[:2] + data)[0]
+	if t == typeFalse:
+		return 0
+	# typeFixed coerced to extended
+	# typeFloat coerced to extended
+	if t == typeFSS:
+		return macfs.RawFSSpec(desc.data)
+	if t == typeInsertionLoc:
+		record = desc.AECoerceDesc('reco')
+		return mkinsertionloc(unpack(record))
+	# typeInteger equal to typeLongInteger
+	if t == typeIntlText:
+		script, language = struct.unpack('hh', desc.data[:4])
+		return aetypes.IntlText(script, language, desc.data[4:])
+	if t == typeIntlWritingCode:
+		script, language = struct.unpack('hh', desc.data)
+		return aetypes.IntlWritingCode(script, language)
+	if t == typeKeyword:
+		return mkkeyword(desc.data)
+	# typeLongFloat is equal to typeFloat
+	if t == typeLongInteger:
+		return struct.unpack('l', desc.data)[0]
+	if t == typeNull:
+		return None
+	if t == typeMagnitude:
+		v = struct.unpack('l', desc.data)
+		if v < 0:
+			v = 0x100000000L + v
+		return v
+	if t == typeObjectSpecifier:
+		record = desc.AECoerceDesc('reco')
+		return mkobject(unpack(record))
+	# typePict returned as unknown
+	# typePixelMap coerced to typeAERecord
+	# typePixelMapMinus returned as unknown
+	# typeProcessSerialNumber returned as unknown
+	if t == typeQDPoint:
+		v, h = struct.unpack('hh', desc.data)
+		return aetypes.QDPoint(v, h)
+	if t == typeQDRectangle:
+		v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
+		return aetypes.QDRectangle(v0, h0, v1, h1)
+	if t == typeRGBColor:
+		r, g, b = struct.unpack('hhh', desc.data)
+		return aetypes.RGBColor(r, g, b)
+	# typeRotation coerced to typeAERecord
+	# typeScrapStyles returned as unknown
+	# typeSessionID returned as unknown
+	if t == typeShortFloat:
+		return struct.unpack('f', desc.data)[0]
+	if t == typeShortInteger:
+		return struct.unpack('h', desc.data)[0]
+	# typeSMFloat identical to typeShortFloat
+	# typeSMInt	indetical to typeShortInt
+	# typeStyledText coerced to typeAERecord
+	if t == typeTargetID:
+		return mktargetid(desc.data)
+	# typeTextStyles coerced to typeAERecord
+	# typeTIFF returned as unknown
+	if t == typeTrue:
+		return 1
+	if t == typeType:
+		return mktype(desc.data)
+	#
+	# The following are special
+	#
+	if t == 'rang':
+		record = desc.AECoerceDesc('reco')
+		return mkrange(unpack(record))
+	if t == 'cmpd':
+		record = desc.AECoerceDesc('reco')
+		return mkcomparison(unpack(record))
+	if t == 'logi':
+		record = desc.AECoerceDesc('reco')
+		return mklogical(unpack(record))
+	return mkunknown(desc.type, desc.data)
+	
+def coerce(data, egdata):
+	"""Coerce a python object to another type using the AE coercers"""
+	pdata = pack(data)
+	pegdata = pack(egdata)
+	pdata = pdata.AECoerceDesc(pegdata.type)
+	return unpack(pdata)
+
+#
+# Helper routines for unpack
+#
+def mktargetid(data):
+	sessionID = getlong(data[:4])
+	name = mkppcportrec(data[4:4+72])
+	location = mklocationnamerec(data[76:76+36])
+	rcvrName = mkppcportrec(data[112:112+72])
+	return sessionID, name, location, rcvrName
+
+def mkppcportrec(rec):
+	namescript = getword(rec[:2])
+	name = getpstr(rec[2:2+33])
+	portkind = getword(rec[36:38])
+	if portkind == 1:
+		ctor = rec[38:42]
+		type = rec[42:46]
+		identity = (ctor, type)
+	else:
+		identity = getpstr(rec[38:38+33])
+	return namescript, name, portkind, identity
+
+def mklocationnamerec(rec):
+	kind = getword(rec[:2])
+	stuff = rec[2:]
+	if kind == 0: stuff = None
+	if kind == 2: stuff = getpstr(stuff)
+	return kind, stuff
+
+def mkunknown(type, data):
+	return aetypes.Unknown(type, data)
+
+def getpstr(s):
+	return s[1:1+ord(s[0])]
+
+def getlong(s):
+	return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
+
+def getword(s):
+	return (ord(s[0])<<8) | (ord(s[1])<<0)
+
+def mkkeyword(keyword):
+	return aetypes.Keyword(keyword)
+
+def mkrange(dict):
+	return aetypes.Range(dict['star'], dict['stop'])
+
+def mkcomparison(dict):
+	return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
+
+def mklogical(dict):
+	return aetypes.Logical(dict['logc'], dict['term'])
+
+def mkstyledtext(dict):
+	return aetypes.StyledText(dict['ksty'], dict['ktxt'])
+	
+def mkaetext(dict):
+	return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
+	
+def mkinsertionloc(dict):
+	return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])
+
+def mkobject(dict):
+	want = dict['want'].type
+	form = dict['form'].enum
+	seld = dict['seld']
+	fr   = dict['from']
+	if form in ('name', 'indx', 'rang', 'test'):
+		if want == 'text': return aetypes.Text(seld, fr)
+		if want == 'cha ': return aetypes.Character(seld, fr)
+		if want == 'cwor': return aetypes.Word(seld, fr)
+		if want == 'clin': return aetypes.Line(seld, fr)
+		if want == 'cpar': return aetypes.Paragraph(seld, fr)
+		if want == 'cwin': return aetypes.Window(seld, fr)
+		if want == 'docu': return aetypes.Document(seld, fr)
+		if want == 'file': return aetypes.File(seld, fr)
+		if want == 'cins': return aetypes.InsertionPoint(seld, fr)
+	if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
+		return aetypes.Property(seld.type, fr)
+	return aetypes.ObjectSpecifier(want, form, seld, fr)
+
+def _test():
+	"""Test program. Pack and unpack various things"""
+	objs = [
+		'a string',
+		12,
+		12.0,
+		None,
+		['a', 'list', 'of', 'strings'],
+		{'key1': 'value1', 'key2':'value2'},
+		macfs.FSSpec(':'),
+		macfs.FSSpec(':').NewAliasMinimal(),
+		aetypes.Enum('enum'),
+		aetypes.Type('type'),
+		aetypes.Keyword('kwrd'),
+		aetypes.Range(1, 10),
+		aetypes.Comparison(1, '<   ', 10),
+		aetypes.Logical('not ', 1),
+		# Cannot do StyledText
+		# Cannot do AEText
+		aetypes.IntlText(0, 0, 'international text'),
+		aetypes.IntlWritingCode(0,0),
+		aetypes.QDPoint(50,100),
+		aetypes.QDRectangle(50,100,150,200),
+		aetypes.RGBColor(0x7000, 0x6000, 0x5000),
+		aetypes.Unknown('xxxx', 'unknown type data'),
+		aetypes.Character(1),
+		aetypes.Character(2, aetypes.Line(2)),
+	]
+	for o in objs:
+		print 'BEFORE', o, `o`
+		packed = pack(o)
+		unpacked = unpack(packed)
+		print 'AFTER ', unpacked, `unpacked`
+	import sys
+	sys.exit(1)
+	
+if __name__ == '__main__':
+	_test()
+	
diff --git a/Mac/Lib/toolbox/aetools.py b/Mac/Lib/toolbox/aetools.py
index bb0d20f..565cdec 100644
--- a/Mac/Lib/toolbox/aetools.py
+++ b/Mac/Lib/toolbox/aetools.py
@@ -15,477 +15,22 @@
 
 	character 1 of document "foobar"
 
+Some of the stuff that appears to be exported from this module comes from other
+files: the pack stuff from aepack, the objects from aetypes.
+
 """
 
 
-import struct
-import string
-from string import strip
 from types import *
 import AE
+import AppleEvents
 import MacOS
-import macfs
-import StringIO
 
-
-AEDescType = type(AE.AECreateDesc('TEXT', ''))
-
-FSSType = type(macfs.FSSpec(':'))
-
-
-def pack(x, forcetype = None):
-	if forcetype:
-		if type(x) is StringType:
-			return AE.AECreateDesc(forcetype, x)
-		else:
-			return pack(x).AECoerceDesc(forcetype)
-	if x == None:
-		return AE.AECreateDesc('null', '')
-	t = type(x)
-	if t == AEDescType:
-		return x
-	if t == FSSType:
-		vol, dir, filename = x.as_tuple()
-		fnlen = len(filename)
-		header = struct.pack('hlb', vol, dir, fnlen)
-		padding = '\0'*(63-fnlen)
-		return AE.AECreateDesc('fss ', header + filename + padding)
-	if t == IntType:
-		return AE.AECreateDesc('long', struct.pack('l', x))
-	if t == FloatType:
-		# XXX Weird thing -- Think C's "double" is 10 bytes, but
-		# struct.pack('d') return 12 bytes (and struct.unpack requires
-		# them, too).  The first 2 bytes seem to be repeated...
-		# Probably an alignment problem
-		return AE.AECreateDesc('exte', struct.pack('d', x)[2:])
-	if t == StringType:
-		return AE.AECreateDesc('TEXT', x)
-	if t == ListType:
-		list = AE.AECreateList('', 0)
-		for item in x:
-			list.AEPutDesc(0, pack(item))
-		return list
-	if t == DictionaryType:
-		record = AE.AECreateList('', 1)
-		for key, value in x.items():
-			record.AEPutParamDesc(key, pack(value))
-		return record
-	if t == InstanceType and hasattr(x, '__aepack__'):
-		return x.__aepack__()
-	return AE.AECreateDesc('TEXT', repr(x)) # Copout
-
-
-def unpack(desc):
-	t = desc.type
-	if t == 'TEXT':
-		return desc.data
-	if t == 'fals':
-		return 0
-	if t == 'true':
-		return 1
-	if t == 'enum':
-		return mkenum(desc.data)
-	if t == 'type':
-		return mktype(desc.data)
-	if t == 'long':
-		return struct.unpack('l', desc.data)[0]
-	if t == 'shor':
-		return struct.unpack('h', desc.data)[0]
-	if t == 'sing':
-		return struct.unpack('f', desc.data)[0]
-	if t == 'exte':
-		data = desc.data
-		# XXX See corresponding note for pack()
-		return struct.unpack('d', data[:2] + data)[0]
-	if t in ('doub', 'comp', 'magn'):
-		return unpack(desc.AECoerceDesc('exte'))
-	if t == 'null':
-		return None
-	if t == 'list':
-		l = []
-		for i in range(desc.AECountItems()):
-			keyword, item = desc.AEGetNthDesc(i+1, '****')
-			l.append(unpack(item))
-		return l
-	if t == 'reco':
-		d = {}
-		for i in range(desc.AECountItems()):
-			keyword, item = desc.AEGetNthDesc(i+1, '****')
-			d[keyword] = unpack(item)
-		return d
-	if t == 'obj ':
-		record = desc.AECoerceDesc('reco')
-		return mkobject(unpack(record))
-	if t == 'rang':
-		record = desc.AECoerceDesc('reco')
-		return mkrange(unpack(record))
-	if t == 'cmpd':
-		record = desc.AECoerceDesc('reco')
-		return mkcomparison(unpack(record))
-	if t == 'logi':
-		record = desc.AECoerceDesc('reco')
-		return mklogical(unpack(record))
-	if t == 'targ':
-		return mktargetid(desc.data)
-	if t == 'alis':
-		# XXX Can't handle alias records yet, so coerce to FS spec...
-		return unpack(desc.AECoerceDesc('fss '))
-	if t == 'fss ':
-		return mkfss(desc.data)
-	return mkunknown(desc.type, desc.data)
-
-
-def mkfss(data):
-	print "mkfss data =", `data`
-	vol, dir, fnlen = struct.unpack('hlb', data[:7])
-	filename = data[7:7+fnlen]
-	print (vol, dir, fnlen, filename)
-	return macfs.FSSpec((vol, dir, filename))
-
-
-def mktargetid(data):
-	sessionID = getlong(data[:4])
-	name = mkppcportrec(data[4:4+72])
-	print len(name), `name`
-	location = mklocationnamerec(data[76:76+36])
-	rcvrName = mkppcportrec(data[112:112+72])
-	return sessionID, name, location, rcvrName
-
-def mkppcportrec(rec):
-	namescript = getword(rec[:2])
-	name = getpstr(rec[2:2+33])
-	portkind = getword(rec[36:38])
-	if portkind == 1:
-		ctor = rec[38:42]
-		type = rec[42:46]
-		identity = (ctor, type)
-	else:
-		identity = getpstr(rec[38:38+33])
-	return namescript, name, portkind, identity
-
-def mklocationnamerec(rec):
-	kind = getword(rec[:2])
-	stuff = rec[2:]
-	if kind == 0: stuff = None
-	if kind == 2: stuff = getpstr(stuff)
-	return kind, stuff
-
-def getpstr(s):
-	return s[1:1+ord(s[0])]
-
-def getlong(s):
-	return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
-
-def getword(s):
-	return (ord(s[0])<<8) | (ord(s[1])<<0)
-
-
-def mkunknown(type, data):
-	return Unknown(type, data)
-
-class Unknown:
-	
-	def __init__(self, type, data):
-		self.type = type
-		self.data = data
-	
-	def __repr__(self):
-		return "Unknown(%s, %s)" % (`self.type`, `self.data`)
-	
-	def __aepack__(self):
-		return pack(self.data, self.type)
-
-
-def IsSubclass(cls, base):
-	"""Test whether CLASS1 is the same as or a subclass of CLASS2"""
-	# Loop to optimize for single inheritance
-	while 1:
-		if cls is base: return 1
-		if len(cls.__bases__) <> 1: break
-		cls = cls.__bases__[0]
-	# Recurse to cope with multiple inheritance
-	for c in cls.__bases__:
-		if IsSubclass(c, base): return 1
-	return 0
-
-def IsInstance(x, cls):
-	"""Test whether OBJECT is an instance of (a subclass of) CLASS"""
-	return type(x) is InstanceType and IsSubclass(x.__class__, cls)
-
-
-def nice(s):
-	if type(s) is StringType: return repr(s)
-	else: return str(s)
-
-
-def mkenum(enum):
-	if IsEnum(enum): return enum
-	return Enum(enum)
-
-class Enum:
-	
-	def __init__(self, enum):
-		self.enum = "%-4.4s" % str(enum)
-	
-	def __repr__(self):
-		return "Enum(%s)" % `self.enum`
-	
-	def __str__(self):
-		return strip(self.enum)
-	
-	def __aepack__(self):
-		return pack(self.enum, 'enum')
-
-def IsEnum(x):
-	return IsInstance(x, Enum)
-
-
-def mktype(type):
-	if IsType(type): return type
-	return Type(type)
-
-class Type:
-	
-	def __init__(self, type):
-		self.type = "%-4.4s" % str(type)
-	
-	def __repr__(self):
-		return "Type(%s)" % `self.type`
-	
-	def __str__(self):
-		return strip(self.type)
-	
-	def __aepack__(self):
-		return pack(self.type, 'type')
-
-def IsType(x):
-	return IsInstance(x, Type)
-
-
-def mkrange(dict):
-	return Range(dict['star'], dict['stop'])
-
-class Range:
-	
-	def __init__(self, start, stop):
-		self.start = start
-		self.stop = stop
-	
-	def __repr__(self):
-		return "Range(%s, %s)" % (`self.start`, `self.stop`)
-	
-	def __str__(self):
-		return "%s thru %s" % (nice(self.start), nice(self.stop))
-	
-	def __aepack__(self):
-		return pack({'star': self.start, 'stop': self.stop}, 'rang')
-
-def IsRange(x):
-	return IsInstance(x, Range)
-
-
-def mkcomparison(dict):
-	return Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
-
-class Comparison:
-	
-	def __init__(self, obj1, relo, obj2):
-		self.obj1 = obj1
-		self.relo = "%-4.4s" % str(relo)
-		self.obj2 = obj2
-	
-	def __repr__(self):
-		return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
-	
-	def __str__(self):
-		return "%s %s %s" % (nice(self.obj1), strip(self.relo), nice(self.obj2))
-	
-	def __aepack__(self):
-		return pack({'obj1': self.obj1,
-			     'relo': mkenum(self.relo),
-			     'obj2': self.obj2},
-			    'cmpd')
-
-def IsComparison(x):
-	return IsInstance(x, Comparison)
-
-
-def mklogical(dict):
-	return Logical(dict['logc'], dict['term'])
-
-class Logical:
-	
-	def __init__(self, logc, term):
-		self.logc = "%-4.4s" % str(logc)
-		self.term = term
-	
-	def __repr__(self):
-		return "Logical(%s, %s)" % (`self.logc`, `self.term`)
-	
-	def __str__(self):
-		if type(self.term) == ListType and len(self.term) == 2:
-			return "%s %s %s" % (nice(self.term[0]),
-			                     strip(self.logc),
-			                     nice(self.term[1]))
-		else:
-			return "%s(%s)" % (strip(self.logc), nice(self.term))
-	
-	def __aepack__(self):
-		return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
-
-def IsLogical(x):
-	return IsInstance(x, Logical)
-
-
-class ObjectSpecifier:
-	
-	"""A class for constructing and manipulation AE object specifiers in python.
-	
-	An object specifier is actually a record with four fields:
-	
-	key	type	description
-	---	----	-----------
-	
-	'want'	type	what kind of thing we want,
-			e.g. word, paragraph or property
-	
-	'form'	enum	how we specify the thing(s) we want,
-			e.g. by index, by range, by name, or by property specifier
-	
-	'seld'	any	which thing(s) we want,
-			e.g. its index, its name, or its property specifier
-	
-	'from'	object	the object in which it is contained,
-			or null, meaning look for it in the application
-	
-	Note that we don't call this class plain "Object", since that name
-	is likely to be used by the application.
-	"""
-	
-	def __init__(self, want, form, seld, fr = None):
-		self.want = want
-		self.form = form
-		self.seld = seld
-		self.fr = fr
-	
-	def __repr__(self):
-		s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
-		if self.fr:
-			s = s + ", %s)" % `self.fr`
-		else:
-			s = s + ")"
-		return s
-	
-	def __aepack__(self):
-		return pack({'want': mktype(self.want),
-			     'form': mkenum(self.form),
-			     'seld': self.seld,
-			     'from': self.fr},
-			    'obj ')
-
-
-def IsObjectSpecifier(x):
-	return IsInstance(x, ObjectSpecifier)
-
-
-class Property(ObjectSpecifier):
-
-	def __init__(self, which, fr = None):
-		ObjectSpecifier.__init__(self, 'prop', 'prop', mkenum(which), fr)
-
-	def __repr__(self):
-		if self.fr:
-			return "Property(%s, %s)" % (`self.seld.enum`, `self.fr`)
-		else:
-			return "Property(%s)" % `self.seld.enum`
-	
-	def __str__(self):
-		if self.fr:
-			return "Property %s of %s" % (str(self.seld), str(self.fr))
-		else:
-			return "Property %s" % str(self.seld)
-
-
-class SelectableItem(ObjectSpecifier):
-	
-	def __init__(self, want, seld, fr = None):
-		t = type(seld)
-		if t == StringType:
-			form = 'name'
-		elif IsRange(seld):
-			form = 'rang'
-		elif IsComparison(seld) or IsLogical(seld):
-			form = 'test'
-		else:
-			form = 'indx'
-		ObjectSpecifier.__init__(self, want, form, seld, fr)
-
-
-class ComponentItem(SelectableItem):
-	# Derived classes *must* set the *class attribute* 'want' to some constant
-	
-	def __init__(self, which, fr = None):
-		SelectableItem.__init__(self, self.want, which, fr)
-	
-	def __repr__(self):
-		if not self.fr:
-			return "%s(%s)" % (self.__class__.__name__, `self.seld`)
-		return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
-	
-	def __str__(self):
-		seld = self.seld
-		if type(seld) == StringType:
-			ss = repr(seld)
-		elif IsRange(seld):
-			start, stop = seld.start, seld.stop
-			if type(start) == InstanceType == type(stop) and \
-			   start.__class__ == self.__class__ == stop.__class__:
-				ss = str(start.seld) + " thru " + str(stop.seld)
-			else:
-				ss = str(seld)
-		else:
-			ss = str(seld)
-		s = "%s %s" % (self.__class__.__name__, ss)
-		if self.fr: s = s + " of %s" % str(self.fr)
-		return s
-
-
-template = """
-class %s(ComponentItem): want = '%s'
-"""
-
-exec template % ("Text", 'text')
-exec template % ("Character", 'cha ')
-exec template % ("Word", 'cwor')
-exec template % ("Line", 'clin')
-exec template % ("Paragraph", 'cpar')
-exec template % ("Window", 'cwin')
-exec template % ("Document", 'docu')
-exec template % ("File", 'file')
-exec template % ("InsertionPoint", 'cins')
-
-
-def mkobject(dict):
-	want = dict['want'].type
-	form = dict['form'].enum
-	seld = dict['seld']
-	fr   = dict['from']
-	if form in ('name', 'indx', 'rang', 'test'):
-		if want == 'text': return Text(seld, fr)
-		if want == 'cha ': return Character(seld, fr)
-		if want == 'cwor': return Word(seld, fr)
-		if want == 'clin': return Line(seld, fr)
-		if want == 'cpar': return Paragraph(seld, fr)
-		if want == 'cwin': return Window(seld, fr)
-		if want == 'docu': return Document(seld, fr)
-		if want == 'file': return File(seld, fr)
-		if want == 'cins': return InsertionPoint(seld, fr)
-	if want == 'prop' and form == 'prop' and IsType(seld):
-		return Property(seld.type, fr)
-	return ObjectSpecifier(want, form, seld, fr)
-
+from aetypes import *
+from aepack import pack, unpack, coerce, AEDescType
 
 # Special code to unpack an AppleEvent (which is *not* a disguised record!)
+# Note by Jack: No??!? If I read the docs correctly it *is*....
 
 aekeywords = [
 	'tran',
@@ -531,8 +76,90 @@
 	for key, value in attributes.items():
 		ae.AEPutAttributeDesc(key, pack(value))
 
+#
+# Support routine for automatically generated Suite interfaces
+#
+def keysubst(arguments, keydict):
+	"""Replace long name keys by their 4-char counterparts, and check"""
+	ok = keydict.values()
+	for k in arguments.keys():
+		if keydict.has_key(k):
+			v = arguments[k]
+			del arguments[k]
+			arguments[keydict[k]] = v
+		elif k != '----' and k not in ok:
+			raise TypeError, 'Unknown keyword argument: %s'%k
+			
+def enumsubst(arguments, key, edict):
+	"""Substitute a single enum keyword argument, if it occurs"""
+	if not arguments.has_key(key):
+		return
+	v = arguments[key]
+	ok = edict.values()
+	if edict.has_key(v):
+		arguments[key] = edict[v]
+	elif not v in ok:
+		raise TypeError, 'Unknown enumerator: %s'%v
+		
+def decodeerror(arguments):
+	"""Create the 'best' argument for a raise MacOS.Error"""
+	errn = arguments['errn']
+	errarg = (errn, MacOS.GetErrorString(errn))
+	if arguments.has_key('errs'):
+		errarg = errarg + (arguments['errs'],)
+	if arguments.has_key('erob'):
+		errarg = errarg + (arguments['erob'],)
+	return errarg
 
+class TalkTo:
+	"""An AE connection to an application"""
+	
+	def __init__(self, signature):
+		"""Create a communication channel with a particular application.
+		
+		Addressing the application is done by specifying either a
+		4-byte signature, an AEDesc or an object that will __aepack__
+		to an AEDesc.
+		"""
+		if type(signature) == AEDescType:
+			self.target = signature
+		elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
+			self.target = signature.__aepack__()
+		elif type(signature) == StringType and len(signature) != 4:
+			self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
+		else:
+			raise TypeError, "signature should be 4-char string or AEDesc"
+		self.send_flags = AppleEvents.kAEWaitReply
+		self.send_priority = AppleEvents.kAENormalPriority
+		self.send_timeout = AppleEvents.kAEDefaultTimeout
+	
+	def newevent(self, code, subcode, parameters = {}, attributes = {}):
+		"""Create a complete structure for an apple event"""
+		
+		event = AE.AECreateAppleEvent(code, subcode, self.target,
+		      	  AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
+		packevent(event, parameters, attributes)
+		return event
+	
+	def sendevent(self, event):
+		"""Send a pre-created appleevent, await the reply and unpack it"""
+		
+		reply = event.AESend(self.send_flags, self.send_priority,
+		                          self.send_timeout)
+		parameters, attributes = unpackevent(reply)
+		return reply, parameters, attributes
+		
+	def send(self, code, subcode, parameters = {}, attributes = {}):
+		"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
+		return self.sendevent(self.newevent(code, subcode, parameters, attributes))
+	
+	def activate(self):
+		"""Send 'activate' command"""
+		self.send('misc', 'actv')
+	
+	
 # Test program
+# XXXX Should test more, really...
 
 def test():
 	target = AE.AECreateDesc('sign', 'KAHL')
diff --git a/Mac/Lib/toolbox/aetypes.py b/Mac/Lib/toolbox/aetypes.py
new file mode 100644
index 0000000..e0a466f
--- /dev/null
+++ b/Mac/Lib/toolbox/aetypes.py
@@ -0,0 +1,452 @@
+"""aetypes - Python objects representing various AE types."""
+
+from AppleEvents import *
+from AERegistry import *
+from AEObjects import *
+import struct
+from types import *
+import string
+
+#
+# convoluted, since there are cyclic dependencies between this file and
+# aetools_convert.
+#
+def pack(*args):
+	from aepack import pack
+	return apply(pack, args)
+	
+def IsSubclass(cls, base):
+	"""Test whether CLASS1 is the same as or a subclass of CLASS2"""
+	# Loop to optimize for single inheritance
+	while 1:
+		if cls is base: return 1
+		if len(cls.__bases__) <> 1: break
+		cls = cls.__bases__[0]
+	# Recurse to cope with multiple inheritance
+	for c in cls.__bases__:
+		if IsSubclass(c, base): return 1
+	return 0
+
+def IsInstance(x, cls):
+	"""Test whether OBJECT is an instance of (a subclass of) CLASS"""
+	return type(x) is InstanceType and IsSubclass(x.__class__, cls)
+
+def nice(s):
+	"""'nice' representation of an object"""
+	if type(s) is StringType: return repr(s)
+	else: return str(s)
+
+class Unknown:
+	"""An uninterpreted AE object"""
+	
+	def __init__(self, type, data):
+		self.type = type
+		self.data = data
+	
+	def __repr__(self):
+		return "Unknown(%s, %s)" % (`self.type`, `self.data`)
+	
+	def __aepack__(self):
+		return pack(self.data, self.type)
+
+class Enum:
+	"""An AE enumeration value"""
+	
+	def __init__(self, enum):
+		self.enum = "%-4.4s" % str(enum)
+	
+	def __repr__(self):
+		return "Enum(%s)" % `self.enum`
+	
+	def __str__(self):
+		return string.strip(self.enum)
+	
+	def __aepack__(self):
+		return pack(self.enum, typeEnumeration)
+
+def IsEnum(x):
+	return IsInstance(x, Enum)
+
+def mkenum(enum):
+	if IsEnum(enum): return enum
+	return Enum(enum)
+
+class Type:
+	"""An AE 4-char typename object"""
+	
+	def __init__(self, type):
+		self.type = "%-4.4s" % str(type)
+	
+	def __repr__(self):
+		return "Type(%s)" % `self.type`
+	
+	def __str__(self):
+		return string.strip(self.type)
+	
+	def __aepack__(self):
+		return pack(self.type, typeType)
+
+def IsType(x):
+	return IsInstance(x, Type)
+
+def mktype(type):
+	if IsType(type): return type
+	return Type(type)
+
+
+class Keyword:
+	"""An AE 4-char keyword object"""
+	
+	def __init__(self, keyword):
+		self.keyword = "%-4.4s" % str(keyword)
+	
+	def __repr__(self):
+		return "Keyword(%s)" % `self.keyword`
+	
+	def __str__(self):
+		return string.strip(self.keyword)
+	
+	def __aepack__(self):
+		return pack(self.keyword, typeKeyword)
+
+def IsKeyword(x):
+	return IsInstance(x, Keyword)
+
+class Range:
+	"""An AE range object"""
+	
+	def __init__(self, start, stop):
+		self.start = start
+		self.stop = stop
+	
+	def __repr__(self):
+		return "Range(%s, %s)" % (`self.start`, `self.stop`)
+	
+	def __str__(self):
+		return "%s thru %s" % (nice(self.start), nice(self.stop))
+	
+	def __aepack__(self):
+		return pack({'star': self.start, 'stop': self.stop}, 'rang')
+
+def IsRange(x):
+	return IsInstance(x, Range)
+
+class Comparison:
+	"""An AE Comparison"""
+	
+	def __init__(self, obj1, relo, obj2):
+		self.obj1 = obj1
+		self.relo = "%-4.4s" % str(relo)
+		self.obj2 = obj2
+	
+	def __repr__(self):
+		return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
+	
+	def __str__(self):
+		return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
+	
+	def __aepack__(self):
+		return pack({'obj1': self.obj1,
+			     'relo': mkenum(self.relo),
+			     'obj2': self.obj2},
+			    'cmpd')
+
+def IsComparison(x):
+	return IsInstance(x, Comparison)
+
+class Logical:
+	"""An AE logical expression object"""
+	
+	def __init__(self, logc, term):
+		self.logc = "%-4.4s" % str(logc)
+		self.term = term
+	
+	def __repr__(self):
+		return "Logical(%s, %s)" % (`self.logc`, `self.term`)
+	
+	def __str__(self):
+		if type(self.term) == ListType and len(self.term) == 2:
+			return "%s %s %s" % (nice(self.term[0]),
+			                     string.strip(self.logc),
+			                     nice(self.term[1]))
+		else:
+			return "%s(%s)" % (string.strip(self.logc), nice(self.term))
+	
+	def __aepack__(self):
+		return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
+
+def IsLogical(x):
+	return IsInstance(x, Logical)
+
+class StyledText:
+	"""An AE object respresenting text in a certain style"""
+	
+	def __init__(self, style, text):
+		self.style = style
+		self.text = text
+	
+	def __repr__(self):
+		return "StyledText(%s, %s)" % (`self.style`, `self.text`)
+	
+	def __str__(self):
+		return self.text
+	
+	def __aepack__(self):
+		return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
+
+def IsStyledText(x):
+	return IsInstance(x, StyledText)
+
+class AEText:
+	"""An AE text object with style, script and language specified"""
+	
+	def __init__(self, script, style, text):
+		self.script = script
+		self.style = style
+		self.text = text
+	
+	def __repr__(self):
+		return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
+	
+	def __str__(self):
+		return self.text
+	
+	def __aepack__(self):
+		return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
+				 keyAEText: self.text}, typeAEText)
+
+def IsAEText(x):
+	return IsInstance(x, AEText)
+
+class IntlText:
+	"""A text object with script and language specified"""
+	
+	def __init__(self, script, language, text):
+		self.script = script
+		self.language = language
+		self.text = text
+	
+	def __repr__(self):
+		return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
+	
+	def __str__(self):
+		return self.text
+	
+	def __aepack__(self):
+		return pack(struct.pack('hh', self.script, self.language)+self.text,
+			typeIntlText)
+
+def IsIntlText(x):
+	return IsInstance(x, IntlText)
+
+class IntlWritingCode:
+	"""An object representing script and language"""
+	
+	def __init__(self, script, language):
+		self.script = script
+		self.language = language
+	
+	def __repr__(self):
+		return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
+	
+	def __str__(self):
+		return "script system %d, language %d"%(self.script, self.language)
+	
+	def __aepack__(self):
+		return pack(struct.pack('hh', self.script, self.language),
+			typeIntlWritingCode)
+
+def IsIntlWritingCode(x):
+	return IsInstance(x, IntlWritingCode)
+
+class QDPoint:
+	"""A point"""
+	
+	def __init__(self, v, h):
+		self.v = v
+		self.h = h
+	
+	def __repr__(self):
+		return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
+	
+	def __str__(self):
+		return "(%d, %d)"%(self.v, self.h)
+	
+	def __aepack__(self):
+		return pack(struct.pack('hh', self.v, self.h),
+			typeQDPoint)
+
+def IsQDPoint(x):
+	return IsInstance(x, QDPoint)
+
+class QDRectangle:
+	"""A rectangle"""
+	
+	def __init__(self, v0, h0, v1, h1):
+		self.v0 = v0
+		self.h0 = h0
+		self.v1 = v1
+		self.h1 = h1
+	
+	def __repr__(self):
+		return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
+				`self.v1`, `self.h1`)
+	
+	def __str__(self):
+		return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
+	
+	def __aepack__(self):
+		return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
+			typeQDRectangle)
+
+def IsQDRectangle(x):
+	return IsInstance(x, QDRectangle)
+
+class RGBColor:
+	"""An RGB color"""
+	
+	def __init__(self, r, g, b):
+		self.r = r
+		self.g = g
+		self.b = b
+			
+	def __repr__(self):
+		return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
+	
+	def __str__(self):
+		return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
+	
+	def __aepack__(self):
+		return pack(struct.pack('hhh', self.r, self.g, self.b),
+			typeRGBColor)
+
+def IsRGBColor(x):
+	return IsInstance(x, RGBColor)
+
+class ObjectSpecifier:
+	
+	"""A class for constructing and manipulation AE object specifiers in python.
+	
+	An object specifier is actually a record with four fields:
+	
+	key	type	description
+	---	----	-----------
+	
+	'want'	type	what kind of thing we want,
+			e.g. word, paragraph or property
+	
+	'form'	enum	how we specify the thing(s) we want,
+			e.g. by index, by range, by name, or by property specifier
+	
+	'seld'	any	which thing(s) we want,
+			e.g. its index, its name, or its property specifier
+	
+	'from'	object	the object in which it is contained,
+			or null, meaning look for it in the application
+	
+	Note that we don't call this class plain "Object", since that name
+	is likely to be used by the application.
+	"""
+	
+	def __init__(self, want, form, seld, fr = None):
+		self.want = want
+		self.form = form
+		self.seld = seld
+		self.fr = fr
+	
+	def __repr__(self):
+		s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
+		if self.fr:
+			s = s + ", %s)" % `self.fr`
+		else:
+			s = s + ")"
+		return s
+	
+	def __aepack__(self):
+		return pack({'want': mktype(self.want),
+			     'form': mkenum(self.form),
+			     'seld': self.seld,
+			     'from': self.fr},
+			    'obj ')
+
+
+def IsObjectSpecifier(x):
+	return IsInstance(x, ObjectSpecifier)
+
+
+class Property(ObjectSpecifier):
+
+	def __init__(self, which, fr = None):
+		ObjectSpecifier.__init__(self, 'prop', 'prop', mkenum(which), fr)
+
+	def __repr__(self):
+		if self.fr:
+			return "Property(%s, %s)" % (`self.seld.enum`, `self.fr`)
+		else:
+			return "Property(%s)" % `self.seld.enum`
+	
+	def __str__(self):
+		if self.fr:
+			return "Property %s of %s" % (str(self.seld), str(self.fr))
+		else:
+			return "Property %s" % str(self.seld)
+
+
+class SelectableItem(ObjectSpecifier):
+	
+	def __init__(self, want, seld, fr = None):
+		t = type(seld)
+		if t == StringType:
+			form = 'name'
+		elif IsRange(seld):
+			form = 'rang'
+		elif IsComparison(seld) or IsLogical(seld):
+			form = 'test'
+		else:
+			form = 'indx'
+		ObjectSpecifier.__init__(self, want, form, seld, fr)
+
+
+class ComponentItem(SelectableItem):
+	# Derived classes *must* set the *class attribute* 'want' to some constant
+	
+	def __init__(self, which, fr = None):
+		SelectableItem.__init__(self, self.want, which, fr)
+	
+	def __repr__(self):
+		if not self.fr:
+			return "%s(%s)" % (self.__class__.__name__, `self.seld`)
+		return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
+	
+	def __str__(self):
+		seld = self.seld
+		if type(seld) == StringType:
+			ss = repr(seld)
+		elif IsRange(seld):
+			start, stop = seld.start, seld.stop
+			if type(start) == InstanceType == type(stop) and \
+			   start.__class__ == self.__class__ == stop.__class__:
+				ss = str(start.seld) + " thru " + str(stop.seld)
+			else:
+				ss = str(seld)
+		else:
+			ss = str(seld)
+		s = "%s %s" % (self.__class__.__name__, ss)
+		if self.fr: s = s + " of %s" % str(self.fr)
+		return s
+
+
+template = """
+class %s(ComponentItem): want = '%s'
+"""
+
+exec template % ("Text", 'text')
+exec template % ("Character", 'cha ')
+exec template % ("Word", 'cwor')
+exec template % ("Line", 'clin')
+exec template % ("Paragraph", 'cpar')
+exec template % ("Window", 'cwin')
+exec template % ("Document", 'docu')
+exec template % ("File", 'file')
+exec template % ("InsertionPoint", 'cins')
+
