Whitespace normalization.  Ran reindent.py over the entire source tree.
diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py
index 7510d1e..a1ab635 100755
--- a/Demo/pdist/FSProxy.py
+++ b/Demo/pdist/FSProxy.py
@@ -24,299 +24,299 @@
 import fnmatch
 
 if os.name == 'mac':
-	import macfs
-	maxnamelen = 31
+    import macfs
+    maxnamelen = 31
 else:
-	macfs = None
-	maxnamelen = 255
+    macfs = None
+    maxnamelen = 255
 
 skipnames = (os.curdir, os.pardir)
 
 
 class FSProxyLocal:
-	
-	def __init__(self):
-		self._dirstack = []
-		self._ignore = ['*.pyc'] + self._readignore()
-	
-	def _close(self):
-		while self._dirstack:
-			self.back()
-	
-	def _readignore(self):
-		file = self._hide('ignore')
-		try:
-			f = open(file)
-		except IOError:
-			file = self._hide('synctree.ignorefiles')
-			try:
-				f = open(file)
-			except IOError:
-				return []
-		ignore = []
-		while 1:
-			line = f.readline()
-			if not line: break
-			if line[-1] == '\n': line = line[:-1]
-			ignore.append(line)
-		f.close()
-		return ignore
-	
-	def _hidden(self, name):
-		if os.name == 'mac':
-			return name[0] == '(' and name[-1] == ')'
-		else:
-			return name[0] == '.'
-	
-	def _hide(self, name):
-		if os.name == 'mac':
-			return '(%s)' % name
-		else:
-			return '.%s' % name
-	
-	def visible(self, name):
-		if len(name) > maxnamelen: return 0
-		if name[-1] == '~': return 0
-		if name in skipnames: return 0
-		if self._hidden(name): return 0
-		head, tail = os.path.split(name)
-		if head or not tail: return 0
-		if macfs:
-			if os.path.exists(name) and not os.path.isdir(name):
-				try:
-					fs = macfs.FSSpec(name)
-					c, t = fs.GetCreatorType()
-					if t != 'TEXT': return 0
-				except macfs.error, msg:
-					print "***", name, msg
-					return 0
-		else:
-			if os.path.islink(name): return 0
-			if '\0' in open(name, 'rb').read(512): return 0
-		for ign in self._ignore:
-			if fnmatch.fnmatch(name, ign): return 0
-		return 1
-	
-	def check(self, name):
-		if not self.visible(name):
-			raise os.error, "protected name %s" % repr(name)
-	
-	def checkfile(self, name):
-		self.check(name)
-		if not os.path.isfile(name):
-			raise os.error, "not a plain file %s" % repr(name)
-	
-	def pwd(self):
-		return os.getcwd()
-	
-	def cd(self, name):
-		self.check(name)
-		save = os.getcwd(), self._ignore
-		os.chdir(name)
-		self._dirstack.append(save)
-		self._ignore = self._ignore + self._readignore()
-	
-	def back(self):
-		if not self._dirstack:
-			raise os.error, "empty directory stack"
-		dir, ignore = self._dirstack[-1]
-		os.chdir(dir)
-		del self._dirstack[-1]
-		self._ignore = ignore
-	
-	def _filter(self, files, pat = None):
-		if pat:
-			def keep(name, pat = pat):
-				return fnmatch.fnmatch(name, pat)
-			files = filter(keep, files)
-		files = filter(self.visible, files)
-		files.sort()
-		return files
-	
-	def list(self, pat = None):
-		files = os.listdir(os.curdir)
-		return self._filter(files, pat)
-	
-	def listfiles(self, pat = None):
-		files = os.listdir(os.curdir)
-		files = filter(os.path.isfile, files)
-		return self._filter(files, pat)
-	
-	def listsubdirs(self, pat = None):
-		files = os.listdir(os.curdir)
-		files = filter(os.path.isdir, files)
-		return self._filter(files, pat)
-	
-	def exists(self, name):
-		return self.visible(name) and os.path.exists(name)
-	
-	def isdir(self, name):
-		return self.visible(name) and os.path.isdir(name)
-	
-	def islink(self, name):
-		return self.visible(name) and os.path.islink(name)
-	
-	def isfile(self, name):
-		return self.visible(name) and os.path.isfile(name)
-	
-	def sum(self, name):
-		self.checkfile(name)
-		BUFFERSIZE = 1024*8
-		f = open(name)
-		sum = md5.new()
-		while 1:
-			buffer = f.read(BUFFERSIZE)
-			if not buffer:
-				break
-			sum.update(buffer)
-		return sum.digest()
-	
-	def size(self, name):
-		self.checkfile(name)
-		return os.stat(name)[ST_SIZE]
-	
-	def mtime(self, name):
-		self.checkfile(name)
-		return time.localtime(os.stat(name)[ST_MTIME])
-	
-	def stat(self, name):
-		self.checkfile(name)
-		size = os.stat(name)[ST_SIZE]
-		mtime = time.localtime(os.stat(name)[ST_MTIME])
-		return size, mtime
-	
-	def info(self, name):
-		sum = self.sum(name)
-		size = os.stat(name)[ST_SIZE]
-		mtime = time.localtime(os.stat(name)[ST_MTIME])
-		return sum, size, mtime
-	
-	def _list(self, function, list):
-		if list is None:
-			list = self.listfiles()
-		res = []
-		for name in list:
-			try:
-				res.append((name, function(name)))
-			except (os.error, IOError):
-				res.append((name, None))
-		return res
-	
-	def sumlist(self, list = None):
-		return self._list(self.sum, list)
-	
-	def statlist(self, list = None):
-		return self._list(self.stat, list)
-	
-	def mtimelist(self, list = None):
-		return self._list(self.mtime, list)
-	
-	def sizelist(self, list = None):
-		return self._list(self.size, list)
-	
-	def infolist(self, list = None):
-		return self._list(self.info, list)
-	
-	def _dict(self, function, list):
-		if list is None:
-			list = self.listfiles()
-		dict = {}
-		for name in list:
-			try:
-				dict[name] = function(name)
-			except (os.error, IOError):
-				pass
-		return dict
-	
-	def sumdict(self, list = None):
-		return self.dict(self.sum, list)
-	
-	def sizedict(self, list = None):
-		return self.dict(self.size, list)
-	
-	def mtimedict(self, list = None):
-		return self.dict(self.mtime, list)
-	
-	def statdict(self, list = None):
-		return self.dict(self.stat, list)
-	
-	def infodict(self, list = None):
-		return self._dict(self.info, list)
-	
-	def read(self, name, offset = 0, length = -1):
-		self.checkfile(name)
-		f = open(name)
-		f.seek(offset)
-		if length == 0:
-			data = ''
-		elif length < 0:
-			data = f.read()
-		else:
-			data = f.read(length)
-		f.close()
-		return data
-	
-	def create(self, name):
-		self.check(name)
-		if os.path.exists(name):
-			self.checkfile(name)
-			bname = name + '~'
-			try:
-				os.unlink(bname)
-			except os.error:
-				pass
-			os.rename(name, bname)
-		f = open(name, 'w')
-		f.close()
-	
-	def write(self, name, data, offset = 0):
-		self.checkfile(name)
-		f = open(name, 'r+')
-		f.seek(offset)
-		f.write(data)
-		f.close()
-	
-	def mkdir(self, name):
-		self.check(name)
-		os.mkdir(name, 0777)
-	
-	def rmdir(self, name):
-		self.check(name)
-		os.rmdir(name)
+
+    def __init__(self):
+        self._dirstack = []
+        self._ignore = ['*.pyc'] + self._readignore()
+
+    def _close(self):
+        while self._dirstack:
+            self.back()
+
+    def _readignore(self):
+        file = self._hide('ignore')
+        try:
+            f = open(file)
+        except IOError:
+            file = self._hide('synctree.ignorefiles')
+            try:
+                f = open(file)
+            except IOError:
+                return []
+        ignore = []
+        while 1:
+            line = f.readline()
+            if not line: break
+            if line[-1] == '\n': line = line[:-1]
+            ignore.append(line)
+        f.close()
+        return ignore
+
+    def _hidden(self, name):
+        if os.name == 'mac':
+            return name[0] == '(' and name[-1] == ')'
+        else:
+            return name[0] == '.'
+
+    def _hide(self, name):
+        if os.name == 'mac':
+            return '(%s)' % name
+        else:
+            return '.%s' % name
+
+    def visible(self, name):
+        if len(name) > maxnamelen: return 0
+        if name[-1] == '~': return 0
+        if name in skipnames: return 0
+        if self._hidden(name): return 0
+        head, tail = os.path.split(name)
+        if head or not tail: return 0
+        if macfs:
+            if os.path.exists(name) and not os.path.isdir(name):
+                try:
+                    fs = macfs.FSSpec(name)
+                    c, t = fs.GetCreatorType()
+                    if t != 'TEXT': return 0
+                except macfs.error, msg:
+                    print "***", name, msg
+                    return 0
+        else:
+            if os.path.islink(name): return 0
+            if '\0' in open(name, 'rb').read(512): return 0
+        for ign in self._ignore:
+            if fnmatch.fnmatch(name, ign): return 0
+        return 1
+
+    def check(self, name):
+        if not self.visible(name):
+            raise os.error, "protected name %s" % repr(name)
+
+    def checkfile(self, name):
+        self.check(name)
+        if not os.path.isfile(name):
+            raise os.error, "not a plain file %s" % repr(name)
+
+    def pwd(self):
+        return os.getcwd()
+
+    def cd(self, name):
+        self.check(name)
+        save = os.getcwd(), self._ignore
+        os.chdir(name)
+        self._dirstack.append(save)
+        self._ignore = self._ignore + self._readignore()
+
+    def back(self):
+        if not self._dirstack:
+            raise os.error, "empty directory stack"
+        dir, ignore = self._dirstack[-1]
+        os.chdir(dir)
+        del self._dirstack[-1]
+        self._ignore = ignore
+
+    def _filter(self, files, pat = None):
+        if pat:
+            def keep(name, pat = pat):
+                return fnmatch.fnmatch(name, pat)
+            files = filter(keep, files)
+        files = filter(self.visible, files)
+        files.sort()
+        return files
+
+    def list(self, pat = None):
+        files = os.listdir(os.curdir)
+        return self._filter(files, pat)
+
+    def listfiles(self, pat = None):
+        files = os.listdir(os.curdir)
+        files = filter(os.path.isfile, files)
+        return self._filter(files, pat)
+
+    def listsubdirs(self, pat = None):
+        files = os.listdir(os.curdir)
+        files = filter(os.path.isdir, files)
+        return self._filter(files, pat)
+
+    def exists(self, name):
+        return self.visible(name) and os.path.exists(name)
+
+    def isdir(self, name):
+        return self.visible(name) and os.path.isdir(name)
+
+    def islink(self, name):
+        return self.visible(name) and os.path.islink(name)
+
+    def isfile(self, name):
+        return self.visible(name) and os.path.isfile(name)
+
+    def sum(self, name):
+        self.checkfile(name)
+        BUFFERSIZE = 1024*8
+        f = open(name)
+        sum = md5.new()
+        while 1:
+            buffer = f.read(BUFFERSIZE)
+            if not buffer:
+                break
+            sum.update(buffer)
+        return sum.digest()
+
+    def size(self, name):
+        self.checkfile(name)
+        return os.stat(name)[ST_SIZE]
+
+    def mtime(self, name):
+        self.checkfile(name)
+        return time.localtime(os.stat(name)[ST_MTIME])
+
+    def stat(self, name):
+        self.checkfile(name)
+        size = os.stat(name)[ST_SIZE]
+        mtime = time.localtime(os.stat(name)[ST_MTIME])
+        return size, mtime
+
+    def info(self, name):
+        sum = self.sum(name)
+        size = os.stat(name)[ST_SIZE]
+        mtime = time.localtime(os.stat(name)[ST_MTIME])
+        return sum, size, mtime
+
+    def _list(self, function, list):
+        if list is None:
+            list = self.listfiles()
+        res = []
+        for name in list:
+            try:
+                res.append((name, function(name)))
+            except (os.error, IOError):
+                res.append((name, None))
+        return res
+
+    def sumlist(self, list = None):
+        return self._list(self.sum, list)
+
+    def statlist(self, list = None):
+        return self._list(self.stat, list)
+
+    def mtimelist(self, list = None):
+        return self._list(self.mtime, list)
+
+    def sizelist(self, list = None):
+        return self._list(self.size, list)
+
+    def infolist(self, list = None):
+        return self._list(self.info, list)
+
+    def _dict(self, function, list):
+        if list is None:
+            list = self.listfiles()
+        dict = {}
+        for name in list:
+            try:
+                dict[name] = function(name)
+            except (os.error, IOError):
+                pass
+        return dict
+
+    def sumdict(self, list = None):
+        return self.dict(self.sum, list)
+
+    def sizedict(self, list = None):
+        return self.dict(self.size, list)
+
+    def mtimedict(self, list = None):
+        return self.dict(self.mtime, list)
+
+    def statdict(self, list = None):
+        return self.dict(self.stat, list)
+
+    def infodict(self, list = None):
+        return self._dict(self.info, list)
+
+    def read(self, name, offset = 0, length = -1):
+        self.checkfile(name)
+        f = open(name)
+        f.seek(offset)
+        if length == 0:
+            data = ''
+        elif length < 0:
+            data = f.read()
+        else:
+            data = f.read(length)
+        f.close()
+        return data
+
+    def create(self, name):
+        self.check(name)
+        if os.path.exists(name):
+            self.checkfile(name)
+            bname = name + '~'
+            try:
+                os.unlink(bname)
+            except os.error:
+                pass
+            os.rename(name, bname)
+        f = open(name, 'w')
+        f.close()
+
+    def write(self, name, data, offset = 0):
+        self.checkfile(name)
+        f = open(name, 'r+')
+        f.seek(offset)
+        f.write(data)
+        f.close()
+
+    def mkdir(self, name):
+        self.check(name)
+        os.mkdir(name, 0777)
+
+    def rmdir(self, name):
+        self.check(name)
+        os.rmdir(name)
 
 
 class FSProxyServer(FSProxyLocal, server.Server):
-	
-	def __init__(self, address, verbose = server.VERBOSE):
-		FSProxyLocal.__init__(self)
-		server.Server.__init__(self, address, verbose)
-	
-	def _close(self):
-		server.Server._close(self)
-		FSProxyLocal._close(self)
-	
-	def _serve(self):
-		server.Server._serve(self)
-		# Retreat into start directory
-		while self._dirstack: self.back()
+
+    def __init__(self, address, verbose = server.VERBOSE):
+        FSProxyLocal.__init__(self)
+        server.Server.__init__(self, address, verbose)
+
+    def _close(self):
+        server.Server._close(self)
+        FSProxyLocal._close(self)
+
+    def _serve(self):
+        server.Server._serve(self)
+        # Retreat into start directory
+        while self._dirstack: self.back()
 
 
 class FSProxyClient(client.Client):
