SEBA-282 xosgenx filtering by app or model;
provide a default argument class for XOSProcessor;
remove tabs;
rename unit tests missed by nose2

Change-Id: I07b782982b6733f8828b8a5a72807326f430b1a5
diff --git a/VERSION b/VERSION
index 2f1a5aa..d302656 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.17
+2.1.18
diff --git a/containers/chameleon/Dockerfile.chameleon b/containers/chameleon/Dockerfile.chameleon
index c0fefa3..0b197e7 100644
--- a/containers/chameleon/Dockerfile.chameleon
+++ b/containers/chameleon/Dockerfile.chameleon
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # xosproject/chameleon
-FROM xosproject/xos-base:2.1.17
+FROM xosproject/xos-base:2.1.18
 
 # xos-base already has protoc and dependencies installed
 
diff --git a/containers/xos/Dockerfile.client b/containers/xos/Dockerfile.client
index 8b56edc..3b29b0d 100644
--- a/containers/xos/Dockerfile.client
+++ b/containers/xos/Dockerfile.client
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # xosproject/xos-client
-FROM xosproject/xos-libraries:2.1.17
+FROM xosproject/xos-libraries:2.1.18
 
 # Install XOS client
 COPY xos/xos_client /tmp/xos_client
diff --git a/containers/xos/Dockerfile.libraries b/containers/xos/Dockerfile.libraries
index d78140f..364f44a 100644
--- a/containers/xos/Dockerfile.libraries
+++ b/containers/xos/Dockerfile.libraries
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM xosproject/xos-base:2.1.17
+FROM xosproject/xos-base:2.1.18
 
 # Add libraries
 COPY lib /opt/xos/lib
diff --git a/containers/xos/Dockerfile.synchronizer-base b/containers/xos/Dockerfile.synchronizer-base
index f354c1a..9f4a785 100644
--- a/containers/xos/Dockerfile.synchronizer-base
+++ b/containers/xos/Dockerfile.synchronizer-base
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # xosproject/xos-synchronizer-base
-FROM xosproject/xos-client:2.1.17
+FROM xosproject/xos-client:2.1.18
 
 COPY xos/synchronizers/new_base /opt/xos/synchronizers/new_base
 COPY xos/xos/logger.py /opt/xos/xos/logger.py
diff --git a/containers/xos/Dockerfile.xos-core b/containers/xos/Dockerfile.xos-core
index e009aea..f9c8ae3 100644
--- a/containers/xos/Dockerfile.xos-core
+++ b/containers/xos/Dockerfile.xos-core
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # xosproject/xos-core
-FROM xosproject/xos-libraries:2.1.17
+FROM xosproject/xos-libraries:2.1.18
 
 # Install XOS
 ADD xos /opt/xos
diff --git a/lib/xos-genx/xos-genx-tests/helpers.py b/lib/xos-genx/xos-genx-tests/helpers.py
index ca73402..ae52076 100644
--- a/lib/xos-genx/xos-genx-tests/helpers.py
+++ b/lib/xos-genx/xos-genx-tests/helpers.py
@@ -21,9 +21,8 @@
 
 TMP_TARGET_PATH = os.path.join(OUTPUT_DIR, 'tmp.xtarget')
 
-# Store in this class the args to pass at the generator
-class FakeArgs:
-    verbosity=0
+# Passed around in various security / validation checks
+class FakeObject:
     pass
 
 class XProtoTestHelpers:
diff --git a/lib/xos-genx/xos-genx-tests/test_django_generator.py b/lib/xos-genx/xos-genx-tests/test_django_generator.py
index d2b3c8a..4f4dae4 100644
--- a/lib/xos-genx/xos-genx-tests/test_django_generator.py
+++ b/lib/xos-genx/xos-genx-tests/test_django_generator.py
@@ -16,8 +16,7 @@
 
 import unittest
 import os
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 
 VROUTER_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/vrouterport.xproto")
 
@@ -27,9 +26,8 @@
         """
         [XOS-GenX] Generate DJANGO models, verify Fields and Foreign Keys
         """
-        args = FakeArgs()
-        args.files = [VROUTER_XPROTO]
-        args.target = 'django.xtarget'
+        args = XOSProcessorArgs(files = [VROUTER_XPROTO],
+                                target = 'django.xtarget')
         output = XOSProcessor.process(args)
 
         fields = filter(lambda s:'Field(' in s, output.splitlines())
@@ -57,9 +55,8 @@
             }
             """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = 'django.xtarget'
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = 'django.xtarget')
         output = XOSProcessor.process(args)
 
         null_true = filter(lambda s: 'null = True' in s, output.splitlines())
@@ -90,9 +87,8 @@
             }
             """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = 'django.xtarget'
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = 'django.xtarget')
         output = XOSProcessor.process(args)
 
         self.assertIn("feedback_state_fields = ['parent_name', 'name']", output)
@@ -110,9 +106,8 @@
             }
             """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = 'django.xtarget'
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = 'django.xtarget')
         output = XOSProcessor.process(args)
 
         self.assertIn("validators=[", output)
diff --git a/lib/xos-genx/xos-genx-tests/test_field_graph.py b/lib/xos-genx/xos-genx-tests/test_field_graph.py
index 9aa1051..478708a 100644
--- a/lib/xos-genx/xos-genx-tests/test_field_graph.py
+++ b/lib/xos-genx/xos-genx-tests/test_field_graph.py
@@ -16,8 +16,8 @@
 
 import unittest
 from xosgenx.jinja2_extensions import FieldNotFound
-from helpers import FakeArgs, OUTPUT_DIR, XProtoTestHelpers
-from xosgenx.generator import XOSProcessor
+from helpers import XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 
 class XProtoFieldGraphTest(unittest.TestCase):
     def _test_field_graph(self):
@@ -43,9 +43,8 @@
 {{ xproto_field_graph_components(proto.messages.0.fields, proto.messages.0) }}
 """)
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = target)
         output = XOSProcessor.process(args)
         output =  eval(output)
         self.assertIn({'A','B','C'}, output)
