Link.py
class Link(object):
    __slots__ = ["_next", "_prev"]

    def __init__(self):
        self._next = self._prev = None
        pass

    @property
    def Next(self):
        return self._next

    @Next.setter
    def Next(self, obj):
        if self._next == obj:
            return

        if not issubclass(obj.__class__, Link):
            raise TypeError("Wrong Type: %s" % obj)
        if self._next is None:
            self._next = obj
        else:
            self._next.Prev = obj
        obj.Prev = self

    @property
    def Prev(self):
        return self._prev

    @Prev.setter
    def Prev(self, obj):
        if self._prev == obj:
            return

        if not issubclass(obj.__class__, Link):
            raise TypeError("Wrong Type: %s" % obj)
        if self._prev is None:
            self._prev = obj
        else:
            self._prev.Next = obj

    @property
    def First(self):
        p = self
        while p._prev is not None:
            p = p._prev
        return p

    @property
    def Last(self):
        p = self
        while p._next is not None:
            p = p._next
        return p

    def insert(self, linkobj):
        assert isinstance(linkobj, self.__class__)
        linkobj.First._prev = self
        linkobj.Last._next = self._next
        self._next = linkobj

    def append(self, linkobj):
        assert isinstance(linkobj, self.__class__)
        obj_first = linkobj.First
        last = self.Last
        last._next = obj_first
        obj_first._prev = last

    def remove(self):
        if self._prev:
            self._prev._next = self._prev
        if self._next:
            self._next._prev = self._next

    def __del__(self):
        self.remove()