-	
-	def __init__(self, address, verbose = client.VERBOSE):
-		client.Client.__init__(self, address, verbose)
+
+    def __init__(self, address, verbose = client.VERBOSE):
+        client.Client.__init__(self, address, verbose)
 
 
 def test():
-	import string
-	import sys
-	if sys.argv[1:]:
-		port = string.atoi(sys.argv[1])
-	else:
-		port = 4127
-	proxy = FSProxyServer(('', port))
-	proxy._serverloop()
+    import string
+    import sys
+    if sys.argv[1:]:
+        port = string.atoi(sys.argv[1])
+    else:
+        port = 4127
+    proxy = FSProxyServer(('', port))
+    proxy._serverloop()
 
 
 if __name__ == '__main__':
-	test()
+    test()
diff --git a/Demo/pdist/client.py b/Demo/pdist/client.py
index a00f005..3e97d84 100755
--- a/Demo/pdist/client.py
+++ b/Demo/pdist/client.py
@@ -12,118 +12,118 @@
 
 
 class Client:
-	
-	"""RPC Client class.  No need to derive a class -- it's fully generic."""
-	
-	def __init__(self, address, verbose = VERBOSE):
-		self._pre_init(address, verbose)
-		self._post_init()
-	
-	def _pre_init(self, address, verbose = VERBOSE):
-		if type(address) == type(0):
-			address = ('', address)
-		self._address = address
-		self._verbose = verbose
-		if self._verbose: print "Connecting to %s ..." % repr(address)
-		self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-		self._socket.connect(address)
-		if self._verbose: print "Connected."
-		self._lastid = 0 # Last id for which a reply has been received
-		self._nextid = 1 # Id of next request
-		self._replies = {} # Unprocessed replies
-		self._rf = self._socket.makefile('r')
-		self._wf = self._socket.makefile('w')
-	
-	def _post_init(self):
-		self._methods = self._call('.methods')
-	
-	def __del__(self):
-		self._close()
-	
-	def _close(self):
-		if self._rf: self._rf.close()
-		self._rf = None
-		if self._wf: self._wf.close()
-		self._wf = None
-		if self._socket: self._socket.close()
-		self._socket = None
-	
-	def __getattr__(self, name):
-		if name in self._methods:
-			method = _stub(self, name)
-			setattr(self, name, method) # XXX circular reference
-			return method
-		raise AttributeError, name
-	
-	def _setverbose(self, verbose):
-		self._verbose = verbose
-	
-	def _call(self, name, *args):
-		return self._vcall(name, args)
-	
-	def _vcall(self, name, args):
-		return self._recv(self._vsend(name, args))
-	
-	def _send(self, name, *args):
-		return self._vsend(name, args)
-	
-	def _send_noreply(self, name, *args):
-		return self._vsend(name, args, 0)
-	
-	def _vsend_noreply(self, name, args):
-		return self._vsend(name, args, 0)
-	
-	def _vsend(self, name, args, wantreply = 1):
-		id = self._nextid
-		self._nextid = id+1
-		if not wantreply: id = -id
-		request = (name, args, id)
-		if self._verbose > 1: print "sending request: %s" % repr(request)
-		wp = pickle.Pickler(self._wf)
-		wp.dump(request)
-		return id
-	
-	def _recv(self, id):
-		exception, value, rid = self._vrecv(id)
-		if rid != id:
-			raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid)
-		if exception is None:
-			return value
-		x = exception
-		if hasattr(__builtin__, exception):
-			x = getattr(__builtin__, exception)
-		elif exception in ('posix.error', 'mac.error'):
-			x = os.error
-		if x == exception:
-			exception = x
-		raise exception, value		
-	
-	def _vrecv(self, id):
-		self._flush()
-		if self._replies.has_key(id):
-			if self._verbose > 1: print "retrieving previous reply, id = %d" % id
-			reply = self._replies[id]
-			del self._replies[id]
-			return reply
-		aid = abs(id)
-		while 1:
-			if self._verbose > 1: print "waiting for reply, id = %d" % id
-			rp = pickle.Unpickler(self._rf)
-			reply = rp.load()
-			del rp
-			if self._verbose > 1: print "got reply: %s" % repr(reply)
-			rid = reply[2]
-			arid = abs(rid)
-			if arid == aid:
-				if self._verbose > 1: print "got it"
-				return reply
-			self._replies[rid] = reply
-			if arid > aid:
-				if self._verbose > 1: print "got higher id, assume all ok"
-				return (None, None, id)
-	
-	def _flush(self):
-		self._wf.flush()
+
+    """RPC Client class.  No need to derive a class -- it's fully generic."""
+
+    def __init__(self, address, verbose = VERBOSE):
+        self._pre_init(address, verbose)
+        self._post_init()
+
+    def _pre_init(self, address, verbose = VERBOSE):
+        if type(address) == type(0):
+            address = ('', address)
+        self._address = address
+        self._verbose = verbose
+        if self._verbose: print "Connecting to %s ..." % repr(address)
+        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._socket.connect(address)
+        if self._verbose: print "Connected."
+        self._lastid = 0 # Last id for which a reply has been received
+        self._nextid = 1 # Id of next request
+        self._replies = {} # Unprocessed replies
+        self._rf = self._socket.makefile('r')
+        self._wf = self._socket.makefile('w')
+
+    def _post_init(self):
+        self._methods = self._call('.methods')
+
+    def __del__(self):
+        self._close()
+
+    def _close(self):
+        if self._rf: self._rf.close()
+        self._rf = None
+        if self._wf: self._wf.close()
+        self._wf = None
+        if self._socket: self._socket.close()
+        self._socket = None
+
+    def __getattr__(self, name):
+        if name in self._methods:
+            method = _stub(self, name)
+            setattr(self, name, method) # XXX circular reference
+            return method
+        raise AttributeError, name
+
+    def _setverbose(self, verbose):
+        self._verbose = verbose
+
+    def _call(self, name, *args):
+        return self._vcall(name, args)
+
+    def _vcall(self, name, args):
+        return self._recv(self._vsend(name, args))
+
+    def _send(self, name, *args):
+        return self._vsend(name, args)
+
+    def _send_noreply(self, name, *args):
+        return self._vsend(name, args, 0)
+
+    def _vsend_noreply(self, name, args):
+        return self._vsend(name, args, 0)
+
+    def _vsend(self, name, args, wantreply = 1):
+        id = self._nextid
+        self._nextid = id+1
+        if not wantreply: id = -id
+        request = (name, args, id)
+        if self._verbose > 1: print "sending request: %s" % repr(request)
+        wp = pickle.Pickler(self._wf)
+        wp.dump(request)
+        return id
+
+    def _recv(self, id):
+        exception, value, rid = self._vrecv(id)
+        if rid != id:
+            raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid)
+        if exception is None:
+            return value
+        x = exception
+        if hasattr(__builtin__, exception):
+            x = getattr(__builtin__, exception)
+        elif exception in ('posix.error', 'mac.error'):
+            x = os.error
+        if x == exception:
+            exception = x
+        raise exception, value
+
+    def _vrecv(self, id):
+        self._flush()
+        if self._replies.has_key(id):
+            if self._verbose > 1: print "retrieving previous reply, id = %d" % id
+            reply = self._replies[id]
+            del self._replies[id]
+            return reply
+        aid = abs(id)
+        while 1:
+            if self._verbose > 1: print "waiting for reply, id = %d" % id
+            rp = pickle.Unpickler(self._rf)
+            reply = rp.load()
+            del rp
+            if self._verbose > 1: print "got reply: %s" % repr(reply)
+            rid = reply[2]
+            arid = abs(rid)
+            if arid == aid:
+                if self._verbose > 1: print "got it"
+                return reply
+            self._replies[rid] = reply
+            if arid > aid:
+                if self._verbose > 1: print "got higher id, assume all ok"
+                return (None, None, id)
+
+    def _flush(self):
+        self._wf.flush()
 
 
 from security import Security
@@ -131,28 +131,27 @@
 
 class SecureClient(Client, Security):
 
-	def __init__(self, *args):
-		import string
-		apply(self._pre_init, args)
-		Security.__init__(self)
-		self._wf.flush()
-		line = self._rf.readline()
-		challenge = string.atoi(string.strip(line))
-		response = self._encode_challenge(challenge)
-		line = repr(long(response))
-		if line[-1] in 'Ll': line = line[:-1]
-		self._wf.write(line + '\n')
-		self._wf.flush()
-		self._post_init()
+    def __init__(self, *args):
+        import string
+        apply(self._pre_init, args)
+        Security.__init__(self)
+        self._wf.flush()
+        line = self._rf.readline()
+        challenge = string.atoi(string.strip(line))
+        response = self._encode_challenge(challenge)
+        line = repr(long(response))
+        if line[-1] in 'Ll': line = line[:-1]
+        self._wf.write(line + '\n')
+        self._wf.flush()
+        self._post_init()
 
 class _stub:
-	
-	"""Helper class for Client -- each instance serves as a method of the client."""
-	
-	def __init__(self, client, name):
-		self._client = client
-		self._name = name
-	
-	def __call__(self, *args):
-		return self._client._vcall(self._name, args)
 
+    """Helper class for Client -- each instance serves as a method of the client."""
+
+    def __init__(self, client, name):
+        self._client = client
+        self._name = name
+
+    def __call__(self, *args):
+        return self._client._vcall(self._name, args)
diff --git a/Demo/pdist/cmdfw.py b/Demo/pdist/cmdfw.py
index 25584b7..e2edd0a 100755
--- a/Demo/pdist/cmdfw.py
+++ b/Demo/pdist/cmdfw.py
@@ -3,142 +3,142 @@
 
 class CommandFrameWork:
 
-	"""Framework class for command line interfaces like CVS.
+    """Framework class for command line interfaces like CVS.
 
-	The general command line structure is
+    The general command line structure is
 
-		command [flags] subcommand [subflags] [argument] ...
+            command [flags] subcommand [subflags] [argument] ...
 
-	There's a class variable GlobalFlags which specifies the
-	global flags options.  Subcommands are defined by defining
-	methods named do_<subcommand>.  Flags for the subcommand are
-	defined by defining class or instance variables named
-	flags_<subcommand>.  If there's no command, method default()
-	is called.  The __doc__ strings for the do_ methods are used
-	for the usage message, printed after the general usage message
-	which is the class variable UsageMessage.  The class variable
-	PostUsageMessage is printed after all the do_ methods' __doc__
-	strings.  The method's return value can be a suggested exit
-	status.  [XXX Need to rewrite this to clarify it.]
+    There's a class variable GlobalFlags which specifies the
+    global flags options.  Subcommands are defined by defining
+    methods named do_<subcommand>.  Flags for the subcommand are
+    defined by defining class or instance variables named
+    flags_<subcommand>.  If there's no command, method default()
+    is called.  The __doc__ strings for the do_ methods are used
+    for the usage message, printed after the general usage message
+    which is the class variable UsageMessage.  The class variable
+    PostUsageMessage is printed after all the do_ methods' __doc__
+    strings.  The method's return value can be a suggested exit
+    status.  [XXX Need to rewrite this to clarify it.]
 
-	Common usage is to derive a class, instantiate it, and then call its
-	run() method; by default this takes its arguments from sys.argv[1:].
-	"""
+    Common usage is to derive a class, instantiate it, and then call its
+    run() method; by default this takes its arguments from sys.argv[1:].
+    """
 
-	UsageMessage = \
-	  "usage: (name)s [flags] subcommand [subflags] [argument] ..."
+    UsageMessage = \
+      "usage: (name)s [flags] subcommand [subflags] [argument] ..."
 
-	PostUsageMessage = None
+    PostUsageMessage = None
 
-	GlobalFlags = ''
+    GlobalFlags = ''
 
-	def __init__(self):
-		"""Constructor, present for completeness."""
-		pass
+    def __init__(self):
+        """Constructor, present for completeness."""
+        pass
 
-	def run(self, args = None):
-		"""Process flags, subcommand and options, then run it."""
-		import getopt, sys
-		if args is None: args = sys.argv[1:]
-		try:
-			opts, args = getopt.getopt(args, self.GlobalFlags)
-		except getopt.error, msg:
-			return self.usage(msg)
-		self.options(opts)
-		if not args:
-			self.ready()
-			return self.default()
-		else:
-			cmd = args[0]
-			mname = 'do_' + cmd
-			fname = 'flags_' + cmd
-			try:
-				method = getattr(self, mname)
-			except AttributeError:
-				return self.usage("command %r unknown" % (cmd,))
-			try:
-				flags = getattr(self, fname)
-			except AttributeError:
-				flags = ''
-			try:
-				opts, args = getopt.getopt(args[1:], flags)
-			except getopt.error, msg:
-				return self.usage(
-					"subcommand %s: " % cmd + str(msg))
-			self.ready()
-			return method(opts, args)
+    def run(self, args = None):
+        """Process flags, subcommand and options, then run it."""
+        import getopt, sys
+        if args is None: args = sys.argv[1:]
+        try:
+            opts, args = getopt.getopt(args, self.GlobalFlags)
+        except getopt.error, msg:
+            return self.usage(msg)
+        self.options(opts)
+        if not args:
+            self.ready()
+            return self.default()
+        else:
+            cmd = args[0]
+            mname = 'do_' + cmd
+            fname = 'flags_' + cmd
+            try:
+                method = getattr(self, mname)
+            except AttributeError:
+                return self.usage("command %r unknown" % (cmd,))
+            try:
+                flags = getattr(self, fname)
+            except AttributeError:
+                flags = ''
+            try:
+                opts, args = getopt.getopt(args[1:], flags)
+            except getopt.error, msg:
+                return self.usage(
+                        "subcommand %s: " % cmd + str(msg))
+            self.ready()
+            return method(opts, args)
 
-	def options(self, opts):
-		"""Process the options retrieved by getopt.
-		Override this if you have any options."""
-		if opts:
-			print "-"*40
-			print "Options:"
-			for o, a in opts:
-				print 'option', o, 'value', repr(a)
-			print "-"*40
+    def options(self, opts):
+        """Process the options retrieved by getopt.
+        Override this if you have any options."""
+        if opts:
+            print "-"*40
+            print "Options:"
+            for o, a in opts:
+                print 'option', o, 'value', repr(a)
+            print "-"*40
 
-	def ready(self):
-		"""Called just before calling the subcommand."""
-		pass
+    def ready(self):
+        """Called just before calling the subcommand."""
+        pass
 
