diff --git a/xos/attic/header.py b/xos/attic/header.py
new file mode 100644
index 0000000..6b19427
--- /dev/null
+++ b/xos/attic/header.py
@@ -0,0 +1,21 @@
+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.forms.models import model_to_dict
+from django.db.models import *
+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
+
+VCPE_KIND = "vCPE"
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
diff --git a/xos/attic/vsgtenant_bottom.py b/xos/attic/vsgtenant_bottom.py
new file mode 100644
index 0000000..767a903
--- /dev/null
+++ b/xos/attic/vsgtenant_bottom.py
@@ -0,0 +1,11 @@
+def model_policy_vcpe(pk):
+    # TODO: this should be made in to a real model_policy
+    with transaction.atomic():
+        vcpe = VSGTenant.objects.select_for_update().filter(pk=pk)
+        if not vcpe:
+            return
+        vcpe = vcpe[0]
+        vcpe.manage_container()
+        vcpe.manage_vrouter()
+        vcpe.cleanup_orphans()
+
diff --git a/xos/attic/vsgtenant_model.py b/xos/attic/vsgtenant_model.py
new file mode 100644
index 0000000..d768098
--- /dev/null
+++ b/xos/attic/vsgtenant_model.py
@@ -0,0 +1,298 @@
+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(VSGTenant, 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("VSGTenant.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("VSGTenant.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 vCPE 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_vsg", 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 vCPE 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_vsg_service(self):
+    return VSGService.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_vsg_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(VSGTenant,self).manage_container()
+        return
+
+    if not self.volt:
+        raise XOSConfigurationError("This vCPE 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(VSGTenant,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 vSG 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(VSGTenant, 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_vsg", 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 vCPE since it creates a slice
+            raise XOSProgrammingError("VSGTenant's self.caller was not set")
+        self.creator = self.caller
+        if not self.creator:
+            raise XOSProgrammingError("VSGTenant's self.creator was not set")
+
+    super(VSGTenant, self).save(*args, **kwargs)
+    model_policy_vcpe(self.pk)
+
+def delete(self, *args, **kwargs):
+    self.cleanup_vrouter()
+    self.cleanup_container()
+    super(VSGTenant, self).delete(*args, **kwargs)
+