@@ -69,9 +68,8 @@
 """)
 
         def generate():
-            args = FakeArgs()
-            args.inputs = xproto
-            args.target = target
+            args = XOSProcessorArgs(inputs = xproto,
+                                    target = target)
             output = XOSProcessor.process(args)
 
         with self.assertRaises(FieldNotFound) as e:
diff --git a/lib/xos-genx/xos-genx-tests/test_general_security.py b/lib/xos-genx/xos-genx-tests/test_general_security.py
index 8744a6c..1a7b7ca 100644
--- a/lib/xos-genx/xos-genx-tests/test_general_security.py
+++ b/lib/xos-genx/xos-genx-tests/test_general_security.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers, FakeObject
 
 """The function below is for eliminating warnings arising due to the missing output_security_check,
 which is generated and loaded dynamically.
@@ -42,9 +42,8 @@
 """
     policy output < True >
 """
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -65,9 +64,8 @@
     policy output < ctx.user = obj.user >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -79,10 +77,10 @@
             return i1
         """
 
-        obj = FakeArgs()
-	obj.user = 1
-        ctx = FakeArgs()
-	ctx.user = 1
+        obj = FakeObject()
+        obj.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         verdict = output_security_check(obj, ctx)
 
@@ -93,9 +91,8 @@
     policy output < *sub_policy(child) >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -114,12 +111,12 @@
 	    return i1
         """
 
-        obj = FakeArgs()
-        obj.child = FakeArgs()
-	obj.child.user = 1
+        obj = FakeObject()
+        obj.child = FakeObject()
+        obj.child.user = 1
 
-        ctx = FakeArgs()
-	ctx.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         verdict = output_security_check(obj, ctx)
         self.assertTrue(verdict)
@@ -131,9 +128,8 @@
     policy output < *sub_policy(child) >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -152,11 +148,11 @@
 	    return i1
         """
 
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.child = None
 
-        ctx = FakeArgs()
-	ctx.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         verdict = output_security_check(obj, ctx)
         self.assertTrue(verdict)
@@ -167,9 +163,8 @@
     policy output < ctx.is_admin = True | obj.empty = True>
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
         exec(output) # This loads the generated function, which should look like this:
@@ -182,11 +177,11 @@
 	    return i1
         """
 
-        obj = FakeArgs()
-	obj.empty = True
+        obj = FakeObject()
+        obj.empty = True
 
-	ctx = FakeArgs()
-	ctx.is_admin = True
+        ctx = FakeObject()
+        ctx.is_admin = True
 
         verdict = output_security_check(obj, ctx)
 
@@ -198,9 +193,8 @@
 """
     policy output < exists Privilege: Privilege.object_id = obj.id >
 """
-	args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
         exec(output) # This loads the generated function, which should look like this:
@@ -218,9 +212,8 @@
 """
     policy output < {{ "jack" in ["the", "box"] }} = False >
 """
-	args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
         output = XOSProcessor.process(args)
         exec(output) # This loads the generated function, which should look like this:
 
@@ -240,9 +233,8 @@
     policy output < forall Credential: Credential.obj_id = obj_id >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
         """
diff --git a/lib/xos-genx/xos-genx-tests/test_general_validation.py b/lib/xos-genx/xos-genx-tests/test_general_validation.py
index 0fc0092..048167a 100644
--- a/lib/xos-genx/xos-genx-tests/test_general_validation.py
+++ b/lib/xos-genx/xos-genx-tests/test_general_validation.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers, FakeObject
 import pdb
 
 """The function below is for eliminating warnings arising due to the missing policy_output_validator,
@@ -43,9 +43,8 @@
 """
     policy output < False >
 """
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -67,9 +66,8 @@
     policy output < not (ctx.user = obj.user) >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -83,10 +81,10 @@
                 raise Exception('Necessary Failure')
         """
 
-        obj = FakeArgs()
-	obj.user = 1
-        ctx = FakeArgs()
-	ctx.user = 1
+        obj = FakeObject()
+        obj.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         with self.assertRaises(Exception):
            policy_output_validator(obj, ctx)
@@ -97,9 +95,8 @@
     policy output < not (ctx.user = obj.user) >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -113,10 +110,10 @@
                 raise Exception('Necessary Failure')
         """
 
-        obj = FakeArgs()
-	obj.user = 1
-        ctx = FakeArgs()
-	ctx.user = 1
+        obj = FakeObject()
+        obj.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         with self.assertRaises(Exception):
            policy_output_validator(obj, ctx)
@@ -127,7 +124,7 @@
     policy output < (ctx.is_admin = True | obj.empty = True) | False>
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -143,11 +140,11 @@
                 raise Exception('Necessary Failure')
         """
 
-        obj = FakeArgs()
-	obj.empty = False
+        obj = FakeObject()
+        obj.empty = False
 
-	ctx = FakeArgs()
-	ctx.is_admin = False
+        ctx = FakeObject()
+        ctx.is_admin = False
 
         with self.assertRaises(Exception):
             verdict = policy_output_validator(obj, ctx)
@@ -158,9 +155,8 @@
 """
     policy output < exists Privilege: Privilege.object_id = obj.id >
 """
-	args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
         exec(output) # This loads the generated function, which should look like this:
@@ -179,9 +175,8 @@
 """
     policy output < {{ "jack" in ["the", "box"] }} = True >
 """
-	args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
         output = XOSProcessor.process(args)
         exec(output) # This loads the generated function, which should look like this:
 
@@ -203,9 +198,8 @@
     policy output < *sub_policy(child) >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
@@ -223,12 +217,12 @@
                 raise ValidationError('Necessary Failure')
         """
 
-        obj = FakeArgs()
-        obj.child = FakeArgs()
-	obj.child.user = 1
+        obj = FakeObject()
+        obj.child = FakeObject()
+        obj.child.user = 1
 
-        ctx = FakeArgs()
-	ctx.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         with self.assertRaises(Exception):
             verdict = policy_output_enforcer(obj, ctx)