-	def usage(self, msg = None):
-		"""Print usage message.  Return suitable exit code (2)."""
-		if msg: print msg
-		print self.UsageMessage % {'name': self.__class__.__name__}
-		docstrings = {}
-		c = self.__class__
-		while 1:
-			for name in dir(c):
-				if name[:3] == 'do_':
-					if docstrings.has_key(name):
-						continue
-					try:
-						doc = getattr(c, name).__doc__
-					except:
-						doc = None
-					if doc:
-						docstrings[name] = doc
-			if not c.__bases__:
-				break
-			c = c.__bases__[0]
-		if docstrings:
-			print "where subcommand can be:"
-			names = docstrings.keys()
-			names.sort()
-			for name in names:
-				print docstrings[name]
-		if self.PostUsageMessage:
-			print self.PostUsageMessage
-		return 2
+    def usage(self, msg = None):
+        """Print usage message.  Return suitable exit code (2)."""
+        if msg: print msg
+        print self.UsageMessage % {'name': self.__class__.__name__}
+        docstrings = {}
+        c = self.__class__
+        while 1:
+            for name in dir(c):
+                if name[:3] == 'do_':
+                    if docstrings.has_key(name):
+                        continue
+                    try:
+                        doc = getattr(c, name).__doc__
+                    except:
+                        doc = None
+                    if doc:
+                        docstrings[name] = doc
+            if not c.__bases__:
+                break
+            c = c.__bases__[0]
+        if docstrings:
+            print "where subcommand can be:"
+            names = docstrings.keys()
+            names.sort()
+            for name in names:
+                print docstrings[name]
+        if self.PostUsageMessage:
+            print self.PostUsageMessage
+        return 2
 
-	def default(self):
-		"""Default method, called when no subcommand is given.
-		You should always override this."""
-		print "Nobody expects the Spanish Inquisition!"
+    def default(self):
+        """Default method, called when no subcommand is given.
+        You should always override this."""
+        print "Nobody expects the Spanish Inquisition!"
 
 
 def test():
-	"""Test script -- called when this module is run as a script."""
-	import sys
-	class Hello(CommandFrameWork):
-		def do_hello(self, opts, args):
-			"hello -- print 'hello world', needs no arguments"
-			print "Hello, world"
-	x = Hello()
-	tests = [
-		[],
-		['hello'],
-		['spam'],
-		['-x'],
-		['hello', '-x'],
-		None,
-		]
-	for t in tests:
-		print '-'*10, t, '-'*10
-		sts = x.run(t)
-		print "Exit status:", repr(sts)
+    """Test script -- called when this module is run as a script."""
+    import sys
+    class Hello(CommandFrameWork):
+        def do_hello(self, opts, args):
+            "hello -- print 'hello world', needs no arguments"
+            print "Hello, world"
+    x = Hello()
+    tests = [
+            [],
+            ['hello'],
+            ['spam'],
+            ['-x'],
+            ['hello', '-x'],
+            None,
+            ]
+    for t in tests:
+        print '-'*10, t, '-'*10
+        sts = x.run(t)
+        print "Exit status:", repr(sts)
 
 
 if __name__ == '__main__':
-	test()
+    test()
diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py
index 8a34f3f..f6c611f 100755
--- a/Demo/pdist/cmptree.py
+++ b/Demo/pdist/cmptree.py
@@ -7,202 +7,202 @@
 import os
 
 def main():
-	pwd = os.getcwd()
-	s = raw_input("chdir [%s] " % pwd)
-	if s:
-		os.chdir(s)
-		pwd = os.getcwd()
-	host = ask("host", 'voorn.cwi.nl')
-	port = 4127
-	verbose = 1
-	mode = ''
-	print """\
+    pwd = os.getcwd()
+    s = raw_input("chdir [%s] " % pwd)
+    if s:
+        os.chdir(s)
+        pwd = os.getcwd()
+    host = ask("host", 'voorn.cwi.nl')
+    port = 4127
+    verbose = 1
+    mode = ''
+    print """\
 Mode should be a string of characters, indicating what to do with differences.
 r - read different files to local file system
 w - write different files to remote file system
 c - create new files, either remote or local
 d - delete disappearing files, either remote or local
 """
-	s = raw_input("mode [%s] " % mode)
-	if s: mode = s
-	address = (host, port)
-	t1 = time.time()
-	local = FSProxy.FSProxyLocal()
-	remote = FSProxy.FSProxyClient(address, verbose)
-	compare(local, remote, mode)
-	remote._close()
-	local._close()
-	t2 = time.time()
-	dt = t2-t1
-	mins, secs = divmod(dt, 60)
-	print mins, "minutes and", round(secs), "seconds"
-	raw_input("[Return to exit] ")
+    s = raw_input("mode [%s] " % mode)
+    if s: mode = s
+    address = (host, port)
+    t1 = time.time()
+    local = FSProxy.FSProxyLocal()
+    remote = FSProxy.FSProxyClient(address, verbose)
+    compare(local, remote, mode)
+    remote._close()
+    local._close()
+    t2 = time.time()
+    dt = t2-t1
+    mins, secs = divmod(dt, 60)
+    print mins, "minutes and", round(secs), "seconds"
+    raw_input("[Return to exit] ")
 
 def ask(prompt, default):
-	s = raw_input("%s [%s] " % (prompt, default))
-	return s or default
+    s = raw_input("%s [%s] " % (prompt, default))
+    return s or default
 
 def askint(prompt, default):
-	s = raw_input("%s [%s] " % (prompt, str(default)))
-	if s: return string.atoi(s)
-	return default
+    s = raw_input("%s [%s] " % (prompt, str(default)))
+    if s: return string.atoi(s)
+    return default
 
 def compare(local, remote, mode):
-	print
-	print "PWD =", repr(os.getcwd())
-	sums_id = remote._send('sumlist')
-	subdirs_id = remote._send('listsubdirs')
-	remote._flush()
-	print "calculating local sums ..."
-	lsumdict = {}
-	for name, info in local.sumlist():
-		lsumdict[name] = info
-	print "getting remote sums ..."
-	sums = remote._recv(sums_id)
-	print "got", len(sums)
-	rsumdict = {}
-	for name, rsum in sums:
-		rsumdict[name] = rsum
-		if not lsumdict.has_key(name):
-			print repr(name), "only remote"
-			if 'r' in mode and 'c' in mode:
-				recvfile(local, remote, name)
-		else:
-			lsum = lsumdict[name]
-			if lsum != rsum:
-				print repr(name),
-				rmtime = remote.mtime(name)
-				lmtime = local.mtime(name)
-				if rmtime > lmtime:
-					print "remote newer",
-					if 'r' in mode:
-						recvfile(local, remote, name)
-				elif lmtime > rmtime:
-					print "local newer",
-					if 'w' in mode:
-						sendfile(local, remote, name)
-				else:
-					print "same mtime but different sum?!?!",
-				print
-	for name in lsumdict.keys():
-		if not rsumdict.keys():
-			print repr(name), "only locally",
-			fl()
-			if 'w' in mode and 'c' in mode:
-				sendfile(local, remote, name)
-			elif 'r' in mode and 'd' in mode:
-				os.unlink(name)
-				print "removed."
-			print
-	print "gettin subdirs ..."
-	subdirs = remote._recv(subdirs_id)
-	common = []
-	for name in subdirs:
-		if local.isdir(name):
-			print "Common subdirectory", repr(name)
-			common.append(name)
-		else:
-			print "Remote subdirectory", repr(name), "not found locally"
-			if 'r' in mode and 'c' in mode:
-				pr = "Create local subdirectory %s? [y] " % \
-				     repr(name)
-				if 'y' in mode:
-					ok = 'y'
-				else:
-					ok = ask(pr, "y")
-				if ok[:1] in ('y', 'Y'):
-					local.mkdir(name)
-					print "Subdirectory %s made" % \
-						repr(name)
-					common.append(name)
-	lsubdirs = local.listsubdirs()
-	for name in lsubdirs:
-		if name not in subdirs:
-			print "Local subdirectory", repr(name), "not found remotely"
-	for name in common:
-		print "Entering subdirectory", repr(name)
-		local.cd(name)
-		remote.cd(name)
-		compare(local, remote, mode)
-		remote.back()
-		local.back()
+    print
+    print "PWD =", repr(os.getcwd())
+    sums_id = remote._send('sumlist')
+    subdirs_id = remote._send('listsubdirs')
+    remote._flush()
+    print "calculating local sums ..."
+    lsumdict = {}
+    for name, info in local.sumlist():
+        lsumdict[name] = info
+    print "getting remote sums ..."
+    sums = remote._recv(sums_id)
+    print "got", len(sums)
+    rsumdict = {}
+    for name, rsum in sums:
+        rsumdict[name] = rsum
+        if not lsumdict.has_key(name):
+            print repr(name), "only remote"
+            if 'r' in mode and 'c' in mode:
+                recvfile(local, remote, name)
+        else:
+            lsum = lsumdict[name]
+            if lsum != rsum:
+                print repr(name),
+                rmtime = remote.mtime(name)
+                lmtime = local.mtime(name)
+                if rmtime > lmtime:
+                    print "remote newer",
+                    if 'r' in mode:
+                        recvfile(local, remote, name)
+                elif lmtime > rmtime:
+                    print "local newer",
+                    if 'w' in mode:
+                        sendfile(local, remote, name)
+                else:
+                    print "same mtime but different sum?!?!",
+                print
+    for name in lsumdict.keys():
+        if not rsumdict.keys():
+            print repr(name), "only locally",
+            fl()
+            if 'w' in mode and 'c' in mode:
+                sendfile(local, remote, name)
+            elif 'r' in mode and 'd' in mode:
+                os.unlink(name)
+                print "removed."
+            print
+    print "gettin subdirs ..."
+    subdirs = remote._recv(subdirs_id)
+    common = []
+    for name in subdirs:
+        if local.isdir(name):
+            print "Common subdirectory", repr(name)
+            common.append(name)
+        else:
+            print "Remote subdirectory", repr(name), "not found locally"
+            if 'r' in mode and 'c' in mode:
+                pr = "Create local subdirectory %s? [y] " % \
+                     repr(name)
+                if 'y' in mode:
+                    ok = 'y'
+                else:
+                    ok = ask(pr, "y")
+                if ok[:1] in ('y', 'Y'):
+                    local.mkdir(name)
+                    print "Subdirectory %s made" % \
+                            repr(name)
+                    common.append(name)
+    lsubdirs = local.listsubdirs()
+    for name in lsubdirs:
+        if name not in subdirs:
+            print "Local subdirectory", repr(name), "not found remotely"
+    for name in common:
+        print "Entering subdirectory", repr(name)
+        local.cd(name)
+        remote.cd(name)
+        compare(local, remote, mode)
+        remote.back()
+        local.back()
 
 def sendfile(local, remote, name):
-	try:
-		remote.create(name)
-	except (IOError, os.error), msg:
-		print "cannot create:", msg
-		return
-	
-	print "sending ...",
-	fl()
-	
-	data = open(name).read()
-	
-	t1 = time.time()
-	
-	remote._send_noreply('write', name, data)
-	remote._flush()
-	
-	t2 = time.time()
-	
-	dt = t2-t1
-	print len(data), "bytes in", round(dt), "seconds",
-	if dt:
-		print "i.e.", round(len(data)/dt), "bytes/sec",
-	print
+    try:
+        remote.create(name)
+    except (IOError, os.error), msg:
+        print "cannot create:", msg
+        return
+
+    print "sending ...",
+    fl()
+
+    data = open(name).read()
+
+    t1 = time.time()
+
+    remote._send_noreply('write', name, data)
+    remote._flush()
+
+    t2 = time.time()
+
+    dt = t2-t1
+    print len(data), "bytes in", round(dt), "seconds",
+    if dt:
+        print "i.e.", round(len(data)/dt), "bytes/sec",
+    print
 
 def recvfile(local, remote, name):
-	ok = 0
-	try:
-		rv = recvfile_real(local, remote, name)
-		ok = 1
-		return rv
-	finally:
-		if not ok:
-			print "*** recvfile of %r failed, deleting" % (name,)
-			local.delete(name)
+    ok = 0
+    try:
+        rv = recvfile_real(local, remote, name)
+        ok = 1
+        return rv
+    finally:
+        if not ok:
+            print "*** recvfile of %r failed, deleting" % (name,)
+            local.delete(name)
 
 def recvfile_real(local, remote, name):
-	try:
-		local.create(name)
-	except (IOError, os.error), msg:
-		print "cannot create:", msg
-		return
-	
-	print "receiving ...",
-	fl()
-	
-	f = open(name, 'w')
-	t1 = time.time()
-	
-	length = 4*1024
-	offset = 0
-	id = remote._send('read', name, offset, length)
-	remote._flush()
-	while 1:
-		newoffset = offset + length
-		newid = remote._send('read', name, newoffset, length)
-		data = remote._recv(id)
-		id = newid
-		if not data: break
-		f.seek(offset)
-		f.write(data)
-		offset = newoffset
-	size = f.tell()
-	
-	t2 = time.time()
-	f.close()
-	
-	dt = t2-t1
-	print size, "bytes in", round(dt), "seconds",
-	if dt:
-		print "i.e.", int(size/dt), "bytes/sec",
-	print
-	remote._recv(id) # ignored
+    try:
+        local.create(name)
+    except (IOError, os.error), msg:
+        print "cannot create:", msg
+        return
+
+    print "receiving ...",
+    fl()
+
+    f = open(name, 'w')
+    t1 = time.time()
+
+    length = 4*1024
+    offset = 0
+    id = remote._send('read', name, offset, length)
+    remote._flush()
+    while 1:
+        newoffset = offset + length
+        newid = remote._send('read', name, newoffset, length)
+        data = remote._recv(id)
+        id = newid
+        if not data: break
+        f.seek(offset)
+        f.write(data)
+        offset = newoffset
+    size = f.tell()
+
+    t2 = time.time()
+    f.close()
+
+    dt = t2-t1
+    print size, "bytes in", round(dt), "seconds",
+    if dt:
+        print "i.e.", int(size/dt), "bytes/sec",
+    print
+    remote._recv(id) # ignored
 
 def fl():
-	sys.stdout.flush()
+    sys.stdout.flush()
 
 if __name__ == '__main__':
-	main()
+    main()
diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py
index 0f689c4..ebcc697 100755
--- a/Demo/pdist/cvslib.py
+++ b/Demo/pdist/cvslib.py
@@ -7,358 +7,358 @@
 import fnmatch
 
 if not hasattr(time, 'timezone'):
-	time.timezone = 0
+    time.timezone = 0
 
 class File:
 
-	"""Represent a file's status.
+    """Represent a file's status.
 
-	Instance variables:
+    Instance variables:
 
-	file -- the filename (no slashes), None if uninitialized
-	lseen -- true if the data for the local file is up to date
-	eseen -- true if the data from the CVS/Entries entry is up to date
-	         (this implies that the entry must be written back)
-	rseen -- true if the data for the remote file is up to date
-	proxy -- RCSProxy instance used to contact the server, or None
+    file -- the filename (no slashes), None if uninitialized
+    lseen -- true if the data for the local file is up to date
+    eseen -- true if the data from the CVS/Entries entry is up to date
+             (this implies that the entry must be written back)
+    rseen -- true if the data for the remote file is up to date
+    proxy -- RCSProxy instance used to contact the server, or None
 
-	Note that lseen and rseen don't necessary mean that a local
-	or remote file *exists* -- they indicate that we've checked it.
-	However, eseen means that this instance corresponds to an
-	entry in the CVS/Entries file.
+    Note that lseen and rseen don't necessary mean that a local
+    or remote file *exists* -- they indicate that we've checked it.
+    However, eseen means that this instance corresponds to an
+    entry in the CVS/Entries file.
 
-	If lseen is true:
-	
-	lsum -- checksum of the local file, None if no local file
-	lctime -- ctime of the local file, None if no local file
-	lmtime -- mtime of the local file, None if no local file
+    If lseen is true:
 
-	If eseen is true:
+    lsum -- checksum of the local file, None if no local file
+    lctime -- ctime of the local file, None if no local file
+    lmtime -- mtime of the local file, None if no local file
 
-	erev -- revision, None if this is a no revision (not '0')
-	enew -- true if this is an uncommitted added file
-	edeleted -- true if this is an uncommitted removed file
-	ectime -- ctime of last local file corresponding to erev
-	emtime -- mtime of last local file corresponding to erev
-	extra -- 5th string from CVS/Entries file
+    If eseen is true:
 
-	If rseen is true:
+    erev -- revision, None if this is a no revision (not '0')
+    enew -- true if this is an uncommitted added file
+    edeleted -- true if this is an uncommitted removed file
+    ectime -- ctime of last local file corresponding to erev
+    emtime -- mtime of last local file corresponding to erev
+    extra -- 5th string from CVS/Entries file
 
-	rrev -- revision of head, None if non-existent
-	rsum -- checksum of that revision, Non if non-existent
+    If rseen is true:
 
-	If eseen and rseen are both true:
-	
-	esum -- checksum of revision erev, None if no revision
+    rrev -- revision of head, None if non-existent
+    rsum -- checksum of that revision, Non if non-existent
 
-	Note
-	"""
+    If eseen and rseen are both true:
 
