diff --git a/Mac/Lib/MiniAEFrame.py b/Mac/Lib/MiniAEFrame.py
new file mode 100644
index 0000000..fbb6f1b
--- /dev/null
+++ b/Mac/Lib/MiniAEFrame.py
@@ -0,0 +1,194 @@
+"""MiniAEFrame - A minimal AppleEvent Application framework.
+
+There are two classes:
+	AEServer -- a mixin class offering nice AE handling.
+	MiniApplication -- a very minimal alternative to FrameWork.py,
+		only suitable for the simplest of AppleEvent servers.
+"""
+
+import sys
+import traceback
+import MacOS
+import AE
+from AppleEvents import *
+import Evt
+from Events import *
+import Menu
+import Win
+from Windows import *
+import Qd
+
+import aetools
+import EasyDialogs
+
+kHighLevelEvent = 23				# Not defined anywhere for Python yet?
+
+
+class MiniApplication:
+	
+	"""A minimal FrameWork.Application-like class"""
+	
+	def __init__(self):
+		self.quitting = 0
+		# Initialize menu
+		self.appleid = 1
+		self.quitid = 2
+		Menu.ClearMenuBar()
+		self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024")
+		applemenu.AppendMenu("%s;(-" % self.getaboutmenutext())
+		if MacOS.runtimemodel == 'ppc':
+			applemenu.AppendResMenu('DRVR')
+		applemenu.InsertMenu(0)
+		self.quitmenu = Menu.NewMenu(self.quitid, "File")
+		self.quitmenu.AppendMenu("Quit")
+		self.quitmenu.SetItemCmd(1, ord("Q"))
+		self.quitmenu.InsertMenu(0)
+		Menu.DrawMenuBar()
+	
+	def __del__(self):
+		self.close()
+	
+	def close(self):
+		pass
+	
+	def mainloop(self, mask = everyEvent, timeout = 60*60):
+		while not self.quitting:
+			self.dooneevent(mask, timeout)
+	
+	def _quit(self):
+		self.quitting = 1
+	
+	def dooneevent(self, mask = everyEvent, timeout = 60*60):
+			got, event = Evt.WaitNextEvent(mask, timeout)
+			if got:
+				self.lowlevelhandler(event)
+	
+	def lowlevelhandler(self, event):
+		what, message, when, where, modifiers = event
+		h, v = where
+		if what == kHighLevelEvent:
+			msg = "High Level Event: %s %s" % \
+				(`code(message)`, `code(h | (v<<16))`)
+			try:
+				AE.AEProcessAppleEvent(event)
+			except AE.Error, err:
+				print 'AE error: ', err
+				print 'in', msg
+				traceback.print_exc()
+			return
+		elif what == keyDown:
+			c = chr(message & charCodeMask)
+			if modifiers & cmdKey:
+				if c == '.':
+					raise KeyboardInterrupt, "Command-period"
+				if c == 'q':
+					MacOS.OutputSeen()
+					self.quitting = 1
+					return
+		elif what == mouseDown:
+			partcode, window = Win.FindWindow(where)
+			if partcode == inMenuBar:
+				result = Menu.MenuSelect(where)
+				id = (result>>16) & 0xffff	# Hi word
+				item = result & 0xffff		# Lo word
+				if id == self.appleid:
+					if item == 1:
+						EasyDialogs.Message(self.getabouttext())
+					elif item > 1 and hasattr(Menu, 'OpenDeskAcc'):
+						name = self.applemenu.GetMenuItemText(item)
+						Menu.OpenDeskAcc(name)
+				elif id == self.quitid and item == 1:
+					MacOS.OutputSeen()
+					self.quitting = 1
+				Menu.HiliteMenu(0)
+				return
+		# Anything not handled is passed to Python/SIOUX
+		MacOS.HandleEvent(event)
+	
+	def getabouttext(self):
+		return self.__class__.__name__
+	
+	def getaboutmenutext(self):
+		return "About %s\311" % self.__class__.__name__
+
+
+class AEServer:
+	
+	def __init__(self):
+		self.ae_handlers = {}
+	
+	def installaehandler(self, classe, type, callback):
+		AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
+		self.ae_handlers[(classe, type)] = callback
+	
+	def close(self):
+		for classe, type in self.ae_handlers.keys():
+			AE.AERemoveEventHandler(classe, type)
+	
+	def callback_wrapper(self, _request, _reply):
+		_parameters, _attributes = aetools.unpackevent(_request)
+		_class = _attributes['evcl'].type
+		_type = _attributes['evid'].type
+		
+		if self.ae_handlers.has_key((_class, _type)):
+			_function = self.ae_handlers[(_class, _type)]
+		elif self.ae_handlers.has_key((_class, '****')):
+			_function = self.ae_handlers[(_class, '****')]
+		elif self.ae_handlers.has_key(('****', '****')):
+			_function = self.ae_handlers[('****', '****')]
+		else:
+			raise 'Cannot happen: AE callback without handler', (_class, _type)
+		
+		# XXXX Do key-to-name mapping here
+		
+		_parameters['_attributes'] = _attributes
+		_parameters['_class'] = _class
+		_parameters['_type'] = _type
+		if _parameters.has_key('----'):
+			_object = _parameters['----']
+			del _parameters['----']
+			# The try/except that used to be here can mask programmer errors.
+			# Let the program crash, the programmer can always add a **args
+			# to the formal parameter list.
+			rv = apply(_function, (_object,), _parameters)
+		else:
+			#Same try/except comment as above
+			rv = apply(_function, (), _parameters)
+		
+		if rv == None:
+			aetools.packevent(_reply, {})
+		else:
+			aetools.packevent(_reply, {'----':rv})
+
+
+def code(x):
+	"Convert a long int to the 4-character code it really is"
+	s = ''
+	for i in range(4):
+		x, c = divmod(x, 256)
+		s = chr(c) + s
+	return s
+
+class _Test(AEServer, MiniApplication):
+	"""Mini test application, handles required events"""
+	
+	def __init__(self):
+		MiniApplication.__init__(self)
+		AEServer.__init__(self)
+		self.installaehandler('aevt', 'oapp', self.open_app)
+		self.installaehandler('aevt', 'quit', self.quit)
+		self.installaehandler('****', '****', self.other)
+		self.mainloop()
+
+	def quit(self, **args):
+		self._quit()
+		
+	def open_app(self, **args):
+		pass
+		
+	def other(self, _object=None, _class=None, _type=None, **args):
+		print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
+		
+
+if __name__ == '__main__':
+	_Test()
diff --git a/Mac/Lib/aepack.py b/Mac/Lib/aepack.py
new file mode 100644
index 0000000..be6e645
--- /dev/null
+++ b/Mac/Lib/aepack.py
@@ -0,0 +1,347 @@
+"""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 *
+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 : typeFloat,
+	typeColorTable : typeAEList,
+	typeDrawingArea : typeAERecord,
+	typeFixed : typeFloat,
+	typeExtended : typeFloat,
+	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:
+		return AE.AECreateDesc('doub', struct.pack('d', x))
+	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])
+		t = desc.type # This is a guess by Jack....
+	
+	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 == typeFalse:
+		return 0
+	if t == typeFloat:
+		data = desc.data
+		return struct.unpack('d', data)[0]
+	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)
+	if t == typeLongInteger:
+		return struct.unpack('l', desc.data)[0]
+	if t == typeLongDateTime:
+		a, b = struct.unpack('lL', desc.data)
+		return (long(a) << 32) + b
+	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/aetools.py b/Mac/Lib/aetools.py
new file mode 100644
index 0000000..1af761e
--- /dev/null
+++ b/Mac/Lib/aetools.py
@@ -0,0 +1,277 @@
+"""Tools for use in AppleEvent clients and servers.
+
+pack(x) converts a Python object to an AEDesc object
+unpack(desc) does the reverse
+
+packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record
+unpackevent(event) returns the parameters and attributes from an AEAppleEvent record
+
+Plus...  Lots of classes and routines that help representing AE objects,
+ranges, conditionals, logicals, etc., so you can write, e.g.:
+
+	x = Character(1, Document("foobar"))
+
+and pack(x) will create an AE object reference equivalent to AppleScript's
+
+	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.
+
+"""
+
+
+from types import *
+import AE
+import AppleEvents
+import MacOS
+import sys
+
+from aetypes import *
+from aepack import pack, unpack, coerce, AEDescType
+
+Error = 'aetools.Error'
+
+# 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',
+	'rtid',
+	'evcl',
+	'evid',
+	'addr',
+	'optk',
+	'timo',
+	'inte',	# this attribute is read only - will be set in AESend
+	'esrc',	# this attribute is read only
+	'miss',	# this attribute is read only
+	'from'	# new in 1.0.1
+]
+
+def missed(ae):
+	try:
+		desc = ae.AEGetAttributeDesc('miss', 'keyw')
+	except AE.Error, msg:
+		return None
+	return desc.data
+
+def unpackevent(ae):
+	parameters = {}
+	try:
+		dirobj = ae.AEGetParamDesc('----', '****')
+	except AE.Error:
+		pass
+	else:
+		parameters['----'] = unpack(dirobj)
+		del dirobj
+	while 1:
+		key = missed(ae)
+		if not key: break
+		parameters[key] = unpack(ae.AEGetParamDesc(key, '****'))
+	attributes = {}
+	for key in aekeywords:
+		try:
+			desc = ae.AEGetAttributeDesc(key, '****')
+		except (AE.Error, MacOS.Error), msg:
+			if msg[0] != -1701 and msg[0] != -1704:
+				raise sys.exc_type, sys.exc_value
+			continue
+		attributes[key] = unpack(desc)
+	return parameters, attributes
+
+def packevent(ae, parameters = {}, attributes = {}):
+	for key, value in parameters.items():
+		ae.AEPutParamDesc(key, pack(value))
+	for key, value in attributes.items():
+		ae.AEPutAttributeDesc(key, pack(value))
+
+#
+# Support routine for automatically generated Suite interfaces
+# These routines are also useable for the reverse function.
+#
+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) or edict is None:
+		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']
+	err_a1 = errn
+	if arguments.has_key('errs'):
+		err_a2 = arguments['errs']
+	else:
+		err_a2 = MacOS.GetErrorString(errn)
+	if arguments.has_key('erob'):
+		err_a3 = arguments['erob']
+	else:
+		err_a3 = None
+	
+	return (err_a1, err_a2, err_a3)
+
+class TalkTo:
+	"""An AE connection to an application"""
+	_signature = None	# Can be overridden by subclasses
+	
+	def __init__(self, signature=None, start=0, timeout=0):
+		"""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.
+		"""
+		self.target_signature = None
+		if signature is None:
+			signature = self._signature
+		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)
+			self.target_signature = signature
+		else:
+			raise TypeError, "signature should be 4-char string or AEDesc"
+		self.send_flags = AppleEvents.kAEWaitReply
+		self.send_priority = AppleEvents.kAENormalPriority
+		if timeout:
+			self.send_timeout = timeout
+		else:
+			self.send_timeout = AppleEvents.kAEDefaultTimeout
+		if start:
+			self.start()
+		
+	def start(self):
+		"""Start the application, if it is not running yet"""
+		try:
+			self.send('ascr', 'noop')
+		except AE.Error:
+			_launch(self.target_signature)
+			
+	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))
+	
+	#
+	# The following events are somehow "standard" and don't seem to appear in any
+	# suite...
+	#
+	def activate(self):
+		"""Send 'activate' command"""
+		self.send('misc', 'actv')
+
+	def _get(self, _object, as=None, _attributes={}):
+		"""_get: get data from an object
+		Required argument: the object
+		Keyword argument _attributes: AppleEvent attribute dictionary
+		Returns: the data
+		"""
+		_code = 'core'
+		_subcode = 'getd'
+
+		_arguments = {'----':_object}
+		if as:
+			_arguments['rtyp'] = mktype(as)
+
+		_reply, _arguments, _attributes = self.send(_code, _subcode,
+				_arguments, _attributes)
+		if _arguments.has_key('errn'):
+			raise Error, decodeerror(_arguments)
+
+		if _arguments.has_key('----'):
+			return _arguments['----']
+
+# Tiny Finder class, for local use only
+
+class _miniFinder(TalkTo):
+	def open(self, _object, _attributes={}, **_arguments):
+		"""open: Open the specified object(s)
+		Required argument: list of objects to open
+		Keyword argument _attributes: AppleEvent attribute dictionary
+		"""
+		_code = 'aevt'
+		_subcode = 'odoc'
+
+		if _arguments: raise TypeError, 'No optional args expected'
+		_arguments['----'] = _object
+
+
+		_reply, _arguments, _attributes = self.send(_code, _subcode,
+				_arguments, _attributes)
+		if _arguments.has_key('errn'):
+			raise Error, decodeerror(_arguments)
+		# XXXX Optionally decode result
+		if _arguments.has_key('----'):
+			return _arguments['----']
+#pass
+	
+_finder = _miniFinder('MACS')
+
+def _launch(appfile):
+	"""Open a file thru the finder. Specify file by name or fsspec"""
+	_finder.open(_application_file(('ID  ', appfile)))
+
+
+class _application_file(ComponentItem):
+	"""application file - An application's file on disk"""
+	want = 'appf'
+	
+_application_file._propdict = {
+}
+_application_file._elemdict = {
+}
+	
+# Test program
+# XXXX Should test more, really...
+
+def test():
+	target = AE.AECreateDesc('sign', 'quil')
+	ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
+	print unpackevent(ae)
+	raw_input(":")
+	ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
+	obj = Character(2, Word(1, Document(1)))
+	print obj
+	print repr(obj)
+	packevent(ae, {'----': obj})
+	params, attrs = unpackevent(ae)
+	print params['----']
+	raw_input(":")
+
+if __name__ == '__main__':
+	test()
+	sys.exit(1)
diff --git a/Mac/Lib/aetypes.py b/Mac/Lib/aetypes.py
new file mode 100644
index 0000000..253d1e7
--- /dev/null
+++ b/Mac/Lib/aetypes.py
@@ -0,0 +1,564 @@
+"""aetypes - Python objects representing various AE types."""
+
+from AppleEvents 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 Boolean:
+	"""An AE boolean value"""
+	
+	def __init__(self, bool):
+		self.bool = (not not bool)
+	
+	def __repr__(self):
+		return "Boolean(%s)" % `self.bool`
+	
+	def __str__(self):
+		if self.bool:
+			return "True"
+		else:
+			return "False"
+	
+	def __aepack__(self):
+		return pack(struct.pack('b', self.bool), 'bool')
+
+def IsBoolean(x):
+	return IsInstance(x, Boolean)
+
+def mkboolean(bool):
+	if IsBoolean(bool): return bool
+	return Boolean(bool)
+
+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 NComparison(Comparison):
+	# The class attribute 'relo' must be set in a subclass
+	
+	def __init__(self, obj1, obj2):
+		Comparison.__init__(obj1, self.relo, obj2)
+
+class Ordinal:
+	"""An AE Ordinal"""
+	
+	def __init__(self, abso):
+#		self.obj1 = obj1
+		self.abso = "%-4.4s" % str(abso)
+	
+	def __repr__(self):
+		return "Ordinal(%s)" % (`self.abso`)
+	
+	def __str__(self):
+		return "%s" % (string.strip(self.abso))
+	
+	def __aepack__(self):
+		return pack(self.abso, 'abso')
+
+def IsOrdinal(x):
+	return IsInstance(x, Ordinal)
+	
+class NOrdinal(Ordinal):
+	# The class attribute 'abso' must be set in a subclass
+	
+	def __init__(self):
+		Ordinal.__init__(self, self.abso)
+
+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	4-char class code of thing we want,
+			e.g. word, paragraph or property
+	
+	'form'	enum	how we specify which 'want' 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)
+
+
+# Backwards compatability, sigh...
+class Property(ObjectSpecifier):
+
+	def __init__(self, which, fr = None, want='prop'):
+		ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
+
+	def __repr__(self):
+		if self.fr:
+			return "Property(%s, %s)" % (`self.seld.type`, `self.fr`)
+		else:
+			return "Property(%s)" % `self.seld.type`
+	
+	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 NProperty(ObjectSpecifier):
+	# Subclasses *must* self baseclass attributes:
+	# want is the type of this property
+	# which is the property name of this property
+
+	def __init__(self, fr = None):
+		#try:
+		#	dummy = self.want
+		#except:
+		#	self.want = 'prop'
+		self.want = 'prop'
+		ObjectSpecifier.__init__(self, self.want, 'prop', 
+					mktype(self.which), fr)
+
+	def __repr__(self):
+		rv = "Property(%s"%`self.seld.type`
+		if self.fr:
+			rv = rv + ", fr=%s" % `self.fr`
+		if self.want != 'prop':
+			rv = rv + ", want=%s" % `self.want`
+		return rv + ")"
+	
+	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'
+		elif t == TupleType:
+			# Breakout: specify both form and seld in a tuple
+			# (if you want ID or rele or somesuch)
+			form, seld = seld
+		else:
+			form = 'indx'
+		ObjectSpecifier.__init__(self, want, form, seld, fr)
+
+
+class ComponentItem(SelectableItem):
+	# Derived classes *must* set the *class attribute* 'want' to some constant
+	# Also, dictionaries _propdict and _elemdict must be set to map property
+	# and element names to the correct classes
+	
+	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
+		
+	def __getattr__(self, name):
+		if self._elemdict.has_key(name):
+			cls = self._elemdict[name]
+			return DelayedComponentItem(cls, self)
+		if self._propdict.has_key(name):
+	   		cls = self._propdict[name]
+	   		return cls(self)
+		raise AttributeError, name
+		
+		
+class DelayedComponentItem:
+	def __init__(self, compclass, fr):
+		self.compclass = compclass
+		self.fr = fr
+		
+	def __call__(self, which):
+		return self.compclass(which, self.fr)
+		
+	def __repr__(self):
+		return "%s(???, %s)" % (self.__class__.__name__, `self.fr`)
+		
+	def __str__(self):
+		return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
+
+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')
+