@@ -240,9 +234,8 @@
     policy output < forall Credential: Credential.obj_id = obj_id >
 """
 
-        args = FakeArgs()
-        args.inputs = xproto
-        args.target = self.target
+        args = XOSProcessorArgs(inputs = xproto,
+                                target = self.target)
 
         output = XOSProcessor.process(args)
 
diff --git a/lib/xos-genx/xos-genx-tests/test_generator.py b/lib/xos-genx/xos-genx-tests/test_generator.py
index 1a81f8a..06da7ee 100644
--- a/lib/xos-genx/xos-genx-tests/test_generator.py
+++ b/lib/xos-genx/xos-genx-tests/test_generator.py
@@ -16,8 +16,8 @@
 
 import unittest
 import os
-from helpers import FakeArgs, OUTPUT_DIR
-from xosgenx.generator import XOSProcessor
+from helpers import OUTPUT_DIR
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 
 TEST_EXPECTED_OUTPUT = """
     name: XOSModel
@@ -33,10 +33,12 @@
 BASE_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/base.xproto")
 TEST_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/test.xproto")
 FIELDTEST_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/fieldtest.xproto")
+FILTERTEST_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/filtertest.xproto")
 SKIP_DJANGO_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/skip_django.xproto")
 VROUTER_XPROTO = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xproto/vrouterport.xproto")
 TEST_TARGET = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xtarget/test.xtarget")
 FIELDTEST_TARGET = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xtarget/fieldtest.xtarget")
+FILTERTEST_TARGET = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xtarget/filtertest.xtarget")
 SPLIT_TARGET = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/xtarget/split.xtarget")
 
 TEST_ATTICS = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/attics/")
@@ -57,9 +59,8 @@
         """
         [XOS-GenX] Generate output from base.xproto
         """
-        args = FakeArgs()
-        args.files = [TEST_XPROTO]
-        args.target = TEST_TARGET
+        args = XOSProcessorArgs(files = [TEST_XPROTO],
+                                target = TEST_TARGET)
         output = XOSProcessor.process(args)
         self.assertEqual(output, TEST_EXPECTED_OUTPUT)
 
@@ -67,9 +68,8 @@
         """
         [XOS-GenX] Generate output from base.xproto
         """
-        args = FakeArgs()
-        args.inputs = open(TEST_XPROTO).read()
-        args.target = TEST_TARGET
+        args = XOSProcessorArgs(inputs = open(TEST_XPROTO).read(),
+                                target = TEST_TARGET)
         output = XOSProcessor.process(args)
         self.assertEqual(output, TEST_EXPECTED_OUTPUT)
 
@@ -77,13 +77,12 @@
         """
         [XOS-GenX] Generate django output from test.xproto
         """
-        args = FakeArgs()
-        args.files = [TEST_XPROTO, VROUTER_XPROTO]
-        args.target = 'django.xtarget'
-        args.attic = TEST_ATTICS
-        args.output = OUTPUT_DIR
-        args.dest_extension = 'py'
-        args.write_to_file = 'model'
+        args = XOSProcessorArgs(files = [TEST_XPROTO, VROUTER_XPROTO],
+                                target = 'django.xtarget',
+                                attic = TEST_ATTICS,
+                                output = OUTPUT_DIR,
+                                dest_extension = 'py',
+                                write_to_file = 'model')
         output = XOSProcessor.process(args)
 
         # xosmodel has custom header attic
@@ -108,13 +107,12 @@
         self.assertIn('class VRouterPort(XOSBase):', vrpf)
 
     def test_django_with_base(self):
-        args = FakeArgs()
-        args.files = [TEST_XPROTO, BASE_XPROTO]
-        args.target = 'django.xtarget'
-        args.attic = TEST_ATTICS
-        args.output = OUTPUT_DIR
-        args.dest_extension = 'py'
-        args.write_to_file = 'model'
+        args = XOSProcessorArgs(files = [TEST_XPROTO, BASE_XPROTO],
+                                target = 'django.xtarget',
+                                attic = TEST_ATTICS,
+                                output = OUTPUT_DIR,
+                                dest_extension = 'py',
+                                write_to_file = 'model')
         output = XOSProcessor.process(args)
 
         # verify files
@@ -134,12 +132,11 @@
         """
         [XOS-GenX] read multiple models as input, print one file per model
         """
-        args = FakeArgs()
-        args.files = [TEST_XPROTO, VROUTER_XPROTO]
-        args.target = TEST_TARGET
-        args.output = OUTPUT_DIR
-        args.dest_extension = 'txt'
-        args.write_to_file = 'model'
+        args = XOSProcessorArgs(files = [TEST_XPROTO, VROUTER_XPROTO],
+                                target = TEST_TARGET,
+                                output = OUTPUT_DIR,
+                                dest_extension = 'txt',
+                                write_to_file = 'model')
         XOSProcessor.process(args)
 
         generated_files = [f for f in os.listdir(OUTPUT_DIR) if not f.startswith('.')]
@@ -155,11 +152,10 @@
         """
         [XOS-GenX] read multiple models as input, print separate files based on +++
         """
-        args = FakeArgs()
-        args.files = [TEST_XPROTO, VROUTER_XPROTO]
-        args.target = SPLIT_TARGET
-        args.output = OUTPUT_DIR
-        args.write_to_file = 'target'
+        args = XOSProcessorArgs(files = [TEST_XPROTO, VROUTER_XPROTO],
+                                target = SPLIT_TARGET,
+                                output = OUTPUT_DIR,
+                                write_to_file = 'target')
         XOSProcessor.process(args)
 
         generated_files = [f for f in os.listdir(OUTPUT_DIR) if not f.startswith('.')]
@@ -172,12 +168,11 @@
         self.assertIn("name: VRouterPort", vrouterport)
 
     def test_skip_django(self):
-        args = FakeArgs()
-        args.files = [SKIP_DJANGO_XPROTO]
-        args.target = 'django.xtarget'
-        args.output = OUTPUT_DIR
-        args.dest_extension = 'py'
-        args.write_to_file = 'model'
+        args = XOSProcessorArgs(files = [SKIP_DJANGO_XPROTO],
+                                target = 'django.xtarget',
+                                output = OUTPUT_DIR,
+                                dest_extension = 'py',
+                                write_to_file = 'model')
         output = XOSProcessor.process(args)
 
         # should not print a file if options.skip_django = True
@@ -185,11 +180,10 @@
         self.assertFalse(os.path.isfile(file))
 
     def test_service_order(self):
