# Path: groundstation/objects/update_object.py
# class UpdateObject(base_object.BaseObject):
#     data_members = ["parents", "data"]
# 
#     def __init__(self, parents, data):
#         self.parents = parents
#         self.data = data
#         self._sha1 = None
# 
#     @staticmethod
#     def from_object(obj):
#         """Convert an object straight from Git into a RootObject"""
#         protobuf = update_object_pb2.UpdateObject()
#         protobuf.ParseFromString(obj)
#         return UpdateObject(protobuf.parents, protobuf.data)
# 
#     def as_object(self):
#         """Convert a RootObject into data suitable to write into the database
#         as a Git object"""
#         protobuf = update_object_pb2.UpdateObject()
#         protobuf.parents.extend(self.parents)
#         protobuf.data = self.data
#         return protobuf.SerializeToString()
# 
# Path: groundstation/objects/root_object.py
# class RootObject(base_object.BaseObject):
#     data_members = ["id", "channel", "protocol"]
# 
#     def __init__(self, id, channel, protocol):
#         self.id = id
#         self.channel = channel
#         self.protocol = protocol
#         self._sha1 = None
# 
#     @staticmethod
#     def from_object(obj):
#         """Convert an object straight from Git into a RootObject"""
#         protobuf = root_object_pb2.RootObject()
#         protobuf.ParseFromString(obj)
#         return RootObject(protobuf.id, protobuf.channel, protobuf.protocol)
# 
#     def as_object(self):
#         """Convert a RootObject into data suitable to write into the database
#         as a Git object"""
#         protobuf = root_object_pb2.RootObject()
#         for member in self.data_members:
#             setattr(protobuf, member, getattr(self, member))
#         return protobuf.SerializeToString()
# 
#     def as_json(self):
#         return {
#                 "id": self.id,
#                 "channel": self.channel,
#                 "protocol": self.protocol
#                 }


import os
import groundstation.objects.object_factory as object_factory
import logger
from collections import namedtuple
from groundstation.objects.update_object import UpdateObject
from groundstation.objects.root_object import RootObject
        return parents

    def marshall(self, crypto_adaptor=None):
        """Marshalls the gref into something renderable:
        {
            "thread": An ordered thread of UpdateObjects. Ordering is
                      arbitraryish.
            "roots": The root nodes of this gref.
            "tips": The string names of the tips used to marshall
        }
        """
        thread = []
        root_nodes = []
        visited_nodes = set()
        tips = []
        signatures = {}

        # TODO Big issues will smash the stack
        def _process(node):
            if node in visited_nodes:
                log.debug("Bailing on visited node: %s" % (node))
                return
            visited_nodes.add(node)

            if crypto_adaptor:
                signature = self.get_signature(node)
                if signature:
                    signatures[node] = crypto_adaptor.verify(node, signature)

            obj = object_factory.hydrate_object(self.store[node].data)

# Path: groundstation/objects/update_object.py
# class UpdateObject(base_object.BaseObject):
#     data_members = ["parents", "data"]
# 
#     def __init__(self, parents, data):
#         self.parents = parents
#         self.data = data
#         self._sha1 = None
# 
#     @staticmethod
#     def from_object(obj):
#         """Convert an object straight from Git into a RootObject"""
#         protobuf = update_object_pb2.UpdateObject()
#         protobuf.ParseFromString(obj)
#         return UpdateObject(protobuf.parents, protobuf.data)
# 
#     def as_object(self):
#         """Convert a RootObject into data suitable to write into the database
#         as a Git object"""
#         protobuf = update_object_pb2.UpdateObject()
#         protobuf.parents.extend(self.parents)
#         protobuf.data = self.data
#         return protobuf.SerializeToString()
# 
# Path: groundstation/objects/root_object.py
# class RootObject(base_object.BaseObject):
#     data_members = ["id", "channel", "protocol"]
# 
#     def __init__(self, id, channel, protocol):
#         self.id = id
#         self.channel = channel
#         self.protocol = protocol
#         self._sha1 = None
# 
#     @staticmethod
#     def from_object(obj):
#         """Convert an object straight from Git into a RootObject"""
#         protobuf = root_object_pb2.RootObject()
#         protobuf.ParseFromString(obj)
#         return RootObject(protobuf.id, protobuf.channel, protobuf.protocol)
# 
#     def as_object(self):
#         """Convert a RootObject into data suitable to write into the database
#         as a Git object"""
#         protobuf = root_object_pb2.RootObject()
#         for member in self.data_members:
#             setattr(protobuf, member, getattr(self, member))
#         return protobuf.SerializeToString()
# 
#     def as_json(self):
#         return {
#                 "id": self.id,
#                 "channel": self.channel,
#                 "protocol": self.protocol
#                 }


# Path: groundstation/gref.py
import os
import groundstation.objects.object_factory as object_factory
import logger
from collections import namedtuple
from groundstation.objects.update_object import UpdateObject
from groundstation.objects.root_object import RootObject

        return parents

    def marshall(self, crypto_adaptor=None):
        """Marshalls the gref into something renderable:
        {
            "thread": An ordered thread of UpdateObjects. Ordering is
                      arbitraryish.
            "roots": The root nodes of this gref.
            "tips": The string names of the tips used to marshall
        }
        """
        thread = []
        root_nodes = []
        visited_nodes = set()
        tips = []
        signatures = {}

        # TODO Big issues will smash the stack
        def _process(node):
            if node in visited_nodes:
                log.debug("Bailing on visited node: %s" % (node))
                return
            visited_nodes.add(node)

            if crypto_adaptor:
                signature = self.get_signature(node)
                if signature:
                    signatures[node] = crypto_adaptor.verify(node, signature)

            obj = object_factory.hydrate_object(self.store[node].data)

            if isinstance(obj, RootObject):  # We've found a root