-	def __init__(self, file = None):
-		if file and '/' in file:
-			raise ValueError, "no slash allowed in file"
-		self.file = file
-		self.lseen = self.eseen = self.rseen = 0
-		self.proxy = None
+    esum -- checksum of revision erev, None if no revision
 
-	def __cmp__(self, other):
-		return cmp(self.file, other.file)
+    Note
+    """
 
-	def getlocal(self):
-		try:
-			self.lmtime, self.lctime = os.stat(self.file)[-2:]
-		except os.error:
-			self.lmtime = self.lctime = self.lsum = None
-		else:
-			self.lsum = md5.new(open(self.file).read()).digest()
-		self.lseen = 1
+    def __init__(self, file = None):
+        if file and '/' in file:
+            raise ValueError, "no slash allowed in file"
+        self.file = file
+        self.lseen = self.eseen = self.rseen = 0
+        self.proxy = None
 
-	def getentry(self, line):
-		words = string.splitfields(line, '/')
-		if self.file and words[1] != self.file:
-			raise ValueError, "file name mismatch"
-		self.file = words[1]
-		self.erev = words[2]
-		self.edeleted = 0
-		self.enew = 0
-		self.ectime = self.emtime = None
-		if self.erev[:1] == '-':
-			self.edeleted = 1
-			self.erev = self.erev[1:]
-		if self.erev == '0':
-			self.erev = None
-			self.enew = 1
-		else:
-			dates = words[3]
-			self.ectime = unctime(dates[:24])
-			self.emtime = unctime(dates[25:])
-		self.extra = words[4]
-		if self.rseen:
-			self.getesum()
-		self.eseen = 1
+    def __cmp__(self, other):
+        return cmp(self.file, other.file)
 
-	def getremote(self, proxy = None):
-		if proxy:
-			self.proxy = proxy
-		try:
-			self.rrev = self.proxy.head(self.file)
-		except (os.error, IOError):
-			self.rrev = None
-		if self.rrev:
-			self.rsum = self.proxy.sum(self.file)
-		else:
-			self.rsum = None
-		if self.eseen:
-			self.getesum()
-		self.rseen = 1
+    def getlocal(self):
+        try:
+            self.lmtime, self.lctime = os.stat(self.file)[-2:]
+        except os.error:
+            self.lmtime = self.lctime = self.lsum = None
+        else:
+            self.lsum = md5.new(open(self.file).read()).digest()
+        self.lseen = 1
 
-	def getesum(self):
-		if self.erev == self.rrev:
-			self.esum = self.rsum
-		elif self.erev:
-			name = (self.file, self.erev)
-			self.esum = self.proxy.sum(name)
-		else:
-			self.esum = None
+    def getentry(self, line):
+        words = string.splitfields(line, '/')
+        if self.file and words[1] != self.file:
+            raise ValueError, "file name mismatch"
+        self.file = words[1]
+        self.erev = words[2]
+        self.edeleted = 0
+        self.enew = 0
+        self.ectime = self.emtime = None
+        if self.erev[:1] == '-':
+            self.edeleted = 1
+            self.erev = self.erev[1:]
+        if self.erev == '0':
+            self.erev = None
+            self.enew = 1
+        else:
+            dates = words[3]
+            self.ectime = unctime(dates[:24])
+            self.emtime = unctime(dates[25:])
+        self.extra = words[4]
+        if self.rseen:
+            self.getesum()
+        self.eseen = 1
 
-	def putentry(self):
-		"""Return a line suitable for inclusion in CVS/Entries.
+    def getremote(self, proxy = None):
+        if proxy:
+            self.proxy = proxy
+        try:
+            self.rrev = self.proxy.head(self.file)
+        except (os.error, IOError):
+            self.rrev = None
+        if self.rrev:
+            self.rsum = self.proxy.sum(self.file)
+        else:
+            self.rsum = None
+        if self.eseen:
+            self.getesum()
+        self.rseen = 1
 
-		The returned line is terminated by a newline.
-		If no entry should be written for this file,
-		return "".
-		"""
-		if not self.eseen:
-			return ""
+    def getesum(self):
+        if self.erev == self.rrev:
+            self.esum = self.rsum
+        elif self.erev:
+            name = (self.file, self.erev)
+            self.esum = self.proxy.sum(name)
+        else:
+            self.esum = None
 
-		rev = self.erev or '0'
-		if self.edeleted:
-			rev = '-' + rev
-		if self.enew:
-			dates = 'Initial ' + self.file
-		else:
-			dates = gmctime(self.ectime) + ' ' + \
-				gmctime(self.emtime)
-		return "/%s/%s/%s/%s/\n" % (
-			self.file,
-			rev,
-			dates,
-			self.extra)
+    def putentry(self):
+        """Return a line suitable for inclusion in CVS/Entries.
 
-	def report(self):
-		print '-'*50
-		def r(key, repr=repr, self=self):
-			try:
-				value = repr(getattr(self, key))
-			except AttributeError:
-				value = "?"
-			print "%-15s:" % key, value
-		r("file")
-		if self.lseen:
-			r("lsum", hexify)
-			r("lctime", gmctime)
-			r("lmtime", gmctime)
-		if self.eseen:
-			r("erev")
-			r("enew")
-			r("edeleted")
-			r("ectime", gmctime)
-			r("emtime", gmctime)
-		if self.rseen:
-			r("rrev")
-			r("rsum", hexify)
-			if self.eseen:
-				r("esum", hexify)
+        The returned line is terminated by a newline.
+        If no entry should be written for this file,
+        return "".
+        """
+        if not self.eseen:
+            return ""
+
+        rev = self.erev or '0'
+        if self.edeleted:
+            rev = '-' + rev
+        if self.enew:
+            dates = 'Initial ' + self.file
+        else:
+            dates = gmctime(self.ectime) + ' ' + \
+                    gmctime(self.emtime)
+        return "/%s/%s/%s/%s/\n" % (
+                self.file,
+                rev,
+                dates,
+                self.extra)
+
+    def report(self):
+        print '-'*50
+        def r(key, repr=repr, self=self):
+            try:
+                value = repr(getattr(self, key))
+            except AttributeError:
+                value = "?"
+            print "%-15s:" % key, value
+        r("file")
+        if self.lseen:
+            r("lsum", hexify)
+            r("lctime", gmctime)
+            r("lmtime", gmctime)
+        if self.eseen:
+            r("erev")
+            r("enew")
+            r("edeleted")
+            r("ectime", gmctime)
+            r("emtime", gmctime)
+        if self.rseen:
+            r("rrev")
+            r("rsum", hexify)
+            if self.eseen:
+                r("esum", hexify)
 
 
 class CVS:
-	
-	"""Represent the contents of a CVS admin file (and more).
 
-	Class variables:
+    """Represent the contents of a CVS admin file (and more).
 
-	FileClass -- the class to be instantiated for entries
-	             (this should be derived from class File above)
-	IgnoreList -- shell patterns for local files to be ignored
+    Class variables:
 
-	Instance variables:
+    FileClass -- the class to be instantiated for entries
+                 (this should be derived from class File above)
+    IgnoreList -- shell patterns for local files to be ignored
 
-	entries -- a dictionary containing File instances keyed by
-	           their file name
-	proxy -- an RCSProxy instance, or None
-	"""
-	
-	FileClass = File
+    Instance variables:
 
