diff --git a/xos/models.py b/xos/models.py
new file mode 100644
index 0000000..8f3cc1f
--- /dev/null
+++ b/xos/models.py
@@ -0,0 +1,367 @@
+from django.db import models
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, 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 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
+
+VOLT_KIND = "vOLT"
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
+# -------------------------------------------
+# CordSubscriberRoot
+# -------------------------------------------
+
+class CordSubscriberRoot(Subscriber):
+    class Meta:
+        proxy = True
+
+    KIND = CORD_SUBSCRIBER_KIND
+
+    status_choices = (("enabled", "Enabled"),
+                      ("suspended", "Suspended"),
+                      ("delinquent", "Delinquent"),
+                      ("copyrightviolation", "Copyright Violation"))
+
+    # 'simple_attributes' will be expanded into properties and setters that
+    # store the attribute using self.set_attribute / self.get_attribute.
+
+    simple_attributes = ( ("firewall_enable", False),
+                          ("firewall_rules", "accept all anywhere anywhere"),
+                          ("url_filter_enable", False),
+                          ("url_filter_rules", "allow all"),
+                          ("url_filter_level", "PG"),
+                          ("cdn_enable", False),
+                          ("devices", []),
+                          ("is_demo_user", False),
+
+                          ("uplink_speed", 1000000000),  # 1 gigabit, a reasonable default?
+                          ("downlink_speed", 1000000000),
+                          ("enable_uverse", True) )
+
+    default_attributes = {"status": "enabled"}
+
+    sync_attributes = ("firewall_enable",
+                       "firewall_rules",
+                       "url_filter_enable",
+                       "url_filter_rules",
+                       "cdn_enable",
+                       "uplink_speed",
+                       "downlink_speed",
+                       "enable_uverse",
+                       "status")
+
+    def __init__(self, *args, **kwargs):
+        super(CordSubscriberRoot, self).__init__(*args, **kwargs)
+        self.cached_volt = None
+        self._initial_url_filter_enable = self.url_filter_enable
+
+    @property
+    def volt(self):
+        volt = self.get_newest_subscribed_tenant(VOLTTenant)
+        if not volt:
+            return None
+
+        # always return the same object when possible
+        if (self.cached_volt) and (self.cached_volt.id == volt.id):
+            return self.cached_volt
+
+        #volt.caller = self.creator
+        self.cached_volt = volt
+        return volt
+
+    @property
+    def status(self):
+        return self.get_attribute("status", self.default_attributes["status"])
+
+    @status.setter
+    def status(self, value):
+        if not value in [x[0] for x in self.status_choices]:
+            raise Exception("invalid status %s" % value)
+        self.set_attribute("status", value)
+
+    def find_device(self, mac):
+        for device in self.devices:
+            if device["mac"] == mac:
+                return device
+        return None
+
+    def update_device(self, mac, **kwargs):
+        # kwargs may be "level" or "mac"
+        #    Setting one of these to None will cause None to be stored in the db
+        devices = self.devices
+        for device in devices:
+            if device["mac"] == mac:
+                for arg in kwargs.keys():
+                    device[arg] = kwargs[arg]
+                self.devices = devices
+                return device
+        raise ValueError("Device with mac %s not found" % mac)
+
+    def create_device(self, **kwargs):
+        if "mac" not in kwargs:
+            raise XOSMissingField("The mac field is required")
+
+        if self.find_device(kwargs['mac']):
+                raise XOSDuplicateKey("Device with mac %s already exists" % kwargs["mac"])
+
+        device = kwargs.copy()
+
+        devices = self.devices
+        devices.append(device)
+        self.devices = devices
+
+        return device
+
+    def delete_device(self, mac):
+        devices = self.devices
+        for device in devices:
+            if device["mac"]==mac:
+                devices.remove(device)
+                self.devices = devices
+                return
+
+        raise ValueError("Device with mac %s not found" % mac)
+
+    #--------------------------------------------------------------------------
+    # Deprecated -- devices used to be called users
+
+    def find_user(self, uid):
+        return self.find_device(uid)
+
+    def update_user(self, uid, **kwargs):
+        return self.update_device(uid, **kwargs)
+
+    def create_user(self, **kwargs):
+        return self.create_device(**kwargs)
+
+    def delete_user(self, uid):
+        return self.delete_user(uid)
+
+    # ------------------------------------------------------------------------
+
+    @property
+    def services(self):
+        return {"cdn": self.cdn_enable,
+                "url_filter": self.url_filter_enable,
+                "firewall": self.firewall_enable}
+
+    @services.setter
+    def services(self, value):
+        pass
+
+    def save(self, *args, **kwargs):
+        self.validate_unique_service_specific_id(none_okay=True)
+        if (not hasattr(self, 'caller') or not self.caller.is_admin):
+            if (self.has_field_changed("service_specific_id")):
+                raise XOSPermissionDenied("You do not have permission to change service_specific_id")
+        super(CordSubscriberRoot, self).save(*args, **kwargs)
+        if (self.volt) and (self.volt.vcpe): # and (self._initial_url_filter_enabled != self.url_filter_enable):
+            # 1) trigger manage_bbs_account to run
+            # 2) trigger vcpe observer to wake up
+            self.volt.vcpe.save()
+
+CordSubscriberRoot.setup_simple_attributes()
+
+# -------------------------------------------
+# VOLT
+# -------------------------------------------
+
+class VOLTService(Service):
+    KIND = VOLT_KIND
+
+    class Meta:
+        app_label = "volt"
+        verbose_name = "vOLT Service"
+
+class VOLTTenant(Tenant):
+    KIND = VOLT_KIND
+
+    class Meta:
+        app_label = "volt"
+        verbose_name = "vOLT Tenant"
+
+    s_tag = models.IntegerField(null=True, blank=True, help_text="s-tag")
+    c_tag = models.IntegerField(null=True, blank=True, help_text="c-tag")
+
+    # at some point, this should probably end up part of Tenant.
+    creator = models.ForeignKey(User, related_name='created_volts', blank=True, null=True)
+
+    def __init__(self, *args, **kwargs):
+        volt_services = VOLTService.get_service_objects().all()
+        if volt_services:
+            self._meta.get_field("provider_service").default = volt_services[0].id
+        super(VOLTTenant, self).__init__(*args, **kwargs)
+        self.cached_vcpe = None
+
+    @property
+    def vcpe(self):
+        from services.vsg.models import VSGTenant
+        vcpe = self.get_newest_subscribed_tenant(VSGTenant)
+        if not vcpe:
+            return None
+
+        # always return the same object when possible
+        if (self.cached_vcpe) and (self.cached_vcpe.id == vcpe.id):
+            return self.cached_vcpe
+
+        vcpe.caller = self.creator
+        self.cached_vcpe = vcpe
+        return vcpe
+
+    @vcpe.setter
+    def vcpe(self, value):
+        raise XOSConfigurationError("vOLT.vCPE cannot be set this way -- create a new vCPE object and set its subscriber_tenant instead")
+
+    @property
+    def subscriber(self):
+        if not self.subscriber_root:
+            return None
+        subs = CordSubscriberRoot.objects.filter(id=self.subscriber_root.id)
+        if not subs:
+            return None
+        return subs[0]
+
+    def manage_vcpe(self):
+        # Each VOLT object owns exactly one VCPE object
+
+        if self.deleted:
+            return
+
+        if self.vcpe is None:
+            from services.vsg.models import VSGService, VSGTenant
+            vsgServices = VSGService.get_service_objects().all()
+            if not vsgServices:
+                raise XOSConfigurationError("No VSG Services available")
+
+            vcpe = VSGTenant(provider_service = vsgServices[0],
+                              subscriber_tenant = self)
+            vcpe.caller = self.creator
+            vcpe.save()
+
+    def manage_subscriber(self):
+        if (self.subscriber_root is None):
+            # The vOLT is not connected to a Subscriber, so either find an
+            # existing subscriber with the same SSID, or autogenerate a new
+            # subscriber.
+            #
+            # TODO: This probably goes away when we rethink the ONOS-to-XOS
+            # vOLT API.
+
+            subs = CordSubscriberRoot.get_tenant_objects().filter(service_specific_id = self.service_specific_id)
+            if subs:
+                sub = subs[0]
+            else:
+                sub = CordSubscriberRoot(service_specific_id = self.service_specific_id,
+                                         name = "autogenerated-for-vOLT-%s" % self.id)
+                sub.save()
+            self.subscriber_root = sub
+            self.save()
+
+    def cleanup_vcpe(self):
+        if self.vcpe:
+            # print "XXX cleanup vcpe", self.vcpe
+            self.vcpe.delete()
+
+    def cleanup_orphans(self):
+        from services.vsg.models import VSGTenant
+        # ensure vOLT only has one vCPE
+        cur_vcpe = self.vcpe
+        for vcpe in list(self.get_subscribed_tenants(VSGTenant)):
+            if (not cur_vcpe) or (vcpe.id != cur_vcpe.id):
+                # print "XXX clean up orphaned vcpe", vcpe
+                vcpe.delete()
+
+    def save(self, *args, **kwargs):
+        # VOLTTenant probably doesn't need a SSID anymore; that will be handled
+        # by CORDSubscriberRoot...
+        # self.validate_unique_service_specific_id()
+
+        if (self.subscriber_root is not None):
+            subs = self.subscriber_root.get_subscribed_tenants(VOLTTenant)
+            if (subs) and (self not in subs):
+                raise XOSDuplicateKey("Subscriber should only be linked to one vOLT")
+
+        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("VOLTTenant's self.caller was not set")
+            self.creator = self.caller
+            if not self.creator:
+                raise XOSProgrammingError("VOLTTenant's self.creator was not set")
+
+        super(VOLTTenant, self).save(*args, **kwargs)
+        model_policy_volt(self.pk)
+
+    def delete(self, *args, **kwargs):
+        self.cleanup_vcpe()
+        super(VOLTTenant, self).delete(*args, **kwargs)
+
+def model_policy_volt(pk):
+    # TODO: this should be made in to a real model_policy
+    with transaction.atomic():
+        volt = VOLTTenant.objects.select_for_update().filter(pk=pk)
+        if not volt:
+            return
+        volt = volt[0]
+        volt.manage_vcpe()
+        volt.manage_subscriber()
+        volt.cleanup_orphans()
+
+class VOLTDevice(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    name = models.CharField(max_length=254, help_text="name of device", null=False, blank=False)
+    volt_service = models.ForeignKey(VOLTService, related_name='volt_devices')
+    openflow_id = models.CharField(max_length=254, help_text="OpenFlow ID", null=True, blank=True)
+    driver = models.CharField(max_length=254, help_text="driver", null=True, blank=True)
+    access_agent = models.ForeignKey("AccessAgent", related_name='volt_devices', blank=True, null=True)
+
+    def __unicode__(self): return u'%s' % (self.name)
+
+class AccessDevice(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    volt_device = models.ForeignKey(VOLTDevice, related_name='access_devices')
+    uplink = models.IntegerField(null=True, blank=True)
+    vlan = models.IntegerField(null=True, blank=True)
+
+    def __unicode__(self): return u'%s-%d:%d' % (self.volt_device.name,self.uplink,self.vlan)
+
+class AccessAgent(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    name = models.CharField(max_length=254, help_text="name of agent", null=False, blank=False)
+    volt_service = models.ForeignKey(VOLTService, related_name='access_agents')
+    mac = models.CharField(max_length=32, help_text="MAC Address or Access Agent", null=True, blank=True)
+
+    def __unicode__(self): return u'%s' % (self.name)
+
+class AgentPortMapping(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    access_agent = models.ForeignKey(AccessAgent, related_name='port_mappings')
+    mac = models.CharField(max_length=32, help_text="MAC Address", null=True, blank=True)
+    port = models.CharField(max_length=32, help_text="Openflow port ID", null=True, blank=True)
+
+    def __unicode__(self): return u'%s-%s-%s' % (self.access_agent.name, self.port, self.mac)
+
+
+
