copied everything over from 2012 and removed all of the actual robot code except the drivetrain stuff


git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4078 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/build/act_builder.rb b/aos/build/act_builder.rb
new file mode 100644
index 0000000..d98549c
--- /dev/null
+++ b/aos/build/act_builder.rb
@@ -0,0 +1,242 @@
+require File.dirname(__FILE__) + "/parser.rb"
+
+module Contents
+	class HasEntry < SimpleField
+	end
+	class Priority < SimpleField
+		def initialize
+			super :is_number
+		end
+	end
+
+	class OutputFile
+		def fillin_initials
+			@args_struct = nil	# string
+			@status_struct = nil 	# string
+			@action_name = nil	# string
+			@actions = []
+			@has = []
+		end
+		def fillin_defaults
+			@action_name = @base unless @action_name
+			@actions.push @action_name if @actions.empty?
+			@args_struct.add_hidden_field 'timespec', 'set_time'
+			@status_struct.add_hidden_field 'timespec', 'set_time'
+		end
+		def parse_token token, tokenizer
+			case token
+			when 'args'
+				throw :syntax_error, '"args" redefined' if @args_struct
+				@args_struct = Struct.parse tokenizer
+			when 'status'
+				throw :syntax_error, '"status" redefined' if @status_struct
+				@status_struct = Struct.parse tokenizer
+			when 'action_name'
+				throw :syntax_error, '"action_name" redefined' if @action_name
+				@action_name = NameField.parse tokenizer
+			when 'async_queue'
+				@actions.push(NameField.parse tokenizer)
+			when 'has'
+				@has.push(HasEntry.parse tokenizer)
+			when 'priority'
+				throw :syntax_error, '"priority" redefined' if @priority
+				@priority = Priority.parse tokenizer
+			else
+				throw :syntax_error, "unsupported field \"#{token}\""
+			end
+		end
+		def check_format tokenizer
+			tokenizer.item_missing("args") unless @args_struct
+			tokenizer.item_missing("status") unless @status_struct
+			tokenizer.item_missing("priority") unless @priority
+		end
+
+		def superclass
+			"aos::AsyncAction<#{@args_struct.name}, #{@status_struct.name}>"
+		end
+		def impl_class
+			@action_name + '_t'
+		end
+		def handle_class
+			@action_name + 'Handle'
+		end
+		def write_header
+			f = File.open(filename('h'), "w+")
+			f.puts <<END
+#ifndef AOS_GENERATED_ASYNC_ACTION_#{impl_class}_H_
+#define AOS_GENERATED_ASYNC_ACTION_#{impl_class}_H_
+// This file is autogenerated.
+// Edit #{@filename} to change its contents.
+
+#include "aos/common/messages/QueueHolder.h"
+#include "aos/atom_code/async_action/AsyncAction.h"
+#include "aos/atom_code/async_action/AsyncActionHandle.h"
+
+namespace #{$namespace} {
+#{@args_struct.writer}
+#{@status_struct.writer}
+	class #{impl_class} : public #{superclass} {
+		virtual void DoAction(#{@args_struct.name} &args __attribute__((unused))){
+			DoAction(#{@args_struct.params_from 'args'});
+		}
+		void DoAction(#{@args_struct.params});
+#{@has.grep('OnStart').empty? ? '' : "virtual void OnStart();"}
+#{@has.grep('OnEnd').empty? ? '' : "virtual void OnEnd();"}
+		using #{superclass}::PostStatus;
+		inline void PostStatus(#{@status_struct.params}){
+			#{@status_struct.copy_params_into 'new_stat'}
+			PostStatus(new_stat);
+		}
+		public:
+		#{impl_class}(const std::string name) : #{superclass}(name) {}
+#ifdef AOS_#{impl_class}_HEADER_FRAG
+		AOS_#{impl_class}_HEADER_FRAG
+#endif
+	};
+
+	class #{handle_class} : public aos::AsyncActionHandle {
+		friend class ::AsyncActionTest;
+		private:
+			const std::string name;
+			#{superclass} *instance;
+			#{superclass} &GetInstance(){
+				if(instance == NULL){
+					instance = new #{superclass}(name);
+				}
+				return *instance;
+			}
+			#{@status_struct.name} temp_status;
+			void Free(){
+				if(instance != NULL){
+					delete instance;
+					instance = NULL;
+				}
+			}
+		public:
+			inline uint16_t Start(#{@args_struct.name} &args){
+				return GetInstance().Start(args);
+			}
+			inline uint16_t Start(#{@args_struct.params}){
+				#{@args_struct.copy_params_into 'args_struct'}
+				return Start(args_struct);
+			}
+			inline void Execute(#{@args_struct.name} &args){
+				GetInstance().Join(GetInstance().Start(args));
+			}
+			inline bool Execute(#{@args_struct.params}){
+				#{@args_struct.copy_params_into 'args_struct'}
+				Execute(args_struct);
+				return GetStatus();
+			}
+			inline bool IsDone(){
+				return GetInstance().IsDone();
+			}
+			inline bool IsDone(int32_t count){
+				return GetInstance().IsDone(count);
+			}
+			inline uint16_t Join(){
+				return GetInstance().Join();
+			}
+			inline uint16_t Join(int32_t count){
+				return GetInstance().Join(count);
+			}
+			inline bool GetStatus(#{@status_struct.name} &status_out) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetStatus(status_out);
+			}
+			inline bool GetStatus(#{@status_struct.name} &status_out, int32_t count) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetStatus(status_out, count);
+			}
+			inline bool GetStatus() __attribute__ ((warn_unused_result)){
+				return GetInstance().GetStatus(temp_status);
+			}
+			inline bool GetStatus(int32_t count) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetStatus(temp_status, count);
+			}
+			inline bool GetNextStatus(#{@status_struct.name} &status_out) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetNextStatus(status_out);
+			}
+			inline bool GetNextStatus(#{@status_struct.name} &status_out, int32_t count) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetNextStatus(status_out, count);
+			}
+			inline bool GetNextStatus() __attribute__ ((warn_unused_result)){
+				return GetInstance().GetNextStatus(temp_status);
+			}
+			inline bool GetNextStatus(int32_t count) __attribute__ ((warn_unused_result)){
+				return GetInstance().GetNextStatus(temp_status, count);
+			}
+			inline const #{@status_struct.name} &GetLastStatus(){
+				return temp_status;
+			}
+			inline void Stop(){
+				GetInstance().Stop();
+			}
+			inline void Stop(int32_t count){
+				GetInstance().Stop(count);
+			}
+
+			#{handle_class}(const std::string name) : name(name), instance(NULL) {}
+	};
+#{(@actions.collect do |a|
+<<END2
+	extern #{handle_class} #{a};
+END2
+end).join('')}
+
+} // namespace #{$namespace}
+
+#endif
+END
+			f.close
+		end
+		def write_cpp
+			f = File.open(filename('cc'), "w+")
+f.puts <<END
+// This file is autogenerated.
+// Edit #{@filename} to change its contents.
+
+#include "#{filename 'h'}"
+
+namespace #{$namespace} {
+
+#{(@actions.collect do |a|
+<<END2
+#{handle_class} #{a}("#{a}");
+END2
+end).join("\n")}
+
+} // namespace #{$namespace}
+END
+			f.close
+		end
+		def write_main
+			f = File.open(filename('main'), "w+")
+f.puts <<END
+// This file is autogenerated.
+// Edit #{@filename} to change its contents.
+
+#include "#{filename 'h'}"
+#include "aos/atom_code/async_action/AsyncActionRunner.h"
+#include <string>
+#include <cstring>
+#include <iostream>
+
+int main(int argc, char **argv) {
+	aos::Init();
+
+	std::string name = "#{@action_name}";
+	if(argc > 1)
+		name = std::string(argv[1]);
+	#{$namespace}::#{impl_class} action(name);
+	int rv = aos::AsyncActionRunner::Run(action, #{@priority});
+
+	aos::Cleanup();
+	return rv;
+}
+END
+			f.close
+		end
+	end
+end
+
+write_file_out
+
diff --git a/aos/build/aos.gyp b/aos/build/aos.gyp
new file mode 100644
index 0000000..b6bd3ee
--- /dev/null
+++ b/aos/build/aos.gyp
@@ -0,0 +1,156 @@
+# This file has all of the aos targets.
+# For the cRIO, shared_library means to build a .out file, NOT a shared library.
+#   This means that depending on shared libraries doesn't work very well.
+# Shared libraries don't seem to be supported by the powerpc-wrs-vxworks
+# tools and gyp doesn't like a static_library that depends on static_librarys.
+{
+  'variables': {
+    'conditions': [
+      ['OS=="crio"', {
+          'libaos_source_files': [
+            '<!@(find <(AOS)/crio/controls <(AOS)/crio/messages <(AOS)/crio/motor_server <(AOS)/crio/shared_libs -name *.c -or -name *.cpp -or -name *.cc)',
+            '<(AOS)/crio/Talon.cpp',
+            '<(AOS)/common/die.cc',
+          ],
+        }, {
+          'libaos_source_files': [
+            '<(AOS)/atom_code/camera/Buffers.cpp',
+            '<(AOS)/atom_code/async_action/AsyncAction_real.cpp',
+            '<(AOS)/atom_code/init.cc',
+            '<(AOS)/atom_code/ipc_lib/mutex.cpp',
+            '<(AOS)/common/die.cc',
+          ],
+        }
+      ],
+    ],
+  },
+  'targets': [
+    {
+      'target_name': 'logging',
+      'type': 'static_library',
+      'conditions': [
+        ['OS=="crio"', {
+          'sources': [
+            '<(AOS)/crio/logging/crio_logging.cpp',
+          ],
+          'dependencies': [
+            '<(EXTERNALS):WPILib',
+          ]
+        }, {
+          'sources': [
+            '<(AOS)/atom_code/logging/atom_logging.cpp'
+          ],
+          'dependencies': [
+            '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:ipc_lib',
+          ],
+          'export_dependent_settings': [
+            '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:ipc_lib',
+          ]
+        }],
+      ],
+      'dependencies': [
+        '<(AOS)/common/common.gyp:time',
+      ],
+    },
+    {
+# Private to make Brian happy.  Don't use elsewhere in so targets or risk things
+# breaking.
+      'target_name': 'aos_swig',
+      'type': 'static_library',
+      'sources': [
+        '<(AOS)/aos.swig',
+      ],
+      'variables': {
+        'package': 'aos',
+      },
+      'dependencies': [
+        '<(AOS)/common/common.gyp:queues',
+      ],
+      'includes': ['../build/swig.gypi'],
+    },
+    {
+      'target_name': 'libaos',
+      'type': 'static_library',
+      'sources': ['<@(libaos_source_files)'],
+      'sources/': [['exclude', '_test\.c[cp]*$']],
+      'dependencies': [
+        '<(AOS)/common/messages/messages.gyp:aos_queues',
+        'logging',
+        '<(EXTERNALS):WPILib',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/common/messages/messages.gyp:aos_queues',
+        '<(EXTERNALS):WPILib',
+      ],
+      'conditions': [
+        ['OS=="atom"', {
+          'dependencies': [
+            '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:ipc_lib',
+          ],
+        }]
+      ],
+    },
+    {
+      'target_name': 'aos_shared_lib',
+      'type': 'shared_library',
+      'sources': ['<@(libaos_source_files)'],
+      'sources/': [['exclude', '_test\.c[cp]*$']],
+      'variables': {'no_rsync': 1},
+      'dependencies': [
+        '<(AOS)/common/messages/messages.gyp:queues_so',
+        '<(AOS)/common/common.gyp:queues',
+        'aos_swig',
+        '<(EXTERNALS):WPILib',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/common/messages/messages.gyp:queues_so',
+        '<(EXTERNALS):WPILib',
+        'aos_swig',
+      ],
+      'direct_dependent_settings': {
+        'variables': {
+          'jni_libs': [
+            'aos_shared_lib',
+          ],
+        },
+      },
+    },
+    {
+# A target that has all the same dependencies as libaos and aos_shared_lib
+#   without any queues so that the queues can get the necessary headers without
+#   creating circular dependencies.
+      'target_name': 'aos_internal_nolib',
+      'type': 'none',
+      'dependencies': [
+        'aos/ResourceList.h',
+        '<(EXTERNALS):WPILib',
+      ],
+      'export_dependent_settings': [
+        'aos/ResourceList.h',
+        '<(EXTERNALS):WPILib',
+      ],
+    },
+    {
+      'target_name': 'aos/ResourceList.h',
+      'type': 'static_library',
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '<(SHARED_INTERMEDIATE_DIR)/ResourceList',
+        ],
+      },
+      'hard_dependency': 1,
+      'actions': [
+        {
+          'variables': {
+            'script': '<(AOS)/build/gen_resource_list.rb'
+          },
+          'action_name': 'gen_aos_ResourceList_h',
+          'inputs': ['<(script)'],
+          'outputs': ['<(SHARED_INTERMEDIATE_DIR)/ResourceList/aos/ResourceList.h'],
+          'message': 'Generating',
+          'action': ['ruby', '<(script)', '<(SHARED_INTERMEDIATE_DIR)/ResourceList/aos',],
+        },
+      ],
+    },
+  ],
+}
diff --git a/aos/build/aos.gypi b/aos/build/aos.gypi
new file mode 100644
index 0000000..08bf975
--- /dev/null
+++ b/aos/build/aos.gypi
@@ -0,0 +1,194 @@
+# This file gets passed to gyp with -I so that it gets included everywhere.
+{
+  'variables': {
+    'AOS': '<(DEPTH)/aos',
+# A directory with everything in it ignored from source control.
+    'TMPDIR': '<(DEPTH)/aos/build/temp',
+    'aos_abs': '<!(readlink -f <(DEPTH)/aos)', # for use in non-path contexts
+# the .gyp file that has targets for the various external libraries
+    'EXTERNALS': '<(AOS)/build/externals.gyp',
+# the directory that gets rsynced to the atom
+    'rsync_dir': '<(PRODUCT_DIR)/outputs',
+# The directory that loadable_module and shared_library targets get put into
+# There's a target_conditions that puts loadable_modules here and
+#   shared_librarys automatically get put here.
+    'so_dir': '<(PRODUCT_DIR)/lib',
+# the directory that executables that depend on <(EXTERNALS):gtest get put into
+    'test_dir': '<(PRODUCT_DIR)/tests',
+# 'executable' for the atom and 'static_library' for the cRIO
+# Useful for targets that should either be an executable or get compiled into
+# a .out file depending on the current platform.
+#   'aos_target': platform-dependent,
+  },
+  'conditions': [
+    ['OS=="crio"', {
+        'make_global_settings': [
+          ['CC', '<!(which powerpc-wrs-vxworks-gcc)'],
+          ['CXX', '<!(which powerpc-wrs-vxworks-g++)'],
+          ['LD', '<!(readlink -f <(AOS)/build/crio_link_out)'],
+          #['LD', 'powerpc-wrs-vxworks-ld'],
+          #['AR', '<!(which powerpc-wrs-vxworks-ar)'],
+          #['NM', '<!(which powerpc-wrs-vxworks-nm)'],
+        ],
+        'variables': {
+          'aos_target': 'static_library',
+        },
+      }, {
+        'variables': {
+          'aos_target': 'executable',
+        },
+      }
+    ],
+  ],
+  'target_defaults': {
+    'defines': [
+      '__STDC_FORMAT_MACROS',
+      '_FORTIFY_SOURCE=2',
+    ],
+    'ldflags': [
+      '-pipe',
+    ],
+    'cflags': [
+      '-pipe',
+
+      '-Wall',
+      '-Wextra',
+      '-Wswitch-enum',
+      '-Wpointer-arith',
+      '-Wstrict-aliasing=2',
+      '-Wcast-qual',
+      '-Wcast-align',
+      '-Wwrite-strings',
+      '-Wtype-limits',
+      '-Wsign-compare',
+      '-Wformat=2',
+      '-Werror',
+    ],
+    'cflags_c': [
+      '-std=gnu99',
+    ],
+    'cflags_cc': [
+      '-std=gnu++0x',
+    ],
+    'include_dirs': [
+      '<(DEPTH)',
+    ],
+    'conditions': [
+      ['DEBUG=="yes"', {
+          'cflags': [
+            '-ggdb3',
+            '-O0',
+          ],
+          'ldflags': [
+            '-O3',
+          ],
+        }, {
+          'cflags': [
+            '-O3',
+          ],
+          'conditions': [['OS=="crio"', {
+              'cflags': [
+                '-fstrength-reduce',
+                '-fno-builtin',
+                '-fno-strict-aliasing',
+              ],
+            }, {
+              'cflags': [
+                # core2 says the same stuff as atom in the gcc docs but is supported by 4.4.5
+                '-march=core2',
+                '-mtune=generic',
+                '-msse3',
+                '-mfpmath=sse',
+
+                '-fstack-protector',
+              ],
+            }
+          ]],
+        }
+      ],
+      ['OS=="crio"', {
+          'target_conditions': [
+            ['_type=="shared_library"', {
+                'ldflags': [
+                  '-r',
+                  '-nostdlib',
+                  '-Wl,-X',
+                ],
+              }
+            ],
+          ],
+          'ldflags': [
+            '-mcpu=603',
+            '-mstrict-align',
+            '-mlongcall',
+          ],
+          'cflags': [
+            '-mcpu=603',
+            '-mstrict-align',
+            '-mlongcall',
+            '-isystem', '<(aos_abs)/externals/gccdist/WindRiver/gnu/3.4.4-vxworks-6.3/x86-win32/lib/gcc/powerpc-wrs-vxworks/3.4.4/include/',
+            '-isystem', '<(aos_abs)/externals/gccdist/WindRiver/vxworks-6.3/target/h/',
+            '-isystem', '<(aos_abs)/externals/gccdist/WindRiver/gnu/3.4.4-vxworks-6.3/x86-win32/include/c++/3.4.4/',
+            '-isystem', '<(aos_abs)/externals/gccdist/WindRiver/gnu/3.4.4-vxworks-6.3/x86-win32/include/c++/3.4.4/powerpc-wrs-vxworks/',
+            '-isystem', '<(WIND_BASE)/target/h',
+            '-isystem', '<(WIND_BASE)/target/h/wrn/coreip',
+          ],
+          'defines': [
+            'CPU=PPC603',
+            'TOOL_FAMILY=gnu',
+            'TOOL=gnu',
+            '_WRS_KERNEL',
+            '__PPC__',
+# This tells eigen to not do anything with alignment at all. See
+# <http://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html> for
+# details. It really doesn't like to work without this.
+            'EIGEN_DONT_ALIGN',
+# prevent the vxworks system headers from being dumb and #defining min and max
+            'NOMINMAX',
+          ],
+        }, {
+          'variables': {
+            'no_rsync%': 0,
+          },
+          'target_conditions': [
+# default to putting outputs into rsync_dir
+            ['no_rsync==0 and _type!="static_library"', {
+                'product_dir': '<(rsync_dir)',
+              },
+            ],
+            ['_type=="loadable_module"', {
+                'product_dir': '<(so_dir)',
+              }
+            ],
+            ['_type=="loadable_module" or _type=="shared_library"', {
+                'ldflags': [
+# Support loading other shared objects that are in the same directory but not
+#   the shared object load path. Required for using the swig-generated libs.
+                  '-Wl,-rpath=\\$$ORIGIN',
+                ],
+              }
+            ],
+          ],
+          'ldflags': [
+            '-pthread',
+            '-m32',
+          ],
+          'library_dirs': [
+            '/usr/lib32',
+          ],
+          'cflags': [
+            '-pthread',
+            '-m32',
+          ],
+          'defines': [
+            '_LARGEFILE64_SOURCE',
+          ],
+          'libraries': [
+            '-lm',
+            '-lrt',
+          ],
+        }
+      ]
+    ],
+  },
+}
diff --git a/aos/build/aos_all.gyp b/aos/build/aos_all.gyp
new file mode 100644
index 0000000..a65909d
--- /dev/null
+++ b/aos/build/aos_all.gyp
@@ -0,0 +1,48 @@
+# This file has the executables etc that AOS builds.
+# User .gyp files for the atom should depend on :Atom.
+# User .gyp files for the crio should depend on :Crio.
+{
+  'targets': [
+    {
+      'target_name': 'Atom',
+      'type': 'none',
+      'variables': {
+        'no_rsync': 1,
+      },
+      'dependencies': [
+        '../atom_code/camera/camera.gyp:CameraHTTPStreamer',
+        '../atom_code/camera/camera.gyp:CameraReader',
+        '../atom_code/core/core.gyp:*',
+        #'../atom_code/async_action:*', # TODO(brians) fix this broken test
+        '../atom_code/ipc_lib/ipc_lib.gyp:*',
+        '../atom_code/starter/starter.gyp:*',
+        '../crio/crio.gyp:unsafe_queue_test',
+        '../common/common.gyp:queue_test',
+        #'../common/messages/messages.gyp:*', # TODO(brians) did this test ever exist?
+        '../atom_code/logging/logging.gyp:*',
+        '../common/common.gyp:die_test',
+        ':Common',
+      ],
+    },
+    {
+      'target_name': 'Crio',
+      'type': 'none',
+      'dependencies': [
+        '../crio/googletest/googletest.gyp:*',
+        ':Common',
+      ],
+    },
+    {
+      'target_name': 'Common',
+      'type': 'none',
+      'variables': {
+        'no_rsync': 1,
+      },
+      'dependencies': [
+        '<(AOS)/common/common.gyp:type_traits_test',
+        '<(AOS)/common/common.gyp:time_test',
+        '<(AOS)/common/common.gyp:mutex_test',
+      ],
+    },
+  ],
+}
diff --git a/aos/build/build.sh b/aos/build/build.sh
new file mode 100755
index 0000000..7c0362b
--- /dev/null
+++ b/aos/build/build.sh
@@ -0,0 +1,81 @@
+#!/bin/bash -e
+#set -x
+
+# This file should be called to build the code.
+# Usage: build.sh platform main_file.gyp debug [action]
+
+PLATFORM=$1
+GYP_MAIN=$2
+DEBUG=$3
+ACTION=$4
+
+export WIND_BASE=${WIND_BASE:-"/usr/local/powerpc-wrs-vxworks/wind_base"}
+
+[ ${PLATFORM} == "crio" -o ${PLATFORM} == "atom" ] || ( echo Platform "(${PLATFORM})" must be '"crio" or "atom"'. ; exit 1 )
+[ ${DEBUG} == "yes" -o ${DEBUG} == "no" ] || ( echo Debug "(${DEBUG})" must be '"yes" or "no"'. ; exit 1 )
+
+AOS=`dirname $0`/..
+NINJA_DIR=${AOS}/externals/ninja
+NINJA=${NINJA_DIR}/ninja
+# From chromium@154360:trunk/src/DEPS.
+GYP_REVISION=1488
+GYP_DIR=${AOS}/externals/gyp-${GYP_REVISION}
+GYP=${GYP_DIR}/gyp
+
+OUTDIR=${AOS}/../out_${PLATFORM}
+BUILD_NINJA=${OUTDIR}/Default/build.ninja
+
+[ -d ${NINJA_DIR} ] || git clone --branch release https://github.com/martine/ninja.git ${NINJA_DIR}
+[ -x ${NINJA} ] || ${NINJA_DIR}/bootstrap.py
+[ -d ${GYP_DIR} ] || ( svn co http://gyp.googlecode.com/svn/trunk -r ${GYP_REVISION} ${GYP_DIR} && patch -p1 -d ${GYP_DIR} < ${AOS}/externals/gyp.patch )
+${AOS}/build/download_externals.sh
+
+# The exciting quoting is so that it ends up with -DWHATEVER='"'`a command`'"'.
+# The '"' at either end is so that it creates a string constant when expanded
+#   in the C/C++ code.
+COMMONFLAGS='-DLOG_SOURCENAME='"'\"'"'`basename $in`'"'\"' "
+if [ ${PLATFORM} == crio ]; then
+  COMMONFLAGS+='-DAOS_INITNAME=aos_init_function_`readlink -f $out | sed \"s/[\/.]/_/g\"` '
+fi
+
+if [[ "${ACTION}" != "clean" && ( ! -d ${OUTDIR} || -n \
+  			"`find ${AOS}/.. -newer ${BUILD_NINJA} \( -name '*.gyp' -or -name '*.gypi' \)`" ) ]]; then
+  ${GYP} \
+    --check --depth=${AOS}/.. --no-circular-check -f ninja \
+    -I${AOS}/build/aos.gypi -Goutput_dir=out_${PLATFORM} \
+    -DOS=${PLATFORM} -DWIND_BASE=${WIND_BASE} -DDEBUG=${DEBUG} \
+    ${GYP_MAIN}
+  # Have to substitute "command = $compiler" so that it doesn't try to
+  #   substitute them in the linker commands, where it doesn't work.
+  sed -i "s:command = \$cc:\\0 ${COMMONFLAGS}:g ; \
+    s:command = \$cxx:\\0 ${COMMONFLAGS}:g" \
+    ${BUILD_NINJA}
+  if [ ${PLATFORM} == crio ]; then
+    sed -i 's/nm -gD/nm/g' ${BUILD_NINJA}
+  fi
+fi
+
+if [ "${ACTION}" == "clean" ]; then
+  rm -r ${OUTDIR}
+else
+  if [ "${ACTION}" != "deploy" -a "${ACTION}" != "tests" ]; then
+					GYP_ACTION=${ACTION}
+	else
+					GYP_ACTION=
+	fi
+  ${NINJA} -C ${OUTDIR}/Default ${GYP_ACTION}
+  case ${ACTION} in
+    deploy)
+      [ ${PLATFORM} == atom ] && \
+        rsync --progress -t -r --rsync-path=/home/driver/bin/rsync \
+        ${OUTDIR}/Default/outputs/* \
+        driver@fitpc:/home/driver/robot_code/bin
+      [ ${PLATFORM} == crio ] && \
+        ncftpput robot / \
+        ${OUTDIR}/Default/lib/FRC_UserProgram.out
+      ;;
+    tests)
+      find ${OUTDIR}/Default/tests -executable -exec {} \;
+      ;;
+  esac
+fi
diff --git a/aos/build/create_aos_ctdt.sh b/aos/build/create_aos_ctdt.sh
new file mode 100755
index 0000000..63c927c
--- /dev/null
+++ b/aos/build/create_aos_ctdt.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+echo '#include "aos/crio/aos_ctdt.h"'
+calls=''
+for symbol in `cat - | awk '{ print $NF }' | grep '^aos_init_function_'`; do
+	echo "void $symbol();"
+	calls="$calls$symbol();\n"
+done
+echo 'void aos_call_init_functions() {'
+echo -e $calls
+echo '}'
+
diff --git a/aos/build/create_jar b/aos/build/create_jar
new file mode 100755
index 0000000..2ef496e
--- /dev/null
+++ b/aos/build/create_jar
@@ -0,0 +1,29 @@
+#!/bin/bash
+source `dirname $0`/jdk_tools_common
+
+# This is a helper script that compiles java files into a jar.
+
+SOURCEFILEPARENTDIRS=`echo $4 | tr -d '"'`
+SOURCEFILEDIRS=`echo $1 | tr -d '"'`
+[ -n "${SOURCEFILEPARENTDIRS}" ] && SOURCEFILEDIRS+=" `find ${SOURCEFILEPARENTDIRS} -type d -maxdepth 1`"
+SOURCEFILES=`find ${SOURCEFILEDIRS} -name *.java`
+MANIFEST_FILE=$5
+OUTPUT_JAR=$6
+HEADER_DIR=$7
+GEN_HEADERS=$8
+
+CLASSFILES_DIR=${TMPDIR}/classfiles
+
+[ -a ${CLASSFILES_DIR} ] && rm -r ${CLASSFILES_DIR}
+mkdir ${CLASSFILES_DIR}
+[ -a ${HEADER_DIR} ] && rm -r ${HEADER_DIR}
+mkdir -p ${HEADER_DIR}
+
+javac -d ${CLASSFILES_DIR} -classpath "${EXTRA_CLASSPATH}" ${SOURCEFILES}
+
+jar cfm ${OUTPUT_JAR} ${MANIFEST_FILE} \
+  `find ${CLASSFILES_DIR} -name *.class | \
+  sed "s:${CLASSFILES_DIR}/\(.*\):-C ${CLASSFILES_DIR} \1:g"`
+
+[ -z ${GEN_HEADERS} ] || javah -d ${HEADER_DIR} \
+  -classpath "${EXTRA_CLASSPATH}:${OUTPUT_JAR}" ${GEN_HEADERS}
diff --git a/aos/build/create_onejar b/aos/build/create_onejar
new file mode 100755
index 0000000..aa7ecd5
--- /dev/null
+++ b/aos/build/create_onejar
@@ -0,0 +1,26 @@
+#!/bin/bash
+source `dirname $0`/jdk_tools_common
+
+# This is a helper script that puts jars into a OneJAR package.
+
+MAIN_JAR=$1
+OUTPUT_ONEJAR=$4
+ONEJAR_JAR=$5
+SHARED_OBJECTS=$6
+
+JAR_DIR=${TMPDIR}/jardir
+
+# the dir name in the jar under which shared objects get put
+BINLIB_DIR=so_libs
+
+[ -a ${JAR_DIR} ] && rm -r ${JAR_DIR}
+mkdir ${JAR_DIR} ${JAR_DIR}/main ${JAR_DIR}/lib ${JAR_DIR}/${BINLIB_DIR}
+
+cp ${EXTRA_JARS} ${JAR_DIR}/lib
+cp ${SHARED_OBJECTS} ${JAR_DIR}/${BINLIB_DIR}
+cp ${MAIN_JAR} ${JAR_DIR}/main/main.jar
+
+unzip -q -d ${JAR_DIR} ${ONEJAR_JAR}
+cp ${JAR_DIR}/boot-manifest.mf ${TMPDIR}/manifest.mf
+echo "One-Jar-Expand: ${BINLIB_DIR}" >> ${TMPDIR}/manifest.mf
+jar cfm ${OUTPUT_ONEJAR} ${TMPDIR}/manifest.mf -C ${JAR_DIR} .
diff --git a/aos/build/crio_link_out b/aos/build/crio_link_out
new file mode 100755
index 0000000..eef549b
--- /dev/null
+++ b/aos/build/crio_link_out
@@ -0,0 +1,26 @@
+#!/bin/bash -e
+
+# This is a helper script that compiles .out files for the cRIO. It is designed
+# to be called as a replacement for g++ being used as a linker.
+
+# All the flags except -shared.
+INPUTS_FLAGS=`echo "$@" | sed 's/-shared//g'`
+# The arguments after any -o flags.
+OUTPUT=`echo ${INPUTS_FLAGS} | awk \
+  'BEGIN { RS=" " }; output { print ; output = 0 }; /-o/ { output = 1 }'`
+# All arguments that don't start with a - and aren't ${OUTPUT}.
+#INPUTS=`echo ${INPUTS_FLAGS} | sed "s:-[^ ]*::g; s:${OUTPUT}::g;"`
+INPUTS=`echo ${INPUTS_FLAGS} | awk \
+  'BEGIN { RS=" " }; /-Wl,--no-whole-archive/ { output = 0 }; \
+  output { print }; \
+  /-Wl,--whole-archive/ { output = 1 }'`
+TEMPDIR=`dirname ${OUTPUT}`
+AOS=`dirname $0`/..
+powerpc-wrs-vxworks-nm ${INPUTS} | \
+  tclsh ${WIND_BASE}/host/resource/hutils/tcl/munch.tcl -c ppc > ${TEMPDIR}/ctdt.c
+powerpc-wrs-vxworks-gcc -I${AOS}/.. -c ${TEMPDIR}/ctdt.c -o ${TEMPDIR}/ctdt.o
+powerpc-wrs-vxworks-nm ${INPUTS} | \
+  ${AOS}/build/create_aos_ctdt.sh > ${TEMPDIR}/aos_ctdt.c
+powerpc-wrs-vxworks-gcc -I${AOS}/.. -c ${TEMPDIR}/aos_ctdt.c -o ${TEMPDIR}/aos_ctdt.o
+powerpc-wrs-vxworks-g++ ${INPUTS_FLAGS} ${TEMPDIR}/ctdt.o ${TEMPDIR}/aos_ctdt.o
+ln -f ${OUTPUT} `echo ${OUTPUT} | sed 's/lib\([A-Za-z0-9_]*\)\.so$/\1.out/'`
diff --git a/aos/build/download_externals.sh b/aos/build/download_externals.sh
new file mode 100755
index 0000000..ef843e1
--- /dev/null
+++ b/aos/build/download_externals.sh
@@ -0,0 +1,62 @@
+#!/bin/bash -e
+
+AOS=`dirname $0`/..
+EXTERNALS=${AOS}/externals
+
+# get gccdist
+GCCDIST=${EXTERNALS}/gccdist
+[ -f ${GCCDIST}.zip ] || wget ftp://ftp.ni.com/pub/devzone/tut/updated_vxworks63gccdist.zip -O ${GCCDIST}.zip
+[ -d ${GCCDIST} ] || ( cd ${EXTERNALS} && unzip -q ${GCCDIST}.zip )
+
+# get eigen
+EIGEN_VERSION=3.0.5
+EIGEN_DIR=${EXTERNALS}/eigen-${EIGEN_VERSION}
+[ -f ${EIGEN_DIR}.tar.bz2 ] || wget http://bitbucket.org/eigen/eigen/get/${EIGEN_VERSION}.tar.bz2 -O ${EIGEN_DIR}.tar.bz2
+[ -d ${EIGEN_DIR} ] || ( mkdir ${EIGEN_DIR} && tar --strip-components=1 -C ${EIGEN_DIR} -xf ${EIGEN_DIR}.tar.bz2 )
+
+# get the javacv binaries
+JAVACV_VERSION=0.2
+JAVACV_DIR=${EXTERNALS}/javacv-bin
+JAVACV_ZIP=${EXTERNALS}/javacv-${JAVACV_VERSION}-bin.zip
+[ -f ${JAVACV_ZIP} ] || wget http://javacv.googlecode.com/files/javacv-${JAVACV_VERSION}-bin.zip -O ${JAVACV_ZIP}
+[ -d ${JAVACV_DIR} ] || ( cd ${EXTERNALS} && unzip ${JAVACV_ZIP} )
+
+# get the simple one-jar template jar
+ONEJAR_VERSION=0.97
+ONEJAR_JAR=${EXTERNALS}/one-jar-boot-${ONEJAR_VERSION}.jar
+[ -f ${ONEJAR_JAR} ] || wget http://sourceforge.net/projects/one-jar/files/one-jar/one-jar-${ONEJAR_VERSION}/one-jar-boot-${ONEJAR_VERSION}.jar/download -O ${ONEJAR_JAR}
+
+# get and build libjpeg
+LIBJPEG_VERSION=8d
+LIBJPEG_DIR=${EXTERNALS}/jpeg-${LIBJPEG_VERSION}
+# NOTE: this directory ends up in #include names
+LIBJPEG_PREFIX=${EXTERNALS}/libjpeg
+LIBJPEG_LIB=${LIBJPEG_PREFIX}/lib/libjpeg.a
+LIBJPEG_TAR=${EXTERNALS}/jpegsrc.v${LIBJPEG_VERSION}.tar.gz
+[ -f ${LIBJPEG_TAR} ] || wget http://www.ijg.org/files/jpegsrc.v${LIBJPEG_VERSION}.tar.gz -O ${LIBJPEG_TAR}
+[ -d ${LIBJPEG_DIR} ] || ( mkdir ${LIBJPEG_DIR} && tar --strip-components=1 -C ${LIBJPEG_DIR} -xf ${LIBJPEG_TAR} )
+[ -f ${LIBJPEG_LIB} ] || env -i PATH="${PATH}" bash -c "cd ${LIBJPEG_DIR} && CFLAGS='-m32' ./configure --disable-shared --prefix=`readlink -f ${LIBJPEG_PREFIX}` && make && make install"
+
+# get gtest
+GTEST_VERSION=1.6.0
+GTEST_DIR=${EXTERNALS}/gtest-${GTEST_VERSION}-p1
+GTEST_ZIP=${EXTERNALS}/gtest-${GTEST_VERSION}.zip
+TMPDIR=/tmp/$$-aos-tmpdir
+[ -f ${GTEST_ZIP} ] || wget http://googletest.googlecode.com/files/gtest-${GTEST_VERSION}.zip -O ${GTEST_ZIP}
+[ -d ${GTEST_DIR} ] || ( unzip ${GTEST_ZIP} -d ${TMPDIR} && mv ${TMPDIR}/gtest-${GTEST_VERSION} ${GTEST_DIR} && cd ${GTEST_DIR} && patch -p1 < ../gtest.patch )
+
+# get and build ctemplate
+CTEMPLATE_VERSION=2.2
+CTEMPLATE_DIR=${EXTERNALS}/ctemplate-${CTEMPLATE_VERSION}
+CTEMPLATE_PREFIX=${CTEMPLATE_DIR}-prefix
+CTEMPLATE_LIB=${CTEMPLATE_PREFIX}/lib/libctemplate.a
+CTEMPLATE_URL=http://ctemplate.googlecode.com/files
+CTEMPLATE_URL=${CTEMPLATE_URL}/ctemplate-${CTEMPLATE_VERSION}.tar.gz
+[ -f ${CTEMPLATE_DIR}.tar.gz ] || \
+	wget ${CTEMPLATE_URL} -O ${CTEMPLATE_DIR}.tar.gz
+[ -d ${CTEMPLATE_DIR} ] || ( mkdir ${CTEMPLATE_DIR} && tar \
+	--strip-components=1 -C ${CTEMPLATE_DIR} -xf ${CTEMPLATE_DIR}.tar.gz )
+[ -f ${CTEMPLATE_LIB} ] || env -i PATH="${PATH}" \
+	CFLAGS='-m32' CXXFLAGS='-m32' LDFLAGS='-m32' \
+	bash -c "cd ${CTEMPLATE_DIR} && ./configure --disable-shared \
+	--prefix=`readlink -f ${CTEMPLATE_PREFIX}` && make && make install"
diff --git a/aos/build/externals.gyp b/aos/build/externals.gyp
new file mode 100644
index 0000000..2ed0478
--- /dev/null
+++ b/aos/build/externals.gyp
@@ -0,0 +1,133 @@
+# This file has targets for various external libraries.
+# download_externals.sh makes sure that all of them have been downloaded.
+{
+  'variables': {
+    'externals': '<(AOS)/externals',
+    'externals_abs': '<!(readlink -f ../externals)',
+
+# These versions have to be kept in sync with the ones in download_externals.sh.
+    'eigen_version': '3.0.5',
+    'gtest_version': '1.6.0-p1',
+    'onejar_version': '0.97',
+    'ctemplate_version': '2.2',
+  },
+  'targets': [
+    {
+# does nothing when OS!="crio"
+      'target_name': 'WPILib',
+      'type': 'none',
+      'conditions': [['OS=="crio"', {
+            'direct_dependent_settings': {
+              'cflags': [
+                '-isystem', '<(aos_abs)/externals/WPILib',
+              ],
+              'link_settings': {
+                'libraries': [
+                  '<(aos_abs)/externals/WPILib/WPILib.a',
+                ],
+              },
+            },
+        }]],
+    },
+    {
+      'target_name': 'onejar',
+      'type': 'none',
+      'direct_dependent_settings': {
+        'variables': {
+          'onejar_jar': '<(externals_abs)/one-jar-boot-<(onejar_version).jar',
+        },
+      },
+    },
+    {
+      'target_name': 'javacv',
+      'type': 'none',
+      'variables': {
+        'javacv_dir': '<(externals_abs)/javacv-bin',
+      },
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '/usr/lib/jvm/default-java/include',
+          '/usr/lib/jvm/default-java/include/linux',
+        ],
+        'variables': {
+          'classpath': [
+            '<(javacv_dir)/javacv.jar',
+            '<(javacv_dir)/javacpp.jar',
+            '<(javacv_dir)/javacv-linux-x86.jar',
+          ],
+        },
+      },
+    },
+    {
+# TODO(brians) convert this to downloading + building
+      'target_name': 'libevent',
+      'type': 'none',
+      'link_settings': {
+        'libraries': ['-levent'],
+      },
+    },
+    {
+      'target_name': 'eigen',
+      'type': 'none',
+      'direct_dependent_settings': {
+        'include_dirs': ['<(externals)/eigen-<(eigen_version)'],
+      },
+    },
+    {
+      'target_name': 'libjpeg',
+      'type': 'none',
+      'direct_dependent_settings': {
+        'libraries': ['<(externals_abs)/libjpeg/lib/libjpeg.a'],
+      },
+    },
+    {
+      'target_name': 'gtest',
+      'type': 'static_library',
+      'sources': [
+        '<(externals)/gtest-<(gtest_version)/fused-src/gtest/gtest-all.cc',
+      ],
+      'conditions': [['OS=="crio"', {
+            'defines': [
+              'GTEST_HAS_TR1_TUPLE=0',
+              'GTEST_HAS_STREAM_REDIRECTION=0',
+              'GTEST_HAS_POSIX_RE=0', # it only has a broken header...
+            ],
+            'direct_dependent_settings': {
+              'defines': [
+                'GTEST_HAS_TR1_TUPLE=0',
+                'GTEST_HAS_STREAM_REDIRECTION=0',
+                'GTEST_HAS_POSIX_RE=0',
+              ],
+            },
+        }, {
+          'sources': [
+            '<(externals)/gtest-<(gtest_version)/fused-src/gtest/gtest_main.cc',
+          ],
+        }]],
+      'include_dirs': [
+        '<(externals)/gtest-<(gtest_version)',
+        '<(externals)/gtest-<(gtest_version)/include'
+      ],
+      'cflags!': ['-Werror'],
+      'direct_dependent_settings': {
+        'include_dirs': ['<(externals)/gtest-<(gtest_version)/include'],
+        'target_conditions': [
+          ['_type=="executable"', {
+              'product_dir': '<(test_dir)',
+            },
+          ],
+        ],
+      },
+    },
+    {
+      'target_name': 'ctemplate',
+      'type': 'none',
+      'link_settings': {
+        'libraries': ['<(externals)/ctemplate-<(ctemplate_version)-prefix/lib/libctemplate.a'],
+      },
+      'direct_dependent_settings': {
+        'include_dirs': ['<(externals)/ctemplate-<(ctemplate_version)-prefix/include'],
+      },
+    },
+  ],
+}
diff --git a/aos/build/gen_resource_list.rb b/aos/build/gen_resource_list.rb
new file mode 100644
index 0000000..259b438
--- /dev/null
+++ b/aos/build/gen_resource_list.rb
@@ -0,0 +1,36 @@
+outpath = ARGV.shift
+
+outputh = File.new(outpath + '/ResourceList.h', 'w+')
+
+File.open(File.dirname(__FILE__) + '/../atom_code/ipc_lib/resource_list.txt') do |f|
+	outputh.puts <<END
+#ifndef __AOS_RESOURCE_LIST_H_
+#define __AOS_RESOURCE_LIST_H_
+// This file is autogenerated.
+// Edit #{File.expand_path f.path} to change its contents.
+
+#include <stdint.h>
+
+#ifdef __cplusplus // for the c code that just wants to know how long it should be
+namespace aos {
+END
+
+	i = 0
+	f.readlines.each do |l|
+		l = l.chomp
+		outputh.puts "static const uint16_t #{l}(#{i});"
+		i += 1
+	end
+	outputh.puts <<END
+} // namespace aos
+#endif
+
+#define AOS_RESOURCE_NUM #{i}
+
+#endif
+
+END
+end
+
+outputh.close
+
diff --git a/aos/build/java.gypi b/aos/build/java.gypi
new file mode 100644
index 0000000..d832b0a
--- /dev/null
+++ b/aos/build/java.gypi
@@ -0,0 +1,74 @@
+# Include this file in any target that is going to build java files.
+#
+# To use, create a target of the following form:
+# {
+#   'target_name': 'whatever',
+#   'variables': {
+#     'srcdirs': ['.', 'java'],
+#   },
+#   'includes': ['path/to/java.gypi'],
+# }
+# See below for more variables.
+# To make any output jars include some loadable modules, set the 'jni_libs'
+#   variable in 'direct_dependent_settings'. Making this easier causes lots of
+#   recursion issues in gyp.
+#   The dependency on these targets also has to be added manually.
+{
+  'type': 'none',
+  'variables': {
+# The manifest file for creating the jar.
+    'manifest%': '/dev/null',
+# Additional jars/directories to add to the classpath when compiling.
+# This target will automatically add itself to this list for any dependents.
+    'classpath': [],
+# Classes to generate JNI headers for.
+# They will be able to be #included as "jni/package_ClassName.h" by targets
+#   that depend on this one.
+    'gen_headers': [],
+# Like 'srcdirs', except not required to exist at gyp time. However, nothing
+#   here will depend on any files in these directories.
+    'gen_srcdirs': ['/dev/null'],
+# Like 'gen_srcdirs', except all folders that are children of this folder will
+#   be used instead.
+    'gen_srcdir_parents%': [],
+    'srcdirs': ['/dev/null'],
+    'jar_dir': '<(PRODUCT_DIR)/jars',
+    'java_files': '<!(find <(srcdirs) -name *.java)',
+    'create_jar': '<(AOS)/build/create_jar',
+    'out_jar': '<(jar_dir)/<(_target_name).jar',
+    'header_dir': '<(SHARED_INTERMEDIATE_DIR)/jni_headers_<!(pwd | sed s:/:_:g)_<(_target_name)',
+    'no_rsync': 1,
+  },
+  'direct_dependent_settings': {
+    'variables': {
+      'classpath': ['<(out_jar)'],
+    },
+    'include_dirs': [
+      '<(header_dir)',
+    ],
+  },
+  'actions': [
+    {
+      'action_name': 'run javac',
+      'message': 'Compiling java code',
+      'inputs': [
+        '<(create_jar)',
+        '<@(java_files)',
+        '>@(classpath)',
+        '>@(gen_srcdirs)',
+        '>(manifest)',
+      ],
+      'outputs': [
+        '<(out_jar)',
+      ],
+      'action': [
+        '<(create_jar)',
+        '<(srcdirs) <(gen_srcdirs)',
+        '<(INTERMEDIATE_DIR)', '>(classpath)',
+        '>(gen_srcdir_parents)',
+        '>(manifest)', '<(out_jar)',
+        '<(header_dir)/jni', '>(gen_headers)',
+      ],
+    },
+  ],
+}
diff --git a/aos/build/jdk_tools_common b/aos/build/jdk_tools_common
new file mode 100644
index 0000000..3ebfc2f
--- /dev/null
+++ b/aos/build/jdk_tools_common
@@ -0,0 +1,13 @@
+# This file gets sourced by all the shell scripts that use the JDK tools.
+# gyp likes quoting some of the input arguments, but nothing else tolerates it,
+#   so " are removed from various inputs.
+
+set -e # stop on error
+#set -x # echo everything
+
+TMPDIR=$2
+# ${CLASSPATH} is used by the jdk tools
+EXTRA_CLASSPATH=`echo $3 | tr -d '"' | sed 's/ /:/g'`
+EXTRA_JARS=`echo $3 | tr -d '"'`
+
+mkdir -p ${TMPDIR}
diff --git a/aos/build/mkdirswig b/aos/build/mkdirswig
new file mode 100755
index 0000000..83403e4
--- /dev/null
+++ b/aos/build/mkdirswig
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Creates the directory specified by the first argument and runs swig with the
+# rest of the arguments.
+mkdir -p $1
+shift
+swig $@
diff --git a/aos/build/onejar.gypi b/aos/build/onejar.gypi
new file mode 100644
index 0000000..6185f02
--- /dev/null
+++ b/aos/build/onejar.gypi
@@ -0,0 +1,53 @@
+# Include this file in any target that should get packaged with OneJAR.
+#
+# To use, create a target of the following form:
+# {
+#   'target_name': 'whatever',
+#   'variables': {
+#     'main_jar': 'something',
+#   },
+#   'includes': ['path/to/onejar.gypi'],
+# },
+# See below for more variables.
+{
+  'type': 'none',
+  'variables': {
+# The names of loadable_module targets to add to the jar.
+    'jni_libs': [],
+# Additional jars to add to the output.
+# Named this so that targets from java.gypi will add themselves automatically.
+    'classpath': [],
+    'jar_dir': '<(PRODUCT_DIR)/jars',
+    'create_onejar': '<(AOS)/build/create_onejar',
+    'out_onejar': '<(rsync_dir)/<(_target_name).jar',
+    'main_jar_file': '<(jar_dir)/<(main_jar).jar',
+    'shared_objects': ">!(echo '>(jni_libs)' | sed 's:[^ ]*:<(so_dir)/lib\\0.so:g')",
+    'no_rsync': 1,
+  },
+  'dependencies': [
+    '<(EXTERNALS):onejar',
+  ],
+  'product_dir': '<(PRODUCT_DIR)',
+  'actions': [
+    {
+      'action_name': 'create onejar',
+      'message': 'Creating OneJAR jar',
+      'inputs': [
+        '<(create_onejar)',
+        '>@(classpath)',
+        '<(main_jar_file)',
+        '>@(shared_objects)',
+      ],
+      'outputs': [
+        '<(out_onejar)',
+      ],
+      'action': [
+        '<(create_onejar)',
+        '<(main_jar_file)',
+        '<(INTERMEDIATE_DIR)', '>(classpath)',
+        '<(out_onejar)', '>(onejar_jar)',
+        '>(shared_objects)',
+      ],
+    },
+  ],
+}
diff --git a/aos/build/parser.rb b/aos/build/parser.rb
new file mode 100644
index 0000000..6163129
--- /dev/null
+++ b/aos/build/parser.rb
@@ -0,0 +1,556 @@
+require 'digest'
+require 'fileutils'
+
+def javaify name
+	name = name.dup
+	name.gsub! /(\w)_(\w)/ do
+		$1 + $2.upcase
+	end
+	name.gsub /^\w/ do |char|
+		char.downcase
+	end
+end
+
+module Contents
+	class SyntaxError < Exception
+	end
+	class Tokenizer
+		def initialize file
+			@file = file
+			@token = ""
+			@lineno = 0
+		end
+		def filename
+			@file.path
+		end
+		def pop_char
+			if char = @hold_char
+				@hold_char = nil
+				return char
+			end
+			return @file.read(1)
+		end
+		def unpop_char char
+			@hold_char = char
+		end
+		def clear_comment
+			@hold_char = nil
+			@file.gets
+			@lineno += 1
+		end
+		def syntax_error error
+			filename = File.basename(@file.path)
+			line = @lineno + 1
+			raise SyntaxError, error + "\n from #{line} of #{filename}", caller
+		end
+		def item_missing item
+			syntax_error "expected \"#{item}\"! you missing something!?"
+		end
+		def peek_token
+			@peek_token = next_token
+		end
+		def next_token
+			if token = @peek_token
+				@peek_token = nil
+				return token
+			end
+			token = @token
+			while char = pop_char
+				if char == "\n"
+					@lineno += 1
+				end
+				if char == "/"
+					if pop_char == "/"
+						clear_comment
+					else
+						syntax_error("unexpected #{char.inspect}")
+					end
+				elsif char =~ /[\s\r\n]/
+					if token.length > 0
+						@token = ""
+						return token
+					end
+				elsif char =~ /[;\{\}]/
+					if token.length > 0
+						unpop_char char
+						@token = ""
+						return token
+					end
+					return(char)
+				elsif token.length > 0 && char =~ /[\w:]/
+					token += char
+				elsif char =~ /[a-zA-Z0-9]/
+					token = char
+				else
+					syntax_error("unexpected #{char.inspect}")
+				end
+			end
+		rescue EOFError
+		end
+		def self.is_string token
+			token =~ /[a-zA-Z]\w*/
+		end
+		def self.is_number token
+			token =~ /[0-9]*/
+		end
+	end
+
+	class Struct
+		class StructField
+			def initialize
+				@members = [] # array of strings
+			end
+			def parse tokenizer
+				while true
+					token = tokenizer.next_token
+					if Tokenizer.is_string(token)
+						@members.push token
+					elsif token == ";" || token == "\n"
+						if @members.length > 0
+							return @members
+						else
+							return nil
+						end
+					else
+						tokenizer.syntax_error("expected member name in struct!")
+					end
+				end
+			end
+			def self.parse *args
+				self.new.parse *args
+			end
+			def use members
+				members
+			end
+			def self.use *args
+				self.new.use *args
+			end
+			def to_s
+				@members.join " "
+			end
+		end
+
+		def parse tokenizer, parse_name = true
+			if parse_name
+				token = tokenizer.next_token
+				if Tokenizer.is_string(token)
+					@name_raw = token
+				else
+					tokenizer.syntax_error("expected struct name!")
+				end
+			else
+				@name_raw = nil
+				@name_data = tokenizer.filename
+			end
+			token = tokenizer.next_token
+			tokenizer.syntax_error("expected '{', got '#{token}'") if(token != "{")
+			while token != "}"
+				token = tokenizer.peek_token
+				if token != "}"
+					field = StructField.parse(tokenizer)
+					@fields.push(field) if(field)
+				end
+			end
+			if tokenizer.next_token == "}"
+				return self
+			else
+				tokenizer.syntax_error("wahh; call parker. #{__LINE__}")
+			end
+		end
+		def self.parse *args
+			self.new.parse *args
+		end
+
+		def use fields, name_data
+			@name_raw = nil
+			@name_data = name_data
+			fields.each do |field|
+				@fields.push(StructField.use field.split(' '))
+			end
+			self
+		end
+		def self.use *args
+			self.new.use *args
+		end
+
+		def name
+			@name_raw || gen_name
+		end
+		def gen_name
+			unless @generated_name
+				@generated_name = 'a' + Digest::SHA1.hexdigest(@fields.join('') + $namespace + @name_data)
+			end
+			@generated_name
+		end
+
+		def initialize
+			@fields = [] # array of arrays of strings
+			@hidden_fields = []
+		end
+		def upcase_name
+			name.gsub(/^[a-z]|_[a-z]/) do |v|
+				v[-1].chr.upcase
+			end
+		end
+		def join_fields array
+			(array.collect { |a|
+				"  #{a.join(" ")};"
+			}).join("\n")
+		end
+		def fields
+			join_fields @fields
+		end
+		def hidden_fields
+			join_fields @hidden_fields
+		end
+		def add_hidden_field k, v
+			@hidden_fields.push [k, v]
+		end
+		def params
+			(@fields.collect do |a|
+				a.join(" ")
+			end).join(', ')
+		end
+		def copy_params_into varname, decl = true
+			(decl ? "#{name} #{varname};\n" : '') + (@fields.collect do |a|
+				"#{varname}.#{a[-1]} = #{a[-1]};"
+			end).join("\n")
+		end
+		def params_from name
+			(@fields.collect do |a|
+				name + '.' + a[-1]
+			end).join(', ')
+		end
+		def builder_name aos_namespace = true, this_namespace = true
+			(aos_namespace ? "aos::" : '') + "QueueBuilder<#{this_namespace ? $namespace + '::' : ''}#{name}>"
+		end
+		def java_builder
+			name + 'Builder'
+		end
+		def builder_defs name
+			(@fields.collect do |field|
+				"  inline #{name} &#{field[-1]}" +
+				"(#{field[0...-1].join(" ")} in) " +
+				"{ holder_.View().#{field[-1]} = in; return *this; }"
+			end).join "\n"
+		end
+		def swig_builder_defs name
+			(@fields.collect do |field|
+				"  %rename(#{javaify field[-1]}) #{field[-1]};\n" +
+				"  #{name} &#{field[-1]}" +
+				"(#{field[0...-1].join(" ")} #{field[-1]});"
+			end).join "\n"
+		end
+		def zero name
+			(@fields.collect do |field|
+				"    new (&#{name}.#{field[-1]}) #{field[0...-1].join ' '}();"
+			end).join("\n")
+		end
+		def size
+			(@fields.collect do |field|
+				"sizeof(#{$namespace}::#{name}::#{field[-1]})"
+			end.push('0')).join(' + ')
+		end
+		def get_format(field)
+			case(field[0...-1])
+			when ['int']
+				r = '%d'
+			when ['float'], ['double']
+				r = '%f'
+			when ['bool']
+				r = '%s'
+			when ['uint8_t']
+				r = '%hhu'
+			when ['uint16_t']
+				r = '%d'
+			when ['struct', 'timespec']
+				r = '%jdsec,%ldnsec'
+			else
+				return 'generator_error'
+			end
+			return field[-1] + ': ' + r
+		end
+		def to_printf(name, field)
+			case(field[0...-1])
+			when ['bool']
+				return name + '.' + field[-1] + ' ? "true" : "false"'
+			when ['uint16_t']
+				return "static_cast<int>(#{name}.#{field[-1]})"
+			when ['struct', 'timespec']
+				return "#{name}.#{field[-1]}.tv_sec, #{name}.#{field[-1]}.tv_nsec"
+			else
+				return name + '.' + field[-1]
+			end
+		end
+		def netop name, buffer
+			offset = '0'
+			(@fields.collect do |field|
+				# block |var_pointer, output_pointer|
+				val = yield "&#{name}.#{field[-1]}", "&#{buffer}[#{offset}]"
+				offset += " + sizeof(#{name}.#{field[-1]})"
+				'    ' + val
+			end).join("\n") + "\n    " +
+				"static_assert(#{offset} == #{size}, \"code generator issues\");"
+		end
+		def hton name, output
+			netop(name, output) do |var, output|
+				"to_network(#{var}, #{output});"
+			end
+		end
+		def ntoh input, name
+			netop(name, input) do |var, input|
+				"to_host(#{input}, #{var});"
+			end
+		end
+		def swig_writer
+			<<END
+struct #{name} {
+#{(@fields.collect { |a|
+	"  %rename(#{javaify a[-1]}) #{a[-1]};"
+}).join("\n")}
+#{self.fields}
+  %extend {
+    const char *toString() {
+      return aos::TypeOperator<#{$namespace}::#{name}>::Print(*$self);
+    }
+  }
+ private:
+  #{name}();
+};
+} // namespace #{$namespace}
+namespace aos {
+%typemap(jstype) #{builder_name false}& "#{java_builder}"
+%typemap(javaout) #{builder_name false}& {
+    $jnicall;
+    return this;
+  }
+template <> class #{builder_name false} {
+ private:
+  #{builder_name false}();
+ public:
+  inline bool Send();
+  %rename(#{javaify 'Send'}) Send;
+#{swig_builder_defs builder_name(false)}
+};
+%template(#{java_builder}) #{builder_name false};
+%typemap(javaout) #{builder_name false}& {
+    return new #{java_builder}($jnicall, false);
+  }
+} // namespace aos
+namespace #{$namespace} {
+END
+		end
+		def writer
+			<<END
+struct #{name} {
+#{self.fields}
+#{self.hidden_fields}
+};
+} // namespace #{$namespace}
+namespace aos {
+template <> class TypeOperator<#{$namespace}::#{name}> {
+ public:
+  static void Zero(#{$namespace}::#{name} &inst) {
+    (void)inst;
+#{zero 'inst'}
+  }
+  static void NToH(const char *input, #{$namespace}::#{name} &inst) {
+    (void)input;
+    (void)inst;
+#{ntoh 'input', 'inst'}
+  }
+  static void HToN(const #{$namespace}::#{name} &inst, char *output) {
+    (void)inst;
+    (void)output;
+#{hton 'inst', 'output'}
+  }
+  static inline size_t Size() { return #{size}; }
+  static const char *Print(const #{$namespace}::#{name} &inst) {
+#{@fields.empty? ? <<EMPTYEND : <<NOTEMPTYEND}
+    (void)inst;
+    return "";
+EMPTYEND
+    static char buf[1024];
+    if (snprintf(buf, sizeof(buf), "#{@fields.collect do |field|
+	    get_format(field)
+    end.join(', ')}", #{@fields.collect do |field|
+	    to_printf('inst', field)
+    end.join(', ')}) >= static_cast<ssize_t>(sizeof(buf))) {
+      LOG(WARNING, "#{name}'s buffer was too small\\n");
+      buf[sizeof(buf) - 1] = '\\0';
+    }
+    return buf;
+NOTEMPTYEND
+  }
+};
+template <> class #{builder_name false} {
+ private:
+  aos::QueueHolder<#{$namespace}::#{name}> &holder_;
+ public:
+  #{builder_name false}(aos::QueueHolder<#{$namespace}::#{name}> &holder) : holder_(holder) {}
+  inline bool Send() { return holder_.Send(); }
+  inline const char *Print() const { return holder_.Print(); }
+#{builder_defs builder_name(false)}
+};
+} // namespace aos
+namespace #{$namespace} {
+END
+		end
+		def to_s
+			return <<END
+#{name}: #{(@fields.collect {|n| n.join(" ") }).join("\n\t")}
+END
+		end
+	end
+
+	class SimpleField
+		def initialize check_function = :is_string
+			@check_function = check_function
+			@name = nil
+		end
+		def parse tokenizer
+			token = tokenizer.next_token
+			if Tokenizer.__send__ @check_function, token
+				@name = token
+			else
+				tokenizer.syntax_error('expected value!')
+			end
+			if tokenizer.next_token == ';'
+				@name
+			else
+				tokenizer.syntax_error('expected ";"!')
+			end
+		end
+		def self.parse tokenizer
+			self.new.parse tokenizer
+		end
+	end
+	class NameField < SimpleField
+	end
+
+	class OutputFile
+		def initialize namespace, filename, topdir, outpath
+			@namespace = namespace
+			$namespace = namespace
+			@base = filename.gsub(/\.\w*$/, "").gsub(/^.*\//, '')
+      @topdir = topdir
+			@filebase = outpath + @base
+			@filename = filename
+      FileUtils.mkdir_p(outpath)
+
+			fillin_initials if respond_to? :fillin_initials
+			parse filename
+			fillin_defaults if respond_to? :fillin_defaults
+			self
+		rescue SyntaxError => e
+			puts e
+			exit 1
+		end
+		def filename type
+			case type
+			when 'h'
+				@filebase + '.q.h'
+			when 'cc'
+				@filebase + '.q.cc'
+			when 'main'
+				@filebase + '_main.cc'
+			when 'swig'
+				@filebase + '.swg'
+      when 'java_dir'
+        @filebase + '_java/'
+      when 'java_wrap'
+        @filebase + '_java_wrap.cc'
+			else
+				throw SyntaxError, "unknown filetype '#{type}'"
+			end
+		end
+		def parse filename
+			file = File.open filename
+			tokenizer = Tokenizer.new file
+			while token = tokenizer.next_token
+				if !token || token.gsub('\s', '').empty?
+				elsif token == ';'
+				else
+					error = catch :syntax_error do
+						case token
+						when 'namespace'
+							$namespace = NameField.parse tokenizer
+						else
+							parse_token token, tokenizer
+						end
+						nil
+					end
+					if error
+						tokenizer.syntax_error error.to_s
+						raise error
+					end
+				end
+			end
+
+			check_format tokenizer
+		end
+    def call_swig
+      output_dir = filename('java_dir') + $namespace
+      FileUtils.mkdir_p(output_dir)
+      if (!system('swig', '-c++', '-Wall', '-Wextra', '-java',
+                  '-package', $namespace, "-I#{@topdir}",
+                  '-o', filename('java_wrap'),
+                  '-outdir', output_dir, filename('swig')))
+        exit $?.to_i
+      end
+    end
+
+		def queue_holder_accessors suffix, var, type, force_timing = nil
+<<END
+  inline bool Get#{suffix}(#{force_timing ? '' : 'bool check_time'}) aos_check_rv { return #{var}.Get(#{force_timing || 'check_time'}); }
+  inline #{type} &View#{suffix}() { return #{var}.View(); }
+  inline void Clear#{suffix}() { #{var}.Clear(); }
+  inline bool Send#{suffix}() { return #{var}.Send(); }
+  inline const char *Print#{suffix}() { return #{var}.Print(); }
+  inline aos::QueueBuilder<#{type}> &#{suffix || 'Builder'}() { return #{var}.Builder(); }
+END
+		end
+		def queue_holder_accessors_swig suffix, var, type, force_timing = nil
+<<END
+  %rename(#{javaify "Get#{suffix}"}) Get#{suffix};
+  bool Get#{suffix}(#{force_timing ? '' : 'bool check_time'});
+  %rename(#{javaify "View#{suffix}"}) View#{suffix};
+  #{type} &View#{suffix}();
+  %rename(#{javaify "Clear#{suffix}"}) Clear#{suffix};
+  void Clear#{suffix}();
+  %rename(#{javaify "Send#{suffix}"}) Send#{suffix};
+  bool Send#{suffix}();
+  %rename(#{javaify suffix || 'Builder'}) #{suffix || 'Builder'};
+  aos::QueueBuilder<#{type}> &#{suffix || 'Builder'}();
+END
+		end
+	end
+end
+
+def write_file_out
+	if ARGV.length < 3
+		puts 'Error: at least 3 arguments required!!!'
+		exit 1
+	end
+	file = Contents::OutputFile.new ARGV.shift,
+		File.expand_path(ARGV.shift),
+    ARGV.shift,
+		File.expand_path(ARGV.shift) + '/'
+	while !ARGV.empty?
+		case type = ARGV.shift
+		when 'cpp'
+			file.write_cpp
+		when 'header'
+			file.write_header
+		when 'main'
+			file.write_main
+		when 'swig'
+			file.write_swig
+      file.call_swig
+		else
+			puts "Error: unknown output type '#{type}'"
+			exit 1
+		end
+	end
+end
+
diff --git a/aos/build/queues.gypi b/aos/build/queues.gypi
new file mode 100644
index 0000000..30fe7cd
--- /dev/null
+++ b/aos/build/queues.gypi
@@ -0,0 +1,123 @@
+# Include this file in any target that needs to use files generated from queue
+#   etc. definitions.
+#
+# To use, create a target of the following form:
+# {
+#   'target_name': 'my_queues',
+#   'type': 'static_library', # or any other type that can handle .cc files
+#   'sources': [
+#     'aos/example/Queue.q',
+#     'aos/example/ControlLoop.q',
+#   ],
+#   'variables': {
+#     'header_path': 'aos/example',
+#   },
+#   'includes': ['path/to/queues.gypi'],
+# },
+# Code that depends on this target will be able to #include
+#   "aos/example/Queue.q.h" and "aos/example/ControlLoop.q.h".
+#
+# using <http://src.chromium.org/svn/trunk/src/build/protoc.gypi> as an
+# example of how this should work
+{
+  'variables': {
+    #'header_path': '>!(python -c "import os.path; print os.path.relpath(\'<(RULE_INPUT_PATH)\', \'<(DEPTH)\')")',
+    'prefix_dir': '<(SHARED_INTERMEDIATE_DIR)/<!(echo <(header_path) | sed "s/[^A-Za-z0-9]/_/g")',
+    'out_dir': '<(prefix_dir)/<(_target_name)/<(header_path)',
+    'gen_namespace%': '>!(echo >(header_path) | sed "s:\([^/]*\).*:\\1:g")',
+    'output_h': '<(out_dir)/<(RULE_INPUT_ROOT).q.h',
+    'output_cc': '<(out_dir)/<(RULE_INPUT_ROOT).q.cc',
+    'output_main': '<(out_dir)/<(RULE_INPUT_ROOT)_main.cc',
+    'output_swg': '<(out_dir)/<(RULE_INPUT_ROOT).q.swig',
+    'output_java_wrap': '<(out_dir)/<(RULE_INPUT_ROOT)_java_wrap.cc',
+    'java_dir': '<(out_dir)/<(RULE_INPUT_ROOT).q_java',
+    'no_rsync': 1,
+  },
+  'rules': [
+    {
+      'variables': {
+        'script': '<(AOS)/build/queues/compiler.rb',
+      },
+      'rule_name': 'genqueue',
+      'extension': 'q',
+      'outputs': [
+        '<(output_h)',
+        '<(output_cc)',
+      ],
+      'conditions': [
+        ['OS=="crio"', {
+          'outputs': [
+            # cRIO doesn't do swig for a good reason.
+          ]
+        },{
+          'outputs': [
+            '<(output_swg)',
+            '<(output_java_wrap)',
+            '<(java_dir)',
+          ]
+        }]
+      ],
+      'inputs': [
+        '<(script)',
+        '<!@(find <(AOS)/build/queues/ -name *.rb)',
+        '<(AOS)/common/queue.h',
+        '<(AOS)/common/time.h',
+      ],
+      'action': ['ruby', '<(script)',
+        '--swig',
+        '--swigccout', '<(output_java_wrap)',
+        '-I', '<(DEPTH)',
+        '<(RULE_INPUT_PATH)',
+        '-cpp_out',
+        '<(header_path)',
+        '-cpp_base',
+        '<(prefix_dir)/<(_target_name)'],
+      'message': 'Generating C++ code from <(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).q',
+      'process_outputs_as_sources': 1,
+    },
+    {
+      'variables': {
+        'script': '<(AOS)/build/act_builder.rb',
+      },
+      'rule_name': 'genact',
+      'extension': 'act',
+      'outputs': [
+        '<(output_h)',
+        '<(output_cc)',
+        '<(output_main)',
+      ],
+      'inputs': [
+        '<(script)',
+      ],
+      'action': ['ruby', '<(script)',
+        '<(gen_namespace)',
+        '<(RULE_INPUT_PATH)',
+        '<(DEPTH)',
+        '<(out_dir)', 'header', 'cpp', 'main'],
+      #'message': 'Generating C++ code from <(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).act',
+      'process_outputs_as_sources': 1,
+    },
+  ],
+  'cflags': [
+# For the swig-generated C++ code.
+    '-fno-strict-aliasing',
+    '-Wno-cast-qual',
+  ],
+  'include_dirs': [
+    '/usr/lib/jvm/default-java/include',
+    '/usr/lib/jvm/default-java/include/linux',
+    '<(prefix_dir)/<(_target_name)',
+  ],
+  'direct_dependent_settings': {
+    'include_dirs': [
+      '<(prefix_dir)/<(_target_name)',
+    ],
+    'variables': {
+      'gen_srcdir_parents': ['<(out_dir)'],
+    },
+  },
+  'dependencies': [
+    '<(AOS)/build/aos.gyp:aos_internal_nolib',
+  ],
+  'hard_dependency': 1,
+}
diff --git a/aos/build/queues/compiler.rb b/aos/build/queues/compiler.rb
new file mode 100644
index 0000000..aef5cbf
--- /dev/null
+++ b/aos/build/queues/compiler.rb
@@ -0,0 +1,151 @@
+["tokenizer.rb","q_file.rb","queue_group.rb","queue.rb","namespaces.rb",
+"interface.rb","errors.rb"].each do |name|
+	require File.dirname(__FILE__) + "/objects/" + name
+end
+["standard_types.rb","auto_gen.rb","file_pair_types.rb",
+"dep_file_pair.rb","swig.rb"].each do |name|
+	require File.dirname(__FILE__) + "/cpp_pretty_print/" + name
+end
+["q_file.rb","message_dec.rb","queue_dec.rb"].each do |name|
+	require File.dirname(__FILE__) + "/output/" + name
+end
+require "fileutils"
+require "pathname"
+
+def parse_args(globals,args)
+	i = 0
+	$swig = false
+	$swigccout_path = ""
+	while(i < args.length)
+		if(args[i] == "-I")
+			args.delete_at(i)
+			if(!args[i])
+				$stderr.puts "hey! -I is followed by nothing."
+				$stderr.puts "\tnot a supported usage..."
+				$stderr.puts "\tWot. Wot."
+				exit!(-1)
+			end
+			path = args.delete_at(i)
+			globals.add_path(path)
+		elsif(args[i] == "--swigccout")
+			args.delete_at(i)
+			$swigccout_path = args.delete_at(i)
+		elsif(args[i] == "-cpp_out")
+			args.delete_at(i)
+			path = args.delete_at(i)
+			if(path =~ /\./)
+				$stderr.puts "hey! path #{path} has a \".\" char which is "
+				$stderr.puts "\tnot a supported usage..."
+				$stderr.puts "\tWot. Wot."
+				exit!(-1)
+			elsif(!path)
+				$stderr.puts "hey! No cpp_out path provided."
+				$stderr.puts "\tumm, you could try -cpp_out \"\""
+				$stderr.puts "\tThat might do the trick"
+				$stderr.puts "\tWot. Wot."
+				exit!(-1)
+			end
+			$cpp_out = path.split(/\\|\//)
+		elsif(args[i] == "--swig")
+			$swig = true
+			args.delete_at(i)
+		elsif(args[i] == "-cpp_base")
+			args.delete_at(i)
+			path = args.delete_at(i)
+			$cpp_base = File.expand_path(path)
+			if(!File.exists?($cpp_base))
+				$stderr.puts "output directory #{$cpp_base.inspect} does not exist."
+				$stderr.puts "\tI'm not going to make that! sheesh, who do you think I am?"
+				$stderr.puts "\tWot. Wot."
+				exit!(-1)
+			end
+		elsif(args[i] =~ /^-/)
+			$stderr.puts "hey! unknown argument #{args[i]}."
+			$stderr.puts "\tWot. Wot."
+			exit!(-1)
+		else
+			i += 1
+		end
+	end
+	if(!$cpp_base)
+		$stderr.puts "hey! missing -cpp_base argument."
+		$stderr.puts "\tWot. Wot."
+		exit!(-1)
+	end
+	if(!$cpp_out)
+		$stderr.puts "hey! missing -cpp_out argument."
+		$stderr.puts "\tWot. Wot."
+		exit!(-1)
+	end
+end
+def build(filename,globals_template)
+	globals = Globals.new()
+	globals_template.paths.each do |path|
+		globals.add_path(path)
+	end
+	filename = File.expand_path(filename)
+	q_file = QFile.parse(filename)
+	output_file = q_file.q_eval(globals)
+	q_filename = File.basename(filename)
+	rel_path = ($cpp_out + [q_filename]).join("/")
+
+	FileUtils.mkdir_p(Pathname.new($cpp_base) + $cpp_out.join("/"))
+
+	cpp_tree = output_file.make_cpp_tree(rel_path)
+
+	h_file_path = $cpp_base + "/" + rel_path + ".h"
+	cc_file_path = $cpp_base + "/" + rel_path + ".cc"
+	swig_file_path = $cpp_base + "/" + rel_path + ".swig"
+	java_directory = $cpp_base + "/" + rel_path + "_java/"
+	cpp_tree.add_cc_include((rel_path + ".h").inspect)
+	cpp_tree.add_cc_include("aos/common/byteorder.h".inspect)
+	cpp_tree.add_cc_include("aos/common/inttypes.h".inspect)
+	cpp_tree.add_cc_using("::aos::to_network")
+	cpp_tree.add_cc_using("::aos::to_host")
+	cpp_tree.add_swig_header_include("aos/common/queue.h".inspect)
+	cpp_tree.add_swig_body_include("aos/atom_code/queue-tmpl.h".inspect)
+	cpp_tree.add_swig_header_include("aos/common/time.h".inspect)
+	cpp_tree.add_swig_include((rel_path + ".h").inspect)
+
+	header_file = File.open(h_file_path,"w+")
+	cc_file = File.open(cc_file_path,"w+")
+	cpp_tree.write_header_file($cpp_base,header_file)
+	cpp_tree.write_cc_file($cpp_base,cc_file)
+	cc_file.close()
+	header_file.close()
+	if ($swig)
+		swig_file = File.open(swig_file_path,"w+")
+		cpp_tree.write_swig_file($cpp_base,swig_file,q_filename)
+		swig_file.close()
+		namespace = q_file.namespace.get_name()[1..-1]
+		FileUtils.mkdir_p(java_directory)
+		includes = globals.paths.collect { |a| "-I#{a}" }
+
+		if (!system('/usr/bin/swig', *(includes + ['-I' + $cpp_base + '/',
+				    '-package', namespace,
+				    '-outdir', java_directory,
+				    '-o', $swigccout_path,
+				    '-c++', '-Wall', '-Wextra', '-java', swig_file_path])))
+			puts "Swig failed."
+			exit -1
+		end
+	end
+end
+begin
+	args = ARGV.dup
+	globals = Globals.new()
+	parse_args(globals,args)
+	if(args.length == 0)
+		$stderr.puts "hey! you want me to do something,"
+		$stderr.puts "\tbut you gave me no q files to build!"
+		$stderr.puts "\tWot. Wot."
+		exit!(-1)
+	end
+	args.each do |filename|
+		build(filename,globals)
+	end
+	exit(0)
+rescue QError => e
+	$stderr.print(e.to_s)
+	exit!(-1)
+end
diff --git a/aos/build/queues/cpp_pretty_print/auto_gen.rb b/aos/build/queues/cpp_pretty_print/auto_gen.rb
new file mode 100644
index 0000000..633c7c0
--- /dev/null
+++ b/aos/build/queues/cpp_pretty_print/auto_gen.rb
@@ -0,0 +1,282 @@
+module CPP
+end
+class CPP::Comment
+	def initialize(text)
+		@text = text
+	end
+	def pp(state)
+		state.needs_semi = false
+		if(@text.include?("\n"))
+			state.print("/* #{@text} */")
+		else
+			state.print("// #{@text}")
+		end
+	end
+end
+class CPP::TODO < CPP::Comment
+	def initialize(owner,text)
+		@text = "TODO(#{owner}): #{text}"
+	end
+end
+class CPP::MemberFunc
+	class ForwardDec
+		def initialize(func) ; @func = func ; end
+		def pp(state) ; @func.pp_forward_dec(state) ; end
+	end
+	attr_accessor :args,:suite,:return_type,:name,:pre_func_types,:const,:static,:virtual
+	def initialize(type_class,return_type,name)
+		@type_class = type_class
+		@return_type = return_type
+		@name = name
+		@const = false
+		@static = false
+		@virtual = false
+		@args = CPP::Args.new()
+		@suite = CPP::Suite.new()
+	end
+	attr_accessor :inline
+	def forward_dec() ; ForwardDec.new(self) ; end
+	def pp_forward_dec(state)
+		return self.pp_inline(state) if(@inline)
+        if (@static)
+          state.print("static ")
+				elsif (@virtual)
+          state.print("virtual ")
+        end
+		state.print("#{@return_type} #{@pre_func_types}#{@name}(")
+		state.pp(@args)
+		state.print(")")
+        if (@const)
+          state.print(" const")
+        end
+	end
+	def pp_inline(state)
+        if (@static)
+          state.print("static ")
+				elsif (@virtual)
+          state.print("virtual ")
+        end
+		state.print("#{@return_type} #{@pre_func_types}#{@name}(")
+		state.pp(@args)
+		state.print(") ")
+        if (@const)
+          state.print(" const")
+        end
+		@suite.pp_one_line(state)
+	end
+	def pp(state)
+		return if(@inline)
+		state.print("#{@return_type} #{@pre_func_types}#{@type_class.chop_method_prefix}#{@name}(")
+		state.pp(@args)
+		state.print(") ")
+		if (@const)
+			state.print("const ")
+		end
+		state.pp(@suite)
+		state.v_pad(2)
+	end
+  def pp_pre_swig_file(state)
+  end
+  def pp_post_swig_file(state)
+  end
+	alias_method :pp_header_file, :pp_forward_dec
+	alias_method :pp_cc_file, :pp
+	
+end
+class CPP::Constructor
+	class ForwardDec
+		def initialize(func) ; @func = func ; end
+		def pp(state) ; @func.pp_forward_dec(state) ; end
+	end
+	attr_accessor :args,:suite,:return_type,:name
+	def initialize(type_class)
+		@type_class = type_class
+		@args = CPP::Args.new()
+		@suite = CPP::Suite.new()
+		@var_cons = CPP::Args.new()
+	end
+	def forward_dec() ; ForwardDec.new(self) ; end
+	def add_cons(*args)
+		@var_cons.push(CPP::FuncCall.build(*args))
+	end
+	def pp_forward_dec(state)
+		state.print("#{@type_class.name}(")
+		state.pp(@args)
+		state.print(")")
+	end
+	def pp_inline(state)
+		pp(state,false)
+	end
+	def pp(state,prefix = true)
+		state.needs_semi = false
+		state.print(@type_class.chop_method_prefix) if(prefix)
+		state.print("#{@type_class.name}(")
+		state.pp(@args)
+		if(@var_cons.length >= 1)
+			state.print(")")
+			state.endline()
+			state.indent += 4
+			state.print(": ")
+			state.pp(@var_cons)
+			state.indent -= 4
+			state.print(" ")
+		else
+			state.print(") ")
+		end
+		state.pp(@suite)
+		state.v_pad(2)
+	end
+	alias_method :pp_header_file, :pp_forward_dec
+	alias_method :pp_cc_file, :pp
+end
+class CPP::Destructor
+	class ForwardDec
+		def initialize(func) ; @func = func ; end
+		def pp(state) ; @func.pp_forward_dec(state) ; end
+	end
+	attr_accessor :args,:suite,:return_type,:name
+	def initialize(type_class)
+		@type_class = type_class
+		@args = CPP::Args.new()
+		@suite = CPP::Suite.new()
+	end
+	def forward_dec() ; ForwardDec.new(self) ; end
+	def pp_forward_dec(state)
+		state.print("~#{@type_class.name}(")
+		state.pp(@args)
+		state.print(")")
+	end
+	def pp(state)
+		state.print("#{@type_class.chop_method_prefix}~#{@type_class.name}(")
+		state.pp(@args)
+		state.print(") ")
+		state.pp(@suite)
+		state.v_pad(2)
+	end
+	alias_method :pp_header_file, :pp_forward_dec
+	alias_method :pp_cc_file, :pp
+end
+class CPP::Include
+	attr_accessor :filename
+	def initialize(filename)
+		@filename = filename
+	end
+	def pp(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#include #{@filename}")
+		state.endline()
+	end
+end
+class CPP::IncludeGuard
+	attr_accessor :name,:suite
+	def initialize(suite = CPP::Suite.new())
+		@suite = suite
+	end
+	def self.rand_name(len = 40)
+		str = ""
+		len.times { str += ((rand(26) + ?A).chr)}
+		return str
+	end
+	def pp(state)
+		@name ||= IncludeGuard.rand_name
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#ifndef #{@name}")
+		state.endline()
+		state.suppress_indent()
+		state.print("#define #{@name}")
+		state.endline()
+		if(@suite.respond_to?(:pp_no_braces))
+			@suite.pp_no_braces(state)
+		else
+			state.pp(@suite)
+		end
+		state.endline()
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#endif  // #{@name}")
+		state.endline()
+	end
+end
+class CPP::IfnDef
+	attr_accessor :name,:suite
+	def initialize(suite = CPP::Suite.new())
+		@suite = suite
+	end
+	def pp(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#ifndef #{@name}")
+		state.endline()
+		if(@suite.respond_to?(:pp_no_braces))
+			@suite.pp_no_braces(state)
+		else
+			state.pp(@suite)
+		end
+		state.endline()
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#endif  // #{@name}")
+		state.endline()
+	end
+end
+class CPP::PreprocessorIf
+	attr_accessor :name,:suite
+	def initialize(ifsuite, elsesuite)
+		@ifsuite = ifsuite
+		@elsesuite = elsesuite
+	end
+	def write_if(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#if #{@name}")
+		state.endline()
+	end
+	def write_else(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#else  // #{@name}")
+		state.endline()
+	end
+	def write_endif(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("#endif  // #{@name}")
+		state.endline()
+	end
+	def pp_inline(state)
+		self.write_if(state)
+		@ifsuite.pp_inline(state)
+		if(@elsesuite != nil)
+			self.write_else(state)
+			@elsesuite.pp_inline(state)
+		end
+		self.write_endif(state)
+	end
+	def pp(state)
+		self.write_if(state)
+		if(@ifsuite.respond_to?(:pp_no_braces))
+			@ifsuite.pp_no_braces(state)
+		else
+			state.pp(@ifsuite)
+		end
+		if(@elsesuite != nil)
+			self.write_else(state)
+			if(@elsesuite.respond_to?(:pp_no_braces))
+				@elsesuite.pp_no_braces(state)
+			else
+				state.pp(@elsesuite)
+			end
+		end
+		self.write_endif(state)
+	end
+end
+class CPP::Using
+	def initialize(using)
+		@using = using
+	end
+	def pp(state)
+		state.print("using #{@using}")
+	end
+end
diff --git a/aos/build/queues/cpp_pretty_print/dep_file_pair.rb b/aos/build/queues/cpp_pretty_print/dep_file_pair.rb
new file mode 100644
index 0000000..571d9e0
--- /dev/null
+++ b/aos/build/queues/cpp_pretty_print/dep_file_pair.rb
@@ -0,0 +1,617 @@
+class GroupElement
+	def add_group_dep(group_dep)
+		@group_dep = group_dep
+	end
+	def adjust_group(state,old_group)
+		if(@group_dep != old_group)
+			@group_dep.adjust_from(state,old_group)
+		end
+		return @group_dep
+	end
+end
+class DepMask < GroupElement
+	def initialize(elem)
+		@elem = elem
+		@deps = []
+	end
+	def add_dep(dep)
+		@deps << dep
+		self
+	end
+	def method_missing(method,*args,&blk)
+		@elem.send(method,*args,&blk)
+	end
+	alias_method :old_respond_to, :respond_to?
+	def respond_to?(method)
+		old_respond_to(method) || @elem.respond_to?(method)
+	end
+end
+
+class MemberElementHeader < GroupElement
+	def initialize(elem)
+		@elem = elem
+	end
+	def pp(state)
+		if(@elem.respond_to?(:pp_header_file))
+			@elem.pp_header_file(state)
+		else
+			state.pp(@elem)
+		end
+	end
+	def self.check(plan,elem)
+		plan.push(self.new(elem))
+	end
+end
+class MemberElementInline < GroupElement
+	def initialize(elem)
+		@elem = elem
+	end
+	def pp(state)
+		if(@elem.respond_to?(:pp_inline))
+			@elem.pp_inline(state)
+		else
+			state.pp(@elem)
+		end
+	end
+end
+class MemberElementPreSWIG < GroupElement
+	def initialize(elem)
+		@elem = elem
+	end
+	def pp(state)
+		if(@elem.respond_to?(:pp_pre_swig_file))
+			@elem.pp_pre_swig_file(state)
+		else
+			state.pp(@elem)
+		end
+	end
+	def self.check(plan,elem)
+		plan.push(self.new(elem)) if(elem.respond_to?(:pp_pre_swig_file))
+	end
+end
+class MemberElementPostSWIG < GroupElement
+	def initialize(elem)
+		@elem = elem
+	end
+	def pp(state)
+		if(@elem.respond_to?(:pp_post_swig_file))
+			@elem.pp_post_swig_file(state)
+		else
+			state.pp(@elem)
+		end
+	end
+	def self.check(plan,elem)
+		plan.push(self.new(elem)) if(elem.respond_to?(:pp_post_swig_file))
+	end
+end
+class MemberElementCC < GroupElement
+	attr_accessor :pp_override
+	def initialize(elem)
+		@elem = elem
+	end
+	def pp(state)
+		return state.pp(@elem) if(@pp_override)
+		@elem.pp_cc_file(state)
+	end
+	def self.check(plan,elem)
+		plan.push(self.new(elem)) if(elem.respond_to?(:pp_cc_file))
+	end
+end
+class ImplicitName
+	attr_accessor :parent
+	def initialize(name,parent)
+		@name = name
+		@parent = parent
+	end
+	def close(state)
+		state.endline()
+		state.needs_semi = false
+		state.print("}  // namespace #{@name}\n")
+	end
+	def name()
+		if(@parent)
+			return @parent.name + "." + @name
+		else
+			return "." + @name
+		end
+	end
+	def open(state)
+		state.endline()
+		state.needs_semi = false
+		state.print("namespace #{@name} {\n")
+	end
+	def adjust_from(state,old_group)
+		close_grps = []
+		grp = old_group
+		while(grp)
+			close_grps << grp
+			grp = grp.parent
+		end
+		open_grps = []
+		grp = self
+		while(grp)
+			open_grps << grp
+			grp = grp.parent
+		end
+		while(open_grps[-1] == close_grps[-1] && close_grps[-1])
+			close_grps.pop()
+			open_grps.pop()
+		end
+		close_grps.each do |grp|
+			grp.close(state)
+		end
+		open_grps.reverse.each do |grp|
+			grp.open(state)
+		end
+	end
+	def adjust_to(state,new_group)
+		grp = self
+		while(grp)
+			grp.close(state)
+			grp = grp.parent
+		end
+	end
+end
+class GroupPlan < GroupElement
+	attr_accessor :implicit
+	def initialize(group_elem,members = [])
+		@group_elem = group_elem
+		@members = CPP::Suite.new(members)
+	end
+	def push(mem)
+		mem.add_group_dep(@implicit) if(@implicit)
+		@members << mem
+	end
+	def pp(state)
+		if(@group_elem)
+			@group_elem.open(state)
+		end
+		group = nil
+		@members.each do |member|
+			group = member.adjust_group(state,group)
+			#puts "at:#{group.name}" if(group.respond_to?(:name))
+			state.endline()
+			state.needs_semi = true
+			state.pp(member)
+			state.endline()
+		end
+		group.adjust_to(state,nil) if(group)
+		if(@group_elem)
+			@group_elem.close(state)
+		end
+	end
+end
+class SWIGPre_Mask
+	def initialize(elem)
+		@elem = elem
+	end
+	def plan_cc(plan)
+	end
+	def plan_pre_swig(plan)
+		elem = MemberElementPreSWIG.new(@elem)
+		plan.push(elem)
+	end
+	def plan_post_swig(plan)
+	end
+	def plan_header(plan);
+	end
+end
+class SWIGPost_Mask
+	def initialize(elem)
+		@elem = elem
+	end
+	def plan_cc(plan)
+	end
+	def plan_pre_swig(plan)
+	end
+	def plan_post_swig(plan)
+		elem = MemberElementPostSWIG.new(@elem)
+		plan.push(elem)
+	end
+	def plan_header(plan);
+	end
+end
+class CC_Mask
+	def initialize(elem)
+		@elem = elem
+	end
+	def plan_cc(plan)
+		elem = MemberElementCC.new(@elem)
+		elem.pp_override = true
+		plan.push(elem)
+	end
+	def plan_header(plan);
+	end
+	def plan_pre_swig(plan);
+	end
+	def plan_post_swig(plan);
+	end
+end
+module Types
+	class TypeDef
+		def initialize(type,name)
+			@type = type
+			@name = name
+		end
+		def pp(state)
+			state.pp("typedef #{@type.name} #{@name}")
+		end
+	end
+	class Type
+		attr_accessor :name,:static,:dec,:space
+		def initialize(namespace,name)
+			@space = namespace
+			@name = name
+			@members = []
+			@protections = {}
+			@deps = []
+		end
+		class ProtectionGroup
+			def initialize(name)
+				@name = name
+			end
+			def adjust_from(state,other)
+				state.indent -= 1
+				state.pp("#@name:")
+				state.endline
+				state.indent += 1
+			end
+			def adjust_to(state,other)
+				other.adjust_from(state,self) if other
+			end
+		end
+		ProtectionGroups = { :public => ProtectionGroup.new(:public),
+			:protected => ProtectionGroup.new(:protected),
+		 	:private => ProtectionGroup.new(:private)}
+		def set_parent(parent)
+			@parent = parent
+		end
+		def chop_method_prefix()
+			@space.chop_method_prefix + "#@name::"
+		end
+		def def_func(*args)
+			func = CPP::MemberFunc.new(self,*args)
+			@protections[func] = @protection
+			@members << func
+			return func
+		end
+		def add_cc_comment(*args)
+			args.each do |arg|
+				@members.push(CC_Mask.new(CPP::Comment.new(arg)))
+			end
+		end
+		def add_pre_swig(arg)
+			@members.push(SWIGPre_Mask.new(arg))
+		end
+		def add_post_swig(arg)
+			@members.push(SWIGPost_Mask.new(arg))
+		end
+		def plan_pre_swig(plan)
+			@members.each do |member|
+				if(member.respond_to?(:plan_pre_swig))
+					member.plan_pre_swig(plan)
+				elsif(member.respond_to?(:pp_pre_swig_file))
+					plan.push(MemberElementPreSWIG.new(member))
+				end
+			end
+		end
+		def plan_post_swig(plan)
+			@members.each do |member|
+				if(member.respond_to?(:plan_post_swig))
+					member.plan_post_swig(plan)
+				elsif(member.respond_to?(:pp_post_swig_file))
+					plan.push(MemberElementPostSWIG.new(member))
+				end
+			end
+		end
+		def plan_cc(plan)
+			@members.each do |member|
+				if(member.respond_to?(:plan_cc))
+					member.plan_cc(plan)
+				elsif(member.respond_to?(:pp_cc_file))
+					plan.push(MemberElementCC.new(member))
+				end
+			end
+		end
+		def plan_header(plan)
+			group_plan = GroupPlan.new(self)
+			plan.push(group_plan)
+			@members.each do |member|
+				group_plan.implicit = ProtectionGroups[@protections[member]]
+				if(member.respond_to?(:plan_header))
+					member.plan_header(group_plan)
+				else
+					group_plan.push(MemberElementHeader.new(member))
+				end
+				#member.plan_cc(plan)
+			end
+		end
+		def open(state)
+			state.needs_semi = false
+			state.v_pad(2)
+			if(@static)
+				state.print("static ")
+			end
+			self.template_header(state) if(self.respond_to?(:template_header))
+			state.print("#{self.class.type_name} #{@name}")
+			self.template_spec_args(state) if(self.respond_to?(:template_spec_args))
+			if(@parent)
+				state.print(" : #{@parent} {\n")
+			else
+				state.pp(" {\n")
+			end
+			state.indent += 2
+		end
+		def close(state)
+			state.indent -= 2
+			state.needs_semi = true
+			if(@dec)
+				state.print("\n} #{@dec}")
+			else
+				state.print("\n}")
+			end
+			state.v_pad(2)
+		end
+		def add_dep(other)
+			@deps << other
+			self
+		end
+	end
+	class Class < Type
+		def add_member(protection,member)
+			@protection = protection
+			@members.push(member)
+			@protections[member] = protection
+			return member
+		end
+		def add_struct(*args)
+			add_member(:public, Types::Struct.new(self,*args))
+		end
+		def public() ; @protection = :public ; end 
+		def protected() ; @protection = :protected ; end 
+		def private() ; @protection = :private ; end 
+		def self.type_name() ; "class" ; end
+	end
+	class PreprocessorIf < Type
+		def initialize(*args)
+			super(*args)
+		end
+		def add_member(member)
+			@members.push(member)
+			return member
+		end
+		def self.type_name() ; "#if" ; end
+		def open(state)
+			state.needs_semi = false
+			state.print("\n#if #{@name}")
+		end
+		def close(state)
+			state.needs_semi = false
+			state.print("\n#endif  // #{@name}")
+		end
+	end
+	class Struct < Type
+		def add_member(member)
+			@members.push(member)
+			return member
+		end
+		def self.type_name() ; "struct" ; end
+	end
+	class TemplateClass < Class
+		def initialize(*args)
+			super(*args)
+			@t_args = CPP::Args.new()
+		end
+		def spec_args()
+			return @spec_args ||= CPP::Args.new()
+		end
+		def template_header(state)
+			if(@t_args.length > 0)
+				state.pp("template < ")
+				state.pp(@t_args)
+			else
+				state.pp("template <")
+			end
+			state.pp(">\n")
+		end
+		def plan_cc(plan)
+
+		end
+		def plan_header(plan)
+			group_plan = GroupPlan.new(self)
+			plan.push(group_plan)
+			@members.each do |member|
+				group_plan.implicit = ProtectionGroups[@protections[member]]
+				if(member.respond_to?(:plan_header))
+					member.plan_header(group_plan)
+				else
+					group_plan.push(MemberElementInline.new(member))
+				end
+			end
+		end
+		def template_spec_args(state)
+			if(@spec_args)
+				state.pp("< ")
+				state.pp(@spec_args)
+				state.pp(">")
+			end
+		end
+	end
+end
+class DepFilePair
+	class NameSpace
+		def initialize(name,parent)
+			@name,@parent = name,parent
+			@members = []
+		end
+		def add_struct(*args)
+			add Types::Struct.new(self,*args)
+		end
+		def add_template(*args)
+			add Types::TemplateClass.new(self,*args)
+		end
+		def add_class(*args)
+			add Types::Class.new(self,*args)
+		end
+		def add_cc(arg)
+			@members.push(CC_Mask.new(arg))
+		end
+		def add_pre_swig(arg)
+			@members.push(SWIGPre_Mask.new(arg))
+		end
+		def add_post_swig(arg)
+			@members.push(SWIGPost_Mask.new(arg))
+		end
+		def chop_method_prefix()
+			""
+		end
+		def class_comment(*args)
+			add CPP::Comment.new(*args)
+		end
+		def var_dec_comment(*args)
+			add CPP::Comment.new(*args)
+		end
+		def add_var_dec(arg)
+			add DepMask.new(arg)
+		end
+		def plan_pre_swig(plan)
+			plan.implicit = ImplicitName.new(@name,plan.implicit)
+			@members.each do |member|
+				if(member.respond_to?(:plan_pre_swig))
+					member.plan_pre_swig(plan)
+				else
+					MemberElementPreSWIG.check(plan,member)
+				end
+			end
+		end
+		def plan_post_swig(plan)
+			@members.each do |member|
+				if(member.respond_to?(:plan_post_swig))
+					member.plan_post_swig(plan)
+				else
+					MemberElementPostSWIG.check(plan,member)
+				end
+			end
+		end
+		def plan_cc(plan)
+			plan.implicit = ImplicitName.new(@name,plan.implicit)
+			@members.each do |member|
+				if(member.respond_to?(:plan_cc))
+					member.plan_cc(plan)
+				else
+					MemberElementCC.check(plan,member)
+				end
+			end
+			plan.implicit = plan.implicit.parent
+		end
+		def plan_header(plan)
+			plan.implicit = ImplicitName.new(@name,plan.implicit)
+			@members.each do |member|
+				if(member.respond_to?(:plan_header))
+					member.plan_header(plan)
+				else
+					MemberElementHeader.check(plan,member)
+				end
+			end
+			plan.implicit = plan.implicit.parent
+		end
+		def add val
+			@members << val
+			val
+		end
+	end
+	def initialize(rel_path)
+		@rel_path = rel_path
+		@cc_includes = []
+		@swig_includes_h = []
+		@swig_includes_swig = []
+		@header_includes = []
+		@spaces = []
+		@cc_usings = []
+		@cache = {}
+	end
+	def add_swig_body_include(inc_path)
+		@swig_includes_swig << CPP::SwigInclude.new(inc_path)
+	end
+	def add_swig_header_include(inc_path)
+		@swig_includes_h << CPP::Include.new(inc_path)
+	end
+	def add_swig_include(inc_path)
+		@swig_includes_h << CPP::Include.new(inc_path)
+		@swig_includes_swig << CPP::SwigInclude.new(inc_path)
+	end
+	def add_cc_include(inc_path)
+		@cc_includes << CPP::Include.new(inc_path)
+	end
+	def add_cc_using(using)
+		@cc_usings << CPP::Using.new(using)
+	end
+	def add_header_include(inc_path)
+		@header_includes << CPP::Include.new(inc_path)
+	end
+	def add_namespace(name,parent)
+		space = NameSpace.new(name,parent)
+		if(parent != self)
+			parent.add(space)
+		else
+			@spaces.push(space)
+		end
+		return space
+	end
+	def set(type,cached)
+		@cache[type] = cached
+	end
+	def get(type)
+		cached = @cache[type]
+		return cached if cached
+		cached = type.create(self)
+		cached_check = @cache[type]
+		return cached_check if cached_check
+		set(type,cached)
+		return cached
+	end
+	def write_cc_file(cpp_base,cc_file)
+		plan_cc = GroupPlan.new(nil,elems_cc = [])
+		@spaces.each do |space|
+			space.plan_cc(plan_cc)
+		end
+		suite = CPP::Suite.new(@cc_includes + @cc_usings + [plan_cc])
+		CPP.pretty_print(suite,cc_file)
+	end
+	def write_header_file(cpp_base,header_file)
+		plan_header = GroupPlan.new(nil,elems_cc = [])
+		@spaces.each do |space|
+			space.plan_header(plan_header)
+		end
+		suite = CPP::Suite.new(@header_includes + [plan_header])
+		include_guard = CPP::IncludeGuard.new(suite)
+		include_guard.name = @rel_path.upcase.gsub(/[\.\/\\]/,"_") + "_H_"
+		CPP.pretty_print(include_guard,header_file)
+	end
+	def write_swig_file(cpp_base,swig_file,q_filename)
+		plan_pre_swig = GroupPlan.new(nil, elems_cc = [])
+		plan_post_swig = GroupPlan.new(nil, elems_cc = [])
+		q_filename_underscore = q_filename.gsub(".","_")
+		@spaces.each do |space|
+			space.plan_pre_swig(plan_pre_swig)
+			space.plan_post_swig(plan_post_swig)
+		end
+                header_includes = CPP::SWIGBraces.new(CPP::Suite.new(@swig_includes_h))
+		# TODO(aschuh): I should probably %import any other headers from this queue's dependencies.
+                suite = CPP::Suite.new(["%module \"#{q_filename_underscore}\"",
+				        "%typemap(javaimports) SWIGTYPE, SWIGTYPE * \"import aos.QueueGroup; import aos.Message; import aos.Time;\"",
+				        "%pragma(java) jniclassimports=\"import aos.QueueGroup; import aos.Message; import aos.Time;\"",
+                                        "%pragma(java) moduleimports=\"import aos.QueueGroup; import aos.Message; import aos.Time;\"",
+                                        "%include \"std_string.i\"",
+                                        "%include \"stdint.i\""] +
+                                       [header_includes] +
+                                       #["%import \"aos/common/time.h\"",
+                                        #"%import \"aos/common/queue.h\""] +
+                                       ["%import \"aos/aos.swig\""] +
+                                       [plan_pre_swig] +
+                                       @swig_includes_swig +
+                                       [plan_post_swig]
+                                      )
+		CPP.pretty_print(suite, swig_file)
+	end
+end
diff --git a/aos/build/queues/cpp_pretty_print/file_pair_types.rb b/aos/build/queues/cpp_pretty_print/file_pair_types.rb
new file mode 100644
index 0000000..8f60b77
--- /dev/null
+++ b/aos/build/queues/cpp_pretty_print/file_pair_types.rb
@@ -0,0 +1,204 @@
+module CPP
+end
+class CPP::TypePair
+	attr_accessor :name,:static,:dec
+	def initialize(namespace,name)
+		@space,@name = namespace,name
+		@members = []
+		@protections = {}
+		@dont_sort = {}
+	end
+	ProtectionTable = { :public => 0,:protected => 1,:private => 2 }
+	def comp(m1,m2)
+		if(!(@dont_sort[m1] || @dont_sort[m2]))
+			if(@protections[m1] && @protections[m2])
+				comp = ProtectionTable[@protections[m1]] <=> ProtectionTable[@protections[m2]]
+				return comp if(comp != 0)
+			end
+			comp = TypeTable[m1.class] <=> TypeTable[m2.class]
+			return comp if(comp != 0)
+		end
+		return @stable[m1] <=> @stable[m2]
+	end
+	def set_parent(parent)
+		@parent = parent
+	end
+	def add_class(name)
+		return add_member(:public,CPP::ClassPair.new(self,name))
+	end
+	def add_struct(name)
+		return add_member(:public,CPP::StructPair.new(self,name))
+	end
+	def add_cc_comment(*strs)
+		strs.each do |str|
+			@members << comment = CPP::CCMemberWrapper.new(CPP::Comment.new(str))
+			@protections[comment] = @protection
+		end
+		#@dont_sort[comment] = true
+	end
+	def method_prefix()
+		@space.method_prefix + "#@name::"
+	end
+	def chop_method_prefix()
+		@space.chop_method_prefix + "#@name::"
+	end
+	def pp(state)
+		@stable = {}
+		@members.each_with_index { |mem,i| @stable[mem] = i }
+		members = @members.sort { |m1,m2| comp(m1,m2) }
+
+		state.needs_semi = false
+		state.v_pad(2)
+		if(@static)
+			state.print("static ")
+		end
+		if(@parent)
+			state.print("#{self.class.type_name} #{@name} : #{@parent} {\n")
+		else
+			state.print("#{self.class.type_name} #{@name} {\n")
+		end 
+		state.indent += 2
+		protection = nil 
+		members.each do |member|
+			if(protection != @protections[member])
+				state.indent -= 1
+				state.needs_semi = false
+				state.v_pad(2) if(protection)
+				protection = @protections[member]
+				state.print("#{protection}:\n")
+				state.indent += 1
+				state.endline()
+			end
+			state.endline()
+			state.needs_semi = true
+			if(member.respond_to?(:pp_header_file))
+				member.pp_header_file(state)
+			else
+				state.pp(member)
+			end
+			state.endline()
+		end 
+		state.indent -= 2
+		state.needs_semi = true
+		if(@dec)
+		state.print("\n} #{@dec}")
+		else
+		state.print("\n}")
+		end
+		state.v_pad(2)
+	end
+	def pp_header_file(state)
+		pp(state)
+	end
+	def pp_cc_file(state)
+		@members.each do |member|
+			state.needs_semi = true
+			member.pp_cc_file(state) if(member.respond_to?(:pp_cc_file))
+			state.endline()
+		end
+	end
+	def def_func(*args)
+		func = CPP::MemberFunc.new(self,*args)
+		@protections[func] = @protection
+		@members << func
+		return func
+	end
+end
+class CPP::CCMemberWrapper
+	def initialize(member)
+		@member = member
+	end
+	def pp_header_file(state) ; end
+	def pp_cc_file(state)
+		state.pp(@member)
+	end
+end
+class CPP::ClassPair < CPP::TypePair
+	attr_accessor :name
+	def initialize(namespace,name)
+		super(namespace,name)
+		@protection = :public #default to public
+	end
+	def add_member(protection,member)
+		@protection = protection
+		@members << member
+		@protections[member] = protection
+		return member
+	end
+	def public() ; @protection = :public ; end
+	def protected() ; @protection = :protected ; end
+	def private() ; @protection = :private ; end
+	def self.type_name() ; "class" ; end
+end
+class CPP::StructPair < CPP::TypePair
+	def self.type_name() ; "struct" ; end
+	def add_member(member)
+		@members << member
+		return member
+	end
+end
+CPP::TypePair::TypeTable = { CPP::StructPair => 0, CPP::ClassPair => 1,CPP::Constructor => 2 }
+CPP::TypePair::TypeTable.default = 3
+class CPP::TemplateClass < CPP::ClassPair
+	def initialize(namespace,name)
+		super(namespace,name)
+		@t_args = CPP::Args.new()
+	end
+	def spec_args()
+		return @spec_args ||= CPP::Args.new()
+	end
+	def pp(state)
+		@stable = {}
+		@members.each_with_index { |mem,i| @stable[mem] = i }
+		members = @members.sort { |m1,m2| comp(m1,m2) }
+		state.needs_semi = false
+		state.v_pad(2)
+		if(@t_args.length > 0)
+			state.pp("template < ")
+			state.pp(@t_args)
+		else
+			state.pp("template <")
+		end
+		state.pp(">\n")
+		state.pp("class #@name")
+		if(@spec_args)
+			state.pp("< ")
+			state.pp(@spec_args)
+			state.pp("> {")
+		else
+			state.pp(" {")
+		end
+		state.endline()
+		state.indent += 2
+		protection = nil 
+		members.each do |member|
+			if(protection != @protections[member])
+				state.indent -= 1
+				state.needs_semi = false
+				state.v_pad(2) if(protection)
+				protection = @protections[member]
+				state.print("#{protection}:\n")
+				state.indent += 1
+				state.endline()
+			end
+			state.endline()
+			state.needs_semi = true
+			if(member.respond_to?(:pp_inline))
+				member.pp_inline(state)
+			else
+				state.pp(member)
+			end
+			state.endline()
+		end 
+		state.indent -= 2
+		state.needs_semi = true
+		if(@dec)
+			state.print("\n} #{@dec}")
+		else
+			state.print("\n}")
+		end
+		state.v_pad(2)
+	end
+	def pp_cc_file(state); end
+end
+
diff --git a/aos/build/queues/cpp_pretty_print/standard_types.rb b/aos/build/queues/cpp_pretty_print/standard_types.rb
new file mode 100644
index 0000000..566f542
--- /dev/null
+++ b/aos/build/queues/cpp_pretty_print/standard_types.rb
@@ -0,0 +1,363 @@
+module CPP
+	class Class
+
+	end
+	class Funct
+		attr_accessor :retval,:name,:args,:suite
+		def initialize(retval = nil,name = nil,args = Args.new(),suite = Suite.new())
+			@retval,@name,@args,@suite = retval,name,args,suite
+		end
+		def pp(state)
+			state.pp(@retval)
+			state.print(" ")
+			state.pp(@name)
+			state.print("(")
+			state.pp(@args)
+			state.print(")")
+			state.pp(@suite)
+		end
+	end
+	class If
+		attr_accessor :cond,:suite,:else_suite
+		def initialize(cond = nil,suite = Suite.new(),else_suite = nil)
+			@cond,@suite,@else_suite = cond,suite,else_suite
+		end
+		def pp(state)
+			state.print("if (")
+			state.pp(@cond)
+			state.print(") ")
+			state.needs_semi = false
+			state.pp(@suite)
+			if(@else_suite)
+				state.print(" else ")
+				state.pp(@else_suite)
+			end
+		end
+		def else_suite()
+			return(@else_suite ||= Suite.new())
+		end
+	end
+	class For
+		attr_accessor :init,:cond,:update,:suite
+		def initialize(init = nil,cond = nil,update = nil,suite = Suite.new())
+			@init,@cond,@update,@suite = init,cond,update,suite
+		end
+		def pp(state)
+			state.print("for (")
+			Args.new([@init,@cond,@update]).pp(state,";")
+			state.print(") ")
+			state.needs_semi = false
+			state.pp(@suite)
+		end
+	end
+	class Args < Array
+		attr_accessor :dont_wrap
+		def pp(state,sep = ",")
+			pos = start = state.col
+			self.each_with_index do |arg,i|
+				#puts "#{state.col - start} , #{start}"
+				state.print(sep) if(i != 0)
+				if(pos > 80)
+					state.wrap(state.indent + 4)
+					pos = start = state.col
+				elsif(state.col * 2 - pos > 80 && !@dont_wrap)
+					state.wrap(start)
+					start = pos
+				else
+					state.print(" ") if(i != 0)
+					pos = state.col
+				end
+				state.pp(arg)
+			end
+		end
+	end
+	class Suite < Array
+		def pp(state)
+			state.print("{")
+			state.>>
+			state.needs_semi = false
+			self.pp_no_braces(state)
+			state.<<
+			state.print("}")
+		end
+		def pp_no_braces(state)
+			self.each do |arg,i|
+				state.endline()
+				state.needs_semi = true
+				state.pp(arg)
+				state.endline()
+			end
+		end
+		def pp_one_line(state)
+			if(self.length == 1)
+				state.needs_semi = true
+				state.print("{ ")
+				state.pp(self[0])
+				state.print(";") if(state.needs_semi)
+				state.needs_semi = false
+				state.print(" }")
+			else
+				self.pp(state)
+			end
+		end
+	end
+	class FuncCall
+		attr_accessor :name,:args
+		def initialize(name = nil,args = Args.new())
+			@name,@args = name,args
+		end
+		def self.build(name,*args)
+			self.new(name,Args.new(args))
+		end
+		def pp(state)
+			state.pp(@name)
+			state.print("(")
+			state.pp(@args)
+			state.print(")")
+		end
+	end
+	class BIT_OR
+		attr_accessor :val1,:val2
+		def initialize(val1,val2)
+			@val1,@val2 = val1,val2
+		end
+		def pp(state)
+			state.pp(@val1)
+			state.print(" | ")
+			state.pp(@val2)
+		end
+	end
+	class LT
+		attr_accessor :val1,:val2
+		def initialize(val1,val2)
+			@val1,@val2 = val1,val2
+		end
+		def pp(state)
+			state.pp(@val1)
+			state.print(" < ")
+			state.pp(@val2)
+		end
+	end
+	class Div
+		attr_accessor :val1,:val2
+		def initialize(val1,val2)
+			@val1,@val2 = val1,val2
+		end
+		def pp(state)
+			state.pp(@val1)
+			state.print(" / ")
+			state.pp(@val2)
+		end
+	end
+	class Add
+		attr_accessor :val1,:val2
+		def initialize(val1,val2)
+			@val1,@val2 = val1,val2
+		end
+		def pp(state)
+			state.pp(@val1)
+			state.print(" + ")
+			state.pp(@val2)
+		end
+	end
+	class Member
+		attr_accessor :obj,:name
+		def initialize(obj,name)
+			@obj,@name = obj,name
+		end
+		def pp(state)
+			state.pp(@obj)
+			state.print(".")
+			state.pp(@name)
+		end
+	end
+	class PointerMember
+		attr_accessor :obj,:name
+		def initialize(obj,name)
+			@obj,@name = obj,name
+		end
+		def pp(state)
+			state.pp(@obj)
+			state.print("->")
+			state.pp(@name)
+		end
+	end
+	class Minus
+		attr_accessor :val
+		def initialize(val)
+			@val = val
+		end
+		def pp(state)
+			state.print("-")
+			state.pp(@val)
+		end
+	end
+	class Not
+		attr_accessor :val
+		def initialize(val)
+			@val = val
+		end
+		def pp(state)
+			state.print("!")
+			state.pp(@val)
+		end
+	end
+	class Address
+		attr_accessor :val
+		def initialize(val)
+			@val = val
+		end
+		def pp(state)
+			state.print("&")
+			state.pp(@val)
+		end
+	end
+	class Paran
+		attr_accessor :val
+		def initialize(val)
+			@val = val
+		end
+		def pp(state)
+			state.print("(")
+			state.pp(@val)
+			state.print(")")
+		end
+	end
+	class Assign
+		attr_accessor :lval,:rval
+		def initialize(lval = nil,rval = Args.new())
+			@lval,@rval = lval,rval
+		end
+		def pp(state)
+			state.pp(@lval)
+			state.print(" = ")
+			state.pp(@rval)
+		end
+	end
+	class PointerDeref
+		attr_accessor :val
+		def initialize(val)
+			@val = val
+		end
+		def pp(state)
+			state.print("*")
+			state.pp(@val)
+		end
+	end
+	class Cast
+		attr_accessor :to,:val
+		def initialize(to,val)
+			@to,@val = to,val
+		end
+		def pp(state)
+			state.print("(")
+			state.pp(@to)
+			state.print(")")
+			state.pp(@val)
+		end
+	end
+	class VarDec
+		attr_accessor :type,:name
+		def initialize(type = nil,name = nil)
+			@type,@name = type,name
+		end
+		def pp(state)
+			state.pp(@type)
+			state.print(" ")
+			state.pp(@name)
+		end
+	end
+	class Return
+		attr_accessor :val
+		def initialize(val = nil)
+			@val = val
+		end
+		def pp(state)
+			state.print("return ")
+			state.pp(@val)
+		end
+	end
+	class TraversalState
+		attr_accessor :needs_semi,:indent,:col
+		def initialize(file)
+			@file = file
+			@indent = 0
+			@not_indented = true
+			@just_endlined = true
+			@hold_points = []
+			@col = 0
+		end
+		def set_hold_point()
+			@hold_points.push(@col)
+		end
+		def wrap(col)
+			@file.print("\n")
+			@file.print(" " * col)
+			@col = col
+		end
+		def suppress_indent()
+			@not_indented = false
+		end
+		def <<()
+			@indent -= 2
+		end
+		def >>()
+			@indent += 2
+		end
+		def pp(ast)
+			return ast.pp(self) if(ast.respond_to?(:pp))
+			self.print(ast)
+		end
+		def print(chars)
+			return print_no_split(chars) if(!chars.respond_to?(:split))
+			chars.split(/\n/,-1).each_with_index do |line,i|
+				endline() if(i != 0)
+				print_no_split(line) if(line && line.length > 0)
+			end
+		end
+		def print_no_split(chars)
+			if(@not_indented)
+				@file.print(" "*@indent)
+				@col += @indent
+				@not_indented = false
+			end
+			if(chars)
+				chars = chars.to_s
+				if(chars.length > 0)
+					@col += chars.length
+					@file.print(chars)
+					@just_endlined = false
+					@v_pad = 0
+				end
+			end
+		end
+		def endline()
+			return if(@just_endlined)
+			@file.print(";") if(@needs_semi)
+			@needs_semi = false
+			@file.print("\n")
+			@not_indented = true
+			@just_endlined = true
+			@hold_points.clear()
+			@v_pad += 1
+			@col = 0
+		end
+		def v_pad(n)
+			while(@v_pad < n)
+				force_endline()
+			end
+		end
+		def force_endline()
+			@just_endlined = false
+			endline()
+		end
+	end
+	def self.pretty_print(ast,file)
+		state = TraversalState.new(file)
+		if(ast.respond_to?(:pp_no_braces))
+			ast.pp_no_braces(state) 
+		else
+			state.pp(ast)
+		end
+	end
+end
diff --git a/aos/build/queues/cpp_pretty_print/swig.rb b/aos/build/queues/cpp_pretty_print/swig.rb
new file mode 100644
index 0000000..ac6d062
--- /dev/null
+++ b/aos/build/queues/cpp_pretty_print/swig.rb
@@ -0,0 +1,60 @@
+class CPP::SwigPragma
+	attr_accessor :suite
+	def initialize(language, pragmatype, suite = CPP::Suite.new())
+		@suite = suite
+	@language = language
+	@pragmatype = pragmatype
+	end
+	def pp(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("%pragma(#{@language}) #{@pragmatype}=%{")
+		state.endline()
+		if(@suite.respond_to?(:pp_no_braces))
+			@suite.pp_no_braces(state)
+		else
+			state.pp(@suite)
+		end
+		state.endline()
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("%}")
+		state.endline()
+		state.endline()
+	end
+end
+class CPP::SWIGBraces
+	attr_accessor :suite
+	def initialize(suite = CPP::Suite.new())
+		@suite = suite
+	end
+	def pp(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("%{")
+		state.endline()
+		if(@suite.respond_to?(:pp_no_braces))
+			@suite.pp_no_braces(state)
+		else
+			state.pp(@suite)
+		end
+		state.endline()
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("%}")
+		state.endline()
+		state.endline()
+	end
+end
+class CPP::SwigInclude
+	attr_accessor :filename
+	def initialize(filename)
+		@filename = filename
+	end
+	def pp(state)
+		state.needs_semi = false
+		state.suppress_indent()
+		state.print("%include #{@filename}")
+		state.endline()
+	end
+end
diff --git a/aos/build/queues/objects/errors.rb b/aos/build/queues/objects/errors.rb
new file mode 100644
index 0000000..d776a22
--- /dev/null
+++ b/aos/build/queues/objects/errors.rb
@@ -0,0 +1,43 @@
+class QError < Exception
+	def initialize(msg)
+		super()
+		@msg = msg
+		@qstacktrace = []
+	end
+	def self.set_name(name)
+		@pretty_name = name
+	end
+	def self.pretty_name()
+		@pretty_name
+	end
+	def to_s
+		msg = "Error:(#{self.class.pretty_name})\n\t"
+		msg += @msg
+		msg += "\n" if(msg[-1] != "\n")
+		@qstacktrace.each do |part|
+			part = part.q_stack_name if(part.respond_to?(:q_stack_name))
+			msg += "\tfrom: #{part}\n"
+		end
+		return msg
+	end
+	set_name("Base Level Exception.")
+	attr_accessor :qstacktrace
+end
+class QSyntaxError < QError
+	def initialize(msg)
+		super(msg)
+	end
+	set_name("Syntax Error")
+end
+class QNamespaceCollision < QError
+	def initialize(msg)
+		super(msg)
+	end
+	set_name("Namespace Collision")
+end
+class QImportNotFoundError < QError
+	def initialize(msg)
+		super(msg)
+	end
+	set_name("Couldn't Find Target of Import Statement")
+end
diff --git a/aos/build/queues/objects/interface.rb b/aos/build/queues/objects/interface.rb
new file mode 100644
index 0000000..52332b6
--- /dev/null
+++ b/aos/build/queues/objects/interface.rb
@@ -0,0 +1,69 @@
+class MessageElementReq
+	def initialize(type,name)
+		@type = type
+		@name = name
+	end
+	def self.parse(tokens)
+		type = tokens.expect(:tWord).data
+		name = tokens.expect(:tWord).data
+		tokens.expect(:tSemi)
+		return self.new(type,name)
+	end 
+end 
+class QueueReq
+	def initialize(name,type = nil)
+		@name = name
+		@type = type
+	end
+	def self.parse(tokens)
+		type_or_name = tokens.expect(:tWord).data
+		if(tokens.peak == :tSemi)
+			tokens.expect(:tSemi)
+			return self.new(type_or_name)
+		else
+			name = tokens.expect(:tWord).data
+			tokens.expect(:tSemi)
+			return self.new(name,type_or_name)
+		end
+	end
+end
+class InterfaceStmt < QStmt
+	def initialize(name,elements)
+		@name = name
+		@elements = elements
+	end
+	def q_eval(locals)
+
+	end
+	def self.check_type(tokens,new_type,old_type)
+		return new_type if(old_type == nil)
+		if(new_type != old_type)
+			tokens.qError(<<ERROR_MSG)
+error: intermixing queue definitions (a queue_group feature)
+	and type definitions (a message_group feature)
+	this results in an undefined type value.
+	Wot. Wot.
+ERROR_MSG
+		end
+		return old_type
+	end
+	def self.parse(tokens)
+		name = tokens.expect(:tWord).data
+		values = []
+		type = nil
+		tokens.expect(:tOpenB)
+		while(tokens.peak != :tCloseB)
+			if(tokens.peak.data == "queue")
+				tokens.expect(:tWord)
+				values << QueueReq.parse(tokens)
+				type = check_type(tokens,:queue_group,type)
+			else
+				values << MessageElementReq.parse(tokens)
+				type = check_type(tokens,:message_group,type)
+			end
+		end 
+		tokens.expect(:tCloseB)
+		tokens.expect(:tSemi)
+		self.new(name,values)
+	end
+end
diff --git a/aos/build/queues/objects/namespaces.rb b/aos/build/queues/objects/namespaces.rb
new file mode 100644
index 0000000..b799d36
--- /dev/null
+++ b/aos/build/queues/objects/namespaces.rb
@@ -0,0 +1,210 @@
+class LocalSituation
+	attr_accessor :globals,:local
+	def initialize(globals)
+		@globals = globals
+		@local = nil
+	end
+	def package=(qualified)
+		if(@local)
+			raise QSyntaxError.new(<<ERROR_MSG)
+You are redefining the package path.
+ Stuff might break if you do that.
+ Other options include: using another header file, and just using the same namespace.
+ If you are confident that you need this you can remove this check at
+ 	#{__FILE__}:#{__LINE__}.
+ Or file a feature request.
+ But that would be weird...
+ Wot. Wot.
+ERROR_MSG
+		end
+		@local = @globals.space
+		qualified.names.each do |name|
+			@local = @local.get_make(name)
+		end
+	end
+	def register(value)
+		if(!@local)
+			raise QError.new(<<ERROR_MSG)
+There is no package path defined, This is a big problem because
+ we are kindof expecting you to have a package path...
+ use a :
+    package my_super.cool.project;
+ statement to remedy this situation. (or file a feature request)
+ Wot. Wot.
+ERROR_MSG
+		end
+		@local[value.name] = value
+		value.parent = @local if(value.respond_to?(:parent=))
+		value.loc = @local
+	end
+	def bind(bind_to)
+		return BoundSituation.new(self,bind_to)
+	end
+end
+class BoundSituation < LocalSituation
+	def initialize(locals,bind_to)
+		@globals = globals
+		@local = bind_to
+	end
+end
+class NameSpace
+	attr_accessor :parent,:name
+	def initialize(name = nil,parent = nil)
+		@name = name
+		@parent = parent
+		@spaces = {}
+	end
+	def []=(key,val)
+		if(old_val = @spaces[key])
+			old_val = old_val.created_by if(old_val.respond_to?(:created_by) && old_val.created_by)
+			if(old_val.respond_to?(:q_stack_name))
+				old_val = old_val.q_stack_name
+			else
+				old_val = "eh, it is a #{old_val.class} thats all I know..."
+			end
+			raise QNamespaceCollision.new(<<ERROR_MSG)
+Woah! The name #{queue_name(key).inspect} is already taken by some chap at #{old_val}.
+\tFind somewhere else to peddle your wares.
+\tWot. Wot.
+ERROR_MSG
+		end
+		@spaces[key] = val
+	end
+	def to_cpp_id(name)
+		txt = @name + "::" + name
+		return @parent.to_cpp_id(txt) if(@parent && parent.name)
+		return "::" + txt
+	end
+	def queue_name(queue)
+		get_name() + "." + queue
+	end
+	def [](key)
+		#puts "getting #{get_name}.#{key}"
+		@spaces[key]
+	end
+	def get_make(name)
+		@spaces[name] ||= self.class.new(name,self)
+	end
+	def get_name()
+		if(@parent)
+			return "#{@parent.get_name}.#{@name}"
+		else
+			return "#{@name}"
+		end
+	end
+	def create(cpp_tree)
+		if(@parent && @parent.name)
+			parent = cpp_tree.get(@parent)
+		else
+			parent = cpp_tree
+		end
+		return cpp_tree.add_namespace(@name,parent)
+	end
+	def to_s()
+		"<NameSpace: #{get_name()}>"
+	end
+	def inspect()
+		"<NameSpace: #{get_name()}>"
+	end
+	def root()
+		return self if(@parent == nil)
+		return @parent.root
+	end
+end
+class Globals
+	attr_accessor :space
+	def initialize()
+		@space = NameSpace.new()
+		@space.get_make("aos")
+		@include_paths = []
+	end
+	def paths()
+		@include_paths
+	end
+	def add_path(path)
+		@include_paths << path
+	end
+	def find_file(filename)
+		@include_paths.each do |path_name|
+			new_path = File.expand_path(path_name) + "/" + filename
+			if(File.exists?(new_path))
+				return new_path 
+			end
+		end
+		raise QImportNotFoundError.new(<<ERROR_MSG)
+Problem Loading:#{filename.inspect} I looked in:
+\t#{(@include_paths.collect {|name| name.inspect}).join("\n\t")}
+\tbut alas, it was nowhere to be found.
+\tIt is popular to include the top of the repository as the include path start, 
+\tand then reference off of that. 
+\tI would suggest doing that and then trying to build again.
+\tWot. Wot.
+ERROR_MSG
+	end
+end
+class QualifiedName
+	attr_accessor :names,:off_root
+	def initialize(names,off_root = false)
+		@names = names
+		@off_root = off_root
+	end
+	def test_lookup(namespace)
+		@names.each do |name|
+			namespace = namespace[name]
+			return nil if(!namespace)
+		end
+		return namespace
+	end
+	def is_simple?()
+		return !@off_root && @names.length == 1
+	end
+	def to_simple()
+		return @names[-1]
+	end
+	def to_s()
+		if(@off_root)
+			return ".#{@names.join(".")}"
+		else
+			return @names.join(".")
+		end
+	end
+	def lookup(locals)
+		if(@off_root)
+			local = locals.globals.space
+		else
+			local = locals.local
+		end
+		target = nil
+		while(!target && local)
+			target = test_lookup(local)
+			local = local.parent
+		end
+		return target if(target)
+		if(@off_root)
+			raise QError.new(<<ERROR_MSG)
+I was looking for .#{@names.join(".")}, but alas, it was not under
+\tthe root namespace.
+\tI'm really sorry old chap.
+\tWot. Wot.
+ERROR_MSG
+		else
+			raise QError.new(<<ERROR_MSG)
+I was looking for #{@names.join(".")}, but alas, I could not find
+\tit in #{locals.local.get_name} or any parent namespaces.
+\tI'm really sorry old chap.
+\tWot. Wot.
+ERROR_MSG
+		end
+	end
+	def self.parse(tokens)
+		names = []
+		off_root = (tokens.peak == :tDot)
+		tokens.next if(off_root)
+		names << tokens.expect(:tWord).data
+		while(tokens.peak == :tDot)
+			tokens.next
+			names << tokens.expect(:tWord).data
+		end
+		return self.new(names,off_root)
+	end
+end
diff --git a/aos/build/queues/objects/q_file.rb b/aos/build/queues/objects/q_file.rb
new file mode 100644
index 0000000..f683dda
--- /dev/null
+++ b/aos/build/queues/objects/q_file.rb
@@ -0,0 +1,148 @@
+class QStmt
+	def set_line(val)
+		@file_line = val
+		return self
+	end
+	def q_stack_name()
+		@file_line
+	end
+	def self.method_added(name)
+		@wrapped ||= {}
+		return if(name != :q_eval && name != :q_eval_extern)
+		return if(@wrapped[name])
+		@wrapped[name] = true
+		method = self.instance_method(name)
+		define_method(name) do |*args,&blk|
+			begin 
+				method.bind(self).call(*args,&blk)
+			rescue QError => e
+				e.qstacktrace << self
+				raise e
+			end 
+		end 
+	end 
+
+end
+class ImportStmt < QStmt
+	def initialize(filename)
+		@filename = filename
+	end
+	def q_eval(locals)
+		filename = locals.globals.find_file(@filename)
+		#puts "importing #{filename.inspect}"
+		q_file = QFile.parse(filename)
+		q_output = q_file.q_eval_extern(locals.globals)
+		q_output.extern = true
+		return Target::QInclude.new(@filename + ".h")
+	end
+	def self.parse(tokens)
+		line = tokens.pos
+		to_import = (tokens.expect(:tString) do |token|
+			<<ERROR_MSG
+I found a #{token.humanize} at #{token.pos}.
+\tI was really looking for a "filename" for this import statement.
+\tSomething like: import "super_cool_file";
+\tWot.Wot
+ERROR_MSG
+		end).data
+		tokens.expect(:tSemi) do |token|
+			<<ERROR_MSG
+I found a #{token.humanize} at #{token.pos}.
+\tI was really looking for a ";" to finish off this import statement
+\tat line #{line};
+\tSomething like: import #{to_import.inspect};
+\tWot.Wot                #{" "*to_import.inspect.length}^
+ERROR_MSG
+		end
+		return self.new(to_import).set_line(line)
+	end
+end
+class PackageStmt < QStmt
+	def initialize(name)
+		@name = name
+	end
+	def q_eval(locals)
+		locals.package = @name
+		return nil
+	end
+	def self.parse(tokens)
+		line = tokens.pos
+		qualified_name = QualifiedName.parse(tokens)
+		tokens.expect(:tSemi)
+		return self.new(qualified_name).set_line(line)
+	end
+end
+class QFile
+	attr_accessor :namespace
+	def initialize(filename,suite)
+		@filename,@suite = filename,suite
+	end
+	def q_eval(globals = Globals.new())
+		local_pos = LocalSituation.new(globals)
+		q_file = Target::QFile.new()
+		@suite.each do |name|
+			val = name.q_eval(local_pos)
+			if(val)
+				if(val.respond_to?(:create))
+					q_file.add_type(val)
+				end
+			end
+		end
+		@namespace = local_pos.local
+		return q_file
+	end
+	def q_eval_extern(globals)
+		local_pos = LocalSituation.new(globals)
+		q_file = Target::QFile.new()
+		@suite.each do |name|
+			if(name.respond_to?(:q_eval_extern))
+				val = name.q_eval_extern(local_pos)
+			else
+				val = name.q_eval(local_pos)
+			end
+			if(val)
+				if(val.respond_to?(:create))
+					q_file.add_type(val)
+				end
+			end
+		end
+		return q_file
+	end
+	def self.parse(filename)
+		tokens = Tokenizer.new(filename)
+		suite = []
+		while(tokens.peak != :tEnd)
+			token = tokens.expect(:tWord) do |token| #symbol
+			<<ERROR_MSG
+I found a #{token.humanize} at #{token.pos}.
+\tI was really looking for a "package", "import", "queue_group",
+\t"message", or "queue" statement to get things moving.
+\tSomething like: import "super_cool_file";
+\tWot.Wot
+ERROR_MSG
+			end
+			case token.data
+			when "package"
+				suite << PackageStmt.parse(tokens)
+			when "import"
+				suite << ImportStmt.parse(tokens)
+			when "queue_group"
+				suite << QueueGroupStmt.parse(tokens)
+			when "message"
+				suite << MessageStmt.parse(tokens)
+			when "queue"
+				suite << QueueStmt.parse(tokens)
+			when "interface"
+				suite << InterfaceStmt.parse(tokens)
+			else
+				tokens.qError(<<ERROR_MSG)
+expected a "package","import","queue","queue_group", or "message" statement rather
+	than a #{token.data.inspect}, (whatever that is?)
+	oh! no! a feature request!?
+	Wot. Wot.
+ERROR_MSG
+			end
+		end
+		return self.new(filename,suite)
+	end
+end
diff --git a/aos/build/queues/objects/queue.rb b/aos/build/queues/objects/queue.rb
new file mode 100644
index 0000000..5693486
--- /dev/null
+++ b/aos/build/queues/objects/queue.rb
@@ -0,0 +1,154 @@
+class MessageElementStmt < QStmt
+	attr_accessor :name
+	def initialize(type,name,length = nil) #lengths are for arrays
+		@type = type
+		@name = name
+		@length = length
+	end
+	CommonMistakes = {"short" => "int16_t","int" => "int32_t","long" => "int64_t"}
+	def check_type_error()
+		if(!(Sizes[@type] || (@length != nil && @type == "char")) )
+			if(correction = CommonMistakes[@type])
+				raise QError.new(<<ERROR_MSG)
+Hey! you have a \"#{@type}\" in your message statement.
+\tplease use #{correction} instead. Your type is not supported because we
+\twant to guarantee that the sizes of the messages stay the same across platforms.
+\tWot. Wot.
+ERROR_MSG
+			elsif(@type == "char")
+				raise QError.new(<<ERROR_MSG)
+Hey! you have a \"#{@type}\" in your message statement.
+\tyou need your declaration to be a char array like: char[10].
+\tor, please use int8_t or uint8_t.
+\tWot. Wot.
+ERROR_MSG
+			else
+				raise QError.new(<<ERROR_MSG)
+Hey! you have a \"#{@type}\" in your message statement.
+\tThat is not in the list of supported types.
+\there is the list of supported types:
+\tint{8,16,32,64}_t,uint{8,16,32,64}_t,bool,float,double#{len_comment}
+\tWot. Wot.
+ERROR_MSG
+			end
+		end
+	end
+
+	PrintFormat = {"bool" => "%c",
+                       "float" => "%f",
+                       "char" => "%c",
+                       "double" => "%f",
+                       "uint8_t" => "%\"PRIu8\"",
+                       "uint16_t" => "%\"PRIu16\"",
+                       "uint32_t" => "%\"PRIu32\"",
+                       "uint64_t" => "%\"PRIu64\"",
+                       "int8_t" => "%\"PRId8\"",
+                       "int16_t" => "%\"PRId16\"",
+                       "int32_t" => "%\"PRId32\"",
+                       "int64_t" => "%\"PRId64\""}
+        def toPrintFormat()
+		if(format = PrintFormat[@type])
+			return format;
+		end
+		raise QError.new(<<ERROR_MSG)
+Somehow this slipped past me, but
+\tI couldn't find the print format of #{@type}. Really, my bad.
+\tWot. Wot.
+ERROR_MSG
+	end
+
+	Sizes = {"bool" => 1, "float" => 4,"double" => 8}
+	[8,16,32,64].each do |len|
+		Sizes["int#{len}_t"] = len / 8
+		Sizes["uint#{len}_t"] = len / 8
+	end
+	Zero = {"float" => "0.0f","double" => "0.0","bool" => "false"}
+	def size()
+		if(size = Sizes[@type]); return size; end
+		return 1 if(@type == "char")
+		raise QError.new(<<ERROR_MSG)
+Somehow this slipped past me, but
+\tI couldn't find the size of #{@type}. Really, my bad.
+\tWot. Wot.
+ERROR_MSG
+	end
+	def q_eval(locals)
+		check_type_error()
+		if(@length == nil)
+			member = Target::MessageElement.new(@type,@name)
+		else
+			member = Target::MessageArrayElement.new(@type,@name,@length)
+		end
+		member.size = size()
+		member.zero = Zero[@type] || "0";
+		member.printformat = toPrintFormat()
+		locals.local.add_member(member)
+	end
+	def self.parse(tokens)
+		line = tokens.pos
+		type = tokens.expect(:tWord).data
+		len = nil
+		if(tokens.peak == :tOpenB)
+			tokens.expect(:tOpenB)
+			len = tokens.expect(:tNumber).data
+			tokens.expect(:tCloseB)
+		end
+		name = tokens.expect(:tWord).data
+		tokens.expect(:tSemi)
+		return self.new(type,name,len).set_line(line)
+	end
+end
+class MessageStmt < QStmt
+	def initialize(name,suite)
+		@name = name
+		@suite = suite
+	end
+	def q_eval(locals)
+		group = Target::MessageDec.new(@name)
+		locals.register(group)
+		@suite.each do |stmt|
+			stmt.q_eval(locals.bind(group))
+		end 
+		return group
+	end
+	def self.parse(tokens)
+		name = tokens.expect(:tWord).data
+		values = []
+		tokens.expect(:tOpenB)
+		while(tokens.peak != :tCloseB)
+			values << MessageElementStmt.parse(tokens)
+		end
+		names = {}
+		values.each do |val|
+			if(names[val.name])
+				raise QSyntaxError.new(<<ERROR_MSG)
+Hey! duplicate name #{val.name.inspect} in your message declaration statement (message #{name}).
+\tI found them at: #{names[val.name].q_stack_name()} and #{val.q_stack_name()}.
+\tWot. Wot.
+ERROR_MSG
+			end
+			names[val.name] = val
+		end
+		tokens.expect(:tCloseB)
+		tokens.expect(:tSemi)
+		self.new(name,values)
+	end
+end
+class QueueStmt < QStmt
+	def initialize(type,name)
+		@type,@name = type,name
+	end
+	def q_eval(locals)
+		queue = Target::QueueDec.new(@type.lookup(locals),@name)
+		locals.register(queue)
+		locals.local.add_queue(queue) if(locals.local.respond_to?(:add_queue))
+		return queue
+	end
+	def self.parse(tokens)
+		line = tokens.pos
+		type_name = QualifiedName.parse(tokens)
+		name = tokens.expect(:tWord).data
+		tokens.expect(:tSemi)
+		return self.new(type_name,name).set_line(line)
+	end
+end
diff --git a/aos/build/queues/objects/queue_group.rb b/aos/build/queues/objects/queue_group.rb
new file mode 100644
index 0000000..136834f
--- /dev/null
+++ b/aos/build/queues/objects/queue_group.rb
@@ -0,0 +1,115 @@
+class QueueGroupTypeStmt < QStmt
+	def initialize(name,suite)
+		@name,@suite = name,suite
+	end
+	def q_eval(locals)
+		group = Target::QueueGroupDec.new(@name)
+		group.created_by = self
+		locals.register(group)
+		@suite.each do |stmt|
+			stmt.q_eval(locals.bind(group))
+		end
+		return group
+	end
+end
+class ImplementsStmt < QStmt
+	def initialize(name)
+		@name = name
+	end
+	def q_eval(locals)
+
+	end
+	def self.parse(tokens)
+		name = QualifiedName.parse(tokens)
+		tokens.expect(:tSemi)
+		return self.new(name)
+	end
+end
+class QueueGroupStmt < QStmt
+	def initialize(type,name)
+		@type,@name = type,name
+	end
+	def q_eval(locals)
+		group = Target::QueueGroup.new(@type.lookup(locals),@name)
+		group.created_by = self
+		locals.register(group)
+		return group
+	end
+	def self.parse(tokens)
+		line = tokens.pos
+		type_name = QualifiedName.parse(tokens)
+		if(type_name.names.include?("queue_group"))
+			tokens.qError(<<ERROR_MSG)
+I was looking at the identifier you gave 
+\tfor the queue group type between line #{line} and #{tokens.pos}
+\tThere shouldn't be a queue_group type called queue_group
+\tor including queue_group in it's path, it is a reserved keyword.
+\tWot. Wot.
+ERROR_MSG
+		end
+		if(tokens.peak == :tOpenB)
+			if(type_name.is_simple?())
+				type_name = type_name.to_simple
+			else
+				tokens.qError(<<ERROR_MSG)
+You gave the name: "#{type_name.to_s}" but you're only allowed to 
+\thave simple names like "#{type_name.names[-1]}" in queue_group definitions
+\ttry something like:
+\tqueue_group ControlLoop { }
+\tWot. Wot.
+ERROR_MSG
+			end
+			tokens.expect(:tOpenB)
+			suite = []
+			while(tokens.peak != :tCloseB)
+				token = tokens.expect(:tWord) do |token|
+					<<ERROR_MSG
+I'm a little confused, I found a #{token.humanize} at #{token.pos}
+\tbut what I really wanted was an identifier signifying a nested 
+\tmessage declaration, or queue definition, or an impliments statement.
+\tWot.Wot
+ERROR_MSG
+				end
+				case token.data
+				when "message"
+					suite << MessageStmt.parse(tokens)
+				when "queue"
+					suite << QueueStmt.parse(tokens)
+				when "implements"
+					suite << ImplementsStmt.parse(tokens)
+				else
+					tokens.qError(<<ERROR_MSG)
+expected a "queue","implements" or "message" statement rather
+\tthan a #{token.data.inspect}.
+\tWot. Wot.
+ERROR_MSG
+				end 
+			end
+			tokens.expect(:tCloseB)
+			obj = QueueGroupTypeStmt.new(type_name,suite).set_line(line)
+		else
+			name = (tokens.expect(:tWord) do |token|
+				<<ERROR_MSG
+I found a #{token.humanize} at #{token.pos}
+\tbut I was in the middle of parsing a queue_group statement, and
+\twhat I really wanted was an identifier to store the queue group.
+\tSomething like: queue_group control_loops.Drivetrain my_cool_group;
+\tWot.Wot
+ERROR_MSG
+			end).data
+			obj = QueueGroupStmt.new(type_name,name).set_line(line)
+			if(tokens.peak == :tDot)
+				tokens.qError(<<ERROR_MSG)
+Hey! It looks like you're trying to use a complex identifier at: #{tokens.pos}
+\tThats not going to work. Queue Group definitions have to be of the form:
+\tqueue_group ComplexID SimpleID
+\tWot. Wot.
+ERROR_MSG
+			end	
+		end
+		tokens.expect(:tSemi) do |token|
+			token.pos
+		end
+		return obj
+	end
+end
diff --git a/aos/build/queues/objects/tokenizer.rb b/aos/build/queues/objects/tokenizer.rb
new file mode 100644
index 0000000..2a33b90
--- /dev/null
+++ b/aos/build/queues/objects/tokenizer.rb
@@ -0,0 +1,213 @@
+class BufferedReader
+	def initialize(file)
+		@file = file
+		@line = 1
+		@chars = []
+		@col_nums = []
+		@col = 0
+	end
+	def filename
+		return File.basename(@file.path)
+	end
+	def pos()
+		"#{filename()}:#{lineno()},#{@col}"
+	end
+	def clear_comment()
+		@file.gets
+		@line += 1
+	end
+	def lineno()
+		return @line
+		return @file.lineno + 1
+	end
+	def pop_char()
+		val = @chars.pop() || @file.read(1)
+		@col_nums[@line] = @col += 1
+		if(val == "\n")
+			@line += 1
+			@col = 0
+		end
+
+		return val
+	end
+	def unpop_char(char)
+		if(char == "\n")
+			@line -= 1
+			@col = @col_nums[@line]
+		end
+		@col -= 1
+		@chars.push(char)
+	end
+end
+class Tokenizer
+	TOKEN_TYPES = {"{" => :tOpenB,"}"=> :tCloseB,";" => :tSemi,"," => :tComma,
+		"(" => :tOpenParan,")" => :tCloseParan,"=" => :tAssign,"." => :tDot,
+		"<<"=> :tLShift,"*" => :tMult,"+" => :tAdd,"[" => :tOpenB,
+		"]" => :tCloseB}
+	Humanize = TOKEN_TYPES.invert
+	class Token
+		attr_accessor :type,:data,:pos
+		def to_s
+			if(@type == :tString)
+				val = @data.inspect.to_s
+			elsif(@type == :tWord)
+				val = @data.to_s
+			else
+				val = @data.to_s
+			end
+			return "#{val.ljust(50)}:#{@type}"
+		end
+		def humanize()
+			if(@type == :tString)
+				return "#{@data.inspect.to_s} string"
+			elsif(@type == :tWord)
+				return "#{@data.inspect} identifier"
+			end
+			return Humanize[@type].inspect
+		end
+		def inspect()
+			data = ""
+			data = " #{@data.inspect}" if(@data)
+			"<Token :#{@type}#{data} at #{@pos}>"
+		end
+		def ==(other)
+			if(other.class == Symbol)
+				return @type == other
+			elsif(other.class == self.class)
+				return @type == other.type && @data == other.data
+			else
+				return nil
+			end
+		end
+	end
+	def initialize(file)
+		file = File.open(file,"r") if(file.class == String)
+		@read = BufferedReader.new(file)
+	end
+	def qError(error)
+		syntax_error(error)
+	end
+	def syntax_error(msg)
+		err = QSyntaxError.new(msg)
+		err.qstacktrace << "#{@read.lineno} of #{@read.filename}"
+		raise err
+	end
+	def peak_token()
+		@peak_token = next_token()
+	end
+	def peak()
+		peak_token()
+	end
+	def next()
+		next_token()
+	end
+	def pos()
+		@read.pos
+	end
+	def tokenize(string_token)
+		token = Token.new()
+		token.type = TOKEN_TYPES[string_token]
+		return token
+	end
+	def next_token()
+		if(token = @peak_token)
+			@peak_token = nil
+			return token
+		end
+		token = next_token_cache()
+		pos = self.pos()
+		token.pos = pos
+		return token
+	end
+	def next_token_cache()
+		token = Token.new()
+		token.data = ""
+		while (char = @read.pop_char())
+			#puts "#{char.inspect}:#{token.inspect}"
+			if(char == "/")
+				if(@read.pop_char == "/")
+					@read.clear_comment()
+				else
+					syntax_error("unexpected #{char.inspect}")
+				end
+			elsif(char == "#")
+				@read.clear_comment()
+			elsif(char =~ /[\s\r\n]/)
+				if(token.type)
+					return token
+				end
+			elsif(char =~ /\"/)
+				token.type = :tString
+				token.data = ""
+				while((char = @read.pop_char) != "\"")
+					token.data += char
+				end
+				return token
+			elsif(char =~ /[1-9]/)
+				token.type = :tNumber
+				token.data = char.to_i
+				while(char != ".")
+					char = @read.pop_char
+					if(char =~ /[0-9]/)
+						token.data = char.to_i + token.data * 10
+					elsif(char == ".")
+					else
+						@read.unpop_char(char)
+						return token
+					end
+				end
+				second_char = 0
+				man = 0
+				while(true)
+					char = @read.pop_char
+					if(char =~ /[0-9]/)
+						second_char = char.to_i + second_char * 10
+						man = man * 10
+					else
+						@read.unpop_char(char)
+						token.data += second_char / man.to_f
+						return token
+					end
+				end
+			elsif(char == ":")
+				if(@read.pop_char == "=")
+					return tokenize(":=")
+				end
+				syntax_error("unexpected \":\"")
+			elsif(char =~ /[;\{\}=()\",\*\+\.\[\]]/)
+				return(tokenize(char))
+			elsif(char =~ /[a-zA-Z_]/)
+				token.type = :tWord
+				token.data = char
+				while(true)
+					char = @read.pop_char()
+					if(char && char =~ /\w/)
+						token.data += char
+					else
+						@read.unpop_char(char)
+						return token
+					end
+				end
+			elsif(char == "<")
+				if((char = @read.pop_char()) == "<")
+					return tokenize("<<")
+				else
+					@read.unpop_char(char)
+					return tokenize("<")
+				end
+			else
+				syntax_error("unexpected #{char.inspect}")
+			end
+		end
+		token.type = :tEnd
+		return token
+	end
+	def expect(type,&blk)
+		token = self.next
+		if(token != type)
+			syntax_error(blk.call(token)) if(blk)
+			syntax_error("unexpected: #{token.type}")
+		end
+		return token
+	end
+end
diff --git a/aos/build/queues/output/message_dec.rb b/aos/build/queues/output/message_dec.rb
new file mode 100644
index 0000000..0e957be
--- /dev/null
+++ b/aos/build/queues/output/message_dec.rb
@@ -0,0 +1,277 @@
+require "sha1"
+class Target::MessageDec < Target::Node
+	attr_accessor :name,:loc,:parent,:msg_hash
+	def initialize(name)
+		@name = name
+		@members = []
+	end
+	def extern=(value)
+		@extern=value
+	end
+	def get_name()
+		if(@parent)
+			return "#{@parent.get_name}.#{@name}"
+		else
+			return "#{@name}"
+		end
+	end
+	def add_member(member)
+		@members << member
+	end
+	def create_Print(type_class,cpp_tree)
+		member_func = CPP::MemberFunc.new(type_class,"size_t","Print")
+		type_class.add_member(member_func)
+		member_func.args << "char *buffer"
+		member_func.args << "size_t length"
+		member_func.const = true
+                format = "\""
+                args = []
+		@members.each do |elem|
+			format += ", "
+			format += elem.toPrintFormat()
+			if (elem.type == 'bool')
+				args.push("#{elem.name} ? 't' : 'f'")
+			else
+				args.push(elem.name)
+			end
+		end
+                format += "\""
+                member_func.suite << "size_t super_size = ::aos::Message::Print(buffer, length)"
+                member_func.suite << "buffer += super_size"
+                member_func.suite << "length -= super_size"
+                member_func.suite << "return super_size + snprintf(buffer, length, " + ([format] + args).join(", ") + ")";
+	end
+	def create_Serialize(type_class,cpp_tree)
+		member_func = CPP::MemberFunc.new(type_class,"size_t","Serialize")
+		type_class.add_member(member_func)
+		#cpp_tree.cc_file.add_funct(member_func)
+		member_func.args << "char *buffer"
+		member_func.suite << "::aos::Message::Serialize(buffer)"
+		member_func.const = true
+		offset = 0
+		@members.each do |elem|
+			elem.toNetwork(offset,member_func.suite)
+			offset += elem.size;
+		end
+                member_func.suite << "return Size()"
+	end
+	def create_Deserialize(type_class,cpp_tree)
+		member_func = CPP::MemberFunc.new(type_class,"size_t","Deserialize")
+		type_class.add_member(member_func)
+		#cpp_tree.cc_file.add_funct(member_func)
+		member_func.args << "const char *buffer"
+		member_func.suite << "::aos::Message::Deserialize(buffer)"
+		offset = 0
+		@members.each do |elem|
+			elem.toHost(offset,member_func.suite)
+			offset += elem.size;
+		end
+                member_func.suite << "return Size()"
+	end
+	def create_Zero(type_class,cpp_tree)
+		member_func = CPP::MemberFunc.new(type_class,"void","Zero")
+		type_class.add_member(member_func)
+		#cpp_tree.cc_file.add_funct(member_func)
+		@members.each do |elem|
+			elem.zeroCall(member_func.suite)
+		end
+		member_func.suite << "::aos::Message::Zero()"
+	end
+	def create_Size(type_class,cpp_tree)
+		member_func = CPP::MemberFunc.new(type_class,"size_t","Size")
+		member_func.inline = true
+        member_func.static = true
+		type_class.add_member(member_func.forward_dec)
+		#cpp_tree.cc_file.add_funct(member_func)
+		size = 0
+		@members.each do |elem|
+			size += elem.size
+		end
+		member_func.suite << CPP::Return.new(CPP::Add.new(size,
+							"::aos::Message::Size()"))
+	end
+	def self.builder_loc(loc)
+		return @builder_loc if(@builder_loc)
+		return @builder_loc = loc.root.get_make("aos")
+	end
+	def type_name(builder_loc,name)
+		if(builder_loc == @loc) #use relative name
+			return name
+		else #use full name
+			return @loc.to_cpp_id(name)
+		end
+	end
+	def create(cpp_tree)
+		return self if(@extern)
+		orig_namespace = namespace = cpp_tree.get(@loc)
+		name = ""
+		if(namespace.class < Types::Type) #is nested
+			name = namespace.name + "_" + name
+			namespace = namespace.space
+		end
+		type_class = namespace.add_struct(name + @name)
+		if(name.length > 0)
+			orig_namespace.add_member(:public, Types::TypeDef.new(type_class,@name))
+		end
+		cpp_tree.set(self,type_class)
+		type_class.set_parent("public ::aos::Message")
+		ts = (@members.collect { |elem|
+			elem.type + " " + elem.name
+		}).join(";")
+		self.msg_hash = "0x#{SHA1.hexdigest(ts)[-8..-1]}"
+		type_class.add_member("enum {kQueueLength = 1234, kHash = #{self.msg_hash}}")
+		@members.each do |elem|
+			type_class.add_member(elem.create_usage(cpp_tree))
+		end
+
+		create_Serialize(type_class,cpp_tree)
+		create_Deserialize(type_class,cpp_tree)
+		create_Zero(type_class,cpp_tree)
+		create_Size(type_class,cpp_tree)
+		create_Print(type_class,cpp_tree)
+
+		b_namespace = cpp_tree.get(b_loc = self.class.builder_loc(@loc))
+
+		safetemplate = Types::TemplateClass.new(b_namespace,"SafeMessageBuilder")
+		ifdef_statement = Types::PreprocessorIf.new(b_namespace,"!defined(__VXWORKS__) && !defined(__TEST_VXWORKS__)")
+		ifdef_statement.add_member(safetemplate)
+		b_namespace.add(ifdef_statement)
+		template = b_namespace.add_template("MessageBuilder")
+		safetemplate.spec_args << t = @loc.to_cpp_id(@name)
+		template.spec_args << t = @loc.to_cpp_id(@name)
+		safemsg_ptr_t = "SafeScopedMessagePtr< #{t}>"
+		msg_ptr_t = "ScopedMessagePtr< #{t}>"
+		safemsg_bld_t = "SafeMessageBuilder< #{t}>"
+		msg_bld_t = "MessageBuilder< #{t}>"
+		safetemplate.add_member(:private,"#{safemsg_ptr_t} msg_ptr_")
+		template.add_member(:private,"#{msg_ptr_t} msg_ptr_")
+		namespace.add_pre_swig("%feature(\"valuewrapper\") #{safemsg_bld_t}")
+		template.add_member(:private,"#{msg_bld_t}(const #{msg_bld_t}&)")
+		template.add_member(:private,"void operator=(const #{msg_bld_t}&)")
+		safetemplate.add_member(:private,"friend class ::aos::Queue< #{t}>")
+		template.add_member(:private,"friend class ::aos::Queue< #{t}>")
+
+		cons = CPP::Constructor.new(template)
+		unsafe_cons = CPP::Constructor.new(template)
+		cons_ifdef_statement = CPP::PreprocessorIf.new(cons, unsafe_cons)
+		cons_ifdef_statement.name = "!defined(__VXWORKS__) && !defined(__TEST_VXWORKS__)"
+		template.add_member(:private,cons_ifdef_statement)
+		cons.args << "aos_queue *queue"
+		cons.args << "#{t} *msg"
+		unsafe_cons.args << "#{t} *msg"
+		cons.add_cons("msg_ptr_","queue","msg")
+		unsafe_cons.add_cons("msg_ptr_","msg")
+		cons = safetemplate.add_member(:private,CPP::Constructor.new(safetemplate))
+		cons.args << "aos_queue *queue"
+		cons.add_cons("msg_ptr_","queue")
+		safetemplate.public
+		template.public
+		DefineMembers(cpp_tree, safetemplate, safemsg_bld_t)
+		DefineMembers(cpp_tree, template, msg_bld_t)
+
+		java_type_name = java_type_name(cpp_tree)
+		namespace.add_post_swig("%template(#{java_type_name}) ::aos::Queue< #{t}>")
+		namespace.add_post_swig("%template(#{java_ptr_name(cpp_tree)}) ::aos::SafeScopedMessagePtr< #{t}>")
+		namespace.add_post_swig("%template(#{java_builder_name(cpp_tree)}) ::aos::SafeMessageBuilder< #{t}>")
+		# TODO(aschuh): Figure out why this doesn't work and fix it.
+		#namespace.add_post_swig("%typemap(javabase) #{@name} \"aos.Message\"")
+
+	end
+	def DefineMembers(cpp_tree, template, msg_bld_t) 
+		send = template.def_func("bool","Send")
+		send.suite << CPP::Return.new("msg_ptr_.Send()")
+		@members.each do |elem|
+=begin
+			MessageBuilder<frc971::control_loops::Drivetrain::Goal> &steering(
+				      double steering) {
+				    msg_ptr_->steering = steering;
+					    return *this;
+						  }
+=end
+			setter = template.def_func(msg_bld_t,"&#{elem.name}")
+			setter.args << elem.create_usage(cpp_tree)
+			elem.set_message_builder(setter.suite)
+			setter.suite << CPP::Return.new("*this")
+
+		end
+	end
+	def java_ptr_name(cpp_tree)
+		return "#{@name}MessagePtr"
+	end
+	def java_builder_name(cpp_tree)
+		return "#{@name}MessageBuilder"
+	end
+	def java_type_name(cpp_tree)
+		return "#{@name}Queue"
+	end
+end
+class Target::MessageElement < Target::Node
+	attr_accessor :name,:loc,:size,:zero,:type,:printformat
+	def initialize(type,name)
+		@type,@name = type,name
+	end
+	def toPrintFormat()
+		return printformat
+	end
+	def create_usage(cpp_tree)
+		"#{@type} #{@name}"
+	end
+	def toNetwork(offset,suite)
+		offset = (offset == 0) ? "" : "#{offset} + "
+		suite << f_call = CPP::FuncCall.build("to_network",
+									 "&#{@name}",
+									 "&buffer[#{offset}::aos::Message::Size()]")
+		f_call.args.dont_wrap = true
+	end
+	def toHost(offset,suite)
+		offset = (offset == 0) ? "" : "#{offset} + "
+		suite << f_call = CPP::FuncCall.build("to_host",
+									 "&buffer[#{offset}::aos::Message::Size()]",
+									 "&#{@name}")
+		f_call.args.dont_wrap = true
+	end
+	def set_message_builder(suite)
+		suite << "msg_ptr_->#{@name} = #{@name}"
+	end
+
+	def zeroCall(suite)
+		suite << CPP::Assign.new(@name,@zero)
+	end
+end
+class Target::MessageArrayElement < Target::Node
+	attr_accessor :name,:loc,:size,:zero,:type
+	def initialize(type,name,length)
+		@type,@name,@length = type,name,length
+	end
+	def create_usage(cpp_tree)
+		"#{@type} #{@name}[#@length]"
+	end
+	def type()
+		"#{@type}[#@length]"
+	end
+	def size()
+		@size * @length
+	end
+	def toNetwork(offset,suite)
+		offset = (offset == 0) ? "" : "#{offset} + "
+		suite << for_stmt = CPP::For.new("int i = 0","i < #{@length}","i++")
+		for_stmt.suite << f_call = CPP::FuncCall.build("to_network",
+									 "&(#{@name}[i])",
+									 "&buffer[i + #{offset}::aos::Message::Size()]")
+		f_call.args.dont_wrap = true
+	end
+	def toHost(offset,suite)
+		offset = (offset == 0) ? "" : "#{offset} + "
+		suite << for_stmt = CPP::For.new("int i = 0","i < #{@length}","i++")
+		for_stmt.suite << f_call = CPP::FuncCall.build("to_host",
+									 "&buffer[i + #{offset}::aos::Message::Size()]",
+									 "&(#{@name}[i])")
+		f_call.args.dont_wrap = true
+	end
+	def set_message_builder(suite)
+		suite << "memcpy(msg_ptr_->#{@name},#{@name},#@length)"
+	end
+	def zeroCall(suite)
+		suite << "memset(#@name,0,#{size()})"
+	end
+end
diff --git a/aos/build/queues/output/q_file.rb b/aos/build/queues/output/q_file.rb
new file mode 100644
index 0000000..af76ee1
--- /dev/null
+++ b/aos/build/queues/output/q_file.rb
@@ -0,0 +1,187 @@
+require "sha1"
+module Target
+end
+class Target::Node
+	attr_accessor :created_by
+end
+class Target::QFile < Target::Node
+	def initialize() #needs to know repo_path, 
+		@class_types = []
+	end
+	def add_type(type)
+		@class_types << type
+	end
+	def extern=(value)
+		@class_types.each do |type|
+			type.extern=value
+		end
+	end
+	def make_cpp_tree(rel_path)
+		cpp_tree = DepFilePair.new(rel_path)
+		cpp_tree.add_header_include("\"aos/common/macros.h\"")
+		cpp_tree.add_header_include("\"aos/common/queue.h\"")
+		@class_types.each do |type|
+			cpp_tree.get(type)
+		end
+		return cpp_tree
+	end
+end
+class Target::QInclude < Target::Node
+	def initialize(path)
+		@path = path
+	end
+	def create(cpp_tree)
+#		inc = cpp_tree.header.add_include("\"#{@path}\"")
+		inc = cpp_tree.add_header_include("\"#{@path}\"")
+		cpp_tree.set(self,inc)
+	end
+end
+class Target::QueueGroupDec < Target::Node
+	attr_accessor :name,:loc,:parent,:queues
+	def initialize(name)
+		@name = name
+		@queues = []
+		@subs = {}
+	end
+	def root()
+		@parent.root()
+	end
+	def []=(key,val)
+		#puts "#{key}= #{val}"
+		@subs[key] = val
+	end
+	def extern=(value)
+		@extern=value
+	end
+	def get_name()
+		if(@parent)
+			return "#{@parent.get_name}.#{@name}"
+		else
+			return "#{@name}"
+		end 
+	end
+	def to_cpp_id(id)
+		name = "#{@name}::#{id}"
+		return @parent.to_cpp_id(name) if(@parent)
+		return name
+	end
+	def [](key)
+		#puts "#{key}"
+		@subs[key]
+	end
+	def add_queue(queue)
+		@queues.push(queue)
+	end
+	def hash_with_name(name)
+		ts = (@queues.collect { |queue|
+			queue.msg_hash()
+		}).join("") + name
+		return "0x#{SHA1.hexdigest(ts)[-8..-1]}"
+	end
+	def create(cpp_tree)
+		return if(@extern)
+		namespace = cpp_tree.get(@loc)
+		type_class = Types::Class.new(namespace,@name)
+		cpp_tree.set(self,type_class)  #breaks infinite recursion
+		type_class.set_parent("public ::aos::QueueGroup")
+		@queues.each do |queue|
+			type_class.add_member(:public,queue.create_usage(cpp_tree))
+			namespace.add_pre_swig("%immutable #{@name}::#{queue.name}")
+		end
+		create_Constructor(type_class,cpp_tree)
+		namespace.add(type_class)
+	end
+	def create_Constructor(type_class,cpp_tree)
+		member_func = CPP::Constructor.new(type_class)
+		type_class.add_member(:public,member_func)
+		#cpp_tree.cc_file.add_funct(member_func)
+		member_func.args << "const char *name";
+		member_func.args << "uint32_t hash";
+		member_func.add_cons("::aos::QueueGroup","name", "hash")
+		@queues.each do |queue|
+			member_func.args << "const char *#{queue.name}_name";
+			member_func.add_cons(queue.name,"#{queue.name}_name")
+		end
+	end
+end
+class Target::QueueGroup < Target::Node
+	attr_accessor :name,:loc
+	def initialize(type,name)
+		@type,@name = type,name
+	end
+	def type_name()
+		if(@type.loc == @loc) #use relative name
+			return @type.name
+		else #use full name
+			return @type.loc.to_cpp_id(@type.name)
+		end 
+	end
+	def create(cpp_tree)
+		namespace = cpp_tree.get(@loc)
+		type = cpp_tree.get(@type)
+		cpp_tree.set(self,self)
+		namespace.add_cc("static #{type_name} *#{@name}_ptr")
+		counter = "#{@name}_counter"
+		namespace.add_cc("static int #{counter}")
+
+		str = <<COMMENT_END
+Schwarz counter to construct and destruct the #{@name} object.
+Must be constructed before &#{@name} is constructed so that #{@name}_ptr
+is valid so we can store a reference to the object.
+COMMENT_END
+		str.split(/\n/).each do |str_sec|
+			namespace.class_comment(str_sec)
+		end
+		init_class = namespace.add_class("InitializerFor_" + @name).add_dep(type)
+		
+
+		init_class.add_cc_comment(
+        "The counter is initialized at load-time, i.e., before any of the static",
+		"objects are initialized.")
+
+
+		cons = CPP::Constructor.new(init_class)
+		init_class.add_member(:public,cons)
+		cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
+		if_stmt.suite << "printf(#{"making a #{@name}!\n".inspect})"
+
+		cons_call = CPP::FuncCall.new("new #{type_name}")
+		cons_call.args.push(@loc.queue_name(@name).inspect)
+
+		cons_call.args.push(@type.hash_with_name(@loc.queue_name(@name).inspect))
+		@type.queues.collect do |queue|
+			cons_call.args.push(@loc.queue_name(@name + "." + queue.name).inspect)
+		end
+		if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
+		if_stmt.else_suite << CPP::FuncCall.build("printf","already made a #{@name}\n".inspect)
+
+
+		destruct = CPP::Destructor.new(init_class)
+		destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
+		if_stmt.suite << "printf(#{"deleting a #{@name}!! :) !!\n".inspect})"
+		if_stmt.suite << "delete #{@name}_ptr"
+		if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
+
+		init_class.add_member(:public,destruct)
+		init_class.static = true
+		init_class.dec = @name + "_initializer";
+
+		str = <<COMMENT_END
+Create a reference to the new object in the pointer.  Since we have already
+created the initializer
+COMMENT_END
+		comments = str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}
+		comments << "static UNUSED_VARIABLE #{type_name} &#{@name} = " +
+		            "#{@name}_initializer.get()"
+		namespace.add_post_swig("%immutable #{@name}_initializer")
+		namespace.add_post_swig(CPP::SwigPragma.new("java", "modulecode", CPP::Suite.new(["public static final #{@name} = get#{@name.capitalize}_initializer().get()"])))
+		ifdef_statement = CPP::IfnDef.new(CPP::Suite.new(comments))
+		ifdef_statement.name = "SWIG"
+		namespace.add(ifdef_statement)
+
+
+		get = init_class.def_func(type_name,"get") #.add_dep(type)
+		get.pre_func_types = "&"
+		get.suite << CPP::Return.new("*#{@name}_ptr")
+	end
+end
diff --git a/aos/build/queues/output/queue_dec.rb b/aos/build/queues/output/queue_dec.rb
new file mode 100644
index 0000000..8c3bd51
--- /dev/null
+++ b/aos/build/queues/output/queue_dec.rb
@@ -0,0 +1,104 @@
+class Target::QueueDec < Target::Node
+	attr_accessor :name,:loc
+	def initialize(type,name)
+		@type,@name = type,name
+	end
+	def msg_hash()
+		return @type.msg_hash
+	end
+	def java_type_name(cpp_tree)
+		type = cpp_tree.get(@type)
+		return "#{type.name}Queue"
+	end
+	def full_message_name(cpp_tree)
+		type = cpp_tree.get(@type)
+		return @type.loc.to_cpp_id(type.name)
+	end
+	def full_ptr_name(cpp_tree)
+		return "::aos::SafeScopedMessagePtr< #{full_message_name(cpp_tree)}>"
+	end
+	def full_builder_name(cpp_tree)
+		return "::aos::MessageBuilder< #{full_message_name(cpp_tree)}>"
+	end
+	def full_type_name(cpp_tree)
+		return "::aos::Queue< #{full_message_name(cpp_tree)}>"
+	end
+	def type_name(cpp_tree,queue_type = "::aos::Queue")
+		type = cpp_tree.get(@type)
+		if(@type.loc == @loc) #use relative name
+			return "#{queue_type}<#{type.name}>"
+		else #use full name
+			return "#{queue_type}< #{@type.loc.to_cpp_id(type.name)}>"
+		end
+	end
+	def create_usage(cpp_tree)
+		"#{type_name(cpp_tree)} #{@name}"
+	end
+	def create(cpp_tree)
+		namespace = cpp_tree.get(@loc)
+		type = cpp_tree.get(@type)
+		cpp_tree.set(self,self)
+		type_name = type_name(cpp_tree)
+		full_type_name = full_type_name(cpp_tree)
+		namespace.add_cc("static #{type_name} *#{@name}_ptr")
+		counter = "#{@name}_counter"
+		namespace.add_cc("static int #{counter}")
+
+		str = <<COMMENT_END
+Schwarz counter to construct and destruct the #{@name} queue.
+Must be constructed before &#{@name} is constructed so that #{@name}_ptr
+is valid so we can store a reference to the object.
+COMMENT_END
+		str.split(/\n/).each do |str_sec|
+			namespace.class_comment(str_sec)
+		end
+		init_class = namespace.add_class("InitializerFor_" + @name)
+
+		init_class.add_cc_comment(
+        "The counter is initialized at load-time, i.e., before any of the static",
+		"objects are initialized.")
+
+
+		cons = CPP::Constructor.new(init_class)
+		init_class.add_member(:public,cons)
+		cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
+		if_stmt.suite << "printf(#{"making a #{@name} queue!\n".inspect})"
+
+		cons_call = CPP::FuncCall.new("new #{type_name}")
+		cons_call.args.push(@loc.queue_name(@name).inspect)
+		if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
+		if_stmt.else_suite << CPP::FuncCall.build("printf","already made a #{@name}\n".inspect)
+
+
+		destruct = CPP::Destructor.new(init_class)
+		init_class.add_member(:public,destruct)
+		destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
+		if_stmt.suite << "printf(#{"deleting a #{@name}!! :) !!\n".inspect})"
+		if_stmt.suite << "delete #{@name}_ptr"
+		if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
+
+		init_class.static = true
+		init_class.dec = @name + "_initializer";
+
+		str = <<COMMENT_END
+Create a reference to the new object in the pointer.  Since we have already
+created the initializer
+COMMENT_END
+		comments = str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}
+		comments << "static UNUSED_VARIABLE #{type_name} &#{@name} = " +
+		            "#{@name}_initializer.get()"
+		namespace.add_post_swig("%immutable #{@name}_initializer")
+		java_type_name = java_type_name(cpp_tree)
+		namespace.add_post_swig(CPP::SwigPragma.new("java", "modulecode", CPP::Suite.new(["public static final #{java_type_name} #{@name} = get#{@name.capitalize}_initializer().get()"])))
+
+		ifdef_statement = CPP::IfnDef.new(CPP::Suite.new(comments))
+		ifdef_statement.name = "SWIG"
+		namespace.add(ifdef_statement)
+
+		get = init_class.def_func(full_type_name,"get")
+		get.pre_func_types = "&"
+		get.suite << CPP::Return.new("*#{@name}_ptr")
+		
+	end
+end
+
diff --git a/aos/build/swig.gypi b/aos/build/swig.gypi
new file mode 100644
index 0000000..2e99a95
--- /dev/null
+++ b/aos/build/swig.gypi
@@ -0,0 +1,73 @@
+# Include this file in any target that needs to use swig wrappers.
+#
+# To use, create a target of the following form:
+# {
+#   'target_name': 'my_target_javawrap',
+#   'type': 'static_library', # or any other type that can handle .cc files
+#   'sources': [
+#     'aos/example/target.swig',
+#   ],
+#   'variables': {
+#     'package': 'aos.test',
+#   },
+#   'includes': ['path/to/swig.gypi'],
+# },
+# Code that depends on this target will be able to use the swig wrapped
+# java classes.
+#
+# using <http://src.chromium.org/svn/trunk/src/build/protoc.gypi> as an
+# example of how this should work
+{
+  'variables': {
+    'prefix_dir': '<(SHARED_INTERMEDIATE_DIR)/',
+    'out_dir': '<(prefix_dir)/<(_target_name)/',
+    'output_java_wrap': '<(out_dir)/<(RULE_INPUT_ROOT)_wrap.cc',
+    'java_dir': '<(out_dir)/<(RULE_INPUT_ROOT)_java',
+    'no_rsync': 1,
+  },
+  'rules': [
+    {
+      'rule_name': 'genswig',
+      'extension': 'swig',
+      'outputs': [
+        '<(output_java_wrap)',
+        '<(java_dir)',
+      ],
+      'action': [
+        '<(DEPTH)/aos/build/mkdirswig',
+        '<(java_dir)',
+        '-I<(DEPTH)',
+        '-outdir', ' <(java_dir)',
+        '-package', '<(package)',
+        '-o', '<(output_java_wrap)',
+        '-c++',
+        '-Wall',
+        '-Wextra',
+        '-java',
+        '<(RULE_INPUT_PATH)'],
+      'message': 'Generating C++ code from <(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).swig',
+      'process_outputs_as_sources': 1,
+    },
+  ],
+  'cflags': [
+# For the swig-generated C++ code.
+    '-fno-strict-aliasing',
+    '-Wno-cast-qual',
+  ],
+  'include_dirs': [
+    '<(prefix_dir)/<(_target_name)',
+    '/usr/lib/jvm/default-java/include',
+    '/usr/lib/jvm/default-java/include/linux',
+  ],
+  'direct_dependent_settings': {
+    'include_dirs': [
+      '<(prefix_dir)/<(_target_name)',
+      '/usr/lib/jvm/default-java/include',
+      '/usr/lib/jvm/default-java/include/linux',
+    ],
+    'variables': {
+      'gen_srcdir_parents': ['<(out_dir)'],
+    },
+  },
+  'hard_dependency': 1,
+}