-        args = FakeArgs()
-        args.files = [BASE_XPROTO, TEST_XPROTO, VROUTER_XPROTO]
-        args.target = 'service.xtarget'
-        args.output = OUTPUT_DIR
-        args.write_to_file = 'target'
+        args = XOSProcessorArgs(files = [BASE_XPROTO, TEST_XPROTO, VROUTER_XPROTO],
+                                target = 'service.xtarget',
+                                output = OUTPUT_DIR,
+                                write_to_file = 'target')
         output = XOSProcessor.process(args)
 
         model = OUTPUT_DIR + '/models.py'
@@ -208,9 +202,8 @@
         self.assertLess(xosmodel_line, vrouter_line)
 
     def test_field_numbers(self):
-        args = FakeArgs()
-        args.files = [FIELDTEST_XPROTO]
-        args.target = FIELDTEST_TARGET
+        args = XOSProcessorArgs(files = [FIELDTEST_XPROTO],
+                                target = FIELDTEST_TARGET)
         output = XOSProcessor.process(args)
 
         def _assert_field(modelname, fieldname, id):
@@ -229,6 +222,34 @@
         _assert_field("Slice", "slice_field", 101)
         _assert_field("Slice", "site", 102)
 
+    def test_unfiltered(self):
+        """ With no include_* args, should get all models """
+        args = XOSProcessorArgs(files = [FILTERTEST_XPROTO],
+                                target = FILTERTEST_TARGET)
+        output = XOSProcessor.process(args)
+
+        self.assertEqual(output, "Model1,Model2,Model3,")
+
+    def test_filter_models(self):
+        """ Should only get models specified by include_models """
+        args = XOSProcessorArgs(files = [FILTERTEST_XPROTO],
+                                target = FILTERTEST_TARGET,
+                                include_models = ["Model1", "Model3"])
+        output = XOSProcessor.process(args)
+
+        self.assertEqual(output, "Model1,Model3,")
+
+    def test_filter_apps(self):
+        """ Should only get models whose apps are specified by include_apps """
+        args = XOSProcessorArgs(files = [FILTERTEST_XPROTO],
+                                target = FILTERTEST_TARGET,
+                                include_apps = ["core"])
+        output = XOSProcessor.process(args)
+
+        self.assertEqual(output, "Model1,Model2,")
+
+
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib/xos-genx/xos-genx-tests/test_graph.py b/lib/xos-genx/xos-genx-tests/test_graph.py
index cda36d0..fda3d99 100644
--- a/lib/xos-genx/xos-genx-tests/test_graph.py
+++ b/lib/xos-genx/xos-genx-tests/test_graph.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 class XProtoGraphTests(unittest.TestCase):
     def test_cross_model(self):
@@ -112,7 +112,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = proto
         args.target = target
         output = XOSProcessor.process(args)
@@ -213,7 +213,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = proto
         args.target = xtarget
         output = XOSProcessor.process(args)
@@ -305,7 +305,7 @@
      required manytomany tags->Tag = 18 [db_index = False, null = False, blank = True];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = proto
         args.target = xtarget
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_package.py b/lib/xos-genx/xos-genx-tests/test_package.py
index 373a818..f1cf426 100644
--- a/lib/xos-genx/xos-genx-tests/test_package.py
+++ b/lib/xos-genx/xos-genx-tests/test_package.py
@@ -16,12 +16,12 @@
 
 import unittest
 import os
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 class XProtoPackageTest(unittest.TestCase):
     def test_package_fqn(self):
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         target = XProtoTestHelpers.write_tmp_target(
 """
   {% for m in proto.messages %}
@@ -42,7 +42,7 @@
      required bool xos_created = 6 [default = False, null = False, db_index = False, blank = True];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
@@ -159,7 +159,7 @@
      required manytomany tags->Tag = 18 [db_index = False, null = False, blank = True];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
         output = XOSProcessor.process(args)
@@ -220,7 +220,7 @@
      required manytomany tags->Tag = 17 [db_index = False, null = False, blank = True];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
         output = XOSProcessor.process(args)
@@ -321,7 +321,7 @@
      required manytomany tags->Tag = 18 [db_index = False, null = False, blank = True];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
         output = XOSProcessor.process(args)
@@ -427,7 +427,7 @@
 }
 """
          
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/parse_test.py b/lib/xos-genx/xos-genx-tests/test_parse.py
similarity index 91%
rename from lib/xos-genx/xos-genx-tests/parse_test.py
rename to lib/xos-genx/xos-genx-tests/test_parse.py
index e63c7d0..d7edcb7 100644
--- a/lib/xos-genx/xos-genx-tests/parse_test.py
+++ b/lib/xos-genx/xos-genx-tests/test_parse.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 class XProtoParseTests(unittest.TestCase):
     def test_global_options(self):
@@ -28,7 +28,7 @@
     option kind = "vsg";
     option verbose_name = "vSG Service";
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
@@ -57,7 +57,7 @@
   repeated PhoneNumber phones = 4;
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
@@ -72,13 +72,11 @@
     required manytoone vrouter_service->VRouterService:device_ports = 4 [db_index = True, null = False, blank = False];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
         self.assertIn("VRouterService", output)
-	
-	pass
 
     def test_through_extensions(self):
         xtarget = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0.links.0.through }}")
@@ -88,7 +86,7 @@
     required manytomany vrouter_service->VRouterService/ServiceProxy:device_ports = 4 [db_index = True, null = False, blank = False];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
@@ -102,14 +100,12 @@
     option type = "e1000";
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
         self.assertIn("e1000", output)
 
-	pass
-
     def test_message_base(self):
         xtarget = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0.bases }}")
         xproto = \
