refactored again
diff --git a/xos/tosca/engine.py b/xos/tosca/engine.py
index 2ecf165..118bfe2 100644
--- a/xos/tosca/engine.py
+++ b/xos/tosca/engine.py
@@ -37,7 +37,9 @@
     def execute_nodetemplate(self, user, nodetemplate):
         if nodetemplate.type in resources.resources:
             cls = resources.resources[nodetemplate.type]
+            #print "work on", cls.__name__, nodetemplate.name
             obj = cls(user, nodetemplate)
+            obj.create_or_update()
 
 
 
diff --git a/xos/tosca/resources/compute.py b/xos/tosca/resources/compute.py
index db65406..719c4f5 100644
--- a/xos/tosca/resources/compute.py
+++ b/xos/tosca/resources/compute.py
@@ -13,6 +13,7 @@
 
 class XOSCompute(XOSResource):
     provides = "tosca.nodes.Compute"
+    xos_model = Sliver
 
     def select_compute_node(self, user, v):
         mem_size = v.get_property_value("mem_size")
@@ -34,7 +35,7 @@
 
         return XOSImageSelector(user, distribution=distribution, version=version, type=type, architecture=architecture).get_image()
 
-    def process_nodetemplate(self):
+    def get_xos_args(self):
         nodetemplate = self.nodetemplate
 
         host=None
@@ -58,19 +59,19 @@
         if not flavor:
             raise Exception("Failed to pick a flavor")
 
-        sliver = Sliver(deployment = compute_node.site_deployment.deployment,
-                        node = compute_node,
-                        flavor = flavor,
-                        slice = slice,
-                        image = image)
+        return {"name": nodetemplate.name,
+                "image": image,
+                "slice": slice,
+                "flavor": flavor,
+                "node": compute_node,
+                "deployment": compute_node.site_deployment.deployment}
+
+    def create(self):
+        xos_args = self.get_xos_args()
+        sliver = Sliver(**xos_args)
         sliver.caller = self.user
         sliver.save()
 
-        self.resource = sliver
-
         self.info("Created Sliver '%s' on node '%s' using flavor '%s' and image '%s'" %
-                  (str(sliver), str(compute_node), str(flavor), str(image)))
-
-    def save(self):
-        self.resource.save()
+                  (str(sliver), str(sliver.node), str(sliver.flavor), str(sliver.image)))
 
diff --git a/xos/tosca/resources/service.py b/xos/tosca/resources/service.py
index 0ef64ba..fb394e4 100644
--- a/xos/tosca/resources/service.py
+++ b/xos/tosca/resources/service.py
@@ -11,37 +11,34 @@
 
 class XOSService(XOSResource):
     provides = "tosca.nodes.Service"
+    xos_model = Service
 
-    def process_nodetemplate(self):
-        nodetemplate = self.nodetemplate
-        serviceName = nodetemplate.name
+    def get_xos_args(self):
+        return {"name": self.nodetemplate.name}
 
-        existing_services = Service.objects.filter(name=serviceName)
-        if existing_services:
-            self.info("Service %s already exists" % serviceName)
-            service = existing_services[0]
-        else:
-            service = Service(name = serviceName)
-            service.caller = self.user
-            service.save()
-
-            self.info("Created Service '%s'" % (str(service), ))
-
+    def postprocess(self, obj):
         for provider_service_name in self.get_requirements("tosca.relationships.TenantOfService"):
             provider_service = self.get_xos_object(Service, name=provider_service_name)
 
-            existing_tenancy = CoarseTenant.get_tenant_objects().filter(provider_service = provider_service, subscriber_service = service)
+            existing_tenancy = CoarseTenant.get_tenant_objects().filter(provider_service = provider_service, subscriber_service = obj)
             if existing_tenancy:
                 self.info("Tenancy relationship from %s to %s already exists" % (str(service), str(provider_service)))
             else:
                 tenancy = CoarseTenant(provider_service = provider_service,
-                                       subscriber_service = service)
+                                       subscriber_service = obj)
                 tenancy.save()
 
