diff --git a/xos/attic/header.py b/xos/attic/header.py
new file mode 100644
index 0000000..9e5e133
--- /dev/null
+++ b/xos/attic/header.py
@@ -0,0 +1,22 @@
+from django.db import models
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, NetworkParameter, NetworkParameterType, Port, AddressPool, User
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.db.models import *
+
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.vrouter.models import VRouterService, VRouterTenant
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+    pass
+
+VEG_KIND = "vEG"
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
diff --git a/xos/attic/vegtenant_bottom.py b/xos/attic/vegtenant_bottom.py
new file mode 100644
index 0000000..e60e71b
--- /dev/null
+++ b/xos/attic/vegtenant_bottom.py
@@ -0,0 +1,12 @@
+def model_policy_veg(pk):
+    # TODO: this should be made in to a real model_policy
+    with transaction.atomic():
+        veg = VEGTenant.objects.select_for_update().filter(pk=pk)
+        if not veg:
+            return
+        veg = veg[0]
+        veg.manage_container()
+        veg.manage_vrouter()
+        veg.cleanup_orphans()
+
+
diff --git a/xos/attic/vegtenant_model.py b/xos/attic/vegtenant_model.py
new file mode 100644
index 0000000..943b205
--- /dev/null
+++ b/xos/attic/vegtenant_model.py
@@ -0,0 +1,300 @@
+sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
+                   "wan_container_gateway_ip", "wan_container_gateway_mac",
+                   "wan_vm_ip", "wan_vm_mac")
+
+
+def __init__(self, *args, **kwargs):
+    super(VEGTenant, self).__init__(*args, **kwargs)
+    self.cached_vrouter=None
+
+@property
+def vrouter(self):
+    vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
+    if not vrouter:
+        return None
+
+    # always return the same object when possible
+    if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
+        return self.cached_vrouter
+
+    vrouter.caller = self.creator
+    self.cached_vrouter = vrouter
+    return vrouter
+
+@vrouter.setter
+def vrouter(self, value):
+    raise XOSConfigurationError("vEGTenant.vrouter setter is not implemented")
+
+@property
+def volt(self):
+    from services.volt.models import VOLTTenant
+    if not self.subscriber_tenant:
+        return None
+    volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
+    if not volts:
+        return None
+    return volts[0]
+
+@volt.setter
+def volt(self, value):
+    raise XOSConfigurationError("VEGTenant.volt setter is not implemented")
+
+@property
+def ssh_command(self):
+    if self.instance:
+        return self.instance.get_ssh_command()
+    else:
+        return "no-instance"
+
+def get_vrouter_field(self, name, default=None):
+    if self.vrouter:
+        return getattr(self.vrouter, name, default)
+    else:
+        return default
+
+@property
+def wan_container_ip(self):
+    return self.get_vrouter_field("public_ip", None)
+
+@property
+def wan_container_mac(self):
+    return self.get_vrouter_field("public_mac", None)
+
+@property
+def wan_container_netbits(self):
+    return self.get_vrouter_field("netbits", None)
+
+@property
+def wan_container_gateway_ip(self):
+    return self.get_vrouter_field("gateway_ip", None)
+
+@property
+def wan_container_gateway_mac(self):
+    return self.get_vrouter_field("gateway_mac", None)
+
+@property
+def wan_vm_ip(self):
+    tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+    if tags:
+        tenant = VRouterTenant.objects.get(id=tags[0].value)
+        return tenant.public_ip
+    else:
+        raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+
+@property
+def wan_vm_mac(self):
+    tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+    if tags:
+        tenant = VRouterTenant.objects.get(id=tags[0].value)
+        return tenant.public_mac
+    else:
+        raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+
+@property
+def is_synced(self):
+    return (self.enacted is not None) and (self.enacted >= self.updated)
+
+@is_synced.setter
+def is_synced(self, value):
+    pass
+
+def get_vrouter_service(self):
+    vrouterServices = VRouterService.get_service_objects().all()
+    if not vrouterServices:
+        raise XOSConfigurationError("No VROUTER Services available")
+    return vrouterServices[0]
+
+def manage_vrouter(self):
+    # Each vEG object owns exactly one vRouterTenant object
+
+    if self.deleted:
+        return
+
+    if self.vrouter is None:
+        vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_veg", subscriber_tenant = self)
+        vrouter.caller = self.creator
+        vrouter.save()
+
+def cleanup_vrouter(self):
+    if self.vrouter:
+        # print "XXX cleanup vrouter", self.vrouter
+        self.vrouter.delete()
+
+def cleanup_orphans(self):
+    # ensure vEG only has one vRouter
+    cur_vrouter = self.vrouter
+    for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
+        if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
+            # print "XXX clean up orphaned vrouter", vrouter
+            vrouter.delete()
+
+    if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
+        instances=Instance.objects.filter(id=self.orig_instance_id)
+        if instances:
+            # print "XXX clean up orphaned instance", instances[0]
+            instances[0].delete()
+
+def get_slice(self):
+    if not self.provider_service.slices.count():
+        print self, "dio porco"
+        raise XOSConfigurationError("The service has no slices")
+    slice = self.provider_service.slices.all()[0]
+    return slice
+
+def get_veg_service(self):
+    return VEGService.get_service_objects().get(id=self.provider_service.id)
+
+def find_instance_for_s_tag(self, s_tag):
+    #s_tags = STagBlock.objects.find(s_s_tag)
+    #if s_tags:
+    #    return s_tags[0].instance
+
+    tags = Tag.objects.filter(name="s_tag", value=s_tag)
+    if tags:
+        return tags[0].content_object
+
+    return None
+
+def find_or_make_instance_for_s_tag(self, s_tag):
+    instance = self.find_instance_for_s_tag(self.volt.s_tag)
+    if instance:
+        return instance
+
+    flavors = Flavor.objects.filter(name="m1.small")
+    if not flavors:
+        raise XOSConfigurationError("No m1.small flavor")
+
+    slice = self.provider_service.slices.all()[0]
+
+    if slice.default_isolation == "container_vm":
+        (node, parent) = ContainerVmScheduler(slice).pick()
+    else:
+        (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_veg_service().node_label).pick()
+
+    instance = Instance(slice = slice,
+                    node = node,
+                    image = self.image,
+                    creator = self.creator,
+                    deployment = node.site_deployment.deployment,
+                    flavor = flavors[0],
+                    isolation = slice.default_isolation,
+                    parent = parent)
+
+    self.save_instance(instance)
+
+    return instance
+
+def manage_container(self):
+    from core.models import Instance, Flavor
+
+    if self.deleted:
+        return
+
+    # For container or container_vm isolation, use what TenantWithCotnainer
+    # provides us
+    slice = self.get_slice()
+    if slice.default_isolation in ["container_vm", "container"]:
+        super(VEGTenant,self).manage_container()
+        return
+
+    if not self.volt:
+        raise XOSConfigurationError("This vEG container has no volt")
+
+    if self.instance:
+        # We're good.
+        return
+
+    instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
+    self.instance = instance
+    super(TenantWithContainer, self).save()
+
+def cleanup_container(self):
+    if self.get_slice().default_isolation in ["container_vm", "container"]:
+        super(VEGTenant,self).cleanup_container()
+
+    # To-do: cleanup unused instances
+    pass
+
+def find_or_make_port(self, instance, network, **kwargs):
+    port = Port.objects.filter(instance=instance, network=network)
+    if port:
+        port = port[0]
+    else:
+        port = Port(instance=instance, network=network, **kwargs)
+        port.save()
+    return port
+
+def get_lan_network(self, instance):
+    slice = self.provider_service.slices.all()[0]
+    # there should only be one network private network, and its template should not be the management template
+    lan_networks = [x for x in slice.networks.all() if x.template.visibility == "private" and (not "management" in x.template.name)]
+    if len(lan_networks) > 1:
+        raise XOSProgrammingError("The vEG slice should only have one non-management private network")
+    if not lan_networks:
+        raise XOSProgrammingError("No lan_network")
+    return lan_networks[0]
+
+def save_instance(self, instance):
+    with transaction.atomic():
+        instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
+        super(VEGTenant, self).save_instance(instance)
+
+        if instance.isolation in ["container", "container_vm"]:
+            lan_network = self.get_lan_network(instance)
+            port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
+            port.set_parameter("c_tag", self.volt.c_tag)
+            port.set_parameter("s_tag", self.volt.s_tag)
+            port.set_parameter("device", "eth1")
+            port.set_parameter("bridge", "br-lan")
+
+            wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
+            if not wan_networks:
+                raise XOSProgrammingError("No wan_network")
+            port = self.find_or_make_port(instance, wan_networks[0])
+            port.set_parameter("next_hop", value="10.0.1.253")   # FIX ME
+            port.set_parameter("device", "eth0")
+
+        if instance.isolation in ["vm"]:
+            lan_network = self.get_lan_network(instance)
+            port = self.find_or_make_port(instance, lan_network)
+            port.set_parameter("c_tag", self.volt.c_tag)
+            port.set_parameter("s_tag", self.volt.s_tag)
+            port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
+            port.save()
+
+        # tag the instance with the s-tag, so we can easily find the
+        # instance later
+        if self.volt and self.volt.s_tag:
+            tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
+            if not tags:
+                tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
+                tag.save()
+
+        # VTN-CORD needs a WAN address for the VM, so that the VM can
+        # be configured.
+        tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
+
+        if not tags:
+            vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_veg", subscriber_service=self.provider_service)
+            vrouter.set_attribute("tenant_for_instance_id", instance.id)
+            vrouter.save()
+            tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant",value="%d" % vrouter.id)
+            tag.save()
+
+def save(self, *args, **kwargs):
+    if not self.creator:
+        if not getattr(self, "caller", None):
+            # caller must be set when creating a vEG since it creates a slice
+            raise XOSProgrammingError("VEGTenant's self.caller was not set")
+        self.creator = self.caller
+        if not self.creator:
+            raise XOSProgrammingError("VEGTenant's self.creator was not set")
+
+    super(VEGTenant, self).save(*args, **kwargs)
+    model_policy_veg(self.pk)
+
+def delete(self, *args, **kwargs):
+    self.cleanup_vrouter()
+    self.cleanup_container()
+    super(VEGTenant, self).delete(*args, **kwargs)
+