@@ -118,7 +114,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = xtarget
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_policy.py b/lib/xos-genx/xos-genx-tests/test_policy.py
index 9e77976..d83ab6c 100644
--- a/lib/xos-genx/xos-genx-tests/test_policy.py
+++ b/lib/xos-genx/xos-genx-tests/test_policy.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import FakeObject, XProtoTestHelpers
 import pdb
 
 """
@@ -37,7 +37,7 @@
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0 }}")
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
@@ -52,7 +52,7 @@
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.true_policy }}")
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
@@ -66,14 +66,14 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
        
-        slice = FakeArgs()
-        slice.user = FakeArgs()
+        slice = FakeObject()
+        slice.user = FakeObject()
         slice.user.compute_is_admin = lambda: True
 
         expr = eval(output)
@@ -86,14 +86,14 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
        
-        slice = FakeArgs()
-        slice.user = FakeArgs()
+        slice = FakeObject()
+        slice.user = FakeObject()
         slice.user.is_admin = True
 
         expr = eval(output)
@@ -106,14 +106,14 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
        
-        slice = FakeArgs()
-        slice.user = FakeArgs()
+        slice = FakeObject()
+        slice.user = FakeObject()
         slice.user.is_admin = True
 
         expr = eval(output)
@@ -126,14 +126,14 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
        
-        slice = FakeArgs()
-        slice.user = FakeArgs()
+        slice = FakeObject()
+        slice.user = FakeObject()
         slice.user.is_admin = True
 
         expr = eval(output)
@@ -146,15 +146,15 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
        
-        slice = FakeArgs()
+        slice = FakeObject()
         slice.user = 'twin'
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.user = 'twin'
 
         (op, operands), = eval(output).items()
@@ -168,15 +168,15 @@
     policy slice_admin < slice.is_admin | obj.empty >
 """
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_admin }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
 
-        slice = FakeArgs()
+        slice = FakeObject()
         slice.is_admin = False
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.empty = []
 
         (op, operands), = eval(output).items()
@@ -190,15 +190,15 @@
     policy implies < obj.name -> obj.creator >
 """
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.implies }}")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
 
-        slice = FakeArgs()
+        slice = FakeObject()
         slice.is_admin = False
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.name = 'Thing 1'
         obj.creator = None
 
@@ -214,15 +214,15 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.privilege }} ")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
         output = XOSProcessor.process(args)
         
-        Privilege = FakeArgs()
+        Privilege = FakeObject()
         Privilege.object_id = 1
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.id = 1
 
         (op, operands), = eval(output).items()
@@ -239,7 +239,7 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.network_slice_policy }} ")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
@@ -258,7 +258,7 @@
 """
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.network_slice_policy }} ")
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
@@ -275,7 +275,7 @@
 
         target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.instance }}")
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
 
diff --git a/lib/xos-genx/xos-genx-tests/test_pure_proto.py b/lib/xos-genx/xos-genx-tests/test_pure_proto.py
index 45cb6ed..ade4957 100644
--- a/lib/xos-genx/xos-genx-tests/test_pure_proto.py
+++ b/lib/xos-genx/xos-genx-tests/test_pure_proto.py
@@ -16,8 +16,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 # Generate from xproto, then generate from equivalent proto
 class XPureProtobufGenerator(unittest.TestCase):
@@ -83,14 +83,14 @@
 {% endfor %}
 """)
 
-		args_xproto = FakeArgs()
+		args_xproto = XOSProcessorArgs()
 		args_xproto.inputs = xproto
 		args_xproto.target = target
 		xproto_gen = XOSProcessor.process(args_xproto)
 
 		count1 = len(xproto_gen.split('\n'))
 
-		args_proto = FakeArgs()
+		args_proto = XOSProcessorArgs()
 		args_proto.inputs = proto
 		args_proto.target = target
 		args_proto.rev = True
@@ -114,12 +114,12 @@
 {{ policies }}
 """)
 
-		args_xproto = FakeArgs()
+		args_xproto = XOSProcessorArgs()
 		args_xproto.inputs = xproto
 		args_xproto.target = target
 		xproto_gen = XOSProcessor.process(args_xproto)
 
-		args_proto = FakeArgs()
+		args_proto = XOSProcessorArgs()
 		args_proto.inputs = proto
 		args_proto.target = target
 		args_proto.rev = True
diff --git a/lib/xos-genx/xos-genx-tests/test_rlinks.py b/lib/xos-genx/xos-genx-tests/test_rlinks.py
index ba025ab..635c81f 100644
--- a/lib/xos-genx/xos-genx-tests/test_rlinks.py
+++ b/lib/xos-genx/xos-genx-tests/test_rlinks.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 class XProtoRlinkTests(unittest.TestCase):
     def test_proto_generator(self):
@@ -53,7 +53,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = target
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_swagger.py b/lib/xos-genx/xos-genx-tests/test_swagger.py
index 8107870..00b0684 100644
--- a/lib/xos-genx/xos-genx-tests/test_swagger.py
+++ b/lib/xos-genx/xos-genx-tests/test_swagger.py
@@ -17,8 +17,8 @@
 import unittest
 
 import yaml
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, OUTPUT_DIR
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import OUTPUT_DIR
 
 class Args:
     pass
@@ -56,7 +56,7 @@
                  optional manytoone parent->Instance:instance = 16 [help_text = "Parent Instance for containers nested inside of VMs", null = True, db_index = True, blank = True];
             }
             """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'swagger.xtarget'
         args.output = OUTPUT_DIR
diff --git a/lib/xos-genx/xos-genx-tests/target_test.py b/lib/xos-genx/xos-genx-tests/test_target.py
similarity index 92%
rename from lib/xos-genx/xos-genx-tests/target_test.py
rename to lib/xos-genx/xos-genx-tests/test_target.py
index 1dab47c..d729be7 100644
--- a/lib/xos-genx/xos-genx-tests/target_test.py
+++ b/lib/xos-genx/xos-genx-tests/test_target.py
@@ -16,8 +16,8 @@
 
 import unittest
 import os
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers, OUTPUT_DIR
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers, OUTPUT_DIR
 
 TEST_FILE = "test_file"
 
@@ -39,7 +39,7 @@
 """%(TEST_FILE, TEST_FILE)
         )
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = ''
         args.target = target
         args.attic = OUTPUT_DIR
@@ -51,7 +51,7 @@
 """
   {{ xproto_first_non_empty([None, None, None, None, None, None, "Eureka"]) }}
 """)
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = ''
         args.target = target
         output = XOSProcessor.process(args)
@@ -62,7 +62,7 @@
 """
   {{ context.what }}
 """)
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = ''
         args.target = target
         args.kv='what:what is what'
