diff --git a/xos/models.py b/xos/models.py
deleted file mode 100644
index 05aeebc..0000000
--- a/xos/models.py
+++ /dev/null
@@ -1,370 +0,0 @@
-from header import *
-
-
-
-#from core.models.service import Service
-from core.models import Service
-
-
-
-#from core.models.tenantwithcontainer import TenantWithContainer
-from core.models import TenantWithContainer
-
-
-
-
-
-class VSGService(Service):
-
-  KIND = "vCPE"
-
-  class Meta:
-      app_label = "vsg"
-      name = "vsg"
-      verbose_name = "vSG Service"
-
-  # Primitive Fields (Not Relations)
-  url_filter_kind = StrippedCharField( blank = True, max_length = 30, null = True, db_index = False, choices = ((None, 'None'), ('safebrowsing', 'Safe Browsing'), ('answerx', 'AnswerX')) )
-  dns_servers = StrippedCharField( default = "8.8.8.8", max_length = 255, null = False, db_index = False, blank = False )
-  node_label = StrippedCharField( db_index = False, max_length = 30, null = True, blank = True )
-  docker_image_name = StrippedCharField( default = "docker.io/xosproject/vsg", max_length = 255, null = False, db_index = False, blank = False )
-  docker_insecure_registry = BooleanField( default = False, null = False, blank = True, db_index = False )
-  
-
-  # Relations
-  
-
-  
-  pass
-
-
-
-
-class VSGTenant(TenantWithContainer):
-
-  KIND = "vCPE"
-
-  class Meta:
-      app_label = "vsg"
-      name = "vsg"
-      verbose_name = "vSG Service"
-
-  # Primitive Fields (Not Relations)
-  last_ansible_hash = StrippedCharField( db_index = False, max_length = 128, null = True, blank = True )
-  
-
-  # Relations
-  
-
-  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)
-  
-  pass
-
-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()
-
-