-	IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc']
-	
-	def __init__(self):
-		self.entries = {}
-		self.proxy = None
-	
-	def setproxy(self, proxy):
-		if proxy is self.proxy:
-			return
-		self.proxy = proxy
-		for e in self.entries.values():
-			e.rseen = 0
-	
-	def getentries(self):
-		"""Read the contents of CVS/Entries"""
-		self.entries = {}
-		f = self.cvsopen("Entries")
-		while 1:
-			line = f.readline()
-			if not line: break
-			e = self.FileClass()
-			e.getentry(line)
-			self.entries[e.file] = e
-		f.close()
-	
-	def putentries(self):
-		"""Write CVS/Entries back"""
-		f = self.cvsopen("Entries", 'w')
-		for e in self.values():
-			f.write(e.putentry())
-		f.close()
+    entries -- a dictionary containing File instances keyed by
+               their file name
+    proxy -- an RCSProxy instance, or None
+    """
 
-	def getlocalfiles(self):
-		list = self.entries.keys()
-		addlist = os.listdir(os.curdir)
-		for name in addlist:
-			if name in list:
-				continue
-			if not self.ignored(name):
-				list.append(name)
-		list.sort()
-		for file in list:
-			try:
-				e = self.entries[file]
-			except KeyError:
-				e = self.entries[file] = self.FileClass(file)
-			e.getlocal()
+    FileClass = File
 
-	def getremotefiles(self, proxy = None):
-		if proxy:
-			self.proxy = proxy
-		if not self.proxy:
-			raise RuntimeError, "no RCS proxy"
-		addlist = self.proxy.listfiles()
-		for file in addlist:
-			try:
-				e = self.entries[file]
-			except KeyError:
-				e = self.entries[file] = self.FileClass(file)
-			e.getremote(self.proxy)
+    IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc']
 
-	def report(self):
-		for e in self.values():
-			e.report()
-		print '-'*50
-	
-	def keys(self):
-		keys = self.entries.keys()
-		keys.sort()
-		return keys
+    def __init__(self):
+        self.entries = {}
+        self.proxy = None
 
-	def values(self):
-		def value(key, self=self):
-			return self.entries[key]
-		return map(value, self.keys())
+    def setproxy(self, proxy):
+        if proxy is self.proxy:
+            return
+        self.proxy = proxy
+        for e in self.entries.values():
+            e.rseen = 0
 
-	def items(self):
-		def item(key, self=self):
-			return (key, self.entries[key])
-		return map(item, self.keys())
+    def getentries(self):
+        """Read the contents of CVS/Entries"""
+        self.entries = {}
+        f = self.cvsopen("Entries")
+        while 1:
+            line = f.readline()
+            if not line: break
+            e = self.FileClass()
+            e.getentry(line)
+            self.entries[e.file] = e
+        f.close()
 
-	def cvsexists(self, file):
-		file = os.path.join("CVS", file)
-		return os.path.exists(file)
-	
-	def cvsopen(self, file, mode = 'r'):
-		file = os.path.join("CVS", file)
-		if 'r' not in mode:
-			self.backup(file)
-		return open(file, mode)
-	
-	def backup(self, file):
-		if os.path.isfile(file):
-			bfile = file + '~'
-			try: os.unlink(bfile)
-			except os.error: pass
-			os.rename(file, bfile)
+    def putentries(self):
+        """Write CVS/Entries back"""
+        f = self.cvsopen("Entries", 'w')
+        for e in self.values():
+            f.write(e.putentry())
+        f.close()
 
-	def ignored(self, file):
-		if os.path.isdir(file): return True
-		for pat in self.IgnoreList:
-			if fnmatch.fnmatch(file, pat): return True
-		return False
+    def getlocalfiles(self):
+        list = self.entries.keys()
+        addlist = os.listdir(os.curdir)
+        for name in addlist:
+            if name in list:
+                continue
+            if not self.ignored(name):
+                list.append(name)
+        list.sort()
+        for file in list:
+            try:
+                e = self.entries[file]
+            except KeyError:
+                e = self.entries[file] = self.FileClass(file)
+            e.getlocal()
+
+    def getremotefiles(self, proxy = None):
+        if proxy:
+            self.proxy = proxy
+        if not self.proxy:
+            raise RuntimeError, "no RCS proxy"
+        addlist = self.proxy.listfiles()
+        for file in addlist:
+            try:
+                e = self.entries[file]
+            except KeyError:
+                e = self.entries[file] = self.FileClass(file)
+            e.getremote(self.proxy)
+
+    def report(self):
+        for e in self.values():
+            e.report()
+        print '-'*50
+
+    def keys(self):
+        keys = self.entries.keys()
+        keys.sort()
+        return keys
+
+    def values(self):
+        def value(key, self=self):
+            return self.entries[key]
+        return map(value, self.keys())
+
+    def items(self):
+        def item(key, self=self):
+            return (key, self.entries[key])
+        return map(item, self.keys())
+
+    def cvsexists(self, file):
+        file = os.path.join("CVS", file)
+        return os.path.exists(file)
+
+    def cvsopen(self, file, mode = 'r'):
+        file = os.path.join("CVS", file)
+        if 'r' not in mode:
+            self.backup(file)
+        return open(file, mode)
+
+    def backup(self, file):
+        if os.path.isfile(file):
+            bfile = file + '~'
+            try: os.unlink(bfile)
+            except os.error: pass
+            os.rename(file, bfile)
+
+    def ignored(self, file):
+        if os.path.isdir(file): return True
+        for pat in self.IgnoreList:
+            if fnmatch.fnmatch(file, pat): return True
+        return False
 
 
 # hexify and unhexify are useful to print MD5 checksums in hex format
 
 hexify_format = '%02x' * 16
 def hexify(sum):
-	"Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
-	if sum is None:
-		return "None"
-	return hexify_format % tuple(map(ord, sum))
+    "Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
+    if sum is None:
+        return "None"
+    return hexify_format % tuple(map(ord, sum))
 
 def unhexify(hexsum):
-	"Return the original from a hexified string"
-	if hexsum == "None":
-		return None
-	sum = ''
-	for i in range(0, len(hexsum), 2):
-		sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
-	return sum
+    "Return the original from a hexified string"
+    if hexsum == "None":
+        return None
+    sum = ''
+    for i in range(0, len(hexsum), 2):
+        sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
+    return sum
 
 
 unctime_monthmap = {}
 def unctime(date):
-	if date == "None": return None
-	if not unctime_monthmap:
-		months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-			  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-		i = 0
-		for m in months:
-			i = i+1
-			unctime_monthmap[m] = i
-	words = string.split(date) # Day Mon DD HH:MM:SS YEAR
-	year = string.atoi(words[4])
-	month = unctime_monthmap[words[1]]
-	day = string.atoi(words[2])
-	[hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
-	ss = ss - time.timezone
-	return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
+    if date == "None": return None
+    if not unctime_monthmap:
+        months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+        i = 0
+        for m in months:
+            i = i+1
+            unctime_monthmap[m] = i
+    words = string.split(date) # Day Mon DD HH:MM:SS YEAR
+    year = string.atoi(words[4])
+    month = unctime_monthmap[words[1]]
+    day = string.atoi(words[2])
+    [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
+    ss = ss - time.timezone
+    return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
 
 def gmctime(t):
-	if t is None: return "None"
-	return time.asctime(time.gmtime(t))
+    if t is None: return "None"
+    return time.asctime(time.gmtime(t))
 
 def test_unctime():
-	now = int(time.time())
-	t = time.gmtime(now)
-	at = time.asctime(t)
-	print 'GMT', now, at
-	print 'timezone', time.timezone
-	print 'local', time.ctime(now)
-	u = unctime(at)
-	print 'unctime()', u
-	gu = time.gmtime(u)
-	print '->', gu
-	print time.asctime(gu)
+    now = int(time.time())
+    t = time.gmtime(now)
+    at = time.asctime(t)
+    print 'GMT', now, at
+    print 'timezone', time.timezone
+    print 'local', time.ctime(now)
+    u = unctime(at)
+    print 'unctime()', u
+    gu = time.gmtime(u)
+    print '->', gu
+    print time.asctime(gu)
 
 def test():
-	x = CVS()
-	x.getentries()
-	x.getlocalfiles()
-##	x.report()
-	import rcsclient
-	proxy = rcsclient.openrcsclient()
-	x.getremotefiles(proxy)
-	x.report()
+    x = CVS()
+    x.getentries()
+    x.getlocalfiles()
+##      x.report()
+    import rcsclient
+    proxy = rcsclient.openrcsclient()
+    x.getremotefiles(proxy)
+    x.report()
 
 
 if __name__ == "__main__":
-	test()
+    test()
diff --git a/Demo/pdist/cvslock.py b/Demo/pdist/cvslock.py
index 75f866e..8f6d008 100755
--- a/Demo/pdist/cvslock.py
+++ b/Demo/pdist/cvslock.py
@@ -22,25 +22,25 @@
 
 - To set a read lock:
 
-	- acquire the meta-lock
-	- create the file "#cvs.rfl.<pid>"
-	- release the meta-lock
+        - acquire the meta-lock
+        - create the file "#cvs.rfl.<pid>"
+        - release the meta-lock
 
 - To set a write lock:
 
-	- acquire the meta-lock
-	- check that there are no files called "#cvs.rfl.*"
-		- if there are, release the meta-lock, sleep, try again
-	- create the file "#cvs.wfl.<pid>"
+        - acquire the meta-lock
+        - check that there are no files called "#cvs.rfl.*"
+                - if there are, release the meta-lock, sleep, try again
+        - create the file "#cvs.wfl.<pid>"
 
 - To release a write lock:
 
-	- remove the file "#cvs.wfl.<pid>"
-	- rmdir the meta-lock
+        - remove the file "#cvs.wfl.<pid>"
+        - rmdir the meta-lock
 
 - To release a read lock:
 
-	- remove the file "#cvs.rfl.<pid>"
+        - remove the file "#cvs.rfl.<pid>"
 
 
 Additional notes
@@ -93,188 +93,188 @@
 
 class Error:
 
-	def __init__(self, msg):
-		self.msg = msg
+    def __init__(self, msg):
+        self.msg = msg
 
-	def __repr__(self):
-		return repr(self.msg)
+    def __repr__(self):
+        return repr(self.msg)
 
-	def __str__(self):
-		return str(self.msg)
+    def __str__(self):
+        return str(self.msg)
 
 
 class Locked(Error):
-	pass
+    pass
 
 
 class Lock:
 
-	def __init__(self, repository = ".", delay = DELAY):
-		self.repository = repository
-		self.delay = delay
-		self.lockdir = None
-		self.lockfile = None
-		pid = repr(os.getpid())
-		self.cvslck = self.join(CVSLCK)
-		self.cvsrfl = self.join(CVSRFL + pid)
-		self.cvswfl = self.join(CVSWFL + pid)
+    def __init__(self, repository = ".", delay = DELAY):
+        self.repository = repository
+        self.delay = delay
+        self.lockdir = None
+        self.lockfile = None
+        pid = repr(os.getpid())
+        self.cvslck = self.join(CVSLCK)
+        self.cvsrfl = self.join(CVSRFL + pid)
+        self.cvswfl = self.join(CVSWFL + pid)
 
-	def __del__(self):
-		print "__del__"
-		self.unlock()
+    def __del__(self):
+        print "__del__"
+        self.unlock()
 
-	def setlockdir(self):
-		while 1:
-			try:
-				self.lockdir = self.cvslck
-				os.mkdir(self.cvslck, 0777)
-				return
-			except os.error, msg:
-				self.lockdir = None
-				if msg[0] == EEXIST:
-					try:
-						st = os.stat(self.cvslck)
-					except os.error:
-						continue
-					self.sleep(st)
-					continue
-				raise Error("failed to lock %s: %s" % (
-					self.repository, msg))
+    def setlockdir(self):
+        while 1:
+            try:
+                self.lockdir = self.cvslck
+                os.mkdir(self.cvslck, 0777)
+                return
+            except os.error, msg:
+                self.lockdir = None
+                if msg[0] == EEXIST:
+                    try:
+                        st = os.stat(self.cvslck)
+                    except os.error:
+                        continue
+                    self.sleep(st)
+                    continue
+                raise Error("failed to lock %s: %s" % (
+                        self.repository, msg))
 
-	def unlock(self):
-		self.unlockfile()
-		self.unlockdir()
+    def unlock(self):
+        self.unlockfile()
+        self.unlockdir()
 
-	def unlockfile(self):
-		if self.lockfile:
-			print "unlink", self.lockfile
-			try:
-				os.unlink(self.lockfile)
-			except os.error:
-				pass
-			self.lockfile = None
+    def unlockfile(self):
+        if self.lockfile:
+            print "unlink", self.lockfile
+            try:
+                os.unlink(self.lockfile)
+            except os.error:
+                pass
+            self.lockfile = None
 
-	def unlockdir(self):
-		if self.lockdir:
-			print "rmdir", self.lockdir
-			try:
-				os.rmdir(self.lockdir)
-			except os.error:
-				pass
-			self.lockdir = None
+    def unlockdir(self):
+        if self.lockdir:
+            print "rmdir", self.lockdir
+            try:
+                os.rmdir(self.lockdir)
+            except os.error:
+                pass
+            self.lockdir = None
 
-	def sleep(self, st):
-		sleep(st, self.repository, self.delay)
+    def sleep(self, st):
+        sleep(st, self.repository, self.delay)
 
-	def join(self, name):
-		return os.path.join(self.repository, name)
+    def join(self, name):
+        return os.path.join(self.repository, name)
 
 
 def sleep(st, repository, delay):
-	if delay <= 0:
-		raise Locked(st)
-	uid = st[stat.ST_UID]
-	try:
-		pwent = pwd.getpwuid(uid)
-		user = pwent[0]
-	except KeyError:
-		user = "uid %d" % uid
-	print "[%s]" % time.ctime(time.time())[11:19],
-	print "Waiting for %s's lock in" % user, repository
-	time.sleep(delay)
+    if delay <= 0:
+        raise Locked(st)
+    uid = st[stat.ST_UID]
+    try:
+        pwent = pwd.getpwuid(uid)
+        user = pwent[0]
+    except KeyError:
+        user = "uid %d" % uid
+    print "[%s]" % time.ctime(time.time())[11:19],
+    print "Waiting for %s's lock in" % user, repository
+    time.sleep(delay)
 
 
 class ReadLock(Lock):
 
-	def __init__(self, repository, delay = DELAY):
-		Lock.__init__(self, repository, delay)
-		ok = 0
-		try:
-			self.setlockdir()
-			self.lockfile = self.cvsrfl
-			fp = open(self.lockfile, 'w')
-			fp.close()
-			ok = 1
-		finally:
-			if not ok:
-				self.unlockfile()
-			self.unlockdir()
+    def __init__(self, repository, delay = DELAY):
+        Lock.__init__(self, repository, delay)
+        ok = 0
+        try:
+            self.setlockdir()
+            self.lockfile = self.cvsrfl
+            fp = open(self.lockfile, 'w')
+            fp.close()
+            ok = 1
+        finally:
+            if not ok:
+                self.unlockfile()
+            self.unlockdir()
 
 
 class WriteLock(Lock):
 
-	def __init__(self, repository, delay = DELAY):
-		Lock.__init__(self, repository, delay)
-		self.setlockdir()
-		while 1:
-			uid = self.readers_exist()
-			if not uid:
-				break
-			self.unlockdir()
-			self.sleep(uid)
-		self.lockfile = self.cvswfl
-		fp = open(self.lockfile, 'w')
-		fp.close()
+    def __init__(self, repository, delay = DELAY):
+        Lock.__init__(self, repository, delay)
+        self.setlockdir()
+        while 1:
+            uid = self.readers_exist()
+            if not uid:
+                break
+            self.unlockdir()
+            self.sleep(uid)
+        self.lockfile = self.cvswfl
+        fp = open(self.lockfile, 'w')
+        fp.close()
 
-	def readers_exist(self):
-		n = len(CVSRFL)
-		for name in os.listdir(self.repository):
-			if name[:n] == CVSRFL:
-				try:
-					st = os.stat(self.join(name))
-				except os.error:
-					continue
-				return st
-		return None
+    def readers_exist(self):
+        n = len(CVSRFL)
+        for name in os.listdir(self.repository):
+            if name[:n] == CVSRFL:
+                try:
+                    st = os.stat(self.join(name))
+                except os.error:
+                    continue
+                return st
+        return None
 
 
 def MultipleWriteLock(repositories, delay = DELAY):
-	while 1:
-		locks = []
-		for r in repositories:
-			try:
-				locks.append(WriteLock(r, 0))
-			except Locked, instance:
-				del locks
-				break
-		else:
-			break
-		sleep(instance.msg, r, delay)
-	return list
+    while 1:
+        locks = []
+        for r in repositories:
+            try:
+                locks.append(WriteLock(r, 0))
+            except Locked, instance:
+                del locks
+                break
+        else:
+            break
+        sleep(instance.msg, r, delay)
+    return list
 
 
 def test():
-	import sys
-	if sys.argv[1:]:
-		repository = sys.argv[1]
-	else:
-		repository = "."
-	rl = None
-	wl = None
-	try:
-		print "attempting write lock ..."
-		wl = WriteLock(repository)
-		print "got it."
-		wl.unlock()
-		print "attempting read lock ..."
-		rl = ReadLock(repository)
-		print "got it."
-		rl.unlock()
-	finally:
-		print [1]
-		sys.exc_traceback = None
-		print [2]
-		if rl:
-			rl.unlock()
-		print [3]
-		if wl:
-			wl.unlock()
-		print [4]
-		rl = None
-		print [5]
-		wl = None
-		print [6]
+    import sys
+    if sys.argv[1:]:
+        repository = sys.argv[1]
+    else:
+        repository = "."
+    rl = None
+    wl = None
+    try:
+        print "attempting write lock ..."
+        wl = WriteLock(repository)
+        print "got it."
+        wl.unlock()
+        print "attempting read lock ..."
+        rl = ReadLock(repository)
+        print "got it."
+        rl.unlock()
+    finally:
+        print [1]
+        sys.exc_traceback = None
+        print [2]
+        if rl:
+            rl.unlock()
+        print [3]
+        if wl:
+            wl.unlock()
+        print [4]
+        rl = None
+        print [5]
+        wl = None
+        print [6]
 
 
 if __name__ == '__main__':
-	test()
+    test()
diff --git a/Demo/pdist/mac.py b/Demo/pdist/mac.py
index 516ee15..107113c 100755
--- a/Demo/pdist/mac.py
+++ b/Demo/pdist/mac.py
@@ -3,17 +3,17 @@
 import rcvs
 
 def main():
-	while 1:
-		try:
-			line = raw_input('$ ')
-		except EOFError:
-			break
-		words = string.split(line)
-		if not words:
-			continue
-		if words[0] != 'rcvs':
-			words.insert(0, 'rcvs')
-		sys.argv = words
-		rcvs.main()
+    while 1:
+        try:
+            line = raw_input('$ ')
+        except EOFError:
+            break
+        words = string.split(line)
+        if not words:
+            continue
+        if words[0] != 'rcvs':
+            words.insert(0, 'rcvs')
+        sys.argv = words
+        rcvs.main()
 
 main()
diff --git a/Demo/pdist/rcsclient.py b/Demo/pdist/rcsclient.py
index 5d88a57..d8cb004 100755
--- a/Demo/pdist/rcsclient.py
+++ b/Demo/pdist/rcsclient.py
@@ -21,51 +21,51 @@
 
 
 class RCSProxyClient(client.SecureClient):
-	
-	def __init__(self, address, verbose = client.VERBOSE):
-		client.SecureClient.__init__(self, address, verbose)
+
+    def __init__(self, address, verbose = client.VERBOSE):
+        client.SecureClient.__init__(self, address, verbose)
 
 
 def openrcsclient(opts = []):
-	"open an RCSProxy client based on a list of options returned by getopt"
-	import RCSProxy
-	host = HOST
-	port = PORT
-	verbose = VERBOSE
-	local = LOCAL
-	directory = None
-	for o, a in opts:
-		if o == '-h':
-			host = a
-			if ':' in host:
-				i = string.find(host, ':')
-				host, p = host[:i], host[i+1:]
-				if p:
-					port = string.atoi(p)
-		if o == '-p':
-			port = string.atoi(a)
-		if o == '-d':
-			directory = a
-		if o == '-v':
-			verbose = verbose + 1
-		if o == '-q':
-			verbose = 0
-		if o == '-L':
-			local = 1
-	if local:
-		import RCSProxy
-		x = RCSProxy.RCSProxyLocal()
-	else:
-		address = (host, port)
-		x = RCSProxyClient(address, verbose)
-	if not directory:
-		try:
-			directory = open(os.path.join("CVS", "Repository")).readline()
-		except IOError:
-			pass
-		else:
-			if directory[-1] == '\n':
-				directory = directory[:-1]
-	if directory:
-		x.cd(directory)
-	return x
+    "open an RCSProxy client based on a list of options returned by getopt"
+    import RCSProxy
+    host = HOST
+    port = PORT
+    verbose = VERBOSE
+    local = LOCAL
+    directory = None
+    for o, a in opts:
+        if o == '-h':
+            host = a
+            if ':' in host:
+                i = string.find(host, ':')
+                host, p = host[:i], host[i+1:]
+                if p:
+                    port = string.atoi(p)
+        if o == '-p':
+            port = string.atoi(a)
+        if o == '-d':
+            directory = a
+        if o == '-v':
+            verbose = verbose + 1
+        if o == '-q':
+            verbose = 0
+        if o == '-L':
+            local = 1
+    if local:
+        import RCSProxy
+        x = RCSProxy.RCSProxyLocal()
+    else:
+        address = (host, port)
+        x = RCSProxyClient(address, verbose)
+    if not directory:
+        try:
+            directory = open(os.path.join("CVS", "Repository")).readline()
+        except IOError:
+            pass
+        else:
+            if directory[-1] == '\n':
+                directory = directory[:-1]
+    if directory:
+        x.cd(directory)
+    return x
diff --git a/Demo/pdist/rcslib.py b/Demo/pdist/rcslib.py
index 78de111..d5f7b65 100755
--- a/Demo/pdist/rcslib.py
+++ b/Demo/pdist/rcslib.py
@@ -83,7 +83,7 @@
             if line[0] == '\t':
                 # XXX could be a lock or symbolic name
                 # Anything else?
-                continue 
+                continue
             i = string.find(line, ':')
             if i > 0:
                 key, value = line[:i], string.strip(line[i+1:])
@@ -287,7 +287,7 @@
         if reason&0x80:
             code = code + '(coredump)'
         return code, signal
- 
+
     def _system(self, cmd):
         """INTERNAL: run COMMAND in a subshell.
 