@@ -89,7 +89,7 @@
 {{ xproto_singularize(m) }},
 {%- endfor %}
 """)
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = proto
         args.target = target
         output = XOSProcessor.process(args)
@@ -115,7 +115,7 @@
 {{ xproto_pluralize(m) }},
 {%- endfor %}
 """)
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = proto
         args.target = target
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_tosca.py b/lib/xos-genx/xos-genx-tests/test_tosca.py
index 0d2ec4e..270d126 100644
--- a/lib/xos-genx/xos-genx-tests/test_tosca.py
+++ b/lib/xos-genx/xos-genx-tests/test_tosca.py
@@ -13,8 +13,8 @@
 # limitations under the License.
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 
 class XProtoToscaTypeTest(unittest.TestCase):
@@ -43,7 +43,7 @@
         }
         """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target_tosca_type
         output = XOSProcessor.process(args)
@@ -74,7 +74,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target_tosca_keys
         output = XOSProcessor.process(args)
@@ -95,7 +95,7 @@
             }
             """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target_tosca_keys
         output = XOSProcessor.process(args)
@@ -117,7 +117,7 @@
             }
             """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target_tosca_keys
         output = XOSProcessor.process(args)
@@ -144,7 +144,7 @@
             }
             """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target_tosca_keys
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_translator.py b/lib/xos-genx/xos-genx-tests/test_translator.py
index 5923bc7..f3476cd 100644
--- a/lib/xos-genx/xos-genx-tests/test_translator.py
+++ b/lib/xos-genx/xos-genx-tests/test_translator.py
@@ -16,8 +16,7 @@
 
 import unittest
 import os
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 import yaml
 
 PROTO_EXPECTED_OUTPUT = """
@@ -34,7 +33,7 @@
 # Generate other formats from xproto
 class XProtoTranslatorTest(unittest.TestCase):
     def _test_proto_generator(self):
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.files = [VROUTER_XPROTO]
         args.target = 'proto.xtarget'
         output = XOSProcessor.process(args)
@@ -119,7 +118,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -142,7 +141,7 @@
     required string name = 1 [ null = "False", blank="False"];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -161,7 +160,7 @@
     required string secret = 1 [ null = "False", blank="False", gui_hidden = "True"];
 }
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -181,7 +180,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -198,7 +197,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -218,7 +217,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -238,7 +237,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -259,7 +258,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -287,7 +286,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -309,7 +308,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
@@ -329,7 +328,7 @@
 }
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = 'modeldefs.xtarget'
         output = XOSProcessor.process(args)
diff --git a/lib/xos-genx/xos-genx-tests/test_xos_security.py b/lib/xos-genx/xos-genx-tests/test_xos_security.py
index 2c704ac..766e102 100644
--- a/lib/xos-genx/xos-genx-tests/test_xos_security.py
+++ b/lib/xos-genx/xos-genx-tests/test_xos_security.py
@@ -15,10 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
-import pdb
-import mock
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import XProtoTestHelpers
 
 """The function below is for eliminating warnings arising due to the missing policy_output_enforcer,
 which is generated and loaded dynamically.
@@ -44,7 +42,7 @@
 """
     policy test_policy < ctx.user.is_admin | exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.object_type = "Deployment" & Privilege.permission = "role:admin" & Privilege.object_id = obj.id >
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -83,7 +81,7 @@
              & Privilege.object_id = obj.owner.site.id
              & Privilege.permission = "role:admin") >
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -131,7 +129,7 @@
             )>
     
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -177,7 +175,7 @@
              & Privilege.object_type = "Site"
              & Privilege.object_id = ctx.user.site.id) >
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
diff --git a/lib/xos-genx/xos-genx-tests/test_xos_validation.py b/lib/xos-genx/xos-genx-tests/test_xos_validation.py
index f38f65b..f2f8ce3 100644
--- a/lib/xos-genx/xos-genx-tests/test_xos_validation.py
+++ b/lib/xos-genx/xos-genx-tests/test_xos_validation.py
@@ -15,8 +15,8 @@
 
 
 import unittest
-from xosgenx.generator import XOSProcessor
-from helpers import FakeArgs, XProtoTestHelpers
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
+from helpers import FakeObject, XProtoTestHelpers
 
 """The function below is for eliminating warnings arising due to the missing policy_output_validator,
 which is generated and loaded dynamically.
@@ -38,13 +38,13 @@
 """
     policy test_policy < (obj.isolation = "container" | obj.isolation = "container_vm" ) -> (obj.image.kind = "container") >
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
         output = XOSProcessor.process(args)
 
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.isolation = 'container'
         obj.kind = 'not a container'
 
@@ -68,13 +68,13 @@
 """
     policy test_policy < not obj.id -> {{ obj.name.startswith(obj.site.login_base) }} >
 """
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
         output = XOSProcessor.process(args)
 
-        obj = FakeArgs()
+        obj = FakeObject()
         obj.isolation = 'container'
         obj.kind = 'not a container'
 
@@ -99,7 +99,7 @@
     policy test_policy < not (ctx.user = obj.user) >
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -115,10 +115,10 @@
                 raise Exception('Necessary Failure')
         """
 
-        obj = FakeArgs()
-	obj.user = 1
-        ctx = FakeArgs()
-	ctx.user = 1
+        obj = FakeObject()
+        obj.user = 1
+        ctx = FakeObject()
+        ctx.user = 1
 
         with self.assertRaises(Exception):
            policy_output_validator(obj, ctx)
@@ -129,7 +129,7 @@
     policy test_policy < not (ctx.is_admin = True | obj.empty = True) | False>
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -145,11 +145,11 @@
                 raise Exception('Necessary Failure')
         """
 
-        obj = FakeArgs()
-	obj.empty = True
+        obj = FakeObject()
+        obj.empty = True
 
-	ctx = FakeArgs()
-	ctx.is_admin = True
+        ctx = FakeObject()
+        ctx.is_admin = True
 
         with self.assertRaises(Exception):
             verdict = policy_output_validator(obj, ctx)
@@ -160,7 +160,7 @@
 """
     policy test_policy < exists Privilege: Privilege.object_id = obj.id >
 """
-	args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
@@ -181,7 +181,7 @@
 """
     policy test_policy < {{ "jack" in ["the", "box"] }} = True >
 """
-	args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
         output = XOSProcessor.process(args)
@@ -205,7 +205,7 @@
     policy test_policy < forall Credential: Credential.obj_id = obj_id >
 """
 