-                self.info("Created Tenancy relationship  from %s to %s" % (str(service), str(provider_service)))
+                self.info("Created Tenancy relationship  from %s to %s" % (str(obj), str(provider_service)))
 
-        self.resource = service
+    def create(self):
+        nodetemplate = self.nodetemplate
 
-    def save(self):
-        self.resource.save()
+        xos_args = self.get_xos_args()
+        service = Service(**xos_args)
+        service.caller = self.user
+        service.save()
+
+        self.postprocess(service)
+
+        self.info("Created Service '%s'" % (str(service), ))
 
diff --git a/xos/tosca/resources/slice.py b/xos/tosca/resources/slice.py
index bbcd861..90ae75f 100644
--- a/xos/tosca/resources/slice.py
+++ b/xos/tosca/resources/slice.py
@@ -11,29 +11,26 @@
 
 class XOSSlice(XOSResource):
     provides = "tosca.nodes.Slice"
+    xos_model = Slice
 
-    def process_nodetemplate(self):
+    def get_existing_objs(self):
+        return Slice.objects.filter(name=self.nodetemplate.name)
+
+    def get_xos_args(self):
+        site_name = self.get_requirement("tosca.relationships.MemberOfSite", throw_exception=True)
+        site = self.get_xos_object(Site, login_base=site_name)
+        return {"name": self.nodetemplate.name,
+                "site": site}
+
+    def create(self):
         nodetemplate = self.nodetemplate
         sliceName = nodetemplate.name
 
-        existing_slices = Slice.objects.filter(name=sliceName)
-        if existing_slices:
-            self.info("Slice %s already exists" % sliceName)
-            slice = existing_slices[0]
-        else:
-            site_name = self.get_requirement("tosca.relationships.MemberOfSite", throw_exception=True)
-            site = self.get_xos_object(Site, login_base=site_name)
+        xos_args = self.get_xos_args()
+        slice = Slice(**xos_args)
+        slice.caller = self.user
+        slice.save()
 
-            slice = Slice(name = sliceName,
-                          site = site)
-            slice.caller = self.user
-            slice.save()
+        self.info("Created Slice '%s' on Site '%s'" % (str(slice), str(slice.site)))
 
-            self.info("Created Slice '%s' on Site '%s'" % (str(slice), str(site)))
-
-        self.resource = slice
-
-
-    def save(self):
-        self.resource.save()
 
diff --git a/xos/tosca/resources/xosresource.py b/xos/tosca/resources/xosresource.py
index 1bb555c..4a685c6 100644
--- a/xos/tosca/resources/xosresource.py
+++ b/xos/tosca/resources/xosresource.py
@@ -1,12 +1,12 @@
 class XOSResource(object):
     xos_base_class = "XOSResource"
+    xos_model = None
     provides = None
 
     def __init__(self, user, nodetemplate):
         self.dirty = False
         self.user = user
         self.nodetemplate = nodetemplate
-        self.process_nodetemplate()
 
     def get_requirements(self, relationship_name, throw_exception=False):
         """ helper to search the list of requirements for a particular relationship
@@ -36,7 +36,24 @@
             raise Exception("Failed to find %s filtered by %s" % (cls.__name__, str(kwargs)))
         return objs[0]
 
-    def process_nodetemplate(self):
+    def get_existing_objs(self):
+        return self.xos_model.objects.filter(name = self.nodetemplate.name)
+
+    def get_xos_args(self):
+        return {}
+
+    def create_or_update(self):
+        existing_objs = self.get_existing_objs()
+        if existing_objs:
+            self.info("%s %s already exists" % (self.xos_model.__name__, self.nodetemplate.name))
+            self.update(existing_objs[0])
+        else:
+            self.create()
+
+    def create(self):
+        raise Exception("abstract method -- must override")
+
+    def update(self, obj):
         pass
 
     def info(self, s):