@@ -311,7 +311,7 @@
 
         If a second PATTERN argument is given, only files matching it
         are kept.  No check for valid filenames is made.
-        
+
         """
         if pat:
             def keep(name, pat = pat):
diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py
index 24036c7..8b8bae6 100755
--- a/Demo/pdist/rcvs.py
+++ b/Demo/pdist/rcvs.py
@@ -40,188 +40,188 @@
 from cmdfw import CommandFrameWork
 
 
-DEF_LOCAL = 1				# Default -l
+DEF_LOCAL = 1                           # Default -l
 
 
 class MyFile(File):
 
-	def action(self):
-		"""Return a code indicating the update status of this file.
+    def action(self):
+        """Return a code indicating the update status of this file.
 
-		The possible return values are:
-		
-		'=' -- everything's fine
-		'0' -- file doesn't exist anywhere
-		'?' -- exists locally only
-		'A' -- new locally
-		'R' -- deleted locally
-		'U' -- changed remotely, no changes locally
-		       (includes new remotely or deleted remotely)
-		'M' -- changed locally, no changes remotely
-		'C' -- conflict: changed locally as well as remotely
-		       (includes cases where the file has been added
-		       or removed locally and remotely)
-		'D' -- deleted remotely
-		'N' -- new remotely
-		'r' -- get rid of entry
-		'c' -- create entry
-		'u' -- update entry
+        The possible return values are:
 
-		(and probably others :-)
-		"""
-		if not self.lseen:
-			self.getlocal()
-		if not self.rseen:
-			self.getremote()
-		if not self.eseen:
-			if not self.lsum:
-				if not self.rsum: return '0' # Never heard of
-				else:
-					return 'N' # New remotely
-			else: # self.lsum
-				if not self.rsum: return '?' # Local only
-				# Local and remote, but no entry
-				if self.lsum == self.rsum:
-					return 'c' # Restore entry only
-				else: return 'C' # Real conflict
-		else: # self.eseen
-			if not self.lsum:
-				if self.edeleted:
-					if self.rsum: return 'R' # Removed
-					else: return 'r' # Get rid of entry
-				else: # not self.edeleted
-					if self.rsum:
-						print "warning:",
-						print self.file,
-						print "was lost"
-						return 'U'
-					else: return 'r' # Get rid of entry
-			else: # self.lsum
-				if not self.rsum:
-					if self.enew: return 'A' # New locally
-					else: return 'D' # Deleted remotely
-				else: # self.rsum
-					if self.enew:
-						if self.lsum == self.rsum:
-							return 'u'
-						else:
-							return 'C'
-					if self.lsum == self.esum:
-						if self.esum == self.rsum:
-							return '='
-						else:
-							return 'U'
-					elif self.esum == self.rsum:
-						return 'M'
-					elif self.lsum == self.rsum:
-						return 'u'
-					else:
-						return 'C'
+        '=' -- everything's fine
+        '0' -- file doesn't exist anywhere
+        '?' -- exists locally only
+        'A' -- new locally
+        'R' -- deleted locally
+        'U' -- changed remotely, no changes locally
+               (includes new remotely or deleted remotely)
+        'M' -- changed locally, no changes remotely
+        'C' -- conflict: changed locally as well as remotely
+               (includes cases where the file has been added
+               or removed locally and remotely)
+        'D' -- deleted remotely
+        'N' -- new remotely
+        'r' -- get rid of entry
+        'c' -- create entry
+        'u' -- update entry
 
-	def update(self):
-		code = self.action()
-		if code == '=': return
-		print code, self.file
-		if code in ('U', 'N'):
-			self.get()
-		elif code == 'C':
-			print "%s: conflict resolution not yet implemented" % \
-			      self.file
-		elif code == 'D':
-			remove(self.file)
-			self.eseen = 0
-		elif code == 'r':
-			self.eseen = 0
-		elif code in ('c', 'u'):
-			self.eseen = 1
-			self.erev = self.rrev
-			self.enew = 0
-			self.edeleted = 0
-			self.esum = self.rsum
-			self.emtime, self.ectime = os.stat(self.file)[-2:]
-			self.extra = ''
+        (and probably others :-)
+        """
+        if not self.lseen:
+            self.getlocal()
+        if not self.rseen:
+            self.getremote()
+        if not self.eseen:
+            if not self.lsum:
+                if not self.rsum: return '0' # Never heard of
+                else:
+                    return 'N' # New remotely
+            else: # self.lsum
+                if not self.rsum: return '?' # Local only
+                # Local and remote, but no entry
+                if self.lsum == self.rsum:
+                    return 'c' # Restore entry only
+                else: return 'C' # Real conflict
+        else: # self.eseen
+            if not self.lsum:
+                if self.edeleted:
+                    if self.rsum: return 'R' # Removed
+                    else: return 'r' # Get rid of entry
+                else: # not self.edeleted
+                    if self.rsum:
+                        print "warning:",
+                        print self.file,
+                        print "was lost"
+                        return 'U'
+                    else: return 'r' # Get rid of entry
+            else: # self.lsum
+                if not self.rsum:
+                    if self.enew: return 'A' # New locally
+                    else: return 'D' # Deleted remotely
+                else: # self.rsum
+                    if self.enew:
+                        if self.lsum == self.rsum:
+                            return 'u'
+                        else:
+                            return 'C'
+                    if self.lsum == self.esum:
+                        if self.esum == self.rsum:
+                            return '='
+                        else:
+                            return 'U'
+                    elif self.esum == self.rsum:
+                        return 'M'
+                    elif self.lsum == self.rsum:
+                        return 'u'
+                    else:
+                        return 'C'
 
-	def commit(self, message = ""):
-		code = self.action()
-		if code in ('A', 'M'):
-			self.put(message)
-			return 1
-		elif code == 'R':
-			print "%s: committing removes not yet implemented" % \
-			      self.file
-		elif code == 'C':
-			print "%s: conflict resolution not yet implemented" % \
-			      self.file
+    def update(self):
+        code = self.action()
+        if code == '=': return
+        print code, self.file
+        if code in ('U', 'N'):
+            self.get()
+        elif code == 'C':
+            print "%s: conflict resolution not yet implemented" % \
+                  self.file
+        elif code == 'D':
+            remove(self.file)
+            self.eseen = 0
+        elif code == 'r':
+            self.eseen = 0
+        elif code in ('c', 'u'):
+            self.eseen = 1
+            self.erev = self.rrev
+            self.enew = 0
+            self.edeleted = 0
+            self.esum = self.rsum
+            self.emtime, self.ectime = os.stat(self.file)[-2:]
+            self.extra = ''
 
-	def diff(self, opts = []):
-		self.action()		# To update lseen, rseen
-		flags = ''
-		rev = self.rrev
-		# XXX should support two rev options too!
-		for o, a in opts:
-			if o == '-r':
-				rev = a
-			else:
-				flags = flags + ' ' + o + a
-		if rev == self.rrev and self.lsum == self.rsum:
-			return
-		flags = flags[1:]
-		fn = self.file
-		data = self.proxy.get((fn, rev))
-		sum = md5.new(data).digest()
-		if self.lsum == sum:
-			return
-		import tempfile
-		tf = tempfile.NamedTemporaryFile()
-		tf.write(data)
-		tf.flush()
-		print 'diff %s -r%s %s' % (flags, rev, fn)
-		sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
-		if sts:
-			print '='*70
+    def commit(self, message = ""):
+        code = self.action()
+        if code in ('A', 'M'):
+            self.put(message)
+            return 1
+        elif code == 'R':
+            print "%s: committing removes not yet implemented" % \
+                  self.file
+        elif code == 'C':
+            print "%s: conflict resolution not yet implemented" % \
+                  self.file
 
-	def commitcheck(self):
-		return self.action() != 'C'
+    def diff(self, opts = []):
+        self.action()           # To update lseen, rseen
+        flags = ''
+        rev = self.rrev
+        # XXX should support two rev options too!
+        for o, a in opts:
+            if o == '-r':
+                rev = a
+            else:
+                flags = flags + ' ' + o + a
+        if rev == self.rrev and self.lsum == self.rsum:
+            return
+        flags = flags[1:]
+        fn = self.file
+        data = self.proxy.get((fn, rev))
+        sum = md5.new(data).digest()
+        if self.lsum == sum:
+            return
+        import tempfile
+        tf = tempfile.NamedTemporaryFile()
+        tf.write(data)
+        tf.flush()
+        print 'diff %s -r%s %s' % (flags, rev, fn)
+        sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
+        if sts:
+            print '='*70
 
-	def put(self, message = ""):
-		print "Checking in", self.file, "..."
-		data = open(self.file).read()
-		if not self.enew:
-			self.proxy.lock(self.file)
-		messages = self.proxy.put(self.file, data, message)
-		if messages:
-			print messages
-		self.setentry(self.proxy.head(self.file), self.lsum)
-	
-	def get(self):
-		data = self.proxy.get(self.file)
-		f = open(self.file, 'w')
-		f.write(data)
-		f.close()
-		self.setentry(self.rrev, self.rsum)
+    def commitcheck(self):
+        return self.action() != 'C'
 
-	def log(self, otherflags):
-		print self.proxy.log(self.file, otherflags)
+    def put(self, message = ""):
+        print "Checking in", self.file, "..."
+        data = open(self.file).read()
+        if not self.enew:
+            self.proxy.lock(self.file)
+        messages = self.proxy.put(self.file, data, message)
+        if messages:
+            print messages
+        self.setentry(self.proxy.head(self.file), self.lsum)
 
-	def add(self):
-		self.eseen = 0		# While we're hacking...
-		self.esum = self.lsum
-		self.emtime, self.ectime = 0, 0
-		self.erev = ''
-		self.enew = 1
-		self.edeleted = 0
-		self.eseen = 1		# Done
-		self.extra = ''
+    def get(self):
+        data = self.proxy.get(self.file)
+        f = open(self.file, 'w')
+        f.write(data)
+        f.close()
+        self.setentry(self.rrev, self.rsum)
 
-	def setentry(self, erev, esum):
-		self.eseen = 0		# While we're hacking...
-		self.esum = esum
-		self.emtime, self.ectime = os.stat(self.file)[-2:]
-		self.erev = erev
-		self.enew = 0
-		self.edeleted = 0
-		self.eseen = 1		# Done
-		self.extra = ''
+    def log(self, otherflags):
+        print self.proxy.log(self.file, otherflags)
+
+    def add(self):
+        self.eseen = 0          # While we're hacking...
+        self.esum = self.lsum
+        self.emtime, self.ectime = 0, 0
+        self.erev = ''
+        self.enew = 1
+        self.edeleted = 0
+        self.eseen = 1          # Done
+        self.extra = ''
+
+    def setentry(self, erev, esum):
+        self.eseen = 0          # While we're hacking...
+        self.esum = esum
+        self.emtime, self.ectime = os.stat(self.file)[-2:]
+        self.erev = erev
+        self.enew = 0
+        self.edeleted = 0
+        self.eseen = 1          # Done
+        self.extra = ''
 
 
 SENDMAIL = "/usr/lib/sendmail -t"
@@ -231,247 +231,247 @@
 ...Message from rcvs...
 
 Committed files:
-	%s
+        %s
 
 Log message:
-	%s
+        %s
 """
 
 
 class RCVS(CVS):
 
-	FileClass = MyFile
+    FileClass = MyFile
 
-	def __init__(self):
-		CVS.__init__(self)
+    def __init__(self):
+        CVS.__init__(self)
 
-	def update(self, files):
-		for e in self.whichentries(files, 1):
-			e.update()
+    def update(self, files):
+        for e in self.whichentries(files, 1):
+            e.update()
 
-	def commit(self, files, message = ""):
-		list = self.whichentries(files)
-		if not list: return
-		ok = 1
-		for e in list:
-			if not e.commitcheck():
-				ok = 0
-		if not ok:
-			print "correct above errors first"
-			return
-		if not message:
-			message = raw_input("One-liner: ")
-		committed = []
-		for e in list:
-			if e.commit(message):
-				committed.append(e.file)
-		self.mailinfo(committed, message)
+    def commit(self, files, message = ""):
+        list = self.whichentries(files)
+        if not list: return
+        ok = 1
+        for e in list:
+            if not e.commitcheck():
+                ok = 0
+        if not ok:
+            print "correct above errors first"
+            return
+        if not message:
+            message = raw_input("One-liner: ")
+        committed = []
+        for e in list:
+            if e.commit(message):
+                committed.append(e.file)
+        self.mailinfo(committed, message)
 