-        args = FakeArgs()
+        args = XOSProcessorArgs()
         args.inputs = xproto
         args.target = self.target
 
diff --git a/lib/xos-genx/xos-genx-tests/xproto/filtertest.xproto b/lib/xos-genx/xos-genx-tests/xproto/filtertest.xproto
new file mode 100644
index 0000000..e2f6f10
--- /dev/null
+++ b/lib/xos-genx/xos-genx-tests/xproto/filtertest.xproto
@@ -0,0 +1,15 @@
+option app_label = "core";
+
+message Model1 {
+    optional string somefield = 1;
+}
+
+message Model2 {
+    optional string somefield = 2;
+}
+
+message Model3 {
+    option app_label = "someservice";
+    optional string somefield = 3;
+}
+
diff --git a/lib/xos-genx/xos-genx-tests/xtarget/filtertest.xtarget b/lib/xos-genx/xos-genx-tests/xtarget/filtertest.xtarget
new file mode 100644
index 0000000..e88d1d6
--- /dev/null
+++ b/lib/xos-genx/xos-genx-tests/xtarget/filtertest.xtarget
@@ -0,0 +1 @@
+{% for object in proto.messages|selectattr("is_included")|sort(attribute='name') %}{{ object.name }},{% endfor %}
diff --git a/lib/xos-genx/xosgenx/generator.py b/lib/xos-genx/xosgenx/generator.py
index dc1ff9e..3355fb5 100644
--- a/lib/xos-genx/xosgenx/generator.py
+++ b/lib/xos-genx/xosgenx/generator.py
@@ -26,6 +26,43 @@
 loader = jinja2.PackageLoader(__name__, 'templates')
 env = jinja2.Environment(loader=loader)
 
+class XOSProcessorArgs:
+    """ Helper class for use cases that want to call XOSProcessor directly, rather than executing xosgenx from the
+        command line.
+    """
+
+    default_rev = False
+    default_output = None
+    default_attic = None
+    default_kvpairs = None
+    default_write_to_file = None
+    default_dest_file = None
+    default_dest_extension = None
+    default_target = None
+    default_checkers = None
+    default_verbosity = 0         # Higher numbers = more verbosity, lower numbers = less verbosity
+    default_include_models = []   # If neither include_models nor include_apps is specified, then all models will
+    default_include_apps = []     # be included.
+
+    def __init__(self, **kwargs):
+        # set defaults
+        self.rev = XOSProcessorArgs.default_rev
+        self.output = XOSProcessorArgs.default_output
+        self.attic = XOSProcessorArgs.default_attic
+        self.kvpairs = XOSProcessorArgs.default_kvpairs
+        self.verbosity = XOSProcessorArgs.default_verbosity
+        self.write_to_file = XOSProcessorArgs.default_write_to_file
+        self.default_dest_file = XOSProcessorArgs.default_dest_file
+        self.default_dest_extension = XOSProcessorArgs.default_dest_extension
+        self.default_target = XOSProcessorArgs.default_target
+        self.default_checkers = XOSProcessorArgs.default_target
+        self.include_models = XOSProcessorArgs.default_include_models
+        self.include_apps = XOSProcessorArgs.default_include_apps
+
+        # override defaults with kwargs
+        for (k,v) in kwargs.items():
+            setattr(self, k, v)
+
 class XOSProcessor:
 
     @staticmethod
@@ -225,7 +262,7 @@
             if start == 0:
                 beginning = ''
             else:
-                beginning = inputs[ptr:start-1] 
+                beginning = inputs[ptr:start-1]
 
             line_end_char = inputs[start+end:].find('\n')
             line_end = inputs[line_end_char]
@@ -242,6 +279,19 @@
 
         v = XOSProcessor._attach_parser(ast, args)
 
+        if args.include_models or args.include_apps:
+            for message in v.messages:
+                message["is_included"] = False
+                if message["name"] in args.include_models:
+                    message["is_included"] = True
+                else:
+                    app_label = message.get("options", {}).get("app_label").strip('"')
+                    if app_label in args.include_apps:
+                        message["is_included"] = True
+        else:
+            for message in v.messages:
+                message["is_included"] = True
+
         if args.output is not None and args.write_to_file == "model":
             rendered = {}
             for i, model in enumerate(v.models):
@@ -255,7 +305,7 @@
                             'message_table': models,
                             'messages': messages,
                             'policies': v.policies,
-                            'message_names': [m['name'] for m in messages]
+                            'message_names': [m['name'] for m in v.messages]
                         },
                         "context": context,
                         "options": v.options
diff --git a/lib/xos-genx/xosgenx/jinja2_extensions/base.py b/lib/xos-genx/xosgenx/jinja2_extensions/base.py
index 3bfcd70..af1c241 100644
--- a/lib/xos-genx/xosgenx/jinja2_extensions/base.py
+++ b/lib/xos-genx/xosgenx/jinja2_extensions/base.py
@@ -164,6 +164,9 @@
 
     # The "id" field is a special field. Every model has one. Put it up front and pretend it's part of the
 
+    if not fields:
+        raise Exception("Model %s has no fields. Check for missing base class." % m["name"])
+
     id_field = {'type': 'int32', 'name': 'id', 'options': {}, "id": "1", "accessor": fields[0]["accessor"]}
 
     fields = [id_field] + fields
diff --git a/lib/xos-genx/xosgenx/targets/protoapi.xtarget b/lib/xos-genx/xosgenx/targets/protoapi.xtarget
index 2311b98..e87e7d8 100644
--- a/lib/xos-genx/xosgenx/targets/protoapi.xtarget
+++ b/lib/xos-genx/xosgenx/targets/protoapi.xtarget
@@ -11,7 +11,7 @@
 // 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 proto.messages|sort(attribute='name') %}
