← Back to team overview

divmod-dev team mailing list archive

[Merge] lp:~cyli/divmod.org/remove-vertex into lp:divmod.org

 

cyli has proposed merging lp:~cyli/divmod.org/remove-vertex into lp:divmod.org.

Requested reviews:
  Divmod-dev (divmod-dev)

For more details, see:
https://code.launchpad.net/~cyli/divmod.org/remove-vertex/+merge/171717

Proposing to remove Vertex from the divmod repos.  I found only one branch with a merge proposal for it:

https://code.launchpad.net/~alfred-54/divmod.org/divmod.org/+merge/158833

I've ported trunk as well as alfred-54's branch to https://github.com/cyli/vertex, which I will then transfer to the twistedmatrix organization after/if this branch is merged into divmod.org repo.
-- 
https://code.launchpad.net/~cyli/divmod.org/remove-vertex/+merge/171717
Your team Divmod-dev is requested to review the proposed merge of lp:~cyli/divmod.org/remove-vertex into lp:divmod.org.
=== modified file 'Divmod.pth'
--- Divmod.pth	2013-01-02 10:08:46 +0000
+++ Divmod.pth	2013-06-27 06:07:28 +0000
@@ -1,4 +1,4 @@
-# -*- test-case-name: axiom,combinator,epsilon,xmantissa,nevow,formless,xquotient,reverend,sine,vertex,hyperbola,imaginary,examplegame -*-
+# -*- test-case-name: axiom,combinator,epsilon,xmantissa,nevow,formless,xquotient,reverend,sine,hyperbola,imaginary,examplegame -*-
 Axiom
 Combinator
 Epsilon
@@ -7,7 +7,6 @@
 Quotient
 Reverend
 Sine
-Vertex
 Hyperbola
 Imaginary
 Imaginary/ExampleGame

=== removed directory 'Vertex'
=== removed file 'Vertex/DEPS.txt'
--- Vertex/DEPS.txt	2006-06-14 11:54:41 +0000
+++ Vertex/DEPS.txt	1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
-Python 2.4
-Twisted 2.4.0
-PyOpenSSL 0.6
-OpenSSL 0.9.7
-Epsilon 0.5.0

=== removed file 'Vertex/LICENSE'
--- Vertex/LICENSE	2005-12-10 22:31:51 +0000
+++ Vertex/LICENSE	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-Copyright (c) 2005 Divmod Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file

=== removed file 'Vertex/MANIFEST.in'
--- Vertex/MANIFEST.in	2006-06-14 11:54:41 +0000
+++ Vertex/MANIFEST.in	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-include LICENSE
-include NAME.txt
-include DEPS.txt
-include doc/q2q-standalone.tac

=== removed file 'Vertex/NAME.txt'
--- Vertex/NAME.txt	2005-08-27 23:09:07 +0000
+++ Vertex/NAME.txt	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-
-See: http://mathworld.wolfram.com/Vertex.html
-
-A vertex in mathematics is a location where two or more lines or edges meet.
-
-Divmod Vertex is an implementation of and interface to the Q2Q protocol.  It is
-named for a vertext because it provides a way for peers on the internet to
-establish connections with each other, e.g. to make their connection lines
-meet, regardless of intermediary interference such as network address
-translators and lack of naming information.

=== removed file 'Vertex/NEWS.txt'
--- Vertex/NEWS.txt	2009-11-30 01:08:55 +0000
+++ Vertex/NEWS.txt	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-0.3.0 (2009-11-25):
-  - Remove use of deprecated Twisted APIs from the test suite and improve
-    some error handling as a necessary consequence.
-  - Use twisted.internet.ssl instead of epsilon.sslverify.
-  - Remove an implementation of deferLater.
-
-0.2.0 (2006-06-12):
-  - Moved JUICE implementation into Epsilon.
-  - Removed dependency on Nevow's formless.
-  - Clarify licensing terms.
-  - Fix bugs on 64-bit platforms.
-  - removed buggy legacy non-TLS options which would break negotiation with
-    OpenSSL 0.9.8a.
-  - Deprecated twisted test APIs removed.
-  - First phase of integration with twisted.cred; vertex endpoints can now be
-    authenticated against a Twisted UsernamePassword cred authenticator.
-
-0.1.0 (2005-10-10):
-
-  - Initial release.

=== removed file 'Vertex/README.txt'
--- Vertex/README.txt	2006-06-14 11:54:41 +0000
+++ Vertex/README.txt	1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-
-Divmod Vertex
-=============
-
-Divmod Vertex is the first implementation of the Q2Q protocol, which is a
-peer-to-peer communication protocol for establishing stream-based communication
-between named endpoints.
-
-It is also a P2P application client and server platform in the early stages of
-development.  It is currently quite usable for knocking holes in firewalls, but
-requires some polish to really be usable.
-

=== removed directory 'Vertex/bin'
=== removed file 'Vertex/bin/gvertex'
--- Vertex/bin/gvertex	2006-03-08 04:10:37 +0000
+++ Vertex/bin/gvertex	1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-#!/usr/bin/python
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from vertex.gtk2hack import main
-
-if __name__ == '__main__':
-    main()

=== removed file 'Vertex/bin/vertex'
--- Vertex/bin/vertex	2005-08-10 22:20:03 +0000
+++ Vertex/bin/vertex	1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-#!/usr/bin/python
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from vertex.q2qclient import Q2QClientProgram
-
-if __name__ == '__main__':
-    Q2QClientProgram().parseOptions()

=== removed directory 'Vertex/doc'
=== removed file 'Vertex/doc/notes'
--- Vertex/doc/notes	2005-08-05 03:13:02 +0000
+++ Vertex/doc/notes	1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-
-Gin
-===
-
-TCP-alike over UDP
-
-Packet Format
-=============
-
-Connection ID - 32 bits
-Sequence Number - 32 bits
-Ack number - 32 bits
-Window - 32 bits
-Flags (SYN, ACK, FIN, IGN) - 8 bits
-Checksum - 32 bits
-Data length in bytes - 16 bits
-Data - See previous
-
-SEMANTICS
-=========
-Different types of packets:
-
-just SYN:
-SYN+ACK:
-just ACK: normal tcp packet meanings
-
-SYN+NAT: Request for information about the sender's public address
-
-ACK+NAT: Response with information about the recipient's public address.  The
-data is the IP address and port number to which the packet is being sent,
-formatted as a dotted-quad formatted IP address followed by a colon followed by
-the base-10 string representation of the port number..
-
-STB: Size Too Big - a packet with a dlen greater than the length of its data
-was received.
-
-Other Stuff:
-
-Connection IDs uniquely identify a stream for a protocol.  All bytes
-associated with a particular connectionID will be delivered to the
-same protocol instance.
-
-Sequence Numbers indicate the senders notion of how far into its
-outgoing stream this packet is.  Sequence numbers start from a
-pseudo-random value within the allowed range and are incremented by
-the number of bytes in each packet transmitted (re-transmits
-discounted).  This indicates to the peer where the bytes in each
-packet lie in the stream, allowing ordered delivery.
-
-Ack numbers indicate the senders notion of how far into its incoming
-stream all data has been received.  This value is always what the
-sender expects the receiver to use as its next sequence number.
-
-Window indicates the number of bytes in advance of the senders ack
-number the receiver may proceed in sending.  This receiver's sequence
-numbers must never be greater than the sender's last ack number plus
-their window number.
-
-Checksum is a CRC 32 of the data (and only the data - wait maybe this
-should be the header less the checksum, too, in case things get
-corrupted there)

=== removed file 'Vertex/doc/q2q-standalone.tac'
--- Vertex/doc/q2q-standalone.tac	2005-08-10 22:20:03 +0000
+++ Vertex/doc/q2q-standalone.tac	1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-from vertex.q2qstandalone import defaultConfig
-
-application = defaultConfig()
-

=== removed directory 'Vertex/prime'
=== removed directory 'Vertex/prime/plugins'
=== removed file 'Vertex/prime/plugins/vertex_client.py'
--- Vertex/prime/plugins/vertex_client.py	2006-06-01 04:57:02 +0000
+++ Vertex/prime/plugins/vertex_client.py	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-
-from vertex.gtk2hack import PlugEntry
-
-pe = PlugEntry()

=== removed file 'Vertex/setup.py'
--- Vertex/setup.py	2009-11-30 01:08:55 +0000
+++ Vertex/setup.py	1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
-from epsilon import setuphelper
-
-from vertex import version
-
-setuphelper.autosetup(
-    name="Vertex",
-    version=version.short(),
-    maintainer="Divmod, Inc.",
-    maintainer_email="support@xxxxxxxxxx",
-    url="http://divmod.org/trac/wiki/DivmodVertex";,
-    license="MIT",
-    platforms=["any"],
-    description=
-        """
-        Divmod Vertex is the first implementation of the Q2Q protocol, which
-        is a peer-to-peer communication protocol for establishing
-        stream-based communication between named endpoints.
-        """,
-    classifiers=[
-        "Development Status :: 2 - Pre-Alpha",
-        "Framework :: Twisted",
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: MIT License",
-        "Programming Language :: Python",
-        "Topic :: Communications",
-        "Topic :: Internet",
-        "Topic :: Internet :: File Transfer Protocol (FTP)",
-        "Topic :: Internet :: Name Service (DNS)",
-        "Topic :: Software Development :: Libraries :: Python Modules",
-        ],
-    )

=== removed directory 'Vertex/vertex'
=== removed file 'Vertex/vertex/__init__.py'
--- Vertex/vertex/__init__.py	2008-08-11 11:19:59 +0000
+++ Vertex/vertex/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-# -*- test-case-name: vertex.test -*-
-
-from vertex._version import version

=== removed file 'Vertex/vertex/_version.py'
--- Vertex/vertex/_version.py	2009-11-30 01:08:55 +0000
+++ Vertex/vertex/_version.py	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-# This is an auto-generated file. Use admin/change-versions to update.
-from twisted.python import versions
-version = versions.Version(__name__[:__name__.rfind('.')], 0, 3, 0)

=== removed file 'Vertex/vertex/bits.py'
--- Vertex/vertex/bits.py	2005-08-05 06:02:56 +0000
+++ Vertex/vertex/bits.py	1970-01-01 00:00:00 +0000
@@ -1,142 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-# -*- test-case-name: vertex.test.test_bits -*-
-""" The purpose of this module is to provide the class BitArray, a compact
-overlay onto an array of bytes which is instead bit-addressable.  It also
-includes several bitwise operators.
-
-It does not include all array operations yet, most notably those related to
-slicing, since it is written primarily for use by the swarming implementation
-and swarming only requires fixed-size bit masks.
-
-"""
-
-__metaclass__ = type
-
-import array
-import operator
-import math
-
-BITS_PER_BYTE = 8
-
-def operate(operation):
-    # XXX TODO: optimize this and countbits later
-    def __x__(self, other):
-        if len(self) < len(other):
-            return operation(other, self)
-        new = BitArray(size=len(self))
-        for offt, (mybit, hisbit) in enumerate(zip(self, other)):
-            result = new[offt] = operation(mybit, hisbit)
-
-        for j in range(offt+1, len(self)):
-            new[j] = operation(self[j], 0)
-        return new
-    return __x__
-
-
-class BitArray:
-    """
-    A large mutable array of bits.
-    """
-
-    def __init__(self, bytes=None, size=None, default=0):
-        if bytes is None and size is None:
-            size = 0
-        if bytes is None:
-            bytes = array.array("B")
-            bytesize = int(math.ceil(float(size) / BITS_PER_BYTE))
-            if default:
-                padbyte = 255
-            else:
-                padbyte = 0
-            bytes.fromlist([padbyte] * bytesize)
-        self.bytes = bytes
-        if size is None:
-            size = len(self.bytes) * self.bytes.itemsize * BITS_PER_BYTE
-        self.size = size
-
-        # initialize 'on' and 'off' lists to optimize various things
-        self.on = []
-        self.off = []
-        blists = self.blists = self.off, self.on
-
-        for index, bit in enumerate(self):
-            blists[bit].append(index)
-
-    def append(self, bit):
-        offt = self.size
-        self.size += 1
-        if (len(self.bytes) * self.bytes.itemsize * BITS_PER_BYTE) < self.size:
-            self.bytes.append(0)
-        self[offt] = bit
-
-    def any(self, req=1):
-        return bool(self.blists[req])
-
-    def percent(self):
-        """
-        debugging method; returns a string indicating percentage completion
-        """
-        if not len(self):
-            return 'Inf%'
-        return '%0.2f%%'% ((float(self.countbits()) / len(self)) * 100,)
-
-    def __getitem__(self, bitcount):
-        if bitcount < 0:
-            bitcount += self.size
-        if bitcount >= self.size:
-            raise IndexError("%r >= %r" % (bitcount, self.size))
-        div, mod = divmod(bitcount, self.bytes.itemsize * BITS_PER_BYTE)
-        byte = self.bytes[div]
-        return (byte >> mod) & 1
-
-    def __setitem__(self, bitcount, bit):
-        if bitcount < 0:
-            bitcount += self.size
-        if bitcount >= self.size:
-            raise IndexError("bitcount too big")
-        div, mod = divmod(bitcount, self.bytes.itemsize * BITS_PER_BYTE)
-        if bit:
-            self.bytes[div] |= 1 << mod
-        else:
-            self.bytes[div] &= ~(1 << mod)
-
-        # change updating
-        notbitlist = self.blists[not bit]
-        try:
-            notbitlist.remove(bitcount)
-        except ValueError:
-            pass
-        bitlist = self.blists[bit]
-        if bitcount not in bitlist:
-            bitlist.append(bitcount)
-
-    def __len__(self):
-        return self.size
-
-    def __repr__(self):
-        l = []
-        l.append('[')
-        for b in self:
-            if b:
-                c = 'X'
-            else:
-                c = ' '
-            l.append(c)
-        l.append(']')
-        return ''.join(l)
-
-    def countbits(self, on=True):
-        return len(self.blists[on])
-
-    def positions(self, bit):
-        """
-        An iterator of all positions that a bit holds in this BitArray.
-
-        @param bit: 1 or 0
-        """
-        return self.blists[bit][:]
-
-    __xor__ = operate(operator.xor)
-    __and__ = operate(operator.and_)
-    __or__ = operate(operator.or_)
-

=== removed file 'Vertex/vertex/conncache.py'
--- Vertex/vertex/conncache.py	2009-07-06 11:40:18 +0000
+++ Vertex/vertex/conncache.py	1970-01-01 00:00:00 +0000
@@ -1,160 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-# -*- test-case-name: vertex.test.test_q2q.TCPConnection.testSendingFiles -*-
-
-"""
-Connect between two endpoints using a message-based protocol to exchange
-messages lazily in response to UI events, caching the protocol as necessary.
-Using connection-oriented protocols, you will most likely not want to use this
-class - you might end up retrieving a cached connection in the middle of a
-chunk of data being sent.  For the purposes of this distinction, a
-'message-oriented' protocol is one which has an API which either::
-
-  a) writes only whole messages to its transport so there is never an
-     opportunity to insert data into the middle of a message, or
-
-  b) provides an API on the Protocol instance for queuing whole messages such
-     that if partial messages are sent, calling the API multiple times will
-     queue them internally so that clients do not need to care whether the
-     connection is made or not.
-
-It is worth noting that all Juice-derived protocols meet constraint (b).
-"""
-
-from zope.interface import implements
-
-from twisted.internet.defer import maybeDeferred, DeferredList, Deferred
-from twisted.internet.main import CONNECTION_LOST
-from twisted.internet import interfaces
-from twisted.internet.protocol import ClientFactory
-
-
-class ConnectionCache:
-    def __init__(self):
-        """
-        """
-        # map (fromAddress, toAddress, protoName): protocol instance
-        self.cachedConnections = {}
-        # map (fromAddress, toAddress, protoName): list of Deferreds
-        self.inProgress = {}
-
-    def connectCached(self, endpoint, protocolFactory,
-                      extraWork=lambda x: x,
-                      extraHash=None):
-        """See module docstring
-        """
-        key = endpoint, extraHash
-        D = Deferred()
-        if key in self.cachedConnections:
-            D.callback(self.cachedConnections[key])
-        elif key in self.inProgress:
-            self.inProgress[key].append(D)
-        else:
-            self.inProgress[key] = [D]
-            endpoint.connect(
-                _CachingClientFactory(
-                    self, key, protocolFactory,
-                    extraWork))
-        return D
-
-    def cacheUnrequested(self, endpoint, extraHash, protocol):
-        self.connectionMadeForKey((endpoint, extraHash), protocol)
-
-    def connectionMadeForKey(self, key, protocol):
-        deferreds = self.inProgress.pop(key, [])
-        self.cachedConnections[key] = protocol
-        for d in deferreds:
-            d.callback(protocol)
-
-    def connectionLostForKey(self, key):
-        if key in self.cachedConnections:
-            del self.cachedConnections[key]
-
-    def connectionFailedForKey(self, key, reason):
-        deferreds = self.inProgress.pop(key)
-        for d in deferreds:
-            d.errback(reason)
-
-    def shutdown(self):
-        return DeferredList(
-            [maybeDeferred(p.transport.loseConnection)
-             for p in self.cachedConnections.values()])
-
-
-class _CachingClientFactory(ClientFactory):
-    debug = False
-
-    def __init__(self, cache, key, subFactory, extraWork):
-        """
-        @param cache: a Q2QService
-
-        @param key: a 2-tuple of (endpoint, extra) that represents what
-        connections coming from this factory are for.
-
-        @param subFactory: a ClientFactory which I forward methods to.
-
-        @param extraWork: extraWork(proto) -> Deferred which fires when the
-        connection has been prepared sufficiently to be used by subsequent
-        connections and can be counted as a success.
-        """
-
-        self.cache = cache
-        self.key = key
-        self.subFactory = subFactory
-        self.finishedExtraWork = False
-        self.extraWork = extraWork
-
-    lostAsFailReason = CONNECTION_LOST
-
-    def clientConnectionMade(self, protocol):
-        def success(reason):
-            self.cache.connectionMadeForKey(self.key, protocol)
-            self.finishedExtraWork = True
-            return protocol
-
-        def failed(reason):
-            self.lostAsFailReason = reason
-            protocol.transport.loseConnection()
-            return reason
-        maybeDeferred(self.extraWork, protocol).addCallbacks(
-            success, failed)
-
-    def clientConnectionLost(self, connector, reason):
-        if self.finishedExtraWork:
-            self.cache.connectionLostForKey(self.key)
-        else:
-            self.cache.connectionFailedForKey(self.key,
-                                              self.lostAsFailReason)
-        self.subFactory.clientConnectionLost(connector, reason)
-
-    def clientConnectionFailed(self, connector, reason):
-        self.cache.connectionFailedForKey(self.key, reason)
-        self.subFactory.clientConnectionFailed(connector, reason)
-
-    def buildProtocol(self, addr):
-        return _CachingTransportShim(self, self.subFactory.buildProtocol(addr))
-
-
-class _CachingTransportShim:
-    disconnecting = property(lambda self: self.transport.disconnecting)
-
-    implements(interfaces.IProtocol)
-
-    def __init__(self, factory, protocol):
-        self.factory = factory
-        self.protocol = protocol
-
-        # IProtocol
-        self.dataReceived = protocol.dataReceived
-        self.connectionLost = protocol.connectionLost
-
-
-    def makeConnection(self, transport):
-        self.transport = transport
-        self.protocol.makeConnection(transport)
-        self.factory.clientConnectionMade(self.protocol)
-
-
-    def __repr__(self):
-        return 'Q2Q-Cached<%r, %r>' % (self.transport,
-                                       self.protocol)
-

=== removed file 'Vertex/vertex/depserv.py'
--- Vertex/vertex/depserv.py	2009-07-06 11:40:18 +0000
+++ Vertex/vertex/depserv.py	1970-01-01 00:00:00 +0000
@@ -1,197 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-"""
-This module is no longer supported for use outside Vertex.
-"""
-
-from twisted.python import log
-from sets import Set
-from twisted.persisted import sob
-from twisted.application import service, internet
-
-from zope.interface import implements
-
-class Conf(dict):
-    """A class to help in construction the configuration for delpoy().
-
-    Typical usage::
-
-        from vertex.depserv import Conf
-        conf = Conf()
-        s = conf.section
-        s('pop',
-            port = 110,
-            sslPort = 995)
-        ...
-    """
-    def section(self, name, **kw):
-        self.setdefault(name, {}).update(kw)
-
-
-class NotPersistable:
-    implements(sob.IPersistable)
-    def __init__(self, original):
-        self.original = original
-
-    def setStyle(self, style):
-        self.style = style
-
-    def save(self, tag=None, filename=None, passphrase=None):
-        pass
-
-
-class StartupError(Exception):
-    pass
-
-
-class DependencyService(service.MultiService):
-    """A MultiService that can start multiple services with interdependencies.
-
-    Each keyword parameter is a dict which serves as the options for that
-    service.
-
-    Each service defines a method setup_SERVICE, which is called with the
-    matching parameters (the service name must be all caps). If there is no key
-    for SERVICE in the class parameters, the setup method is not called. The
-    return value is ignored, and DependencyService makes no assumptions about
-    any side effects.
-
-    Each service may also optionally define depends_SERVICE which is called
-    before the setup method with the same parameters as the setup method. This
-    method returns a list of names of services on which SERVICE depends.
-    DependencyService will then initialize the service is the correct order. If
-    circular dependencies result, or a service depends on another service which
-    does not exist or is not configured to run, StartupError is raised.
-
-    The class can define required services by setting 'requiredServices' to a
-    list of service names. These services will be initialized first in the
-    order they appear in the list, ignoring all dependency information. If
-    there are no parameters for a required service (consequently, the setup
-    method would not normally be called), StartupError is raised.
-    """
-
-
-    requiredServices = []
-
-
-    def __init__(self, **kw):
-        service.MultiService.__init__(self)
-
-        # this makes it possible for one service to change the configuration of
-        # another. Avoid if possible, there if you need it. Be sure to properly
-        # set the dependencies.
-        self.config = kw
-        self.servers = []
-
-        services = kw.keys()
-        initedServices = Set()
-        uninitedServices = Set(services)
-
-        # build dependencies
-        dependencies = {}
-        for serv in services:
-            try:
-                dependMethod = self._getDependsMethod(serv)
-            except AttributeError:
-                continue
-            dependencies[serv] = dependMethod(**kw[serv])
-
-        def initializeService(svc):
-            self._getServiceMethod(svc)(**kw[svc])
-            initedServices.add(svc)
-            uninitedServices.remove(svc)
-
-        for svc in self.requiredServices:
-            if dependencies.get(svc):
-                raise StartupError(
-                    '%r is a required service but has unsatisfied '
-                    'dependency on %r' % (svc, dependencies[svc]))
-            initializeService(svc)
-
-        while uninitedServices:
-            # iterate over the uninitialized services, adding those with no
-            # outstanding dependencies to initThisRound.
-            initThisRound = []
-            for serv in uninitedServices:
-                for dep in dependencies.get(serv, []):
-                    if dep not in initedServices:
-                        if dep not in uninitedServices:
-                            raise StartupError(
-                                'service %r depends on service %r, which is not '
-                                'configured or does not exist.' % (serv, dep))
-                        break
-                else:
-                    initThisRound.append(serv)
-            if not initThisRound:
-                raise StartupError(
-                    'Can not initialize all services. Circular dependencies '
-                    'between setup methods?')
-            for svc in initThisRound:
-                initializeService(svc)
-
-
-    def _getServiceMethod(self, service):
-        return getattr(self, 'setup_%s' % (service.upper(),))
-
-
-    def _getDependsMethod(self, service):
-        return getattr(self, 'depends_%s' % (service.upper(),))
-
-
-    def deploy(Class, name=None, uid=None, gid=None, **kw):
-        """Create an application with the give name, uid, and gid.
-
-        The application has one child service, an instance of Class
-        configured based on the additional keyword arguments passed.
-
-        The application is not persistable.
-        """
-        svc = Class(**kw)
-
-        if name is None:
-            name = Class.__name__
-        # Make it easier (possible) to find this service by name later on
-        svc.setName(name)
-
-        app = service.Application(name, uid=uid, gid=gid)
-        app.addComponent(NotPersistable(app), ignoreClass=True)
-        svc.setServiceParent(app)
-
-        return app
-    deploy = classmethod(deploy)
-
-    def attach(self, subservice):
-        subservice.setServiceParent(self)
-        return subservice
-
-    def detach(self, subservice):
-        subservice.disownServiceParent()
-
-    def addServer(self, normalPort, sslPort, f, name):
-        """Add a TCP and an SSL server. Name them `name` and `name`+'s'."""
-        tcp = internet.TCPServer(normalPort,f)
-        tcp.setName(name)
-        self.servers.append(tcp)
-        if sslPort is not None:
-            ssl = internet.SSLServer(sslPort, f, contextFactory=self.sslfac)
-            ssl.setName(name+'s')
-            self.servers.append(ssl)
-
-    def discernPrivilegedServers(self):
-        return [srv for srv in self.servers if srv.args[0] <= 1024]
-
-    def discernUnprivilegedServers(self):
-        return [srv for srv in self.servers if srv.args[0] > 1024]
-
-    def privilegedStartService(self):
-        for server in self.discernPrivilegedServers():
-            log.msg("privileged attach %r" % server)
-            self.attach(server)
-        return service.MultiService.privilegedStartService(self)
-
-    def startService(self):
-        for server in self.discernUnprivilegedServers():
-            log.msg("attaching %r" % server)
-            self.attach(server)
-
-        return service.MultiService.startService(self)

=== removed file 'Vertex/vertex/endpoint.py'
--- Vertex/vertex/endpoint.py	2005-08-05 06:02:56 +0000
+++ Vertex/vertex/endpoint.py	1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-def stablesort(self, other):
-    return cmp(self.__class__, getattr(other, '__class__', type(other)))
-
-class TCPEndpoint:
-    def __init__(self, host, port):
-        self.host = host
-        self.port = port
-
-    def __hash__(self):
-        return hash((self.host, self.port)) + 5
-
-    def connect(self, protocolFactory):
-        from twisted.internet import reactor
-        return reactor.connectTCP(self.host, self.port, protocolFactory)
-
-    def __repr__(self):
-        return '<TCP@%s,%d>' % (self.host, self.port)
-
-    def __cmp__(self, other):
-        if isinstance(other, TCPEndpoint):
-            return cmp((self.host, self.port),
-                       (other.host, other.port))
-        return stablesort(self, other)
-
-
-class Q2QEndpoint:
-    def __init__(self, service, fromAddress, toAddress, protocolName):
-        self.service = service
-        self.fromAddress = fromAddress
-        self.toAddress = toAddress
-        self.protocolName = protocolName
-
-    def __repr__(self):
-        return '<Q2Q from <%s> to <%s> on %r>' % (
-            self.fromAddress, self.toAddress, self.protocolName)
-
-    def __cmp__(self, other):
-        if isinstance(other, Q2QEndpoint):
-            return cmp((self.fromAddress, self.toAddress, self.protocolName),
-                       (other.fromAddress, other.toAddress, other.protocolName))
-        return stablesort(self, other)
-
-    def __hash__(self):
-        return hash((self.fromAddress,
-                     self.toAddress,
-                     self.protocolName)) + 7
-
-    def connect(self, protocolFactory):
-        # from twisted.python.context import get
-        # get("q2q-service")
-        return self.service.connectQ2Q(
-            self.fromAddress, self.toAddress, self.protocolName,
-            protocolFactory)
-

=== removed file 'Vertex/vertex/gtk2hack.glade'
--- Vertex/vertex/gtk2hack.glade	2006-06-01 04:57:02 +0000
+++ Vertex/vertex/gtk2hack.glade	1970-01-01 00:00:00 +0000
@@ -1,635 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkMenu" id="notification_popup">
-
-  <child>
-    <widget class="GtkImageMenuItem" id="add_contact1">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">Add Contact</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="addContact" last_modification_time="Sun, 22 May 2005 01:24:07 GMT"/>
-
-      <child internal-child="image">
-	<widget class="GtkImage" id="image9">
-	  <property name="visible">True</property>
-	  <property name="stock">gtk-add</property>
-	  <property name="icon_size">1</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	</widget>
-      </child>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkMenuItem" id="identifymenuitem">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">Identify</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="identifyDialog" last_modification_time="Sun, 22 May 2005 03:20:18 GMT"/>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkSeparatorMenuItem" id="contacts_begin">
-      <property name="visible">True</property>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkSeparatorMenuItem" id="separator3">
-      <property name="visible">True</property>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkMenuItem" id="animate">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">Animate</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="toggleAnimate" last_modification_time="Sun, 22 May 2005 01:44:10 GMT"/>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkSeparatorMenuItem" id="separator1">
-      <property name="visible">True</property>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkImageMenuItem" id="quit1">
-      <property name="visible">True</property>
-      <property name="stock_item">GNOMEUIINFO_MENU_EXIT_ITEM</property>
-      <signal name="activate" handler="quit" last_modification_time="Sun, 22 May 2005 01:24:07 GMT"/>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="ident_dialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Identify Yourself</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">False</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	      <signal name="clicked" handler="identifyCancel" last_modification_time="Sun, 22 May 2005 03:14:51 GMT"/>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	      <signal name="clicked" handler="identifyOK" last_modification_time="Sun, 22 May 2005 03:15:00 GMT"/>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkTable" id="table1">
-	      <property name="border_width">5</property>
-	      <property name="visible">True</property>
-	      <property name="n_rows">2</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">2</property>
-	      <property name="column_spacing">5</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label4">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Address</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label5">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Password</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="addressEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="has_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">*</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="passwordEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">False</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">*</property>
-		  <property name="activates_default">True</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkProgressBar" id="identifyProgressBar">
-	      <property name="visible">True</property>
-	      <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
-	      <property name="fraction">0</property>
-	      <property name="pulse_step">0.10000000149</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="identifyProgressLabel">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes"></property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">3</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="add_contact_dialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Add Contact</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox2">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area2">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	      <signal name="activate" handler="popdownDialog" last_modification_time="Tue, 28 Feb 2006 09:34:42 GMT"/>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	      <signal name="activate" handler="doAddContact" last_modification_time="Tue, 28 Feb 2006 09:34:23 GMT"/>
-	      <signal name="clicked" handler="doAddContact" last_modification_time="Tue, 28 Feb 2006 10:36:25 GMT"/>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkFrame" id="frame1">
-	  <property name="visible">True</property>
-	  <property name="label_xalign">0</property>
-	  <property name="label_yalign">0.5</property>
-	  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment1">
-	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">12</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkTable" id="table2">
-		  <property name="border_width">16</property>
-		  <property name="visible">True</property>
-		  <property name="n_rows">2</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">16</property>
-		  <property name="column_spacing">16</property>
-
-		  <child>
-		    <widget class="GtkEntry" id="nameentry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">*</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="q2qidentry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">*</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="label7">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Name</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="label8">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Q2QID</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label6">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Contact Information</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">True</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">label_item</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="accept_connection_dialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Accept Connection?</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-  <signal name="destroy" handler="rejectConnectionEvt" last_modification_time="Tue, 28 Feb 2006 10:00:37 GMT"/>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox3">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area3">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton3">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	      <signal name="activate" handler="destroyit" last_modification_time="Tue, 28 Feb 2006 10:00:55 GMT"/>
-	      <signal name="clicked" handler="destroyit" last_modification_time="Tue, 28 Feb 2006 10:36:09 GMT"/>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton3">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	      <signal name="activate" handler="acceptConnectionEvt" last_modification_time="Tue, 28 Feb 2006 09:59:48 GMT"/>
-	      <signal name="clicked" handler="acceptConnectionEvt" last_modification_time="Tue, 28 Feb 2006 10:36:51 GMT"/>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="accept_connection_label">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">Accept connection?</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>

=== removed file 'Vertex/vertex/gtk2hack.py'
--- Vertex/vertex/gtk2hack.py	2006-06-01 04:57:02 +0000
+++ Vertex/vertex/gtk2hack.py	1970-01-01 00:00:00 +0000
@@ -1,270 +0,0 @@
-
-import os
-import rfc822
-
-from twisted.python.filepath import FilePath
-
-# import gtk ### pyflakes complains about this, due to the next line
-import gtk.glade
-
-from vertex.q2qclient import ClientQ2QService
-from vertex.q2q import Q2QAddress
-
-class _NullCb:
-    def __init__(self, name):
-        self.name = name
-
-    def __call__(self, *a, **kw):
-        print 'No callback provided for', self.name, a, kw
-
-class _SignalAttacher:
-    def __init__(self, original):
-        self.original = original
-
-    def __getitem__(self, callbackName):
-        return getattr(self.original, callbackName, None) or _NullCb(callbackName)
-
-GLADE_FILE = os.path.splitext(__file__)[0] + '.glade'
-
-class IdentificationDialog:
-    def __init__(self, clientService, plug):
-        self.xml = gtk.glade.XML(GLADE_FILE, "ident_dialog")
-        self.clientService = clientService
-        self.xml.signal_autoconnect(_SignalAttacher(self))
-        self.addressEntry = self.xml.get_widget('addressEntry')
-        self.passwordEntry = self.xml.get_widget('passwordEntry')
-        self.progressBar = self.xml.get_widget('identifyProgressBar')
-        self.progressLabel = self.xml.get_widget('identifyProgressLabel')
-        self.identifyWindow = self.xml.get_widget("ident_dialog")
-        self.cancelButton = self.xml.get_widget('cancelbutton1')
-        self.okButton = self.xml.get_widget('okbutton1')
-        self.plug = plug
-
-    def identifyCancel(self, event):
-        self.identifyWindow.destroy()
-
-    def identifyOK(self, event):
-        idstr = self.addressEntry.get_text()
-        D = self.clientService.authorize(
-            Q2QAddress.fromString(idstr),
-            self.passwordEntry.get_text())
-
-        sensitiveWidgets = [self.addressEntry,
-                            self.passwordEntry,
-                            self.okButton,
-                            self.cancelButton]
-        for widget in sensitiveWidgets:
-            widget.set_sensitive(False)
-        self.progressLabel.set_text("Authenticating...")
-        def itWorked(workedNone):
-            self.identifyWindow.destroy()
-            self.plug.setCurrentID(idstr)
-        def itDidntWork(error):
-            self.progressLabel.set_text(error.getErrorMessage())
-            for widget in sensitiveWidgets:
-                widget.set_sensitive(True)
-        D.addCallbacks(itWorked, itDidntWork)
-
-class AddContactDialog:
-    def __init__(self, plug):
-        self.xml = gtk.glade.XML(GLADE_FILE, "add_contact_dialog")
-        self.xml.signal_autoconnect(_SignalAttacher(self))
-        self.window = self.xml.get_widget("add_contact_dialog")
-        self.window.show_all()
-        self.plug = plug
-
-    def doAddContact(self, evt):
-        name = self.xml.get_widget("nameentry").get_text()
-        addr = self.xml.get_widget("q2qidentry").get_text()
-        self.plug.addBuddy(name, addr)
-        self.popdownDialog()
-
-    def popdownDialog(self, evt=None):
-        self.window.destroy()
-
-class AcceptConnectionDialog:
-    def __init__(self, d, From, to, protocol):
-        self.d = d
-        self.xml = gtk.glade.XML(GLADE_FILE, "accept_connection_dialog")
-        self.xml.signal_autoconnect(_SignalAttacher(self))
-        self.label = self.xml.get_widget("accept_connection_label")
-        self.label.set_text(
-            "Accept connection from %s for %s?" % (From, protocol))
-        self.window = self.xml.get_widget("accept_connection_dialog")
-        self.window.show_all()
-
-    done = False
-
-    def destroyit(self, evt):
-        self.window.destroy()
-
-    def acceptConnectionEvt(self, evt):
-        self.done = True
-        print "YES"
-        self.d.callback(1)
-        print "WHAT"
-        self.window.destroy()
-
-    def rejectConnectionEvt(self, evt):
-        print "DSTRY"
-        if not self.done:
-            print "DIE!"
-            from twisted.python import failure
-            self.d.errback(failure.Failure(KeyError("Connection rejected by user")))
-        else:
-            print "OK"
-
-from twisted.internet.protocol import ServerFactory
-from twisted.internet.protocol import Protocol
-
-class VertexDemoProtocol(Protocol):
-
-    def connectionMade(self):
-        print 'CONN MADE'
-
-    def dataReceived(self, data):
-        print 'HOLY SHNIKIES', data
-
-class VertexFactory(ServerFactory):
-    protocol = VertexDemoProtocol
-
-    def __init__(self, plug):
-        self.plug = plug
-
-    def startFactory(self):
-        #self.plug.animator.stop(1)
-        pass
-
-    def stopFactory(self):
-        #self.plug.animator.stop(0)
-        pass
-
-
-class BuddyItem:
-    def __init__(self, plug, alias, q2qaddress):
-        mi = self.menuItem = gtk.MenuItem(alias + " <"+q2qaddress+">")
-        mi.connect("activate", self.initiateFileTransfer)
-        mi.show_all()
-        self.plug = plug
-        self.alias = alias
-        self.q2qaddress = q2qaddress
-        self.plug.loadedBuddies[q2qaddress] = self
-
-    def initiateFileTransfer(self, evt):
-        print 'Initiate transfer with ' + self.alias + self.q2qaddress
-
-    def addToMenu(self):
-        self.plug.section.append(self.menuItem)
-
-    def removeFromMenu(self):
-        self.plug.section.remove(self.menuItem)
-
-from twisted.plugin import IPlugin
-from prime.iprime import IMenuApplication
-from zope.interface import implements
-
-class PlugEntry:
-    implements(IMenuApplication, IPlugin)
-
-    def __init__(self):
-        self.xml = gtk.glade.XML(GLADE_FILE, "notification_popup")
-
-    def register(self, section):
-        print 'REGISTER'
-        self.section = section
-
-        workingdir = FilePath(os.path.expanduser("~/.vertex"))
-        self.clientService = ClientQ2QService(
-            workingdir.child("q2q-certificates").path,
-            verifyHook=self.displayVerifyDialog,
-            inboundTCPPortnum=8172,
-            # q2qPortnum=8173,
-            udpEnabled=False)
-        self.setCurrentID(self.clientService.getDefaultFrom())
-        self.buddiesfile = workingdir.child("q2q-buddies.txt")
-        self.loadedBuddies = {}
-        self.parseBuddies()
-
-    def parseBuddies(self):
-        try:
-            self.buddyList = rfc822.AddressList(self.buddiesfile.open().read())
-        except IOError:
-            return
-        self.clearContactMenu()
-        for dispn, addr in self.buddyList:
-            if addr not in self.loadedBuddies:
-                BuddyItem(self, dispn, addr)
-        self.buildContactMenu()
-
-    def clearContactMenu(self):
-        for bud in self.loadedBuddies.values():
-            bud.removeFromMenu()
-
-    def buildContactMenu(self):
-        l = self.loadedBuddies.values()
-        l.sort(key=lambda x: x.alias)
-        l.reverse()
-        for bud in l:
-            bud.addToMenu()
-
-    def addBuddy(self, alias, q2qaddr):
-        temp = self.buddiesfile.temporarySibling()
-        try:
-            origdata = self.buddiesfile.open().read()
-        except IOError:
-            origdata = ''
-        moredata = '\n%s <%s>' % (alias, q2qaddr)
-        ftemp = temp.open('w')
-        ftemp.write(origdata)
-        ftemp.write(moredata)
-        ftemp.close()
-        temp.moveTo(self.buddiesfile)
-        self.parseBuddies()
-
-    def displayVerifyDialog(self, From, to, protocol):
-        from twisted.internet import defer
-        d = defer.Deferred()
-        AcceptConnectionDialog(d, From, to, protocol)
-        return d
-
-    def setCurrentID(self, idName):
-
-        if idName is not None:
-            currentID = Q2QAddress.fromString(idName)
-            # log in?
-            # self.animator.start()
-            SL = self.xml.get_widget("identifymenuitem").get_children()[0].set_label
-            def loggedIn(result):
-                SL(str(currentID))
-                self.currentID = currentID
-            def notLoggedIn(error):
-                SL("Identify")
-                # self.animator.stop(0)
-            # This following order is INSANE - you should definitely not have
-            # to wait until the LISTEN succeeds to start the service; quite the
-            # opposite, you should wait until the service has started, then
-            # issue the LISTEN!! For some reason, the connection drops
-            # immediately if you do that, and I have no idea why.  As soon as I
-            # can fix that issue the startService should be moved up previous
-            # to listenQ2Q.
-            self.clientService.listenQ2Q(currentID,
-                                         {'vertex': VertexFactory(self)},
-                                         "desktop vertex UI").addCallbacks(
-                loggedIn, notLoggedIn).addCallback(
-                lambda ign: self.clientService.startService())
-
-    # XXX event handlers
-
-    def toggleAnimate(self, event):
-        if self.animator.animating:
-            # SL("Animate")
-            self.animator.stop()
-        else:
-            # SL("Stop Animating")
-            self.animator.start()
-
-    def identifyDialog(self, event):
-        IdentificationDialog(self.clientService, self)
-
-    def addContact(self, event):
-        AddContactDialog(self)

=== removed file 'Vertex/vertex/icon-active.png'
Binary files Vertex/vertex/icon-active.png	2006-06-01 04:57:02 +0000 and Vertex/vertex/icon-active.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'Vertex/vertex/icon-inactive.png'
Binary files Vertex/vertex/icon-inactive.png	2006-06-01 04:57:02 +0000 and Vertex/vertex/icon-inactive.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'Vertex/vertex/ivertex.py'
--- Vertex/vertex/ivertex.py	2012-03-14 16:23:22 +0000
+++ Vertex/vertex/ivertex.py	1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from zope.interface import Interface
-
-class IQ2QTransport(Interface):
-    """
-    I am a byte-stream-oriented transport which has Q2Q identifiers associated
-    with the endpoints, and possibly some cryptographic verification of the
-    authenticity of those endpoints.
-    """
-
-    def getQ2QHost():
-        """ Returns a Q2QAddress object representing the user on this end of the
-        connection.
-        """
-
-    def getQ2QPeer():
-        """ Returns a Q2QAddress object representing the user on the other end of the
-        connection.
-        """
-
-class IQ2QUser(Interface):
-    """
-    A cred interface for Q2Q users.
-    """
-    def signCertificateRequest(certificateRequest, domainCert, suggestedSerial):
-        """
-        Return a signed certificate object if the subject fields in the
-        certificateRequest are valid.
-        """
-
-class IFileTransfer(Interface):
-
-    def getUploadSink(self, path):
-        """
-        @param path: a PathFragment that the client wishes to upload to.
-
-        @return: a DataSink where we'll save the data to.
-        """
-
-    def getDownloadSource(self, path):
-        """
-        @param path: a PathFragment that the client wishes to download.
-
-        @return: a DataSource to download data from.
-        """
-
-    def listChildren(self, path):
-        """
-        @param path: a PathFragment that the client wishes to get a list of.
-
-        @return: a list of dictionaries mapping::
-            {'name': str,
-             'size': int,
-             'type': vertex.filexfer.MIMEType,
-             'modified': datetime.datetime}
-        """
-
-class ISessionTokenStorage(Interface):
-    def idFromCookie(self, cookie, domain):
-        """Look up a user ID from the given cookie in the given domain.
-        """
-
-class ICertificateStorage(Interface):
-    def getSelfSignedCertificate(self, domainName):
-        """
-        @return: a Deferred which will fire with the certificate for the given
-        domain name.
-        """
-
-    def storeSelfSignedCertificate(self, domainName, mainCert):
-        """
-        @type mainCert: C{str}
-        @param mainCert: Serialized, self-signed certificate to associate
-        with the given domain.
-
-        @return: a Deferred which will fire when the certificate has been
-        stored successfully.
-        """
-
-    def getPrivateCertificate(self, domainName):
-        """
-        @return: a PrivateCertificate instance, e.g. a certificate including a
-        private key, for 'domainName'.
-        """
-
-    def addPrivateCertificate(self, domainName, existingCertificate=None):
-        """
-        """
-
-class IOfferUp(Interface):
-    """
-    Sharing control database storage.
-    """
-
-class IPlugin(Interface):
-    """
-    """
-
-class ITestPlugin(Interface):
-    """
-    Dummy plug-in interface for unit testing.
-    """
-
-class ITestPlugin2(Interface):
-    """
-    Dummy plug-in interface for unit testing.
-    """

=== removed file 'Vertex/vertex/ptcp.py'
--- Vertex/vertex/ptcp.py	2012-03-14 16:23:22 +0000
+++ Vertex/vertex/ptcp.py	1970-01-01 00:00:00 +0000
@@ -1,1050 +0,0 @@
-# -*- test-case-name: vertex.test.test_ptcp -*-
-
-import struct
-
-from binascii import crc32  # used to use zlib.crc32 - but that gives different
-                            # results on 64-bit platforms!!
-
-import itertools
-
-from twisted.python.failure import Failure
-from twisted.internet.defer import Deferred
-from twisted.internet import protocol, error, reactor, defer
-from twisted.internet.main import CONNECTION_DONE
-from twisted.python import log, util
-
-from vertex import tcpdfa
-from vertex.statemachine import StateError
-
-
-genConnID = itertools.count(8).next
-
-MAX_PSEUDO_PORT = (2 ** 16)
-
-_packetFormat = ('!' # WTF did you think
-                 'H' # sourcePseudoPort
-                 'H' # destPseudoPort
-                 'L' # sequenceNumber
-                 'L' # acknowledgementNumber
-                 'L' # window
-                 'B' # flags
-                 'l' # checksum
-                     # (signed because of binascii.crc32)
-                 'H' # dlen
-                 )
-_fixedSize = struct.calcsize(_packetFormat)
-
-_SYN, _ACK, _FIN, _RST, _STB = [1 << n for n in range(5)]
-
-def _flagprop(flag):
-    def setter(self, value):
-        if value:
-            self.flags |= flag
-        else:
-            self.flags &= ~flag
-    return property(lambda self: bool(self.flags & flag), setter)
-
-def relativeSequence(wireSequence, initialSequence, lapNumber):
-    """ Compute a relative sequence number from a wire sequence number so that we
-    can use natural Python comparisons on it, such as <, >, ==.
-
-    @param wireSequence: the sequence number received on the wire.
-
-    @param initialSequence: the ISN for this sequence, negotiated at SYN time.
-
-    @param lapNumber: the number of times that this value has wrapped around
-    2**32.
-    """
-    return (wireSequence + (lapNumber * (2**32))) - initialSequence
-
-class PTCPPacket(util.FancyStrMixin, object):
-    showAttributes = (
-        ('sourcePseudoPort', 'sourcePseudoPort', '%d'),
-        ('destPseudoPort', 'destPseudoPort', '%d'),
-        ('shortdata', 'data', '%r'),
-        ('niceflags', 'flags', '%s'),
-        ('dlen', 'dlen', '%d'),
-        ('seqNum', 'seq', '%d'),
-        ('ackNum', 'ack', '%d'),
-        ('checksum', 'checksum', '%x'),
-        ('peerAddressTuple', 'peerAddress', '%r'),
-        ('retransmitCount', 'retransmitCount', '%d'),
-        )
-
-    syn = _flagprop(_SYN)
-    ack = _flagprop(_ACK)
-    fin = _flagprop(_FIN)
-    rst = _flagprop(_RST)
-    stb = _flagprop(_STB)
-
-    # Number of retransmit attempts left for this segment.  When it reaches
-    # zero, this segment is dead.
-    retransmitCount = 50
-
-    def shortdata():
-        def get(self):
-            if len(self.data) > 13:
-                return self.data[:5] + '...' + self.data[-5:]
-            else:
-                return self.data
-        return get,
-    shortdata = property(*shortdata())
-
-    def niceflags():
-        def get(self):
-            res = []
-            for (f, v) in [
-                (self.syn, 'S'), (self.ack, 'A'), (self.fin, 'F'),
-                (self.rst, 'R'), (self.stb, 'T')]:
-                res.append(f and v or '.')
-            return ''.join(res)
-        return get,
-    niceflags = property(*niceflags())
-
-    def create(cls,
-               sourcePseudoPort, destPseudoPort,
-               seqNum, ackNum, data,
-               window=(1 << 15),
-               syn=False, ack=False, fin=False,
-               rst=False, stb=False,
-               destination=None):
-        i = cls(sourcePseudoPort, destPseudoPort,
-                seqNum, ackNum, window,
-                0, 0, len(data), data)
-        i.syn = syn
-        i.ack = ack
-        i.fin = fin
-        i.rst = rst
-        i.stb = stb
-        i.checksum = i.computeChecksum()
-        i.destination = destination
-        return i
-    create = classmethod(create)
-
-
-    def __init__(self,
-                 sourcePseudoPort,
-                 destPseudoPort,
-                 seqNum, ackNum, window, flags,
-                 checksum, dlen, data, peerAddressTuple=None,
-                 seqOffset=0, ackOffset=0, seqLaps=0, ackLaps=0):
-        self.sourcePseudoPort = sourcePseudoPort
-        self.destPseudoPort = destPseudoPort
-        self.seqNum = seqNum
-        self.ackNum = ackNum
-        self.window = window
-        self.flags = flags
-        self.checksum = checksum
-        self.dlen = dlen
-        self.data = data
-        self.peerAddressTuple = peerAddressTuple # None if local
-
-        self.seqOffset = seqOffset
-        self.ackOffset = ackOffset
-        self.seqLaps = seqLaps
-        self.ackLaps = ackLaps
-
-    def segmentLength(self):
-        """RFC page 26: 'The segment length (SEG.LEN) includes both data and sequence
-        space occupying controls'
-        """
-        return self.dlen + self.syn + self.fin
-
-    def relativeSeq(self):
-        return relativeSequence(self.seqNum, self.seqOffset, self.seqLaps)
-
-    def relativeAck(self):
-        return relativeSequence(self.ackNum, self.ackOffset, self.ackLaps)
-
-
-    def verifyChecksum(self):
-        if len(self.data) != self.dlen:
-            if len(self.data) > self.dlen:
-                raise GarbageDataError(self)
-            else:
-                raise TruncatedDataError(self)
-        expected = self.computeChecksum()
-        received = self.checksum
-        if expected != received:
-            raise ChecksumMismatchError(expected, received)
-
-    def computeChecksum(self):
-        return crc32(self.data)
-
-    def decode(cls, bytes, hostPortPair):
-        fields = struct.unpack(_packetFormat, bytes[:_fixedSize])
-        sourcePseudoPort, destPseudoPort, seq, ack, window, flags, checksum, dlen = fields
-        data = bytes[_fixedSize:]
-        pkt = cls(sourcePseudoPort, destPseudoPort, seq, ack, window, flags,
-                  checksum, dlen, data, hostPortPair)
-        return pkt
-    decode = classmethod(decode)
-
-    def mustRetransmit(self):
-        """Check to see if this packet must be retransmitted until it was received.
-        """
-        if self.syn or self.fin or self.dlen:
-            return True
-        return False
-
-    def encode(self):
-        dlen = len(self.data)
-        checksum = self.computeChecksum()
-        return struct.pack(
-            _packetFormat,
-            self.sourcePseudoPort, self.destPseudoPort,
-            self.seqNum, self.ackNum, self.window,
-            self.flags, checksum, dlen) + self.data
-
-    def fragment(self, mtu):
-        if self.dlen < mtu:
-            return [self]
-        assert not self.syn, "should not be originating syn packets w/ data"
-        seqOfft = 0
-        L = []
-        # XXX TODO: need to take seqLaps into account, etc.
-        for chunk in iterchunks(self.data, mtu):
-            last = self.create(self.sourcePseudoPort,
-                               self.destPseudoPort,
-                               self.seqNum + seqOfft,
-                               self.ackNum,
-                               chunk,
-                               self.window,
-                               destination=self.destination,
-                               ack=self.ack)
-            L.append(last)
-            seqOfft += len(chunk)
-        if self.fin:
-            last.fin = self.fin
-            last.checksum = last.computeChecksum()
-        return L
-
-
-def iterchunks(data, chunksize):
-    """iterate chunks of data
-    """
-    offt = 0
-    while offt < len(data):
-        yield data[offt:offt+chunksize]
-        offt += chunksize
-
-
-def ISN():
-    """
-    Initial Sequence Number generator.
-    """
-    # return int((time.time() * 1000000) / 4) % 2**32
-    return 0
-
-
-def segmentAcceptable(RCV_NXT, RCV_WND, SEG_SEQ, SEG_LEN):
-    # RFC page 26.
-    if SEG_LEN == 0 and RCV_WND == 0:
-        return SEG_SEQ == RCV_NXT
-    if SEG_LEN == 0 and RCV_WND > 0:
-        return ((RCV_NXT <= SEG_SEQ) and (SEG_SEQ < RCV_NXT + RCV_WND))
-    if SEG_LEN > 0 and RCV_WND == 0:
-        return False
-    if SEG_LEN > 0 and RCV_WND > 0:
-        return ((  (RCV_NXT <= SEG_SEQ) and (SEG_SEQ < RCV_NXT + RCV_WND))
-                or ((RCV_NXT <= SEG_SEQ+SEG_LEN-1) and
-                    (SEG_SEQ+SEG_LEN-1 < RCV_NXT + RCV_WND)))
-    assert 0, 'Should be impossible to get here.'
-    return False
-
-class BadPacketError(Exception):
-    """
-    A packet was bad for some reason.
-    """
-
-class ChecksumMismatchError(Exception):
-    """
-    The checksum and data received did not match.
-    """
-
-class TruncatedDataError(Exception):
-    """
-    The packet was truncated in transit, and all of the data did not arrive.
-    """
-
-class GarbageDataError(Exception):
-    """
-    Too much data was received (???)
-    """
-
-class PTCPConnection(tcpdfa.TCP):
-    """
-    Implementation of RFC 793 state machine.
-
-    @ivar oldestUnackedSendSeqNum: (TCP RFC: SND.UNA) The oldest (relative)
-    sequence number referring to an octet which we have sent or may send which
-    is unacknowledged.  This begins at 0, which is special because it is not
-    for an octet, but rather for the initial SYN packet.  Unless it is 0, this
-    represents the sequence number of self._outgoingBytes[0].
-
-    @ivar nextSendSeqNum: (TCP RFC: SND.NXT) The next (relative) sequence
-    number that we will send to our peer after the current buffered segments
-    have all been acknowledged.  This is the sequence number of the
-    not-yet-extant octet in the stream at
-    self._outgoingBytes[len(self._outgoingBytes)].
-
-    @ivar nextRecvSeqNum: (TCP RFC: RCV.NXT) The next (relative) sequence
-    number that the peer should send to us if they want to send more data;
-    their first unacknowledged sequence number as far as we are concerned; the
-    left or lower edge of the receive window; the sequence number of the first
-    octet that has not been delivered to the application.  changed whenever we
-    receive an appropriate ACK.
-
-    @ivar peerSendISN: the initial sequence number that the peer sent us during
-    the negotiation phase.  All peer-relative sequence numbers are computed
-    using this.  (see C{relativeSequence}).
-
-    @ivar hostSendISN: the initial sequence number that the we sent during the
-    negotiation phase.  All host-relative sequence numbers are computed using
-    this.  (see C{relativeSequence})
-
-    @ivar retransmissionQueue: a list of packets to be re-sent until their
-    acknowledgements come through.
-
-    @ivar recvWindow: (TCP RFC: RCV.WND) - the size [in octets] of the current
-    window allowed by this host, to be in transit from the other host.
-
-    @ivar sendWindow: (TCP RFC: SND.WND) - the size [in octets] of the current
-    window allowed by our peer, to be in transit from us.
-
-    """
-
-    mtu = 512 - _fixedSize
-
-    recvWindow = mtu
-    sendWindow = mtu
-    sendWindowRemaining = mtu * 2
-
-    protocol = None
-
-    def __init__(self,
-                 hostPseudoPort, peerPseudoPort,
-                 ptcp, factory, peerAddressTuple):
-        tcpdfa.TCP.__init__(self)
-        self.hostPseudoPort = hostPseudoPort
-        self.peerPseudoPort = peerPseudoPort
-        self.ptcp = ptcp
-        self.factory = factory
-        self._receiveBuffer = []
-        self.retransmissionQueue = []
-        self.peerAddressTuple = peerAddressTuple
-
-        self.oldestUnackedSendSeqNum = 0
-        self.nextSendSeqNum = 0
-        self.hostSendISN = 0
-        self.nextRecvSeqNum = 0
-        self.peerSendISN = 0
-        self.setPeerISN = False
-
-    peerSendISN = None
-
-    def packetReceived(self, packet):
-        # XXX TODO: probably have to do something to the packet here to
-        # identify its relative sequence number.
-
-        # print 'received', self, packet
-
-        if packet.stb:
-            # Shrink the MTU
-            [self.mtu] = struct.unpack('!H', packet.data)
-            rq = []
-            for pkt in self.retransmissionQueue:
-                rq.extend(pkt.fragment(self.mtu))
-            self.retransmissionQueue = rq
-            return
-
-        if self._paused:
-            return
-
-        generatedStateMachineInput = False
-        if packet.syn:
-            if packet.dlen:
-                # Whoops, what?  SYNs probably can contain data, I think, but I
-                # certainly don't see anything in the spec about how to deal
-                # with this or in ethereal for how linux deals with it -glyph
-                raise BadPacketError(
-                    "currently no data allowed in SYN packets: %r"
-                    % (packet,))
-            else:
-                assert packet.segmentLength() == 1
-            if self.peerAddressTuple is None:
-                # we're a server
-                assert self.wasEverListen, "Clients must specify a connect address."
-                self.peerAddressTuple = packet.peerAddressTuple
-            else:
-                # we're a client
-                assert self.peerAddressTuple == packet.peerAddressTuple
-            if self.setPeerISN:
-                if self.peerSendISN != packet.seqNum:
-                    raise BadPacketError(
-                        "Peer ISN was already set to %s but incoming packet "
-                        "tried to set it to %s" % (
-                            self.peerSendISN, packet.seqNum))
-                if not self.retransmissionQueue:
-                    # If our retransmissionQueue is hot, we are going to send
-                    # them an ACK to this with the next packet we send them
-                    # anyway; as a bonus, this will properly determine whether
-                    # we're sending a SYN+ACK or merely an ACK; the only time
-                    # we send an ACK is when we have nothing to say to them and
-                    # they're blocked on getting a response to their SYN+ACK
-                    # from us. -glyph
-                    self.originate(ack=True)
-                return
-            self.setPeerISN = True
-            self.peerSendISN = packet.seqNum
-            # syn, fin, and data are mutually exclusive, so this relative
-            # sequence-number increment is done both here, and below in the
-            # data/fin processing block.
-            self.nextRecvSeqNum += packet.segmentLength()
-            if not packet.ack:
-                generatedStateMachineInput = True
-                self.input(tcpdfa.SYN)
-
-        SEG_ACK = packet.relativeAck() # aliasing this for easier reading w/
-                                       # the RFC
-        if packet.ack:
-            if (self.oldestUnackedSendSeqNum < SEG_ACK and
-                SEG_ACK <= self.nextSendSeqNum):
-                # According to the spec, an 'acceptable ack
-                rq = self.retransmissionQueue
-                while rq:
-                    segmentOnQueue = rq[0]
-                    qSegSeq = segmentOnQueue.relativeSeq()
-                    if qSegSeq + segmentOnQueue.segmentLength() <= SEG_ACK:
-                        # fully acknowledged, as per RFC!
-                        rq.pop(0)
-                        sminput = None
-                        self.sendWindowRemaining += segmentOnQueue.segmentLength()
-                        # print 'inc send window', self, self.sendWindowRemaining
-                        if segmentOnQueue.syn:
-                            if packet.syn:
-                                sminput = tcpdfa.SYN_ACK
-                            else:
-                                sminput = tcpdfa.ACK
-                        elif segmentOnQueue.fin:
-                            sminput = tcpdfa.ACK
-                        if sminput is not None:
-                            # print 'ack input:', segmentOnQueue, packet, sminput
-                            generatedStateMachineInput = True
-                            self.input(sminput)
-                    else:
-                        break
-                else:
-                    # write buffer is empty; alert the application layer.
-                    self._writeBufferEmpty()
-                self.oldestUnackedSendSeqNum = SEG_ACK
-
-        if packet.syn:
-            assert generatedStateMachineInput
-            return
-
-        # XXX TODO: examine 'window' field and adjust sendWindowRemaining
-        # is it 'occupying a portion of valid receive sequence space'?  I think
-        # this means 'packet which might acceptably contain useful data'
-        if not packet.segmentLength():
-            assert packet.ack, "What the _HELL_ is wrong with this packet:" +str(packet)
-            return
-
-        if not segmentAcceptable(self.nextRecvSeqNum,
-                                 self.recvWindow,
-                                 packet.relativeSeq(),
-                                 packet.segmentLength()):
-            # We have to transmit an ack here since it's old data.  We probably
-            # need to ack in more states than just ESTABLISHED... but which
-            # ones?
-            if not self.retransmissionQueue:
-                self.originate(ack=True)
-            return
-
-        # OK!  It's acceptable!  Let's process the various bits of data.
-        # Where is the useful data in the packet?
-        if packet.relativeSeq() > self.nextRecvSeqNum:
-            # XXX: Here's what's going on.  Data can be 'in the window', but
-            # still in the future.  For example, if I have a window of length 3
-            # and I send segments DATA1(len 1) DATA2(len 1) FIN and you receive
-            # them in the order FIN DATA1 DATA2, you don't actually want to
-            # process the FIN until you've processed the data.
-
-            # For the moment we are just dropping anything that isn't exactly
-            # the next thing we want to process.  This is perfectly valid;
-            # these packets might have been dropped, so the other end will have
-            # to retransmit them anyway.
-            return
-
-        if packet.dlen:
-            assert not packet.syn, 'no seriously I _do not_ know how to handle this'
-            usefulData = packet.data[self.nextRecvSeqNum - packet.relativeSeq():]
-            # DONT check/slice the window size here, the acceptability code
-            # checked it, we can over-ack if the other side is buggy (???)
-            if self.protocol is not None:
-                try:
-                    self.protocol.dataReceived(usefulData)
-                except:
-                    log.err()
-                    self.loseConnection()
-
-        self.nextRecvSeqNum += packet.segmentLength()
-        if self.state == tcpdfa.ESTABLISHED:
-            # In all other states, the state machine takes care of sending ACKs
-            # in its output process.
-            self.originate(ack=True)
-
-        if packet.fin:
-            self.input(tcpdfa.FIN)
-
-
-    def getHost(self):
-        tupl = self.ptcp.transport.getHost()
-        return PTCPAddress((tupl.host, tupl.port),
-                           self.pseudoPortPair)
-
-    def getPeer(self):
-        return PTCPAddress(self.peerAddressTuple,
-                           self.pseudoPortPair)
-
-    _outgoingBytes = ''
-    _nagle = None
-
-    def write(self, bytes):
-        assert not self.disconnected, 'Writing to a transport that was already disconnected.'
-        self._outgoingBytes += bytes
-        self._writeLater()
-
-
-    def writeSequence(self, seq):
-        self.write(''.join(seq))
-
-
-    def _writeLater(self):
-        if self._nagle is None:
-            self._nagle = reactor.callLater(0.001, self._reallyWrite)
-
-    def _originateOneData(self):
-        amount = min(self.sendWindowRemaining, self.mtu)
-        sendOut = self._outgoingBytes[:amount]
-        # print 'originating data packet', len(sendOut)
-        self._outgoingBytes = self._outgoingBytes[amount:]
-        self.sendWindowRemaining -= len(sendOut)
-        self.originate(ack=True, data=sendOut)
-
-    def _reallyWrite(self):
-        # print self, 'really writing', self._paused
-        self._nagle = None
-        if self._outgoingBytes:
-            # print 'window and bytes', self.sendWindowRemaining, len(self._outgoingBytes)
-            while self.sendWindowRemaining and self._outgoingBytes:
-                self._originateOneData()
-
-    _retransmitter = None
-    _retransmitTimeout = 0.5
-
-    def _retransmitLater(self):
-        assert self.state != tcpdfa.CLOSED
-        if self._retransmitter is None:
-            self._retransmitter = reactor.callLater(self._retransmitTimeout, self._reallyRetransmit)
-
-    def _stopRetransmitting(self):
-        # used both as a quick-and-dirty test shutdown hack and a way to shut
-        # down when we die...
-        if self._retransmitter is not None:
-            self._retransmitter.cancel()
-            self._retransmitter = None
-        if self._nagle is not None:
-            self._nagle.cancel()
-            self._nagle = None
-        if self._closeWaitLoseConnection is not None:
-            self._closeWaitLoseConnection.cancel()
-            self._closeWaitLoseConnection = None
-
-    def _reallyRetransmit(self):
-        # XXX TODO: packet fragmentation & coalescing.
-        # print 'Wee a retransmit!  What I got?', self.retransmissionQueue
-        self._retransmitter = None
-        if self.retransmissionQueue:
-            for packet in self.retransmissionQueue:
-                packet.retransmitCount -= 1
-                if packet.retransmitCount:
-                    packet.ackNum = self.currentAckNum()
-                    self.ptcp.sendPacket(packet)
-                else:
-                    self.input(tcpdfa.TIMEOUT)
-                    return
-            self._retransmitLater()
-
-    disconnecting = False       # This is *TWISTED* level state-machine stuff,
-                                # not TCP-level.
-
-    def loseConnection(self):
-        if not self.disconnecting:
-            self.disconnecting = True
-            if not self._outgoingBytes:
-                self._writeBufferEmpty()
-
-
-    def _writeBufferEmpty(self):
-        if self._outgoingBytes:
-            self._reallyWrite()
-        elif self.producer is not None:
-            if (not self.streamingProducer) or self.producerPaused:
-                self.producerPaused = False
-                self.producer.resumeProducing()
-        elif self.disconnecting and (not self.disconnected
-                                     or self.state == tcpdfa.CLOSE_WAIT):
-            self.input(tcpdfa.APP_CLOSE)
-
-
-    def _writeBufferFull(self):
-        # print 'my write buffer is full'
-        if (self.producer is not None
-            and not self.producerPaused):
-            self.producerPaused = True
-            # print 'producer pausing'
-            self.producer.pauseProducing()
-            # print 'producer paused'
-        else:
-            # print 'but I am not telling my producer to pause!'
-            # print '  ', self.producer, self.streamingProducer, self.producerPaused
-            pass
-
-
-    disconnected = False
-    producer = None
-    producerPaused = False
-    streamingProducer = False
-
-    def registerProducer(self, producer, streaming):
-        if self.producer is not None:
-            raise RuntimeError(
-                "Cannot register producer %s, "
-                "because producer %s was never unregistered."
-                % (producer, self.producer))
-        if self.disconnected:
-            producer.stopProducing()
-        else:
-            self.producer = producer
-            self.streamingProducer = streaming
-            if not streaming and not self._outgoingBytes:
-                producer.resumeProducing()
-
-    def unregisterProducer(self):
-        self.producer = None
-        if not self._outgoingBytes:
-            self._writeBufferEmpty()
-
-    _paused = False
-    def pauseProducing(self):
-        self._paused = True
-
-    def resumeProducing(self):
-        self._paused = False
-
-    def currentAckNum(self):
-        return (self.nextRecvSeqNum + self.peerSendISN) % (2**32)
-
-    def originate(self, data='', syn=False, ack=False, fin=False):
-        if syn:
-            # We really should be randomizing the ISN but until we finish the
-            # implementations of the various bits of wraparound logic that were
-            # started with relativeSequence
-            assert self.nextSendSeqNum == 0
-            assert self.hostSendISN == 0
-        p = PTCPPacket.create(self.hostPseudoPort,
-                              self.peerPseudoPort,
-                              seqNum=(self.nextSendSeqNum + self.hostSendISN) % (2**32),
-                              ackNum=self.currentAckNum(),
-                              data=data,
-                              window=self.recvWindow,
-                              syn=syn, ack=ack, fin=fin,
-                              destination=self.peerAddressTuple)
-        # do we want to enqueue this packet for retransmission?
-        sl = p.segmentLength()
-        self.nextSendSeqNum += sl
-
-        if p.mustRetransmit():
-            # print self, 'originating retransmittable packet', len(self.retransmissionQueue)
-            if self.retransmissionQueue:
-                if self.retransmissionQueue[-1].fin:
-                    raise AssertionError("Sending %r after FIN??!" % (p,))
-            # print 'putting it on the queue'
-            self.retransmissionQueue.append(p)
-            # print 'and sending it later'
-            self._retransmitLater()
-            if not self.sendWindowRemaining: # len(self.retransmissionQueue) > 5:
-                # print 'oh no my queue is too big'
-                # This is a random number (5) because I ought to be summing the
-                # packet lengths or something.
-                self._writeBufferFull()
-            else:
-                # print 'my queue is still small enough', len(self.retransmissionQueue), self, self.sendWindowRemaining
-                pass
-        self.ptcp.sendPacket(p)
-
-    # State machine transition definitions, hooray.
-    def transition_SYN_SENT_to_CLOSED(self):
-        """
-        The connection never got anywhere.  Goodbye.
-        """
-        # XXX CONNECTOR API OMFG
-        self.factory.clientConnectionFailed(None, error.TimeoutError())
-
-
-    wasEverListen = False
-
-    def enter_LISTEN(self):
-        # Spec says this is necessary for RST handling; we need it for making
-        # sure it's OK to bind port numbers.
-        self.wasEverListen = True
-
-    def enter_CLOSED(self):
-        self.ptcp.connectionClosed(self)
-        self._stopRetransmitting()
-        if self._timeWaitCall is not None:
-            self._timeWaitCall.cancel()
-            self._timeWaitCall = None
-
-    _timeWaitCall = None
-    _timeWaitTimeout = 0.01     # REALLY fast timeout, right now this is for
-                                # the tests...
-
-    def enter_TIME_WAIT(self):
-        self._stopRetransmitting()
-        self._timeWaitCall = reactor.callLater(self._timeWaitTimeout, self._do2mslTimeout)
-
-    def _do2mslTimeout(self):
-        self._timeWaitCall = None
-        self.input(tcpdfa.TIMEOUT)
-
-    peerAddressTuple = None
-
-    def transition_LISTEN_to_SYN_SENT(self):
-        """
-        Uh, what?  We were listening and we tried to send some bytes.
-        This is an error for PTCP.
-        """
-        raise StateError("You can't write anything until someone connects to you.")
-
-#     def invalidInput(self, datum):
-#         print self, self.protocol, 'invalid input', datum
-
-    def pseudoPortPair():
-        def get(self):
-            return (self.hostPseudoPort,
-                    self.peerPseudoPort)
-        return get,
-    pseudoPortPair = property(*pseudoPortPair())
-
-    def enter_ESTABLISHED(self):
-        """
-        We sent out SYN, they acknowledged it.  Congratulations, you
-        have a new baby connection.
-        """
-        assert not self.disconnecting
-        assert not self.disconnected
-        try:
-            p = self.factory.buildProtocol(PTCPAddress(
-                    self.peerAddressTuple, self.pseudoPortPair))
-            p.makeConnection(self)
-        except:
-            log.msg("Exception during PTCP connection setup.")
-            log.err()
-            self.loseConnection()
-        else:
-            self.protocol = p
-
-    def exit_ESTABLISHED(self):
-        assert not self.disconnected
-        self.disconnected = True
-        try:
-            self.protocol.connectionLost(Failure(CONNECTION_DONE))
-        except:
-            log.err()
-        self.protocol = None
-
-        if self.producer is not None:
-            try:
-                self.producer.stopProducing()
-            except:
-                log.err()
-            self.producer = None
-
-
-    _closeWaitLoseConnection = None
-
-    def enter_CLOSE_WAIT(self):
-        # Twisted automatically reacts to network half-close by issuing a full
-        # close.
-        self._closeWaitLoseConnection = reactor.callLater(0.01, self._loseConnectionBecauseOfCloseWait)
-
-    def _loseConnectionBecauseOfCloseWait(self):
-        self._closeWaitLoseConnection = None
-        self.loseConnection()
-
-    def immediateShutdown(self):
-        """_IMMEDIATELY_ shut down this connection, sending one (non-retransmitted)
-        app-close packet, emptying our buffers, clearing our producer and
-        getting ready to die right after this call.
-        """
-        self._outgoingBytes = ''
-        if self.state == tcpdfa.ESTABLISHED:
-            self.input(tcpdfa.APP_CLOSE)
-            self._stopRetransmitting()
-            self._reallyRetransmit()
-
-        # All states that we can reasonably be in handle a timeout; force our
-        # connection to think that it's become desynchronized with the other
-        # end so that it will totally shut itself down.
-
-        self.input(tcpdfa.TIMEOUT)
-        assert self._retransmitter is None
-        assert self._nagle is None
-
-    def output_ACK(self):
-        self.originate(ack=True)
-
-    def output_FIN(self):
-        self.originate(fin=True)
-
-    def output_SYN_ACK(self):
-        self.originate(syn=True, ack=True)
-
-    def output_SYN(self):
-        self.originate(syn=True)
-
-class PTCPAddress(object):
-    # garbage
-
-    def __init__(self, (host, port), (pseudoHostPort, pseudoPeerPort)):
-        self.host = host
-        self.port = port
-        self.pseudoHostPort = pseudoHostPort
-        self.pseudoPeerPort = pseudoPeerPort
-
-    def __repr__(self):
-        return 'PTCPAddress((%r, %r), (%r, %r))' % (
-            self.host, self.port,
-            self.pseudoHostPort,
-            self.pseudoPeerPort)
-
-
-
-class _PendingEvent(object):
-    def __init__(self):
-        self.listeners = []
-
-
-    def deferred(self):
-        d = Deferred()
-        self.listeners.append(d)
-        return d
-
-
-    def callback(self, result):
-        l = self.listeners
-        self.listeners = []
-        for d in l:
-            d.callback(result)
-
-
-    def errback(self, result=None):
-        if result is None:
-            result = Failure()
-        l = self.listeners
-        self.listeners = []
-        for d in l:
-            d.errback(result)
-
-
-
-class PTCP(protocol.DatagramProtocol):
-    """
-    L{PTCP} implements a strongly TCP-like protocol on top of UDP.  It
-    provides a transport which is connection-oriented, streaming,
-    ordered, and reliable.
-
-    @ivar factory: A L{ServerFactory} which is used to create
-        L{IProtocol} providers whenever a new PTCP connection is made
-        to this port.
-
-    @ivar _connections: A mapping of endpoint addresses to connection
-        objects.  These are the active connections being multiplexed
-        over this UDP port.  Many PTCP connections may run over the
-        same L{PTCP} instance, communicating with many different
-        remote hosts as well as multiplexing different PTCP
-        connections to the same remote host.  The mapping keys,
-        endpoint addresses, are three-tuples of:
-
-            - The destination pseudo-port which is always C{1}
-            - The source pseudo-port
-            - A (host, port) tuple giving the UDP address of a PTCP
-              peer holding the other side of the connection
-
-        The mapping values, connection objects, are L{PTCPConnection}
-        instances.
-    @type _connections: C{dict}
-
-    """
-    # External API
-
-    def __init__(self, factory):
-        self.factory = factory
-        self._allConnectionsClosed = _PendingEvent()
-
-
-    def connect(self, factory, host, port, pseudoPort=1):
-        """
-        Attempt to establish a new connection via PTCP to the given
-        remote address.
-
-        @param factory: A L{ClientFactory} which will be used to
-            create an L{IProtocol} provider if the connection is
-            successfully set up, or which will have failure callbacks
-            invoked on it otherwise.
-
-        @param host: The IP address of another listening PTCP port to
-            connect to.
-        @type host: C{str}
-
-        @param port: The port number of that other listening PTCP port
-            to connect to.
-        @type port: C{int}
-
-        @param pseudoPort: Not really implemented.  Do not pass a
-            value for this parameter or things will break.
-
-        @return: A L{PTCPConnection} instance representing the new
-            connection, but you really shouldn't use this for
-            anything.  Write a protocol!
-        """
-        sourcePseudoPort = genConnID() % MAX_PSEUDO_PORT
-        conn = self._connections[(pseudoPort, sourcePseudoPort, (host, port))
-                                 ] = PTCPConnection(
-            sourcePseudoPort, pseudoPort, self, factory, (host, port))
-        conn.input(tcpdfa.APP_ACTIVE_OPEN)
-        return conn
-
-    def sendPacket(self, packet):
-        if self.transportGoneAway:
-            return
-        self.transport.write(packet.encode(), packet.destination)
-
-
-    # Internal stuff
-    def startProtocol(self):
-        self.transportGoneAway = False
-        self._lastConnID = 10 # random.randrange(2 ** 32)
-        self._connections = {}
-
-    def _finalCleanup(self):
-        """
-        Clean up all of our connections by issuing application-level close and
-        stop notifications, sending hail-mary final FIN packets (which may not
-        reach the other end, but nevertheless can be useful) when possible.
-        """
-        for conn in self._connections.values():
-            conn.immediateShutdown()
-        assert not self._connections
-
-    def stopProtocol(self):
-        """
-        Notification from twisted that our underlying port has gone away;
-        make sure we're not going to try to send any packets through our
-        transport and blow up, then shut down all of our protocols, issuing
-        appr
-        opriate application-level messages.
-        """
-        self.transportGoneAway = True
-        self._finalCleanup()
-
-    def cleanupAndClose(self):
-        """
-        Clean up all remaining connections, then close our transport.
-
-        Although in a pinch we will do cleanup after our socket has gone away
-        (if it does so unexpectedly, above in stopProtocol), we would really
-        prefer to do cleanup while we still have access to a transport, since
-        that way we can force out a few final packets and save the remote
-        application an awkward timeout (if it happens to get through, which
-        is generally likely).
-        """
-        self._finalCleanup()
-        return self._stop()
-
-    def datagramReceived(self, bytes, addr):
-        if len(bytes) < _fixedSize:
-            # It can't be any good.
-            return
-
-        pkt = PTCPPacket.decode(bytes, addr)
-        try:
-            pkt.verifyChecksum()
-        except TruncatedDataError:
-#             print '(ptcp packet truncated: %r)' % (pkt,)
-            self.sendPacket(
-                PTCPPacket.create(
-                    pkt.destPseudoPort,
-                    pkt.sourcePseudoPort,
-                    0,
-                    0,
-                    struct.pack('!H', len(pkt.data)),
-                    stb=True,
-                    destination=addr))
-        except GarbageDataError:
-            print "garbage data!", pkt
-        except ChecksumMismatchError, cme:
-            print "bad checksum", pkt, cme
-            print repr(pkt.data)
-            print hex(pkt.checksum), hex(pkt.computeChecksum())
-        else:
-            self.packetReceived(pkt)
-
-    stopped = False
-    def _stop(self, result=None):
-        if not self.stopped:
-            self.stopped = True
-            return self.transport.stopListening()
-        else:
-            return defer.succeed(None)
-
-    def waitForAllConnectionsToClose(self):
-        """
-        Wait for all currently-open connections to enter the 'CLOSED' state.
-        Currently this is only usable from test fixtures.
-        """
-        if not self._connections:
-            return self._stop()
-        return self._allConnectionsClosed.deferred().addBoth(self._stop)
-
-    def connectionClosed(self, ptcpConn):
-        packey = (ptcpConn.peerPseudoPort, ptcpConn.hostPseudoPort,
-                  ptcpConn.peerAddressTuple)
-        del self._connections[packey]
-        if ((not self.transportGoneAway) and
-            (not self._connections) and
-            self.factory is None):
-            self._stop()
-        if not self._connections:
-            self._allConnectionsClosed.callback(None)
-
-    def packetReceived(self, packet):
-        packey = (packet.sourcePseudoPort, packet.destPseudoPort, packet.peerAddressTuple)
-        if packey not in self._connections:
-            if packet.flags == _SYN and packet.destPseudoPort == 1: # SYN and _ONLY_ SYN set.
-                conn = PTCPConnection(packet.destPseudoPort,
-                                      packet.sourcePseudoPort, self,
-                                      self.factory, packet.peerAddressTuple)
-                conn.input(tcpdfa.APP_PASSIVE_OPEN)
-                self._connections[packey] = conn
-            else:
-                log.msg("corrupted packet? %r %r %r" % (packet,packey, self._connections))
-                return
-        try:
-            self._connections[packey].packetReceived(packet)
-        except:
-            log.msg("PTCPConnection error on %r:" % (packet,))
-            log.err()
-            del self._connections[packey]

=== removed file 'Vertex/vertex/q2q.py'
--- Vertex/vertex/q2q.py	2012-03-14 23:42:53 +0000
+++ Vertex/vertex/q2q.py	1970-01-01 00:00:00 +0000
@@ -1,2763 +0,0 @@
-# -*- test-case-name: vertex.test.test_q2q -*-
-# Copyright 2005-2008 Divmod, Inc.  See LICENSE file for details
-
-"""
-I{Quotient to Quotient} protocol implementation.
-"""
-
-# stdlib
-import itertools
-from hashlib import md5
-import struct
-import datetime
-import time
-from collections import namedtuple
-
-from pprint import pformat
-
-from zope.interface import implements
-
-# twisted
-from twisted.internet import reactor, defer, interfaces, protocol, error
-from twisted.internet.main import CONNECTION_DONE
-from twisted.internet.ssl import (
-    CertificateRequest, Certificate, PrivateCertificate, KeyPair,
-    DistinguishedName)
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.application import service
-
-# twisted.cred
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.portal import IRealm, Portal
-from twisted.cred.credentials import IUsernamePassword, UsernamePassword
-from twisted.cred.error import UnauthorizedLogin
-
-from twisted.protocols.amp import Argument, Boolean, Integer, String, Unicode, ListOf, AmpList
-from twisted.protocols.amp import AmpBox, Command, StartTLS, ProtocolSwitchCommand, AMP
-from twisted.protocols.amp import _objectsToStrings
-
-# vertex
-from vertex import subproducer, ptcp
-from vertex import endpoint, ivertex
-from vertex.conncache import ConnectionCache
-
-MESSAGE_PROTOCOL = 'q2q-message'
-port = 8788
-
-class ConnectionError(Exception):
-    pass
-
-class AttemptsFailed(ConnectionError):
-    pass
-
-class NoAttemptsMade(ConnectionError):
-    pass
-
-class VerifyError(Exception):
-    pass
-
-class BadCertificateRequest(VerifyError):
-    pass
-
-class IgnoreConnectionFailed(protocol.ClientFactory):
-    def __init__(self, realFactory):
-        self.realFactory = realFactory
-
-    def clientConnectionLost(self, connector, reason):
-        self.realFactory.clientConnectionLost(connector, reason)
-
-    def clientConnectionFailed(self, connector, reason):
-        pass
-
-    def buildProtocol(self, addr):
-        return self.realFactory.buildProtocol(addr)
-
-class Q2QAddress(object):
-    def __init__(self, domain, resource=None):
-        self.resource = resource
-        self.domain = domain
-
-    def domainAddress(self):
-        """ Return an Address object which is the same as this one with ONLY the
-        'domain' attribute set, not 'resource'.
-
-        May return 'self' if 'resource' is already None.
-        """
-        if self.resource is None:
-            return self
-        else:
-            return Q2QAddress(self.domain)
-
-    def claimedAsIssuerOf(self, cert):
-        """
-        Check if the information in a provided certificate *CLAIMS* to be issued by
-        this address.
-
-        PLEASE NOTE THAT THIS METHOD IS IN NO WAY AUTHORITATIVE.  It does not
-        perform any cryptographic checks.
-
-        Currently this check is if L{Q2QAddress.__str__}C{(self)} is equivalent
-        to the commonName on the certificate's issuer.
-        """
-        return cert.getIssuer().commonName == str(self)
-
-    def claimedAsSubjectOf(self, cert):
-        """
-        Check if the information in a provided certificate *CLAIMS* to be
-        provided for use by this address.
-
-        PLEASE NOTE THAT THIS METHOD IS IN NO WAY AUTHORITATIVE.  It does not
-        perform any cryptographic checks.
-
-        Currently this check is if L{Q2QAddress.__str__}C{(self)} is equivalent
-        to the commonName on the certificate's subject.
-        """
-        return cert.getSubject().commonName == str(self)
-
-    def __cmp__(self, other):
-        if not isinstance(other, Q2QAddress):
-            return cmp(self.__class__, other.__class__)
-        return cmp((self.domain, self.resource), (other.domain, other.resource))
-
-    def __iter__(self):
-        return iter((self.resource, self.domain))
-
-    def __str__(self):
-        """
-        Return a string of the normalized form of this address.  e.g.::
-
-            glyph@xxxxxxxxxx    # for a user
-            divmod.com          # for a domain
-        """
-        if self.resource:
-            resource = self.resource + '@'
-        else:
-            resource = ''
-        return (resource + self.domain).encode('utf-8')
-
-    def __repr__(self):
-        return '<Q2Q at %s>' % self.__str__()
-
-    def __hash__(self):
-        return hash(str(self))
-
-    def fromString(cls, string):
-        args = string.split("@",1)
-        args.reverse()
-        return cls(*args)
-    fromString = classmethod(fromString)
-
-
-class VirtualTransportAddress:
-    def __init__(self, underlying):
-        self.underlying = underlying
-
-    def __repr__(self):
-        return 'VirtualTransportAddress(%r)' % (self.underlying,)
-
-class Q2QTransportAddress:
-    """
-    The return value of getPeer() and getHost() for Q2Q-enabled transports.
-    Passed to buildProtocol of factories passed to listenQ2Q.
-
-    @ivar underlying: The return value of the underlying transport's getPeer()
-    or getHost(); an address which indicates the path which the bytes carrying
-    Q2Q traffic are travelling over.  It is tempting to think of this as a
-    'physical' layer but that it not necessarily accurate; there are
-    potentially multiple layers of wrapping on any Q2Q transport, as an SSL
-    transport may be tunnelled over a UDP NAT-traversal layer.  Implements
-    C{IAddress} from Twisted, for all the good that will do you.
-
-    @ivar logical: a L{Q2QAddress}, The logical peer; the user ostensibly
-    listening to data on the other end of this transport.
-
-    @ivar protocol: a L{str}, the name of the protocol that is connected.
-    """
-
-    def __init__(self, underlying, logical, protocol):
-        self.underlying = underlying
-        self.logical = logical
-        self.protocol = protocol
-
-    def __repr__(self):
-        return 'Q2QTransportAddress(%r, %r, %r)' % (
-            self.underlying,
-            self.logical,
-            self.protocol)
-
-
-class AmpTime(Argument):
-    def toString(self, inObject):
-        return inObject.strftime("%Y-%m-%dT%H:%M:%S")
-
-
-    def fromString(self, inString):
-        return datetime.datetime.strptime(inString, "%Y-%m-%dT%H:%M:%S")
-
-
-
-class Q2QAddressArgument(Argument):
-    fromString = Q2QAddress.fromString
-    toString = Q2QAddress.__str__
-
-class HostPort(Argument):
-    def toString(self, inObj):
-        return "%s:%d" % tuple(inObj)
-
-    def fromString(self, inStr):
-        host, sPort = inStr.split(":")
-        return (host, int(sPort))
-
-
-
-class _BinaryLoadable(String):
-    def toString(self, arg):
-        assert isinstance(arg, self.loader), "%r not %r" % (arg, self.loader)
-        return String.toString(self, arg.dump())
-
-    def fromString(self, arg):
-        return self.loader.load(String.fromString(self, arg))
-
-class CertReq(_BinaryLoadable):
-    loader = CertificateRequest
-
-class Cert(_BinaryLoadable):
-    loader = Certificate
-
-from twisted.internet import protocol
-
-class Q2QClientProtocolFactoryWrapper:
-
-    def __init__(self, service, cpf, fromAddress, toAddress, protocolName,
-                 connectionEstablishedDeferred):
-        self.service = service
-        self.cpf = cpf
-        self.fromAddress = fromAddress
-        self.toAddress = toAddress
-        self.protocolName = protocolName
-        self.connectionEstablishedDeferred = connectionEstablishedDeferred
-        connectionEstablishedDeferred.addCallback(self.setMyClient)
-
-    myClient = None
-    def setMyClient(self, myClient):
-        # print '***CLIENT SET***', self, self.fromAddress, self.toAddress, self.cpf
-        self.myClient = myClient
-        return myClient
-
-    def buildProtocol(self, addr):
-        # xxx modify addr to include q2q information.
-        subProto = self.cpf.buildProtocol(self.toAddress)
-        myProto = SeparateConnectionTransport(self.service, subProto, self.fromAddress,
-                                              self.toAddress, self.protocolName,
-                                              self.connectionEstablishedDeferred)
-        return myProto
-
-    def clientConnectionFailed(self, connector, reason):
-        # DON'T forward this to our client protocol factory; only one attempt
-        # has failed; let that happen later, when _ALL_ attempts have failed.
-        assert self.myClient is None
-        self.connectionEstablishedDeferred.errback(reason)
-
-    def clientConnectionLost(self, connector, reason):
-        # as in clientConnectionFailed, don't bother to forward; this
-        # clientConnectionLost is actually a clientConnectionFailed for the
-        # underlying transport.
-        if self.myClient is not None:
-            # forward in this case because it's likely that we need to pass it
-            # along...
-            self.cpf.clientConnectionLost(connector, reason)
-
-    def doStart(self):
-        self.cpf.doStart()
-
-    def doStop(self):
-        self.cpf.doStop()
-
-class ImmediatelyLoseConnection(protocol.Protocol):
-    def connectionMade(self):
-        self.transport.loseConnection()
-
-class AbstractConnectionAttempt(protocol.ClientFactory):
-
-
-    def __init__(self, method, q2qproto, connectionID, fromAddress, toAddress,
-                 protocolName, clientProtocolFactory, issueGreeting=False):
-        self.method = method
-        self.q2qproto = q2qproto
-        assert isinstance(connectionID, str)
-        self.connectionID = connectionID
-        self.q2qproto = q2qproto
-        self.fromAddress = fromAddress
-        self.toAddress = toAddress
-        self.protocolName = protocolName
-        self.deferred = defer.Deferred()
-        self.clientProtocolFactory = Q2QClientProtocolFactoryWrapper(
-            q2qproto.service,
-            clientProtocolFactory, fromAddress, toAddress, protocolName,
-            self.deferred)
-        self.issueGreeting = issueGreeting
-
-
-    def startAttempt(self):
-        """
-        +-+
-        |?|
-        +-+
-        """
-        raise NotImplementedError()
-
-
-    q2qb = None
-
-    cancelled = False
-
-    def buildProtocol(self, addr):
-        if self.cancelled:
-            return ImmediatelyLoseConnection()
-        assert self.q2qb is None
-        self.q2qb = Q2QBootstrap(
-            self.connectionID, self.clientProtocolFactory)
-        return self.q2qb
-
-    def clientConnectionFailed(self, connector, reason):
-        """
-        """
-        # Don't bother forwarding.  In fact this should probably never be
-        # called because we're not bothering to forward them along from
-        # Q2QClientProtocolFactoryWrapper
-
-    def clientConnectionLost(self, connector, reason):
-        """
-        """
-        # we don't care - this will be handled by Q2QBootstrap.
-
-    def cancel(self):
-        """
-        - Stop attempting to connect.
-
-        - If a connection is somehow made after this has been cancelled, reject
-          it.
-
-        - Clean up any resources, such as listening UDP or TCP ports,
-          associated with this connection attempt [obviously, that are unshared
-          by other connection attempt]
-
-        """
-        self.cancelled = True
-
-
-class TCPConnectionAttempt(AbstractConnectionAttempt):
-    attempted = False
-    def startAttempt(self):
-        assert not self.attempted
-        self.attempted = True
-        reactor.connectTCP(self.method.host, self.method.port, self)
-        return self.deferred
-
-
-class TCPMethod:
-    def __init__(self, hostport):
-        self.host, port = hostport.split(':')
-        self.port = int(port)
-
-    attemptFactory = TCPConnectionAttempt
-    relayable = True
-    ptype = 'tcp'
-
-    def toString(self):
-        return '%s@%s:%d' % (self.ptype, self.host, self.port)
-
-    def __repr__(self):
-        return '<%s>'%self.toString()
-
-    def attempt(self, *a):
-        return [self.attemptFactory(self, *a)]
-
-connectionCounter = itertools.count().next
-connectionCounter()
-
-class VirtualConnectionAttempt(AbstractConnectionAttempt):
-    attempted = False
-    def startAttempt(self):
-        assert not self.attempted
-        self.attempted = True
-        cid = connectionCounter()
-        if self.q2qproto.isServer:
-            cid = -cid
-        innerTransport = VirtualTransport(self.q2qproto, cid, self, True)
-        def startit(result):
-            proto = innerTransport.startProtocol()
-            return self.deferred
-
-        d = self.q2qproto.callRemote(Virtual, id=cid)
-        d.addCallback(startit)
-        return d
-
-
-class VirtualMethod:
-    def __init__(self, virt=None):
-        pass
-
-    relayable = False
-
-    def toString(self):
-        return 'virtual'
-
-    def __repr__(self):
-        return '<%s>' % (self.toString(),)
-
-    def attempt(self, *a):
-        return [VirtualConnectionAttempt(self, *a)]
-
-
-class _PTCPConnectionAttempt1NoPress(AbstractConnectionAttempt):
-    attempted = False
-    def startAttempt(self):
-        assert not self.attempted
-        self.attempted = True
-        svc = self.q2qproto.service
-        dsp = svc.dispatcher
-        dsp.connectPTCP(
-            self.method.host, self.method.port, self,
-            svc.sharedUDPPortnum)
-        return self.deferred
-
-class _PTCPConnectionAttemptPress(AbstractConnectionAttempt):
-    attempted = False
-    def startAttempt(self):
-        assert not self.attempted
-        self.attempted = True
-
-        svc = self.q2qproto.service
-        dsp = svc.dispatcher
-        newPort = self.newPort = dsp.bindNewPort()
-        dsp.connectPTCP(
-            self.method.host, self.method.port, self,
-            newPort)
-
-        return self.deferred
-
-    def cancel(self):
-        if not self.cancelled:
-            self.q2qproto.service.dispatcher.unbindPort(self.newPort)
-        else:
-            print 'totally wacky, [press] cancelled twice!'
-        AbstractConnectionAttempt.cancel(self)
-
-class PTCPMethod(TCPMethod):
-    """Pseudo-TCP method.
-    """
-    ptype = 'ptcp'
-
-    def attempt(self, *a):
-        return [_PTCPConnectionAttempt1NoPress(self, *a),
-                _PTCPConnectionAttemptPress(self, *a)]
-
-class RPTCPConnectionAttempt(AbstractConnectionAttempt):
-    attempted = False
-    def startAttempt(self):
-        assert not self.attempted
-        self.attempted = True
-
-        realLocalUDP = self.newPort = self.q2qproto.service.dispatcher.seedNAT((self.method.host, self.method.port))
-        # self.host and self.port are remote host and port
-        # realLocalUDP is a local port
-
-        # The arguments here are given from the perspective of the recipient of
-        # the command. we are asking the recipient of the connection to map a
-        # NAT entry of a pre-existing listening UDP socket on their end of the
-        # connection by sending us some traffic.  therefore the src is their
-        # endpoint, the dst is our endpoint, the user we are asking them to
-        # send TO is us, the user we are asking them to accept this FROM is us.
-
-        # we include protocol as an arg because this is helpful for relaying.
-
-        def enbinden(boundereded):
-            if not self.cancelled:
-                self.q2qproto.service.dispatcher.connectPTCP(
-                    self.method.host, self.method.port, self, realLocalUDP
-                    )
-            return self.deferred
-
-        def swallowKnown(error):
-            error.trap(ConnectionError)
-            self.deferred.errback(CONNECTION_DONE)
-            return self.deferred
-
-        d = self.q2qproto.callRemote(
-            BindUDP,
-            q2qsrc=self.toAddress,
-            q2qdst=self.fromAddress,
-            protocol=self.protocolName,
-            udpsrc=(self.method.host, self.method.port),
-            udpdst=(self.q2qproto._determinePublicIP(), realLocalUDP))
-        d.addCallbacks(enbinden, swallowKnown)
-        return d
-
-    def cancel(self):
-        if not self.cancelled:
-            self.q2qproto.service.dispatcher.unbindPort(self.newPort)
-        else:
-            print 'totally wacky, [rptcp] cancelled twice!'
-        AbstractConnectionAttempt.cancel(self)
-
-
-
-
-class RPTCPMethod(TCPMethod):
-    """ Certain NATs respond very poorly to seed traffic: e.g. if they receive
-    unsolicited traffic to a particular port, they will make that outbound port
-    unavailable for outbound traffic originated internally.  The
-    Reverse-Pseudo-TCP method is a way to have the *sender* send the first UDP
-    packet, so they will bind it.
-
-    This is a worst-case scenario: if both ends of the connection have NATs
-    which behave this way, there is no way to establish a connection.
-    """
-
-    ptype = 'rptcp'
-    attemptFactory = RPTCPConnectionAttempt
-
-
-class UnknownMethod:
-
-    relayable = True
-
-    def __init__(self, S):
-        self.string = S
-
-    def attemptConnect(self, q2qproto, connectionID, From, to,
-                       protocolName, protocolFactory):
-        return defer.fail(Failure(ConnectionError(
-                    "unknown connection method: %s" % (self.string,))))
-
-
-_methodFactories = {'virtual': VirtualMethod,
-                    'tcp': TCPMethod,
-                    'ptcp': PTCPMethod,
-                    'rptcp': RPTCPMethod}
-
-class Method(Argument):
-    def toString(self, inObj):
-        return inObj.toString()
-
-
-    def fromString(self, inString):
-        f = inString.split("@", 1)
-        factoryName = f[0]
-        if len(f) > 1:
-            factoryData = f[1]
-        else:
-            factoryData = ''
-        methodFactory = _methodFactories.get(factoryName, None)
-        if methodFactory is None:
-            factory = UnknownMethod(inString)
-        else:
-            factory = methodFactory(factoryData)
-        return factory
-
-
-class Secure(StartTLS):
-
-    commandName = "secure"
-    arguments = StartTLS.arguments + [
-        ('From', Q2QAddressArgument(optional=True)),
-        ('to', Q2QAddressArgument()),
-        ('authorize', Boolean())
-        ]
-
-
-
-class Listen(Command):
-    """
-    A simple command for registering interest with an active Q2Q connection
-    to hear from a server when others come calling.  An occurrence of this
-    command might have this appearance on the wire::
-
-        C: -Command: Listen
-        C: -Ask: 1
-        C: From: glyph@xxxxxxxxxx
-        C: Protocols: q2q-example, q2q-example2
-        C: Description: some simple protocols
-        C:
-        S: -Answer: 1
-        S:
-
-    This puts some state on the server side that will affect any Connect
-    commands with q2q-example or q2q-example2 in the Protocol: header.
-    """
-
-    commandName = 'listen'
-    arguments = [
-        ('From', Q2QAddressArgument()),
-        ('protocols', ListOf(String())),
-        ('description', Unicode())]
-
-    result = []
-
-class ConnectionStartBox(AmpBox):
-    def __init__(self, __transport):
-        super(ConnectionStartBox, self).__init__()
-        self.virtualTransport = __transport
-
-    # XXX Overriding a private interface
-    def _sendTo(self, proto):
-        super(ConnectionStartBox, self)._sendTo(proto)
-        self.virtualTransport.startProtocol()
-
-class Virtual(Command):
-    commandName = 'virtual'
-    result = []
-
-    arguments = [('id', Integer())]
-
-    def makeResponse(cls, objects, proto):
-        tpt = objects.pop('__transport__')
-        # XXX Using a private API
-        return _objectsToStrings(
-            objects, cls.response,
-            ConnectionStartBox(tpt),
-            proto)
-
-    makeResponse = classmethod(makeResponse)
-
-class Identify(Command):
-    """
-    Respond to an IDENTIFY command with a self-signed certificate for the
-    domain requested, assuming we are an authority for said domain.  An
-    occurrence of this command might have this appearance on the wire::
-
-        C: -Command: Identify
-        C: -Ask: 1
-        C: Domain: divmod.com
-        C:
-        S: -Answer: 1
-        S: Certificate: <<<base64-encoded self-signed certificate of divmod.com>>>
-        S:
-
-    """
-
-    commandName = 'identify'
-
-    arguments = [('subject', Q2QAddressArgument())]
-
-    response = [('certificate', Cert())]
-
-class BindUDP(Command):
-    """
-    See UDPXMethod
-    """
-
-    commandName = 'bind-udp'
-
-    arguments = [
-        ('protocol', String()),
-        ('q2qsrc', Q2QAddressArgument()),
-        ('q2qdst', Q2QAddressArgument()),
-        ('udpsrc', HostPort()),
-        ('udpdst', HostPort()),
-        ]
-
-    errors = {ConnectionError: 'ConnectionError'}
-
-    response = []
-
-class SourceIP(Command):
-    """
-    Ask a server on the public internet what my public IP probably is.  An
-    occurrence of this command might have this appearance on the wire::
-
-        C: -Command: Source-IP
-        C: -Ask: 1
-        C:
-        S: -Answer: 1
-        S: IP: 4.3.2.1
-        S:
-
-    """
-
-    commandName = 'source-ip'
-
-    arguments = []
-
-    response = [('ip', String())]
-
-class Inbound(Command):
-    """
-    Request information about where to connect to a particular resource.
-
-    Generally speaking this is an "I want to connect to you" request.
-
-    The format of this request is transport neutral except for the optional
-    'Udp_Source' header, which specifies an IP/Port pair for all receiving peers to
-    send an almost-empty (suggested value of '\\r\\n') UDP packet to to help
-    with NAT traversal issues.
-
-    See L{Q2QService.connectQ2Q} for details.
-
-    An occurrence of this command might have this appearance on the wire::
-
-        C: -Command: Inbound
-        C: -Ask: 1
-        C: From: glyph@xxxxxxxxxx
-        C: Id: 681949ffa3be@xxxxxxxxxxxxxxxxx
-        C: To: radix@xxxxxxxxxxxxxxxxx
-        C: Protocol: q2q-example
-        C: Udp_Source: 1.2.3.4:4321
-        C:
-        S: -Answer: 1
-        S: Listeners:
-        S:  Description: at lab
-        S:  Methods: tcp@18.38.12.4:3827, virtual
-        S:
-        S:  Description: my home machine
-        S:  Methods: tcp@187.48.38.3:49812, udp@187.48.38.3:49814, virtual
-
-    Now the connection-id has been registered and either client or server can
-    issue WRITE or CLOSE commands.
-
-    Failure modes::
-
-      - "NotFound": the toResource or toDomain is invalid, or the resource does
-        not speak that protocol.
-
-      - "VerifyError": Authenticity or security for the requested connection
-        could not be authorized.  This is a fatal error: the connection will be
-        dropped.
-
-    The "Udp_Source" header indicates the address from which this Inbound chain
-    originated.  It is to be used to establish connections where possible
-    between NATs which require traffic between two host/port pairs to be
-    bidirectional before a "hole" is established, such as port restricted cone
-    and symmetric NATs.  (Note, this only has about a 30% probability of
-    working on a symmetric NAT, but it's worth trying sometimes anyway).  Any
-    UDP-based connection methods (currently only Gin, but in principle others
-    such as RTP, RTCP, SIP and Quake traffic) that wish to use this connection
-    must first send some garbage traffic to the host/port specified by the
-    "Udp_Source" header.
-
-    The response is a list of "listeners" - a small (unicode) textual
-    description of a host, plus a list of methods describing how to connect to
-    it.
-    """
-
-    commandName = 'inbound'
-    arguments = [('From', Q2QAddressArgument()),
-                 ('to', Q2QAddressArgument()),
-                 ('protocol', String()),
-                 ('udp_source', HostPort(optional=True))]
-
-    response = [('listeners', AmpList(
-                [('id', String()),
-                 ('certificate', Cert(optional=True)),
-                 ('methods', ListOf(Method())),
-                 ('expires', AmpTime()),
-                 ('description', Unicode())]))]
-
-    errors = {KeyError: "NotFound"}
-    fatalErrors = {VerifyError: "VerifyError"}
-
-class Outbound(Command):
-    """Similar to Inbound, but _requires that the recipient already has the
-    id parameter as an outgoing connection attempt_.
-    """
-    commandName = 'outbound'
-
-    arguments = [('From', Q2QAddressArgument()),
-                 ('to', Q2QAddressArgument()),
-                 ('protocol', String()),
-                 ('id', String()),
-                 ('methods', ListOf(Method()))]
-
-    response = []
-
-    errors = {AttemptsFailed: 'AttemptsFailed'}
-
-class Sign(Command):
-    commandName = 'sign'
-    arguments = [('certificate_request', CertReq()),
-                 ('password', String())]
-
-    response = [('certificate', Cert())]
-
-    errors = {KeyError: "NoSuchUser",
-              BadCertificateRequest: "BadCertificateRequest"}
-
-class Choke(Command):
-    """Ask our peer to be quiet for a while.
-    """
-    commandName = 'Choke'
-    arguments = [('id', Integer())]
-    requiresAnswer = False
-
-
-class Unchoke(Command):
-    """Reverse the effects of a choke.
-    """
-    commandName = 'Unchoke'
-    arguments = [('id', Integer())]
-    requiresAnswer = False
-
-
-def safely(f, *a, **k):
-    """try/except around something, w/ twisted error handling.
-    """
-    try:
-        f(*a,**k)
-    except:
-        log.err()
-
-class Q2Q(AMP, subproducer.SuperProducer):
-    """ Quotient to Quotient protocol.
-
-    At a low level, this uses a protocol called 'Juice' (JUice Is Concurrent
-    Events), which is a simple rfc2822-inspired (although not -compliant)
-    protocol for request/response pair hookup.
-
-    At a higher level, it provides a mechanism for SSL certificate exchange,
-    looking up physical locations of users' data, and switching into other
-    protocols after an initial handshake.
-
-    @ivar publicIP: The IP that the other end of the connection claims to know
-    us by.  This will be used when responding to L{Inbound} commands if the Q2Q
-    service I am attached to does not specify a public IP to use.
-
-    @ivar authorized: A boolean indicating whether SSL verification has taken
-    place to ensure that this connection's peer has claimed an accurate identity.
-    """
-
-    protocolName = 'q2q'
-    service = None
-    publicIP = None
-    authorized = False
-
-    def __init__(self, *a, **kw):
-        """ Q2Q instances should only be created by Q2QService.  See
-        L{Q2QService.connectQ2Q} and L{Q2QService.listenQ2Q}.
-        """
-        subproducer.SuperProducer.__init__(self)
-        AMP.__init__(self, *a, **kw)
-
-    def connectionMade(self):
-        self.producingTransports = {}
-        self.connections = {}
-        self.listeningClient = []
-        self.connectionObservers = []
-        if self.service.publicIP is None:
-            log.msg("Service has no public IP: determining")
-            self.service.publicIP = self.transport.getHost().host
-            self.service._publicIPIsReallyPrivate = True
-            def rememberPublicIP(pubip):
-                ip = pubip['ip']
-                log.msg('remembering public ip as %r' % ip)
-                self.publicIP = ip
-                self.service.publicIP = ip
-                self.service._publicIPIsReallyPrivate = False
-            self.callRemote(SourceIP).addCallback(rememberPublicIP)
-        else:
-            log.msg("Using existing public IP: %r" % (self.service.publicIP,))
-
-    def connectionLost(self, reason):
-        ""
-        AMP.connectionLost(self, reason)
-        self._uncacheMe()
-        self.producingTransports = {}
-        for key, value in self.listeningClient:
-            log.msg("removing remote listener for %r" % (key,))
-            self.service.listeningClients[key].remove(value)
-        self.listeningClient = []
-        for xport in self.connections.values():
-            safely(xport.connectionLost, reason)
-        for observer in self.connectionObservers:
-            safely(observer)
-
-    def notifyOnConnectionLost(self, observer):
-        ""
-        self.connectionObservers.append(observer)
-
-    def _bindUDP(self, q2qsrc, q2qdst, udpsrc, udpdst, protocol):
-
-        # we are representing the src, because they are the ones being told to
-        # originate a UDP packet.
-
-        self.verifyCertificateAllowed(q2qsrc, q2qdst)
-
-        # if I've got a local factory for this 3-tuple, do the bind if I own
-        # this IP...
-        srchost, srcport = udpsrc
-
-        lcget = self.service.listeningClients.get((q2qsrc, protocol), ())
-
-        bindery = []
-
-        for (listener, listenCert, desc
-                 ) in lcget:
-            # print 'looking at listener', listener
-            # print listener.transport.getPeer().host, srchost
-            if listener.transport.getPeer().host == srchost:
-                # print 'bound in clients loop'
-
-                d = listener.callRemote(
-                    BindUDP,
-                    q2qsrc=q2qsrc,
-                    q2qdst=q2qdst,
-                    udpsrc=udpsrc,
-                    udpdst=udpdst,
-                    protocol=protocol)
-                def swallowKnown(err):
-                    err.trap(error.ConnectionDone, error.ConnectionLost)
-                d.addErrback(swallowKnown)
-                bindery.append(d)
-        if bindery:
-            # print 'bindery return', len(bindery)
-            def _justADict(ign):
-                return dict()
-            return defer.DeferredList(bindery).addCallback(_justADict)
-
-        # print 'what?', lcget
-        if (self.service.getLocalFactories(q2qdst, q2qsrc, protocol)
-            and srchost == self._determinePublicIP()):
-            self.service.dispatcher.seedNAT(udpdst, srcport, conditional=True)
-            # print 'bound locally'
-            return dict()
-        # print 'conn-error'
-        raise ConnectionError("unable to find appropriate UDP binder")
-
-    BindUDP.responder(_bindUDP)
-
-    def _identify(self, subject):
-        """
-        Implementation of L{Identify}.
-        """
-        ourCA = self.service.certificateStorage.getPrivateCertificate(str(subject))
-        return dict(certificate=ourCA)
-    Identify.responder(_identify)
-
-
-    def verifyCertificateAllowed(self,
-                                 ourAddress,
-                                 theirAddress):
-        """
-        Check that the certificate currently in use by this transport is valid to
-        claim that the connection offers authorization for this host speaking
-        for C{ourAddress}, to a host speaking for C{theirAddress}.  The remote
-        host (the one claiming to use theirAddress) may have a certificate
-        which is issued for the domain for theirAddress or the full address
-        given in theirAddress.
-
-        This method runs B{after} cryptographic verification of the validity of
-        certificates, although it does not perform any cryptographic checks
-        itself.  It depends on SSL connection handshaking - *and* the
-        particular certificate lookup logic which prevents spoofed Issuer
-        fields, to work properly.  However, all it checks is the X509 names
-        present in the certificates matching with the application-level
-        security claims being made by our peer.
-
-        An example of successful verification, because both parties have
-        properly signed certificates for their usage from the domain they
-        have been issued::
-
-            our current certficate:
-                issuer: divmod.com
-                subject: glyph@xxxxxxxxxx
-            their current certificate:
-                issuer: twistedmatrix.com
-                subject: exarkun@xxxxxxxxxxxxxxxxx
-            Arguments to verifyCertificateAllowed:
-                ourAddress: glyph@xxxxxxxxxx
-                theirAddress: exarkun@xxxxxxxxxxxxxxxxx
-            Result of verifyCertificateAllowed: None
-
-        An example of rejected verification, because domain certificates are
-        always B{self}-signed in Q2Q; verisign is not a trusted certificate
-        authority for the entire internet as with some other TLS
-        implementations::
-
-            our current certificate:
-                issuer: divmod.com
-                subject: divmod.com
-            their current certificate:
-                issuer: verisign.com
-                subject: twistedmatrix.com
-            Arguments to verifyCertificateAllowed:
-                ourAddress: divmod.com
-                theirAddress: twistedmatrix.com
-            Result of verifyCertificateAllowed: exception VerifyError raised
-
-        Another example of successful verification, because we assume our
-        current certificate is under the control of this side of the
-        connection, so *any* claimed subject is considered acceptable::
-
-            our current certificate:
-                issuer: divmod.com
-                subject: divmod.com
-            their current certificate:
-                issuer: divmod.com
-                subject: glyph@xxxxxxxxxxxxxxxxx
-            Arguments to verifyCertificateAllowed:
-                ourAddress: divmod.com
-                theirAddress: glyph@xxxxxxxxxxxxxxxxx
-            Result of verifyCertificateAllowed: None
-
-        Another example of successful verification, because the user is
-        claiming to be anonymous; there is also a somewhat looser
-        cryptographic check applied to signatures for anonymous
-        connections::
-
-            our current certificate:
-                issuer: divmod.com
-                subject: divmod.com
-            their current certificate:
-                issuer: @
-                subject: @
-            arguments to verifyCertificateAllowed:
-                ourAddress: divmod.com
-                theirAddress: @
-            Result of verifyCertificateAllowed: None
-
-        Accept anonymous connections with caution.
-
-        @param ourAddress: a L{Q2QAddress} representing the address that we are
-        supposed to have authority for, requested by our peer.
-
-        @param theirAddress: a L{Q2QAddress} representing the address that our
-        network peer claims to be communicating on behalf of.  For example, if
-        our peer is foobar.com they may claim to be operating on behalf of any
-        user @foobar.com.
-
-        @raise: L{VerifyError} if the certificates do not match the
-        claimed addresses.
-        """
-
-        # XXX TODO: Somehow, it's got to be possible for a single cluster to
-        # internally claim to be agents of any other host when issuing a
-        # CONNECT; in other words, we always implicitly trust ourselves.  Also,
-        # we might want to issue anonymous CONNECTs over unencrypted
-        # connections.
-
-        # IOW: *we* can sign a certificate to be whoever, but the *peer* can
-        # only sign the certificate to be the peer.
-
-        # The easiest way to make this work is to issue ourselves a wildcard
-        # certificate.
-
-        if not self.authorized:
-            if theirAddress.domain == '':
-                # XXX TODO: document this rule, anonymous connections are
-                # allowed to not be authorized because they are not making any
-                # claims about who they are
-
-                # XXX also TODO: make it so that anonymous connections are
-                # disabled by default for most protocols
-                return True
-            raise VerifyError("No official negotiation has taken place.")
-
-        peerCert = Certificate.peerFromTransport(self.transport)
-        ourCert = self.hostCertificate
-
-        ourClaimedDomain = ourAddress.domainAddress()
-        theirClaimedDomain = theirAddress.domainAddress()
-
-        # Sanity check #1: did we pick the right certificate on our end?
-        if not ourClaimedDomain.claimedAsIssuerOf(ourCert):
-            raise VerifyError(
-                "Something has gone horribly wrong: local domain mismatch "
-                "claim: %s actual: %s" % (ourClaimedDomain,
-                                          ourCert.getIssuer()))
-        if theirClaimedDomain.claimedAsIssuerOf(peerCert):
-            # Their domain issued their certificate.
-            if theirAddress.claimedAsSubjectOf(peerCert) or theirClaimedDomain.claimedAsSubjectOf(peerCert):
-                return
-        elif ourClaimedDomain.claimedAsIssuerOf(peerCert):
-            # *our* domain can spoof *anything*
-            return
-        elif ourAddress.claimedAsIssuerOf(peerCert):
-            # Neither our domain nor their domain signed this.  Did *we*?
-            # (Useful in peer-to-peer persistent transactions where we don't
-            # want the server involved: exarkun@xxxxxxxxxxxxxxxxx can sign
-            # glyph@xxxxxxxxxx's certificate).
-            return
-
-        raise VerifyError(
-            "Us: %s Them: %s "
-            "TheyClaimWeAre: %s TheyClaimTheyAre: %s" %
-            (ourCert, peerCert,
-             ourAddress, theirAddress))
-
-    def _listen(self, protocols, From, description):
-        """
-        Implementation of L{Listen}.
-        """
-        # The peer is coming from a client-side representation of the user
-        # described by 'From', and talking *to* a server-side representation of
-        # the user described by 'From'.
-        self.verifyCertificateAllowed(From, From)
-        theirCert = Certificate.peerFromTransport(self.transport)
-        for protocolName in protocols:
-            if protocolName.startswith('.'):
-                raise VerifyError(
-                    "Internal protocols are for server-server use _only_: %r" %
-                    protocolName)
-
-            key = (From, protocolName)
-            value = (self, theirCert, description)
-            log.msg("%r listening for %r" % key)
-            self.listeningClient.append((key, value))
-            self.service.listeningClients.setdefault(key, []).append(value)
-        return {}
-    Listen.responder(_listen)
-
-
-    def _inbound(self, From, to, protocol, udp_source=None):
-        """
-        Implementation of L{Inbound}.
-        """
-        # Verify stuff!
-
-        self.verifyCertificateAllowed(to, From)
-        return self.service.verifyHook(From, to, protocol
-                                       ).addCallback(self._inboundimpl,
-                                                     From,
-                                                     to,
-                                                     protocol,
-                                                     udp_source).addErrback(
-            lambda f: f.trap(KeyError) and dict(listeners=[]))
-    Inbound.responder(_inbound)
-
-    def _inboundimpl(self, ign, From, to, protocol, udp_source):
-
-        # 2-tuples of factory, description
-        srvfacts = self.service.getLocalFactories(From, to, protocol)
-
-        result = []             # list of listener dicts
-
-        if srvfacts:
-            log.msg("local factories found for inbound request: %r" % (srvfacts,))
-            localMethods = []
-            publicIP = self._determinePublicIP()
-            privateIP = self._determinePrivateIP()
-            if self.service.inboundTCPPort is not None:
-                tcpPort = self.service.inboundTCPPort.getHost().port
-                localMethods.append(TCPMethod(
-                        '%s:%d' %
-                        (publicIP, tcpPort)))
-                if publicIP != privateIP:
-                    localMethods.append(TCPMethod(
-                            '%s:%d' %
-                            (privateIP, tcpPort)))
-
-            if not self.service.udpEnabled:
-                log.msg("udp not enabled -- but I so want to send udp traffic!")
-            elif udp_source is None:
-                log.msg("udp_source was none on inbound")
-            else:
-                if self.service.dispatcher is None:
-                    log.msg("udp_source %s:%d, but dispatcher not running" %
-                            udp_source)
-                else:
-                    remoteUDPHost, remoteUDPPort = udp_source
-                    log.msg(
-                        "remote PTCP: %s:%d, "
-                        "local public IP: %s, local private IP: %s"
-                        % (remoteUDPHost, remoteUDPPort, publicIP, privateIP) )
-
-                    # Seed my NAT from my shared UDP port
-                    udpPort = self.service.dispatcher.seedNAT(udp_source, self.service.sharedUDPPortnum)
-
-                    if remoteUDPHost == publicIP and publicIP != privateIP:
-                        log.msg(
-                            "Remote IP matches local, public IP %r;"
-                            " preferring internal IP %r" % (publicIP, privateIP))
-                        localMethods.append(
-                            PTCPMethod("%s:%d" % (privateIP, udpPort)))
-                    localMethods.append(
-                        PTCPMethod("%s:%d" % (publicIP, udpPort)))
-
-                    # XXX CLEANUP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-                    # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-                    # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-                    privateUDPPort = self.service.dispatcher.seedNAT(udp_source)
-                    localMethods.append(
-                        PTCPMethod('%s:%d' % (publicIP, privateUDPPort)))
-
-                    udpxPort = self.service.dispatcher.seedNAT(udp_source)
-                    localMethods.append(
-                        RPTCPMethod("%s:%d" % (publicIP, udpxPort)))
-
-            if self.service.virtualEnabled:
-                localMethods.append(VirtualMethod())
-            log.msg('responding to inbound with local methods: %r' % (localMethods,))
-
-            for serverFactory, description in srvfacts:
-                expiryTime, listenID = self.service.mapListener(
-                    to, From, protocol, serverFactory)
-                result.append(dict(id=listenID,
-                                   expires=expiryTime,
-                                   methods=localMethods,
-                                   description=description))
-
-            # We've looked for our local factory.  Let's see if we have any
-            # listening protocols elsewhere.
-
-
-        key = (to, protocol)
-        if key in self.service.listeningClients:
-            args = dict(From=From,
-                        to=to,
-                        protocol=protocol,
-                        udp_source=udp_source)
-            DL = []
-            lclients = self.service.listeningClients[key]
-            log.msg("listeners found for %s:%r" % (to, protocol))
-            for listener, listenCert, desc in lclients:
-                log.msg("relaying inbound to %r via %r" % (to, listener))
-                DL.append(listener.callRemote(Inbound, **args).addCallback(
-                    self._massageClientInboundResponse, listener, result))
-
-            def allListenerResponses(x):
-                log.msg("all inbound responses received: %s" % (pformat(result),))
-                return dict(listeners=result)
-            return defer.DeferredList(DL).addCallback(allListenerResponses)
-        else:
-            log.msg("no listenening clients for %s:%r. local methods: %r" % (to,protocol, result))
-            return dict(listeners=result)
-
-
-    def _massageClientInboundResponse(self, inboundResponse, listener, result):
-        irl = inboundResponse['listeners']
-        log.msg("received relayed inbound response: %r via %r" %
-                (inboundResponse, listener))
-
-        for listenerInfo in irl:
-            # inboundResponse['description'] = ??? trust client version for
-            # now... maybe the server doesn't even need to know about
-            # descriptions...?
-            listenerInfo['methods'] = [
-                meth for meth in listenerInfo['methods'] if meth.relayable]
-            # make sure that the certificate that we're relaying matches the
-            # certificate that they gave us!
-            if listenerInfo['methods']:
-                allowedCertificate = Certificate.peerFromTransport(
-                    listener.transport)
-                listenerInfo['certificate'] = allowedCertificate
-                result.append(listenerInfo)
-
-    def _determinePublicIP(self):
-        reservePublicIP = None
-        if self.service.publicIP is not None:
-            if self.service._publicIPIsReallyPrivate:
-                reservePublicIP = self.service.publicIP
-            else:
-                return self.service.publicIP
-        if self.publicIP is not None:
-            return self.publicIP
-        if reservePublicIP is not None:
-            return reservePublicIP
-        return self._determinePrivateIP()
-
-    def _determinePrivateIP(self):
-        return self.transport.getHost().host
-
-    def _sourceIP(self):
-        result = {'ip': self.transport.getPeer().host}
-        return result
-    SourceIP.responder(_sourceIP)
-
-    def _resume(self, connection, data, writeDeferred):
-        try:
-            connection.dataReceived(data)
-        except:
-            writeDeferred.errback()
-        else:
-            writeDeferred.callback({})
-
-
-    def _choke(self, id):
-        connection = self.connections[id]
-        connection.choke()
-        return {}
-    Choke.responder(_choke)
-
-
-    def _unchoke(self, id):
-        connection = self.connections[id]
-        connection.unchoke()
-        return {}
-    Unchoke.responder(_unchoke)
-
-
-    def amp_WRITE(self, box):
-        """
-        Respond to a WRITE command, sending some data over a virtual channel
-        created by VIRTUAL.  The answer is simply an acknowledgement, as it is
-        simply meant to note that the write went through without errors.
-
-        An occurrence of I{Write} on the wire, together with the response
-        generated by this method, might have this apperance::
-
-            C: -Command: Write
-            C: -Ask: 1
-            C: -Length: 13
-            C: Id: glyph@xxxxxxxxxx->radix@xxxxxxxxxxxxxxxxx:q2q-example:0
-            C:
-            C: HELLO WORLD
-            C:
-            S: -Answer: 1
-            S:
-
-        """
-        id = int(box['id'])
-        if id not in self.connections:
-            raise error.ConnectionDone()
-        connection = self.connections[id]
-        data = box['body']
-        connection.dataReceived(data)
-        return AmpBox()
-
-    def amp_CLOSE(self, box):
-        """
-        Respond to a CLOSE command, dumping some data onto the stream.  As with
-        WRITE, this returns an empty acknowledgement.
-
-        An occurrence of I{Close} on the wire, together with the response
-        generated by this method, might have this apperance::
-
-            C: -Command: Close
-            C: -Ask: 1
-            C: Id: glyph@xxxxxxxxxx->radix@xxxxxxxxxxxxxxxxx:q2q-example:0
-            C:
-            S: -Answer: 1
-            S:
-
-        """
-        # The connection is removed from the mapping by connectionLost.
-        connection = self.connections[int(box['id'])]
-        connection.connectionLost(Failure(CONNECTION_DONE))
-        return AmpBox()
-
-
-    def _sign(self, certificate_request, password):
-        """
-        Respond to a request to sign a CSR for a user or agent located within
-        our domain.
-        """
-        if self.service.portal is None:
-            raise BadCertificateRequest("This agent cannot sign certificates.")
-
-        subj = certificate_request.getSubject()
-
-        sk = subj.keys()
-        if 'commonName' not in sk:
-            raise BadCertificateRequest(
-                "Certificate requested with bad subject: %s" % (sk,))
-
-        uandd = subj.commonName.split("@")
-        if len(uandd) != 2:
-            raise BadCertificateRequest("Won't sign certificates for other domains")
-        domain = uandd[1]
-
-        CS = self.service.certificateStorage
-        ourCert = CS.getPrivateCertificate(domain)
-
-        D = self.service.portal.login(
-            UsernamePassword(subj.commonName,
-                             password),
-            self,
-            ivertex.IQ2QUser)
-
-        def _(ial):
-            (iface, aspect, logout) = ial
-            ser = CS.genSerial(domain)
-            return dict(certificate=aspect.signCertificateRequest(
-                    certificate_request, ourCert, ser))
-
-        return D.addCallback(_)
-    Sign.responder(_sign)
-
-
-    def _secure(self, to, From, authorize):
-        """
-        Response to a SECURE command, starting TLS when necessary, and using a
-        certificate identified by the I{To} header.
-
-        An occurrence of I{Secure} on the wire, together with the response
-        generated by this method, might have the following appearance::
-
-            C: -Command: Secure
-            C: -Ask: 1
-            C: To: divmod.com
-            C: From: twistedmatrix.com
-            C: Authorize: True
-            C:
-            Client Starts TLS here with twistedmatrix.com certificate
-            S: -Answer: 1
-            S:
-            Server Starts TLS here with divmod.com certificate
-
-        """
-        if self.hostCertificate is not None:
-            raise RuntimeError("Re-encrypting already encrypted connection")
-        CS = self.service.certificateStorage
-        ourCert = CS.getPrivateCertificate(str(to.domainAddress()))
-        if authorize:
-            D = CS.getSelfSignedCertificate(str(From.domainAddress()))
-        else:
-            self.authorized = False
-            return {'tls_localCertificate': ourCert}
-
-        def hadCert(peerSigned):
-            self.authorized = True
-            self._cacheMeNow(From, to, authorize)
-            return {'tls_localCertificate': ourCert,
-                    'tls_verifyAuthorities': [peerSigned]}
-
-        def didNotHaveCert(err):
-            err.trap(KeyError)
-            return self._retrieveRemoteCertificate(From, port)
-
-        D.addErrback(didNotHaveCert)
-        D.addCallback(hadCert)
-
-        return D
-    Secure.responder(_secure)
-
-    _cachedUnrequested = False
-
-    def _cacheMeNow(self, From, to, authorize):
-        tcpeer = self.transport.getPeer()
-        # XXX 'port' is insane here, but we lack a better number to hash
-        # against.  perhaps the SECURE request should give a reciprocal
-        # connection identifier...?
-        self.service.secureConnectionCache.cacheUnrequested(
-            endpoint.TCPEndpoint(tcpeer.host, port),
-            (From, to.domain, authorize), self)
-        assert not self._cachedUnrequested
-        self._cachedUnrequested = (From, to, authorize, tcpeer)
-
-    def _uncacheMe(self):
-        if self._cachedUnrequested:
-            # If this is a client connection, this will never be called, since
-            # _cacheMeNow is called from the _server_ half of this business.
-            # The uncaching API here is a bit of a ragged edge of conncache.py;
-            # the interface should probably be cleaned up, but I don't think
-            # there are any functional problems with it.
-            From, to, authorize, tcpeer = self._cachedUnrequested
-            self.service.secureConnectionCache.connectionLostForKey(
-                (endpoint.TCPEndpoint(tcpeer.host, port),
-                 (From, to.domain, authorize)))
-
-    def _retrieveRemoteCertificate(self, From, port=port):
-        """
-        The entire conversation, starting with TCP handshake and ending at
-        disconnect, to retrieve a foreign domain's certificate for the first
-        time.
-        """
-        CS = self.service.certificateStorage
-        host = str(From.domainAddress())
-        p = AMP()
-        p.wrapper = self.wrapper
-        f = protocol.ClientCreator(reactor, lambda: p)
-        connD = f.connectTCP(host, port)
-
-        def connected(proto):
-            dhost = From.domainAddress()
-            iddom = proto.callRemote(Identify, subject=dhost)
-            def gotCert(identifyBox):
-                theirCert = identifyBox['certificate']
-                theirIssuer = theirCert.getIssuer().commonName
-                theirName = theirCert.getSubject().commonName
-                if (theirName != str(dhost)):
-                    raise VerifyError(
-                        "%r claimed it was %r in IDENTIFY response"
-                        % (theirName, dhost))
-                if (theirIssuer != str(dhost)):
-                    raise VerifyError(
-                        "self-signed %r claimed it was issued by "
-                        "%r in IDENTIFY response" % (dhost, theirIssuer))
-                def storedCert(ignored):
-                    return theirCert
-                return CS.storeSelfSignedCertificate(
-                    str(dhost), theirCert).addCallback(storedCert)
-            def nothingify(x):
-                proto.transport.loseConnection()
-                return x
-            return iddom.addCallback(gotCert).addBoth(nothingify)
-        connD.addCallback(connected)
-        return connD
-
-
-    def secure(self, fromAddress, toAddress,
-               fromCertificate, foreignCertificateAuthority=None,
-               authorize=True):
-        """Return a Deferred which fires True when this connection has been secured as
-        a channel between fromAddress (locally) and toAddress (remotely).
-        Raises an error if this is not possible.
-        """
-        if self.hostCertificate is not None:
-            raise RuntimeError("Re-securing already secured connection.")
-
-        def _cbSecure(response):
-            if foreignCertificateAuthority is not None:
-                self.authorized = True
-            return True
-        extra = {'tls_localCertificate': fromCertificate}
-        if foreignCertificateAuthority is not None:
-            extra['tls_verifyAuthorities'] = [foreignCertificateAuthority]
-
-        return self.callRemote(
-            Secure,
-            From=fromAddress,
-            to=toAddress,
-            authorize=authorize, **extra).addCallback(_cbSecure)
-
-    def _virtual(self, id):
-        if self.isServer:
-            assert id > 0
-        else:
-            assert id < 0
-        # We are double-deferring here so that we only start writing data to
-        # our client _after_ they have processed our ACK.
-        tpt = VirtualTransport(self, id, self.service._bootstrapFactory, False)
-
-
-        return dict(__transport__=tpt)
-
-    Virtual.responder(_virtual)
-
-
-    # Client/Support methods.
-
-    def attemptConnectionMethods(self, methods, connectionID, From, to,
-                                 protocolName, protocolFactory):
-        attemptObjects = []
-        for meth in methods:
-            atts = meth.attempt(self, connectionID, From, to,
-                                protocolName, protocolFactory)
-            attemptObjects.extend(atts)
-
-        attemptDeferreds = [att.startAttempt() for att in attemptObjects]
-
-        d = defer.DeferredList(attemptDeferreds,
-                              fireOnOneCallback=True,
-                              fireOnOneErrback=False)
-        def dontLogThat(e):
-            e.trap(error.ConnectionLost, error.ConnectionDone)
-
-        for attDef in attemptDeferreds:
-            attDef.addErrback(dontLogThat)
-
-        def _unfortunate_defer_hack(results):
-            #Do you see what you've made me become?
-            if isinstance(results, tuple):
-                stuff = [(False, None)] * len(attemptObjects)
-                stuff[results[1]] = (True, results[0])
-                return stuff
-            return results
-
-
-        def gotResults(results):
-            theResult = None
-            anyResult = False
-            for index, (success, result) in enumerate(results):
-                if success:
-                    # woohoo!  home free.
-                    # XXX Cancel outstanding attempts, maybe.  They'll fail anyway,
-                    # because the factory will return None from buildProtocol().
-                    theResult = result
-                    anyResult = True
-                else:
-                    attemptObjects[index].cancel()
-            if anyResult:
-                # theResult will be a SeparateConnectionTransport
-                return theResult.subProtocol
-            else:
-                reason = Failure(AttemptsFailed([fobj for (f, fobj) in results]))
-                return reason
-
-        d.addCallback(_unfortunate_defer_hack)
-        d.addCallback(gotResults)
-        return d
-
-
-    def listen(self, fromAddress, protocols, serverDescription):
-        return self.callRemote(
-            Listen, From=fromAddress,
-            protocols=protocols, description=serverDescription)
-
-
-    def connect(self, From, to,
-                protocolName, clientFactory,
-                chooser):
-        """
-        Issue an INBOUND command, creating a virtual connection to the peer,
-        given identifying information about the endpoint to connect to, and a
-        protocol factory.
-
-        @param clientFactory: a *Client* ProtocolFactory instance which will
-        generate a protocol upon connect.
-
-        @return: a Deferred which fires with the protocol instance that was
-        connected, or fails with AttemptsFailed if the connection was not
-        possible.
-        """
-
-        publicIP = self._determinePublicIP()
-
-        A = dict(From=From,
-                 to=to,
-                 protocol=protocolName)
-
-        if self.service.dispatcher is not None:
-            # tell them exactly where they can shove it
-            A['udp_source'] = (publicIP,
-                               self.service.sharedUDPPortnum)
-        else:
-            # don't tell them because we don't know
-            log.msg("dispatcher unavailable when connecting")
-
-        D = self.callRemote(Inbound, **A)
-
-        def _connected(answer):
-            listenersD = defer.maybeDeferred(chooser, answer['listeners'])
-            def gotListeners(listeners):
-                allConnectionAttempts = []
-                for listener in listeners:
-                    d = self.attemptConnectionMethods(
-                        listener['methods'],
-                        listener['id'],
-                        From, to,
-                        protocolName, clientFactory,
-                        )
-                    allConnectionAttempts.append(d)
-                return defer.DeferredList(allConnectionAttempts)
-            listenersD.addCallback(gotListeners)
-            def finishedAllAttempts(results):
-                succeededAny = False
-                failures = []
-                if not results:
-                    return Failure(NoAttemptsMade(
-                            "there was no available path for connections "
-                            "(%r->%r/%s)" % (From, to, protocolName)))
-                for succeeded, result in results:
-                    if succeeded:
-                        succeededAny = True
-                        randomConnection = result
-                        break
-                    else:
-                        failures.append(result)
-                if not succeededAny:
-                    return Failure(AttemptsFailed(
-                            [failure.getBriefTraceback() for failure in failures]))
-
-                # XXX TODO: this connection is really random; connectQ2Q should
-                # not return one of the connections it's made, put it into your
-                # protocol's connectionMade handler
-
-                return randomConnection
-
-            return listenersD.addCallback(finishedAllAttempts)
-        return D.addCallback(_connected)
-
-
-class SeparateConnectionTransport(object):
-    def __init__(self,
-                 service,
-                 subProtocol,
-                 q2qhost,
-                 q2qpeer,
-                 protocolName,
-                 connectionEstablishedDeferred=None):
-        self.service = service
-        self.subProtocol = subProtocol
-        self.q2qhost = q2qhost
-        self.q2qpeer = q2qpeer
-        self.protocolName = protocolName
-        self.connectionEstablishedDeferred = connectionEstablishedDeferred
-
-    subProtocol = None
-    q2qhost = None
-    q2qpeer = None
-    protocolName = 'unknown'
-
-    # ITransport
-    disconnecting = property(lambda self: self.transport.disconnecting)
-
-    # IQ2QTransport
-
-    def getQ2QHost(self):
-        return self.q2qhost
-
-    def getQ2QPeer(self):
-        return self.q2qpeer
-
-    def makeConnection(self, tpt):
-        self.transport = tpt
-        self.service.subConnections.append(self)
-        self.subProtocol.makeConnection(self)
-        if self.connectionEstablishedDeferred is not None:
-            self.connectionEstablishedDeferred.callback(self)
-
-    def getPeer(self):
-        return Q2QTransportAddress(self.getQ2QPeer(),
-                                   self.transport.getPeer(),
-                                   self.protocolName)
-
-    def getHost(self):
-        return Q2QTransportAddress(self.getQ2QHost(),
-                                   self.transport.getHost(),
-                                   self.protocolName)
-
-    def dataReceived(self, data):
-        self.subProtocol.dataReceived(data)
-
-    def write(self, data):
-        self.transport.write(data)
-
-    def writeSequence(self, data):
-        self.transport.writeSequence(data)
-
-    def registerProducer(self, producer, streaming):
-        self.transport.registerProducer(producer, streaming)
-
-    def unregisterProducer(self):
-        self.transport.unregisterProducer()
-
-    def loseConnection(self):
-        self.transport.loseConnection()
-
-    def connectionLost(self, reason):
-        self.service.subConnections.remove(self)
-        if self.subProtocol is not None:
-            self.subProtocol.connectionLost(reason)
-            self.subProtocol = None
-
-class WhoAmI(Command):
-    commandName = 'Who-Am-I'
-
-    response = [
-        ('address', HostPort()),
-        ]
-
-class RetrieveConnection(ProtocolSwitchCommand):
-    commandName = 'Retrieve-Connection'
-
-    arguments = [
-        ('identifier', String()),
-        ]
-
-    fatalErrors = {KeyError: "NoSuchConnection"}
-
-class Q2QBootstrap(AMP):
-    def __init__(self, connIdentifier=None, protoFactory=None):
-        AMP.__init__(self)
-        assert connIdentifier is None or isinstance(connIdentifier, (str))
-        self.connIdentifier = connIdentifier
-        self.protoFactory = protoFactory
-
-    def connectionMade(self):
-        if self.connIdentifier is not None:
-            def swallowKnown(err):
-                err.trap(error.ConnectionDone, KeyError)
-            self.retrieveConnection(self.connIdentifier, self.protoFactory).addErrback(swallowKnown)
-
-    def whoami(self):
-        """Return a Deferred which fires with a 2-tuple of (dotted quad ip, port
-        number).
-        """
-        def cbWhoAmI(result):
-            return result['address']
-        return self.callRemote(WhoAmI).addCallback(cbWhoAmI)
-
-
-    def _whoami(self):
-        peer = self.transport.getPeer()
-        return {
-            'address': (peer.host, peer.port),
-            }
-    WhoAmI.responder(_whoami)
-
-
-    def retrieveConnection(self, identifier, factory):
-        return self.callRemote(RetrieveConnection, factory, identifier=identifier)
-
-
-    def _retrieveConnection(self, identifier):
-        listenerInfo = self.service.lookupListener(identifier)
-        if listenerInfo is None:
-            raise KeyError(identifier)
-        else:
-            proto = listenerInfo.protocolFactory.buildProtocol(listenerInfo.From)
-            return SeparateConnectionTransport(
-                    self.service,
-                    proto,
-                    listenerInfo.to,
-                    listenerInfo.From,
-                    listenerInfo.protocolName)
-
-    RetrieveConnection.responder(_retrieveConnection)
-
-
-
-class Q2QBootstrapFactory(protocol.Factory):
-    protocol = Q2QBootstrap
-
-    def __init__(self, service):
-        self.service = service
-
-    def buildProtocol(self, addr):
-        q2etc = protocol.Factory.buildProtocol(self, addr)
-        q2etc.service = self.service
-        return q2etc
-
-class VirtualTransport(subproducer.SubProducer):
-    implements(interfaces.IProducer, interfaces.ITransport, interfaces.IConsumer)
-    disconnecting = False
-
-    def __init__(self, q2q, connectionID, protocolFactory, isClient):
-        """
-        @param q2q: a Q2Q Protocol instance.
-
-        @param connectionID: an integer identifier, unique to the q2q instance
-        that I am wrapping (my underlying physical connection).
-
-        @param protocolFactory: an IProtocolFactory implementor which returns a
-        protocol instance for me to use.  I'll use it to build the protocol,
-        and if the 'client' flag is True, also use it to notify
-        connectionLost/connectionFailed.
-
-        @param isClient: a boolean describing whether my protocol is the
-        initiating half of this connection or not.
-        """
-        subproducer.SubProducer.__init__(self, q2q)
-        self.q2q = q2q
-
-        self.id = connectionID
-        self.isClient = isClient
-        self.q2q.connections[self.id] = self
-        self.protocolFactory = protocolFactory
-
-    protocol = None
-
-    def startProtocol(self):
-        self.protocol = self.protocolFactory.buildProtocol(self.getPeer())
-        self.protocol.makeConnection(self)
-        return self.protocol
-
-    def pauseProducing(self):
-        self.q2q.callRemote(Choke, id=self.id)
-
-    def resumeProducing(self):
-        self.q2q.callRemote(Unchoke, id=self.id)
-
-    def writeSequence(self, iovec):
-        self.write(''.join(iovec))
-
-    def loseConnection(self):
-        if self.disconnecting:
-            # print 'omg wtf loseConnection!???!'
-            return
-        self.disconnecting = True
-        d = self.q2q.callRemoteString('close', id=str(self.id))
-        def cbClosed(ignored):
-            self.connectionLost(Failure(CONNECTION_DONE))
-        def ebClosed(reason):
-            if self.id in self.q2q.connections:
-                self.connectionLost(reason)
-            elif not reason.check(error.ConnectionDone):
-                # Anything but a ConnectionDone (or similar things, perhaps)
-                # is fishy.  Like an IndexError, that'd be wacko.  But a
-                # ConnectionDone when self.id is already out of the Q2Q's
-                # connections mapping means the connection was closed after
-                # we thought it was supposed to be closed.  No harm there.
-                log.err(reason, "Close virtual #%d failed" % (self.id,))
-        d.addCallbacks(cbClosed, ebClosed)
-
-
-    def connectionLost(self, reason):
-        del self.q2q.connections[self.id]
-        if self.protocol is not None:
-            self.protocol.connectionLost(reason)
-        if self.isClient:
-            self.protocolFactory.clientConnectionLost(None, reason)
-
-
-    def dataReceived(self, data):
-        try:
-            self.protocol.dataReceived(data)
-        except:
-            # XXX: unconditionally logging errors from user code makes it hard
-            # to write tests, and is not always the right thing to do.  we
-            # should revamp Twisted to have some kind of control over this
-            # behavior, and add that control back in to this code path as well
-            # (although logging exceptions from dataReceived is _by default_
-            # certainly the right thing to do)  --glyph+exarkun
-            reason = Failure()
-            log.err(reason)
-            self.connectionLost(reason)
-
-    def write(self, data):
-        self.q2q.callRemoteString(
-            'write', False, body=data, id=str(self.id))
-
-    def getHost(self):
-        return VirtualTransportAddress(self.q2q.transport.getHost())
-
-    def getPeer(self):
-        return VirtualTransportAddress(self.q2q.transport.getPeer())
-
-
-_counter = 0
-def _nextJuiceLog():
-    global _counter
-    try:
-        return str(_counter)
-    finally:
-        _counter = _counter + 1
-
-class DefaultQ2QAvatar:
-    implements(ivertex.IQ2QUser)
-
-    def __init__(self, username, domain):
-        self.username = username
-        self.domain = domain
-
-    def signCertificateRequest(self, certificateRequest,
-                               domainCert, suggestedSerial):
-        keyz = certificateRequest.getSubject().keys()
-        if keyz != ['commonName']:
-            raise BadCertificateRequest(
-                "Don't know how to verify fields other than CN: " +
-                repr(keyz))
-        newCert = domainCert.signRequestObject(
-            certificateRequest,
-            suggestedSerial)
-        log.msg('signing certificate for user %s@%s: %s' % (
-                self.username, self.domain, newCert.digest()))
-        return newCert
-
-
-
-class DefaultCertificateStore:
-
-    implements(ICredentialsChecker, IRealm)
-
-    credentialInterfaces = [IUsernamePassword]
-
-    def requestAvatar(self, avatarId, mind, interface):
-        assert interface is ivertex.IQ2QUser, (
-            "default certificate store only supports one interface")
-        return interface, DefaultQ2QAvatar(*avatarId.split("@")), lambda : None
-
-    def requestAvatarId(self, credentials):
-        username, domain = credentials.username.split("@")
-        pw = self.users.get((domain, username))
-        if pw is None:
-            return defer.fail(UnauthorizedLogin())
-        def _(passwordIsCorrect):
-            if passwordIsCorrect:
-                return username + '@' + domain
-            else:
-                raise UnauthorizedLogin()
-        return defer.maybeDeferred(
-            credentials.checkPassword, pw).addCallback(_)
-
-    def __init__(self):
-        self.remoteStore = {}
-        self.localStore = {}
-        self.users = {}
-
-    def getSelfSignedCertificate(self, domainName):
-        return defer.maybeDeferred(self.remoteStore.__getitem__, domainName)
-
-    def addUser(self, domain, username, privateSecret):
-        self.users[domain, username] = privateSecret
-
-    def checkUser(self, domain, username, privateSecret):
-        if self.users.get((domain, username)) != privateSecret:
-            return defer.fail(KeyError())
-        return defer.succeed(True)
-
-    def storeSelfSignedCertificate(self, domainName, mainCert):
-        """
-
-        @return: a Deferred which will fire when the certificate has been
-        stored successfully.
-        """
-        assert not isinstance(mainCert, str)
-        return defer.maybeDeferred(self.remoteStore.__setitem__, domainName, mainCert)
-
-    def getPrivateCertificate(self, domainName):
-        """
-
-        @return: a PrivateCertificate instance, e.g. a certificate including a
-        private key, for 'domainName'.
-        """
-        return self.localStore[domainName]
-
-
-    def genSerial(self, name):
-        return abs(struct.unpack('!i', md5(name).digest()[:4])[0])
-
-    def addPrivateCertificate(self, subjectName, existingCertificate=None):
-        """
-        Add a PrivateCertificate object to this store for this subjectName.
-
-        If existingCertificate is None, add a new self-signed certificate.
-        """
-        if existingCertificate is None:
-            assert '@' not in subjectName, "Don't self-sign user certs!"
-            mainDN = DistinguishedName(commonName=subjectName)
-            mainKey = KeyPair.generate()
-            mainCertReq = mainKey.certificateRequest(mainDN)
-            mainCertData = mainKey.signCertificateRequest(mainDN, mainCertReq,
-                                                          lambda dn: True,
-                                                          self.genSerial(subjectName))
-            mainCert = mainKey.newCertificate(mainCertData)
-        else:
-            mainCert = existingCertificate
-        self.localStore[subjectName] = mainCert
-
-import os
-
-class _pemmap(object):
-    def __init__(self, pathname, certclass):
-        self.pathname = pathname
-        try:
-            os.makedirs(pathname)
-        except (OSError, IOError):
-            pass
-        self.certclass = certclass
-
-    def file(self, name, mode):
-        try:
-            return file(os.path.join(self.pathname, name)+'.pem', mode)
-        except IOError, ioe:
-            raise KeyError(name, ioe)
-
-    def __setitem__(self, key, cert):
-        kn = cert.getSubject().commonName
-        assert kn == key
-        self.file(kn, 'wb').write(cert.dumpPEM())
-
-    def __getitem__(self, cn):
-        return self.certclass.loadPEM(self.file(cn, 'rb').read())
-
-    def iteritems(self):
-        files = os.listdir(self.pathname)
-        for file in files:
-            if file.endswith('.pem'):
-                key = file[:-4]
-                value = self[key]
-                yield key, value
-
-    def items(self):
-        return list(self.iteritems())
-
-    def iterkeys(self):
-        for k, v in self.iteritems():
-            yield k
-
-    def keys(self):
-        return list(self.iterkeys())
-
-    def itervalues(self):
-        for k, v in self.iteritems():
-            yield v
-
-    def values(self):
-        return list(self.itervalues())
-
-
-
-class DirectoryCertificateStore(DefaultCertificateStore):
-    def __init__(self, filepath):
-        self.remoteStore = _pemmap(os.path.join(filepath, 'public'),
-                                   Certificate)
-        self.localStore = _pemmap(os.path.join(filepath, 'private'),
-                                  PrivateCertificate)
-
-class MessageSender(AMP):
-    """
-    """
-
-theMessageFactory = protocol.ClientFactory()
-theMessageFactory.protocol = MessageSender
-
-class _MessageChannel(object):
-    """Conceptual curry over source and destination addresses, as well as a namespace.
-
-    Acts as a transport for delivering Q2Q commands between two particular endpoints.
-    """
-
-    def __init__(self, q2qsvc,
-                 fromAddress, toAddress,
-                 namespace):
-        self.q2qsvc = q2qsvc
-        self.fromAddress = fromAddress
-        self.toAddress = toAddress
-        self.namespace = namespace
-
-    def __call__(self, command):
-        return self.q2qsvc.sendMessage(
-            self.fromAddress,
-            self.toAddress,
-            self.namespace, command)
-
-_ConnectionWaiter = namedtuple('_ConnectionWaiter',
-                               'From to protocolName protocolFactory isClient')
-
-
-
-class Q2QClientFactory(protocol.ClientFactory):
-
-    protocol = Q2Q
-
-    def __init__(self, service):
-        self.service = service
-
-    def buildProtocol(self, addr):
-        p = protocol.ClientFactory.buildProtocol(self, addr)
-        p.isServer = False
-        p.service = self.service
-        p.factory = self
-        p.wrapper = self.service.wrapper
-        return p
-
-
-class YourAddress(Command):
-    arguments = [
-        ('address', HostPort()),
-        ]
-
-
-
-class AddressDiscoveryProtocol(Q2QBootstrap):
-    def __init__(self, addrDiscDef):
-        Q2QBootstrap.__init__(self)
-        self.addrDiscDef = addrDiscDef
-
-
-    def connectionMade(self):
-        self.whoami().chainDeferred(self.addrDiscDef)
-
-
-
-class _AddressDiscoveryFactory(protocol.ClientFactory):
-    def __init__(self, addressDiscoveredDeferred):
-        self.addressDiscoveredDeferred = addressDiscoveredDeferred
-
-    def clientConnectionFailed(self, connector, reason):
-        self.addressDiscoveredDeferred.errback(reason)
-
-    def clientConnectionLost(self, connector, reason):
-        """
-        """
-
-    def buildProtocol(self, addr):
-        adp = AddressDiscoveryProtocol(self.addressDiscoveredDeferred)
-        return adp
-
-
-def _noResults(*x):
-    return []
-
-class PTCPConnectionDispatcher(object):
-    def __init__(self, factory):
-        self.factory = factory
-        self._ports = {}
-
-    def seedNAT(self, (host, port), sourcePort=0, conditional=True):
-        if sourcePort not in self._ports:
-            if sourcePort != 0:
-                if conditional:
-                    return None
-                else:
-                    raise AssertionError('tried to seed %r in %r %r %r' %
-                                         (sourcePort, self, self._ports, self.factory.service))
-            sourcePort = self.bindNewPort(sourcePort)
-        else:
-            assert sourcePort != 0
-        p, proto = self._ports[sourcePort]
-        p.write('NAT!', (host, port))
-        return sourcePort
-
-    def bindNewPort(self, portNum=0, iface=''):
-        iPortNum = portNum
-        proto = ptcp.PTCP(self.factory)
-        p = reactor.listenUDP(portNum, proto, interface=iface)
-        portNum = p.getHost().port
-        log.msg("Binding PTCP/UDP %d=%d" % (iPortNum,portNum))
-        self._ports[portNum] = (p, proto)
-        return portNum
-
-    def unbindPort(self, portNum):
-        log.msg("Unbinding PTCP/UDP %d" % portNum)
-        port, proto = self._ports.pop(portNum)
-        proto.cleanupAndClose()
-
-    def connectPTCP(self, host, port, factory, sourcePort):
-        p, proto = self._ports[sourcePort]
-        return proto.connect(factory, host, port)
-
-    def iterconnections(self):
-        for (p, proto) in self._ports.itervalues():
-            for c in p.protocol._connections.itervalues():
-                if c.protocol is not None:
-                    yield c.protocol
-                else:
-                    # print 'NOT yielding', c, 'in', c.state
-                    pass
-
-    def killAllConnections(self):
-        dl = []
-        for p, proto in self._ports.itervalues():
-            for c in p.protocol._connections.itervalues():
-                c._stopRetransmitting()
-            dl.append(defer.maybeDeferred(p.stopListening))
-        self._ports = {}
-        return defer.DeferredList(dl)
-
-
-class Q2QService(service.MultiService, protocol.ServerFactory):
-    # server factory stuff
-    publicIP = None
-    _publicIPIsReallyPrivate = False
-
-    debugName = 'service'
-
-    protocol = Q2Q
-
-    def __repr__(self):
-        return '<Q2QService %r@%x>' % (self.debugName, id(self))
-
-    def buildProtocol(self, addr):
-        p = protocol.ServerFactory.buildProtocol(self, addr)
-        p.isServer = True
-        p.service = self
-        p.factory = self
-        p.wrapper = self.wrapper
-        return p
-
-    def iterconnections(self):
-        """
-        Iterator of all connections associated with this service, whether cached or
-        not.  For testing purposes only.
-        """
-        return itertools.chain(
-            self.appConnectionCache.cachedConnections.itervalues(),
-            self.secureConnectionCache.cachedConnections.itervalues(),
-            iter(self.subConnections),
-            (self.dispatcher or ()) and self.dispatcher.iterconnections())
-
-    def __init__(self,
-                 protocolFactoryFactory=None,
-                 certificateStorage=None, wrapper=None,
-                 q2qPortnum=port,
-                 inboundTCPPortnum=None,
-                 publicIP=None,
-                 udpEnabled=None,
-                 portal=None,
-                 verifyHook=None):
-        """
-
-        @param protocolFactoryFactory: A callable of three arguments
-        (fromAddress, toAddress, protocolName) which returns a list of 2-tuples
-        of (ProtocolFactory, description) appropriate for constructing
-        protocols which can serve the resource specified by the toAddress.
-
-        @param certificateStorage: an implementor of ICertificateStore, or None
-        for the default implementation.
-        """
-
-        if udpEnabled is not None:
-            self.udpEnabled = udpEnabled
-
-        if protocolFactoryFactory is None:
-            protocolFactoryFactory = _noResults
-        self.protocolFactoryFactory = protocolFactoryFactory
-        if certificateStorage is None:
-            certificateStorage = DefaultCertificateStore()
-            if portal is None:
-                portal = Portal(certificateStorage, checkers=[certificateStorage])
-        self.certificateStorage = certificateStorage
-
-        # allow protocols to wrap message handlers in transactions.
-        self.wrapper = wrapper
-
-        # clients which have registered for network events: maps {(q2q_id,
-        # protocol_name): clientQ2QProtocol}
-        self.listeningClients = {}
-
-        self.inboundConnections = {} # map of str(Id) to _ConnectionWaiter
-        self.q2qPortnum = q2qPortnum # port number for q2q
-
-        # port number for inbound almost-raw TCP
-        self.inboundTCPPortnum = inboundTCPPortnum
-
-        # list of independent TCP connections relaying Q2Q traffic.
-        self.subConnections = []
-
-        # map of {(fromAddress, protocolName): [(factory, description)]}
-        self.localFactoriesMapping = {}
-
-        # currently only used for password-lookup for SIGN, but should be
-        # invoked for everything related to connection setup.
-        self.portal = portal
-
-        if publicIP is not None:
-            self.publicIP = publicIP
-
-        if verifyHook is not None:
-            self.verifyHook = verifyHook
-
-        self.appConnectionCache = ConnectionCache()
-        self.secureConnectionCache = ConnectionCache()
-
-        service.MultiService.__init__(self)
-
-    inboundListener = None
-
-    _publicUDPPort = None
-
-    def verifyHook(self, From, to, protocol):
-        return defer.succeed(1)
-
-    def _retrievePublicUDPPortNumber(self, registrationServerAddress):
-        # Create a PTCP port, bounce some traffic off the indicated server,
-        # wait for it to tell us what our address is
-        d = defer.Deferred()
-        addressDiscoveryFactory = _AddressDiscoveryFactory(d)
-
-        host, port = registrationServerAddress
-        self.dispatcher.connectPTCP(host, port, addressDiscoveryFactory,
-                                    self.sharedUDPPortnum)
-        return d
-
-
-    def listenQ2Q(self, fromAddress, protocolsToFactories, serverDescription):
-        """
-        Right now this is really only useful in the client implementation,
-        since it is transient.  protocolFactoryFactory is used for persistent
-        listeners.
-        """
-        myDomain = fromAddress.domainAddress()
-        D = self.getSecureConnection(fromAddress, myDomain)
-        def _secured(proto):
-            lfm = self.localFactoriesMapping
-            def startup(listenResult):
-                for protocol, factory in protocolsToFactories.iteritems():
-                    key = (fromAddress, protocol)
-                    if key not in lfm:
-                        lfm[key] = []
-                    lfm[key].append((factory, serverDescription))
-                    factory.doStart()
-
-                def shutdown():
-                    for protocol, factory in protocolsToFactories.iteritems():
-                        lfm[fromAddress, protocol].remove(
-                            (factory, serverDescription))
-                        factory.doStop()
-
-                proto.notifyOnConnectionLost(shutdown)
-                return listenResult
-
-            if self.dispatcher is not None:
-                gp = proto.transport.getPeer()
-                udpAddress = (gp.host, gp.port)
-                pubUDPDeferred = self._retrievePublicUDPPortNumber(udpAddress)
-            else:
-                pubUDPDeferred = defer.succeed(None)
-
-            def _gotPubUDPPort(publicAddress):
-                self._publicUDPAddress = publicAddress
-                return proto.listen(fromAddress, protocolsToFactories.keys(),
-                                    serverDescription).addCallback(startup)
-            pubUDPDeferred.addCallback(_gotPubUDPPort)
-            return pubUDPDeferred
-
-        D.addCallback(_secured)
-        return D
-
-    def requestCertificateForAddress(self, fromAddress, sharedSecret):
-        """
-        Connect to the authoritative server for the domain part of the given
-        address and obtain a certificate signed by the root certificate for
-        that domain, then store that certificate in my local certificate
-        storage.
-
-        @param fromAddress: an address that this service is authorized to use,
-        and should store a separate private certificate for.
-
-        @param sharedSecret: a str that represents a secret shared between the
-        user of this service and their account on the server running on the
-        domain part of the fromAddress.
-
-        @return: a Deferred which fires None when the certificate has been
-        successfully retrieved, and errbacks if it cannot be retrieved.
-        """
-        kp = KeyPair.generate()
-        subject = DistinguishedName(commonName=str(fromAddress))
-        reqobj = kp.requestObject(subject)
-        # create worthless, self-signed certificate for the moment, it will be
-        # replaced later.
-
-        #attemptAddress = q2q.Q2QAddress(fromAddress.domain,
-        #   fromAddress.resource + '+attempt')
-        # fakeSubj = DistinguishedName(commonName=str(attemptAddress))
-        fakereq = kp.requestObject(subject)
-        ssigned = kp.signRequestObject(subject, fakereq, 1)
-        certpair = PrivateCertificate.fromCertificateAndKeyPair
-        fakecert = certpair(ssigned, kp)
-        apc = self.certificateStorage.addPrivateCertificate
-
-        def _2(secured):
-            D = secured.callRemote(
-                Sign,
-                certificate_request=reqobj,
-                password=sharedSecret)
-            def _1(dcert):
-                cert = dcert['certificate']
-                privcert = certpair(cert, kp)
-                apc(str(fromAddress), privcert)
-            return D.addCallback(_1)
-        return self.getSecureConnection(
-            fromAddress, fromAddress.domainAddress(), authorize=False,
-            usePrivateCertificate=fakecert,
-            ).addCallback(_2)
-
-    def authorize(self, fromAddress, password):
-        """To-be-deprecated synonym for requestCertificateForAddress
-        """
-        return self.requestCertificateForAddress(fromAddress, password)
-
-    _lastConnID = 1
-
-    def _nextConnectionID(self, From, to):
-        lcid = self._lastConnID
-        self._lastConnID += 1
-        fmt = '%s->%s:%s' % (
-            From, to, lcid)
-        return fmt
-
-    def mapListener(self, to, From, protocolName, protocolFactory, isClient=False):
-        """
-        Returns 2-tuple of (expiryTime, listenerID)
-        """
-        listenerID = self._nextConnectionID(From, to)
-        call = reactor.callLater(120,
-                                 self.unmapListener,
-                                 listenerID)
-        expires = datetime.datetime(*time.localtime(call.getTime())[:7])
-        self.inboundConnections[listenerID] = (
-            _ConnectionWaiter(From, to, protocolName, protocolFactory, isClient),
-            call)
-        return expires, listenerID
-
-    def unmapListener(self, listenID):
-        del self.inboundConnections[listenID]
-
-    def lookupListener(self, listenID):
-        """(internal)
-
-        Retrieve a waiting connection by its connection identifier, passing in
-        the transport to be used to connect the waiting protocol factory to.
-        """
-        if listenID in self.inboundConnections:
-            # make the connection?
-            cwait, call = self.inboundConnections.pop(listenID)
-            # _ConnectionWaiter instance
-            call.cancel()
-            return cwait
-        # raise KeyError(listenID)
-
-    def getLocalFactories(self, From, to, protocolName):
-        """
-        Returns a list of 2-tuples of (protocolFactory, description) to handle
-        this from/to/protocolName
-        """
-        result = []
-        x = self.localFactoriesMapping.get((to, protocolName), ())
-        result.extend(x)
-        y = self.protocolFactoryFactory(From, to, protocolName)
-        result.extend(y)
-        return result
-
-
-    q2qPort = None
-    inboundTCPPort = None
-    inboundUDPPort = None
-    dispatcher = None
-    sharedUDPPortnum = None
-
-    udpEnabled = True          # pretty much you never want to turn this off
-                               # except in the unit tests, or in some kind of
-                               # pathological network condition
-
-    virtualEnabled = True
-
-    def startService(self):
-        self._bootstrapFactory = Q2QBootstrapFactory(self)
-        if self.udpEnabled:
-            self.dispatcher = PTCPConnectionDispatcher(self._bootstrapFactory)
-
-        if self.q2qPortnum is not None:
-            self.q2qPort = reactor.listenTCP(self.q2qPortnum, self)
-            self.q2qPortnum = self.q2qPort.getHost().port
-            if self.dispatcher is not None:
-                self.sharedUDPPortnum = self.dispatcher.bindNewPort(self.q2qPortnum, iface=self.publicIP or '')
-
-        if self.inboundTCPPortnum is not None:
-            self.inboundTCPPort = reactor.listenTCP(
-                self.inboundTCPPortnum,
-                self._bootstrapFactory)
-
-        if self.sharedUDPPortnum is None and self.dispatcher is not None:
-            self.sharedUDPPortnum = self.dispatcher.bindNewPort()
-
-        return service.MultiService.startService(self)
-
-    def stopService(self):
-        dl = []
-        for cwait, delayed in self.inboundConnections.itervalues():
-            delayed.cancel()
-        self.inboundConnections.clear()
-        if self.q2qPort is not None:
-            dl.append(defer.maybeDeferred(self.q2qPort.stopListening))
-        if self.inboundTCPPort is not None:
-            dl.append(defer.maybeDeferred(self.inboundTCPPort.stopListening))
-        if self.dispatcher is not None:
-            dl.append(self.dispatcher.killAllConnections())
-        dl.append(self.appConnectionCache.shutdown())
-        dl.append(self.secureConnectionCache.shutdown())
-        dl.append(defer.maybeDeferred(service.MultiService.stopService, self))
-        for conn in self.subConnections:
-            dl.append(defer.maybeDeferred(conn.transport.loseConnection))
-        return defer.DeferredList(dl)
-
-
-    def sendMessage(self, fromAddress, toAddress, namespace, message):
-        """
-        Send a message using the Q2Q-Message protocol to a peer.  This internally
-        uses a connection cache to avoid setting up and tearing down
-        connections too often.
-
-        @param fromAddress: Q2QAddress instance referring to the sender of the
-        message.
-
-        @param toAddress: Q2QAddress instance referring to the receiver of the
-        message.
-
-        @param namespace: str which indicates what juice command namespace the message is in.
-
-        @param message: a juice.Command object.
-        """
-
-
-        return self.connectCachedQ2Q(
-            fromAddress, toAddress, MESSAGE_PROTOCOL, theMessageFactory
-            ).addCallback(message.do, namespace)
-
-
-    def messageChannel(self, fromAddress, toAddress, namespace):
-        """Create a one-arg callable that takes a Command and sends it to .
-        """
-        return _MessageChannel(self, fromAddress, toAddress, namespace)
-
-    def connectCachedQ2Q(self, fromAddress,
-                         toAddress, protocolName, protocolFactory):
-        return self.appConnectionCache.connectCached(
-            endpoint.Q2QEndpoint(self, fromAddress, toAddress, MESSAGE_PROTOCOL),
-            theMessageFactory)
-
-
-    def connectQ2Q(self, fromAddress, toAddress, protocolName, protocolFactory,
-                   usePrivateCertificate=None, fakeFromDomain=None,
-                   chooser=None):
-        """ Connect a named protocol factory from a resource@domain to a
-        resource@domain.
-
-        This is analagous to something like connectTCP, in that it creates a
-        connection-oriented transport for each connection, except instead of
-        specifying your credentials with an application-level (username,
-        password) and your endpoint with a framework-level (host, port), you
-        specify both at once, in the form of your ID (user@my-domain), their ID
-        (user@their-domain) and the desired protocol.  This provides several
-        useful features:
-
-            - All connections are automatically authenticated via SSL
-              certificates, although not authorized for any particular
-              activities, based on their transport interface rather than having
-              to have protocol logic to authenticate.
-
-            - User-meaningful protocol nicknames are attached to
-              implementations of protocol logic, rather than arbitrary
-              numbering.
-
-            - Endpoints can specify a variety of transport mechanisms
-              transparently to the application: for example, you might be
-              connecting to an authorized user-agent on the user's server or to
-              the user directly using a NAT-circumvention handshake.  All the
-              application has to know is that it wants to establish a TCP-like
-              connection.
-
-        XXX Really, really should return an IConnector implementor for symmetry
-        with other connection-oriented transport APIs, but currently does not.
-
-        The 'resource' parameters are so named (rather than beginning with
-        'user', for example) because they are sometimes used to refer to
-        abstract entities or roles, such as 'payments', or groups of users
-        (communities) but generally the convention is to document them as
-        individual users for simplicity's sake.
-
-        The parameters are described as if Alice <alice@xxxxxxxxxx> were trying
-        try connect to Bob <bob@xxxxxxxxxxxxx> to transfer a file over HTTP.
-
-        @param fromAddress: The address of the connecting user: in this case,
-        Q2QAddress("divmod.com", "alice")
-
-        @param toAddress: The address of the user connected to: in this case,
-        Q2QAddress("notdivmod.com", "bob")
-
-        @param protocolName: The name of the protocol, by convention observing
-        similar names to http://www.iana.org/assignments/port-numbers when
-        appropriate.  In this case, 'http'.
-
-        @param protocolFactory: An implementation of
-        L{twisted.internet.interfaces.IProtocolFactory}
-
-        @param usePrivateCertificate: Use a different private certificate for
-        initiating the 'secure' call.  Mostly for testing different invalid
-        certificate attacks.
-
-        @param fakeDomainName: This domain name will be used for an argument to
-        the 'connect' command, but NOT as an argument to the SECURE command.
-        This is to test a particular kind of invalid cert attack.
-
-        @param chooser: a function taking a list of connection-describing
-        objects and returning another list.  Those items in the remaining list
-        will be attempted as connections and buildProtocol called on the client
-        factory.  May return a Deferred.
-
-        @default chooser: C{lambda x: x and [x[0]]}
-        """
-        if chooser is None:
-            chooser = lambda x: x and [x[0]]
-
-        def onSecureConnection(protocol):
-            if fakeFromDomain:
-                connectFromAddress = Q2QAddress(fakeFromDomain, toAddress.resource)
-            else:
-                connectFromAddress = fromAddress
-
-            return protocol.connect(connectFromAddress, toAddress,
-                                    protocolName, protocolFactory,
-                                    chooser)
-
-        def onSecureConnectionFailure(reason):
-            protocolFactory.clientConnectionFailed(None, reason)
-            return reason
-
-        return self.getSecureConnection(
-            fromAddress, toAddress,
-            port, usePrivateCertificate).addCallback(
-            onSecureConnection).addErrback(onSecureConnectionFailure)
-
-    def getSecureConnection(self, fromAddress, toAddress, port=port,
-                            failIfNoCertificate=False,
-                            usePrivateCertificate=None,
-                            authorize=True):
-        """
-        Get a secure connection between two entities by connecting to the
-        domain part of toAddress
-
-        (This really shouldn't be _entirely_ public, because it's slightly
-        misleading: you pass in fully qualified addresses but the connection
-        chops off the resource half of the "to" address, giving you a
-        connection to their host rather than their actual client, as this is a
-        necessary step to look up where their client *is*.)
-        """
-
-        # secure connections using users as clients will have to be established
-        # using the 'secure' method differently than this does: we are ONLY
-        # capable of connecting to other domains (supernodes)
-
-        toDomain = toAddress.domainAddress()
-        resolveme = reactor.resolve(str(toDomain))
-        def cb(toIPAddress, authorize=authorize):
-            GPS = self.certificateStorage.getPrivateCertificate
-            if usePrivateCertificate:
-                ourCert = usePrivateCertificate
-                cacheFrom = fromAddress
-                log.msg('Using fakie private cert:', fromAddress, ourCert, cacheFrom)
-            elif fromAddress.domain == '':
-                assert fromAddress.resource == '', "No domain means anonymous, bozo: %r" % (fromAddress,)
-                # we are actually anonymous, whoops!
-                authorize = False
-                # we need to create our own certificate
-                ourCert = KeyPair.generate().selfSignedCert(218374, CN='@')
-                # feel free to cache the anonymous certificate we just made, whatever
-                cacheFrom = fromAddress
-                log.msg("Using anonymous cert for anonymous user.")
-            else:
-                try:
-                    # Are we in fact a domain, operating on behalf of a user?
-                    x = fromAddress.domainAddress()
-                    ourCert = GPS(str(x))
-                    cacheFrom = x
-                    log.msg('domain on behalf of user:', fromAddress, ourCert, cacheFrom)
-                except KeyError:
-                    # Nope, guess not.  Are we actually that user?
-                    try:
-                        x = fromAddress
-                        ourCert = GPS(str(x))
-                        cacheFrom = x
-                        log.msg( 'actual user:', fromAddress, ourCert, cacheFrom)
-                    except KeyError:
-                        # Hmm.  We're not that user either.  Are we trying to
-                        # pretend to be a user from a *different* domain, to
-                        # ourselves?  (We've got to be a domain to "make
-                        # believe", since this is effectively a clustering
-                        # feature...)
-
-                        try:
-                            x = toDomain
-                            ourCert = GPS(str(x))
-                            cacheFrom = x
-                            log.msg('fakie domain cert:', fromAddress, ourCert, cacheFrom)
-                        except KeyError:
-                            raise VerifyError(
-                                "We tried to secure a connection "
-                                "between %s and %s, "
-                                "but we don't have any certificates "
-                                "that could be used." % (fromAddress,
-                                                         toAddress))
-
-            def connected(proto):
-                certD = self.certificateStorage.getSelfSignedCertificate(
-                    str(toDomain))
-                def nocert(failure):
-                    failure.trap(KeyError)
-                    identD = proto.callRemote(Identify, subject=toDomain).addCallback(
-                        lambda x: x['certificate'])
-                    def storeit(certificate):
-                        return self.certificateStorage.storeSelfSignedCertificate(
-                            str(toDomain), certificate
-                            ).addCallback(lambda x: certificate)
-                    return identD.addCallback(storeit)
-                certD.addErrback(nocert)
-                def gotcert(foreignCA):
-                    secdef = proto.secure(cacheFrom, toDomain,
-                                          ourCert, foreignCA,
-                                          authorize=authorize)
-                    return secdef
-                certD.addCallback(gotcert)
-                return certD
-            return self.secureConnectionCache.connectCached(
-                endpoint.TCPEndpoint(toIPAddress, port),
-                Q2QClientFactory(self),
-                extraWork=connected,
-                extraHash=(cacheFrom, toDomain, authorize)
-                )
-        return resolveme.addCallback(cb)
-

=== removed file 'Vertex/vertex/q2qadmin.py'
--- Vertex/vertex/q2qadmin.py	2010-04-17 15:10:09 +0000
+++ Vertex/vertex/q2qadmin.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from twisted.protocols.amp import Command, String
-
-class NotAllowed(Exception):
-    pass
-
-class AddUser(Command):
-    """
-    Add a user to a domain.
-    """
-    commandName = "add_user"
-
-    arguments = [
-        ("name", String()),
-        ("password", String())
-        ]
-
-    response = []
-
-    errors = {NotAllowed: "NotAllowed"}

=== removed file 'Vertex/vertex/q2qclient.py'
--- Vertex/vertex/q2qclient.py	2010-04-17 15:10:09 +0000
+++ Vertex/vertex/q2qclient.py	1970-01-01 00:00:00 +0000
@@ -1,453 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-import os
-import sys
-import struct
-import getpass
-
-from twisted.protocols.amp import AMP
-
-from vertex import q2q, sigma
-from twisted.python.usage import Options, UsageError
-
-from twisted.python import log
-from twisted.internet import reactor
-from twisted.internet import protocol
-from twisted.internet.task import LoopingCall
-from twisted.internet import error
-from vertex.q2qadmin import AddUser
-
-class Q2QAuthorize(Options):
-    def parseArgs(self, who, password=None):
-        self.who = who
-        self.password = password
-
-    def reportNoCertificate(self, error):
-        print "No certificate retrieved:", error.getErrorMessage(), "(see ~/.q2q-client-log for details)"
-        log.err(error)
-        return None
-
-    def postOptions(self):
-        def go():
-            self.parent.getService().authorize(
-                q2q.Q2QAddress.fromString(self.who),
-                self.password).addErrback(self.reportNoCertificate).addCallback(lambda x: reactor.stop())
-
-        if self.password is None:
-            self.password = getpass.getpass()
-
-        reactor.callWhenRunning(go)
-        self.parent.start()
-
-
-class BandwidthEstimator:
-    bufsize = 20
-    totalBytes = 0
-    def __init__(self, message, length):
-        self.length = length
-        self.message = message
-        self.estim = []
-        self.bytes = 0
-        self.call = LoopingCall(self.estimateBandwidth)
-        self.call.start(1)
-
-    def estimateBandwidth(self):
-        bytes = self.bytes
-        self.totalBytes += bytes
-        self.estim.append(bytes)
-        self.message("%0.2f k/s (%0.2d%%)"
-                     % ((sum(self.estim) / len(self.estim)) / 1024.,
-                        (float(self.totalBytes) / self.length) * 100))
-        if len(self.estim) > self.bufsize:
-            self.estim.pop(0)
-        self.bytes = 0
-
-    def stop(self):
-        self.call.stop()
-        self.estimateBandwidth()
-        self.message("Finished receiving: %d bytes (%d%%)" % (
-                self.totalBytes, (float(self.totalBytes) / self.length) * 100))
-
-class FileReceiver(protocol.Protocol):
-    gotLength = False
-    estimator = None
-
-    def connectionMade(self):
-        self.f = open(self.factory.program.filename, 'wb')
-        self.factory.program.parent.info("Started receiving...")
-
-    def dataReceived(self, data):
-        if not self.gotLength:
-            self.length ,= struct.unpack("!Q", data[:8])
-            data = data[8:]
-            self.estimator = BandwidthEstimator(self.factory.program.parent.info,
-                                                self.length)
-            self.gotLength = True
-
-        self.estimator.bytes += len(data)
-        self.f.write(data)
-
-    def connectionLost(self, reason):
-        self.f.close()
-        if self.estimator:
-            self.estimator.stop()
-        reactor.stop()
-
-from twisted.protocols.basic import FileSender as fsdr
-
-class FileSender(protocol.Protocol):
-    def connectionMade(self):
-        self.file = self.factory.openFile()
-        self.file.seek(0, 2)
-        self.length = self.file.tell()
-        self.file.seek(0)
-        self.estimator = BandwidthEstimator(self.factory.program.parent.info,
-                                            self.length)
-        self.transport.write(struct.pack("!Q", self.length))
-        fsdr().beginFileTransfer(
-            self.file, self).addCallback(
-            lambda x: self.done())
-
-    def done(self):
-        self.factory.program.parent.info("Done sending data: %d bytes" % (
-                self.file.tell(),))
-        self.transport.loseConnection()
-
-    def dataReceived(self, data):
-        print "WTF THE CLIENT IS GETTING DATA", repr(data)
-
-    def registerProducer(self, producer, streaming):
-        self.transport.registerProducer(producer, streaming)
-
-    def unregisterProducer(self):
-        self.transport.unregisterProducer()
-
-    def write(self, data):
-        self.estimator.bytes += len(data)
-        self.transport.write(data)
-
-    def connectionLost(self, reason):
-        reactor.stop()
-
-class FileSenderFactory(protocol.ClientFactory):
-    protocol = FileSender
-
-    def __init__(self, sendprogram):
-        self.program = sendprogram
-
-    def openFile(self):
-        return file(self.program.filename, 'r')
-
-    def clientConnectionFailed(self, connector, reason):
-        self.program.parent.info(
-            "Could not connect: %r" % (reason.getErrorMessage(),))
-        reactor.stop()
-
-    def clientConnectionLost(self, connector, reason):
-        reason.trap(error.ConnectionDone)
-
-class FileReceiverFactory(protocol.Factory):
-    def __init__(self, program):
-        self.program = program
-    protocol = FileReceiver
-
-
-class ClientCertificateStore(q2q.DirectoryCertificateStore):
-    def __init__(self, filepath):
-        q2q.DirectoryCertificateStore.__init__(self, os.path.expanduser(filepath))
-
-
-class ClientQ2QService(q2q.Q2QService):
-    def __init__(self, certspath, *a, **kw):
-        q2q.Q2QService.__init__(self,
-                                certificateStorage=ClientCertificateStore(certspath),
-                                q2qPortnum=0,
-                                *a, **kw)
-
-    def getDefaultFrom(self, default=None):
-        i = self.certificateStorage.localStore.iterkeys()
-        try:
-            return i.next()
-        except StopIteration:
-            return default
-
-
-class TunnelProtocol(protocol.Protocol):
-    def __init__(self, tunnel):
-        self.tunnel = tunnel
-        self.buffer = []
-
-    def connectionMade(self):
-        if self.tunnel is not None:
-            self.tunnel.setTunnel(self)
-
-    def dataReceived(self, data):
-        if self.tunnel is not None:
-            self.tunnel.transport.write(data)
-        else:
-            self.buffer.append(data)
-
-    def setTunnel(self, tunnel):
-        if self.tunnel is None:
-            self.tunnel = tunnel
-            self.dataReceived(''.join(self.buffer))
-            del self.buffer
-            self.tunnel.setTunnel(self)
-
-class TunnelFactory(protocol.ClientFactory):
-    def __init__(self, tunnel):
-        self.tunnel = tunnel
-
-    def buildProtocol(self, addr):
-        return TunnelProtocol(self.tunnel)
-
-    def clientConnectionFailed(self, connector, reason):
-        self.tunnel.transport.loseConnection()
-        reactor.stop()
-
-    clientConnectionLost = clientConnectionFailed
-
-class Q2QTunnel(Options):
-    optParameters = [
-        ['port', 'p', '13000', 'Port on which to start the TCP server'],
-        ['destination', 'd', None, 'Q2Q address to which to create the tunnel'],
-        ['protocol', 'r', None, 'Q2Q protocol which will operate over the tunnel']]
-
-    def postOptions(self):
-        self.toAddr = q2q.Q2QAddress.fromString(self['destination'])
-
-        reactor.listenTCP(int(self['port']), self, interface='127.0.0.1')
-        self.parent.start()
-
-    def doStart(self):
-        pass
-
-    def doStop(self):
-        pass
-
-    def buildProtocol(self, addr):
-        p = TunnelProtocol(None)
-        svc = self.parent.getService()
-        svc.connectQ2Q(self.parent.getFrom(), self.toAddr,
-                       self['protocol'], TunnelFactory(p))
-        return p
-
-class Q2QReceive(Options):
-    optParameters = [["port", "p", "41235", "Port to start the listening server on."]]
-
-    def parseArgs(self, filename):
-        self.filename = filename
-
-    def postOptions(self):
-        serv = self.parent.getService()
-        def pr(x):
-            return x
-        def stopit(err):
-            print "Couldn't Register for File Transfer:", err.getErrorMessage()
-            log.err(err)
-            reactor.stop()
-        serv.listenQ2Q(self.parent.getFrom(),
-                       {'file-transfer': FileReceiverFactory(self)},
-                       "simple file transfer test").addCallback(pr).addErrback(stopit)
-        self.parent.start()
-
-class Q2QSend(Options):
-
-    def parseArgs(self, to, filename):
-        self.to = to
-        self.filename = filename
-
-    def postOptions(self):
-        fs = q2q.Q2QAddress.fromString
-        toAddress = fs(self.to)
-        fromAddress = self.parent.getFrom()
-
-        toDomain = toAddress.domainAddress()
-        svc = self.parent.getService()
-        svc.connectQ2Q(fromAddress, toAddress, 'file-transfer',
-                       FileSenderFactory(self))
-        self.parent.start()
-
-
-class TextNexusUI(sigma.BaseNexusUI):
-    def __init__(self):
-        sigma.BaseNexusUI.__init__(self)
-        self.call = LoopingCall(self.report)
-        self.call.start(5)
-
-    def report(self):
-        print 'Transloads:', len(self.transloads)
-        for transloadui in self.transloads:
-            print '---', transloadui.name, '---'
-            print transloadui.bits.percent()
-            for peer, mask in transloadui.masks.items():
-                print peer, mask.percent()
-        print 'end report'
-
-class Q2QSigma(Options):
-
-    def __init__(self, *a, **k):
-        Options.__init__(self,*a,**k)
-        self.pushers = []
-
-    def opt_push(self, filename):
-        self.pushers.append([file(filename), filename, []])
-
-    def opt_to(self, q2qid):
-        fs = q2q.Q2QAddress.fromString
-        addr = fs(q2qid)
-        self.pushers[-1][-1].append(addr)
-
-    def postOptions(self):
-        nex = sigma.Nexus(self.parent.getService(),
-                          self.parent.getFrom(),
-                          TextNexusUI())
-        # XXX TODO: there has _GOT_ to be a smarter way to handle text UI for
-        # this.
-        for sharefile, sharename, sharepeers in self.pushers:
-            nex.push(sharefile, sharename, sharepeers)
-        self.parent.start()
-
-class UserAdder(AMP):
-    def connectionMade(self):
-        self.d = AddUser(name=self.factory.name,
-                         password=self.factory.password).do(self)
-
-
-class UserAdderFactory(protocol.ClientFactory):
-    protocol = UserAdder
-
-    def __init__(self, name, password):
-        self.name, self.password = name, password
-
-
-def enregister(svc, newAddress, password):
-    """
-    Register a new account and return a Deferred that fires if it worked.
-
-    @param svc: a Q2QService
-
-    @param newAddress: a Q2QAddress object
-
-    @param password: a shared secret (str)
-    """
-    def trapit(x):
-        x.trap(error.ConnectionDone)
-    return svc.connectQ2Q(q2q.Q2QAddress("",""),
-                       q2q.Q2QAddress(newAddress.domain, "accounts"),
-                       'identity-admin',
-                       UserAdderFactory(newAddress.resource, password)
-                       ).addCallback(
-            lambda proto: proto.d).addErrback(
-            trapit)
-
-class Q2QRegister(Options):
-    synopsis = "<new Q2Q address> <password>"
-    def parseArgs(self, newaddress, password):
-        self.newaddress = newaddress
-        self.password = password
-
-    def postOptions(self):
-        fs = q2q.Q2QAddress.fromString
-        newAddress = fs(self.newaddress)
-        svc = self.parent.getService()
-
-        def showit(x):
-            print "%s: %s" % (x.value.__class__, x.getErrorMessage())
-
-        enregister(svc, newAddress, self.password).addErrback(
-            showit).addBoth(lambda nothing: reactor.stop())
-        self.parent.start()
-
-
-class Q2QClientProgram(Options):
-    subCommands = [
-        ['authorize', 'a', Q2QAuthorize, 'Authorize a user'],
-        ['register', 'r', Q2QRegister, 'Create a new user '],
-        ['tunnel', 't', Q2QTunnel, 'Create an SSL tunnel to a given resource'],
-        ['receive', 'l', Q2QReceive, 'Receive for a filetransfer connection'],
-        ['send', 's', Q2QSend, 'Send'],
-        ['sigma', 'g', Q2QSigma, 'Sigma swarming file-transfer']
-        ]
-
-    optParameters = [
-        ['from', 'f', None, "Who to send as?"],
-        ['tcp', 'p', None, 'TCP port number'],
-        ['udp', 'u', 0, 'UDP port number'],
-        ['certspath', 'c', "~/.q2qcerts",
-         "Path to directory full of public/private certificates."],
-        ['logfile', 'l', "~/.q2q-client-log",
-         "Path to file where logs of client activity will be written."]
-        ]
-
-    optFlags = []
-
-    service = None
-
-    def postOptions(self):
-        if not self.subCommand:
-            self.opt_help()
-
-    def info(self, message):
-        sys.stderr.write(">> %s\n" % (message,))
-
-    def getService(self):
-        if self.service is None:
-            u = self['udp']
-            if u is not None:
-                u = int(u)
-            t = self['tcp']
-            if t is not None:
-                t = int(t)
-            self.service = ClientQ2QService(self['certspath'],
-                                            inboundTCPPortnum=t)
-        return self.service
-
-    def getDefaultPath(self):
-        return os.path.expanduser(os.path.join(self['certspath'], 'default-address'))
-
-    def getFrom(self):
-        fr = self['from']
-        if not fr:
-            defpath = self.getDefaultPath()
-            if os.path.exists(defpath):
-                fr = file(defpath).read()
-            else:
-                fr = self.getService().getDefaultFrom()
-                if fr is None:
-                    self.info("No default address available, exiting.")
-                    self.info(
-                        " (Try 'q2q register yourself@xxxxxxxxxx; "
-                        "q2q authorize yourself@xxxxxxxxxx')")
-                    sys.exit(19)
-                self.info("Selected default address:"  +fr)
-                f = file(defpath, 'wb')
-                f.write(fr)
-                f.close()
-
-        return q2q.Q2QAddress.fromString(fr)
-
-    def start(self, portno=None):
-        import sys
-        lfname = self['logfile']
-        if lfname == '-':
-            lf = sys.stdout
-        else:
-            lf = file(os.path.expanduser(lfname), 'ab+')
-        log.startLogging(lf,
-                         setStdout=False)
-        srv = self.getService()
-        from twisted.application.app import startApplication
-        startApplication(srv, False)
-        reactor.run()
-
-    verbosity = 0
-
-    def verboseLogger(self, messageDict):
-        self.info(' '.join([str(x) for x in messageDict.get('message', [])]))
-
-    def opt_verbose(self):
-        self.verbosity += 1
-        log.addObserver(log.FileLogObserver(sys.stderr).emit)
-
-    opt_v = opt_verbose

=== removed file 'Vertex/vertex/q2qstandalone.py'
--- Vertex/vertex/q2qstandalone.py	2010-04-17 15:10:09 +0000
+++ Vertex/vertex/q2qstandalone.py	1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-import os
-
-from twisted.cred.portal import Portal
-
-from twisted.protocols.amp import AMP, Box, parseString
-
-from vertex import q2q
-from vertex.depserv import DependencyService, Conf
-from vertex.q2qadmin import AddUser, NotAllowed
-
-class IdentityAdmin(AMP):
-
-    def command_ADD_USER(self, name, password):
-        # all security is transport security
-        theDomain = self.transport.getQ2QHost().domain
-        self.factory.store.addUser(theDomain, name, password)
-        return {}
-
-    command_ADD_USER.command = AddUser
-
-class IdentityAdminFactory:
-    def __init__(self, certstore):
-        self.store = certstore
-
-    def buildProtocol(self, addr):
-        p = IdentityAdmin()
-        p.factory = self
-        return p
-
-    def examineRequest(self, fromAddress, toAddress, protocolName):
-        if toAddress.resource == "accounts" and protocolName == "identity-admin":
-            return [(self, "identity admin")]
-        return []
-
-class _usermap:
-    def __init__(self, path):
-        self.path = path
-
-    def __setitem__(self, (domain, username), password):
-        domainpath = os.path.join(self.path, domain)
-        if not os.path.exists(domainpath):
-            os.makedirs(domainpath)
-        userpath = os.path.join(domainpath, username+".info")
-        if os.path.exists(userpath):
-            raise NotAllowed()
-        f = open(userpath, 'w')
-        f.write(Box(username=username,
-                    password=password.encode('hex')).serialize())
-        f.close()
-
-    def get(self, (domain, username)):
-        domainpath = os.path.join(self.path, domain)
-        if os.path.exists(domainpath):
-            filepath = os.path.join(domainpath, username+".info")
-            if os.path.exists(filepath):
-                data = parseString(open(filepath).read())[0]
-                return data['password'].decode('hex')
-
-class DirectoryCertificateAndUserStore(q2q.DirectoryCertificateStore):
-    def __init__(self, filepath):
-        q2q.DirectoryCertificateStore.__init__(self, filepath)
-        self.users = _usermap(os.path.join(filepath, "users"))
-
-    def getPrivateCertificate(self, domain):
-        try:
-            return q2q.DirectoryCertificateStore.getPrivateCertificate(self, domain)
-        except KeyError:
-            if len(self.localStore.keys()) > 10:
-                # avoid DoS; nobody is going to need autocreated certs for more
-                # than 10 domains
-                raise
-            self.addPrivateCertificate(domain)
-        return q2q.DirectoryCertificateStore.getPrivateCertificate(self, domain)
-
-class StandaloneQ2Q(DependencyService):
-    def setup_Q2Q(self, path,
-                  q2qPortnum=q2q.port,
-                  inboundTCPPortnum=q2q.port+1,
-                  publicIP=None
-                  ):
-        """Set up a Q2Q service.
-        """
-        store = DirectoryCertificateAndUserStore(path)
-        # store.addPrivateCertificate("kazekage")
-        # store.addUser("kazekage", "username", "password1234")
-        iaf = IdentityAdminFactory(store)
-
-        self.attach(q2q.Q2QService(
-                protocolFactoryFactory=IdentityAdminFactory(store).examineRequest,
-                certificateStorage=store,
-                portal=Portal(store, checkers=[store]),
-                q2qPortnum=q2qPortnum,
-                inboundTCPPortnum=inboundTCPPortnum,
-                publicIP=publicIP,
-                ))
-
-def defaultConfig():
-    # Put this into a .tac file< and customize to your heart's content
-    c = Conf()
-    s = c.section
-    s('q2q',
-      path='q2q-data')
-    application = deploy(**c)
-    return application
-
-deploy = StandaloneQ2Q.deploy

=== removed directory 'Vertex/vertex/scripts'
=== removed file 'Vertex/vertex/scripts/__init__.py'
=== removed file 'Vertex/vertex/sigma.py'
--- Vertex/vertex/sigma.py	2011-06-01 02:15:15 +0000
+++ Vertex/vertex/sigma.py	1970-01-01 00:00:00 +0000
@@ -1,760 +0,0 @@
-# -*- test-case-name: vertex.test.test_sigma -*-
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-"""
-%file transfer protocol, a-la bittorrent.
-"""
-
-import array
-import random
-import sha
-import os
-import sets
-
-from twisted.internet import protocol
-
-from twisted.python.filepath import FilePath
-
-from twisted.protocols.amp import Integer, String, Command, AMP
-
-from vertex import q2q
-from vertex import bits
-from vertex import conncache
-from vertex import endpoint
-
-__metaclass__ = type
-
-# protocol below
-
-PROTOCOL_NAME = 'sigma'
-
-class VerifyError(Exception):
-    pass
-
-class BitArrayArgument(String):
-    def toString(self, arr):
-        return str(arr.size) + ':' + arr.bytes.tostring()
-
-    def fromString(self, st):
-        size, bytes = st.split(":", 1)
-        b = array.array("B")
-        b.fromstring(bytes)
-        return bits.BitArray(b, int(size))
-
-class Put(Command):
-    """
-    Tells the remote end it should request a file from me.
-    """
-
-    arguments = [("name", String())]
-
-
-class Get(Command):
-    """
-    Tells the remote it should start sending me chunks of a file.
-    """
-
-    arguments = [("name", String()),
-                 ('mask', BitArrayArgument(optional=True))]
-
-    response = [("size", Integer())] # number of octets!!
-
-
-
-class Data(Command):
-    """
-    Sends some data for a transfer.
-    """
-    requiresAnswer = False
-
-    arguments = [('name', String()),
-                 ('chunk', Integer()),
-                 ('body', String())]
-
-
-
-class Introduce(Command):
-    """
-    Tells the remote end about another node which should have information about
-    this transfer.
-
-    Peer: the address of the peer
-    Name: the name of the file given.
-    """
-    requiresAnswer = False
-    arguments = [('peer', q2q.Q2QAddressArgument()),
-                 ('name', String())]
-
-
-
-class Verify(Command):
-    """
-    Verify that the checksum of the given chunk is correct.
-
-    Errors:
-
-      - chunk checksum incorrect
-      - host hasn't computed checksum for that chunk yet.
-    """
-
-    arguments = [('name', String()),
-                 ('peer', q2q.Q2QAddressArgument()),
-                 ('chunk', Integer()),
-                 ('sha1sum', String())]
-
-
-
-# this is a fixed, protocol-level constant
-CHUNK_SIZE = 1024 * 16
-
-DONE = {}                       # perhaps Juice should map this to None?
-
-def countChunks(bytes):
-    div, mod = divmod(bytes, CHUNK_SIZE)
-    div += bool(mod)
-    return div
-
-class SigmaProtocol(AMP):
-    """I am a connection to a peer who has some resources I want in the
-    file-swarming network.
-    """
-
-    def __init__(self, nexus):
-        AMP.__init__(self)
-        self.nexus = nexus
-        self.sentTransloads = []
-
-
-    def _get(self, name, mask=None):
-        peer = self.transport.getQ2QPeer()
-        tl = self.nexus.transloads[name]
-        size = tl.getSize()
-        if mask is None:
-            # all zeroes!
-            mask = bits.BitArray(size=countChunks(size))
-        # retrieve persistent scoring and such?
-        tl.updatePeerMask(peer, mask)
-        peerK = tl.peers[peer]
-        if (not peerK.sentGet) and peerK.mask.any(0):
-            # send a reciprocal GET
-            self.get(name, tl.mask)
-        return dict(size=size)
-    Get.responder(_get)
-
-
-    def _data(self, name, chunk, body):
-        self.nexus.transloads[name].chunkReceived(
-            self.transport.getQ2QPeer(), chunk, body)
-        return DONE
-    Data.responder(_data)
-
-
-    def _put(self, name):
-        peer = self.transport.getQ2QPeer()
-        incompleteFilePath, fullFilePath = self.nexus.ui.allocateFile(
-            name, peer)
-        self.nexus.pull(incompleteFilePath, fullFilePath, name, peer)
-        return DONE
-    Put.responder(_put)
-
-
-    def _verify(self, peer, name, chunk, sha1sum):
-        if self.nexus.transloads[name].verifyLocalChunk(peer, chunk, sha1sum):
-            return dict()
-        raise RuntimeError("checksum incorrect")
-    Verify.responder(_verify)
-
-
-    def data(self, name, chunk, body):
-        """
-        Issue a DATA command
-
-        return None
-
-        Sends a chunk of data to a peer.
-        """
-        self.callRemote(Data, name=name, chunk=chunk, body=body)
-
-
-    def introduce(self, name, peerToIntroduce):
-        self.callRemote(
-            Introduce, peer=peerToIntroduce, name=name)
-
-
-    def _introduce(self, peer, name):
-        # Like a PUT, really, but assuming the transload is already
-        # established.
-
-        self.nexus.ui.receivedIntroduction(peer, name)
-
-        t = self.nexus.transloads[name]
-        if peer in t.peers:
-            return {}
-
-        # all bits are set until he responds that he wants something.
-
-        t.updatePeerMask(peer, bits.BitArray(default=1, size=len(t.mask)))
-
-        self.nexus.connectPeer(peer).addCallback(
-            lambda peerProto: peerProto.get(name, t.mask))
-        return {}
-    Introduce.responder(_introduce)
-
-
-    def get(self, name, mask=None):
-        """
-        Issue a GET command
-
-        Return a Deferred which fires with the size of the name being requested
-        """
-        mypeer = self.transport.getQ2QPeer()
-        tl = self.nexus.transloads[name]
-        peerz = tl.peers
-        if mypeer in peerz:
-            peerk = peerz[mypeer]
-        else:
-            # all turned on initially; we aren't going to send them anything.
-            peerk = PeerKnowledge(bits.BitArray(size=len(tl.mask), default=1))
-            peerz[mypeer] = peerk
-        peerk.sentGet = True
-        return self.callRemote(
-            Get, name=name, mask=mask).addCallback(lambda r: r['size'])
-
-
-    def verify(self, name, peer, chunkNumber, sha1sum):
-        return self.callRemote(
-            Verify, name=name, peer=peer, chunk=chunkNumber, sha1sum=sha1sum)
-
-
-    def connectionMade(self):
-        self.nexus.conns.cacheUnrequested(endpoint.Q2QEndpoint(
-                self.nexus.svc,
-                self.nexus.addr,
-                self.transport.getQ2QPeer(),
-                PROTOCOL_NAME), None, self)
-        self.transport.registerProducer(self, 0)
-
-    def stopProducing(self):
-        ""
-
-    pauses = 0
-
-    def pauseProducing(self):
-        self.pauses += 1
-
-    def resumeProducing(self):
-        """
-        algorithm needed here: determine the proportion of my bandwidth that
-        should be going to _ALL_ consumers based on the proportion of the sum
-        of all scores that are available.  then determine how long I need to
-        wait before I send data to my peer.
-        """
-        self.nexus.callLater(0.0001, self.sendSomeData, 2)
-
-    def sendSomeData(self, howMany):
-        """
-        Send some DATA commands to my peer(s) to relay some data.
-
-        @param howMany: an int, the number of chunks to send out.
-        """
-        # print 'sending some data', howMany
-        if self.transport is None:
-            return
-        peer = self.transport.getQ2QPeer()
-        while howMany > 0:
-            # sort transloads so that the least-frequently-serviced ones will
-            # come first
-            tloads = [
-                (findin(tl.name, self.sentTransloads),
-                 tl) for tl in self.nexus.transloadsForPeer(peer)]
-            tloads.sort()
-            tloads = [tl for (idx, tl) in tloads if tl.peerNeedsData(peer)]
-            if not tloads:
-                break
-
-            wasHowMany = howMany
-
-            for myTransload in tloads:
-                # move this transload to the end so it will be sorted last next
-                # time.
-                name = myTransload.name
-                if name in self.sentTransloads:
-                    self.sentTransloads.remove(name)
-                self.sentTransloads.append(name)
-
-                knowledge = myTransload.peers[peer]
-                chunkNumber, chunkData = myTransload.selectOptimalChunk(peer)
-                if chunkNumber is None:
-                    continue
-
-                peerToIntroduce = knowledge.selectPeerToIntroduce(
-                    myTransload.peers.keys())
-
-                if peerToIntroduce is not None:
-                    self.introduce(myTransload.name, peerToIntroduce)
-
-                self.data(name, chunkNumber, chunkData)
-                # Don't re-send that chunk again unless they explicitly tell us
-                # they need it for some reason
-                knowledge.mask[chunkNumber] = 1
-                howMany -= 1
-                if howMany <= 0:
-                    break
-
-            if wasHowMany == howMany:
-                # couldn't find anything to send.
-                break
-
-
-def findin(item, list):
-    """
-    Find C{item} in C{list}.
-    """
-    try:
-        return list.index(item)
-    except ValueError:
-        # x not in list
-        return -1
-
-class PeerKnowledge:
-    """
-    Local representation of a peer's knowledge of a transload.
-    """
-
-    sentGet = False
-
-    def __init__(self, mask):
-        self.mask = mask
-        self.otherPeers = []
-
-    def selectPeerToIntroduce(self, otherPeers):
-        """
-        Choose a peer to introduce.  Return a q2q address or None, if there are
-        no suitable peers to introduce at this time.
-        """
-        for peer in otherPeers:
-            if peer not in self.otherPeers:
-                self.otherPeers.append(peer)
-                return peer
-
-
-class Transload:
-    """
-    An upload/download currently in progress
-
-    @ivar maximumMaskUpdateDelayAfterChange: the maximum amount of time to wait
-          after a change to the bitmask before sending out an updated mask to
-          our peers.
-
-    @ivar maximumChangeCountBeforeMaskUpdate: the maximum number of bits we
-          will allow to change in our mask before sending an update to our
-          peers.
-
-    """
-
-    maximumMaskUpdateDelayAfterChange = 30.0
-    maximumChangeCountBeforeMaskUpdate = 25
-
-    def __init__(self, authority, nexus, name,
-                 incompletePath, fullPath, ui,
-                 seed=False):
-        """
-        Create a Transload.
-
-        @param authority: the q2q address of the first authority on this file.
-        """
-
-        self.incompletePath = incompletePath
-        self.fullPath = fullPath
-
-        self.ui = ui
-        self.authorities = [authority] # q2q address(es) that you send VERIFYs to
-
-        self.seed = seed
-
-        if not seed:
-            self.file = openReadWrite(incompletePath.path)
-        else:
-            self.file = fullPath.open()
-
-        chunkCount = countChunks(self.getSize())
-        mask = bits.BitArray(size=chunkCount, default=int(seed))
-        if seed:
-            maskfile = None
-        else:
-            maskfile = openMaskFile(incompletePath.path)
-
-        self.mask = mask        # BitArray object representing which chunks of
-                                # the file I've got
-        self.maskfile = maskfile # ugh - open file object that keeps a record
-                                 # of the bitmask
-        self.sha1sums = {}       # map {chunk-number: sha1sum}
-        self.nexus = nexus         # Nexus instance that I belong to
-        self.name = name         # the name of the file object being
-                                 # transferred.
-
-        self.changes = 0        # the number of mask changes since the last update
-        self.peers = {}         # map {q2q address: [PeerKnowledge]}
-
-        # We want to retransmit GET every so often
-        self.call = self.nexus.callLater(0.002, self.maybeUpdateMask)
-
-    def stop(self):
-        if self.call is not None:
-            self.call.cancel()
-            self.call = None
-
-    def changeSize(self, size):
-        assert len(self.mask) == 0
-        self.file.seek(size-1)
-        assert self.file.read(1) == ''
-        self.file.write("\x00")
-        chunkCount = countChunks(size)
-        self.mask = bits.BitArray(size=chunkCount)
-        self.writeMaskFile()
-
-    def writeMaskFile(self):
-        self.maskfile.seek(0)
-        self.maskfile.write(buffer(self.mask.bytes))
-        self.maskfile.flush()
-
-    def updatePeerMask(self, peer, mask):
-        if peer in self.peers:
-            self.peers[peer].mask = mask
-        else:
-            self.peers[peer] = PeerKnowledge(mask)
-        self.ui.updatePeerMask(peer, mask)
-
-    def verifyLocalChunk(self, peer, chunkNumber, remoteSum):
-        assert self.mask[chunkNumber] # XXX legit exception(?)
-        localSum = self.sha1sums.get(chunkNumber)
-        if localSum is None:
-            self.file.seek(chunkNumber * CHUNK_SIZE)
-            localChunk = self.file.read(CHUNK_SIZE)
-            localSum = self.sha1sums[chunkNumber] = sha.new(localChunk).digest()
-        return remoteSum == localSum
-
-    def getSize(self):
-        """
-        return the size of my file in bytes
-        """
-        self.file.seek(0, 2)
-        return self.file.tell()
-
-    def chunkReceived(self, who, chunkNumber, chunkData):
-        """
-        A chunk was received from the peer.
-        """
-        def verifyError(error):
-            error.trap(VerifyError)
-            self.nexus.decreaseScore(who, self.authorities)
-        return self.nexus.verifyChunk(self.name,
-                                      who,
-                                      chunkNumber,
-                                      sha.new(chunkData).digest(),
-                                      self.authorities).addCallbacks(
-            lambda whatever: self.chunkVerified(who, chunkNumber, chunkData),
-            verifyError)
-
-    def chunkVerified(self, who, chunkNumber, chunkData):
-        """A chunk (#chunkNumber) containing the data C{chunkData} was verified, sent
-        to us by the Q2QAddress C{who}.
-        """
-        if self.mask[chunkNumber]:
-            # already received that chunk.
-            return
-        self.file.seek(chunkNumber * CHUNK_SIZE)
-        self.file.write(chunkData)
-        self.file.flush()
-        self.sha1sums[chunkNumber] = sha.new(chunkData).digest()
-
-        if not self.mask[chunkNumber]:
-            self.nexus.increaseScore(who)
-            self.mask[chunkNumber] = 1
-            self.writeMaskFile()
-            self.changes += 1
-
-            if self.changes > self.maximumChangeCountBeforeMaskUpdate:
-                self.call.cancel()
-                self.sendMaskUpdate()
-                self.call = self.nexus.callLater(
-                    self.maximumChangeCountBeforeMaskUpdate,
-                    self.maybeUpdateMask)
-
-            if not self.seed and not self.mask.countbits(0):
-                # we're done, let's let other people get at that file.
-                self.file.close()
-                os.rename(self.incompletePath.path,
-                          self.fullPath.path)
-                self.file = self.fullPath.open()
-                self.maskfile.close()
-                os.unlink(self.maskfile.name)
-
-            self.ui.updateHostMask(self.mask)
-
-
-    def maybeUpdateMask(self):
-        if self.changes:
-            self.sendMaskUpdate()
-        self.call = self.nexus.callLater(
-            self.maximumMaskUpdateDelayAfterChange,
-            self.maybeUpdateMask)
-
-
-    def selectOptimalChunk(self, peer):
-        """
-        select an optimal chunk to send to a peer.
-
-        @return: int(chunkNumber), str(chunkData) if there is data to be sent,
-        otherwise None, None
-        """
-
-        # stuff I have
-        have = sets.Set(self.mask.positions(1))
-        # stuff that this peer wants
-        want = sets.Set(self.peers[peer].mask.positions(0))
-        exchangeable = have.intersection(want)
-        finalSet = dict.fromkeys(exchangeable, 0)
-
-        # taking a page from bittorrent, rarest-first
-        for chunkNumber in exchangeable:
-            for otherPeer in self.peers.itervalues():
-                finalSet[chunkNumber] += not otherPeer.mask[chunkNumber]
-        rarityList = [(rarity, random.random(), chunkNumber)
-                      for (chunkNumber, rarity)
-                      in finalSet.iteritems()]
-        if not rarityList:
-            return None, None
-        rarityList.sort()
-        chunkNumber = rarityList[-1][-1] # sorted in ascending order of rarity
-
-        # sanity check
-        assert self.mask[chunkNumber], "I wanted to send a chunk I didn't have"
-
-        self.file.seek(chunkNumber * CHUNK_SIZE)
-        chunkData = self.file.read(CHUNK_SIZE)
-        self.sha1sums[chunkNumber] = sha.new(chunkData).digest()
-        return chunkNumber, chunkData
-
-
-    def sendMaskUpdate(self):
-        # xxx magic
-        self.changes = 0
-        for peer in self.peers:
-            self.nexus.connectPeer(peer).addCallback(
-                self._connectedPeer, peer)
-
-    def _connectedPeer(self, proto, peer):
-        knowledge = self.peers[peer]
-        proto.get(self.name, self.mask)
-
-    def peerNeedsData(self, peer):
-        mask = self.peers[peer].mask
-        return bool(list(mask.positions(0)))
-
-    def putToPeers(self, peers):
-        def eachPeer(proto):
-            proto.callRemote(Put, name=self.name)
-            return proto
-
-        for peer in peers:
-            self.nexus.connectPeer(peer).addCallback(eachPeer)
-
-
-
-
-def openReadWrite(filename):
-    """
-    Return a 2-tuple of: (whether the file existed before, open file object)
-    """
-    try:
-        os.makedirs(os.path.dirname(filename))
-    except OSError:
-        pass
-    try:
-        return file(filename, 'rb+')
-    except IOError:
-        return file(filename, 'wb+')
-
-def existed(fileobj):
-    """
-    Returns a boolean indicating whether a file opened by openReadWrite existed
-    in the filesystem before it was opened.
-    """
-    return 'r' in getattr(fileobj, "mode", '')
-
-def openMaskFile(filename):
-    """
-    Open the bitmask file sitting next to a file in the filesystem.
-    """
-    dirname, basename = os.path.split(filename)
-    newbasename = '_%s_.sbm' % (basename,)
-    maskfname = os.path.join(dirname, newbasename)
-    maskfile = openReadWrite(maskfname)
-    return maskfile
-
-
-class SigmaServerFactory(protocol.ServerFactory):
-    def __init__(self, nexus):
-        self.nexus = nexus
-    def buildProtocol(self, addr):
-        return SigmaProtocol(self.nexus)
-
-class SigmaClientFactory(protocol.ClientFactory):
-    def __init__(self, nexus):
-        self.nexus = nexus
-    def buildProtocol(self, addr):
-        return SigmaProtocol(self.nexus)
-
-class BaseTransloadUI:
-
-    def __init__(self, nexusUI, name, sender):
-        self.name = name
-        self.sender = sender
-        self.nexusUI = nexusUI
-        self.masks = {}
-        self.bits = bits.BitArray()
-
-    def updatePeerMask(self, q2qid, bits):
-        self.masks[q2qid] = bits
-
-    def updateHostMask(self, bits):
-        self.bits = bits
-
-class BaseNexusUI:
-
-    transloadFactory = BaseTransloadUI
-    receivedIntroductions = 0
-
-    def __init__(self, basepath=os.path.expanduser("~/Sigma/Downloads")):
-        self.basepath = FilePath(basepath)
-        self.transloads = []
-
-    def allocateFile(self, sharename, peer):
-        """
-        return a 2-tuple of incompletePath, fullPath
-        """
-        peerDir = self.basepath.child(str(peer))
-        if not peerDir.isdir():
-            peerDir.makedirs()
-        return (peerDir.child(sharename+'.incomplete'),
-                peerDir.child(sharename))
-
-    def receivedIntroduction(self, peer, name):
-        self.receivedIntroductions += 1
-
-    def startTransload(self, *a, **kw):
-        tl = self.transloadFactory(self, *a, **kw)
-        self.transloads.append(tl)
-        return tl
-
-class Nexus(object):
-    """Orchestrator & factory
-    """
-
-    def __init__(self, svc, addr, ui, callLater=None):
-        """
-        Create a Sigma Nexus
-
-        @param svc: a Q2QService
-
-        @param addr: a Q2QAddress
-
-        @param ui: an ISigmaNexusUI implementor.
-
-        @param callLater: a callable with the signature and semantics of
-        IReactorTime.callLater
-        """
-
-        # callLater is for testing purposes.
-        self.scores = {} # map q2qaddress to score
-        self.transloads = {} # map filename to active transloads
-        self.svc = svc
-        self.addr = addr
-        self.conns = conncache.ConnectionCache()
-        if callLater is None:
-            from twisted.internet import reactor
-            callLater = reactor.callLater
-        self.callLater = callLater
-        self.ui = ui
-
-        self.serverFactory = SigmaServerFactory(self)
-        self.clientFactory = SigmaClientFactory(self)
-
-        svc.listenQ2Q(addr, {PROTOCOL_NAME: self.serverFactory},
-                      'Nexus device description')
-
-    def stopService(self):
-        # XXX Not really a service, but maybe it should be?  hmm.
-        for transload in self.transloads.values():
-            transload.stop()
-
-    def transloadsForPeer(self, peer):
-        """
-        Returns an iterator of transloads that apply to a particular peer.
-        """
-        for tl in self.transloads.itervalues():
-            if peer in tl.peers:
-                yield tl
-
-    def seed(self, path, name):
-        """Create a transload from an existing file that is complete.
-        """
-        t = self.transloads[name] = Transload(self.addr, self, name,
-                                              None, path,
-                                              self.ui.startTransload(name,
-                                                                     self.addr),
-                                              seed=True)
-        return t
-
-    def connectPeer(self, peer):
-        """Establish a SIGMA connection to the given peer.
-
-        @param peer: a Q2QAddress of a peer which has a file that I want
-
-        @return: a Deferred which fires a SigmaProtocol.
-        """
-        return self.conns.connectCached(endpoint.Q2QEndpoint(self.svc,
-                                                             self.addr,
-                                                             peer,
-                                                             PROTOCOL_NAME),
-                                        self.clientFactory)
-
-
-    def push(self, fpath, name, peers):
-        t = self.seed(fpath, name)
-        t.putToPeers(peers)
-
-    def pull(self, incompletePath, finalPath, name, peer):
-        t = self.transloads[name] = Transload(peer, self, name,
-                                              incompletePath, finalPath,
-                                              self.ui.startTransload(name, peer))
-        D = self.connectPeer(peer).addCallback(lambda proto: proto.get(name))
-        D.addCallback(t.changeSize)
-        return D
-
-    def increaseScore(self, participant):
-        """
-        The participant successfully transferred a chunk to me.
-        """
-        if participant not in self.scores:
-            self.scores[participant] = 0
-        self.scores[participant] += 1
-
-
-    def decreaseScore(self, participant, authorities):
-        """
-        Much more severe than increaseScore, this implies that the named
-        participant has a broken client or is cheating.  Report them to
-        authorities if they do this more than once.
-        """
-        self.scores[participant] -= 10
-
-
-    def anyAuthority(self, authorities):
-        return self.connectPeer(random.choice(authorities))
-
-    def verifyChunk(self, name, who, chunkNumber, digest, authorities):
-        return self.anyAuthority(authorities).addCallback(
-            lambda authority: authority.verify(name, who, chunkNumber, digest))
-

=== removed file 'Vertex/vertex/statemachine.py'
--- Vertex/vertex/statemachine.py	2005-08-07 03:21:44 +0000
+++ Vertex/vertex/statemachine.py	1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
-# -*- test-case-name: vertex.test.test_statemachine -*-
-
-NOTHING = 'nothing'             # be quiet (no output)
-
-class StateError(Exception):
-    """
-    """
-
-class StateMachine:
-
-    initialState = None         # a str describing initial state
-
-    states = None     # dict, mapping state to dict of str input: (str output,
-                      # str new-state)
-
-
-    def __init__(self, initialState=None):
-        if initialState is None:
-            initialState = self.initialState
-        self.state = self.initialState
-
-    def transition(self, oldstate, newstate, datum, *a, **kw):
-        if oldstate == newstate:
-            return
-        # print hex(id(self)), 'Going from', oldstate, 'to', newstate, 'because', datum
-        exitmeth = getattr(self, 'exit_%s' % (oldstate,), None)
-        entermeth = getattr(self, 'enter_%s' % (newstate,), None)
-        transmeth = getattr(self, 'transition_%s_to_%s' % (
-                oldstate, newstate), None)
-        for meth in exitmeth, entermeth, transmeth:
-            if meth is not None:
-                meth(*a, **kw)
-        self.state = newstate
-
-    def input(self, datum, *a, **kw):
-        oldstate = self.state
-        if datum == NOTHING:
-            return
-        try:
-            output, newstate = self.states[self.state][datum]
-        except KeyError:
-            self.invalidInput(datum)
-        else:
-            OLDSTATE = self.state.upper()
-            NEWSTATE = newstate.upper()
-            DATUM = datum.upper()
-            self.transition(OLDSTATE, NEWSTATE, DATUM, *a, **kw)
-            self.output(output, *a, **kw)
-
-    def output(self, datum, *a, **kw):
-        foo = getattr(self, 'output_' + datum.upper(), None)
-        if foo is not None:
-            foo(*a, **kw)
-
-    def invalidInput(self, datum):
-        raise StateError("Invalid input in %r: %r" % (self.state, datum))

=== removed file 'Vertex/vertex/subproducer.py'
--- Vertex/vertex/subproducer.py	2005-08-10 18:49:01 +0000
+++ Vertex/vertex/subproducer.py	1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
-# -*- test-case-name: vertex.test.test_subproducer -*-
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from twisted.python import log
-
-class SuperProducer:
-    """I am a mixin which provides support for mixing in several producers to one
-    producer.  I act as a consumer for my producers and as a producer for one
-    consumer.
-
-    I must be mixed into a protocol, or something else with a 'transport' attribute.
-    """
-
-    producersPaused = False
-
-    def __init__(self):
-        self.producingTransports = {}
-
-    def pauseProducing(self):
-        self.producersPaused = True
-        for transport in self.producingTransports.keys():
-            try:
-                transport.parentPauseProducing()
-            except:
-                del self.producingTransports[transport]
-                log.err()
-
-    def resumeProducing(self):
-        producersWerePaused = self.producersPaused
-        if producersWerePaused:
-            self.producersPaused = False
-        for transport in self.producingTransports.keys():
-            try:
-                transport.parentResumeProducing()
-            except:
-                del self.producingTransports[transport]
-                log.err()
-
-    def stopProducing(self):
-        for transport in self.producingTransports.keys():
-            try:
-                transport.parentStopProducing()
-            except:
-                log.err()
-        self.producingTransports = {}
-
-    def registerProducerFor(self, trans):
-        if not self.producersPaused:
-            trans.parentResumeProducing()
-        wasProducing = bool(self.producingTransports)
-        assert trans not in self.producingTransports
-        self.producingTransports[trans] = 1
-        if not wasProducing:
-            self.transport.registerProducer(self, False)
-
-    def unregisterProducerFor(self, trans):
-        if trans in self.producingTransports:
-            del self.producingTransports[trans]
-            if not self.producingTransports:
-                self.transport.unregisterProducer()
-
-
-class SubProducer:
-    """ I am a mixin that provides upwards-registration of my producer to a
-    SuperProducer instance.
-    """
-    def __init__(self, superproducer):
-        self.superproducer = superproducer
-        self.producer = None
-        self.parentAcceptingData = True
-        self.peerAcceptingData = True
-        self.producerPaused = False
-        self.parentStopped = False
-
-    def maybeResumeProducing(self):
-        if ((self.producer is not None) and
-            ((not self.streamingProducer) or
-             (self.producerPaused)) and
-            (self.peerAcceptingData) and
-            (self.parentAcceptingData)):
-            self.producerPaused = False
-            self.producer.resumeProducing()
-
-    def maybePauseProducing(self):
-        if ((self.producer is not None) and
-            ((not self.peerAcceptingData) or
-             (not self.parentAcceptingData)) and
-            (not self.producerPaused)):
-            self.producerPaused = True
-            self.producer.pauseProducing()
-
-    def parentResumeProducing(self):
-        self.parentAcceptingData = True
-        self.maybeResumeProducing()
-
-    def parentPauseProducing(self):
-        self.parentAcceptingData = False
-        self.maybePauseProducing()
-
-    def parentStopProducing(self):
-        self.parentStopped = True
-        if self.producer is not None:
-            self.producer.stopProducing()
-
-    def choke(self):
-        self.peerAcceptingData = False
-        self.maybePauseProducing()
-
-    def unchoke(self):
-        self.peerAcceptingData = True
-        self.maybeResumeProducing()
-
-    def registerProducer(self, producer, streaming):
-        if self.parentStopped:
-            producer.stopProducing()
-            return
-        self.producer = producer
-        self.streamingProducer = streaming
-        self.superproducer.registerProducerFor(self)
-
-    def unregisterProducer(self):
-        if not self.parentStopped:
-            self.superproducer.unregisterProducerFor(self)
-        self.producer = None
-

=== removed file 'Vertex/vertex/tcpdfa.py'
--- Vertex/vertex/tcpdfa.py	2005-08-18 16:10:42 +0000
+++ Vertex/vertex/tcpdfa.py	1970-01-01 00:00:00 +0000
@@ -1,96 +0,0 @@
-# -*- test-case-name: vertex.test.test_ptcp -*-
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from vertex.statemachine import StateMachine, NOTHING
-
-# States
-
-CLOSED = 'CLOSED'
-LISTEN = 'LISTEN'
-SYN_RCVD = 'SYN_RCVD'
-SYN_SENT = 'SYN_SENT'
-ESTABLISHED = 'ESTABLISHED'
-CLOSE_WAIT = 'CLOSE_WAIT'
-LAST_ACK = 'LAST_ACK'
-CLOSING = 'CLOSING'
-FIN_WAIT_1 = 'FIN_WAIT_1'
-FIN_WAIT_2 = 'FIN_WAIT_2'
-TIME_WAIT = 'TIME_WAIT'
-
-# Network vocabulary
-SYN = 'SYN'
-ACK = 'ACK'
-SYN_ACK = 'SYN_ACK'
-FIN = 'FIN'
-RST = 'RST'
-
-# Application vocabulary
-APP_PASSIVE_OPEN = 'PASSIVE_OPEN'
-APP_ACTIVE_OPEN = 'ACTIVE_OPEN'
-APP_SEND_DATA = 'APP_SEND'
-TIMEOUT = 'TIMEOUT'
-APP_CLOSE = 'APP_CLOSE'
-
-# This isn't detailed by the spec in the diagram, so we use a different
-# identifier, but in various places it does make references to going straight
-# to the 'closed' state.
-BROKEN = 'CLOSED'
-
-
-class TCP(StateMachine):
-    # dict, mapping state to dict of input: (output, new-state)
-
-    states = {
-        CLOSED: {
-            APP_PASSIVE_OPEN: (NOTHING, LISTEN),
-            APP_ACTIVE_OPEN: (SYN, SYN_SENT),
-            },
-        SYN_SENT: {
-            TIMEOUT: (NOTHING, CLOSED),
-            APP_CLOSE: (NOTHING, CLOSED),
-            SYN_ACK: (ACK, ESTABLISHED),
-            # SYN: (SYN_ACK, SYN_RCVD),
-            },
-        SYN_RCVD: {
-            ACK: (NOTHING, ESTABLISHED),
-            APP_CLOSE: (FIN, FIN_WAIT_1),
-            TIMEOUT: (RST, CLOSED),
-            RST: (NOTHING, LISTEN),
-            },
-        LISTEN: {
-            APP_SEND_DATA: (SYN, SYN_SENT),
-            SYN: (SYN_ACK, SYN_RCVD),
-            },
-        ESTABLISHED: {
-            APP_CLOSE: (FIN, FIN_WAIT_1),
-            FIN: (ACK, CLOSE_WAIT),
-            TIMEOUT: (NOTHING, BROKEN),
-            },
-        CLOSE_WAIT: {
-            APP_CLOSE: (FIN, LAST_ACK),
-            TIMEOUT: (NOTHING, BROKEN),
-            },
-        LAST_ACK:  {
-            ACK: (NOTHING, CLOSED),
-            TIMEOUT: (NOTHING, BROKEN),
-            },
-        FIN_WAIT_1: {
-            ACK: (NOTHING, FIN_WAIT_2),
-            FIN: (ACK, CLOSING),
-            # FIN_ACK: (ACK, TIME_WAIT),
-            TIMEOUT: (NOTHING, BROKEN),
-            },
-        FIN_WAIT_2: {
-            TIMEOUT: (NOTHING, BROKEN),
-            FIN: (ACK, TIME_WAIT),
-            },
-        CLOSING: {
-            TIMEOUT: (NOTHING, BROKEN),
-            ACK: (NOTHING, TIME_WAIT),
-            },
-        TIME_WAIT: {
-            TIMEOUT: (NOTHING, CLOSED),
-            },
-        }
-
-    initialState = CLOSED

=== removed directory 'Vertex/vertex/test'
=== removed file 'Vertex/vertex/test/__init__.py'
--- Vertex/vertex/test/__init__.py	2005-08-05 06:04:09 +0000
+++ Vertex/vertex/test/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-# -*- test-case-name: vertex.test -*-
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-

=== removed file 'Vertex/vertex/test/mock_data.py'
--- Vertex/vertex/test/mock_data.py	2005-08-05 06:02:56 +0000
+++ Vertex/vertex/test/mock_data.py	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-data = '\xab\xcd\xaf\x14\xe14\x9d\xba\xd72\xc4\x16\xde\xd7\xcd}\xf8\x9a\x1b*?\\\xcf\xcdsaK\xe3\xcd\xf0\x011\xf3\x99\x90\x85M\x0fgk\x16\xfb\x18\xd5\xd1\xec\x85\x077\xbc@\xa6}z\xa3v\xd9A\xce\xfc\xe9\xf4\x0f^\xe0X\x9f\x13\xcb\xe0|7\xa0\x12\xc8&\x95{\xbe\xe8N\xee\\\x0b\xc7\xb1\x811\xfe\x1cT\x0f\xf0\xb2\x02\xc4\xacd\xe2A\tk\x9co#A\x9a\x0e\xbd\xa6\xc3\x9e{$\x98\xa0m\xc6\xc7vl4\xd6x\x04}\x8c*w\xf4\xc3\xb7!\x17\xb4\xdd\xf1\xbd\xfdk/_\xaeVm\xcc\xf4y)\xf2\xbf\x98]\x94$\x050y\xf0b\xa4\x0e\x89\x1e\xdb\x9bz\xcd^j\x91\xf8\x01\xc2\xcee\xb9\xf3\xb1HqT\xb5A\x8a\x89\x96o\xdfm\xb9\xc1nM\xeay\x01\xefn=\x9e\xfaS\xc7\x7f0Xi\x17"S.\xb2\x9fL\x93\xfe\xb4?\xf8j\tK\xbdp\xbdv\x15\xa8}\xe52\xbcO\x04\xff\xfa\xda\x8c\x83\xe2\xdd7\xbaF\xb0=\xd0M\x82\n\xeb\xaf\x06\xb8"\xe4Yxt\xd9H9\xa8\xe8\xc2T\x87\x08\xc3\xd6\xc7\xf9\xf5K&D\xb0\xae\x9c\xe4FCn\xaf\xc7\xe1h2\xd1\x9aJ#\x07\x05@9\xf78i:\x04z\x01e.\xdb\x01\xb0at\x1fe\x86\xfe\xed\x94\xedc\x11\xe2\xed(o\x0b\x82\xc7\x8a\x02\xaf\x90c{1\xedNB%Z\xe9\xea\xa2\xbf\xdc\x95\\kv\xd6\x17(\xa0\xa39\xc2\x8b\xb8\xd9\xd2B<\x94`\x07|\xce\x11\x0f\x151\xbf]^\xc1>\x08\x17\xde0\xdc=\x16\x84s\x90\x83\x8cT\x0b\xe5\rER\xb5\xe4$\xff\x91\x1dl\xd5\xdd\x82^H\x9a_\xde\xdc\xc4\x11\x88\xd6\x9cp\xba\x05\xd3`\xfb\x9e\xe5^\xba\xd5\x0c\xcd\xa1\t\x83\xdf\x85\xbcy\xeel\xfa\xa5\x00\x90{fG\rl$s\x98\xbc\xd7"\x95\xf7\x94K\xa7\xe6=\x1a\xeb1\x00\x97\xc8\x94\xf0\x11\x8b\x16wv#\x12\x0e\xca\xf4\xb36oc\x1a\xaf\xf2%\xaf\x9f\xc1 N\xb8D.\xf0\x85|\xc8Oj]\xc1\xe7(!\xb8\xb8\x9a\xbc\xd4\xc5\x0f+\xcf\x14\x86\x1c\xc5Jx\xf7\xefNSV\x01\xbb\xfb\x82\x9eZ\x809\x9a\xf0C\x05g\x99!g\xcdVQ0\'0\xa4$\x04W\xbbE\x92\xb8\x971\xc1\x1cd\xaf\xf8\x9e:\x89\xf4\xadR\xfb\x98\x0b\xf2\x82\x07\r\x93\xb7$\x85\x14&\xad#\xc2s\xbah-xm3@\xe8S\x8a\xeb\xfd5\xd4\xa0O\t%\n\xf35\x13\xe3#.j\xcf\xa4wH\xf8\xb0\x02\x89aN\xe3(\xcd\x15s\xc6\xa8\xac\x0b\xa0\xe5\x97%\xcc\xc7\xc8\x93N\x86\x02#,\xf2\xa9\xe3q\xff\x99\x1f+H\r\xf5o<\xe41OKc?\xae\x15\xdc\xbb\xc8\xdd\xa0\xc1\x8f\x14*\xcd\xa3\xba\xc5\xb2\r\xb3\x0fu\xc6\x83f{\x91\x0b\xa1\x9c\xbd"3\xf2l\xb2\x81\xe5l\x10k0`\'\xc1Su\rk\xe92U\xa2\x87J\xb1\x02\xf0\x90%XY\x02s\xc3:\xd5F9.\xd7\xd1IP\xd9;\xccP\x0c\xdeI\x14\xa11\x90\xd9y"\xf3L\xb7\xe8\xb0\xca\xe2Y\xe8\xe8b\xb9\xa4\x14o\xad\xe7\x16\xc4|x\xb0H\xdd\xa2J\x8b\xda*,\xee\xb1\xee\x00 [O\xaa\xc0\x00\x8999mj\xb8\x84\xe1\xd4\xf2Z$3#\xac\x8f\x93P\x0b\xd9\x8a\xd2P\x1bk\xa8\x1f-:\xb1q"\xeb\xf4G=dS\x94}L\xc5\x9e=r\x0fO+\xbc\xe5\xd8r2\xd0\xf1r\xdf\xf1\xdf\x88\xa3AC\x89\x99\xc5s6\x1b\xf7u\xc3\xf1J?R\xd5_\xad\xa9\xfe<%\x89]Z\x04\xe8\xac/Z\xfbm\x83)m\xeev=\xd6m\xd6Y\xf0\xaaJ\'\xce\x1d\xd0t$gs\x17E\xa1\x81\xb5\x15\x85\t\x06\x02%\xdd<\x05\xe4\xb5\xba\x83\xe6\x99x\xc9^]\x02\x012p)/\xcdQM\x14&`\xc7)\x8e\xb4~\xf1\x16P\x1e^\xbe\x85\x87\xa0\xd8\xa0NI\xb69!!F\x03\x89t\xdco1\xc5c\x01\xbc\xe9\x0f\x1c|\xc0\x15\xaed\xc6\x18c#\xf42\xc1R\x00 \xe1\xc5\xed\x12x\x1f\xc7jV\xb7\xd704-\x9b@\xa5s\xa51\x03>\x8b\x02\xda\x84f3r@\xa1\xe9t\xea\xd7d\xa7\x86PS\x81B\xe2\xafKw\x95\\\x7fv\r\x9aC\xeb\x99\xcf~\xd2\xc1g\x8e\xbeXmK|\x05\xd0*\x11\xa3up xt\xe0\r\xb8h\tm\x8f\xf8B<QlQ\x18\xc7\x85\x99\x98\x14\xec\\>#\x8c|\x86\x84\xcb\x0b\xa0\x9a\x1c\xb2\xadv#zfeL\xd9\xa5[\xc5s\x01w\xa9\x7f0\x7f\xa2\xef`e\x1c3\x9d\x17\x8d\x1e\xf4\x85\x9b\xc2H\\\xc8\xe2b1\xc0+\x99\xab\x10p-\xaf\x00\xf0ip\xc8\x06GaG\x1b@\xdc\r|\x7f\x1e\xa7\xa8Y\xc3\xa7Dr\xac<\x93\xe2\xd4\xdc;\x02\xff1\xa9\x9d7X\n6\r\x96\x94\xa3\xa9\xf8e\xbc\xcab\x17\xcd\xc4\xb3/ \x0f\x9c\xe0\xb4m\xf3\x9e\xaa\xc2\x02\xecD\xdc\xbah\xf0\x9a\x99V<\xe4\xef{\xa5\xceB\xf3q\xef\xb31\xd8\xd3\x13\xf9\xf1s\xd7\xc5\x80\x06\xa4{\xdc%\x163\x14\xee\xcdx\xee\xdc\x8d8\xae\xe3l\x97\\\xb4\xd5\x0b\x965\xaf\x1d\xd9\x7f\x97Fptb\xeb\x0e]-c\r)%\x1b\xddBr\xdf\x1b\x1a\x18\xb7|\xed2\xf7\x0c\x8d\xa5\x94\x16\xce>\xd5mI\xfd\xd7,\x17\x1a\x89\xa0Y\x88\xbcE\xa1H\x82\xeb\xf7\xf5\x99\xb3l~W[I\x81f\x90\x17\xc0\xbd\xb8\xac\xee\xb9uQ\xe2\xb4`\xf5\xfb:\x17\x86\xf5\xe7\x85\xad|s\xdb\x1e\x81\x03sq\xf1\xd1\xcb\x8fx\x95\xef\xefJ4v\xbe\xc9\x9b\xf5\x8cLP\xd0\x8e\xbb\xe2w\xef\xaf\xc0\xa08\x93\xb2\xd7\x1b-fP\xa2\xba\xde\xc5\xa5^\ng1c\xeeS\xb5\xff\xf8\x10\xde\x87\x0f\xe5\xd8\xec\xb4\xfa=+\xc6\'\x9a\x80n\xf6\xe4\xcd\xcb\x93\x04v\xd87\xa3\xe63\xc9X\xd2\xff\x7fK\xeaw\x80\x8b\x01#\xec.\x13w\xc0v\xb4\x97V\xf4\xa3\xe4\xc7m\n\xa8\xad\x94\xa2\xc8\xd5\xd4\xba}\x13\x17\x9f4\xe4k\'\xba[\xfa\x19\xfe},\xa3j\x00\xc4\x99\xaeT\x1a\xa5\xc6p\x00\xbc\xb1\x06\x08\xf6=\x07\xa7|\x057\xf2|\x86\xe24\xacs2\xdeD%\r\xf0c\xe5\xc0\xb5\xa8\x850*\x0chK|\x89\x1a \x17v\'\xe3\x96M\xfe\xb5d\x88\xfe(\x9d\xea\x01@\xd9\x16\x00\x87\xe8\x0c\xbdhX\xf9\x02\xe3\xdd\x06i\x98\xaaz\xed\xb5\xa8<\x1a\xd6\x18f\x00\x9du$\x03P!p5b\xa5\xc6~\xe1\x8e\xd6\x03e\xdf\xba\xb7\xfaB\xcb\xb0uz\x88\t\x0e\xc7\xa9\xb0\xe4\x17\xf8\xfe\xf8\x14\r\x99\xf0} \xdbWE\xd8\x96\x05\xa7\x86|\xa3g\xb2\xb4\xfd\x16,]\xed\xed`\xab"\xeb\x97=\xbf\xaf\x96T0\x14\xdf\x9d*\xfbA\x9aK\xa7\xb1M\x16\xba(\xa6\xd6\x87e\xbe\xed\xc9"\x93\xeev\xda@(,:9EM\x81A\x04fH|ajjjjjjjjjjjjjjjjjjjjjjjjjjjjjTue\x96V\x83U\xf7\xad%g/P?\xbe{Ty\xe4\x04\xe3\xf3\xe0\xc2;\x8b\xc0\x89\x8c\x8c$\xac\x1eZ[\x056siZ\xbd\x18\xd9\x89\xf5\xb6\x99\xcbW\xf2L\xb4\x9c\xb6\x7f\xcaT"\xcc%0\t\xd4\x07\x9b\xc2\x92\x1e!a\xdd\xdcaM\x9ekA\x9b\xaad\xbbq\xe4\xa7L_\x84(\x96R\xae"\xfc\xd8^\x94\xbe\xf41t\xb9\xd8x\xb3\x95\xce\xdf\x8f\x80Z%F\x84\xc4R\xa0\xe3\xd4\x9e\x0b\xe2\xcf_\xa6\xb4\r\x06\xde\x96\x0c\xcb\x1f\xe6V4%\xb4\x98\xad\xe0\xb8\xe1[\x9d\xfc\x08\xd8\x02\xa6k\x99.\xf4\x14E.\x10\x14\x0f\x9a\xe2\xd6s\x97\x00\xc8\x14\x91\xfe\xd1\x8b\xb9\xe7\xe3\xf1\x8du\xd99\x83\n\xbe\xd1\xa8\xc8m\xe9shFlqv\xfd4I\xd6\x97-\xdcp\x94\xb8\xbb\x1a\x86\xbe\xceT6\x81\xc2\xc9\x91\xd5#\xd7I\x8c\x1b1kqL\t\x8a~\x98\x99\x1c\x85\xc9\x9fE\xd9\x1c\x0c\xf6\xd8J\xff\xac\'\xd8\xd1\x90\x00\xa9?\xe0\xe2;\xc9\xed\xd6\x08\x15\xff\xf0R6\xe6\xabt\x92\xda7\xab\xdau"^a3\xc8\xa0\xa3Zx\x1b\xd6\x802\xf2\n{w\xdd\xb1C\xa7\x8a\x00\xcb\n\x95[\x0c~g\x95K\xbc.G\x91-\x8c4\xaf\xa0">F\x0e\xb9\xd2@\xf5\x16\xa8VA\xb7;\xe2\x9bg*\xb6\x1c\x1c\x9c\x1c\x82\xf9\xa4A\xe4j/\xf0bG$|\x1c\x8f\x95\x87\xe7\x92\xb0g\x82X);HcY\xe1x\xa6tU\xe8\xa1\xdb\xa1\x8bv\x18 \xb7\xb3b\xff\xc4\xdf\xaa\xb9\x17E\'U\x0c\x07q\x86R\x05_\xc7}n\xd1U\xba\x06G\x93\xadG%F\xcb\xe3x\xef\x17\xeec\xed8n0\x1b\xed?\xc9\xae\xf9\x8d\xf5O\xf5\xddg\x84{l\x83\xef\x93\x1e\xeeUD\xca\xddN\x9fM8\x99\xed\x1c\xa8e\xc3\xe9\x10f\xcc\xcf\xbeDZTS\xa2M,\xb3\x82b\xd8\x01\xd2\xdc\xdc\n\x03%\xc9\xa9\x91\x8f\x93A\xf8l\x7f\xe9\x13\x94<\x0f\xd2\xd3\xca.[\xb3e\xc0\x9b\xb7\xae\xba\xb8\xe2\x07\xfdO\x05\xd1<\x10\\\xf8\xb3\xef\x8f\x88\xb1;\xf9\xe3\x85{zP\x02\xdc\xd6o\x84\x0c\xa5\x85\xc9}T\xe0S\xcbd\x9d\x87FOt$6\xfd\xb7\xfb\x05\n\x91\xfe\xd8\xd1\xab\x93G\x99\x9a\xfd\x08\xcc\x01\xec\xc2\x06>\x8c\xba\x936To\x89\xe5\xf3\x04I0g\xa8\xbb\x85\x0b~u\xca\xc7s\x9e}\x96*:!)\x17\x02\x0c\xaepGu\xcd6\x81}\xd8\x98\x03\xcdQ{w\x92\xe5\x03\x87\xc4\xc3yW\xa2\x1c^*\xf8*\xf1\xc1\xcd\x18\xfa\x1d\xc6]\xb6\xd89\x84y*x\x8a\xf9C\xa9\xf5\xc36\xb8T\x06N\xd0\x8aq\x02\xebH\x03 \xac\x1e!v\xeb}\x974\x0b8\xb5O[8c\x84+7\xd6\xdf\xa2\xf9:k\xf1\xb4\x8a\x83\xd7\xac\x9e(\x1e:YZ|6\xcd\x112\x1d+\x84\xa1\xe3\x87B\x04p\xf0\xa7^\x16\x13\xf5\xb60\x91\x07\xfd\xbdq\xcb\xcd\xb5.\x81\xe1\x8c\xba\x16\xb0\xa7\xb7@J\xbc7\x1f\xa1,\xdd\xc3\x0bK\x89\x14\xc9\xe3\xdf\x0f\xc6Y\xf4\xb8L\x1f85\x9d\xdb\xe9\x1ay\xb1g\xaf\xd6\xa1#\x02\x8b\x1cq\xd2D6a0\x87\xdb\xd6\xd8"OI\xa8n\xc5\xbf\xdf7Qyd\xc4\t\xa6B\x0b\xab\x0b\xf7\xdf\xdb5/\xfd\x89\x04\x18j\x88\'M\x89%H\xc5N\x9e\xa5q$4\x1fWrF\x1f\x89\xa9\xf6_rK\xbcd\x8c\xf5\xdak\xf8R\xab\'z\xd0\xe7S\xe6c\tT\x18\x88\xcc\xed!\xdfPN\x00J\xd2\xba\xe9O\xc5hYG\x9e\x81\x9d\xbe\x17Xy\xe4G_l\xeb\xa5\xea\x11o\xf6\x11u\xb6\xb9Q\xe5\xfb\x0c\x15W\x08\x82\xcd\xb9\x9f\x19\xa2\xe2\xf8\x19fffffffffffffffffffffffffffffffffffffffffff\x01\xbbN\x85\x0ce4\xec\x1d{\xd9D\xb2\x1a\xe2\xc7\xb7\xed\xfe\x91H\xf2\xa3\xd7|\xb1\xdd~\x1e\xf3\xfc\x82\xb7B\xae~\x9f\xa5\x05\x8cM6e\xce\xf6*\xacw\x9d\xe2\xdcF\xdf\xe4\'\xb0\xd1\xae&h\xd6x\x04!e\xded\x1c\xc9\xbe\x06/\xf4\xd0\xd8Z\xf32\xe7_\x8c\x85\x07\xc3\x0f\xbd,\x7f0\xbc\x04sit\xd9\xde\xdeV\x06+\x8d\xb6\xca\x82\xba\xf64\xf6\x91<\x16\xbd]\xa0\xa8\x1d\xdc\xdd\xaamM,\xda\xfb\x92i\xe7\xa2F\x9eN\xc7\x06\xf6\x89p\xd1 \xd8\x9b\xa1\x899\xc4\xa6\xf8U\x19\xa0\xe4D\x9e\xca\x83\x9e`i\xedL\xf2V>\x82\xfaD]b\x12\xeb]\x98\xcc\x836\x19\xc3\x14\xc6\x8f\xb1\x16\xa1\xd3d\x032&\xb7\x1foO/*o\x98\x1b\x7f\xaew\x8cv=\xb1\x17\xe5\x14\\\xe1\xc4\xf8?^\xa9)1+BB\x81\xfci\xf7\xcbf\xe3\x17|-F\x82\xa3\xb7\x91\xba\x1738\xcba\xfd\xea\x99\xefa\xe2V\xfa\xd7\xf4\xdc\xda\x10A\xa3\xc7\xa62\xae\xcb\xc9\x7fa\xcb\xb8+@\xd1T\x96\x03\xa3\xa1~)\x85q\xdc\xd8\x01_\t\\\xc0\xf3\xbc\xb2a\xab\xab[|\xb8\xf4\x8b\xe3_y\x0b\xf0\x10r{\xdb\xb6L~\xc4\x01\xd6\xb2\xab\xfc\xbbh\xf0\x01\xdd\xd0S\x08i\xc6\x14\xad\x04^}\x16sKp\xecEq\x048{=\x8f\xcb#\x94\xc7\x85\x0e\x92\xaf\xcdA%4\xf4\x99Ht\xe9\x8fY\r{\xc2\x9d\xf8\xf1o\x1f\x96:X6\xf8#\xc3\xeb\xf2\xf0\x89\xa8\xf6\x13\xbb\x92\xa1\x1bPn\xea\xa5\xc6\xa1\x18o\x92\xc9\xc6)p\xd3)TO!#t\xb2LB\x92F\xe1 N\t\xf7\xf6n\x18\t\xd0\x19\x8a\xe0\xee \x19\xc1 \xa5\xab\x0cbZ\x95\xeaX\xea$\x1c\x93=\xa7t0\x08w6%\x88C~B\x1dY\x05\xb3\xe2\x03P/w\xe6\xc8}\xe4+\xa2\xac\x82\xd3~\xb9T,!\x1c\xf4J\x0b`\x99\x8e0\x18\xf9zr\xca\x82;\xc1\xe66X\xe7O\x1d\xf9vl\x0f3\xdb\xd9-\x88\x8c\x92JY\xfd\xc4N\xf1\x0e\xfb\xe2\xab-\xd3\x90\x894 \xb8\xb8\xcf\x8az\xb6}\xc6(\xad\xd0\xbak\x06\xbeGp\x0c\x00/\xe6\xf8`\x1b~9\x9b\x9ea\x1a\x0fS\x1d5\xc4\xf9O\x81l\xaf\x9c\x15Rgp^\xed\xfa2O\xdbM\xc9q\xe8\x0e\xc1n\x81\xb1\x1f\x86\xf1\tSC:\x8d!`O^\xba\x7fq\x83-W\td\xcfBP\x86\x0eg\x80<\n>\xc7{\xeeL\x83\xe4W\xcb\xc4\x9a\xed\xa0\xce\xb2\xccS\x0b.\x1d\xc5*\x92\x88\xf7\xac\'N\xc4\xe1\xadn\xdd\x15\x89(\t\xcd\xde\x1bP^d\xa4YJY\xda\xf5C\xce\xbdff\x83\xc0Z\xbe\x106\xc1\\\xd0\x08\x95\xa7\xde\xa6\xd9\xc8pg\xea\xde\xc2\xd7w\xfb\xdf@\xc3\x07\xd1n\xcd\xb2u\x15\xf3,W\x01\x8e\xa5NT\x16\xb2\xbcc\xf1\x01\x8dP\x85\xe6\xd9\xd7[b\xae\xb7\x9cE\x11AD\x9b\x18\xc25*n\x06\x97\x98\xc44wP\x85\x94\xa4\x07\x98\x18\xe0k\xba\xec\x88\xae\x93c\x93$\x8d\xb3\x8d\x10\xfb&Y\xb6\x98W4\x8b\xb6\xad\xad\xa7\xe2\x1bc\xf1\x13\x8f? _\xfc\x0f\xf2\xadK\xc8\x93\xec_{\xc18IMEw\x01N\xad\x19;\x01\xbf\xd6\xa4\xd2\x12\x85`1\xbf\r\xb7\xab\xf0Wupx\xd1\x0b\xf7c\xfe\xc1\xf8\x94\xb4\xe0\x11\xc4\xf1\xf9_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\xf1\xf2@\x87\x1b\xb7-\xb9\x08Q\xefh\xaa\xef\xde\x06\xc8\xbf+\x02g\x9f\x91\x8c\xfc[\xc0\x92H\x8cym7S\x94\xd5q\x12\x03\xaav\xb0\xb2\x86\xca\x99\xadfb\xda(\xe1\x97>U\xb6&\x1ff\xde\xaf\xf5\x0c\x857\xb0\xc8A_\x84\xfa\xd3a\x80F\xc8\x91\xd2\xdf\xee}\x9b\x16\xf3\xd7\x05q\x8e\x08uZ\xf0\x8e\xb8^|\xa6\x05\xcd\xc3}\x81_zQ\xe6\xdeY\x14:o\xc0\x94\xa2\x831Tk\x88H\'\x16j$\x155]T\xfc\xbc\xa1\xb7\x89A5,\xe9;\x8a\xe0c\xab&a\xf0\x87\xcc\xa5\xbd\x16\r/\x81\xe7\xde\xb1&n\xe9\xd9CEu\x1f\xc8p\x8e\xb6\xfd\xa1\x9d\xd6(j\x16<,Li>\rA[Ks\xdd\xea\xbe\x94\xb8\xaf\xf8\xb65\xe5:\x88\xa4\x1d\x084Y\xfb\xe4\xf5\x11uM\xa2+\xc9h\xfb\xac\xfbX\xc2F*\xf4\xaa\x9b!|"O\x8fq\x04\xb0\xc2\x89\x14\xa1#t\xf5\x16\xcbm\xfb\xb1\x9de \xe26\x86>X\x11\xc9\x9c\xe3hb?\xc0P_\x979L9\x86F\xf1[\xa8\xac/!5V\xd7\x10B\x10\xa3\x95\x81\x05\xc2;\xac~\xa9EOB3\xe12\xa4\xcfe\x90\x1ez\x8c)\xbf\x06\xc1\xad\xc1\xef\xbb\xc0\\\xdb\xdbNV\x1a\xc7TV\xc6\x01f.4\x8e=\x8f\xc5\xc6\xde@\xd4\x8e\xdbc!2\x05\xd8\xe3\xfd\x13B\xe2\x8d_*\x95mM\xda\x8aFbj^Bq\xc9MV\xd6\xb1;\xaev\xfd\x0f\xd7Df\x0b\x16\x8dQo\xe9\xadF\xdb\x93c\x04\x80\xb3Cc\xe8b\x82\x89\xdc\x87z%\x04\xa2\xcd\xc6&\xf09z]:\x9a;}L\x1e\\zz\xfe\x8a4!O\x14%\x95\xe3\xadA\xe0&X\xb6\xff\xce\x000\xf3\r\x0e>\xc4cdp\xc7\x8f\t\x1e\x87\xe2\xd5"\xae\xd4T52\x9d\xe3\x08<\xc4\xad\xb9\x1b\x86\x7fQ\xfa0w\xe9Y\x8f>&\xaa4\xa3\xc3\xb8X\xf7\xe3s0B\x0f\x1aG\xd3\xc5\xd6\xefU \xa1u\x90)v;\x08\xd4\x96\xc6\xe6.\x7fd\xc3\x9alr\xfe\xbc]BJ\x8c\x0fUi\x8a\xca\xf9\xe2IP\x9d\x0b\xa9G\xf9h\x19\xa0\xfb\x16f\xa0A\xdaC\x87x\x80U>|:m\x7f@\xe6\xf29_\xe9\x1f\xbdi/\xbe\x05\x80\xda\x18\xbf\x13F\x03\xb8\x0f\xf5\xa6j6\xe4\x92\x06\x81\x81*\xec\x9b\x98_/\xe1\x1d\x0b\xdbQ\x00\xb5 \xca \xe7\xc5\x0e:\xa3r\xb8\x1d\x0f\xd3\x83\xd7\x83\x97!\xed~\xa3\x1dL\xf3U\xc5\xe5\xd9\x1dw\xd1Wy\x83:`\xf0A\xfc\xa2\x16\xd9\t\x9cp\xfa}\xc3\xc3\x0c\x9e<d\xb6\x96[\xcd\x7f\xa2\xc2\xc5/Y\t\x0e\x82\x8e\x0c\xf2\xe1\xc3\x8f\xb2\xa1\xa47\x8f]e\xd5\xdfN\xc2\xec\xe0\xd9\xf6\x15Z\xeb(\xbax\xb3\x87#\x0b[5\x16\xc1\xeb\xe3\xe1\xe0\xbb$\xaa\xb7\xa4U\xfb_KF\xe5\xcc\x17j\x089l\x90\xfaR\xf7\xa7\xa2\x82\xee\xba\x8b\x16\x88\x06\x1c\xd9\x8c\xb0\xc1C\xd3\xe8\xf0C\xd5x\xba\xa0\x00\xa3D\xee\xe4Z6\xd9\xbe\xaa\xee\x1c\x84)\r\xec\xa3\xe4o\x06$\x98\xb0&\xc5\xb2\x97MxI\xd2%\x9e\xd6{Q\xcd\xe0\x04_\xc6\xf9\x82\x9f+_\x8c\xd8\x0e\x89\x8d\x13\x16DS\x0f\\f9\xe0,s\x12cS\x84;R\x18D\xa2\x92k\x15\xbcw\xd6\x14\xc2\xef\xfaA\x1c\x14\x9b\xd4e\xc0\x02\xe9\xde%[\xa8\xc6\x06\x05\xe7D|\xcaO\x7f\t-Dr\xd4\xb8\xcbC\xedkQv\xdca\x06\xdc\x8b\xf6\x96\xeb\\k\xdb\xb6\xc7\xda4\x80\xc8\xf9\xaa3\xdc\xc4\xa8k\t\x9fD@\x1a\xcf(\xa3\xc84\xb0\x9e\x82\x1e<s\xa0\x8c\x8a\xfdYM\xcc\x87\xb7Ejy\xdaVED0\xf9\x8f.\xa8\xa22(}\xb5\x9d\xe1\x83r\xab\xde\xa2i6*ka\xca{\x80\x8d\xf9\xf3\xe7\xee\x9b\xda\xa6\xeeN-\x97/?\x91;=\x92\x90Em\xc4\xe3\x81\xc4\xd7|>y0`t|D\xbe\x97\x12\xab/6\xf0"@%\x87>DW\xbfU\x81\xaa\xc2\x05\x8c\xefd\xe0\xa6\xe6{\xd8c\x10\xe9\x8b\\\xf6\xdfz\xbd(>\x10\xce\x18\x05(\t\x7f\x0f\xb1a\xc2\xe7/\x86\x91"y\xa3\x9f\xd0\xa4\t\x8e\xa4\xd4S\xef\xa6(\xd3\x9b\x13\xd6e\xe9\x02\x81N\x02\x92\x08\x10x\x06oF-\xd1\x010\xeb^/\xb1t\xba\x1b\x8a\xcf\x1bH\x03(\xb0\x04\xf7\xbd\xb9\xb4\xbe\x1f\xfb\x0fTq\xbbr\x19t\x08\xfa\xc8^g>\xf3\x1d}pj\x9e\xaa\x0e\x1e\xed\xbf\xac\xa1\x17\x94:\xed\'\xc1j\xb2\xad\xd2\xf1\xb7<13\xaa\xe5\x0fq\x80\xa5\x11\x1ba\xbfO"d\x1d\xa3 \x9a\xa2\x1bUP\x8f\'d\x06\x0f\r\xc6\xa2\x03\xec\xa4^\xdc\xa4,\xf6\x1f&\x91\x96\xa8\x03\x85\x80\xe2Sf\x08\'Us\xe4\xc7\x0e\xff\xf3\xc9~\xa8\x1f\x8a\xae\x04\x04\xc0\xe7\xb7\xc0X\xcd\xbd<t\x8c\x9f\xbb\xe4\xc58\xdc\x95\xd7\x83\xf2\xa45\xbf\xff\x16\x8f\x05\xcc8Ui\xc0\x08\xd3e\xaa \xf4\x86\xa9\xf2\xd6*\x03t!F)\xd2j\x0e\xc22\xd2\x9b\x94\xd9R[\xb1\x1dX\x80\x960\xfb\xd9\x02\x85\x109\xf2\xc5\x1c\xfe\x1e\xa2\\P\xfaH\x91U=6\xad\xb9L\xc6\xa431)\x9em\xf7\xfcH\xa8S\x9f\xa7\x90\xc3+\xe9\xe85\xa4\x07b\xebD\x98\xfaGC|\x85\xff\x19\x1a\x91\x00\x8c\x95- \xb3\xbc\xd4\x99*o\x0f\x0e\xb1\x9d\xfd\xeeC\x90\xc0V{\xe3(Qs\xec\xe3\xf5\x1bx\x1c\x1f\xc6WN\xadh\xb9\xd8\x8b\xa1\x03\x952\x80]a\x1b%\x7f\xdc\xe1\x08!\xbb\x89\xb0\xccVK\xd2\xb4}\x00w\xec2;(\xed\xd4\xf0K\xe0\xd0\xd1B\xb2\x99-\x8e/"\xfc\x00d\xa9\xa4Q\r\xed\xe0B\xb3\x88f\x17\x80\x80\xb5\xc0\x02=\x99\x9b\x87\xacY\xa3\xe2ha\x16\xeaJ\xa6E\x8d\xdd:(\xa4\xc3\xe1\x10\rM#\xd1\xf2\xb3f\xbcT\x9am\xad,\xd9\x85\xac\xe0\x90U\xf0\x16\'\xf44\x01\xcc\xf7\x19\x96N4G\x0c\xf6\xa3\xa4\xdb\xcb\x92\x9b\xaef\xf7\x82\xcfjWx+jC\x08\xfd+\x85\xb0F\xa6\x99\xb2\xe2G|\x96X\xb1\xc5\x8c\x9d^k\xf7\xa9\n\xd0\x1dX?|\xe7_\xf8\r\xd9(\xdf.p\xda\xf8`\x83\x84\xd0\xe7\x14B\x04K\xe1t\xe5n7u\xbd\xd3\x9f$27f\xdaf]\x15\x94\xfa\xcf\xd5\xb4\x8d=\x80\xc8\x9eE\xea\x13\xd3B\xe6\xd2Gr\xe87\xf7E\xf6\xf2g\xa8#\xfc\xb5C\xfb*\xfbE\x8c\xdc\x11\x04 M\xe9\xbf..O\xa2\xbe(\xb6\xb6\xbd\xa12Vg\xb6\rE\xdd\xa2\xd41C\xdf\x88\x0c|\xa8\x1f\xabL\x03P\xdbw\xfc\x91\x0f\r;\x8bl\xa9zWa\x9a\xd76s\xc5\xc9\xddH,D\xb6\\\xa2\x80\xbb\x9fD\xbf\xc6\xaf\x06B}\xef\xe6\x97\x1a\x01\ny\x80\x88\x98\xcc\x86>\xd0\x84\xf2\x08\x93\xd12\xba\xd9\x8dF\x11\x13\x10|\xa2\x00\x96\x05\xf9\x14\x9cy\xea_\xc2\x98\xdav\xe1J}\xdehs@\x80?uF\xec\x93\xfc\xfeG\x1e%.\xe1\xaa\xd3\x1c\xce\xe3\x9d\x7f9\xd3\xab\x88\xea\x95\xe6\x952\xb93\xf8\n\x01\xdf*\xc9Ci\xd2).&\x08s\xec-b\xee\xbf\x04\x88]T\xe4g}\x7f\xdc4\x80q\xce\xfesj/\x18\x95&+\xf8\xac\x18\xd02\x10{\xfc\xc8=\xb5\xed\xd6Wsn\xb5\xd0\x111p\x99\x9f\x86\xf3\x8c\x06t\xf8n2&|\x03\xe9\x93cYx\x94\xe1\xce\xc6E1>S\x05#\xac\xbdz\xdc\xb9.\x82\xc3"\x16D\xd4o\x1a\xbcD\xbd*\xef\xd1W\x1b6\xa0j\x8d_\x8eY/J>\x8c/FN\xd9\xc8D\x95\xa2\xfb\xf5\x1f\x8d/\xa9\x19^\xf8\x1a\x06Q\x88\xca\x08Q\xb8\xb5"0\xa9u\x01pRP\x12\xe88@k(1`\x1b\x07q\xe2\xd5\x0cHE\x86\xe2@l[|\xe3O\xfb\xb7\x1d\xe0j%h\xa8M\'\xdd\xec\x8d(G\xeb\xf5M\x97[\x0c\xd6\x8a\xec\x14\xdf{$\xf0<\x11=\x00\xfb\x0ci/\\\x8er!&\xf9(\xdf-z\xf5H\xef\xef\xf1\x8f\x05\xe3\x8a\xd6!/R\xa1u^\x8c\x9dq\x9e\xb8:\xb4]\x83\xf4\xcd\x1d\x0e\xf20W\xab\xedd\xce\x96\xeb\xcdE\xd3\x9d|\xce\x9epj\t)\xe8\xdc\xff\x94\x03\x11y;\xd3[\xd8\x84Uz{\xf3\'M\xb8\xa9\xceG\xe2P\xf9\n\xd3\x14;\xdeXU\xac\xc6N\xffA\xfd\n\xb8\xa1\xad\x017\x9ch\xbc\x9ff\x0ev\x9f\xb0-\xe8\x9c)\xff\x04\xccG\xcfz\x9d\xbb?JQ\xff\xe6\tY\xe2\xb0\xb8\xa3\x8b\xbc\x8c7\x01\x04\t\xbc\xda>\x82\xe3`\x1e\x0b&a\x9f\x9d\x15\xf69\xde\xf1h\xea}/\xe3G\x95\xc6\x0b\xfdY\x81B\x7f\x93\xdf\x16C3\x95\r\xf8\x11\x08\xa8\xbb1\x06y2}S3\x7f\x86b~\x82\xc3\xcb\xfd\xcf\x94\x9eal\xdd\xf7Y\x12AE\xc3nR%\xb2jH]2\x07KP\x180\xefyPI5\n\xe5$\xe3\x03K0\xe1\x81\xcf\xa1\x17\xeddg:\xe1j\xcb>\xf7\xc9\xa4O\xdbK\xaaN\x17f\xfbNG\xae\x9a\xda}\xfd1\xbf\x8e\x01\x94\x96R\xe7n\xd6\xf1\xf1B,\xe1H\xb90\xbf4\x16?j\x1d\xf6\r\xe7\x047h\x98%(\x05\xfa.L\xa4C\xa4\x12u\xfe\xeb|\xf9\x17\xb0b1\xd1q\x1e\xf2\xa2\x94`O\xd2\x87\x04m\xc1\xf6\x00\xdf\xf4\xd2\xd8\xcc[\xd0Y\xaeD\x97\xb9\x89\x08f_v9\x1c\x9a\x84\xa1a>jT\xea\x1d\x96\x94\x07\xeb\xbe\xddj\xc4\\\x8b\xa2\xe0\xde\xf2\xc9\xac\xa2\x1bN\n\xe4\xc8\xb9\xe7\xd1\xfe\xf0\xd8\x9bR\x12\x93\xdaV\x921\xfe:\xa7M\xbd\xc8R]\xbaMg\xe2\x13\x1c;\xb6C\xd5\xd4\x0b\xc4\x9d\xd4\xe9A\xb8/\xb9\xf7\xb0=\x07I\xd3Gv\xe7]r\x9aT`}e\t\x19\x9c\xea\x0c\xdf\x08\xbf \x84\xd6\r\r9\x04\x15\x1c \xd3\x10p%\x83*F\xb08QS^\n\xab\xf7\\"y\xb3sX\x89d\x12\xa4\x7fk4\x1c{J&L\x95\x0c(\x13z\\\x1e\xecZd"\xfe\xf1AZ\x7f\xb2\xbe\xc6\xfa\xe8Q\xe8fx\x94\x0b\x0b\xba\xa4\xda\x15\xab\xfc\x0142\x9b\xbcf\xf7\xc0$\xf6<\xb7\xdbc\xea"\r\xec\xa7\x8d\xebL\xbb\xb8\x8f\xbdc\xbaNp\xbb\x86+?\'\x88\x19\xda5\xd8-\xc4\xe05w\xd4|\x93R98\xfb\xf9\xcaa\x8a\xed=F\xcc`\xe8\x9b\xa5\xa4liRO\xf7\x063`CF\xb6\xb96s\x00\x08\xa5[\xc0^\x1b\x92\xbd\xec}?\\;b\x9fI\xf6\x99R\xc4\xf4\x9a\xff\x95\xc2f\x9c\xb3\xb1\x97^\x19\xfc\xe3\xea\xfaZ\xb9`\xf9E\xb1\x1b\x17\xc1\xd9\xed\xe3\xb97\xc8\x88\xac\xafWY\x83D\xa2\x84\x99\x0b\x89\xa6\xd3\x96\t\xe0\x1f\x88\x88q\xaf\xc3\xb4Ne@\xff\xbb0\\\x17`\xbd\xfd*\x9a\xf3\x05\x96\x9b\xcd=\xfa\xf3E\xe6\x8b\xea3\xfb7\x8a$GQ\xbf\xfb\xfal\x84\xbew\\\xdf\\.\xfcW\x8d\xe7\x9e_h\x05\x10\xbd\xbb\xc7\xd3\x1a\r\xe8%\xab\xc0\xf7\x8c\x02\xc1R\xdb\x8d\x14\xc7U\xa0\x96\xff\xdd}\x1a\xad\x17)ap\x82\x94\xf2W\xadB\x98\xdav\x08\x1d\xde\xe7\xd4x\x99\xe05\xd65d\xaa\x0b\xd6\x86\x1a\xb9r9\x8b(n\x08r|OG\xe2\x1b\xdd\x07\x08\xa1\xbd^hbe\x9f\xcfZ\x9a\xb1\x8d\xef\xea\x12B\xb9u\x92W\x9d\x87/\xf5\xab=\xba`\xb1\x91\xd4\xb8\x84/\x02\xe9\x9aP.c\xc1,\x8e\xeda\x98A\x026\xd4\xcfG\xcb\xac\xf5\xfb\x8a|Ot\xac\xa50j*\xca\xba\xb1\xf3\xcd\xa7\x8f\x15\xeaLR\\F\x8b[y\xf6\xd7\xef\xfc\x9a\x08\xa7\xf3;\xa5~\xa1\x0cquS\x89#~\x92t\'^5+\x86\xad\x86{\xaa\x97\xb5\x88\x81Nw\x99!\x9f\x05\xb5*J\x84\xd7y\xb6\t\xea\xb8!(\xd1\xf3\xeb\xd6\xf1\xfb/\xe8\xdc\x90^\x81\xcf\xf1\x9e\x05n\xdbD\x13\xc6C\x96\x81\xdaxfk\x13\x94\xde\xd7\x00\x0f\xd3\xd8\x06\x8f\x00r\xf7\x16JO\x92\x15\xbaYo\xfa\xf2\xcb\x90(YA\xc9\r\x1036+\xdd".\xc4D\xcc\xd0&\x17 s\x80\xc1\xc1\xbf\xd7f\x80a\xfd`\xea\xd6\xb6\x7f\xed}\xeey\r\xe4a\xffg}+\xd5\x9a\xa4\t\x1b\xb1\xfe\x01\xe0\xa0\xaf,1\x93\x05\xbd=\x82\xdb\xf6\x9e\xe9\xabGB\xad\xc1\xac \x19\x04\x91\x90$\x85\xbc\xd8\xe1\x15(\t\x81^nm{\xe8\xad5\xea\x05If\xd1 \x1e,"t"|Dk\xfd\xcb\x01\xa3\x0f%\xb7\x88\xdcN^\xb0}\x1f\xf8\x97\xc8\xae\xe3\xc1!k\xbc\x16\xc2\xf4\x15:H\xebJ\xe7\xbf\\2\xff\x0c\x9f\xc8\xf3&\xb9\x0fD\xe4!~\xb6\x1f\x84\xcf\xc6\x064j`0\xafY\xce}\xa1\xbe\xad\xa6}\xd0U\xec\x90\xf0aB<\xc7\xaa\xa1\x18 \xa8\xb7D\xa7\xe9^\xfb"\x10\xdf\xe4\xe7\xcd\xaeP\xf0\xdd\x98VY\x928&U\x9f=\xce\xfe\xbcP\x81\xc1_7\x97\xcf\xa3\n#\xbb\xee\xb7\xd8\x0c\xb2\x9a\x8b\x16W\xef:\x1bFk\x05\x811a\x07\xd3(\xb3\xd9\xa2\xad\x12\xd6\x9a\xb0\xc2\xea\xa0\xbe\xbc\xe5\x97\xa1\xc2D\xbfE\x923\xcc\xe3\x00\xa3\x11F\xc8I\xecO\x90a\x12z\x86K\xad\xbc\xbb\x99d9F\xaf\x00\x94\xf7wI\x9cvs\xee\xcfd\xdf\xdc\r\xdc\xf6\xde`\xb9=aa\x9f\xcdt\xa8\x14\xb2\xb6\x01\x96\xc1\x18\xb3J0n\xd9NM+\xe7\xd32v \xee\xe0G\xdb\x1dC\xeb\xe7\x13u\x7f\xd54\x92\xb3\x01,z\x0c\x00\xbb\xb5\xb0\x88\xce>_\xa90\xd1\xd9d\xfa\xbb~\x13\xc94\xd5\x06\xa8_\x94B\xf4G\xcc\x19\xf0\xfe?IK\x1c1G:\xe1\x98\xde\xdaF\xef\x94F\xf1\xa0uh\xc4k\x8cz\xcb\xd2\xe4}\x81=\xedg\x8bY*U\xca\xacY0\xed\xa3T\xf5\x88\x93\x95\x0c\xe7^\xe3\xaa\x00#\xa25\'\x9a^\xf7~:/\x17\x88\x04\xd6\x1f\xb2\xd1\x871\xff\xdc[{\'bw/\x04DU\xff|Y-\xca?CGc\xd3\x8f\x14\x95\xe2WWIgbbl\x84:\xc6\x97Y\x83\xdd\x0f\x8a7,D\x8d\r\xd4\x9f\xe2\xc1$A\xa2\x1a\xc2\x89\x11\x10\xb1\x00S\x85a"\x15m\x99\x93\x07\xa0-\x12\x9c]A\xe8\xc6\x90*Oo\xc3\x9fz\x90\xd9{m\x83V\x13wK\xf3\xda\x99\xc4 \xc09\xd5\x85\xf7\xe0V\'=F[\'T\x1cL\xff\xc7."\x036qs7\xcbT\x1f\xa0\x98\x0b#\xb0\xa24\xd2\xc5\x01\xb4\xb1\x18 [\xe5jX\xd6\xd2\xce\x03\xd2\x99\x8b\x98\xb0\x15\x06L\xebzU}\xedq\xdb\xa4\xed\xad8L\x02\xa7J\x1eK\xc5\x90\xa7\xc7\x85b$U\xbd+\xb8 \xc5&\xba%\xe2\xa2%\xa8\xcb\xcc0q\xc5\xfe}q{\n\x07\xd2t\x08C\xfb\x13\xab\x90\xf5^\x98\x88!\x12\tI\xd9\xd6\xb30J\xcb\xf7\x1d\xab\xd5GF\x9a\xd0\x02\x0e\xa2\x19\x10\x06\xac\xf3<\x1a\xcdW8\x8d\xabe@\x1f\xfe\xf6\xf6\xe9U(\xd5\xae\x0c\xb5|\xd2>\x93\x928!#\xee\x84\xccrmx+\x8e2\xe3\xc4I\xafth\x0ceS\x84y\xa2\x91%\xd2{\x95]mJ\x14C\x89\xe6C\xf3\xdbl\xb5od4\xeeg\xdd\x1e\x86\xfat\x93\xcf\x8d\n4o\xf1)\x19\xd8\xb6\xef\x96c\x0c/\x95\x7f\x0f\x99\x98\xa7\x92:\xda\x1b\\\xc8\x82?\xd5\xce\xbd\x13\x98S!(>\x8d_\x12\xf8\x07R\xcf\r\xf16-\xa2U\xdd0\x06r*7=\xfe\x025Q\x1dgO\xe3\x01PoY2\x98\xb6_G\xc9\x1f\x92\xe8Qa\xb3\xc5\xbe\xde\x07"uZ\xa0`\x1b9tl\x9c\x81\r\x02f\x9f\xa1\xa1\x05w\x81\x9e\xac\x96h|\xa9~Do\xd7\xf5\x8c\t]\xa2\xaa\xc58\xffn\x855\x95\\\xd5\xc9\xb9S:\xfe\x13\xc5\xe1\xb6\xf5n\x0b\xa1M\xe0\xae\n\xf1\xbfJ\xe0\xc9\x02\x97)\xc6\x0f\x83\x8c8R\xd2]\xc9IuU\x9c\xba\xf0q\x9c\x9c\xed\x05\xa1\xf4t\xdaz"\xf5\x7f\xd7R~~\x14\xf7\xa3\xe3\xc33\xea%|\xa0\xda\xddX\xb2\xdf2)\xd8\xc8\x87zO\xdf\x18 NVb\xeaI\x03N\x13\xc9\xf5\x0b\xe6i)j\xf7\'~k\xaf\x81\xe0n\xff\xf5R\xf8\r\x9d{\xaa\xfb\x07o5\xf2\xf4\xd2t:Y+7\xb4\x14\xa1j\xf9\x83\xac6\xb1:\xb7\'Y\xba\xd6\xe3\x1e\xcf\x1f\xb8\tZ\x15\t\xe8CT\tz\x1fx\x0fPO\xd0s\xa5\x91\x07`x\xac-\xbaz\xc0\xc8\xa1}[\xe1\xf7z\xde\xe7\xb89\xae<\xe9I&\x06\xd9o\xe6\x8fga3\x0f\xd5\xb2o\xfd}\xb8?H\xdd\x8b\x1c\xeff\x1co\x83\x8aE\x84\xd5\xf1\xa6\xdd\xf0\xb4\x19\x00\x8a\xb6\x9b\xfc4\xbc0V\xd4\xadd\xdef\xd7F\xfa\xc6KV\x94~4\xf7>\x8f\xa0\xeeimVr\'Y\xfc\xbcl3>@\xd3^%\xa9\x85\xe4q-#\x16\x1d:\x11\x08!D\x9ai^%\x96\xff/\x8bu4\xf9\xe1\xb3\x93\xde\x06\x9d`\xe1\xe6$\xc2\x88\x86\xf9z\xaf\xe9J\xe5\x82T4\xd2\xafR\x90\xc2\xc0\x06[\x9d\x04pM\x85R\x1e\xa0h,u\xf6\xc3O/\x15\x01c`\x1b\x92\xf5\x07\xe0\x89\xa6\xd0\x84\xbc\xd7\xbb\xb5\xdd\x8fZ\xdd\x0f\xc8\x14\x16e\x0e\xfc\xfe\x19T\xc2N\x07J\x05\xc8+\x17\xda\xd8\xaa\xe8\xff\xa2\xbd\xb2\x93!"@\xec\xd3\x8f\xea\x84\x9bI\xd7m\xda\xfeRn\xdaKK\xedW\x99D\xac\xb9H\x14\xaf.d\xb0\x13$E\x0bP\xe4n\xb0\xdb\xe20\xe0\xa7\xf1+\xd8\xde:x\xd8\xb1\xe9\xce\x90X\xbb\xa4ZMf[\x8f\x8c\xe0\xab\x99yYO~8\xe8\x92}\xdb\x99a9gM\x15\xac\xaa\xd5\xdch{\xe5;=\xfc[\xd0\\\x92\xc0Q;\x88\xcc\x9cs6Q\xcd4O\xdd\xadu\x9a&\x8ep\x16~\x94}\x9cI\xd2\xbc-"r\x18\xe0\xdbGI0\xd1]:\x97\x9f\xbcF`\x8c\x16;\xebA\xca\xb2M\xba&\xfc\xaf\xd8\xd48\xd6\xe9=\x84\xc9\xf2I\xf4\xb1\x18\x84\xddH\xe2\xbe\xb4+1\x11\xb8O\xb0\xc896P`=*\xe3\x198@\xb7p\xfa&c {s\xff9\x85@\x87\r\tG\xdf-\xee\xb0\xd7\x16\xfa\x84\xeb\rH\x87Q\x84\x9d\x9c\xba\xc2{\xcf\xff\xd1\xd4s\xe7\x8d/S\xa7\xaf\x83\xb99\xe9\xc7i\xf3*\x0c\xbfqK/\x15\x97\xc5>cv\xb9\x19e\xa1\xdc\xde"\xdb>\x82\xe3g%\xceK\x9a\x0b\xfc\xb9\xe4\xc8\x13dU$7\x9c.F\x82\x00\x18!k\xf0\xb5@5H\x88ubM\xa1\x82\xa1\x10\xc4\x18\xb7\x19\xc7\x0e\xad\x97\\/P\xabQ/\x9f 8EP\xd9\xac\xf0\x03\x02`\xa0\xca\x7f\xac\xe1d\xc2\\\x84\x019\x99C\xa0o\x13\xb6\xf0\x87\xcd{\\Z\xe6\xbe\xb7|T\xaf\xd9\xe2\x06\xd3\x9c\xc8\x1f\xb3?\x01\x96{\xef\x01^\xe4\x93=\xc4\x94\x85C\xa3\x00n\x12\xac\xce[%<\x99pqP\xc0\xf1\x8c\xbdO\xf7\xfb1\x08\xc0\x17u\x1e\xb9\\;\xa9\xc4\xfb\x9f~\x9c\x94\xa8\xd4\x15\xa2\xfc\x8bS\x1b\x91\x8fe\xdc\x9e!\xdd\xbd\xc9\x98\x8f\xb9\x94\x86\x08\xa4iP<\xc2\xd71\xf8L\x9b\xfei?\x93 \xd0\x1d\xf0c\xb8\xd6\r\x0b(\xcb\xffxy\xf3\xc6=;\xd0;B\xe5I\xc8w&g\xb6\x81\xb6Q\xe0\x9b)\xef\xf8\xa6\xd86\x04\xf6\x97N\xd2\x1f\xf3\xb7.I^\xa7\x12\x9b\x81\x17\xb9\xbea1\x1e\x8f\xb4D\xaf\xda\xdb\xcd5,\xb4iv,\x88\xa1ki\x89\x97j\xc2B\x99\x92\xdb\x06Ai\xbd\xf7t1!\x03A\xc2\xa7\x9e\x02GR|\t\xc2\xaaS\x9d\xb2\xfb\x1b\x0f\x08\xd1\xa5l\xd5pl\xed\x1bF\xdeu\xf6\xb8\x1a\xaa<\x16\xd9\x9cc\xb7\x95\xa8>\\\xc9P#;\xe5\x1f\x82g)\xdahl\x0e2\x03\x14ox\x18\r\n:\xccREvt\x06\x15@\x194\xe4\xfa\x85\x87\xa9\x96\xf8\xbc\x11\x91\x8f\x8d\x9cC\xbe2L\x0ct\x90[\xc1\x01-}\xf6\x8bM3\xf7\xa0p\xfa\x99%\\\xf0,\xa3`r\xbao\x9e\x95\xf8\xa1\x82\xa9V\xe5\x01B\xa1\x7fhCnz\xbc\x87\xc4@\x95\xee\xe5\xa8\xfc\xf5\xf2\x95/Bi=>\xb6\xa3\xf4\xd9k\xc3\xc1\xdfvm\xbc\xe5\xd1<;\x97\xe4_\x83o(\xdf\xe3x\x1d\xf5\x16\x81p\xe7pU#\xb5q\x9a|\xf3\x91|\xc1\x9eE\x13%\x8c\x1e\xd6E#\xe3\xf8\x8c8\xaae\xd3\x07\xdb\x10\x8a:w\xdf\xbbIqa\xe1\xa1\x94\xca\xd5\xc0\x1e\x87D\x95\xc5\x15\xb8\x07\xe41\x83\x1e\xccl\' \xba\x02\xf0\x15\xc9\xaeN\xb6r\xc7&\x91fU\xb7?_u\xe5\xbe;\x8cg\xa4;/\xddN\xb2\x1e\xf1\xab\xc3\xe9G\x16C\x16\x11\xd3O\xb5I\xda&\xe9s&\xc2e\xa7A\x81\xfb6i\xa5\x9b\xee=m\xdd\xbc.\xfe\xcbN>\xb2\x7f\x82\x98R\r>\xcc\x14\xc33\xaaA5\xf5\xdb\xecr\xf4w\x16\xf9w!\xff\x1ec#2=\xab\x90)\xc5\x96Ni\xa6\xa2\xbfs\xe3]\xce\xde\xee\x9e;\xf1b\x18[\xfd\xe3X\xcc\xd9\xab<\x9d\x08Y\xcb\x04\xab\xd0\xcf\x99:/\xc1@h\xb3@\xfc\xad5J6\xb9\xa33/\xc7"\xf5\r\xc0\xa1\xff\xd9\xe9\xb6I\xb2\xc7\xa6\xbe\xd4\xf5\x90>g\xb1=\x8f\xaf@\xe6\x84\xa8\n\xfeIG\xe9r\xd5\x07%\x98\xe3\\05\xc0WV\x8a\x908&\x1a\xa5\xf5V}Xq\xe3\x18;2\x90\xac\x16\xce7\xb8\x8e\xa5\xd3\xa43\x96\x94EV=\n\xe0\xfd\xeb\xd2\x85+\x99KEt;\xd2(\xb3\xfem\xebw\x7feji\xee\x917\xb5\'\'(\x8b\x1f\x06\x15\xe5\xc4\x8f\xfc\x0b\x83\xa9\xe59\n\xd9\x15\xa6\xc9\xbf\xb8\xb9)\xf4\xe8\x0e0P\xee\x8e\xcc#\xb1\xd2\xfc5\x17\xac\xce\xbf\xc8\xac&\xa0\x1d\xfa\xd4\xaf\xae\x0f\xd4\x82 \x92k\x076\xfa\xaf\x93\xf7\xc3\x0f<\xc8\xd4\x05\xf8L\xcdc\xb0\xc2,\x0e\x93\xa1\xeb\x03\xfcZj\xa7\xbcD+\xf1\x1eT\xb0\xba\x8f\xdd-\xf2\xc3\x8b\xc1)\x95\x15\xf9i~\xb7\xcf\x9cS;\x90m\x93W)wg\x98\xf4\x14\xed:\xaf\x01P\x16\xd8|\xaf\x05\xf3(\xe4\xc7\xae\xa1p\xfc\xc4\xb0\xde\xcc\x11\x99\xec\xc4h\xc8kJ\xeb\x9c\x16\xff[N\xe7\xa8+\xad\xa6pu 1\x01\xcf\xee\xd2\xce\x94LR\xfc\x94\xe0\x97jA\xb8\xfa\x06\x1b\xa46,\xedP\x8e+(\x8c\x8a\x90\xc4%\xfd\x13\'t&\rY\xb2^\x85(\x07\xcd\xc9\xd3g\x9ee\x86X\x8a4Z\xad\x8b\xcf\xb5\xcc\xe0L@\\\x08\xbc\x1c\xb7\x8f\x9d\x1a\x9d^Rsy^}\x0ce\t\xdad*`B\xc0\xaf5\xd0.\xd8\xa0/\x12\xee\xbd\x08\x8a\xa8Z\xf1\xffm\xebI\xb8\xdfi>\xb3\xc4H\xee\x1c\\\t:!l\xbe&\xb5\xf2\x0e%oK\\\xdc\xdd\xa6j\xbe\xb2\x11\x9f\x8e\t\xd3k\x0e\x13\xb7\xef\x14\x91Ug\xeeo\xf5\xe3\xe6\xd2S\x95\xdb\xe7g \xe4\xb7\x12\x12\xd0\x95\x14\x17s`\xee\xf8\xd6;\xa1\n\xd4\r\x92\x0c\xc3P\xb1\x01\xce\xc9D\xb7\xae}\xfby\x01E\xf4<\xe5Hg\x0b\xc6\xde\x91\x07\xcd\x9by\xa7\xf9\x17\xd0\x965\xccY\xef \xbf=OC\xa3\tUa*\x16\xff\xee\\\x86\x83\xc2$\xb7\xf6\xde\xc4}2\xd5\xaa\x1ag\x8bM\xe3\x80\x160\xde\x00bT\x1a\x1c\x9d\x96\xca\x85\xaf\x0e\xff\x0eB\xa0\x1b\x9f1\xc0 \x8a)\x1a\xe6\xd2\xe72\xf8\x81\x9e\x01\xce\x01\xd7\x9a\xf7L\x0bT\x8cf\x8aa\xfc\x87\xf3;`\xf02a\xa1\x86E\xeb\x8a\x8bPRW\xf3\xe7\xc8\xbb\xdb\x9e\xad\xbf1\xa3\x9d\xaa5\x19>h\xa8Q\xd8\xf2\x07D:\xb1\'\xf8\x10\xd7\xb1\xea`;\xbfs\xc4\x0e\x0ecH\xe0\x0e\xec-\xe7$\xb4mZ\x1d\x16\xaf\xcbu\x88!\xa4\xe5;\xed|.\xf4\xd45\x90\x89J\x8c\x133\x07\x10-%vodi\x88\x02\xa0\x16\x16\xd8X\xa6\xf6\x10\xef\x8b\x85y5\xb7k\xfd5>\x11\x08\x0c\xdfP\x11o\xdfR7\x85\xfc\xc7\xf3\x0c\xca`(\x85\x9f\xaaDxF_@9S\x817\x9dK\xe5\xc8\x12Vp,?\x7f\x80f- \xcca\xe8\x97\xc2Y^\xd0\x1d\xd3oR\xae)\x95\xf6\x07\x9a\xea\x03\x01i\xf1\xfe}\xb8\xc1\x0c\xa71\xbfm\xf8\xc9\n`\xb8\x1et#*\xd2\xcc%\x0c\x1f,\x03)\xd2)\xae\x12"\xb3roOu\xda*#*\xac@\x8e\x16):\x9fy2i\x9a/\x18\xdb\xea\x9c\x00d\xea\xe9\xea\x16<m\x0ft\xbf\xec7\xb5o\x10l\x1e\xc8,\xe0\xd2\x91\x8c\xd4\x88=1;K\x81\xca\x91\xed\x81\xc6\xe45:\xee\x93\xb9\xde\xf4\xe2?\xab\x1a\xee\xe0\xa1\xf2\x7f3\x03\xdb^\x9b\x80\x1b\\\xf5\xc8}H\x9c.\x80\x07"\x8b\xc4^\xa0\xa0\xb5iZ\x1c\x13a\x96\xbd\xa9*\xa19\x01\x97\xd6\xeb\xff#\rpP\xdc\xb3\xd2\x95\xcc\x88T7\xac \xf3EAQ!\x14\xedI\xe5\xba\x10\xd2\xc8X&M\x06\x04\xab\x05\xc7gQ\x881\xecv\x9c\x13\xae\xdf\x92bc_\xe7\x05\xf1\xe1E\xea|\xdf\xaf\x85\r\x07\x97=A\xc6\x0c/#V\xd9H&S\xf6\xd0\xd3\xab@\x95\xaf\xb6\x02\x17]\xc7\xd5F\x05_4:\xc1\x96\xef\x10\xfc\x86d \xbc\xdb\x94J\xa1\x94E\xca|Z\x9fn}\xd2ep\x85%s\xfe\xa4\x9a\x9b\x05"\xb6\x938\xd9\x14M\xd2\xff<\xd7E\xe9\xbe\xd8Zb(}5W~,\xe4\xf0\xbc\xa3\xa1\xe4\xc9\x82\x89-K\x0c\xa9\t1\xe1\x1a\xdc\xfc\x95\x0f\xb39\xa8\t\xdev\x16\xf4\x8f\xd4\x19\x19\xe9!(h\xad\x8a\xaeY\x9f\x89\xf76k~\xc5\x8d\xd0\xfd\xdfM\x10!1\xb9\x98a\x1aA\xfb\xc5)\x0f(r\xa2\xbb~(\xb5\xe0C\x19\x8d\xa8\xca]@\xba\xc8\xb6\xcd}\x9f^\xe6\xa3\x7f\x14\x10\nC\x86,vE\xe2\x1c\x84\xfb\x8a@\x19\xa0\xfd\xbc\xf9(!\xf0\xf0\xddm\xbc\x98N\x87 m\x84&\x8d\xcd\xf6G\x12\xc5\xe3\xd5L\xe7`\xcd\n\x89\x88\x85x%\xc1\xfd\xe1\x7f\xf6\xad\xfb\x16\x12\xf1\xc6\xb8*\x10\xa3qhI\xe0\xf3\xb9O\x08cr\xcc\x87I\xb9\xb0C\xa9V#\xa3\xce\x0b\xee\xb4\xb6\x07\xab\xa3H&\xf6\x8c4\xebiN\x9c\xe0\x84\xc4<\x9a [J\xdeY\xf7:\x9c\xa4\xdb\x1e\xfb\x90R\x13Ab\xee\x8f[\x15"N\xden\x02%%\xfa\x9c\x88\xc2e\'\xfe\x89\x9b\xdd\x86\x82\x0f\xcfv1\xec\xb8\xf5\x1c/\x971g\xc6\xceg\x10\x0fR\xce\xa6\xae4\xa0"|\x14\x9b\x05g\xae"\x1eU72\xe8\xae#\x19\xf7T4\xf4\xe6\x96\x84\xa9\xb6\xd8\x94U\x1a\xa4\x1cOc\xb9Y\x1e0\x17\xdf\x84xe\xd6:\xf2=\x1a\'\x96\x96N9I&]\xf5\x9f\xc8;h\x91_\x91;g)t\xf5\x01*\x9b\x16\xb8\\e\xc8\xbfz'

=== removed file 'Vertex/vertex/test/test_bits.py'
--- Vertex/vertex/test/test_bits.py	2005-08-05 06:02:56 +0000
+++ Vertex/vertex/test/test_bits.py	1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-import array
-from vertex.bits import BitArray
-
-from twisted.trial import unittest
-
-bitResult = [
-    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
-    3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
-    3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
-    4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
-    3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
-    6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
-    4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
-    6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
-    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
-    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
-    6, 7, 6, 7, 7, 8 ]
-
-
-
-class BitArrayTest(unittest.TestCase):
-
-    def testBasicBits(self):
-        prev = BitArray(size=3)
-        prev[0] = 1
-        prev[1] = 1
-        prev[2] = 1
-        for size in (5, 6, 8, 12, 14, 15):
-            ba = BitArray(size=size)
-            ba[0] = 1
-            ba[2] = 1
-            ba[-1] = 1
-            assert ba.countbits() == 3, str(ba.countbits())
-            xo = (prev ^ ba)
-            cb = xo.countbits()
-            assert cb == 2, cb
-            prev = ba
-
-    def testPositions(self):
-        SIZE = 25
-        bitz = BitArray(size=SIZE)
-        self.assertEquals(list(bitz.positions(0)), range(SIZE))
-        self.assertEquals(list(bitz.positions(1)), [])
-        rs = range(SIZE)
-        rs.remove(7)
-        bitz[7] = 1
-        self.assertEquals(list(bitz.positions(0)), rs)
-        self.assertEquals(list(bitz.positions(1)), [7])
-
-    def testDefaultBit(self):
-        a = BitArray(size=100, default=0)
-        b = BitArray(size=100, default=1)
-        self.assertEquals(list(a), [0] * 100)
-        self.assertEquals(list(b), [1] * 100)
-
-    def testCalculateOnBits(self):
-        calc = []
-        for x in range(256):
-            c = 0
-            a = array.array('B')
-            a.append(x)
-            for n in BitArray(a):
-                c += n
-            calc.append(c)
-        self.assertEquals(calc, bitResult)
-

=== removed file 'Vertex/vertex/test/test_client.py'
--- Vertex/vertex/test/test_client.py	2006-06-27 13:34:49 +0000
+++ Vertex/vertex/test/test_client.py	1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
-
-from twisted.trial import unittest
-from vertex import q2qclient
-from twisted.python.usage import UsageError
-import sys
-from StringIO import StringIO
-
-class TimeoutTestCase(unittest.TestCase):
-    def testNoUsage(self):
-        """
-        When the vertex Q2QClientProgram is run without any arguments, it
-        should print a usage error and exit.
-        """
-        cp = q2qclient.Q2QClientProgram()
-
-        # smash stdout for the duration of the test.
-        sys.stdout, realout = StringIO(), sys.stdout
-        try:
-            # the act of showing the help will cause a sys.exit(0), catch that
-            # exception.
-            self.assertRaises(SystemExit, cp.parseOptions, [])
-
-            # check that the usage string was (roughly) output.
-            output = sys.stdout.getvalue()
-            self.assertIn('Usage:', output)
-            self.assertIn('Options:', output)
-            self.assertIn('Commands:', output)
-        finally:
-            # always restore stdout.
-            sys.stdout = realout

=== removed file 'Vertex/vertex/test/test_dependencyservice.py'
--- Vertex/vertex/test/test_dependencyservice.py	2005-08-05 06:02:56 +0000
+++ Vertex/vertex/test/test_dependencyservice.py	1970-01-01 00:00:00 +0000
@@ -1,69 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-from twisted.trial import unittest
-
-from vertex import depserv
-
-
-class Serv(depserv.DependencyService):
-    requiredServices = ['one']
-
-    def __init__(self, **kw):
-        self.initialized = []
-        depserv.DependencyService.__init__(self, **kw)
-
-    def setup_ONE(self):
-        self.initialized.append('ONE')
-
-    def setup_TWO(self):
-        self.initialized.append('TWO')
-
-    def setup_THREE(self):
-        self.initialized.append('THREE')
-
-
-class TestDependencyService(unittest.TestCase):
-
-    def test_depends(self):
-        class One(Serv):
-            def depends_TWO(self):
-                return ['three']
-
-        class Two(Serv):
-            def depends_THREE(self):
-                return ['two']
-
-        args = dict(one={}, two={}, three={})
-
-        one = One(**args)
-        self.assert_(one.initialized == ['ONE', 'THREE', 'TWO'])
-
-        two = Two(**args)
-        self.assert_(two.initialized == ['ONE', 'TWO', 'THREE'])
-
-
-    def test_circularDepends(self):
-        class One(Serv):
-            def depends_THREE(self):
-                return ['two']
-            def depends_TWO(self):
-                return ['three']
-        try:
-            One(one={}, two={}, three={})
-        except depserv.StartupError:
-            pass
-        else:
-            raise unittest.FailTest, 'circular dependencies did not raise an error'
-
-
-    def test_requiredWithDependency(self):
-        """A service is required but has dependencies"""
-
-        class One(Serv):
-            def depends_ONE(self):
-                return ['three']
-        try:
-            One(one={}, two={}, three={})
-        except depserv.StartupError:
-            pass
-        else:
-            raise unittest.FailTest, 'unsatisfied dependencies did not raise an error'

=== removed file 'Vertex/vertex/test/test_ptcp.py'
--- Vertex/vertex/test/test_ptcp.py	2008-08-11 13:49:13 +0000
+++ Vertex/vertex/test/test_ptcp.py	1970-01-01 00:00:00 +0000
@@ -1,365 +0,0 @@
-# -*- test-case-name: vertex.test.test_ptcp -*-
-
-import random, os
-
-from twisted.internet import reactor, protocol, defer, error
-from twisted.trial import unittest
-
-from vertex import ptcp
-
-def reallyLossy(method):
-    r = random.Random()
-    r.seed(42)
-    def worseMethod(*a, **kw):
-        if r.choice([True, True, False]):
-            method(*a, **kw)
-    return worseMethod
-
-def insufficientTransmitter(method,  mtu):
-    def worseMethod(bytes, addr):
-        method(bytes[:mtu], addr)
-    return worseMethod
-
-
-class TestProtocol(protocol.Protocol):
-    buffer = None
-    def __init__(self):
-        self.onConnect = defer.Deferred()
-        self.onDisconn = defer.Deferred()
-        self._waiting = None
-        self.buffer = []
-
-    def connectionMade(self):
-        self.onConnect.callback(None)
-
-    def connectionLost(self, reason):
-        self.onDisconn.callback(None)
-
-    def gotBytes(self, bytes):
-        assert self._waiting is None
-        if ''.join(self.buffer) == bytes:
-            return defer.succeed(None)
-        self._waiting = (defer.Deferred(), bytes)
-        return self._waiting[0]
-
-    def dataReceived(self, bytes):
-        self.buffer.append(bytes)
-        if self._waiting is not None:
-            bytes = ''.join(self.buffer)
-            if not self._waiting[1].startswith(bytes):
-                x = len(os.path.commonprefix([bytes, self._waiting[1]]))
-                print x
-                print 'it goes wrong starting with', repr(bytes[x:x+100]), repr(self._waiting[1][x:x+100])
-            if bytes == self._waiting[1]:
-                self._waiting[0].callback(None)
-                self._waiting = None
-
-class Django(protocol.ClientFactory):
-    def __init__(self):
-        self.onConnect = defer.Deferred()
-
-    def buildProtocol(self, addr):
-        p = protocol.ClientFactory.buildProtocol(self, addr)
-        self.onConnect.callback(p)
-        return p
-
-    def clientConnectionFailed(self, conn, err):
-        self.onConnect.errback(err)
-
-class ConnectedPTCPMixin:
-    serverPort = None
-
-    def setUpForATest(self,
-                      ServerProtocol=TestProtocol, ClientProtocol=TestProtocol):
-        serverProto = ServerProtocol()
-        clientProto = ClientProtocol()
-
-
-        self.serverProto = serverProto
-        self.clientProto = clientProto
-
-        sf = protocol.ServerFactory()
-        sf.protocol = lambda: serverProto
-
-        cf = Django()
-        cf.protocol = lambda: clientProto
-
-        serverTransport = ptcp.PTCP(sf)
-        clientTransport = ptcp.PTCP(None)
-
-        self.serverTransport = serverTransport
-        self.clientTransport = clientTransport
-
-        serverPort = reactor.listenUDP(0, serverTransport)
-        clientPort = reactor.listenUDP(0, clientTransport)
-
-        self.clientPort = clientPort
-        self.serverPort = serverPort
-
-        return (
-            serverProto, clientProto,
-            sf, cf,
-            serverTransport, clientTransport,
-            serverPort, clientPort
-            )
-
-    def tearDown(self):
-        td = []
-
-        for ptcp in (self.serverTransport, self.clientTransport):
-            td.append(ptcp.waitForAllConnectionsToClose())
-        d = defer.DeferredList(td)
-        return d
-
-
-class TestProducerProtocol(protocol.Protocol):
-    NUM_WRITES = 32
-    WRITE_SIZE = 32
-
-    def __init__(self):
-        self.onConnect = defer.Deferred()
-        self.onPaused = defer.Deferred()
-
-    def connectionMade(self):
-        self.onConnect.callback(None)
-        self.count = -1
-        self.transport.registerProducer(self, False)
-
-    def pauseProducing(self):
-        if self.onPaused is not None:
-            self.onPaused.callback(None)
-            self.onPaused = None
-
-    def resumeProducing(self):
-        self.count += 1
-        if self.count < self.NUM_WRITES:
-            bytes = chr(self.count) * self.WRITE_SIZE
-            # print 'Issuing a write', len(bytes)
-            self.transport.write(bytes)
-            if self.count == self.NUM_WRITES - 1:
-                # Last time through, intentionally drop the connection before
-                # the buffer is empty to ensure we handle this case properly.
-                # print 'Disconnecting'
-                self.transport.loseConnection()
-        else:
-            # print 'Unregistering'
-            self.transport.unregisterProducer()
-
-class PTCPTransportTestCase(ConnectedPTCPMixin, unittest.TestCase):
-    def setUp(self):
-        """
-        I have no idea why one of these values is divided by 10 and the
-        other is multiplied by 10.  -exarkun
-        """
-        self.patch(
-            ptcp.PTCPConnection, '_retransmitTimeout',
-            ptcp.PTCPConnection._retransmitTimeout / 10)
-        self.patch(
-            ptcp.PTCPPacket, 'retransmitCount',
-            ptcp.PTCPPacket.retransmitCount * 10)
-
-
-    def xtestWhoAmI(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest()
-
-        def gotAddress(results):
-            (serverSuccess, serverAddress), (clientSuccess, clientAddress) = results
-            self.failUnless(serverSuccess)
-            self.failUnless(clientSuccess)
-
-            self.assertEquals(serverAddress[1], serverPort.getHost().port)
-            self.assertEquals(clientAddress[1], clientPort.getHost().port)
-
-        def connectionsMade(ignored):
-            return defer.DeferredList([serverProto.transport.whoami(), clientProto.transport.whoami()]).addCallback(gotAddress)
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-
-        return defer.DeferredList([serverProto.onConnect, clientProto.onConnect]).addCallback(connectionsMade)
-
-    #testWhoAmI.skip = 'arglebargle'
-
-    def testVerySimpleConnection(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest()
-
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-
-        def sendSomeBytes(ignored, n=10, server=False):
-            if n:
-                bytes = 'not a lot of bytes' * 1000
-                if server:
-                    serverProto.transport.write(bytes)
-                else:
-                    clientProto.transport.write(bytes)
-                if server:
-                    clientProto.buffer = []
-                    d = clientProto.gotBytes(bytes)
-                else:
-                    serverProto.buffer = []
-                    d = serverProto.gotBytes(bytes)
-                return d.addCallback(sendSomeBytes, n - 1, not server)
-
-        def loseConnections(ignored):
-            serverProto.transport.loseConnection()
-            clientProto.transport.loseConnection()
-            return defer.DeferredList([
-                    serverProto.onDisconn,
-                    clientProto.onDisconn
-                    ])
-
-        dl = defer.DeferredList([serverProto.onConnect, clientProto.onConnect])
-        dl.addCallback(sendSomeBytes)
-        dl.addCallback(loseConnections)
-        return dl
-
-
-    def testProducerConsumer(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest(
-            ServerProtocol=TestProducerProtocol)
-
-        def disconnected(ignored):
-            self.assertEquals(
-                ''.join(clientProto.buffer),
-                ''.join([chr(n) * serverProto.WRITE_SIZE
-                         for n in range(serverProto.NUM_WRITES)]))
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-        return clientProto.onDisconn.addCallback(disconnected)
-
-
-    def testTransportProducer(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest()
-
-        resumed = []
-        def resumeProducing():
-            resumed.append(True)
-            clientProto.transport.resumeProducing()
-
-        def cbBytes(ignored):
-            self.failUnless(resumed)
-            clientProto.transport.loseConnection()
-
-        def cbConnect(ignored):
-            BYTES = 'Here are bytes'
-            clientProto.transport.pauseProducing()
-            serverProto.transport.write(BYTES)
-            reactor.callLater(2, resumeProducing)
-            return clientProto.gotBytes(BYTES).addCallback(cbBytes)
-
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-        connD = defer.DeferredList([clientProto.onConnect, serverProto.onConnect])
-        connD.addCallback(cbConnect)
-        return connD
-
-    def testTransportProducerProtocolProducer(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest(
-            ServerProtocol=TestProducerProtocol)
-
-        paused = []
-        def cbPaused(ignored):
-            # print 'Paused'
-            paused.append(True)
-            # print 'RESUMING', clientProto, clientTransport, clientPort
-            clientProto.transport.resumeProducing()
-        serverProto.onPaused.addCallback(cbPaused)
-
-        def cbBytes(ignored):
-            # print 'Disconnected'
-            self.assertEquals(
-                ''.join(clientProto.buffer),
-                ''.join([chr(n) * serverProto.WRITE_SIZE
-                         for n in range(serverProto.NUM_WRITES)]))
-
-        def cbConnect(ignored):
-            # The server must write enough to completely fill the outgoing buffer,
-            # since our peer isn't ACKing /anything/ and our server waits for
-            # writes to be acked before proceeding.
-            serverProto.WRITE_SIZE = serverProto.transport.sendWindow * 5
-
-            # print 'Connected'
-            # print 'PAUSING CLIENT PROTO', clientProto, clientTransport, clientPort
-            clientProto.transport.pauseProducing()
-            return clientProto.onDisconn.addCallback(cbBytes)
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-        connD = defer.DeferredList([clientProto.onConnect, serverProto.onConnect])
-        connD.addCallback(cbConnect)
-        return connD
-
-
-class LossyTransportTestCase(PTCPTransportTestCase):
-    def setUpForATest(self, *a, **kw):
-        results = PTCPTransportTestCase.setUpForATest(self, *a, **kw)
-        results[-2].write = reallyLossy(results[-2].write)
-        results[-1].write = reallyLossy(results[-1].write)
-        return results
-
-
-class SmallMTUTransportTestCase(PTCPTransportTestCase):
-    def setUpForATest(self, *a, **kw):
-        results = PTCPTransportTestCase.setUpForATest(self, *a, **kw)
-        results[-2].write = insufficientTransmitter(results[-2].write, 128)
-        results[-1].write = insufficientTransmitter(results[-1].write, 128)
-        return results
-
-
-
-class TimeoutTestCase(ConnectedPTCPMixin, unittest.TestCase):
-    def setUp(self):
-        """
-        Shorten the retransmit timeout so that tests finish more quickly.
-        """
-        self.patch(
-            ptcp.PTCPConnection, '_retransmitTimeout',
-            ptcp.PTCPConnection._retransmitTimeout / 10)
-
-
-    def testConnectTimeout(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest()
-
-        clientTransport.sendPacket = lambda *a, **kw: None
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-        return cf.onConnect.addBoth(lambda result: result.trap(error.TimeoutError) and None)
-
-    def testDataTimeout(self):
-        (serverProto, clientProto,
-         sf, cf,
-         serverTransport, clientTransport,
-         serverPort, clientPort) = self.setUpForATest()
-
-        def cbConnected(ignored):
-            serverProto.transport.ptcp.sendPacket = lambda *a, **kw: None
-            clientProto.transport.write('Receive this data.')
-            serverProto.transport.write('Send this data.') # have to send data
-                                                           # or the server will
-                                                           # never time out:
-                                                           # need a
-                                                           # SO_KEEPALIVE
-                                                           # option somewhere
-            return clientProto.onDisconn
-
-        clientConnID = clientTransport.connect(cf, '127.0.0.1', serverPort.getHost().port)
-
-        d = defer.DeferredList([serverProto.onConnect, clientProto.onConnect])
-        d.addCallback(cbConnected)
-        return d

=== removed file 'Vertex/vertex/test/test_q2q.py'
--- Vertex/vertex/test/test_q2q.py	2012-03-12 18:30:09 +0000
+++ Vertex/vertex/test/test_q2q.py	1970-01-01 00:00:00 +0000
@@ -1,712 +0,0 @@
-# Copyright 2005-2008 Divmod, Inc.  See LICENSE file for details
-# -*- vertex.test.test_q2q.UDPConnection -*-
-
-"""
-Tests for L{vertex.q2q}.
-"""
-
-from cStringIO import StringIO
-
-from twisted.trial import unittest
-from twisted.application import service
-from twisted.internet import reactor, protocol, defer
-from twisted.internet.task import deferLater
-from twisted.internet.ssl import DistinguishedName, PrivateCertificate, KeyPair
-from twisted.protocols import basic
-from twisted.python import log
-from twisted.python import failure
-from twisted.internet.error import ConnectionDone
-# from twisted.internet.main import CONNECTION_DONE
-
-from zope.interface import implements
-from twisted.internet.interfaces import IResolverSimple
-
-from twisted.protocols.amp import (
-    UnhandledCommand, UnknownRemoteError, QuitBox, Command, AMP)
-
-from vertex import q2q
-
-
-def noResources(*a):
-    return []
-
-class FakeConnectTCP:
-    implements(IResolverSimple)
-
-    def __init__(self, connectTCP):
-        self._connectTCP = connectTCP
-        self.hostPortToHostPort = {}
-        self.hostToLocalHost = {}
-        self.counter = 1
-
-    def addHostPort(self, hostname, fakePortNumber, realPortNumber):
-        if hostname in self.hostToLocalHost:
-            localIP = self.hostToLocalHost[hostname]
-        else:
-            localIP = '127.0.0.%d' % (self.counter,)
-            self.counter += 1
-            self.hostToLocalHost[hostname] = localIP
-
-        self.hostPortToHostPort[(localIP, fakePortNumber)] = (localIP, realPortNumber)
-        self.hostPortToHostPort[(hostname, fakePortNumber)] = (hostname, realPortNumber)
-
-    def connectTCP(self, host, port, *args, **kw):
-        localhost, localport = self.hostPortToHostPort.get((host,port), (host, port))
-        return self._connectTCP(localhost, localport, *args, **kw)
-
-    def getHostSync(self,name):
-        result = self.hostToLocalHost[name]
-        return result
-
-    def getHostByName(self, name, timeout):
-        return defer.maybeDeferred(self.getHostSync, name)
-
-def runOneDeferred(d):
-    L = []
-    d.addBoth(L.append)
-    reactor.callLater(0, d.addCallback, lambda ign: reactor.crash())
-    reactor.run()
-    if L:
-        if isinstance(L[0], failure.Failure):
-            L[0].trap()
-        return L[0]
-    raise unittest.FailTest("Keyboard Interrupt")
-
-class Utility(unittest.TestCase):
-    def testServiceInitialization(self):
-        svc = q2q.Q2QService(noResources)
-        svc.certificateStorage.addPrivateCertificate("test.domain")
-
-        cert = svc.certificateStorage.getPrivateCertificate("test.domain")
-        self.failUnless(cert.getPublicKey().matches(cert.privateKey))
-
-class OneTrickPony(AMP):
-    def amp_TRICK(self, box):
-        return QuitBox(tricked='True')
-
-class OneTrickPonyServerFactory(protocol.ServerFactory):
-    protocol = OneTrickPony
-
-class OneTrickPonyClient(AMP):
-    def connectionMade(self):
-        self.callRemoteString('trick').chainDeferred(self.factory.ponged)
-
-class OneTrickPonyClientFactory(protocol.ClientFactory):
-    protocol = OneTrickPonyClient
-
-    def __init__(self, ponged):
-        self.ponged = ponged
-
-    def buildProtocol(self, addr):
-        result = protocol.ClientFactory.buildProtocol(self, addr)
-        self.proto = result
-        return result
-
-    def clientConnectionFailed(self, connector, reason):
-        self.ponged.errback(reason)
-
-
-class DataEater(protocol.Protocol):
-    def __init__(self):
-        self.waiters = []
-        self.data = []
-        self.count = 0
-
-    def dataReceived(self, data):
-        if not data:
-            raise RuntimeError("Empty string delivered to DataEater")
-        self.data.append(data)
-        self.count += len(data)
-        for count, waiter in self.waiters[:]:
-            if self.count >= count:
-                waiter.callback(self.count)
-
-    def removeD(self, result, size, d):
-        # XXX done as a callback because 1.3 util.wait actually calls a
-        # callback on the deferred
-        self.waiters.remove((size, d))
-        return result
-
-    def waitForCount(self, size):
-        D = defer.Deferred()
-        self.waiters.append((size, D))
-        self.waiters.sort()
-        self.waiters.reverse()
-        return D.addBoth(self.removeD, size, D)
-
-    def buildProtocol(self, addr):
-        return self
-
-class DataFeeder(protocol.Protocol):
-    def __init__(self, fobj):
-        self.fobj = fobj
-
-    def clientConnectionFailed(self, connector, reason):
-        log.msg("DataFeeder client connection failed:")
-        log.err(reason)
-
-    def clientConnectionLost(self, connector, reason):
-        pass
-
-    def connectionMade(self):
-        basic.FileSender().beginFileTransfer(self.fobj, self.transport)
-
-    def buildProtocol(self, addr):
-        return self
-
-class StreamingDataFeeder(protocol.Protocol):
-    DELAY = 0.01
-    CHUNK = 1024
-    paused = False
-    pauseCount = 0
-    resumeCount = 0
-    stopCount = 0
-    outCount = 0
-    call = None
-
-    def __init__(self, infile):
-        self.file = infile
-
-    def clientConnectionFailed(sef, connector, reason):
-        log.msg("StreamingDataFeeder client connection failed:")
-        log.err(reason)
-
-    def clientConnectionLost(self, connector, reason):
-        pass
-
-    def connectionMade(self):
-        self.nextChunk = self.file.read(self.CHUNK)
-        self.transport.registerProducer(self, True)
-        self.call = reactor.callLater(self.DELAY, self._keepGoing)
-
-    def _keepGoing(self):
-        self.call = None
-        if self.paused:
-            return
-        chunk = self.nextChunk
-        self.nextChunk = self.file.read(self.CHUNK)
-        self.outCount += len(chunk)
-        if chunk:
-            self.transport.write(chunk)
-        if self.nextChunk:
-            self.call = reactor.callLater(self.DELAY, self._keepGoing)
-
-
-    def pauseProducing(self):
-        self.paused = True
-        self.pauseCount += 1
-        if self.call is not None:
-            self.cancelMe()
-
-    def resumeProducing(self):
-        self.paused = False
-        if self.call is not None:
-            self.cancelMe()
-        self.call = reactor.callLater(self.DELAY, self._keepGoing)
-        self.resumeCount += 1
-
-    def cancelMe(self):
-        self.call.cancel()
-        self.call = None
-
-    def stopProducing(self):
-        self.paused = True
-        self.stopCount += 1
-        if self.call is not None:
-            self.cancelMe()
-
-    def buildProtocol(self, addr):
-        return self
-
-
-class ErroneousClientError(Exception):
-    pass
-
-class EngenderError(Command):
-    commandName = 'Engender-Error'
-
-class Break(Command):
-    commandName = 'Break'
-
-class Flag(Command):
-    commandName = 'Flag'
-
-class FatalError(Exception):
-    pass
-
-class Fatal(Command):
-    fatalErrors = {FatalError: "quite bad"}
-
-class Erroneous(AMP):
-    def _fatal(self):
-        raise FatalError("This is fatal.")
-    Fatal.responder(_fatal)
-
-    flag = False
-    def _break(self):
-        raise ErroneousClientError("Zoop")
-    Break.responder(_break)
-
-    def _engenderError(self):
-        def ebBroken(err):
-            err.trap(ConnectionDone)
-            # This connection is dead.  Avoid having an error logged by turning
-            # this into success; the result can't possibly get to the other
-            # side, anyway. -exarkun
-            return {}
-        return self.callRemote(Break).addErrback(ebBroken)
-    EngenderError.responder(_engenderError)
-
-    def _flag(self):
-        self.flag = True
-        return {}
-    Flag.responder(_flag)
-
-class ErroneousServerFactory(protocol.ServerFactory):
-    protocol = Erroneous
-
-class ErroneousClientFactory(protocol.ClientFactory):
-    protocol = Erroneous
-
-class Greet(Command):
-    commandName = 'Greet'
-
-class Greeter(AMP, protocol.ServerFactory, protocol.ClientFactory):
-    def __init__(self, isServer, startupD):
-        self.isServer = isServer
-        AMP.__init__(self)
-        self.startupD = startupD
-
-    def buildProtocol(self, addr):
-        return self
-
-    def connectionMade(self):
-        self.callRemote(Greet).chainDeferred(self.startupD)
-
-    def _greet(self):
-        self.greeted = True
-        return dict()
-    Greet.responder(_greet)
-
-class Q2QConnectionTestCase(unittest.TestCase):
-    streamer = None
-
-    fromResource = 'clientResource'
-    toResource = 'serverResource'
-
-    fromDomain = 'origin.domain.example.com'
-    fromIP = '127.0.0.1'
-    spoofedDomain = 'spoofed.domain.example.com'
-    toDomain = 'destination.domain.example.org'
-    toIP = '127.0.0.2'
-
-    userReverseDNS = 'i.watch.too.much.tv'
-    inboundTCPPortnum = 0
-    udpEnabled = False
-    virtualEnabled = False
-
-    def _makeQ2QService(self, certificateEntity, publicIP, pff=None):
-        svc = q2q.Q2QService(pff, q2qPortnum=0,
-                             inboundTCPPortnum=self.inboundTCPPortnum,
-                             publicIP=publicIP)
-        svc.udpEnabled = self.udpEnabled
-        svc.virtualEnabled = self.virtualEnabled
-        if '@' not in certificateEntity:
-            svc.certificateStorage.addPrivateCertificate(certificateEntity)
-        svc.debugName = certificateEntity
-        return svc
-
-
-    def _addQ2QProtocol(self, name, factory):
-        resourceKey = (self.fromAddress,
-                       self.toAddress, name)
-        self.resourceMap[resourceKey] = factory
-
-    def protocolFactoryLookup(self, *key):
-        if key in self.resourceMap:
-            return [(self.resourceMap[key], 'test-description')]
-        return []
-
-
-    def setUp(self):
-        self.fromAddress = q2q.Q2QAddress(self.fromDomain, self.fromResource)
-        self.toAddress = q2q.Q2QAddress(self.toDomain, self.toResource)
-
-        # A mapping of host names to port numbers Our connectTCP will always
-        # connect to 127.0.0.1 and on a port which is a value in this
-        # dictionary.
-        fakeDNS = FakeConnectTCP(reactor.connectTCP)
-        reactor.connectTCP = fakeDNS.connectTCP
-
-        # ALSO WE MUST DO OTHER SIMILAR THINGS
-        self._oldResolver = reactor.resolver
-        reactor.installResolver(fakeDNS)
-
-        # Set up a know-nothing service object for the client half of the
-        # conversation.
-        self.serverService2 = self._makeQ2QService(self.fromDomain, self.fromIP, noResources)
-
-        # Do likewise for the server half of the conversation.  Also, allow
-        # test methods to set up some trivial resources which we can attempt to
-        # access from the client.
-        self.resourceMap = {}
-        self.serverService = self._makeQ2QService(self.toDomain, self.toIP,
-                                                  self.protocolFactoryLookup)
-
-        self.msvc = service.MultiService()
-        self.serverService2.setServiceParent(self.msvc)
-        self.serverService.setServiceParent(self.msvc)
-
-        # Let the kernel allocate a random port for each of these service's listeners
-        self.msvc.startService()
-
-        fakeDNS.addHostPort(
-            self.fromDomain, 8788,
-            self.serverService2.q2qPort.getHost().port)
-
-        fakeDNS.addHostPort(
-            self.toDomain, 8788,
-            self.serverService.q2qPort.getHost().port)
-
-        self._addQ2QProtocol('pony', OneTrickPonyServerFactory())
-
-        self.dataEater = DataEater()
-        self._addQ2QProtocol('eat', self.dataEater)
-
-        self._addQ2QProtocol('error', ErroneousServerFactory())
-
-    def tearDown(self):
-        reactor.installResolver(self._oldResolver)
-        del reactor.connectTCP
-        return self.msvc.stopService()
-
-
-
-class ConnectionTestMixin:
-
-    def testConnectWithIntroduction(self):
-        ponged = defer.Deferred()
-        self.serverService2.connectQ2Q(self.fromAddress,
-                                      self.toAddress,
-                                      'pony',
-                                      OneTrickPonyClientFactory(ponged))
-        return ponged.addCallback(lambda answerBox: self.failUnless('tricked' in answerBox))
-
-    def addClientService(self, toAddress, secret, serverService):
-        return self._addClientService(
-            toAddress.resource, secret, serverService, toAddress.domain)
-
-    def _addClientService(self, username,
-                          privateSecret, serverService,
-                          serverDomain):
-        svc = self._makeQ2QService(username + '@' + serverDomain, None)
-        serverService.certificateStorage.addUser(serverDomain,
-                                                 username,
-                                                 privateSecret)
-        svc.setServiceParent(self.msvc)
-        return svc.authorize(q2q.Q2QAddress(serverDomain, username),
-                             privateSecret).addCallback(lambda x: svc)
-
-
-    def testListening(self):
-        _1 = self.addClientService(self.toAddress, 'aaaa', self.serverService)
-        def _1c(_1result):
-            self.clientServerService = _1result
-            ponyFactory = OneTrickPonyServerFactory()
-            _2 = self.clientServerService.listenQ2Q(self.toAddress,
-                                                    {'pony2': ponyFactory},
-                                                    'ponies suck')
-
-            def _2c(ignored):
-                _3 = self.addClientService(
-                        self.fromAddress, 'bbbb', self.serverService2)
-                def _3c(_3result):
-                    self.clientClientService = _3result
-
-                    _4 = defer.Deferred()
-                    otpcf = OneTrickPonyClientFactory(_4)
-                    self.clientClientService.connectQ2Q(self.fromAddress,
-                                                        self.toAddress,
-                                                        'pony2',
-                                                        otpcf)
-                    def _4c(answerBox):
-                        T = otpcf.proto.transport
-                        self.assertEquals(T.getQ2QPeer(), self.toAddress)
-                        self.assertEquals(T.getQ2QHost(), self.fromAddress)
-                        self.failUnless('tricked' in answerBox)
-
-                    return _4.addCallback(_4c)
-                return _3.addCallback(_3c)
-            return _2.addCallback(_2c)
-        return _1.addCallback(_1c)
-
-    def testChooserGetsThreeChoices(self):
-
-        def actualTest(ign):
-            ponyFactory = OneTrickPonyServerFactory()
-            _1 = self.addClientService(
-                self.toAddress, 'aaaa', self.serverService)
-            def _1c(_1result):
-                self.clientServerService2 = _1result
-                # print 'ultra frack'
-
-                _2 = self.clientServerService2.listenQ2Q(self.toAddress,
-                                                         {'pony': ponyFactory},
-                                                         'ponies are weird')
-                def _2c(ign):
-                    _3 = self.clientServerService.listenQ2Q(self.toAddress,
-                                                            {'pony': ponyFactory},
-                                                            'ponies rule')
-                    def _3c(ign):
-                        expectedList = ['ponies rule', 'ponies are weird', 'test-description']
-                        def chooser(servers):
-                            self.failUnlessEqual(len(servers), 3)
-                            for server in servers:
-                                expectedList.remove(server['description'])
-                                if server['description'] == 'ponies rule':
-                                    self.assertEquals(
-                                        self.clientServerService.certificateStorage.getPrivateCertificate(str(self.toAddress)),
-                                        server['certificate'])
-                                    yield server
-
-                        factory = protocol.ClientFactory()
-                        factory.protocol = AMP
-                        _4 = self.clientClientService.connectQ2Q(
-                            self.fromAddress,
-                            self.toAddress,
-                            'pony',
-                            factory,
-                            chooser=chooser)
-                        def _4c(ign):
-                            self.failUnlessEqual(expectedList, [])
-                        return _4.addCallback(_4c)
-                    return _3.addCallback(_3c)
-                return _2.addCallback(_2c)
-            return _1.addCallback(_1c)
-        return self.testListening().addCallback(actualTest)
-
-        # print 'dang yo'
-
-
-    def testTwoGreetings(self):
-        d1 = defer.Deferred()
-        d2 = defer.Deferred()
-        client = Greeter(False, d1)
-        server = Greeter(True, d2)
-        self._addQ2QProtocol('greet', server)
-        self.serverService2.connectQ2Q(self.fromAddress,
-                                      self.toAddress,
-                                      'greet',
-                                      client)
-        def _(x):
-            self.failUnless(client.greeted)
-            self.failUnless(server.greeted)
-        return defer.DeferredList([d1, d2]).addCallback(_)
-
-
-    def testSendingFiles(self):
-        SIZE = 1024 * 500
-        self.streamer = StreamingDataFeeder(StringIO('x' * SIZE))
-        self.streamer.CHUNK = 8192
-        a = self.serverService2.connectQ2Q(self.fromAddress,
-                                                 self.toAddress, 'eat',
-                                                 DataFeeder(StringIO('y' * SIZE)))
-        b = self.serverService2.connectQ2Q(self.fromAddress,
-                                           self.toAddress, 'eat',
-                                           self.streamer)
-
-        def dotest(ign):
-            # self.assertEquals( len(self.serverService.liveConnections), 1)
-            # XXX currently there are 2 connections but there should only be 1: the
-            # connection cache is busted, need a separate test for that
-            for liveConnection in self.serverService.iterconnections():
-                liveConnection.transport.pauseProducing()
-            wfc = self.dataEater.waitForCount(SIZE * 2)
-            resumed = [False]
-            def shouldntHappen(x):
-                if resumed[0]:
-                    return x
-                else:
-                    self.fail("wfc fired with: " + repr(x))
-            wfc.addBoth(shouldntHappen)
-            def keepGoing(ign):
-                resumed[0] = True
-                for liveConnection in self.serverService.iterconnections():
-                    liveConnection.transport.resumeProducing()
-                def assertSomeStuff(ign):
-                    self.failUnless(self.streamer.pauseCount > 0)
-                    self.failUnless(self.streamer.resumeCount > 0)
-                return self.dataEater.waitForCount(SIZE * 2).addCallback(assertSomeStuff)
-            return deferLater(reactor, 3, lambda: None).addCallback(keepGoing)
-        return defer.DeferredList([a, b]).addCallback(dotest)
-    testSendingFiles.skip = "hangs forever"
-
-    def testBadIssuerOnSelfSignedCert(self):
-        x = self.testConnectWithIntroduction()
-        def actualTest(result):
-            ponged = defer.Deferred()
-            signer = self.serverService2.certificateStorage.getPrivateCertificate(
-                self.fromDomain).privateKey
-            req = signer.requestObject(DistinguishedName(commonName=self.toDomain))
-            sreq = signer.signRequestObject(
-                DistinguishedName(commonName=self.fromDomain), req, 12345)
-            selfSignedLie = PrivateCertificate.fromCertificateAndKeyPair(
-                sreq, signer)
-            self.serverService2.connectQ2Q(self.fromAddress,
-                                          self.toAddress,
-                                          'pony',
-                                          OneTrickPonyClientFactory(ponged),
-                                          selfSignedLie,
-                                          fakeFromDomain=self.toDomain).addErrback(
-                lambda e: e.trap(q2q.VerifyError))
-
-            return self.assertFailure(ponged, q2q.VerifyError)
-        return x.addCallback(actualTest)
-
-
-    def testBadCertRequestSubject(self):
-        kp = KeyPair.generate()
-        subject = DistinguishedName(commonName='HACKERX',
-                                    localityName='INTERNETANIA')
-        reqobj = kp.requestObject(subject)
-
-        fakereq = kp.requestObject(subject)
-        ssigned = kp.signRequestObject(subject, fakereq, 1)
-        certpair = PrivateCertificate.fromCertificateAndKeyPair
-        fakecert = certpair(ssigned, kp)
-        apc = self.serverService2.certificateStorage.addPrivateCertificate
-
-        def _2(secured):
-            D = secured.callRemote(
-                q2q.Sign,
-                certificate_request=reqobj,
-                password='itdoesntmatter')
-            def _1(dcert):
-                cert = dcert['certificate']
-                privcert = certpair(cert, kp)
-                apc(str(self.fromAddress), privcert)
-            return D.addCallback(_1)
-
-        d = self.serverService2.getSecureConnection(
-            self.fromAddress, self.fromAddress.domainAddress(), authorize=False,
-            usePrivateCertificate=fakecert,
-            ).addCallback(_2)
-
-        def unexpectedSuccess(result):
-            self.fail("Expected BadCertificateRequest, got %r" % (result,))
-        def expectedFailure(err):
-            err.trap(q2q.BadCertificateRequest)
-        d.addCallbacks(unexpectedSuccess, expectedFailure)
-        return d
-
-    def testClientSideUnhandledException(self):
-        d = self.serverService2.connectQ2Q(
-            self.fromAddress, self.toAddress, 'error',
-            ErroneousClientFactory())
-        def connected(proto):
-            return proto.callRemote(EngenderError)
-        d.addCallback(connected)
-        # The unhandled, undeclared error causes the connection to be closed
-        # from the other side.
-        d = self.assertFailure(d, ConnectionDone, UnknownRemoteError)
-        def cbDisconnected(err):
-            self.assertEqual(
-                len(self.flushLoggedErrors(ErroneousClientError)),
-                1)
-        d.addCallback(cbDisconnected)
-        return d
-
-    def successIsFailure(self, success):
-        self.fail()
-
-    def testTwoBadWrites(self):
-        d = self.serverService2.connectQ2Q(
-            self.fromAddress, self.toAddress, 'error',
-            ErroneousClientFactory())
-
-        def connected(proto):
-            d1 = self.assertFailure(proto.callRemote(Fatal), FatalError)
-            def noMoreCalls(_):
-                 self.assertFailure(proto.callRemote(Flag),
-                                    ConnectionDone)
-            d1.addCallback(noMoreCalls)
-            return d1
-        d.addCallback(connected)
-        return d
-
-
-
-
-class VirtualConnection(Q2QConnectionTestCase, ConnectionTestMixin):
-    inboundTCPPortnum = None
-    udpEnabled = False
-    virtualEnabled = True
-
-    def testListening(self):
-        pass
-
-    def testChooserGetsThreeChoices(self):
-        pass
-
-    testListening.skip = 'virtual port forwarding not implemented'
-    testChooserGetsThreeChoices.skip = 'cant do this without testListening'
-
-class UDPConnection(Q2QConnectionTestCase, ConnectionTestMixin):
-    # skip = 'yep'
-    inboundTCPPortnum = None
-    udpEnabled = True
-    virtualEnabled = False
-
-class TCPConnection(Q2QConnectionTestCase, ConnectionTestMixin):
-    inboundTCPPortnum = 0
-    udpEnabled = False
-    virtualEnabled = False
-
-# class LiveServerMixin:
-#     serverDomain = 'test.domain.example.com'
-
-#     def jackDNS(self, *info):
-#         self.fakeDNS = FakeConnectTCP(reactor.connectTCP)
-#         reactor.connectTCP = self.fakeDNS.connectTCP
-#         self._oldResolver = reactor.resolver
-#         reactor.installResolver(self.fakeDNS)
-
-#         for (hostname, oldport, newport) in info:
-#             self.fakeDNS.addHostPort(hostname, oldport, newport)
-
-#     def unjackDNS(self):
-#         del reactor.connectTCP
-#         reactor.installResolver(self._oldResolver)
-
-# class AuthorizeTestCase(unittest.TestCase, LiveServerMixin):
-#     authUser = 'authtestuser'
-#     authPass = 'p4ssw0rd'
-
-#     def setUp(self):
-#         self.testDir, serverService = self.deploy()
-#         self.serverService = service.IServiceCollection(serverService)
-#         self.serverService.startService()
-#         self.clientDir = os.path.join(self.testDir, 'client')
-#         self.clientService = q2qclient.ClientQ2QService(self.clientDir)
-
-#         q2qPort = self.getQ2QService().q2qPort.getHost().port
-#         self.jackDNS((self.serverDomain, 8788, q2qPort))
-
-#     def tearDown(self):
-#         self.unjackDNS()
-#         util.wait(self.serverService.stopService())
-#         util.wait(self.clientService.stopService())
-
-#     def testAuthorize(self):
-#         self.createUser(self.authUser, self.authPass)
-
-#         d = self.clientService.authorize(
-#             q2q.Q2QAddress(self.serverDomain, self.authUser),
-#             self.authPass)
-
-#         result = runOneDeferred(d)
-
-#         self.failUnless(os.path.exists(os.path.join(self.clientDir, 'public')))
-#         self.failUnless(os.path.exists(os.path.join(self.clientDir, 'public', self.serverDomain + '.pem')))
-#         self.failUnless(os.path.exists(os.path.join(self.clientDir, 'private')))
-#         self.failUnless(os.path.exists(os.path.join(self.clientDir, 'private', self.authUser + '@' + self.serverDomain + '.pem')))

=== removed file 'Vertex/vertex/test/test_sigma.py'
--- Vertex/vertex/test/test_sigma.py	2012-03-14 16:23:22 +0000
+++ Vertex/vertex/test/test_sigma.py	1970-01-01 00:00:00 +0000
@@ -1,210 +0,0 @@
-# Copyright 2005 Divmod, Inc.  See LICENSE file for details
-
-from cStringIO import StringIO
-
-from twisted.internet.protocol import FileWrapper
-from twisted.internet import defer
-from twisted.python.failure import Failure
-from twisted.python.filepath import FilePath
-
-from twisted.trial import unittest
-
-from twisted.test.iosim import connectedServerAndClient, FakeTransport
-
-from vertex.q2q import Q2QAddress
-from vertex import sigma
-
-from vertex.test.mock_data import data as TEST_DATA
-
-class FakeQ2QTransport(FakeTransport):
-
-    def __init__(self, q2qhost, q2qpeer):
-        FakeTransport.__init__(self)
-        self.q2qhost = q2qhost
-        self.q2qpeer = q2qpeer
-
-    def getQ2QPeer(self):
-        return self.q2qpeer
-
-    def getQ2QHost(self):
-        return self.q2qhost
-
-class FakeDelayedCall:
-    def __init__(self, fqs, tup):
-        self.fqs = fqs
-        self.tup = tup
-
-    def cancel(self):
-        self.fqs.calls.remove(self.tup)
-
-class FakeQ2QService:
-    # XXX TODO: move this into test_q2q and make sure that all the q2q tests
-    # run with it in order to verify that the test harness is not broken.
-
-    def __init__(self):
-        self.listeners = {}     # map listening {(q2qid, protocol name):(protocol
-                                # factory, protocol description)}
-        self.pumps = []         # a list of IOPumps that we have to flush
-        self.calls = []
-        self.time = 0
-
-    def callLater(self, s, f, *a, **k):
-        # XXX TODO: return canceller
-        assert f is not None
-        tup = (self.time + s, f, a, k)
-        self.calls.append(tup)
-        self.calls.sort()
-        return FakeDelayedCall(self, tup)
-
-    def flush(self, debug=False):
-        result = True
-        while result:
-            self.time += 1
-            result = False
-            for x in range(2):
-                # run twice so that timed functions can interact with I/O
-                for pump in self.pumps:
-                    if pump.flush(debug):
-                        result = True
-                if debug:
-                    print 'iteration finished.  continuing?', result
-                c = self.calls
-                self.calls = []
-                for s, f, a, k in c:
-                    if debug:
-                        print 'timed event', s, f, a, k
-                    f(*a,**k)
-        return result
-
-    def listenQ2Q(self, fromAddress, protocolsToFactories, serverDescription):
-        for pname, pfact in protocolsToFactories.items():
-            self.listeners[fromAddress, pname] = pfact, serverDescription
-        return defer.succeed(None)
-
-    def connectQ2Q(self, fromAddress, toAddress,
-                   protocolName, protocolFactory,
-                   chooser=lambda x: x and [x[0]]):
-        # XXX update this when q2q is updated to return a connector rather than
-        # a Deferred.
-
-        # XXX this isn't really dealing with the multiple-connectors use case
-        # now.  sigma doesn't need this functionality, but we will need to
-        # update this class to do it properly before using it to test other Q2Q
-        # code.
-
-        listener, description = self.listeners.get((toAddress, protocolName))
-        if listener is None:
-            print 'void listener', fromAddress, toAddress, self.listeners, self.listener
-            reason = Failure(KeyError())
-            protocolFactory.clientConnectionFailed(None, reason)
-            return defer.fail(reason)
-        else:
-            def makeFakeClient(c):
-                ft = FakeQ2QTransport(fromAddress, toAddress)
-                ft.isServer = False
-                ft.protocol = c
-                return ft
-
-            def makeFakeServer(s):
-                ft = FakeQ2QTransport(toAddress, fromAddress)
-                ft.isServer = True
-                ft.protocol = s
-                return ft
-
-            client, server, pump = connectedServerAndClient(
-                lambda: listener.buildProtocol(fromAddress),
-                lambda: protocolFactory.buildProtocol(toAddress),
-                makeFakeClient,
-                makeFakeServer)
-            self.pumps.append(pump)
-
-            return defer.succeed(client)
-
-
-sender = Q2QAddress("sending-data.net", "sender")
-receiver = Q2QAddress("receiving-data.org", "receiver")
-
-class TestBase(unittest.TestCase):
-    def setUp(self):
-        self.realChunkSize = sigma.CHUNK_SIZE
-        sigma.CHUNK_SIZE = 100
-        svc = self.service = FakeQ2QService()
-        fname = self.mktemp()
-
-        sf = self.sfile = FilePath(fname)
-        if not sf.parent().isdir():
-            sf.parent().makedirs()
-        sf.open('w').write(TEST_DATA)
-        self.senderNexus = sigma.Nexus(svc, sender,
-                                       sigma.BaseNexusUI(self.mktemp()),
-                                       svc.callLater)
-
-    def tearDown(self):
-        self.senderNexus.stopService()
-        sigma.CHUNK_SIZE = self.realChunkSize
-
-
-class BasicTransferTest(TestBase):
-    def setUp(self):
-        TestBase.setUp(self)
-        self.stoppers = []
-        self.receiverNexus = sigma.Nexus(self.service, receiver,
-                                         sigma.BaseNexusUI(self.mktemp()),
-                                         self.service.callLater)
-        self.stoppers.append(self.receiverNexus)
-
-
-    def tearDown(self):
-        TestBase.tearDown(self)
-        for stopper in self.stoppers:
-            stopper.stopService()
-
-
-    def testOneSenderOneRecipient(self):
-        self.senderNexus.push(self.sfile, 'TESTtoTEST', [receiver])
-        self.service.flush()
-        peerThingyoes = childrenOf(self.receiverNexus.ui.basepath)
-        self.assertEquals(len(peerThingyoes), 1)
-        rfiles = childrenOf(peerThingyoes[0])
-        self.assertEquals(len(rfiles), 1)
-        rfile = rfiles[0]
-        rfdata = rfile.open().read()
-        self.assertEquals(len(rfdata),
-                          len(TEST_DATA))
-        self.assertEquals(rfdata, TEST_DATA,
-                          "file values unequal")
-
-    def testOneSenderManyRecipients(self):
-        raddresses = [Q2QAddress("receiving-data.org", "receiver%d" % (x,))
-                      for x in range(10)]
-
-        nexi = [sigma.Nexus(self.service,
-                            radr,
-                            sigma.BaseNexusUI(self.mktemp()),
-                            self.service.callLater) for radr in raddresses]
-
-        self.stoppers.extend(nexi)
-
-        self.senderNexus.push(self.sfile, 'TESTtoTEST', raddresses)
-        self.service.flush()
-
-        receivedIntroductions = 0
-
-        for nexium in nexi:
-            receivedIntroductions += nexium.ui.receivedIntroductions
-        self.failUnless(receivedIntroductions > 1)
-
-        for nexium in nexi:
-            peerFiles = childrenOf(nexium.ui.basepath)
-            self.assertEquals(len(peerFiles), 1)
-            rfiles = childrenOf(peerFiles[0])
-            self.assertEquals(len(rfiles), 1, rfiles)
-            rfile = rfiles[0]
-            self.assertEquals(rfile.open().read(),
-                              TEST_DATA,
-                              "file value mismatch")
-
-
-def childrenOf(x):
-    # this should be a part of FilePath, but hey
-    return map(x.child, x.listdir())

=== removed file 'Vertex/vertex/test/test_statemachine.py'
--- Vertex/vertex/test/test_statemachine.py	2005-08-05 03:13:02 +0000
+++ Vertex/vertex/test/test_statemachine.py	1970-01-01 00:00:00 +0000
@@ -1,67 +0,0 @@
-
-from twisted.trial import unittest
-
-from vertex import statemachine
-
-S_1, S_2 = 'S_1', 'S_2'
-I_1, I_2 = 'I_1', 'I_2'
-O_1, O_2 = 'O_1', 'O_2'
-
-class TestMachine(statemachine.StateMachine):
-    states = {
-        S_1: {
-            I_1: (O_1, S_1),
-            I_2: (O_1, S_2),
-            },
-        S_2: {
-            I_1: (O_2, S_2),
-            I_2: (O_1, S_2),
-            },
-        }
-
-    initialState = S_1
-
-    def _event(self, name):
-        def method():
-            self.events.append(name)
-        return method
-
-    def __getattr__(self, name):
-        if (name.startswith('exit_') or name.startswith('enter_') or
-            name.startswith('transition_') or name.startswith('output_')):
-            return self._event(name)
-        raise AttributeError(name)
-
-class Transitions(unittest.TestCase):
-    def testOutput(self):
-        m = TestMachine()
-
-        self.assertEquals(m.state, S_1)
-
-        m.events = []
-        m.input(I_1)
-        self.assertEquals(
-            m.events,
-            ['output_O_1'])
-        self.assertEquals(m.state, S_1)
-
-        m.events = []
-        m.input(I_2)
-        self.assertEquals(
-            m.events,
-            ['exit_S_1', 'enter_S_2', 'transition_S_1_to_S_2', 'output_O_1'])
-        self.assertEquals(m.state, S_2)
-
-        m.events = []
-        m.input(I_1)
-        self.assertEquals(
-            m.events,
-            ['output_O_2'])
-        self.assertEquals(m.state, S_2)
-
-        m.events = []
-        m.input(I_2)
-        self.assertEquals(
-            m.events,
-            ['output_O_1'])
-        self.assertEquals(m.state, S_2)

=== removed file 'Vertex/vertex/test/test_subproducer.py'
--- Vertex/vertex/test/test_subproducer.py	2005-08-10 18:51:37 +0000
+++ Vertex/vertex/test/test_subproducer.py	1970-01-01 00:00:00 +0000
@@ -1,173 +0,0 @@
-
-from twisted.trial import unittest
-
-from vertex.subproducer import SuperProducer, SubProducer
-
-class TestSuper(SuperProducer):
-    transport = property(lambda self: self)
-
-    def registerProducer(self, producer, streaming):
-        self.producer = producer
-        self.streamingProducer = streaming
-
-    def unregisterProducer(self):
-        self.producer = None
-
-class TestProducer:
-    def __init__(self):
-        self.calls = []
-
-    def resumeProducing(self):
-        self.calls.append('resume')
-
-    def pauseProducing(self):
-        self.calls.append('pause')
-
-    def stopProducing(self):
-        self.calls.append('stop')
-
-    def clear(self):
-        del self.calls[:]
-
-
-class SuperProducerTest(unittest.TestCase):
-
-    def testBasicNotification(self):
-        sup = TestSuper()
-        sub = SubProducer(sup)
-
-        tp1 = TestProducer()
-        sub.registerProducer(tp1, False)
-        self.assertEquals(tp1.calls, ['resume'])
-        sub.unregisterProducer()
-
-        tp2 = TestProducer()
-        sub.registerProducer(tp2, True)
-        self.assertEquals(tp2.calls, [])
-        sub.unregisterProducer()
-
-    def testPauseSuperBeforeRegister(self):
-        sup = TestSuper()
-        sub1 = SubProducer(sup)
-        sub2 = SubProducer(sup)
-
-        tp1 = TestProducer()
-        tp2 = TestProducer()
-
-        sub1.registerProducer(tp1, False)
-        sub2.registerProducer(tp2, False)
-
-        self.assertEquals(sup.producer, sup) # Make sure it's registered with
-                                             # itself; IOW it has called
-                                             # self.transport.registerProducer(self).
-
-        sup.pauseProducing()
-        sup.resumeProducing()
-
-        self.assertEquals(tp1.calls, ['resume', 'pause', 'resume'])
-        self.assertEquals(tp2.calls, ['resume', 'pause', 'resume'])
-
-        sup.stopProducing()
-        self.assertEquals(tp1.calls, ['resume', 'pause', 'resume', 'stop'])
-        self.assertEquals(tp2.calls, ['resume', 'pause', 'resume', 'stop'])
-
-
-    def testNonStreamingChoke(self):
-        sup = TestSuper()
-        sub1 = SubProducer(sup)
-        sub2 = SubProducer(sup)
-
-        tp1 = TestProducer()
-        tp2 = TestProducer()
-
-        sub1.registerProducer(tp1, False)
-        sub2.registerProducer(tp2, False)
-
-        self.assertEquals(tp1.calls, ['resume'])
-        self.assertEquals(tp2.calls, ['resume'])
-
-        tp1.clear()
-        tp2.clear()
-
-        self.assertEquals(sup.producer, sup)
-
-        sub1.choke()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, [])
-
-        sup.pauseProducing()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, ['pause'])
-
-        sup.resumeProducing()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, ['pause', 'resume'])
-
-        sup.pauseProducing()
-        sup.resumeProducing()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, ['pause', 'resume', 'pause', 'resume'])
-        sub1.unchoke()
-
-        self.assertEquals(tp1.calls, ['pause', 'resume'])
-        self.assertEquals(tp2.calls, ['pause', 'resume', 'pause', 'resume'])
-
-        sup.pauseProducing()
-        sub1.choke()
-        sub1.choke()
-        sub1.choke()
-        self.assertEquals(tp1.calls, ['pause', 'resume', 'pause'])
-        self.assertEquals(tp2.calls, ['pause', 'resume', 'pause', 'resume',
-                                      'pause'])
-
-        sub1.unchoke()
-        self.assertEquals(tp1.calls, ['pause', 'resume', 'pause'])
-        self.assertEquals(tp2.calls, ['pause', 'resume', 'pause', 'resume',
-                                      'pause'])
-
-        sup.resumeProducing()
-        self.assertEquals(tp1.calls, ['pause', 'resume', 'pause', 'resume'])
-        self.assertEquals(tp2.calls, ['pause', 'resume', 'pause', 'resume',
-                                      'pause', 'resume'])
-        tp1.clear()
-        tp2.clear()
-        sup.stopProducing()
-
-        self.assertEquals(tp1.calls, ['stop'])
-        self.assertEquals(tp2.calls, ['stop'])
-
-    def testStreamingChoke(self):
-        sup = TestSuper()
-        sub1 = SubProducer(sup)
-        sub2 = SubProducer(sup)
-
-        tp1 = TestProducer()
-        tp2 = TestProducer()
-
-        sub1.registerProducer(tp1, True)
-        sub2.registerProducer(tp2, True)
-
-        self.assertEquals(tp1.calls, [])
-        self.assertEquals(tp2.calls, [])
-
-        sub1.choke()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, [])
-
-        sup.pauseProducing()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, ['pause'])
-
-        sup.resumeProducing()
-        self.assertEquals(tp1.calls, ['pause'])
-        self.assertEquals(tp2.calls, ['pause', 'resume'])
-
-        sub1.unchoke()
-        self.assertEquals(tp1.calls, ['pause', 'resume'])
-        self.assertEquals(tp2.calls, ['pause', 'resume'])
-
-        tp1.clear()
-        tp2.clear()
-        sup.stopProducing()
-        self.assertEquals(tp1.calls, ['stop'])
-        self.assertEquals(tp2.calls, ['stop'])


Follow ups