-	def mailinfo(self, files, message = ""):
-		towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX
-		mailtext = MAILFORM % (towhom, string.join(files),
-					string.join(files), message)
-		print '-'*70
-		print mailtext
-		print '-'*70
-		ok = raw_input("OK to mail to %s? " % towhom)
-		if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'):
-			p = os.popen(SENDMAIL, "w")
-			p.write(mailtext)
-			sts = p.close()
-			if sts:
-				print "Sendmail exit status %s" % str(sts)
-			else:
-				print "Mail sent."
-		else:
-			print "No mail sent."
+    def mailinfo(self, files, message = ""):
+        towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX
+        mailtext = MAILFORM % (towhom, string.join(files),
+                                string.join(files), message)
+        print '-'*70
+        print mailtext
+        print '-'*70
+        ok = raw_input("OK to mail to %s? " % towhom)
+        if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'):
+            p = os.popen(SENDMAIL, "w")
+            p.write(mailtext)
+            sts = p.close()
+            if sts:
+                print "Sendmail exit status %s" % str(sts)
+            else:
+                print "Mail sent."
+        else:
+            print "No mail sent."
 
-	def report(self, files):
-		for e in self.whichentries(files):
-			e.report()
+    def report(self, files):
+        for e in self.whichentries(files):
+            e.report()
 
-	def diff(self, files, opts):
-		for e in self.whichentries(files):
-			e.diff(opts)
+    def diff(self, files, opts):
+        for e in self.whichentries(files):
+            e.diff(opts)
 
-	def add(self, files):
-		if not files:
-			raise RuntimeError, "'cvs add' needs at least one file"
-		list = []
-		for e in self.whichentries(files, 1):
-			e.add()
+    def add(self, files):
+        if not files:
+            raise RuntimeError, "'cvs add' needs at least one file"
+        list = []
+        for e in self.whichentries(files, 1):
+            e.add()
 
-	def rm(self, files):
-		if not files:
-			raise RuntimeError, "'cvs rm' needs at least one file"
-		raise RuntimeError, "'cvs rm' not yet imlemented"
+    def rm(self, files):
+        if not files:
+            raise RuntimeError, "'cvs rm' needs at least one file"
+        raise RuntimeError, "'cvs rm' not yet imlemented"
 
-	def log(self, files, opts):
-		flags = ''
-		for o, a in opts:
-			flags = flags + ' ' + o + a
-		for e in self.whichentries(files):
-			e.log(flags)
+    def log(self, files, opts):
+        flags = ''
+        for o, a in opts:
+            flags = flags + ' ' + o + a
+        for e in self.whichentries(files):
+            e.log(flags)
 
-	def whichentries(self, files, localfilestoo = 0):
-		if files:
-			list = []
-			for file in files:
-				if self.entries.has_key(file):
-					e = self.entries[file]
-				else:
-					e = self.FileClass(file)
-					self.entries[file] = e
-				list.append(e)
-		else:
-			list = self.entries.values()
-			for file in self.proxy.listfiles():
-				if self.entries.has_key(file):
-					continue
-				e = self.FileClass(file)
-				self.entries[file] = e
-				list.append(e)
-			if localfilestoo:
-				for file in os.listdir(os.curdir):
-					if not self.entries.has_key(file) \
-					   and not self.ignored(file):
-						e = self.FileClass(file)
-						self.entries[file] = e
-						list.append(e)
-			list.sort()
-		if self.proxy:
-			for e in list:
-				if e.proxy is None:
-					e.proxy = self.proxy
-		return list
+    def whichentries(self, files, localfilestoo = 0):
+        if files:
+            list = []
+            for file in files:
+                if self.entries.has_key(file):
+                    e = self.entries[file]
+                else:
+                    e = self.FileClass(file)
+                    self.entries[file] = e
+                list.append(e)
+        else:
+            list = self.entries.values()
+            for file in self.proxy.listfiles():
+                if self.entries.has_key(file):
+                    continue
+                e = self.FileClass(file)
+                self.entries[file] = e
+                list.append(e)
+            if localfilestoo:
+                for file in os.listdir(os.curdir):
+                    if not self.entries.has_key(file) \
+                       and not self.ignored(file):
+                        e = self.FileClass(file)
+                        self.entries[file] = e
+                        list.append(e)
+            list.sort()
+        if self.proxy:
+            for e in list:
+                if e.proxy is None:
+                    e.proxy = self.proxy
+        return list
 
 
 class rcvs(CommandFrameWork):
 
-	GlobalFlags = 'd:h:p:qvL'
-	UsageMessage = \
+    GlobalFlags = 'd:h:p:qvL'
+    UsageMessage = \
 "usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]"
-	PostUsageMessage = \
-		"If no subcommand is given, the status of all files is listed"
+    PostUsageMessage = \
+            "If no subcommand is given, the status of all files is listed"
 
-	def __init__(self):
-		"""Constructor."""
-		CommandFrameWork.__init__(self)
-		self.proxy = None
-		self.cvs = RCVS()
-		
-	def close(self):
-		if self.proxy:
-			self.proxy._close()
-		self.proxy = None
+    def __init__(self):
+        """Constructor."""
+        CommandFrameWork.__init__(self)
+        self.proxy = None
+        self.cvs = RCVS()
 
-	def recurse(self):
-		self.close()
-		names = os.listdir(os.curdir)
-		for name in names:
-			if name == os.curdir or name == os.pardir:
-				continue
-			if name == "CVS":
-				continue
-			if not os.path.isdir(name):
-				continue
-			if os.path.islink(name):
-				continue
-			print "--- entering subdirectory", name, "---"
-			os.chdir(name)
-			try:
-				if os.path.isdir("CVS"):
-					self.__class__().run()
-				else:
-					self.recurse()
-			finally:
-				os.chdir(os.pardir)
-				print "--- left subdirectory", name, "---"
+    def close(self):
+        if self.proxy:
+            self.proxy._close()
+        self.proxy = None
 
-	def options(self, opts):
-		self.opts = opts
+    def recurse(self):
+        self.close()
+        names = os.listdir(os.curdir)
+        for name in names:
+            if name == os.curdir or name == os.pardir:
+                continue
+            if name == "CVS":
+                continue
+            if not os.path.isdir(name):
+                continue
+            if os.path.islink(name):
+                continue
+            print "--- entering subdirectory", name, "---"
+            os.chdir(name)
+            try:
+                if os.path.isdir("CVS"):
+                    self.__class__().run()
+                else:
+                    self.recurse()
+            finally:
+                os.chdir(os.pardir)
+                print "--- left subdirectory", name, "---"
 
-	def ready(self):
-		import rcsclient
-		self.proxy = rcsclient.openrcsclient(self.opts)
-		self.cvs.setproxy(self.proxy)
-		self.cvs.getentries()
+    def options(self, opts):
+        self.opts = opts
 
-	def default(self):
-		self.cvs.report([])
+    def ready(self):
+        import rcsclient
+        self.proxy = rcsclient.openrcsclient(self.opts)
+        self.cvs.setproxy(self.proxy)
+        self.cvs.getentries()
 
-	def do_report(self, opts, files):
-		self.cvs.report(files)
+    def default(self):
+        self.cvs.report([])
 
-	def do_update(self, opts, files):
-		"""update [-l] [-R] [file] ..."""
-		local = DEF_LOCAL
-		for o, a in opts:
-			if o == '-l': local = 1
-			if o == '-R': local = 0
-		self.cvs.update(files)
-		self.cvs.putentries()
-		if not local and not files:
-			self.recurse()
-	flags_update = '-lR'
-	do_up = do_update
-	flags_up = flags_update
+    def do_report(self, opts, files):
+        self.cvs.report(files)
 
-	def do_commit(self, opts, files):
-		"""commit [-m message] [file] ..."""
-		message = ""
-		for o, a in opts:
-			if o == '-m': message = a
-		self.cvs.commit(files, message)
-		self.cvs.putentries()
-	flags_commit = 'm:'
-	do_com = do_commit
-	flags_com = flags_commit
+    def do_update(self, opts, files):
+        """update [-l] [-R] [file] ..."""
+        local = DEF_LOCAL
+        for o, a in opts:
+            if o == '-l': local = 1
+            if o == '-R': local = 0
+        self.cvs.update(files)
+        self.cvs.putentries()
+        if not local and not files:
+            self.recurse()
+    flags_update = '-lR'
+    do_up = do_update
+    flags_up = flags_update
 
-	def do_diff(self, opts, files):
-		"""diff [difflags] [file] ..."""
-		self.cvs.diff(files, opts)
-	flags_diff = 'cbitwcefhnlr:sD:S:'
-	do_dif = do_diff
-	flags_dif = flags_diff
+    def do_commit(self, opts, files):
+        """commit [-m message] [file] ..."""
+        message = ""
+        for o, a in opts:
+            if o == '-m': message = a
+        self.cvs.commit(files, message)
+        self.cvs.putentries()
+    flags_commit = 'm:'
+    do_com = do_commit
+    flags_com = flags_commit
 
-	def do_add(self, opts, files):
-		"""add file ..."""
-		if not files:
-			print "'rcvs add' requires at least one file"
-			return
-		self.cvs.add(files)
-		self.cvs.putentries()
+    def do_diff(self, opts, files):
+        """diff [difflags] [file] ..."""
+        self.cvs.diff(files, opts)
+    flags_diff = 'cbitwcefhnlr:sD:S:'
+    do_dif = do_diff
+    flags_dif = flags_diff
 
-	def do_remove(self, opts, files):
-		"""remove file ..."""
-		if not files:
-			print "'rcvs remove' requires at least one file"
-			return
-		self.cvs.remove(files)
-		self.cvs.putentries()
-	do_rm = do_remove
+    def do_add(self, opts, files):
+        """add file ..."""
+        if not files:
+            print "'rcvs add' requires at least one file"
+            return
+        self.cvs.add(files)
+        self.cvs.putentries()
 
-	def do_log(self, opts, files):
-		"""log [rlog-options] [file] ..."""
-		self.cvs.log(files, opts)
-	flags_log = 'bhLNRtd:s:V:r:'
+    def do_remove(self, opts, files):
+        """remove file ..."""
+        if not files:
+            print "'rcvs remove' requires at least one file"
+            return
+        self.cvs.remove(files)
+        self.cvs.putentries()
+    do_rm = do_remove
+
+    def do_log(self, opts, files):
+        """log [rlog-options] [file] ..."""
+        self.cvs.log(files, opts)
+    flags_log = 'bhLNRtd:s:V:r:'
 
 
 def remove(fn):
-	try:
-		os.unlink(fn)
-	except os.error:
-		pass
+    try:
+        os.unlink(fn)
+    except os.error:
+        pass
 
 
 def main():
-	r = rcvs()
-	try:
-		r.run()
-	finally:
-		r.close()
+    r = rcvs()
+    try:
+        r.run()
+    finally:
+        r.close()
 
 
 if __name__ == "__main__":
-	main()
+    main()
diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py
index a07260c..4d23e6c 100755
--- a/Demo/pdist/rrcs.py
+++ b/Demo/pdist/rrcs.py
@@ -11,150 +11,150 @@
 from rcsclient import openrcsclient
 
 def main():
-	sys.stdout = sys.stderr
-	try:
-		opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL')
-		if not rest:
-			cmd = 'head'
-		else:
-			cmd, rest = rest[0], rest[1:]
-		if not commands.has_key(cmd):
-			raise getopt.error, "unknown command"
-		coptset, func = commands[cmd]
-		copts, files = getopt.getopt(rest, coptset)
-	except getopt.error, msg:
-		print msg
-		print "usage: rrcs [options] command [options] [file] ..."
-		print "where command can be:"
-		print "      ci|put      # checkin the given files"
-		print "      co|get      # checkout"
-		print "      info        # print header info"
-		print "      head        # print revision of head branch"
-		print "      list        # list filename if valid"
-		print "      log         # print full log"
-		print "      diff        # diff rcs file and work file"
-		print "if no files are given, all remote rcs files are assumed"
-		sys.exit(2)
-	x = openrcsclient(opts)
-	if not files:
-		files = x.listfiles()
-	for fn in files:
-		try:
-			func(x, copts, fn)
-		except (IOError, os.error), msg:
-			print "%s: %s" % (fn, msg)
+    sys.stdout = sys.stderr
+    try:
+        opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL')
+        if not rest:
+            cmd = 'head'
+        else:
+            cmd, rest = rest[0], rest[1:]
+        if not commands.has_key(cmd):
+            raise getopt.error, "unknown command"
+        coptset, func = commands[cmd]
+        copts, files = getopt.getopt(rest, coptset)
+    except getopt.error, msg:
+        print msg
+        print "usage: rrcs [options] command [options] [file] ..."
+        print "where command can be:"
+        print "      ci|put      # checkin the given files"
+        print "      co|get      # checkout"
+        print "      info        # print header info"
+        print "      head        # print revision of head branch"
+        print "      list        # list filename if valid"
+        print "      log         # print full log"
+        print "      diff        # diff rcs file and work file"
+        print "if no files are given, all remote rcs files are assumed"
+        sys.exit(2)
+    x = openrcsclient(opts)
+    if not files:
+        files = x.listfiles()
+    for fn in files:
+        try:
+            func(x, copts, fn)
+        except (IOError, os.error), msg:
+            print "%s: %s" % (fn, msg)
 
 def checkin(x, copts, fn):
-	f = open(fn)
-	data = f.read()
-	f.close()
-	new = not x.isvalid(fn)
-	if not new and same(x, copts, fn, data):
-		print "%s: unchanged since last checkin" % fn
-		return
-	print "Checking in", fn, "..."
-	message = asklogmessage(new)
-	messages = x.put(fn, data, message)
-	if messages:
-		print messages
+    f = open(fn)
+    data = f.read()
+    f.close()
+    new = not x.isvalid(fn)
+    if not new and same(x, copts, fn, data):
+        print "%s: unchanged since last checkin" % fn
+        return
+    print "Checking in", fn, "..."
+    message = asklogmessage(new)
+    messages = x.put(fn, data, message)
+    if messages:
+        print messages
 
 def checkout(x, copts, fn):
-	data = x.get(fn)
-	f = open(fn, 'w')
-	f.write(data)
-	f.close()
+    data = x.get(fn)
+    f = open(fn, 'w')
+    f.write(data)
+    f.close()
 
 def lock(x, copts, fn):
-	x.lock(fn)
+    x.lock(fn)
 
 def unlock(x, copts, fn):
-	x.unlock(fn)
+    x.unlock(fn)
 
 def info(x, copts, fn):
-	dict = x.info(fn)
-	keys = dict.keys()
-	keys.sort()
-	for key in keys:
-		print key + ':', dict[key]
-	print '='*70
+    dict = x.info(fn)
+    keys = dict.keys()
+    keys.sort()
+    for key in keys:
+        print key + ':', dict[key]
+    print '='*70
 
 def head(x, copts, fn):
-	head = x.head(fn)
-	print fn, head
+    head = x.head(fn)
+    print fn, head
 
 def list(x, copts, fn):
-	if x.isvalid(fn):
-		print fn
+    if x.isvalid(fn):
+        print fn
 
 def log(x, copts, fn):
