Committed a more or less working version.
diff --git a/Mac/Demo/resources/copyres.py b/Mac/Demo/resources/copyres.py
new file mode 100644
index 0000000..b401142
--- /dev/null
+++ b/Mac/Demo/resources/copyres.py
@@ -0,0 +1,57 @@
+from Res import *
+from Resources import *
+import MacOS
+
+READ = 1
+WRITE = 2
+smAllScripts = -3
+
+def copyres(src, dst):
+	"""Copy resource from src file to dst file."""
+	
+	cur = CurResFile()
+	ctor, type = MacOS.GetCreatorAndType(src)
+	input = FSpOpenResFile(src, READ)
+	try:
+		FSpCreateResFile(dst, ctor, type, smAllScripts)
+	except:
+		raw_input("%s already exists...  CR to write anyway! " % dst)
+	output = FSpOpenResFile(dst, WRITE)
+	UseResFile(input)
+	ntypes = Count1Types()
+	for itype in range(1, 1+ntypes):
+		type = Get1IndType(itype)
+		nresources = Count1Resources(type)
+		for ires in range(1, 1+nresources):
+			res = Get1IndResource(type, ires)
+			res.LoadResource()
+			id, type, name = res.GetResInfo()
+			size = res.SizeResource()
+			attrs = res.GetResAttrs()
+			print id, type, name, size, hex(attrs)
+			res.DetachResource()
+			UseResFile(output)
+			try:
+				res2 = Get1Resource(type, id)
+			except (RuntimeError, Res.Error), msg:
+				res2 = None
+			if res2:
+				print "Duplicate type+id, not copied"
+				print (res2.size, res2.data)
+				print res2.GetResInfo()
+				if res2.HomeResFile() == output:
+					'OK'
+				elif res2.HomeResFile() == input:
+					'BAD!'
+				else:
+					print 'Home:', res2.HomeResFile()
+			else:
+				res.AddResource(type, id, name)
+				#res.SetResAttrs(attrs)
+				res.WriteResource()
+			UseResFile(input)
+	UseResFile(cur)
+	CloseResFile(output)
+	CloseResFile(input)
+
+copyres('::python.¹.rsrc', '::foo.rsrc')
diff --git a/Mac/Demo/resources/listres.py b/Mac/Demo/resources/listres.py
new file mode 100644
index 0000000..a0b2423
--- /dev/null
+++ b/Mac/Demo/resources/listres.py
@@ -0,0 +1,60 @@
+# List all resources
+
+import Res
+from Resources import *
+
+def list1resources():
+	ntypes = Res.Count1Types()
+	for itype in range(1, 1+ntypes):
+		type = Res.Get1IndType(itype)
+		print "Type:", `type`
+		nresources = Res.Count1Resources(type)
+		for i in range(1, 1 + nresources):
+			Res.SetResLoad(0)
+			res = Res.Get1IndResource(type, i)
+			Res.SetResLoad(1)
+			info(res)
+
+def listresources():
+	ntypes = Res.CountTypes()
+	for itype in range(1, 1+ntypes):
+		type = Res.GetIndType(itype)
+		print "Type:", `type`
+		nresources = Res.CountResources(type)
+		for i in range(1, 1 + nresources):
+			Res.SetResLoad(0)
+			res = Res.GetIndResource(type, i)
+			Res.SetResLoad(1)
+			info(res)
+
+def info(res):
+	print res.GetResInfo(), res.SizeResource(), decodeattrs(res.GetResAttrs())
+
+attrnames = {
+	resChanged:	'Changed',
+	resPreload:	'Preload',
+	resProtected:	'Protected',
+	resLocked:	'Locked',
+	resPurgeable:	'Purgeable',
+	resSysHeap:	'SysHeap',
+}
+
+def decodeattrs(attrs):
+	names = []
+	for bit in range(16):
+		mask = 1<<bit
+		if attrs & mask:
+			if attrnames.has_key(mask):
+				names.append(attrnames[mask])
+			else:
+				names.append(hex(mask))
+	return names
+
+def test():
+	print "=== Local resourcess ==="
+	list1resources()
+	print "=== All resources ==="
+	listresources()
+
+if __name__ == '__main__':
+	test()