+{% for object in proto.messages|selectattr("is_included")|sort(attribute='name') %}
 {% if object.name != 'XOSBase' -%}
 message {{ object.name }} {
     {%- if object.name=='CordSubscriberRoot' %}
@@ -47,7 +47,7 @@
 {% endfor %}
 
 service xos {
-{% for object in proto.messages | sort(attribute='name')%}
+{% for object in proto.messages | selectattr("is_included") | sort(attribute='name')%}
 {% if object.name != 'XOSBase' -%}
   rpc List{{ object.name }}(google.protobuf.Empty) returns ({{ xproto_pluralize(object) }}) {
         option (googleapi.http) = {
diff --git a/lib/xos-genx/xosgenx/xosgen.py b/lib/xos-genx/xosgenx/xosgen.py
index 8259d58..27a7fb4 100755
--- a/lib/xos-genx/xosgenx/xosgen.py
+++ b/lib/xos-genx/xosgenx/xosgen.py
@@ -21,21 +21,36 @@
 from version import __version__
 
 parse = argparse.ArgumentParser(description='XOS Generative Toolchain')
-parse.add_argument('--rev', dest='rev', action='store_true',default=False, help='Convert proto to xproto')
-parse.add_argument('--output', dest='output', action='store',default=None, help='Destination dir')
-parse.add_argument('--attic', dest='attic', action='store',default=None, help='The location at which static files are stored')
-parse.add_argument('--kvpairs', dest='kv', action='store',default=None, help='Key value pairs to make available to the target')
-parse.add_argument('--write-to-file', dest='write_to_file', choices = ['single', 'model', 'target'], action='store',default=None, help='Single output file (single) or output file per model (model) or let target decide (target)')
+parse.add_argument('--rev', dest='rev', action='store_true',
+                   default=XOSProcessorArgs.default_rev, help='Convert proto to xproto')
+parse.add_argument('--output', dest='output', action='store',
+                   default=XOSProcessorArgs.default_output, help='Destination dir')
+parse.add_argument('--attic', dest='attic', action='store',
+                   default=XOSProcessorArgs.default_attic, help='The location at which static files are stored')
+parse.add_argument('--kvpairs', dest='kv', action='store',
+                   default=XOSProcessorArgs.default_kvpairs, help='Key value pairs to make available to the target')
+parse.add_argument('--write-to-file', dest='write_to_file', choices = ['single', 'model', 'target'], action='store',
+                   default=XOSProcessorArgs.default_write_to_file,
+                   help='Single output file (single) or output file per model (model) or let target decide (target)')
 parse.add_argument('--version', action='version', version=__version__)
-parse.add_argument("-v", "--verbosity", action="count", default=0, help="increase output verbosity")
+parse.add_argument("-v", "--verbosity", action="count",
+                   default=XOSProcessorArgs.default_verbosity, help="increase output verbosity")
+parse.add_argument("--include-models", dest="include_models", action="append",
+                   default=XOSProcessorArgs.default_include_models, help="list of models to include")
+parse.add_argument("--include-apps", dest="include_apps", action="append",
+                   default=XOSProcessorArgs.default_include_apps, help="list of models to include")
 
 group = parse.add_mutually_exclusive_group()
-group.add_argument('--dest-file', dest='dest_file', action='store',default=None, help='Output file name (if write-to-file is set to single)')
-group.add_argument('--dest-extension', dest='dest_extension', action='store',default=None, help='Output file extension (if write-to-file is set to single)')
+group.add_argument('--dest-file', dest='dest_file', action='store',
+                   default=XOSProcessorArgs.default_dest_file, help='Output file name (if write-to-file is set to single)')
+group.add_argument('--dest-extension', dest='dest_extension', action='store',
+                   default=XOSProcessorArgs.default_dest_extension, help='Output file extension (if write-to-file is set to single)')
 
 group = parse.add_mutually_exclusive_group(required=True)
-group.add_argument('--target', dest='target', action='store',default=None, help='Output format, corresponding to <output>.yaml file')
-group.add_argument('--checkers', dest='checkers', action='store', default=None, help='Comma-separated list of static checkers')
+group.add_argument('--target', dest='target', action='store',
+                   default=XOSProcessorArgs.default_target, help='Output format, corresponding to <output>.yaml file')
+group.add_argument('--checkers', dest='checkers', action='store',
+                   default=XOSProcessorArgs.default_checkers, help='Comma-separated list of static checkers')
 
 parse.add_argument('files', metavar='<input file>', nargs='+', action='store', help='xproto files to compile')
 
diff --git a/xos/coreapi/dynamicbuild.py b/xos/coreapi/dynamicbuild.py
index 37b5af2..ddf14d3 100644
--- a/xos/coreapi/dynamicbuild.py
+++ b/xos/coreapi/dynamicbuild.py
@@ -18,7 +18,7 @@
 import os
 import shutil
 import tempfile
-from xosgenx.generator import XOSProcessor
+from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 
 from xosconfig import Config
 from multistructlog import create_logger
@@ -227,17 +227,12 @@
 
         xproto_filenames = [os.path.join(manifest["dir"], x["filename"]) for x in manifest["xprotos"]]
 
-        class Args:
-            pass
-
         # Generate models
         is_service = manifest["name"] != 'core'
 
-        args = Args()
-        args.verbosity = 0
-        args.output = manifest["dest_dir"]
-        args.attic = os.path.join(manifest["dir"], 'attic')
-        args.files = xproto_filenames
+        args = XOSProcessorArgs(output = manifest["dest_dir"],
+                                attic = os.path.join(manifest["dir"], 'attic'),
+                                files = xproto_filenames)
 
         if is_service:
             args.target = 'service.xtarget'
@@ -250,15 +245,13 @@
         XOSProcessor.process(args)
 
         # Generate security checks
-        class SecurityArgs:
-            verbosity = 0
-            output = manifest["dest_dir"]
-            target = 'django-security.xtarget'
-            dest_file = 'security.py'
-            write_to_file = 'single'
-            files = xproto_filenames
+        security_args = XOSProcessorArgs(output = manifest["dest_dir"],
+                                         target = 'django-security.xtarget',
+                                         dest_file = 'security.py',
+                                         write_to_file = 'single',
+                                         files = xproto_filenames)
 
-        XOSProcessor.process(SecurityArgs())
+        XOSProcessor.process(security_args)
 
         # Generate __init__.py
         if manifest["name"] == "core":