diff --git a/xos/tools/apigen/chameleon_list_test.template.sh b/xos/tools/apigen/chameleon_list_test.template.sh
deleted file mode 100644
index dd7c9fd..0000000
--- a/xos/tools/apigen/chameleon_list_test.template.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-source /opt/xos/coreapi/tests/testconfig-chameleon.sh
-
-# test modeldefs
-curl -f --silent http://$HOSTNAME:8080/xosapi/v1/modeldefs > /dev/null
-if [[ $? -ne 0 ]]; then
-    echo fail modeldefs
-fi
-
-{% for object in generator.all() %}
-curl -f --silent http://$HOSTNAME:8080/xosapi/v1/{{ object.app_name }}/{{ object.plural() }} > /dev/null
-if [[ $? -ne 0 ]]; then
-    echo fail {{ object.camel() }}
-fi
-{%- endfor %}
-
-echo "okay"
-
diff --git a/xos/tools/apigen/deps.template.json b/xos/tools/apigen/deps.template.json
deleted file mode 100644
index ca35531..0000000
--- a/xos/tools/apigen/deps.template.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-{% for o in generator.all() %}
-    "{{ o.camel() }}": [
-	{% for f in o.refs %}"{{ f.camel() }}",
-	{% endfor %}]
-{% endfor %}
-}
-
diff --git a/xos/tools/apigen/fields.template.txt b/xos/tools/apigen/fields.template.txt
deleted file mode 100644
index e75526d..0000000
--- a/xos/tools/apigen/fields.template.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-{% for object in generator.all() %}
-Object {{ object }}:
-Fields:
-{% for field in object.fields %}{{ field.name }}:{{ field.type }}
-{% endfor %}
-{% endfor %}
diff --git a/xos/tools/apigen/grpc_api.template.py b/xos/tools/apigen/grpc_api.template.py
deleted file mode 100644
index 1048763..0000000
--- a/xos/tools/apigen/grpc_api.template.py
+++ /dev/null
@@ -1,73 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import base64
-import time
-from protos import xos_pb2
-from google.protobuf.empty_pb2 import Empty
-
-from django.contrib.auth import authenticate as django_authenticate
-from xos.exceptions import *
-from apihelper import XOSAPIHelperMixin, translate_exceptions
-
-class XosService(xos_pb2.xosServicer, XOSAPIHelperMixin):
-    def __init__(self, thread_pool):
-        self.thread_pool = thread_pool
-        XOSAPIHelperMixin.__init__(self)
-
-    def stop(self):
-        pass
-
-{% for object in generator.all() %}
-    @translate_exceptions
-    def List{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.querysetToProto(model, model.objects.all())
-
-    @translate_exceptions
-    def Filter{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.filter(model, request)
-
-    @translate_exceptions
-    def Get{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.get(model, request.id)
-
-    @translate_exceptions
-    def Create{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.create(model, user, request)
-
-    @translate_exceptions
-    def Delete{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.delete(model, user, request.id)
-
-    @translate_exceptions
-    def Update{{ object.camel() }}(self, request, context):
-      user=self.authenticate(context)
-      model=self.get_model("{{ object.camel() }}")
-      return self.update(model, user, request.id, request, context)
-
-{% endfor %}
-
-
diff --git a/xos/tools/apigen/grpc_list_test.template.py b/xos/tools/apigen/grpc_list_test.template.py
deleted file mode 100644
index 48c8fbd..0000000
--- a/xos/tools/apigen/grpc_list_test.template.py
+++ /dev/null
@@ -1,57 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import grpc_client
-from grpc_client import Empty
-from testconfig import *
-
-c=grpc_client.InsecureClient("xos-core.cord.lab")
-
-{% for object in generator.all() %}
-print "testing insecure List{{ object.camel() }}...",
-c.stub.List{{ object.camel() }}(Empty())
-print "Okay"
-{%- endfor %}
-
-c=grpc_client.SecureClient("xos-core.cord.lab", username=USERNAME, password=PASSWORD)
-
-{% for object in generator.all() %}
-print "testing basic secure List{{ object.camel() }}...",
-c.stub.List{{ object.camel() }}(Empty())
-print "Okay"
-{%- endfor %}
-
-# now try to login
-c=grpc_client.InsecureClient("xos-core.cord.lab")
-lr=grpc_client.LoginRequest()
-lr.username=USERNAME
-lr.password=PASSWORD
-session=c.utility.Login(lr)
-
-c=grpc_client.SecureClient("xos-core.cord.lab", sessionid=session.sessionid)
-{% for object in generator.all() %}
-print "testing session secure List{{ object.camel() }}...",
-c.stub.List{{ object.camel() }}(Empty())
-print "Okay"
-{%- endfor %}
-
-c=grpc_client.SecureClient("xos-core.cord.lab", sessionid=session.sessionid)
-{% for object in generator.all() %}
-print "testing session secure xos_orm.{{ object.camel() }}.objects.all() ...",
-c.xos_orm.{{ object.camel() }}.objects.all()
-print "Okay"
-{%- endfor %}
-
diff --git a/xos/tools/apigen/hpc-api.template.py b/xos/tools/apigen/hpc-api.template.py
deleted file mode 100644
index b7bd30d..0000000
--- a/xos/tools/apigen/hpc-api.template.py
+++ /dev/null
@@ -1,241 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-from rest_framework.reverse import reverse
-from rest_framework import serializers
-from rest_framework import generics
-from rest_framework import status
-from rest_framework.generics import GenericAPIView
-from services.hpc.models import *
-from django.forms import widgets
-from rest_framework import filters
-from django.conf.urls import patterns, url
-from rest_framework.exceptions import PermissionDenied as RestFrameworkPermissionDenied
-from django.core.exceptions import PermissionDenied as DjangoPermissionDenied
-from apibase import XOSRetrieveUpdateDestroyAPIView, XOSListCreateAPIView, XOSNotAuthenticated
-
-if hasattr(serializers, "ReadOnlyField"):
-    # rest_framework 3.x
-    IdField = serializers.ReadOnlyField
-else:
-    # rest_framework 2.x
-    IdField = serializers.Field
-
-"""
-    Schema of the generator object:
-        all: Set of all Model objects
-        all_if(regex): Set of Model objects that match regex
-
-    Model object:
-        plural: English plural of object name
-        camel: CamelCase version of object name
-        refs: list of references to other Model objects
-        props: list of properties minus refs
-
-    TODO: Deal with subnets
-"""
-
-def get_hpc_REST_patterns():
-    return patterns('',
-        url(r'^hpcapi/$', hpc_api_root_legacy),
-    # legacy - deprecated
-    {% for object in generator.rest_models() %}
-        url(r'hpcapi/{{ object.rest_name() }}/$', {{ object.camel() }}List.as_view(), name='{{ object.singular() }}-list-legacy'),
-        url(r'hpcapi/{{ object.rest_name() }}/(?P<pk>[a-zA-Z0-9\-]+)/$', {{ object.camel() }}Detail.as_view(), name ='{{ object.singular() }}-detail-legacy'),
-    {% endfor %}
-    # new api - use these
-        url(r'^api/service/hpc/$', hpc_api_root),
-    {% for object in generator.rest_models() %}
-        url(r'api/service/hpc/{{ object.rest_name() }}/$', {{ object.camel() }}List.as_view(), name='{{ object.singular() }}-list'),
-        url(r'api/service/hpc/{{ object.rest_name() }}/(?P<pk>[a-zA-Z0-9\-]+)/$', {{ object.camel() }}Detail.as_view(), name ='{{ object.singular() }}-detail'),
-    {% endfor %}
-    )
-
-@api_view(['GET'])
-def hpc_api_root_legacy(request, format=None):
-    return Response({
-        {% for object in generator.rest_models() %}'{{ object.plural() }}': reverse('{{ object }}-list-legacy', request=request, format=format),
-        {% endfor %}
-    })
-
-@api_view(['GET'])
-def hpc_api_root(request, format=None):
-    return Response({
-        {% for object in generator.rest_models() %}'{{ object.plural() }}': reverse('{{ object }}-list', request=request, format=format),
-        {% endfor %}
-    })
-
-# Based on serializers.py
-
-class XOSModelSerializer(serializers.ModelSerializer):
-    def save_object(self, obj, **kwargs):
-
-        """ rest_framework can't deal with ManyToMany relations that have a
-            through table. In xos, most of the through tables we have
-            use defaults or blank fields, so there's no reason why we shouldn't
-            be able to save these objects.
-
-            So, let's strip out these m2m relations, and deal with them ourself.
-        """
-        obj._complex_m2m_data={};
-        if getattr(obj, '_m2m_data', None):
-            for relatedObject in obj._meta.get_all_related_many_to_many_objects():
-                if (relatedObject.field.rel.through._meta.auto_created):
-                    # These are non-trough ManyToMany relations and
-                    # can be updated just fine
-                    continue
-                fieldName = relatedObject.get_accessor_name()
-                if fieldName in obj._m2m_data.keys():
-                    obj._complex_m2m_data[fieldName] = (relatedObject, obj._m2m_data[fieldName])
-                    del obj._m2m_data[fieldName]
-
-        serializers.ModelSerializer.save_object(self, obj, **kwargs);
-
-        for (accessor, stuff) in obj._complex_m2m_data.items():
-            (relatedObject, data) = stuff
-            through = relatedObject.field.rel.through
-            local_fieldName = relatedObject.field.m2m_reverse_field_name()
-            remote_fieldName = relatedObject.field.m2m_field_name()
-
-            # get the current set of existing relations
-            existing = through.objects.filter(**{local_fieldName: obj});
-
-            data_ids = [item.id for item in data]
-            existing_ids = [getattr(item,remote_fieldName).id for item in existing]
-
-            #print "data_ids", data_ids
-            #print "existing_ids", existing_ids
-
-            # remove relations that are in 'existing' but not in 'data'
-            for item in list(existing):
-               if (getattr(item,remote_fieldName).id not in data_ids):
-                   print "delete", getattr(item,remote_fieldName)
-                   item.delete() #(purge=True)
-
-            # add relations that are in 'data' but not in 'existing'
-            for item in data:
-               if (item.id not in existing_ids):
-                   #print "add", item
-                   newModel = through(**{local_fieldName: obj, remote_fieldName: item})
-                   newModel.save()
-
-{% for object in generator.rest_models() %}
-
-class {{ object.camel() }}Serializer(serializers.HyperlinkedModelSerializer):
-    id = IdField()
-    {% for ref in object.refs %}
-    {% if ref.multi %}
-    {{ ref.plural() }} = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='{{ ref }}-detail')
-    {% else %}
-    {{ ref }} = serializers.HyperlinkedRelatedField(read_only=True, view_name='{{ ref }}-detail')
-    {% endif %}
-    {% endfor %}
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = {{ object.camel() }}
-        fields = ('humanReadableName', 'validators', {% for prop in object.props %}'{{ prop }}',{% endfor %}{% for ref in object.refs %}{%if ref.multi %}'{{ ref.plural() }}'{% else %}'{{ ref }}'{% endif %},{% endfor %})
-
-class {{ object.camel() }}IdSerializer(XOSModelSerializer):
-    id = IdField()
-    {% for ref in object.refs %}
-    {% if ref.multi %}
-    {{ ref.plural() }} = serializers.PrimaryKeyRelatedField(many=True, required=False, queryset = {{ ref.camel() }}.objects.all())
-    {% else %}
-    {{ ref }} = serializers.PrimaryKeyRelatedField( queryset = {{ ref.camel() }}.objects.all())
-    {% endif %}
-    {% endfor %}
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = {{ object.camel() }}
-        fields = ('humanReadableName', 'validators', {% for prop in object.props %}'{{ prop }}',{% endfor %}{% for ref in object.refs %}{%if ref.multi %}'{{ ref.plural() }}'{% else %}'{{ ref }}'{% endif %},{% endfor %})
-
-
-{% endfor %}
-
-serializerLookUp = {
-{% for object in generator.rest_models() %}
-                 {{ object.camel() }}: {{ object.camel() }}Serializer,
-{% endfor %}
-                 None: None,
-                }
-
-# Based on core/views/*.py
-{% for object in generator.rest_models() %}
-
-class {{ object.camel() }}List(XOSListCreateAPIView):
-    queryset = {{ object.camel() }}.objects.select_related().all()
-    serializer_class = {{ object.camel() }}Serializer
-    id_serializer_class = {{ object.camel() }}IdSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ({% for prop in object.props %}'{{ prop }}',{% endfor %}{% for ref in object.refs %}{%if ref.multi %}'{{ ref.plural() }}'{% else %}'{{ ref }}'{% endif %},{% endfor %})
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"query_params"):
-            no_hyperlinks = self.request.query_params.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return {{ object.camel() }}.select_by_user(self.request.user)
-
-
-class {{ object.camel() }}Detail(XOSRetrieveUpdateDestroyAPIView):
-    queryset = {{ object.camel() }}.objects.select_related().all()
-    serializer_class = {{ object.camel() }}Serializer
-    id_serializer_class = {{ object.camel() }}IdSerializer
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"query_params"):
-            no_hyperlinks = self.request.query_params.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return {{ object.camel() }}.select_by_user(self.request.user)
-
-    # update() is handled by XOSRetrieveUpdateDestroyAPIView
-
-    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
-
-{% endfor %}
diff --git a/xos/tools/apigen/lib.py b/xos/tools/apigen/lib.py
deleted file mode 100644
index 5f8cc32..0000000
--- a/xos/tools/apigen/lib.py
+++ /dev/null
@@ -1,168 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import pdb
-
-def format_options_string(d):
-    if (not d): return ''
-    lst = []
-    try:
-	    for k,v in d.items():
-               if (type(v)==int or type(v)==bool or type(v)==float):
-	          lst.append('%s = %r'%(k,v))
-               else:
-                  lst.append('%s = "%s"'%(k,v))
-    except:
-            pass
-    return '['+', '.join(lst)+']'
-    
-
-def map_django_to_xproto(f):
-    allowed_keys=['help_text','default','max_length','choices','blank','null','related_name','db_index']
-
-    m = {'help_text':{'_target':'help_text','':None}}
-    out = {}
-
-    for k in allowed_keys:
-        try:
-           v = getattr(f,k)
-        except:
-           continue
-
-        if (k=='choices' and v==[]):
-           continue
-
-        if (k=='default' and type(v)==float): 
-           pass
-
-        if (k=='default' and 'function' in type(v).__name__):
-           v = v.__name__+"()"
-
-        try:
-            n = v.__name__
-        except AttributeError: 
-            n = None
-        if (v is None or n=='NOT_PROVIDED'): 
-	    continue
-       
-        if (k in allowed_keys):
-            try:
-                kv2 = m[k]
-                if (kv2[v] is None):
-                   continue
-
-                out[kv2['_target']] = kv2[v]
-            except:
-                out[k] = v
-    return out
-
-
-def xp_options(field):
-    output_dict = map_django_to_xproto(field)
-    t0 = field.type
-
-    if (t0=='StrippedCharField'):
-        ctype = 'stripped'
-    elif (t0=='URLField'):
-        ctype = 'url'
-    elif (t0=='DateTimeField'):
-        ctype = 'date'
-    elif (t0=='GenericIPAddressField'):
-        ctype = 'ip'
-    else:
-        ctype = None
-
-    if (ctype):
-        output_dict['content_type'] =  ctype
-
-
-    return format_options_string(output_dict)
-    
-def xp_to_xproto(field, idx):
-    at = type(field).__name__
-    try:
-        t = field.get_internal_type()
-    except AttributeError:
-        t = type(field).__name__
-
-    link = False
-    through = None
-
-    if (t=='CharField' or t=='TextField' or t=='SlugField'):
-        xptype = 'string'
-    elif (t=='BooleanField'):
-        xptype = 'bool'
-    elif (t=='ManyToManyField'):
-        if (at=='ManyToManyField'):
-	    xptype = 'manytomany'
-	    peer = field.related.model.__name__
-	    through = field.related.model.through
-	    if (field.related.name):
-		dst_port = ':' + field.related.name
-	    else:
-		dst_port = ''
-        else:
-            xptype = 'manytomany'
-	    peer = field.related.model.__name__
-	    dst_port = ''
-
-
-        link = True
-    elif (t=='ForeignKey'):
-        xptype = 'manytoone'
-        peer = field.related.model.__name__
-        if (field.related.name):
-            dst_port = ':' + field.related.name
-        else:
-            dst_port = ''
-        link = True
-    elif (t=='DateTimeField'):
-        xptype = 'string'
-    elif (t=='AutoField'):
-        xptype = 'int32'
-    elif (t=='BigIntegerField'):
-        xptype = 'int32'
-    elif (t=='IntegerField'):
-        xptype = 'int32'
-    elif (t=='PositiveIntegerField'):
-        xptype = 'uint32'
-    elif (t=='FloatField'):
-        xptype = 'float'
-    elif (t=='GenericIPAddressField'):
-        xptype = 'string'
-    elif (t=='OneToOneField'):
-        link = True
-         
-    else:
-        raise Exception('Bad field')
-    
-    if (field.null==False):
-       modifier = 'required'
-    else: 
-       modifier = 'optional'
-
-    if (link):
-       if (through):
-          dst_model = '%s/%s'%(peer,through)
-       else:
-          dst_model = '%s'%peer
-
-       str = '%s %s %s->%s%s = %d'%(modifier, xptype, field.name, dst_model, dst_port, idx)
-    else:
-       str = '%s %s %s = %d'%(modifier, xptype, field.name, idx)
-
-    return str
-
diff --git a/xos/tools/apigen/list.txt b/xos/tools/apigen/list.txt
deleted file mode 100644
index 2fee073..0000000
--- a/xos/tools/apigen/list.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-{% for o in generator.all() %}
-{{ o.camel() }}
-{% endfor %}
diff --git a/xos/tools/apigen/modelgen b/xos/tools/apigen/modelgen
deleted file mode 100755
index b3ea1d6..0000000
--- a/xos/tools/apigen/modelgen
+++ /dev/null
@@ -1,367 +0,0 @@
-#!/usr/bin/python
-
-import inspect
-import os
-import pdb
-import copy
-import sys
-import json
-import re
-import jinja2
-from optparse import OptionParser
-
-# Django set up
-
-import django
-sys.path.append('.')
-sys.path.append('/opt/xos')
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-from django.db.models.fields.related import ForeignKey, ManyToManyField
-from django.conf import settings
-from django.contrib.contenttypes.models import ContentType
-
-django.setup()
-
-from core.models import XOSBase
-
-options = None
-
-def is_model_class(model):
-    """ Return True if 'model' is something that we're interested in """
-    if not inspect.isclass(model):
-        return False
-    if model.__name__ in ["PlModelMixIn"]:
-        return False
-    bases = inspect.getmro(model)
-    bases = [x.__name__ for x in bases]
-    if ("XOSBase" in bases) or ("PlModelMixIn" in bases):
-        return True
-
-    return False
-
-def module_has_models(module):
-    """ return True if 'module' contains any models we're interested in """
-    for k in dir(module):
-        v=getattr(module,k)
-        if is_model_class(v):
-            return True
-
-    return False
-
-def app_get_models_module(app):
-    """ check whether 'app' includes XOS models """
-
-    app = app + ".models"
-    try:
-        models_module = __import__(app)
-    except ImportError:
-        return False
-
-    for part in app.split(".")[1:]:
-        if module_has_models(models_module):
-            return models_module
-        models_module = getattr(models_module,part)
-
-    if module_has_models(models_module):
-        return models_module
-
-    return None
-
-
-def singular(foo, keys):
-	for k in keys:
-		if (foo==k+'es'):
-			return k
-		elif (foo==k+'s'):
-			return k
-	raise Exception('Plural to singular error for %s'%foo)
-
-g = globals()
-
-def enum_classes(apps):
-    global app_map
-    global class_map
-    app_map = {}
-    class_map = {}
-    model_classes = []
-    for app in apps:
-            orig_app=app
-            models_module = app_get_models_module(app)
-
-            for classname in dir(models_module):
-                    c = getattr(models_module, classname, None)
-
-                    # For services, prevent loading of core models as it causes
-                    # duplication.
-                    if hasattr(c,"_meta") and hasattr(c._meta, "app_label"):
-                        if (c._meta.app_label == "core") and (orig_app!="core"):
-                            continue
-
-                    if is_model_class(c) and c.__name__ not in options.blacklist:
-                            model_classes.append(c)
-                            app_map[c.__name__]=orig_app
-                            c.class_name = c.__name__
-                            file_name = c.__module__.rsplit('.',1)[1]
-                            try:
-                                if (file_name not in class_map[orig_app]):
-                                    class_map[orig_app].append({file_name:[c]})
-                                else:
-                                    class_map[orig_app][file_name].append(c)
-
-                            except KeyError:
-                                class_map[orig_app] = [{file_name:[c]}]
-
-
-    return model_classes
-
-class GenObj(object):
-	def __str__(self):
-		return str(self.model.__name__.lower())
-
-	def __init__(self, m):
-		self.model = m
-		self.props = []
-		self.fields = []
-                self.all_fields = []
-		self.field_dict = []
-		self.refs = []
-                self.reverse_refs = []
-		self.plural_name = None
-
-	def plural(self):
-		if (self.plural_name):
-			return self.plural_name
-		else:
-			name = str(self)
-			if (name.endswith('s')):
-				return name+'es'
-			else:
-				return name+'s'
-
-        def singular(self):
-            return str(self)
-
-        def rest_name(self):
-            # These are things that either for historic reasons or due to incorrect naming,
-            # got called something different than the autogen thinks they should be
-            # called.
-            REST_FIXUP = {'controllernetworkses': 'controllernetworks',
-                            'controllerimageses': 'controllerimages',
-                            'controllersliceses': 'controllerslices',
-                            'controlleruserses': 'controllerusers',
-                            'sitedeploymentses': 'sitedeployments',
-                            'siteroles': 'site_roles',
-                            'sliceprivileges': 'slice_privileges',
-                            'sliceroles': 'slice_roles',
-                            }
-            return REST_FIXUP.get(self.plural(), self.plural())
-
-	def camel(self):
-		name = str(self.model.__name__)
-		return name
-		
-class Generator(dict):
-        def __init__(self):
-            self.apps = {}
-
-	def all(self):
-		return self.values()
-
-        def rest_models(self):
-                norest = [x.lower() for x in options.norest]
-                return [v for v in self.values() if not (str(v) in norest)]
-	
-	def regex(self, r):
-		filtered = filter(lambda o:re.match(r,str(o)), self.values())
-		return filtered
-
-	def add_object(self, o):
-                global app_map
-		obj = GenObj(o)
-		fields = o._meta.fields
-                try:
-                    obj.app = app_map[o.__name__] # full name
-                    if hasattr(o, "_meta") and hasattr(o._meta, "app_label"):
-                        obj.app_name = o._meta.app_label
-                    else:
-                        obj.app_name = app_map[o.__name__].split(".")[-1]  # only the last part
-                except KeyError:
-                    print "KeyError: %r"%o.__name__
-                obj.class_name = o.class_name
-
-                file_name = o.__module__.rsplit('.',1)[1]
-
-                try:
-                    if (file_name not in self.apps[obj.app]):
-                        self.apps[obj.app][file_name]=[obj]
-                    else:
-                        self.apps[obj.app][file_name].append(obj)
-
-                except KeyError:
-                    self.apps[obj.app] = {file_name:[obj]}
-
-		self[str(obj).lower()]=obj
-
-	def compute_links(self):
-                base_props = [f.name for f in XOSBase._meta.fields]
-
-		for obj in self.values():
-			#if (str(obj)=='network'):
-			#	pdb.set_trace()
-			fields = obj.model._meta.fields
-			for f in fields:
-				if (f and f.rel):
-					to_name = str(f.rel.to)
-				else:
-					to_name = None
-
-				if type(f)==ForeignKey and to_name and to_name in self.keys():
-					refobj = self[f.to_name]
-
-					if (str(obj)=='slice' and f.to_name=='networks'):
-						obj.refs.append(refobj)
-					related_name = f.related_query_name()
-					if (related_name!='+' and related_name.lower()!=str(obj).lower()):
-						cobj = copy.deepcopy(obj)
-						cobj.multi = True
-						cobj.plural_name = related_name
-						refobj.refs.append(cobj)
-                                elif f.name.endswith("_ptr"):
-                                        # django inherited model, for example HPCService
-                                        # cause swagger and REST to break
-                                        pass
-				else:
-                                        f.type = f.__class__.__name__
-
-                                        if (type(f)==ForeignKey):
-                                            if isinstance(f.related.model, str):
-                                                f.related.model = {'class_name':f.related.model}
-                                            else:
-                                                f.related.model.class_name = f.related.model.__name__
-
-                                        if (f.name not in base_props):
-                                            obj.fields.append(f)
-                                        obj.all_fields.append(f)
-                                        obj.props.append(f.name)
-
-			m2m = obj.model._meta.many_to_many
-			for f in m2m:
-				try:
-					related_model_name = f.m2m_reverse_field_name()
-				except:
-					related_model_name = f.m2m_db_table().rsplit('_',1)[-1]
-
-				related_name = f.related_query_name()
-				if related_model_name in self.keys():
-                                        #print "XXX1", obj, f, related_name, related_model_name
-					refobj = self[related_model_name]
-					cobj = copy.deepcopy(obj)
-					cobj.multi=True
-					refobj.refs.append(cobj)
-
-                                # deal with upgradeFrom_rel_+
-                                if (related_name.endswith("+")):
-                                    continue
-
-				if (related_name!='+') and related_model_name in self: # and related_name.lower()!=str(obj).lower()):
-                                        refobj = self[related_model_name]
-                                        #print "XXX2", obj, f, related_name, related_model_name, refobj.plural_name
-					cobj = copy.deepcopy(refobj)
-					cobj.multi = True
-
-					obj.refs.append(cobj)
-
-                for obj in self.values():
-                        # generate foreign key reverse references
-                        for f in obj.model._meta.related_objects:
-                            related_model = getattr(f, "related_model", None)
-                            if not f.related_name:
-                                continue
-                            if "+" in f.related_name:
-                                continue
-                            if related_model and (related_model.__name__.lower() in self.keys()):
-                                cobj = copy.deepcopy(self[related_model.__name__.lower()])
-                                cobj.related_name = f.related_name
-                                obj.reverse_refs.append(cobj)
-
-def main():
-        global options
-        parser = OptionParser(usage="modelgen [options] <template_fn>", )
-
-        parser.add_option("-d", "--dict", dest="dict",
-             help="dictionary to replace text in output", metavar="DICT", default=[], action="append")
-
-        parser.add_option("-a", "--app", dest="apps",
-             help="list of applications to parse", metavar="APP", default=[], action="append")
-        parser.add_option("-b", "--blacklist", dest="blacklist",
-             help="add model name to blacklist", metavar="MODEL", default=["SingletonModel", "XOSBase"], action="append")
-        parser.add_option("-n", "--no-rest", dest="norest",
-             help="do not generate rest api for model", metavar="MODEL", default=["SingletonModel", "XOSBase"], action="append")
-
-        (options, args) = parser.parse_args(sys.argv[1:])
-
-        template_name = os.path.abspath(args[0])
-
-        # try to make sure we're running from the right place
-        if (not os.path.exists("core")):
-            if (os.path.exists("../core")):
-                os.chdir("..")
-            elif (os.path.exists("../../core")):
-                os.chdir("../..")
-            else:
-                print >> sys.stderr, "Are you sure you're running modelgen from the root of an XOS installation"
-                sys.exit(-1)
-
-        if not options.apps:
-            options.apps = ["core"]
-
-        if options.apps == ["*"]:
-            options.apps = [x for x in settings.INSTALLED_APPS if app_get_models_module(x)]
-
-        if len(args)!=1:
-            print 'Usage: modelgen [options] <template_fn>'
-            exit(1)
-
-	generator = Generator()
-
-	models = enum_classes(options.apps)
-
-	for m in models:
-		generator.add_object(m)
-
-	generator.compute_links()
-
-        os_template_loader = jinja2.FileSystemLoader( searchpath=[os.path.split(template_name)[0]])
-        os_template_env = jinja2.Environment(loader=os_template_loader)
-
-        template = os_template_env.get_template(os.path.split(template_name)[1])
-        rendered = template.render({"generator": generator})
-
-        lines = rendered.splitlines()
-        current_buffer = []
-        for l in lines:
-            if (l.startswith('+++')):
-                filename = l[4:]
-                fil = open(filename,'w')
-                buf = '\n'.join(current_buffer)
-
-                obuf = buf
-                for d in options.dict:
-                    df = open(d).read()
-                    d = json.loads(df)
-
-                    pattern = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b')
-                    obuf = pattern.sub(lambda x: d[x.group()], buf)
-                fil.write(obuf)
-                fil.close()
-
-                print 'Written to file %s'%filename
-                current_buffer = []
-            else:
-                current_buffer.append(l)
-        if (current_buffer):
-            print '\n'.join(current_buffer)
-
-
-if (__name__=='__main__'):
-	main()
diff --git a/xos/tools/apigen/modelgen2 b/xos/tools/apigen/modelgen2
deleted file mode 100755
index 5620f9f..0000000
--- a/xos/tools/apigen/modelgen2
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/python
-
-import inspect
-import os
-import pdb
-import copy
-import sys
-import json
-import re
-import jinja2
-from optparse import OptionParser
-import lib
-
-# Django set up
-
-import django
-sys.path.append('.')
-sys.path.append('/opt/xos')
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-from django.db.models.fields.related import ForeignKey, ManyToManyField
-from django.contrib.contenttypes.fields import GenericRelation
-from django.conf import settings
-from django.contrib.contenttypes.models import ContentType
-
-django.setup()
-
-from core.models import XOSBase
-
-options = None
-
-
-def is_model_class(model):
-    """ Return True if 'model' is something that we're interested in """
-    if not inspect.isclass(model):
-        return False
-    if model.__name__ in ["PlModelMixIn"]:
-        return False
-    bases = inspect.getmro(model)
-    bases = [x.__name__ for x in bases]
-    if ("XOSBase" in bases) or ("PlModelMixIn" in bases):
-        return True
-
-    return False
-
-def bases(model):
-    return ','.join([b.__name__ for b in model.__bases__])
-
-def module_has_models(module):
-    """ return True if 'module' contains any models we're interested in """
-    for k in dir(module):
-        v=getattr(module,k)
-        if is_model_class(v):
-            return True
-
-    return False
-
-def app_get_models_module(app):
-    """ check whether 'app' includes XOS models """
-
-    app = app + ".models"
-    try:
-        models_module = __import__(app)
-    except ImportError:
-        return False
-
-    for part in app.split(".")[1:]:
-        if module_has_models(models_module):
-            return models_module
-        models_module = getattr(models_module,part)
-
-    if module_has_models(models_module):
-        return models_module
-
-    return None
-
-
-def singular(foo, keys):
-	for k in keys:
-		if (foo==k+'es'):
-			return k
-		elif (foo==k+'s'):
-			return k
-	raise Exception('Plural to singular error for %s'%foo)
-
-g = globals()
-
-def enum_classes(apps):
-    global app_map
-    global class_map
-    app_map = {}
-    class_map = {}
-    model_classes = []
-    for app in apps:
-            orig_app=app
-            models_module = app_get_models_module(app)
-
-            for classname in dir(models_module):
-                    c = getattr(models_module, classname, None)
-
-                    # For services, prevent loading of core models as it causes
-                    # duplication.
-                    if hasattr(c,"_meta") and hasattr(c._meta, "app_label"):
-                        if (c._meta.app_label == "core") and (orig_app!="core"):
-                            continue
-
-                    if is_model_class(c) and c.__name__ not in options.blacklist:
-                            model_classes.append(c)
-                            app_map[c.__name__]=orig_app
-                            c.class_name = c.__name__
-                            file_name = c.__module__.rsplit('.',1)[1]
-                            try:
-                                if (file_name not in class_map[orig_app]):
-                                    class_map[orig_app].append({file_name:[c]})
-                                else:
-                                    class_map[orig_app][file_name].append(c)
-
-                            except KeyError:
-                                class_map[orig_app] = [{file_name:[c]}]
-
-
-    return model_classes
-
-class GenObj(object):
-	def __str__(self):
-		return str(self.model.__name__.lower())
-
-	def __init__(self, m):
-		self.model = m
-		self.props = []
-		self.fields = []
-                self.all_fields = []
-		self.field_dict = []
-		self.refs = []
-                self.reverse_refs = []
-		self.plural_name = None
-                self.content_type_id = ContentType.objects.get_for_model(m).id
-
-	def plural(self):
-		if (self.plural_name):
-			return self.plural_name
-		else:
-			name = str(self)
-			if (name.endswith('s')):
-				return name+'es'
-			else:
-				return name+'s'
-
-        def singular(self):
-            return str(self)
-
-        def rest_name(self):
-            # These are things that either for historic reasons or due to incorrect naming,
-            # got called something different than the autogen thinks they should be
-            # called.
-            REST_FIXUP = {'controllernetworkses': 'controllernetworks',
-                            'controllerimageses': 'controllerimages',
-                            'controllersliceses': 'controllerslices',
-                            'controlleruserses': 'controllerusers',
-                            'sitedeploymentses': 'sitedeployments',
-                            'siteroles': 'site_roles',
-                            'sliceprivileges': 'slice_privileges',
-                            'sliceroles': 'slice_roles',
-                            }
-            return REST_FIXUP.get(self.plural(), self.plural())
-
-	def camel(self):
-		name = str(self.model.__name__)
-		return name
-		
-class Generator(dict):
-        def __init__(self):
-            self.apps = {}
-
-	def all(self):
-		return self.values()
-
-        def rest_models(self):
-                norest = [x.lower() for x in options.norest]
-                return [v for v in self.values() if not (str(v) in norest)]
-	
-	def regex(self, r):
-		filtered = filter(lambda o:re.match(r,str(o)), self.values())
-		return filtered
-
-	def add_object(self, o):
-                global app_map
-		obj = GenObj(o)
-		fields = o._meta.get_fields(include_hidden=False)
-                try:
-                    obj.app = app_map[o.__name__] # full name
-                    if hasattr(o, "_meta") and hasattr(o._meta, "app_label"):
-                        obj.app_name = o._meta.app_label
-                    else:
-                        obj.app_name = app_map[o.__name__].split(".")[-1]  # only the last part
-                except KeyError:
-                    print "KeyError: %r"%o.__name__
-
-                obj.class_name = o.class_name
-                obj.bases = bases(o)
-
-                file_name = o.__module__.rsplit('.',1)[1]
-
-                try:
-                    if (file_name not in self.apps[obj.app]):
-                        self.apps[obj.app][file_name]=[obj]
-                    else:
-                        self.apps[obj.app][file_name].append(obj)
-
-                except KeyError:
-                    self.apps[obj.app] = {file_name:[obj]}
-
-
-		self[str(obj).lower()]=obj
-
-	def compute_links(self):
-
-		for obj in self.values():
-                	base_props = [f.name for f in obj.model.__base__._meta.fields] + ['id']
-			fields = list(obj.model._meta.fields + obj.model._meta.many_to_many)
-
-                        other_fields = obj.model._meta.get_fields()
-                        for o in other_fields:
-                            if (type(o)==GenericRelation): fields+=[o]
-
-
-			for f in fields:
-                                if f.name in base_props or type(f).__name__=='ManyToOneRel': continue
-
-				if (f and hasattr(f, 'rel') and f.rel):
-					to_name = str(f.rel.to)
-				else:
-					to_name = None
-
-
-                                if f.name.endswith("_ptr"):
-                                        # django inherited model, for example HPCService
-                                        # cause swagger and REST to break
-                                        pass
-				else:
-                                        f.type = f.__class__.__name__
-
-                                        if (type(f)==ForeignKey):
-                                            f.related.model.class_name = f.related.model.__name__
-                                        elif (type(f)==ManyToManyField or type(f)==GenericRelation):
-                                            f.related.model.class_name = f.related.model.__name__
-                                            try:
-                                               f.related.model.through = f.related.through.__name__
-                                            except AttributeError: 
-                                               pass
-                                
-                
-                                        if (f.name not in base_props):
-                                            obj.fields.append(f)
-                                        
-                                        #if (f.name == 'tags'): pdb.set_trace()
-
-                                        obj.all_fields.append(f)
-                                        obj.props.append(f.name)
-
-			m2m = obj.model._meta.many_to_many
-			for f in m2m:
-				try:
-					related_model_name = f.m2m_reverse_field_name()
-				except:
-					related_model_name = f.m2m_db_table().rsplit('_',1)[-1]
-
-				related_name = f.related_query_name()
-				if related_model_name in self.keys():
-                                        #print "XXX1", obj, f, related_name, related_model_name
-					refobj = self[related_model_name]
-					cobj = copy.deepcopy(obj)
-					cobj.multi=True
-					refobj.refs.append(cobj)
-
-                                # deal with upgradeFrom_rel_+
-                                if (related_name.endswith("+")):
-                                    continue
-
-				if (related_name!='+') and related_model_name in self: # and related_name.lower()!=str(obj).lower()):
-                                        refobj = self[related_model_name]
-                                        #print "XXX2", obj, f, related_name, related_model_name, refobj.plural_name
-					cobj = copy.deepcopy(refobj)
-					cobj.multi = True
-
-					obj.refs.append(cobj)
-
-                for obj in self.values():
-                        # generate foreign key reverse references
-                        for f in obj.model._meta.related_objects:
-                            related_model = getattr(f, "related_model", None)
-                            if not f.related_name:
-                                continue
-                            if "+" in f.related_name:
-                                continue
-                            if related_model and (related_model.__name__.lower() in self.keys()):
-                                cobj = copy.deepcopy(self[related_model.__name__.lower()])
-                                cobj.related_name = f.related_name
-                                obj.reverse_refs.append(cobj)
-
-def main():
-        global options
-        parser = OptionParser(usage="modelgen [options] <template_fn>", )
-
-        parser.add_option("-d", "--dict", dest="dict",
-             help="dictionary to replace text in output", metavar="DICT", default=[], action="append")
-
-        parser.add_option("-a", "--app", dest="apps",
-             help="list of applications to parse", metavar="APP", default=[], action="append")
-        parser.add_option("-b", "--blacklist", dest="blacklist",
-             help="add model name to blacklist", metavar="MODEL", default=["SingletonModel", "XOSBase"], action="append")
-        parser.add_option("-n", "--no-rest", dest="norest",
-             help="do not generate rest api for model", metavar="MODEL", default=["SingletonModel", "XOSBase"], action="append")
-        parser.add_option("-l", "--local", dest="local",
-             help="skip base models", metavar="MODEL", default=False, action="store_true")
-        (options, args) = parser.parse_args(sys.argv[1:])
-
-        template_name = os.path.abspath(args[0])
-
-        # try to make sure we're running from the right place
-        if (not os.path.exists("core")):
-            if (os.path.exists("../core")):
-                os.chdir("..")
-            elif (os.path.exists("../../core")):
-                os.chdir("../..")
-            else:
-                print >> sys.stderr, "Are you sure you're running modelgen from the root of an XOS installation"
-                sys.exit(-1)
-
-        if not options.apps:
-            options.apps = ["core"]
-
-        if options.apps == ["*"]:
-            options.apps = [x for x in settings.INSTALLED_APPS if app_get_models_module(x)]
-
-        if len(args)!=1:
-            print 'Usage: modelgen [options] <template_fn>'
-            exit(1)
-
-	generator = Generator()
-
-	models = enum_classes(options.apps)
-
-	for m in models:
-		generator.add_object(m)
-
-	generator.compute_links()
-
-        os_template_loader = jinja2.FileSystemLoader( searchpath=[os.path.split(template_name)[0]])
-        os_template_env = jinja2.Environment(loader=os_template_loader)
-
-        for x in dir(lib):
-            if x.startswith('xp'):
-                os_template_env.globals[x] = getattr(lib, x)
-
-        template = os_template_env.get_template(os.path.split(template_name)[1])
-        rendered = template.render({"generator": generator})
-
-        lines = rendered.splitlines()
-        current_buffer = []
-        for l in lines:
-            if (l.startswith('+++')):
-                path = l[4:]
-                
-                direc,filename = path.rsplit('/',1)
-                os.system('mkdir -p %s'%direc)
-              
-                fil = open(path,'w')
-                buf = '\n'.join(current_buffer)
-
-                obuf = buf
-                for d in options.dict:
-                    df = open(d).read()
-                    d = json.loads(df)
-
-                    pattern = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b')
-                    obuf = pattern.sub(lambda x: d[x.group()], buf)
-
-                fil.write(obuf)
-                fil.close()
-
-                print 'Written to file %s'%path
-                current_buffer = []
-            else:
-                current_buffer.append(l)
-        if (current_buffer):
-            print '\n'.join(current_buffer)
-
-
-if (__name__=='__main__'):
-	main()
diff --git a/xos/tools/apigen/modelyaml.fields.template.txt b/xos/tools/apigen/modelyaml.fields.template.txt
deleted file mode 100644
index 161cd65..0000000
--- a/xos/tools/apigen/modelyaml.fields.template.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-{% for object in generator.all() %}
-{{ object.camel() }}:
-fields:
-  {% for f in object.fields %}
-  - name: {{ f.name }}
-    type: {{ f.type }}
-    {% if f.help_text %}
-    help_text: {{ f.help_text }}
-    {% endif %}
-    null: {{ f.null }}
-{% endfor %}
-{% endfor %}
diff --git a/xos/tools/apigen/protobuf.template.txt b/xos/tools/apigen/protobuf.template.txt
deleted file mode 100644
index 26034e5..0000000
--- a/xos/tools/apigen/protobuf.template.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-syntax = "proto3";
-
-package xos;
-
-import "google/protobuf/empty.proto";
-import "google/api/annotations.proto";
-import "common.proto";
-import "xosoptions.proto";
-
-{%- macro fieldOpts(field) -%}
-  {%- set needComma=False -%}
-  {%- set needBrack=True -%}
-  {%- if field.max_length!=None -%}
-    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
-    (val).maxLength = {{ field.max_length }}
-  {%- endif -%}
-  {%- if field.null==False -%}
-    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
-    (val).nonNull= true
-  {%- endif -%}
-  {%- if field.related and field.related.model and field.related.model.__name__ -%}
-    {%- if needBrack -%}[{%- endif -%}{%- if needComma -%}, {%- endif -%}{%- set needComma=True -%}{%- set needBrack=False -%}
-    (foreignKey).modelName = "{{ field.related.model.__name__ }}"
-  {%- endif -%}
-  {%- if not needBrack -%}]{%- endif -%}
-{%- endmacro %}
-
-// Note: all fields are wrapped in a "oneof". This causes proto3 to always send
-// fields that are set by the caller, regardless if they are set to a default
-// value. XOS uses this to know when to apply a default value.
-
-{% for object in generator.all() %}
-
-message {{ object.camel() }} {
-    option (contentTypeId) = "{{ object.app_name }}.{{ object|string() }}";
-  {%- for field in object.all_fields %}
-    oneof {{ field.name }}_present {
-    {%- if (field.get_internal_type() == "CharField") or (field.get_internal_type() == "TextField") or (field.get_internal_type() == "SlugField") %}
-      string {{ field.name }} = {{ loop.index }} {{ fieldOpts(field) }};
-    {%- elif field.get_internal_type() == "BooleanField" %}
-      bool {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "ForeignKey" %}
-      int32 {{ field.name }}_id = {{ loop.index }} {{ fieldOpts(field) }};
-    {%- elif field.get_internal_type() == "DateTimeField" %}
-      float {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "AutoField" %}
-      int32 {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "IntegerField" %}
-      int32 {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "BigIntegerField" %}
-      int64 {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "PositiveIntegerField" %}
-      uint32 {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "FloatField" %}
-      float {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "GenericIPAddressField" %}
-      string {{ field.name }} = {{ loop.index }};
-    {%- elif field.get_internal_type() == "OneToOneField" %}
-      int32 {{ field.name }}_id = {{ loop.index }};
-    {%- else %}
-      UNKNOWN {{ field.get_internal_type() }} {{ field.name }} = {{ loop.index }};
-    {%- endif %}
-    }
-  {%- endfor -%}
-  {%- for ref in object.reverse_refs %}
-    repeated int32 {{ ref.related_name }}_ids  = {{ loop.index+100 }} [(reverseForeignKey).modelName = "{{ ref.camel() }}"];
-  {%- endfor %}
-  string class_names = 201;
-  string self_content_type_id = 202;
-}
-
-message {{ object.camel() }}s {
-    repeated {{ object.camel() }} items = 1;
-}
-
-{% endfor %}
-
-service xos {
-{% for object in generator.all() %}
-  rpc List{{ object.camel() }}(google.protobuf.Empty) returns ({{ object.camel() }}s) {
-        option (google.api.http) = {
-            get: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}"
-        };
-  }
-  rpc Filter{{ object.camel() }}(Query) returns ({{ object.camel() }}s) {
-  }
-  rpc Get{{ object.camel() }}(ID) returns ({{ object.camel() }}) {
-        option (google.api.http) = {
-            get: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
-        };
-  }
-  rpc Create{{ object.camel() }}({{ object.camel() }}) returns ({{ object.camel() }}) {
-        option (google.api.http) = {
-            post: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}"
-            body: "*"
-        };
-  }
-  rpc Update{{ object.camel() }}({{ object.camel() }}) returns ({{ object.camel() }}) {
-        option (google.api.http) = {
-            put: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
-            body: "*"
-        };
-  }
-  rpc Delete{{ object.camel() }}(ID) returns (google.protobuf.Empty) {
-        option (google.api.http) = {
-            delete: "/xosapi/v1/{{ object.app_name }}/{{ object.plural() }}/{id}"
-        };
-  }
-{% endfor %}
-}
-
diff --git a/xos/tools/apigen/simple.template.txt b/xos/tools/apigen/simple.template.txt
deleted file mode 100644
index 4dfe494..0000000
--- a/xos/tools/apigen/simple.template.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-{% for object in generator.all() %}
-Object {{ object }}:
-Refs:
-{% for ref in object.refs %}
-{{ ref }}{% endfor %}
-Props:
-{% for prop in object.props %}{{ prop }}
-{% endfor %}
-{% endfor %}
diff --git a/xos/tools/apigen/type_map b/xos/tools/apigen/type_map
deleted file mode 100644
index ac4a8a8..0000000
--- a/xos/tools/apigen/type_map
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "AutoField":"int64",
-    "ForeignKey":"InstanceIdentifier",
-    "CharField":"string",
-    "TextField":"string",
-    "FloatField":"float64",
-    "BooleanField":"boolean",
-    "StrippedCharField":"string",
-    "DateTimeField":"date-and-time"
-}
diff --git a/xos/tools/apigen/xproto.template.txt b/xos/tools/apigen/xproto.template.txt
deleted file mode 100644
index 252e99a..0000000
--- a/xos/tools/apigen/xproto.template.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-{% for object in generator.all() %}
-
-message {{ object.camel() }} ({%- if (object.bases) -%}{{ object.bases}}){%- endif -%} {
-  {%- for field in object.all_fields %}
-     {{ xp_to_xproto(field, loop.index) }} {{xp_options(field)}};
-  {%- endfor %}
-}
-
-+++ protos/{{ object }}.xproto
-{% endfor %}
diff --git a/xos/tools/apigen/yang.template.txt b/xos/tools/apigen/yang.template.txt
deleted file mode 100644
index 9dc43e1..0000000
--- a/xos/tools/apigen/yang.template.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-{% for app,files in generator.apps.items() %}
-{% for file,m in files.items() %}
-module xos-{{ app }}-{{ file }} {
-    namespace "urn:xos:{{app}}.{{ file }}";
-    prefix xos-cs;
-
-    import complex-types {prefix ct;}
-    revision 2016-2-24 {
-        description "Initial";
-    }   
-
-    complex-type {{ m.class_name }} {
-      {% for f in m.fields %}
-
-      leaf {{ f.name }} { type {{ f.type }}{% if f.type=="ForeignKey" %} { ct:instance-type {{f.related.model.class_name}};{% if f.null%}{%else%}require-instance true{% endif %}{% endif %};{% if f.max_length %} { length {{ f.max_length }};{% endif %}{% if None %}default "{{ f.default }}";{% endif %}}
-      {% endfor %}
-    }
-}
-+++ {{ app }}-{{ file}}.yang
-{% endfor %}
-{% endfor %}
diff --git a/xos/tools/chuckmove b/xos/tools/chuckmove
deleted file mode 100755
index 5a77876..0000000
--- a/xos/tools/chuckmove
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/python
-
-from pyparsing import *
-from optparse import OptionParser
-import os
-from os.path import join,exists
-from shutil import copy
-
-usage = "usage: %prog --old <old namespace> --new <new namespace> <directory root>"
-
-parser = OptionParser(usage=usage)
-
-parser.add_option("-q", "--quiet",
-                          action="store_false", dest="verbose",
-                          help="be vewwy quiet (I'm hunting wabbits)")
-
-parser.add_option("-r", "--reuse",
-                          action="store_false", dest="reuse",
-                          help="Reuse .orig files. Dangerous!")
-
-parser.add_option("-o", "--old", 
-                          metavar="old", help="Old namespace")
-
-parser.add_option("-n", "--new",
-                          default="new", help="New namespace")
-
-(options, args) = parser.parse_args()
-
-old_ns = options.old
-new_ns = options.new
-
-# grammar
-
-comment = '#' + SkipTo(lineEnd)
-
-module_ns = Word(alphanums + '-' + '_' + '.' + '*')
-old_module_ns = Combine(old_ns + Optional(Combine('.'+module_ns)))
-end_of_python_line = Or([lineEnd,comment])
-
-as_suffix = 'as' + module_ns
-
-import_pure = 'import' + old_module_ns 
-import_pure_line = import_pure + Optional(as_suffix) + end_of_python_line
-
-import_from = 'from' + old_module_ns + 'import' + commaSeparatedList
-import_from_line = import_from + Optional(as_suffix) + end_of_python_line
-
-import_line = Or([import_pure_line, import_from_line])
-
-# Make a list of Python files to deal with
-
-try:
-    f = args[0]
-except IndexError:
-    print 'Specify a directory root'
-    exit(1)
-
-for root, dirs, files in os.walk(f):
-    for n in files:
-        if (n.endswith('.py')):
-            full_path = '/'.join([root,n])
-            orig_path = full_path + '.orig'
-            if (options.verbose):
-                print 'Working on %s:'%full_path
-            if (not os.path.exists(orig_path) or not options.reuse):
-                if (options.verbose):
-                    print 'Copying %s->%s:'%(full_path,orig_path)
-                copy(full_path, orig_path)
-            f_contents = open(orig_path).read()
-            new_contents = []
-            for l in f_contents.splitlines():
-                try:
-                    match = import_line.parseString(l)
-                    l = l.replace(old_ns, new_ns)
-                except ParseException:
-                    pass
-                new_contents.append(l)
-
-            new_file = '\n'.join(new_contents)
-            if (f_contents.endswith('\n')):
-                new_file+='\n'
-            open(full_path,'w').write(new_file)
diff --git a/xos/tools/chuckmove.README.md b/xos/tools/chuckmove.README.md
deleted file mode 100644
index 5039548..0000000
--- a/xos/tools/chuckmove.README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-Hi,
-
-I've written a tool called 'chuckmove' for helping move Python modules around in a source tree. You use it as follows. Lets say you want to relocate a module to a different location in the tree, and also rename it. So for instance, x is to become y.z. The syntax you use is:
-
-chuckmove -o x -n y.z <root directory>
-
-Invoking this command makes the tool recursively descend into the root directory, make a backup copy of each file (adding the prefix '.orig') and rewrite the imports in it, so that "import x" gets turned into "import y.z"
-
-It recognizes Python grammar, so it works with all of these forms:
-
-from x import a
-from x.b import c 
-import x.d.e.f as foo # Comments are also handled
-
-...with the nit that lines with syntax/grammatical errors are left as is.
-
-For example, for the observer/synchronizer changes, I just had to do the following:
-
-chuckmove -o observer -n synchronizers.base xos
-
-...and then to generate a patch with the changes:
-
-gendiff xos .orig
-
-It's checked into the xos repository under tools (with a README file!).
-
-Sapan