-	flags = ''
-	for o, a in copts:
-		flags = flags + ' ' + o + a
-	flags = flags[1:]
-	messages = x.log(fn, flags)
-	print messages
+    flags = ''
+    for o, a in copts:
+        flags = flags + ' ' + o + a
+    flags = flags[1:]
+    messages = x.log(fn, flags)
+    print messages
 
 def diff(x, copts, fn):
-	if same(x, copts, fn):
-		return
-	flags = ''
-	for o, a in copts:
-		flags = flags + ' ' + o + a
-	flags = flags[1:]
-	data = x.get(fn)
-	tf = tempfile.NamedTemporaryFile()
-	tf.write(data)
-	tf.flush()
-	print 'diff %s -r%s %s' % (flags, x.head(fn), fn)
-	sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
-	if sts:
-		print '='*70
+    if same(x, copts, fn):
+        return
+    flags = ''
+    for o, a in copts:
+        flags = flags + ' ' + o + a
+    flags = flags[1:]
+    data = x.get(fn)
+    tf = tempfile.NamedTemporaryFile()
+    tf.write(data)
+    tf.flush()
+    print 'diff %s -r%s %s' % (flags, x.head(fn), fn)
+    sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
+    if sts:
+        print '='*70
 
 def same(x, copts, fn, data = None):
-	if data is None:
-		f = open(fn)
-		data = f.read()
-		f.close()
-	lsum = md5.new(data).digest()
-	rsum = x.sum(fn)
-	return lsum == rsum
+    if data is None:
+        f = open(fn)
+        data = f.read()
+        f.close()
+    lsum = md5.new(data).digest()
+    rsum = x.sum(fn)
+    return lsum == rsum
 
 def asklogmessage(new):
-	if new:
-		print "enter description,",
-	else:
-		print "enter log message,",
-	print "terminate with single '.' or end of file:"
-	if new:
-		print "NOTE: This is NOT the log message!"
-	message = ""
-	while 1:
-		sys.stderr.write(">> ")
-		sys.stderr.flush()
-		line = sys.stdin.readline()
-		if not line or line == '.\n': break
-		message = message + line
-	return message
+    if new:
+        print "enter description,",
+    else:
+        print "enter log message,",
+    print "terminate with single '.' or end of file:"
+    if new:
+        print "NOTE: This is NOT the log message!"
+    message = ""
+    while 1:
+        sys.stderr.write(">> ")
+        sys.stderr.flush()
+        line = sys.stdin.readline()
+        if not line or line == '.\n': break
+        message = message + line
+    return message
 
 def remove(fn):
-	try:
-		os.unlink(fn)
-	except os.error:
-		pass
+    try:
+        os.unlink(fn)
+    except os.error:
+        pass
 
 commands = {
-	'ci': ('', checkin),
-	'put': ('', checkin),
-	'co': ('', checkout),
-	'get': ('', checkout),
-	'info': ('', info),
-	'head': ('', head),
-	'list': ('', list),
-	'lock': ('', lock),
-	'unlock': ('', unlock),
-	'log': ('bhLRtd:l:r:s:w:V:', log),
-	'diff': ('c', diff),
-	}
+        'ci': ('', checkin),
+        'put': ('', checkin),
+        'co': ('', checkout),
+        'get': ('', checkout),
+        'info': ('', info),
+        'head': ('', head),
+        'list': ('', list),
+        'lock': ('', lock),
+        'unlock': ('', unlock),
+        'log': ('bhLRtd:l:r:s:w:V:', log),
+        'diff': ('c', diff),
+        }
 
 if __name__ == '__main__':
-	main()
+    main()
diff --git a/Demo/pdist/security.py b/Demo/pdist/security.py
index 0ffd511..b63081e 100755
--- a/Demo/pdist/security.py
+++ b/Demo/pdist/security.py
@@ -1,33 +1,33 @@
 class Security:
 
-	def __init__(self):
-		import os
-		env = os.environ
-		if env.has_key('PYTHON_KEYFILE'):
-			keyfile = env['PYTHON_KEYFILE']
-		else:
-			keyfile = '.python_keyfile'
-			if env.has_key('HOME'):
-				keyfile = os.path.join(env['HOME'], keyfile)
-			if not os.path.exists(keyfile):
-				import sys
-				for dir in sys.path:
-					kf = os.path.join(dir, keyfile)
-					if os.path.exists(kf):
-						keyfile = kf
-						break
-		try:
-			self._key = eval(open(keyfile).readline())
-		except IOError:
-			raise IOError, "python keyfile %s: cannot open" % keyfile
+    def __init__(self):
+        import os
+        env = os.environ
+        if env.has_key('PYTHON_KEYFILE'):
+            keyfile = env['PYTHON_KEYFILE']
+        else:
+            keyfile = '.python_keyfile'
+            if env.has_key('HOME'):
+                keyfile = os.path.join(env['HOME'], keyfile)
+            if not os.path.exists(keyfile):
+                import sys
+                for dir in sys.path:
+                    kf = os.path.join(dir, keyfile)
+                    if os.path.exists(kf):
+                        keyfile = kf
+                        break
+        try:
+            self._key = eval(open(keyfile).readline())
+        except IOError:
+            raise IOError, "python keyfile %s: cannot open" % keyfile
 
-	def _generate_challenge(self):
-		import random
-		return random.randint(100, 100000)
+    def _generate_challenge(self):
+        import random
+        return random.randint(100, 100000)
 
-	def _compare_challenge_response(self, challenge, response):
-		return self._encode_challenge(challenge) == response
+    def _compare_challenge_response(self, challenge, response):
+        return self._encode_challenge(challenge) == response
 
-	def _encode_challenge(self, challenge):
-		p, m = self._key
-		return pow(long(challenge), p, m)
+    def _encode_challenge(self, challenge):
+        p, m = self._key
+        return pow(long(challenge), p, m)
diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py
index 4e4ab0d..e692eea 100755
--- a/Demo/pdist/server.py
+++ b/Demo/pdist/server.py
@@ -12,103 +12,103 @@
 
 
 class Server:
-	
-	"""RPC Server class.  Derive a class to implement a particular service."""
-	
-	def __init__(self, address, verbose = VERBOSE):
-		if type(address) == type(0):
-			address = ('', address)
-		self._address = address
-		self._verbose = verbose
-		self._socket = None
-		self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-		self._socket.bind(address)
-		self._socket.listen(1)
-		self._listening = 1
-	
-	def _setverbose(self, verbose):
-		self._verbose = verbose
-	
-	def __del__(self):
-		self._close()
-	
-	def _close(self):
-		self._listening = 0
-		if self._socket:
-			self._socket.close()
-		self._socket = None
-	
-	def _serverloop(self):
-		while self._listening:
-			self._serve()
-	
-	def _serve(self):
-		if self._verbose: print "Wait for connection ..."
-		conn, address = self._socket.accept()
-		if self._verbose: print "Accepted connection from %s" % repr(address)
-		if not self._verify(conn, address):
-			print "*** Connection from %s refused" % repr(address)
-			conn.close()
-			return
-		rf = conn.makefile('r')
-		wf = conn.makefile('w')
-		ok = 1
-		while ok:
-			wf.flush()
-			if self._verbose > 1: print "Wait for next request ..."
-			ok = self._dorequest(rf, wf)
-	
-	_valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
-	
-	def _verify(self, conn, address):
-		host, port = address
-		for pat in self._valid:
-			if fnmatch(host, pat): return 1
-		return 0
-	
-	def _dorequest(self, rf, wf):
-		rp = pickle.Unpickler(rf)
-		try:
-			request = rp.load()
-		except EOFError:
-			return 0
-		if self._verbose > 1: print "Got request: %s" % repr(request)
-		try:
-			methodname, args, id = request
-			if '.' in methodname:
-				reply = (None, self._special(methodname, args), id)
-			elif methodname[0] == '_':
-				raise NameError, "illegal method name %s" % repr(methodname)
-			else:
-				method = getattr(self, methodname)
-				reply = (None, apply(method, args), id)
-		except:
-			reply = (sys.exc_type, sys.exc_value, id)
-		if id < 0 and reply[:2] == (None, None):
-			if self._verbose > 1: print "Suppress reply"
-			return 1
-		if self._verbose > 1: print "Send reply: %s" % repr(reply)
-		wp = pickle.Pickler(wf)
-		wp.dump(reply)
-		return 1
-	
-	def _special(self, methodname, args):
-		if methodname == '.methods':
-			if not hasattr(self, '_methods'):
-				self._methods = tuple(self._listmethods())
-			return self._methods
-		raise NameError, "unrecognized special method name %s" % repr(methodname)
-	
-	def _listmethods(self, cl=None):
-		if not cl: cl = self.__class__
-		names = cl.__dict__.keys()
-		names = filter(lambda x: x[0] != '_', names)
-		names.sort()
-		for base in cl.__bases__:
-			basenames = self._listmethods(base)
-			basenames = filter(lambda x, names=names: x not in names, basenames)
-			names[len(names):] = basenames
-		return names
+
+    """RPC Server class.  Derive a class to implement a particular service."""
+
+    def __init__(self, address, verbose = VERBOSE):
+        if type(address) == type(0):
+            address = ('', address)
+        self._address = address
+        self._verbose = verbose
+        self._socket = None
+        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._socket.bind(address)
+        self._socket.listen(1)
+        self._listening = 1
+
+    def _setverbose(self, verbose):
+        self._verbose = verbose
+
+    def __del__(self):
+        self._close()
+
+    def _close(self):
+        self._listening = 0
+        if self._socket:
+            self._socket.close()
+        self._socket = None
+
+    def _serverloop(self):
+        while self._listening:
+            self._serve()
+
+    def _serve(self):
+        if self._verbose: print "Wait for connection ..."
+        conn, address = self._socket.accept()
+        if self._verbose: print "Accepted connection from %s" % repr(address)
+        if not self._verify(conn, address):
+            print "*** Connection from %s refused" % repr(address)
+            conn.close()
+            return
+        rf = conn.makefile('r')
+        wf = conn.makefile('w')
+        ok = 1
+        while ok:
+            wf.flush()
+            if self._verbose > 1: print "Wait for next request ..."
+            ok = self._dorequest(rf, wf)
+
+    _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']
+
+    def _verify(self, conn, address):
+        host, port = address
+        for pat in self._valid:
+            if fnmatch(host, pat): return 1
+        return 0
+
+    def _dorequest(self, rf, wf):
+        rp = pickle.Unpickler(rf)
+        try:
+            request = rp.load()
+        except EOFError:
+            return 0
+        if self._verbose > 1: print "Got request: %s" % repr(request)
+        try:
+            methodname, args, id = request
+            if '.' in methodname:
+                reply = (None, self._special(methodname, args), id)
+            elif methodname[0] == '_':
+                raise NameError, "illegal method name %s" % repr(methodname)
+            else:
+                method = getattr(self, methodname)
+                reply = (None, apply(method, args), id)
+        except:
+            reply = (sys.exc_type, sys.exc_value, id)
+        if id < 0 and reply[:2] == (None, None):
+            if self._verbose > 1: print "Suppress reply"
+            return 1
+        if self._verbose > 1: print "Send reply: %s" % repr(reply)
+        wp = pickle.Pickler(wf)
+        wp.dump(reply)
+        return 1
+
+    def _special(self, methodname, args):
+        if methodname == '.methods':
+            if not hasattr(self, '_methods'):
+                self._methods = tuple(self._listmethods())
+            return self._methods
+        raise NameError, "unrecognized special method name %s" % repr(methodname)
+
+    def _listmethods(self, cl=None):
+        if not cl: cl = self.__class__
+        names = cl.__dict__.keys()
+        names = filter(lambda x: x[0] != '_', names)
+        names.sort()
+        for base in cl.__bases__:
+            basenames = self._listmethods(base)
+            basenames = filter(lambda x, names=names: x not in names, basenames)
+            names[len(names):] = basenames
+        return names
 
 
 from security import Security
@@ -116,30 +116,30 @@
 
 class SecureServer(Server, Security):
 
-	def __init__(self, *args):
-		apply(Server.__init__, (self,) + args)
-		Security.__init__(self)
+    def __init__(self, *args):
+        apply(Server.__init__, (self,) + args)
+        Security.__init__(self)
 
-	def _verify(self, conn, address):
-		import string
-		challenge = self._generate_challenge()
-		conn.send("%d\n" % challenge)
-		response = ""
-		while "\n" not in response and len(response) < 100:
-			data = conn.recv(100)
-			if not data:
-				break
-			response = response + data
-		try:
-			response = string.atol(string.strip(response))
-		except string.atol_error:
-			if self._verbose > 0:
-				print "Invalid response syntax", repr(response)
-			return 0
-		if not self._compare_challenge_response(challenge, response):
-			if self._verbose > 0:
-				print "Invalid response value", repr(response)
-			return 0
-		if self._verbose > 1:
-			print "Response matches challenge.  Go ahead!"
-		return 1
+    def _verify(self, conn, address):
+        import string
+        challenge = self._generate_challenge()
+        conn.send("%d\n" % challenge)
+        response = ""
+        while "\n" not in response and len(response) < 100:
+            data = conn.recv(100)
+            if not data:
+                break
+            response = response + data
+        try:
+            response = string.atol(string.strip(response))
+        except string.atol_error:
+            if self._verbose > 0:
+                print "Invalid response syntax", repr(response)
+            return 0
+        if not self._compare_challenge_response(challenge, response):
+            if self._verbose > 0:
+                print "Invalid response value", repr(response)
+            return 0
+        if self._verbose > 1:
+            print "Response matches challenge.  Go ahead!"
+        return 1
diff --git a/Demo/pdist/sumtree.py b/Demo/pdist/sumtree.py
index 92c1fd0..9291a56 100755
--- a/Demo/pdist/sumtree.py
+++ b/Demo/pdist/sumtree.py
@@ -2,23 +2,23 @@
 import FSProxy
 
 def main():
-	t1 = time.time()
-	#proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127))
-	proxy = FSProxy.FSProxyLocal()
-	sumtree(proxy)
-	proxy._close()
-	t2 = time.time()
-	print t2-t1, "seconds"
-	raw_input("[Return to exit] ")
+    t1 = time.time()
+    #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127))
+    proxy = FSProxy.FSProxyLocal()
+    sumtree(proxy)
+    proxy._close()
+    t2 = time.time()
+    print t2-t1, "seconds"
+    raw_input("[Return to exit] ")
 
 def sumtree(proxy):
-	print "PWD =", proxy.pwd()
-	files = proxy.listfiles()
-	proxy.infolist(files)
-	subdirs = proxy.listsubdirs()
-	for name in subdirs:
-		proxy.cd(name)
-		sumtree(proxy)
-		proxy.back()
+    print "PWD =", proxy.pwd()
+    files = proxy.listfiles()
+    proxy.infolist(files)
+    subdirs = proxy.listsubdirs()
+    for name in subdirs:
+        proxy.cd(name)
+        sumtree(proxy)
+        proxy.back()
 
 main()