Index: vtcross/branches/nikhil/crossmodel2/configure.ac
===================================================================
--- vtcross/branches/nikhil/crossmodel2/configure.ac	(revision 457)
+++ vtcross/branches/nikhil/crossmodel2/configure.ac	(revision 457)
@@ -0,0 +1,52 @@
+dnl Copyright 2009 Virginia Polytechnic Institute and State University  
+dnl 
+dnl Licensed under the Apache License, Version 2.0 (the "License"); 
+dnl you may not use this file except in compliance with the License. 
+dnl You may obtain a copy of the License at 
+dnl 
+dnl http://www.apache.org/licenses/LICENSE-2.0 
+dnl
+dnl Unless required by applicable law or agreed to in writing, software 
+dnl distributed under the License is distributed on an "AS IS" BASIS, 
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+dnl See the License for the specific language governing permissions and 
+dnl limitations under the License. 
+
+
+AC_INIT([cross], [0.1.1])
+AM_INIT_AUTOMAKE([cross], [0.1.1])
+AM_CONFIG_HEADER([src/include/vtcross/config.h])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_SWIG
+AC_PROG_LIBTOOL
+AC_PROG_INSTALL
+
+AC_DISABLE_STATIC
+AM_PATH_PYTHON(2.5)
+SWIG_ENABLE_CXX
+SWIG_PYTHON
+
+AC_LANG_PUSH([C])
+AC_CHECK_LIB([sqlite3], [sqlite3_open], [], [AC_MSG_ERROR([Cannot find sqlite3 library!])])
+AC_LANG_POP
+
+
+# fix for older autotools that don't define these by default
+AC_SUBST(abs_top_srcdir)
+AC_SUBST(abs_top_builddir)
+
+
+AC_CONFIG_FILES(Makefile doc/Makefile src/Makefile src/shell/Makefile
+                src/shell/configs/Makefile src/libvtcross/Makefile
+	            src/cognitive_engines/Makefile src/cognitive_engines/CBR_CE/Makefile 
+                src/cognitive_engines/OSSIE_DEMO_CE/Makefile src/cognitive_engines/DSA_CE/Makefile 
+                src/policy_engines/Makefile src/service_management_layer/Makefile 
+                src/lib/tinyxml/Makefile  src/lib/socketcomm/Makefile src/include/Makefile
+                src/include/vtcross/Makefile src/include/tinyxml/Makefile
+                src/lib/Makefile src/libvtcross/swig/Makefile)
+AC_OUTPUT
+
Index: vtcross/branches/nikhil/crossmodel2/Makefile.common
===================================================================
--- vtcross/branches/nikhil/crossmodel2/Makefile.common	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/Makefile.common	(revision 411)
@@ -0,0 +1,17 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+CROSS_LA = ${abs_top_builddir}/src/libvtcross/libvtcross.la
+CROSS_SOCKETCOMM_LA = ${abs_top_builddir}/src/lib/socketcomm/libsocketcomm.la
+CROSS_XML_A = ${abs_top_builddir}/src/lib/tinyxml/libtinyxml.a
Index: vtcross/branches/nikhil/crossmodel2/.gitignore
===================================================================
--- vtcross/branches/nikhil/crossmodel2/.gitignore	(revision 226)
+++ vtcross/branches/nikhil/crossmodel2/.gitignore	(revision 226)
@@ -0,0 +1,40 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+*.[oad]
+*~
+*.swp
+
+# There are a ton of files created by autofoo and libtool that we don't care
+# about.  Ignore all of them.
+Makefile
+Makefile.in
+configure.in
+aclocal.m4
+config.guess
+config.log
+config.status
+config.sub
+configure
+src/include/vtcross/config.h
+src/include/vtcross/stamp-h1
+install-sh
+libtool
+ltmain.sh
+missing
+depcomp
+autom4te.cache/*
+m4/*
+*.in
+
+\.*
+
+# Binary files
+policy_demo
+cbr_demo
+shell_demo
+sml_demo
+libvtcross.la
+libvtcross.lo
+libvtcross_demo
Index: vtcross/branches/nikhil/crossmodel2/AUTHORS
===================================================================
--- vtcross/branches/nikhil/crossmodel2/AUTHORS	(revision 430)
+++ vtcross/branches/nikhil/crossmodel2/AUTHORS	(revision 430)
@@ -0,0 +1,6 @@
+Authors listed alphabetically:
+
+Benjamin Hilburn        - bhilburn@vt.edu
+Timothy Newman          - trnewman@vt.edu
+Warren Rodgers          - wrodgers3@gatech.edu
+
Index: vtcross/branches/nikhil/crossmodel2/config/swig_enable_cxx.m4
===================================================================
--- vtcross/branches/nikhil/crossmodel2/config/swig_enable_cxx.m4	(revision 323)
+++ vtcross/branches/nikhil/crossmodel2/config/swig_enable_cxx.m4	(revision 323)
@@ -0,0 +1,54 @@
+# ===========================================================================
+#            http://autoconf-archive.cryp.to/swig_enable_cxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   SWIG_ENABLE_CXX
+#
+# DESCRIPTION
+#
+#   Enable SWIG C++ support. This affects all invocations of $(SWIG).
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
+#   Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
+#   Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
+#   Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([SWIG_ENABLE_CXX],[
+        AC_REQUIRE([AC_PROG_SWIG])
+        AC_REQUIRE([AC_PROG_CXX])
+        SWIG="$SWIG -c++"
+])
Index: vtcross/branches/nikhil/crossmodel2/config/ac_python_devel.m4
===================================================================
--- vtcross/branches/nikhil/crossmodel2/config/ac_python_devel.m4	(revision 323)
+++ vtcross/branches/nikhil/crossmodel2/config/ac_python_devel.m4	(revision 323)
@@ -0,0 +1,322 @@
+# ===========================================================================
+#         http://www.nongnu.org/autoconf-archive/ac_python_devel.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AC_PYTHON_DEVEL([version])
+#
+# DESCRIPTION
+#
+#   Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
+#   in your configure.ac.
+#
+#   This macro checks for Python and tries to get the include path to
+#   'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
+#   output variables. It also exports $(PYTHON_EXTRA_LIBS) and
+#   $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+#
+#   You can search for some particular version of Python by passing a
+#   parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
+#   note that you *have* to pass also an operator along with the version to
+#   match, and pay special attention to the single quotes surrounding the
+#   version number. Don't use "PYTHON_VERSION" for this: that environment
+#   variable is declared as precious and thus reserved for the end-user.
+#
+#   This macro should work for all versions of Python >= 2.1.0. As an end
+#   user, you can disable the check for the python version by setting the
+#   PYTHON_NOVERSIONCHECK environment variable to something else than the
+#   empty string.
+#
+#   If you need to use this macro for an older Python version, please
+#   contact the authors. We're always open for feedback.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
+#   Copyright (c) 2009 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
+#   Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
+#   Copyright (c) 2009 Andrew Collier <colliera@ukzn.ac.za>
+#   Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
+#   Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([AC_PYTHON_DEVEL],[
+	#
+	# Allow the use of a (user set) custom python version
+	#
+	AC_ARG_VAR([PYTHON_VERSION],[The installed Python
+		version to use, for example '2.3'. This string
+		will be appended to the Python interpreter
+		canonical name.])
+
+	AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+	if test -z "$PYTHON"; then
+	   AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
+	   PYTHON_VERSION=""
+	fi
+
+	#
+	# Check for a version of Python >= 2.1.0
+	#
+	AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
+	ac_supports_python_ver=`$PYTHON -c "import sys; \
+		ver = sys.version.split ()[[0]]; \
+		print (ver >= '2.1.0')"`
+	if test "$ac_supports_python_ver" != "True"; then
+		if test -z "$PYTHON_NOVERSIONCHECK"; then
+			AC_MSG_RESULT([no])
+			AC_MSG_FAILURE([
+This version of the AC@&t@_PYTHON_DEVEL macro
+doesn't work properly with versions of Python before
+2.1.0. You may need to re-run configure, setting the
+variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+to something else than an empty string.
+])
+		else
+			AC_MSG_RESULT([skip at user request])
+		fi
+	else
+		AC_MSG_RESULT([yes])
+	fi
+
+	#
+	# if the macro parameter ``version'' is set, honour it
+	#
+	if test -n "$1"; then
+		AC_MSG_CHECKING([for a version of Python $1])
+		ac_supports_python_ver=`$PYTHON -c "import sys; \
+			ver = sys.version.split ()[[0]]; \
+			print (ver $1)"`
+		if test "$ac_supports_python_ver" = "True"; then
+	   	   AC_MSG_RESULT([yes])
+		else
+			AC_MSG_RESULT([no])
+			AC_MSG_ERROR([this package requires Python $1.
+If you have it installed, but it isn't the default Python
+interpreter in your system path, please pass the PYTHON_VERSION
+variable to configure. See ``configure --help'' for reference.
+])
+			PYTHON_VERSION=""
+		fi
+	fi
+
+	#
+	# Check if you have distutils, else fail
+	#
+	AC_MSG_CHECKING([for the distutils Python package])
+	ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+	if test -z "$ac_distutils_result"; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		AC_MSG_ERROR([cannot import Python module "distutils".
+Please check your Python installation. The error was:
+$ac_distutils_result])
+		PYTHON_VERSION=""
+	fi
+
+	#
+	# Check for Python include path
+	#
+	AC_MSG_CHECKING([for Python include path])
+	if test -z "$PYTHON_CPPFLAGS"; then
+		python_path=`$PYTHON -c "import distutils.sysconfig; \
+           		print (distutils.sysconfig.get_python_inc ());"`
+		if test -n "${python_path}"; then
+		   	python_path="-I$python_path"
+		fi
+		PYTHON_CPPFLAGS=$python_path
+	fi
+	AC_MSG_RESULT([$PYTHON_CPPFLAGS])
+	AC_SUBST([PYTHON_CPPFLAGS])
+
+	#
+	# Check for Python library path
+	#
+	AC_MSG_CHECKING([for Python library path])
+	if test -z "$PYTHON_LDFLAGS"; then
+		# (makes two attempts to ensure we've got a version number
+		# from the interpreter)
+		ac_python_version=`cat<<EOD | $PYTHON -
+
+# join all versioning strings, on some systems
+# major/minor numbers could be in different list elements
+from distutils.sysconfig import *
+ret = ''
+for e in get_config_vars ('VERSION'):
+	if (e != None):
+		ret += e
+print (ret)
+EOD`
+
+		if test -z "$ac_python_version"; then
+			if test -n "$PYTHON_VERSION"; then
+				ac_python_version=$PYTHON_VERSION
+			else
+				ac_python_version=`$PYTHON -c "import sys; \
+					print (sys.version[[:3]])"`
+			fi
+		fi
+
+		# Make the versioning information available to the compiler
+		AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+                                   [If available, contains the Python version number currently in use.])
+
+		# First, the library directory:
+		ac_python_libdir=`cat<<EOD | $PYTHON -
+
+# There should be only one
+import distutils.sysconfig
+for e in distutils.sysconfig.get_config_vars ('LIBDIR'):
+	if e != None:
+		print (e)
+		break
+EOD`
+
+		# Before checking for libpythonX.Y, we need to know
+		# the extension the OS we're on uses for libraries
+		# (we take the first one, if there's more than one fix me!):
+		ac_python_soext=`$PYTHON -c \
+		  "import distutils.sysconfig; \
+		  print (distutils.sysconfig.get_config_vars('SO')[[0]])"`
+
+		# Now, for the library:
+		ac_python_soname=`$PYTHON -c \
+		  "import distutils.sysconfig; \
+		  print (distutils.sysconfig.get_config_vars('LDLIBRARY')[[0]])"`
+
+		# Strip away extension from the end to canonicalize its name:
+		ac_python_library=`echo "$ac_python_soname" | sed "s/${ac_python_soext}$//"`
+
+		# This small piece shamelessly adapted from PostgreSQL python macro;
+		# credits goes to momjian, I think. I'd like to put the right name
+		# in the credits, if someone can point me in the right direction... ?
+		#
+		if test -n "$ac_python_libdir" -a -n "$ac_python_library" \
+			-a x"$ac_python_library" != x"$ac_python_soname"
+		then
+			# use the official shared library
+			ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
+			PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
+		else
+			# old way: use libpython from python_configdir
+			ac_python_libdir=`$PYTHON -c \
+			  "from distutils.sysconfig import get_python_lib as f; \
+			  import os; \
+			  print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
+			PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
+		fi
+
+		if test -z "PYTHON_LDFLAGS"; then
+			AC_MSG_ERROR([
+  Cannot determine location of your Python DSO. Please check it was installed with
+  dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
+			])
+		fi
+	fi
+	AC_MSG_RESULT([$PYTHON_LDFLAGS])
+	AC_SUBST([PYTHON_LDFLAGS])
+
+	#
+	# Check for site packages
+	#
+	AC_MSG_CHECKING([for Python site-packages path])
+	if test -z "$PYTHON_SITE_PKG"; then
+		PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
+		        print (distutils.sysconfig.get_python_lib(0,0));"`
+	fi
+	AC_MSG_RESULT([$PYTHON_SITE_PKG])
+	AC_SUBST([PYTHON_SITE_PKG])
+
+	#
+	# libraries which must be linked in when embedding
+	#
+	AC_MSG_CHECKING(python extra libraries)
+	if test -z "$PYTHON_EXTRA_LIBS"; then
+	   PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+                conf = distutils.sysconfig.get_config_var; \
+                print (conf('LOCALMODLIBS') + ' ' + conf('LIBS'))"`
+	fi
+	AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
+	AC_SUBST(PYTHON_EXTRA_LIBS)
+
+	#
+	# linking flags needed when embedding
+	#
+	AC_MSG_CHECKING(python extra linking flags)
+	if test -z "$PYTHON_EXTRA_LDFLAGS"; then
+		PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
+			conf = distutils.sysconfig.get_config_var; \
+			print (conf('LINKFORSHARED'))"`
+	fi
+	AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
+	AC_SUBST(PYTHON_EXTRA_LDFLAGS)
+
+	#
+	# final check to see if everything compiles alright
+	#
+	AC_MSG_CHECKING([consistency of all components of python development environment])
+	# save current global flags
+	ac_save_LIBS="$LIBS"
+	ac_save_CPPFLAGS="$CPPFLAGS"
+	LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
+	CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
+	AC_LANG_PUSH([C])
+	AC_LINK_IFELSE([
+		AC_LANG_PROGRAM([[#include <Python.h>]],
+				[[Py_Initialize();]])
+		],[pythonexists=yes],[pythonexists=no])
+	AC_LANG_POP([C])
+	# turn back to default flags
+	CPPFLAGS="$ac_save_CPPFLAGS"
+	LIBS="$ac_save_LIBS"
+
+	AC_MSG_RESULT([$pythonexists])
+
+        if test ! "x$pythonexists" = "xyes"; then
+	   AC_MSG_FAILURE([
+  Could not link test program to Python. Maybe the main Python library has been
+  installed in some non-standard library path. If so, pass it to configure,
+  via the LDFLAGS environment variable.
+  Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
+  ============================================================================
+   ERROR!
+   You probably have to install the development version of the Python package
+   for your distribution.  The exact name of this package varies among them.
+  ============================================================================
+	   ])
+	  PYTHON_VERSION=""
+	fi
+
+	#
+	# all done!
+	#
+])
Index: vtcross/branches/nikhil/crossmodel2/config/swig_python.m4
===================================================================
--- vtcross/branches/nikhil/crossmodel2/config/swig_python.m4	(revision 323)
+++ vtcross/branches/nikhil/crossmodel2/config/swig_python.m4	(revision 323)
@@ -0,0 +1,65 @@
+# ===========================================================================
+#              http://autoconf-archive.cryp.to/swig_python.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   SWIG_PYTHON([use-shadow-classes = {no, yes}])
+#
+# DESCRIPTION
+#
+#   Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), and
+#   $(SWIG_PYTHON_OPT) output variables.
+#
+#   $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate code
+#   for Python. Shadow classes are enabled unless the value of the optional
+#   first argument is exactly 'no'. If you need multi module support
+#   (provided by the SWIG_MULTI_MODULE_SUPPORT macro) use
+#   $(SWIG_PYTHON_LIBS) to link against the appropriate library. It contains
+#   the SWIG Python runtime library that is needed by the type check system
+#   for example.
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
+#   Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
+#   Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
+#   Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([SWIG_PYTHON],[
+        AC_REQUIRE([AC_PROG_SWIG])
+        AC_REQUIRE([AC_PYTHON_DEVEL])
+        test "x$1" != "xno" || swig_shadow=" -noproxy"
+        AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow])
+        AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS])
+])
Index: vtcross/branches/nikhil/crossmodel2/config/ac_pkg_swig.m4
===================================================================
--- vtcross/branches/nikhil/crossmodel2/config/ac_pkg_swig.m4	(revision 323)
+++ vtcross/branches/nikhil/crossmodel2/config/ac_pkg_swig.m4	(revision 323)
@@ -0,0 +1,118 @@
+# ===========================================================================
+#           http://www.nongnu.org/autoconf-archive/ac_pkg_swig.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AC_PROG_SWIG([major.minor.micro])
+#
+# DESCRIPTION
+#
+#   This macro searches for a SWIG installation on your system. If found you
+#   should call SWIG via $(SWIG). You can use the optional first argument to
+#   check if the version of the available SWIG is greater than or equal to
+#   the value of the argument. It should have the format: N[.N[.N]] (N is a
+#   number between 0 and 999. Only the first N is mandatory.)
+#
+#   If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
+#   the swig package is this version number or higher.
+#
+#   In configure.in, use as:
+#
+#     AC_PROG_SWIG(1.3.17)
+#     SWIG_ENABLE_CXX
+#     SWIG_MULTI_MODULE_SUPPORT
+#     SWIG_PYTHON
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
+#   Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
+#   Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
+#   Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([AC_PROG_SWIG],[
+        AC_PATH_PROG([SWIG],[swig])
+        if test -z "$SWIG" ; then
+                AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
+                SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
+        elif test -n "$1" ; then
+                AC_MSG_CHECKING([for SWIG version])
+                [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
+                AC_MSG_RESULT([$swig_version])
+                if test -n "$swig_version" ; then
+                        # Calculate the required version number components
+                        [required=$1]
+                        [required_major=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_major" ; then
+                                [required_major=0]
+                        fi
+                        [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                        [required_minor=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_minor" ; then
+                                [required_minor=0]
+                        fi
+                        [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                        [required_patch=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_patch" ; then
+                                [required_patch=0]
+                        fi
+                        # Calculate the available version number components
+                        [available=$swig_version]
+                        [available_major=`echo $available | sed 's/[^0-9].*//'`]
+                        if test -z "$available_major" ; then
+                                [available_major=0]
+                        fi
+                        [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                        [available_minor=`echo $available | sed 's/[^0-9].*//'`]
+                        if test -z "$available_minor" ; then
+                                [available_minor=0]
+                        fi
+                        [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                        [available_patch=`echo $available | sed 's/[^0-9].*//'`]
+                        if test -z "$available_patch" ; then
+                                [available_patch=0]
+                        fi
+                        if test $available_major -ne $required_major \
+                                -o $available_minor -ne $required_minor \
+                                -o $available_patch -lt $required_patch ; then
+                                AC_MSG_WARN([SWIG version >= $1 is required.  You have $swig_version.  You should look at http://www.swig.org])
+                                SWIG='echo "Error: SWIG version >= $1 is required.  You have '"$swig_version"'.  You should look at http://www.swig.org" ; false'
+                        else
+                                AC_MSG_NOTICE([SWIG executable is '$SWIG'])
+                                SWIG_LIB=`$SWIG -swiglib`
+                                AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
+                        fi
+                else
+                        AC_MSG_WARN([cannot determine SWIG version])
+                        SWIG='echo "Error: Cannot determine SWIG version.  You should look at http://www.swig.org" ; false'
+                fi
+        fi
+        AC_SUBST([SWIG_LIB])
+])
Index: vtcross/branches/nikhil/crossmodel2/doc/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/doc/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/doc/Makefile.am	(revision 411)
@@ -0,0 +1,13 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
Index: vtcross/branches/nikhil/crossmodel2/doc/doxygen/Doxyfile
===================================================================
--- vtcross/branches/nikhil/crossmodel2/doc/doxygen/Doxyfile	(revision 520)
+++ vtcross/branches/nikhil/crossmodel2/doc/doxygen/Doxyfile	(revision 520)
@@ -0,0 +1,1560 @@
+# Doxyfile 1.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Cognitive Radio Open Source Systems (CROSS)"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ./output
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set
+# FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../../src
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.vhd \
+                         *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = ../../src/lib/tinyxml \
+                         ../../src/cross-examples \
+                         ../../src/libvtcross/swig \
+                         ../../src/include/tinyxml
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) 
+# there is already a search function so this one should typically 
+# be disabled.
+
+SEARCHENGINE           = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR.cpp	(revision 554)
@@ -0,0 +1,321 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file contains the default implementation of the CBR class, defined in
+ * the cbr.h include file.  This implementation is compiled into a static
+ * library which can be used as as backend for any cognitive engine. */
+
+
+#include "vtcross/cbr.h"
+#include <iostream>
+
+using namespace std;
+
+
+/* This is an internal debugging function used by some sqlite3 function calls.
+ *  It is not used otherwise in the CROSS codebase. */
+int32_t 
+callback(void *notUsed, int32_t argc, char **argv, char **azColName)
+{
+    for(size_t i = 0; i < argc; i++) {
+        LOG("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+    }
+    LOG("\n");
+
+    return 0;
+}
+
+
+CBR::CBR(string _filename, string _tablename, string _cols[], uint32_t _len)
+{
+    /* Store database properties. */
+    filename = _filename;
+    tablename = _tablename;
+    numColumns = _len;
+
+    /* Create the database (or open it if it already exists). */
+    OpenDatabase();
+
+    /* Generate the command that will create the initial table within the
+     * CROSS database. */
+    command = "CREATE TABLE " + tablename + "(";
+    for(size_t i = 0; i < numColumns; i++) {
+        command += _cols[i] + " FLOAT";
+
+        /* If this column is not the last entry, add a comma to the command in
+         * preperation for the next entry. */
+        if(i != numColumns - 1)
+            command += ", ";
+    }
+    command += ");";
+
+    /* Execute the generated command. At this point, the database is ready for
+     * use. */
+    ExecuteCommand();
+
+    std::cout << "Table Created" << std::endl;
+}
+
+
+CBR::CBR(string _filename, string _tablename, string _cols[], \
+        string _primcols[], uint32_t _len, uint32_t _primlen)
+{
+    /* Store database properties. */
+    filename = _filename;
+    tablename = _tablename;
+    numColumns = _len;
+
+    /* Create the database (or open it if it already exists). */
+    OpenDatabase();
+
+    /* Generate the command that will create the initial table within the
+     * CROSS database with primary keys. */
+    command = "CREATE TABLE " + tablename + "(";
+    for(size_t i = 0; i < numColumns; i++) {
+        command += _cols[i] + " FLOAT, ";
+    }
+
+    command += "PRIMARY KEY (";
+    for(size_t j = 0; j < _primlen; j++) {
+        command += _primcols[j];
+
+        /* If this column is not the last entry, add a comma to the command in
+         * preperation for the next entry. */
+        if(j != _primlen - 1)
+            command += ", ";
+    }
+    command += "));";
+
+    /* Execute the generated command. At this point, the database is ready for
+     * use. */
+    ExecuteCommand();
+}
+
+
+CBR::~CBR()
+{  
+    /* Generate the sqlite command to delete a table and all of its contents,
+     * and then execute it. */
+    command = "drop table " + tablename;
+    ExecuteCommand();
+
+    /* Tell sqlite to clean up the database. */
+    command = "vacuum";
+    ExecuteCommand();
+}
+
+
+int32_t 
+CBR::OpenDatabase()
+{
+    int32_t rc = sqlite3_open(filename.c_str(), &db);
+    if(rc) {
+        WARNING("Can't open database: %s\n", sqlite3_errmsg(db));
+        sqlite3_close(db);
+        exit(1);
+    }
+
+    return rc;
+}
+
+
+int32_t
+CBR::ExecuteCommand()
+{
+    char *zErrMsg = 0;
+
+    int32_t rc = sqlite3_exec(db, command.c_str(), callback, 0, &zErrMsg);
+    if(rc != SQLITE_OK) {
+        WARNING("SQL error: %s: %s\n", zErrMsg, command.c_str());
+        sqlite3_free(zErrMsg);
+    }
+
+    return rc;
+}
+
+
+int32_t 
+CBR::ExecuteSearchCommand(float *_retvals)
+{
+    sqlite3_stmt *pStatement;
+
+    int32_t rc = sqlite3_prepare_v2(db, command.c_str(), -1, &pStatement, NULL);
+    if(rc == SQLITE_OK) { 
+        if(sqlite3_step(pStatement) == SQLITE_ROW) {
+            for(size_t i = 0; i < numColumns; ++i) {
+                _retvals[i] = sqlite3_column_double(pStatement, i);
+            }
+        } else {
+		    LOG("CBR:: No matched results returning default.\n");
+			rc = 31337;
+		}
+    } else {
+		WARNING("CBR:: Error executing SQL statement. rc = %i\n%s\n", rc, command.c_str());
+    }
+
+    sqlite3_finalize(pStatement);
+   
+    return rc;
+}
+
+
+void 
+CBR::Print()
+{
+    /* Generate the sqlite command to print the database, which is effectively a
+     * 'select all elements' command, and then execute it. */
+    command = "select " + tablename + ".* from " + tablename + ";";
+
+    ExecuteCommand();
+    LOG("database %s, table %s:\n", filename.c_str(), tablename.c_str());
+}
+
+
+int32_t 
+CBR::Search(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
+        float *_retvals)
+{   
+    char str_buffer[64];
+    const string ops_str[] = {"==", "!=", ">", ">=", "<", "<="};
+
+    command = "select " + tablename + ".* from " + tablename + " where ";
+
+    for(size_t i = 0; i < _n; i++) {
+        /* Make sure that the passed ops value is valid. */
+        if((_ops[i] < 0) || (_ops[i] > 5)) {
+            ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);
+        }
+
+        command += _names[i] + ops_str[_ops[i]];
+
+
+        sprintf(str_buffer, "%E", _vals[i]);
+        command += string(str_buffer);
+
+        if(i < _n - 1)
+            command += " AND ";
+        else
+            command += ";";
+        
+    }
+    //LOG("CBR::Search - command: %s\n", command.c_str());
+
+    return ExecuteSearchCommand(_retvals);
+}
+
+
+int32_t 
+CBR::SearchSum(string _name, float *_retvals)
+{   
+    command = "select SUM(" + tablename + "." + _name + ") from " + tablename + ";";
+
+    return ExecuteSearchCommand(_retvals);
+}
+
+
+int32_t 
+CBR::SearchRand(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
+        float *_retvals)
+{   
+    char str_buffer[64];
+    const char *ops_str[] = {"==", "!=", ">", ">=", "<", "<="};
+
+    command = "select " + tablename + ".* from " + tablename + " where ";
+
+    for(size_t i = 0; i < _n; i++) {
+        /* Make sure that the passed ops value is valid. */
+        if((_ops[i] < 0) || (_ops[i] > 5)) {
+            ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);
+        }
+
+        command += _names[i] + ops_str[_ops[i]];
+
+        sprintf(str_buffer, "%E", _vals[i]);
+        command += str_buffer;
+
+        if(i < _n - 1)
+            command += " AND ";
+        else
+            command += " order by RAND();";
+    }
+
+    return ExecuteSearchCommand(_retvals);
+}
+
+
+int32_t 
+CBR::Update(string _where[], string _set[], float *_wherevals, float *_setvals, 
+		uint32_t _wherelen, uint32_t _setlen)
+{
+    char str_buffer[64];
+
+    /* Generate the command to update the table. */
+    command = "UPDATE " + tablename + " SET ";
+
+    for(size_t i = 0; i < _setlen; i++) {
+        command += _set[i] + " = ";
+        sprintf(str_buffer, "%f", _setvals[i]);
+        command += string(str_buffer) + "  ";
+
+        if(i != _setlen - 1)
+            command += ", ";
+    }
+    command += " WHERE ";
+
+    for(size_t j = 0; j < _wherelen; j++) {
+        command += _where[j] + " = ";
+        sprintf(str_buffer, "%f", _wherevals[j]);
+        command += string(str_buffer) + "  ";
+
+        if(j != _wherelen - 1)
+            command += "AND ";
+    }
+    command += ";";
+    
+    return ExecuteCommand();
+}
+
+
+int32_t 
+CBR::AddRow(string _cols[], float *_vals, uint32_t _len)
+{
+    char str_buffer[64];
+
+    command = "insert into " + tablename + " (";
+
+    for(size_t i = 0; i < _len; i++) {
+        command += _cols[i];
+
+        if(i != numColumns - 1)
+            command += ", ";
+    }
+    command += ") values(";
+
+    for(size_t j = 0; j < _len; j++) {
+        // TODO I have no idea what the below question is about.
+        // ???? how to fill the values if numColumns != _len
+        // assume = in the following
+        sprintf(str_buffer, "%f", _vals[j]);
+        command += str_buffer;
+
+        if(j != numColumns - 1)
+            command += ", ";
+    }
+    command += ");";
+    
+    return ExecuteCommand();
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/Makefile.am	(revision 544)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/Makefile.am	(revision 544)
@@ -0,0 +1,25 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+noinst_LIBRARIES = libce.a libcbr.a
+libce_a_SOURCES = CognitiveEngine.cpp
+libcbr_a_SOURCES = CBR.cpp
+
+SUBDIRS = . CBR_CE DSA_CE OSSIE_DEMO_CE
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.h	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.h	(revision 554)
@@ -0,0 +1,104 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file provides a default implementation for a case-based-reasoning based
+ * cognitive engine.
+ */
+
+#ifndef CBR_CE_H
+#define CBR_CE_H
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <cmath>
+#include <string>
+
+#include "vtcross/cbr.h"
+#include "vtcross/cognitive_engine.h"
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+
+class CBR_CE : public CognitiveEngine
+{
+    public:
+        /*! Default constructor. */
+        CBR_CE() : CognitiveEngine(){};
+        /*! Default destructor. */
+        ~CBR_CE(){};
+
+        /*! \brief Preferred constructor.
+         *
+         * Overloaded constructor that creates a cognitive engine object and
+         * connects it to either the shell or an SML, depening on the SML bool.
+         *
+         * The 'numFields' parameter sets how large the parameter, observable,
+         * and utility arrays should be upon instantiation.
+         */
+        CBR_CE(const char* serverName, const char* serverPort, \
+                const int32_t numFields, const bool SML);
+
+        /*! \brief Request that the CE optimize a set of parameters. 
+         *
+         * Find the most optimal set of transmission parameters given certain
+         * observables and possibly a service if the SML component is present
+         * and active. */
+        Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters, Utility *utilities);
+
+        /*! \brief Receive feedback from the radio 
+         *
+         * Receive a feedback from the radio regarding the performance of a
+         * certain set of parameters, possibly associated with a service.
+         *
+         * Feedback is a single set of performance statistics that is achieved
+         * corresponding to a specific set of transmission parameters.  Feedback
+         * helps a Cognitive Engine make better future decisions based upon 
+         * more accurate performance statistics. 
+         */
+        void ReceiveFeedback(Observable *observables,Parameter *parameters, Utility *utilities);
+
+        /*! \brief Initialize the CE and prepare it for operation. 
+         *
+         * BuildCognitiveEngine performs the CE implementation specific work
+         * that defines the internals of a CE.  For example, a CBR CE engine
+         * would build the case-base reasoner or create the database, a neural
+         * network based CE may perform the initial training, a GA based CE
+         * may build the chromosome structure.
+         */
+        void BuildCognitiveEngine();
+
+        /*! \brief Each of these functions responds to a specific command.
+         *
+         * These functions are left principally un-implemented. It is the duty
+         * of child classes to implement these functions, as they define the
+         * cognitive engine's functionality.
+         */
+        void PerformUpdatePerformance();
+        void PerformRequestOptimization();
+
+        void PerformResetEngineCognitive();
+        void PerformShutdownEngineCognitive();
+
+        CBR *myCBR;
+
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/Makefile.am	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/Makefile.am	(revision 545)
@@ -0,0 +1,26 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = cbr_demo
+
+cbr_demo_SOURCES = CBR_CE.cpp cbr_demo.cpp
+cbr_demo_DEPENDENCIES = ../libce.a ../libcbr.a
+cbr_demo_LDADD = -lsqlite3 ../libce.a ../libcbr.a  $(CROSS_SOCKETCOMM_LA) 
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/cbr_demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/cbr_demo.cpp	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/cbr_demo.cpp	(revision 545)
@@ -0,0 +1,50 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/* TODO DESCRIPTION OF FILE.
+ *
+ * This file is a temporary demo of a policy engine using some of our socket
+ * communication functions. This is *not* an actual implementation of our
+ * defined PolicyEngine class.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+
+#include "CBR_CE.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    if(argc < 3)
+       ERROR(1, "Usage: %s hostname port\n", argv[0]);
+    
+    CBR_CE cognitiveEngine(argv[1], argv[2], 10, false);
+
+    LOG("Waiting for signal...\n");
+    while(1) {
+        cognitiveEngine.WaitForSignal();
+    }
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CBR_CE/CBR_CE.cpp	(revision 554)
@@ -0,0 +1,414 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file provides a default implementation for a case-based-reasoning based
+ * cognitive engine.
+ */
+
+#include "CBR_CE.h"
+#include <iostream>
+
+using namespace std;
+
+
+CBR_CE::CBR_CE(const char* serverName, const char* serverPort, \
+        const int32_t numFields, const bool SML) \
+    : CognitiveEngine(serverName, serverPort, numFields, SML)
+{
+    BuildCognitiveEngine();
+}
+
+
+Parameter* 
+CBR_CE::GetSolution(Observable *observables, Parameter *currentParameters, Utility *utilities)
+{
+    LOG("Cognitive Engine:: Generating solution.\n");
+
+    string searchNames[radioInfo->numUtilities];
+
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        searchNames[i] = uList[i].name;
+    }
+
+    float searchVals[radioInfo->numUtilities];
+
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        searchVals[i] = uList[i].target;
+    }
+
+    uint32_t numberColumns = radioInfo->numParameters + radioInfo->numUtilities + radioInfo->numObservables + 1;
+    
+    float returnValues[numberColumns];
+    
+    int searchOps[radioInfo->numUtilities];
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+
+        /* If the goal is to maximum, set the search operation to
+         * return values greater than the target.
+         *
+         * If the goal is to minimize, set the search operation to
+         * return values less than the target.
+         *
+         * NOTE: the values '2' and '4' here are from some old preprocesser
+         * definitions, which I will copy here until I can figure out just what
+         * exactly they were for:
+                42	#define EQ 0    // equals
+                43	#define NE 1    // not equals
+                44	#define GT 2    // greater than
+                45	#define GE 3    // greater than or equal to
+                46	#define LT 4    // less than
+                47	#define LE 5    // less than or equal to
+         */
+        if(strcmp(uList[i].goal.c_str(), "max") == 0) {
+            searchOps[i] = 2;
+        } else if(strcmp(uList[i].goal.c_str(), "min") == 0) {
+            searchOps[i] = 4;
+        }
+    }
+
+    /* CBR specific call */
+    uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
+            radioInfo->numUtilities, returnValues);
+
+    if(rc == 0){
+        /* Adapt the returned parameters to meet the objective */
+        LOG("Cognitive Engine:: Found\n");
+
+    } else if(rc == 31337) {
+        LOG("Cognitive Engine:: Not Found.\n");
+        /* No rows in the CBR, pick default parameters */
+        /* Currently this is hard coded and implementation specific! */
+
+	for (int i = 0; i < radioInfo->numParameters; i++) {
+            returnValues[i] = currentParameters[i].value + pList[i].step;
+            if (returnValues[i] > pList[i].max) {
+	        std::cout << "SORRY CANT EXCEED MAX VALUE" << std::endl;
+	        returnValues[i] = returnValues[i] - pList[i].step;
+            }
+	    if (returnValues[i] < pList[i].min) {
+		std::cout << "SORRY CANT GO BELOW MIN VALUE" << std::endl;
+	        returnValues[i] = returnValues[i] + pList[i].step ;		 
+	    }
+	}
+
+	for (int i = 0; i < radioInfo->numUtilities; i++)
+	    returnValues[radioInfo->numParameters + i] = uList[i].value;
+
+	for (int i = 0; i < radioInfo->numObservables; i++)
+	    returnValues[radioInfo->numParameters + radioInfo->numUtilities + i] = oList[i].value;
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        pList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        uList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        oList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    returnValues[returnValueIndex] = 0;
+
+    string allNames[numberColumns];
+    size_t allNameIndex = 0;
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        allNames[allNameIndex] = pList[i].name;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        allNames[allNameIndex] = uList[i].name;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        allNames[allNameIndex] = oList[i].name;
+        allNameIndex++;
+    }
+    allNames[allNameIndex] = "TotalWeight";
+
+    // Add row to CBR. 
+    myCBR->AddRow(allNames, returnValues, returnValueIndex + 1);
+
+	} else {
+        LOG("Cognitive Engine:: Search return an invalid value.\n");
+    }
+
+
+    return pList;
+}
+
+
+void 
+CBR_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, Utility *utilities)
+{ 
+    LOG("Cognitive Engine:: Receiving feedback.\n");
+    
+    uint32_t numberColumns = radioInfo->numParameters + radioInfo->numUtilities + radioInfo->numObservables + 1;
+
+    uint32_t whereLen = radioInfo->numParameters;
+    uint32_t setLen = radioInfo->numUtilities + radioInfo->numObservables;
+
+
+    float whereValue[whereLen];
+    float setValue[setLen];
+    string whereList[whereLen];
+    string setList[setLen];
+
+
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        whereList[i] = parameters[i].name;
+        whereValue[i] = parameters[i].value;
+    }
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+	setList[returnValueIndex] = utilities[i].name;
+	setValue[returnValueIndex] = utilities[i].value;   
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+	setList[returnValueIndex] = observables[i].name;
+	setValue[returnValueIndex] = observables[i].value;
+	returnValueIndex++;
+    }
+
+
+myCBR->Update(whereList,setList,whereValue,setValue,whereLen,setLen);
+
+}
+
+
+void
+CBR_CE::BuildCognitiveEngine()
+{
+    string filename = "ex1";
+    string filename2 = "ex2";
+    string tablename = "data";
+
+    uint32_t numberColumns = radioInfo->numParameters + radioInfo->numUtilities \
+                             + radioInfo->numObservables + 1;
+
+    uint32_t numberParameters = radioInfo->numParameters;
+    uint32_t numberUtilities = radioInfo->numUtilities;
+
+    string cols[numberColumns];
+    string Plist[numberParameters];
+    string Ulist[numberUtilities];
+    float Utarget[numberUtilities];
+    string Ugoal[numberUtilities];
+
+    size_t columnIndex = 0;
+    size_t Pindex = 0;              // new
+    size_t Uindex = 0;              // new
+
+
+    for (size_t i = 0; i < radioInfo->numParameters; i++){
+        cols[columnIndex] = pList[i].name;
+        columnIndex++;
+        Plist[Pindex] = pList[i].name;   // new
+        Pindex++;                        // new
+    }
+    for (size_t i = 0; i < radioInfo->numUtilities; i++){
+        cols[columnIndex] = uList[i].name;
+        columnIndex++;
+        Ulist[Uindex] = uList[i].name;     // new
+	Utarget[Uindex] = uList[i].target; // new
+	Ugoal[Uindex] = uList[i].goal;	   // new
+        Uindex++;			   // new
+
+    }      
+    for (size_t i = 0; i < radioInfo->numObservables; i++){   
+        cols[columnIndex] = oList[i].name;
+	columnIndex++;
+    }
+    cols[columnIndex] = "TotalWeight";	
+
+    myCBR = new CBR(filename, tablename, cols, numberColumns);
+
+}
+
+
+void 
+CBR_CE::PerformUpdatePerformance()
+{
+
+    /* Receive Set of current Parameters */
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numParameters = atoi(buffer);
+
+    Parameter *p = new Parameter[numParameters];
+
+    for(size_t i = 0; i < numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].value = atof(buffer);
+    } 
+
+
+    /* Receive Set of Observables */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }
+
+
+    /* Receive Set of Utilities */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numUtilities = atoi(buffer);
+    
+    Utility *u = new Utility[numUtilities];
+
+    for(size_t i = 0; i < numUtilities; i++) {
+ 	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD, buffer);
+	u[i].name = std::string(buffer);
+	
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD, buffer);
+	u[i].value = atof(buffer);
+    }
+ 
+    ReceiveFeedback(o, p, u);
+
+    delete [] o;
+    delete [] p;
+    delete [] u;
+}
+
+
+void
+CBR_CE::PerformRequestOptimization()
+{
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving Observables\n");
+
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    /* Receive Set of current Parameters */
+    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numCurrentParameters = atoi(buffer);
+
+    Parameter *cp = new Parameter[numCurrentParameters];
+
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].value = atof(buffer);
+    }
+
+    /* Receive Set of Utilities */
+    LOG("Cognitive Engine:: Receiving Utilities\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numUtilities = atoi(buffer);
+
+    Utility *u = new Utility[numUtilities];
+
+    for(size_t i = 0; i < numUtilities; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        u[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        u[i].value = atof(buffer);
+    }
+
+
+
+  
+    LOG("Cognitive Engine:: Processing parameters....\n");
+
+    Parameter *solutionSet;
+    
+    solutionSet = GetSolution(o,cp,u);
+
+ 
+   
+    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
+    char numParametersChar[10];
+    char solutionValue[50];
+    sprintf(numParametersChar, "%i", radioInfo->numParameters);
+    SendMessage(commandSocketFD, numParametersChar);
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        SendMessage(commandSocketFD, solutionSet[i].name.c_str());
+        memset(solutionValue, 0, 50);
+        sprintf(solutionValue, "%f", solutionSet[i].value);
+        SendMessage(commandSocketFD, solutionValue);
+    }
+
+    delete [] o;
+    delete [] cp;
+    delete [] u;
+}
+
+
+void
+CBR_CE::PerformResetEngineCognitive()
+{
+    Reset();
+}
+
+
+void
+CBR_CE::PerformShutdownEngineCognitive()
+{
+    Shutdown();
+}
+ 
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.h	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.h	(revision 545)
@@ -0,0 +1,150 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This CE was written to extend the functionality of a basic CBR-based CE for
+ * use with the OSSIE demonstration. It defines its own CBR backend, as well as
+ * its own CognitiveEngine, both of which inherit from the example classes.
+ */
+
+
+#ifndef OSSIE_CE_H
+#define OSSIE_CE_H
+
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <string>
+
+#include "vtcross/cbr.h"
+#include "vtcross/cognitive_engine.h"
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+
+#define TXPOWER 1
+#define BER_ENV 1
+#define BER_OBJ 1
+#define DECREMENTSCALE 5 
+#define INCREMENTSCALE 5 
+#define EVF 20
+
+
+/* ossieCBR Class 
+ *
+ * Derives from the default VTCROSS CBR class to add the following functionality
+ * necessary for the OSSIE demo:
+ *
+ * TODO
+ */
+class ossieCBR : public CBR
+{
+    public:
+        ossieCBR();
+
+        ossieCBR(std::string _filename, std::string _tablename, std::string _cols[], uint32_t _len);
+
+        ~ossieCBR(){};
+
+        int32_t Update(std::string _where[], std::string _set[], float *_wherevals, float *_setvals, \
+                unsigned int _wherelen, unsigned int _setlen);
+
+        int32_t Search(std::string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
+                float *_retvals, int32_t evf);
+};
+
+
+class OSSIE_CE : public CognitiveEngine
+{
+    public:
+        /*! Default constructor. */
+        OSSIE_CE() : CognitiveEngine(){};
+
+        /*! Default destructor. */
+        ~OSSIE_CE();
+
+        /*! \brief Preferred constructor.
+         *
+         * Overloaded constructor that creates a cognitive engine object and
+         * connects it to either the shell or an SML, depening on the SML bool.
+         *
+         * The 'numFields' parameter sets how large the parameter, observable,
+         * and utility arrays should be upon instantiation.
+         */
+        OSSIE_CE(const char* serverName, const char* serverPort, \
+                const int32_t numFields, const bool SML);
+
+        void RegisterServices();
+        void DeregisterServices();
+
+        /*! \brief Request that the CE optimize a set of parameters. 
+         *
+         * Find the most optimal set of transmission parameters given certain
+         * observables and possibly a service if the SML component is present
+         * and active. */
+        Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters);
+        Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters, std::string service);
+
+        /*! \brief Receive feedback from the radio 
+         *
+         * Receive a feedback from the radio regarding the performance of a
+         * certain set of parameters, possibly associated with a service.
+         *
+         * Feedback is a single set of performance statistics that is achieved
+         * corresponding to a specific set of transmission parameters.  Feedback
+         * helps a Cognitive Engine make better future decisions based upon 
+         * more accurate performance statistics. 
+         */
+        void ReceiveFeedback(Observable *observables,Parameter *parameters);
+        void ReceiveFeedback(Observable *observables, Parameter *parameters, \
+                std::string service);
+
+
+        /*! \brief Initialize the CE and prepare it for operation. 
+         *
+         * BuildCognitiveEngine performs the CE implementation specific work
+         * that defines the internals of a CE.  For example, a CBR CE engine
+         * would build the case-base reasoner or create the database, a neural
+         * network based CE may perform the initial training, a GA based CE
+         * may build the chromosome structure.
+         */
+        void BuildCognitiveEngine();
+
+        /*! \brief Each of these functions responds to a specific command.
+         *
+         * These functions are left principally un-implemented. It is the duty
+         * of child classes to implement these functions, as they define the
+         * cognitive engine's functionality.
+         */
+        void PerformUpdatePerformance();
+        void PerformRequestOptimizationService();
+        void PerformRequestOptimization();
+        void PerformQueryComponentType();
+        void PerformConnectSML();
+        void PerformDisconnectSML();
+        void PerformResetEngineCognitive();
+        void PerformShutdownEngineCognitive();
+
+        ossieCBR *myCBR;
+};
+
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_Demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_Demo.cpp	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_Demo.cpp	(revision 545)
@@ -0,0 +1,39 @@
+/* Virginia Tech Cognitive Radio Open Source Systems
+ * Virginia Tech, 2009
+ *
+ * TODO LICENSE INFORMATION GOES HERE
+ */
+
+/* TODO DESCRIPTION OF FILE.
+ *
+ * This file is a temporary demo of a policy engine using some of our socket
+ * communication functions. This is *not* an actual implementation of our
+ * defined PolicyEngine class.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include "OSSIE_CE.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    if(argc < 3)
+       ERROR(1, "Usage: %s hostname port\n", argv[0]);
+    
+    OSSIE_CE cognitiveEngine(argv[1], argv[2], 10, false);
+
+    LOG("Waiting for signal...\n");
+    while(1) {
+        cognitiveEngine.WaitForSignal();
+    }
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/Makefile.am	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/Makefile.am	(revision 545)
@@ -0,0 +1,26 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = OSSIE_Demo
+
+OSSIE_Demo_SOURCES = OSSIE_CE.cpp OSSIE_Demo.cpp
+OSSIE_Demo_DEPENDENCIES = ../libce.a ../libcbr.a
+OSSIE_Demo_LDADD = -lsqlite3 ../libce.a ../libcbr.a $(CROSS_SOCKETCOMM_LA) 
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.cpp	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/OSSIE_DEMO_CE/OSSIE_CE.cpp	(revision 545)
@@ -0,0 +1,662 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This CE was written to extend the functionality of a basic CBR-based CE for
+ * use with the OSSIE demonstration. This file contains the implementation for
+ * both the OSSIE CBR as well as the OSSIE Cognitive Engine.
+ */
+
+
+#include "OSSIE_CE.h"
+
+
+using namespace std;
+
+
+ossieCBR::ossieCBR(string _filename, string _tablename, string _cols[], uint32_t _len)
+{
+    /* Store database properties. */
+    filename = _filename;
+    tablename = _tablename;
+    numColumns = _len;
+
+    /* Create the database (or open it if it already exists). */
+    OpenDatabase();
+
+    /* Generate the command that will create the initial table within the
+     * VTCROSS database. */
+    command = "CREATE TABLE " + tablename + "(";
+    for(size_t i = 0; i < numColumns; i++) {
+        command += _cols[i] + " FLOAT";
+
+        /* If this column is not the last entry, add a comma to the command in
+         * preperation for the next entry. */
+        if(i != numColumns - 1)
+            command += ", ";
+    }
+    command += ", timestamp DATE, PRIMARY KEY(tx_power));";
+
+    /* Execute the generated command. At this point, the database is ready for
+     * use. */
+    ExecuteCommand();
+}
+
+
+int32_t 
+ossieCBR::Search(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
+        float *_retvals, int32_t evf)
+{   
+    float lower_limit;
+    float upper_limit;
+    char str_buffer[64];
+
+    command = "select " + tablename + ".* from " + tablename + " where ";
+
+    for(size_t i = 0; i < _n; i++) {
+        /* Make sure that the passed ops value is valid. */
+        if((_ops[i] < 0) || (_ops[i] > 5)) {
+            ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);
+        }
+
+        command += _names[i] + " between ";
+        
+        lower_limit = _vals[i] * (1 - ((float) evf / 100));
+        upper_limit = _vals[i] * (1 + ((float) evf / 100));
+
+	    LOG("%f %f %f\n", lower_limit, upper_limit, _vals[i]);
+
+        sprintf(str_buffer, "%f", lower_limit);
+        command += string(str_buffer) + " and ";
+        sprintf(str_buffer, "%f", upper_limit);
+        command += string(str_buffer);
+
+        if(i < _n - 1)
+            command += " AND ";
+        else
+            command += " order by abs(utility) asc, timestamp desc;";
+    }
+
+    LOG("Search command: %s\n", command.c_str());
+
+    return ExecuteSearchCommand(_retvals);
+}
+
+
+int32_t 
+ossieCBR::Update(string _where[], string _set[], float *_wherevals, float *_setvals, 
+		uint32_t _wherelen, uint32_t _setlen)
+{
+    char str_buffer[64];
+
+    command = "UPDATE " + tablename + " SET ";
+
+    for(size_t i = 0; i < _setlen; i++) {
+        command += _set[i] + " = ";
+
+        sprintf(str_buffer, "%f", _setvals[i]);
+        command += string(str_buffer) + "  ";
+
+        if(i != _setlen - 1)
+            command += ", ";
+    }
+   
+    command += ", timestamp = DATETIME('NOW') WHERE ";
+    
+    for(size_t j = 0; j < _wherelen; j++) {
+        command += _where[j] + " = ";
+
+        sprintf(str_buffer, "%f", _wherevals[j]);
+        command += string(str_buffer) + "  ";
+
+        if(j != _wherelen - 1)
+            command += "AND ";
+    }
+    command += ";";
+    
+    return ExecuteCommand();
+}
+
+
+/******************** END DEFINITION OF OSSIE CBR CLASS ****************/
+
+
+OSSIE_CE::OSSIE_CE(const char* serverName, const char* serverPort, \
+        const int32_t numFields, const bool SML) \
+    : CognitiveEngine(serverName, serverPort, numFields, SML)
+{
+    BuildCognitiveEngine();
+}
+
+
+OSSIE_CE::~OSSIE_CE()
+{
+    delete myCBR;
+
+    delete [] pList;
+    delete [] oList;
+    delete [] uList;
+    delete [] radioInfo;
+}
+
+// This function needs serious help and is very confusing
+void 
+OSSIE_CE::ReceiveFeedback(Observable *observables, Parameter *parameters)
+{ 
+   LOG("Cognitive Engine:: Receiving feedback.\n");
+    
+    uint32_t numberColumns = radioInfo->numParameters;
+
+    uint32_t utilColumns = radioInfo->numUtilities + 1;
+
+    float valList[numberColumns];
+    float newUtilityVals[numberColumns];
+    string nameList[numberColumns];
+    string utilList[utilColumns];
+
+    size_t columnUtilIndex = 0;
+    for (size_t i = 0; i < radioInfo->numUtilities; i++){
+        utilList[columnUtilIndex] = uList[i].name;
+        columnUtilIndex++;
+    }  
+    utilList[columnUtilIndex] = "utility";
+
+    size_t columnIndex = 0;
+    for (size_t i = 0; i < radioInfo->numParameters; i++){
+        nameList[columnIndex] = parameters[i].name;
+        columnIndex++;
+    }   
+
+    size_t newUtilityValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+
+	    /* This is a special case because the observable is also the utility. */
+        newUtilityVals[newUtilityValueIndex] = observables[i].value;
+        newUtilityValueIndex++;
+    }
+
+    /* Calculate Utility */
+    float newUtilityValue = 0;
+
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        newUtilityValue = newUtilityValue + (uList[i].target - observables[i].value);
+    }
+    newUtilityVals[newUtilityValueIndex] = newUtilityValue;
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        valList[returnValueIndex] = parameters[i].value;
+        returnValueIndex++;
+    }
+
+    myCBR->Update(nameList, utilList, valList, newUtilityVals, 
+            numberColumns, utilColumns);
+}
+
+
+void 
+OSSIE_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \
+    std::string service)
+{
+    LOG("Cognitive Engine:: Receiving feedback.\n");
+}
+
+
+void 
+OSSIE_CE::RegisterServices()
+{
+    LOG("Cognitive Engine:: Registering services.\n");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv1");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv2");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv3");
+
+}
+
+
+void 
+OSSIE_CE::DeregisterServices()
+{
+    LOG("Cognitive Engine:: Deregistering services.\n");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv1");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv2");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv3");
+
+}
+
+
+Parameter* 
+OSSIE_CE::GetSolution(Observable *observables, Parameter *currentParameters)
+{
+    LOG("Cognitive Engine:: Generating solution.\n");
+
+    string searchNames[radioInfo->numObservables];
+
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        searchNames[i] = observables[i].name;
+    }
+
+    float searchVals[radioInfo->numObservables];
+
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        searchVals[i] = observables[i].value;
+    }
+
+    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
+                             radioInfo->numObservables + 1;
+    
+    float returnValues[numberColumns];
+    
+    int searchOps[radioInfo->numUtilities];
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+
+        /* If the goal is to maximum, set the search operation to
+         * return values greater than the target.
+         *
+         * If the goal is to minimize, set the search operation to
+         * return values less than the target.
+         */
+        if(strcmp(uList[i].goal.c_str(), "max") == 0) {
+            searchOps[i] = 2;
+        } else if(strcmp(uList[i].goal.c_str(), "min") == 0) {
+            searchOps[i] = 4;
+        }
+    }
+
+    myCBR->Print();
+
+    /* CBR specific call */
+    uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
+            radioInfo->numUtilities, returnValues, EVF);
+
+    if(rc == 0){
+        /* Adapt the returned parameters to meet the objective */
+        LOG("Cognitive Engine:: Found\n");
+
+        /* Should do a random adaptation.. */
+        if(returnValues[numberColumns-1] > (uList[0].target * 0.2)) {
+            returnValues[1] = returnValues[1] - DECREMENTSCALE*fabs(returnValues[numberColumns-1]);
+		LOG("RREEEALLLY CLOSE1\n %f", fabs(returnValues[numberColumns-1]));
+        } else if(returnValues[numberColumns-1] < -(uList[0].target * 0.2)) {
+		LOG("RREEEALLLY CLOSE2\n %f", fabs(returnValues[numberColumns-1]));
+            returnValues[1] = returnValues[1] + INCREMENTSCALE*fabs(returnValues[numberColumns-1]);
+        } else {
+		LOG("RREEEALLLY CLOSE\n");
+        }
+    } else if(rc == 31337) {
+        LOG("Cognitive Engine:: Not Found.\n");
+        /* No rows in the CBR, pick default parameters */
+        /* Currently this is hard coded and implementation specific! */
+        returnValues[1] = currentParameters[0].value;
+        
+    } else {
+        LOG("Cognitive Engine:: Search return an invalid value.\n");
+    }
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        uList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        pList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        oList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    returnValues[returnValueIndex] = 0;
+
+    string allNames[numberColumns];
+    size_t allNameIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        allNames[allNameIndex] = uList[i].name;
+        returnValues[allNameIndex] = uList[i].target;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        allNames[allNameIndex] = pList[i].name;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        allNames[allNameIndex] = oList[i].name;
+        returnValues[allNameIndex] = observables[i].value;
+        allNameIndex++;
+    }
+    allNames[allNameIndex] = "utility";
+
+    // Add row to CBR. 
+    myCBR->AddRow(allNames, returnValues, returnValueIndex+1);
+
+    return pList;
+}
+
+
+Parameter* 
+OSSIE_CE::GetSolution(Observable *observables, \
+        Parameter *currentParameters, std::string service)
+{
+    LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str());
+
+    return pList;
+}
+
+
+void
+OSSIE_CE::BuildCognitiveEngine()
+{
+    string filename = "ex1";
+    string tablename = "data";
+
+    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
+                             radioInfo->numObservables + 1;
+
+    string cols[numberColumns];
+
+    size_t columnIndex = 0;
+    for (size_t i = 0; i < radioInfo->numUtilities; i++){
+        cols[columnIndex] = uList[i].name;
+        columnIndex++;
+    }   
+    for (size_t i = 0; i < radioInfo->numParameters; i++){
+        cols[columnIndex] = pList[i].name;
+        columnIndex++;
+    }   
+    for (size_t i = 0; i < radioInfo->numObservables; i++){
+        cols[columnIndex] = oList[i].name;
+        columnIndex++;
+    }   
+    cols[columnIndex] = "utility";
+
+    myCBR = new ossieCBR(filename, tablename, cols, numberColumns);
+}
+
+void 
+OSSIE_CE::PerformUpdatePerformance()
+{
+    /* Receive Set of current Parameters */
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numParameters = atoi(buffer);
+
+    Parameter *p = new Parameter[numParameters];
+
+    for(size_t i = 0; i < numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].value = atof(buffer);
+    } 
+
+    /* Receive Set of Observables */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    ReceiveFeedback(o,p);
+
+    delete [] o;
+    delete [] p;
+}
+
+
+void
+OSSIE_CE::PerformRequestOptimizationService()
+{
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving service name\n");
+
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    LOG("\nCognitive Engine:: Got service name, %s\n", buffer);
+
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    /* Receive Set of current Parameters */
+    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numCurrentParameters = atoi(buffer);
+
+    Parameter *cp = new Parameter[numCurrentParameters];
+
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].value = atof(buffer);
+    }  
+    LOG("Cognitive Engine:: Processing parameters....\n");
+
+    //Parameter *solutionSet;
+    
+    //solutionSet = GetSolution(o,cp);
+
+    // TODO need to actually do something with the observables here
+   
+    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
+    char numParametersChar[10];
+    //char solutionValue[50];
+    sprintf(numParametersChar, "%i", radioInfo->numParameters);
+    SendMessage(commandSocketFD, numParametersChar);
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        //SendMessage(commandSocketFD, solutionSet[i].name.c_str());
+        SendMessage(commandSocketFD, "test");
+        //memset(solutionValue, 0, 50);
+        //sprintf(solutionValue, "%f", solutionSet[i].value);
+        //SendMessage(commandSocketFD, solutionValue);
+        SendMessage(commandSocketFD, "00");
+    }
+
+    delete [] o;
+    delete [] cp;
+}
+
+
+void
+OSSIE_CE::PerformRequestOptimization()
+{
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
+
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    /* Receive Set of current Parameters */
+    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numCurrentParameters = atoi(buffer);
+
+    Parameter *cp = new Parameter[numCurrentParameters];
+
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].value = atof(buffer);
+    }  
+    LOG("Cognitive Engine:: Processing parameters....\n");
+
+    Parameter *solutionSet;
+    
+    solutionSet = GetSolution(o,cp);
+
+    // TODO need to actually do something with the observables here
+   
+    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
+    char numParametersChar[10];
+    char solutionValue[50];
+    sprintf(numParametersChar, "%i", radioInfo->numParameters);
+    SendMessage(commandSocketFD, numParametersChar);
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        SendMessage(commandSocketFD, solutionSet[i].name.c_str());
+        memset(solutionValue, 0, 50);
+        sprintf(solutionValue, "%f", solutionSet[i].value);
+        SendMessage(commandSocketFD, solutionValue);
+    }
+
+    delete [] o;
+    delete [] cp;
+}
+
+
+void
+OSSIE_CE::PerformQueryComponentType()
+{
+    SendComponentType();
+}
+
+
+void
+OSSIE_CE::PerformConnectSML()
+{
+    /* This command implies that we are disconnecting from the shell and
+     * connecting to a SML component. */
+    char serverName[256];
+    char serverPort[256];
+    // TODO is this going to end up being too slow?
+    memset(serverName, 0, 256);
+    memset(serverPort, 0, 256);
+
+    ReadMessage(commandSocketFD, serverName);
+    ReadMessage(commandSocketFD, serverPort);
+
+    /* Only continue if we are currently connected to a shell. */
+    if(!SML_present) {
+        DeregisterComponent();
+
+        shutdown(commandSocketFD, 2);
+        close(commandSocketFD);
+
+        ConnectToRemoteComponent(serverName, serverPort, true);
+    }
+}
+
+
+void
+OSSIE_CE::PerformDisconnectSML()
+{
+    /* This command implies that we are disconnecting from the SML and
+     * connecting to a shell component. */
+    char serverName[256];
+    char serverPort[256];
+    // TODO is this going to end up being too slow?
+    memset(serverName, 0, 256);
+    memset(serverPort, 0, 256);
+
+    ReadMessage(commandSocketFD, serverName);
+    ReadMessage(commandSocketFD, serverPort);
+
+    /* We only want to do this if we are actually connected to an SML
+     * currently. */
+    if(SML_present) {
+        DeregisterServices();
+
+        shutdown(commandSocketFD, 2);
+        close(commandSocketFD);
+
+        ConnectToRemoteComponent(serverName, serverPort, false);
+    }
+}
+
+
+void
+OSSIE_CE::PerformResetEngineCognitive()
+{
+    Reset();
+}
+
+
+void
+OSSIE_CE::PerformShutdownEngineCognitive()
+{
+    Shutdown();
+}
+ 
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CognitiveEngine.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CognitiveEngine.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/CognitiveEngine.cpp	(revision 554)
@@ -0,0 +1,361 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file provides a default implementation for a cognitive engine.  Note
+ * that this implementation is very basic, and is meant to act as a non-abstract
+ * parent class.
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <cmath>
+#include <string>
+#include <iostream>
+
+#include "vtcross/cognitive_engine.h"
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+using namespace std;
+
+
+CognitiveEngine::CognitiveEngine()
+{
+    LOG("Creating Cognitive Engine.\n");
+    SML_present = false;
+    commandSocketFD = -1;
+}
+
+
+CognitiveEngine::~CognitiveEngine()
+{
+    delete [] pList;
+    delete [] oList;
+    delete [] uList;
+
+    delete [] radioInfo;
+}
+
+
+CognitiveEngine::CognitiveEngine(const char *serverName, const char *serverPort, \
+        const int32_t numFields, const bool SML)
+{
+    LOG("Creating Cognitive Engine.\n");
+
+    pList = new Parameter[numFields];
+    oList = new Observable[numFields];
+    uList = new Utility[numFields];
+
+    radioInfo = new Radio_Info;
+
+    ConnectToRemoteComponent(serverName, serverPort, SML);
+
+}
+
+void
+CognitiveEngine::SendComponentType()
+{
+    SendMessage(commandSocketFD, "response_engine_cognitive");
+    LOG("Cognitive Engine responded to GetRemoteComponentType query.\n");
+}
+
+
+void
+CognitiveEngine::ConnectToRemoteComponent(const char *serverName, \
+        const char *serverPort, const bool SML)
+{
+    commandSocketFD = ClientSocket(serverName, serverPort);
+
+    SML_present = SML;
+
+
+// Considering only Shell to work in this project!!
+
+        LOG("Cognitive Engine connected to shell at %s.\n", serverName);
+
+        RegisterComponent();
+        ReceiveRadioConfiguration();
+        ReceiveExperience();
+
+}
+
+
+void 
+CognitiveEngine::WaitForSignal()
+{
+    char buffer[256];
+
+    std::cout << "IN WAITFORSIGNAL METHOD" << std::endl;
+
+    while(true) {
+        memset(buffer, 0, 256);
+       
+        ReadMessage(commandSocketFD, buffer);
+
+        if(strcmp(buffer, "update_performance") == 0) {
+	    PerformUpdatePerformance();
+        } 
+        else if(strcmp(buffer, "request_optimization") == 0) {
+            PerformRequestOptimization();
+        }
+        else if(strcmp(buffer, "reset_engine_cognitive") == 0) {
+            PerformResetEngineCognitive();
+        }
+        else if(strcmp(buffer, "shutdown_engine_cognitive") == 0) {
+            PerformShutdownEngineCognitive();
+        }
+    }
+}
+
+
+void 
+CognitiveEngine::Shutdown()
+{
+        DeregisterComponent();
+    // TODO Need to actually kill this process...
+}
+
+
+void
+CognitiveEngine::Reset()
+{
+    LOG("Resetting Cognitive Engine.\n");
+
+        DeregisterComponent();
+
+    // TODO This function then needs to re-call "ConnectToRemoteComponent" to
+    // finish the reset - otherwise, it is just a shutdown.
+}
+
+
+void
+CognitiveEngine::RegisterComponent()
+{
+    char buffer[256];
+    SendMessage(commandSocketFD, "register_engine_cognitive");
+    LOG("Cognitive Engine:: Registration message sent to shell.\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+
+    // TODO Are we reading an ACK here? If so, why aren't we doing anything with
+    // it?
+}
+
+void 
+CognitiveEngine::DeregisterComponent()
+{
+    SendMessage(commandSocketFD, "deregister_engine_cognitive");
+    LOG("Cognitive Engine:: Deregistration message sent.\n");
+
+    shutdown(commandSocketFD, 2);
+    close(commandSocketFD);
+    commandSocketFD = -1;
+    LOG("Cognitive Engine:: Shell socket closed.\n");
+}
+
+
+void 
+CognitiveEngine::ReceiveRadioConfiguration()
+{
+    LOG("Cognitive Engine:: Receiving Radio Configuration.\n");
+    
+    char buffer[256];
+ 
+    /* Receive Set of Utilities */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    radioInfo->numUtilities = atoi(buffer);
+
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        uList[i].name = std::string(buffer);
+   
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        uList[i].units = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        uList[i].goal = std::string(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        uList[i].target = atof(buffer);
+    }
+
+    /* Receive Set of Parameters */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    radioInfo->numParameters = atoi(buffer);
+    
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        pList[i].name = std::string(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        pList[i].units = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        pList[i].min = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        pList[i].max = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        pList[i].step = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD,buffer);
+        pList[i].numAffects = atoi(buffer);
+    
+        for(size_t j = 0; j < pList[i].numAffects; j++) {
+            memset(buffer, 0, 256);
+            ReadMessage(commandSocketFD,buffer);
+            // TODO for + if{break} = while?
+            for(size_t k = 0; k < radioInfo->numUtilities; k++) {
+                if(uList[k].name == std::string(buffer)) {    
+                    pList[i].affection_list[j].u = &uList[k];   
+                    break;
+                }
+            }
+
+            memset(buffer, 0, 256);
+            ReadMessage(commandSocketFD, buffer);
+            pList[i].affection_list[j].relation = std::string(buffer);   
+        }
+    }   
+
+    /* Receive Set of Observables */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    radioInfo->numObservables = atoi(buffer);
+    
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        oList[i].name = std::string(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        oList[i].numAffects = atoi(buffer);
+    
+        for(size_t j = 0; j < oList[i].numAffects; j++) {
+            memset(buffer, 0, 256);
+            ReadMessage(commandSocketFD, buffer);
+            // TODO for + if{break} = while?
+            for(size_t k = 0; k < radioInfo->numUtilities; k++) {
+                if(uList[k].name == std::string(buffer)){    
+                    oList[i].affection_list[j].u = &uList[k];   
+                    break;
+                }
+            }
+ 
+            memset(buffer, 0, 256);
+            ReadMessage(commandSocketFD, buffer);
+            oList[i].affection_list[j].relation = std::string(buffer);   
+        }
+    }
+
+    SendMessage(commandSocketFD, "receive_config_ack");
+}
+
+
+void 
+CognitiveEngine::ReceiveExperience()
+{
+    LOG("Cognitive Engine:: Receiving Experience Report.\n");
+    char buffer[256];
+    uint32_t numberExp;
+    
+    /* Receive number of experience entries */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    numberExp = atoi(buffer);
+
+    LOG("Cognitive Engine:: Waiting for %i number of entries.\n", numberExp);
+    SendMessage(commandSocketFD, "receive_exp_ack");
+
+}
+
+
+/***************************************************************************
+ *
+ * Every function below this banner must be overloaded by child classes.
+ *
+ ***************************************************************************/
+
+
+Parameter* 
+CognitiveEngine::GetSolution(Observable *observables, Parameter *currentParameters, Utility *utilities)
+{
+    LOG("Cognitive Engine:: Generating solution.\n");
+
+    LOG("CognitiveEngine:: GetSolution not implemented.\n");
+
+    return NULL;
+}
+
+
+void 
+CognitiveEngine::ReceiveFeedback(Observable *observables,Parameter *parameters, Utility *utilities)
+{
+    LOG("Cognitive Engine:: Receiving feedback.\n");
+
+    LOG("CognitiveEngine:: ReceiveFeedback not implemented.\n");
+}
+
+
+void
+CognitiveEngine::BuildCognitiveEngine()
+{
+    LOG("Cognitive Engine:: BuildCognitiveEngine not implemented.\n");
+}
+
+
+void 
+CognitiveEngine::PerformUpdatePerformance()
+{
+}
+
+
+void
+CognitiveEngine::PerformRequestOptimization()
+{
+}
+
+
+void
+CognitiveEngine::PerformResetEngineCognitive()
+{
+}
+
+
+void
+CognitiveEngine::PerformShutdownEngineCognitive()
+{
+}
+ 
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp	(revision 545)
@@ -0,0 +1,654 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file provides an implemention of a CBR-based CE that works with the
+ * provided test scripts and configuration filse.
+ */
+
+#include "DSA_CognitiveEngine.h"
+
+
+using namespace std;
+
+
+DSA_CE::DSA_CE()
+{
+    LOG("Creating Cognitive Engine.\n");
+    SML_present = false;
+    commandSocketFD = -1;
+    srand(time(NULL));
+}
+
+
+DSA_CE::~DSA_CE()
+{
+    delete myCBR;
+
+    delete [] pList;
+    delete [] oList;
+    delete [] uList;
+    delete [] radioInfo;
+}
+
+
+DSA_CE::DSA_CE(const char* serverName, const char* serverPort, \
+                const int32_t numFields, const bool SML) \
+        : CognitiveEngine(serverName, serverPort, numFields, SML)
+{
+    LOG("Creating Cognitive Engine.\n");
+    srand ( time(NULL) );
+
+    BuildCognitiveEngine();
+}
+
+
+void 
+DSA_CE::RegisterServices()
+{
+    LOG("Cognitive Engine:: Registering services.\n");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv1");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv2");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "test_srv3");
+
+}
+
+//Combined with deregister component since those two things must happen togeather
+void 
+DSA_CE::DeregisterServices()
+{
+    LOG("Cognitive Engine:: Deregistering services.\n");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv1");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv2");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "test_srv3");
+
+}
+
+/* The core of the CE is this function */
+Parameter* 
+DSA_CE::GetSolution(Observable *observables, Parameter *currentParameters)
+{
+    LOG("Cognitive Engine:: Generating solution.\n");
+
+    /* Put together the CBR search array */
+
+    uint32_t channel = 0;
+    string searchNames[1];
+    string sumSearchName;
+    float searchVals[1];
+    float utilArray[(int)pList[0].max];
+    int searchOps[1];
+    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
+                             radioInfo->numObservables + 1;
+
+    float returnValues[numberColumns];
+    float sumRetVals[numberColumns];
+   
+    // Total sum of utilities in sumRetVals[0]
+
+    string channel_name = "channel";
+    string utility_name = "utility";
+
+    for(int32_t i = 0 ; i < pList[0].max ; i++ ) {
+        searchNames[0] = pList[0].name;
+        searchOps[0] = 0;
+        searchVals[0] = i+1; 
+    
+        uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
+            1, returnValues);
+
+    if(rc == 31337) {
+        // No entry - must add
+        
+            string rowNames[numberColumns];
+            size_t rowIndex = 0;
+            for(size_t j = 0; j < radioInfo->numUtilities; j++) {
+                rowNames[rowIndex] = uList[j].name;
+                rowIndex++;
+            }
+            for(size_t j = 0; j < radioInfo->numParameters; j++) {
+                rowNames[rowIndex] = pList[j].name;
+            if(pList[j].name == "channel")
+                returnValues[rowIndex] = i+1;
+                rowIndex++;
+            }
+            for(size_t j = 0; j < radioInfo->numObservables; j++) {
+                rowNames[rowIndex] = oList[j].name;
+                rowIndex++;
+            }
+   
+            rowNames[rowIndex] = utility_name;
+        returnValues[rowIndex] = 500;
+
+                /* Add the new optimized set to the CBR database */
+
+            myCBR->AddRow(rowNames, returnValues, numberColumns);
+    }
+
+    utilArray[i] = returnValues[UTILITY]; 
+    }
+
+    printf("Current Channel Utility Scores\n");
+    printf("1: %f\t7: %f\t8: %f\t14: %f\n",utilArray[0],utilArray[1],utilArray[2],utilArray[3]);    
+    // Get sum of all the channel utilities.
+    sumSearchName = utility_name;
+    uint32_t rc = myCBR->SearchSum(sumSearchName, sumRetVals);
+
+    // Psuedo random channel selection based upon utility.
+    int k = rand() % (int)sumRetVals[0];
+    int cdf_total(0);
+
+    for ( int i = 0; i < pList[0].max; i++ ) {
+        cdf_total += utilArray[i];
+        if(k < cdf_total) {
+        channel = i + 1;
+        break;
+    }
+    }
+        
+    searchNames[0] = pList[0].name;
+    searchOps[0] = 0;
+    searchVals[0] = channel; 
+  
+    rc = myCBR->Search(searchNames, searchOps, searchVals,
+        1, returnValues);
+
+
+    //returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min; 
+    returnValues[CHANNEL] = channel;
+
+    printf("Cognitive Engine:: ..---===***### Channel %i has been selected ###***===---..\n",channel); 
+    /* Package up the new set of parameters in order to add
+       the new entry into the CBR database.  */
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        uList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        pList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        oList[i].value = returnValues[returnValueIndex];
+        returnValueIndex++;
+    }
+    //returnValues[returnValueIndex] = 0;
+
+    string allNames[numberColumns];
+    size_t allNameIndex = 0;
+    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
+        allNames[allNameIndex] = uList[i].name;
+        returnValues[allNameIndex] = uList[i].target;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        allNames[allNameIndex] = pList[i].name;
+        allNameIndex++;
+    }
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        allNames[allNameIndex] = oList[i].name;
+    //    returnValues[allNameIndex] = 0;
+        allNameIndex++;
+    }
+   
+    allNames[allNameIndex] = utility_name;
+
+    /* Add the new optimized set to the CBR database */
+    //myCBR->AddRow(allNames, returnValues, returnValueIndex+1);
+
+
+    /* Return the set of new parameter values.  */
+    return pList;
+}
+
+
+Parameter* 
+DSA_CE::GetSolution(Observable *observables, \
+        Parameter *currentParameters, std::string service)
+{
+    LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str());
+
+    return pList;
+}
+
+
+void 
+DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters)
+{ 
+   LOG("Cognitive Engine:: Receiving feedback.\n");
+    
+    uint32_t numberColumns = 
+        radioInfo->numParameters;
+
+    uint32_t obsColumns = radioInfo->numObservables + 1;
+    uint32_t numberTotalColumns = radioInfo->numUtilities +
+                    radioInfo->numParameters +
+                    radioInfo->numObservables + 1;
+
+    float valList[numberColumns];
+    float obsVals[numberColumns];
+    string nameList[numberColumns];
+    string obsList[obsColumns];
+    string searchNames[1];
+    float searchVals[1];
+    int searchOps[1];
+    float returnValues[numberTotalColumns];
+
+    size_t columnObsIndex = 0;
+    for (size_t i = 0; i < radioInfo->numObservables; i++){
+        obsList[columnObsIndex] = observables[i].name;
+        columnObsIndex++;
+    }  
+    obsList[columnObsIndex] = "utility";
+
+    size_t columnIndex = 0;
+    for (size_t i = 0; i < radioInfo->numParameters; i++){
+        nameList[columnIndex] = parameters[i].name;
+        columnIndex++;
+    }   
+
+    size_t obsValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numObservables; i++) {
+        obsVals[obsValueIndex] = observables[i].value;
+        obsValueIndex++;
+    }
+
+    /* Make sure we do not return any entries for the current channel */
+    std::string channel_name = "channel";
+    searchNames[0] = channel_name;
+    searchOps[0] = 0;
+    searchVals[0] = parameters[0].value; 
+
+    /* Execute CBR search and put output into returnValues */
+    myCBR->Search(searchNames, searchOps, searchVals,
+            1, returnValues);
+
+    /* Calculate Utility */
+    float oldUtilityValue = returnValues[UTILITY];
+   
+
+    //////////////////////////////////////////////
+    //
+    //  BEGIN CORE DSA ALGORITHM UTILITY FUNCTION
+    //
+    //////////////////////////////////////////////
+ 
+    // Set DSA utility to take into account both the previously sensed
+    //  energy and the average communication time.
+
+    float newUtilityValue = oldUtilityValue + observables[COMMUNICATION_TIME].value;
+
+    // If communication time value is set, we know we need to change channels because of PU.
+    // So we should lower the utility for this channel.
+
+    int reward = 20;
+    int punishment = -100;
+    int Detection_Threshold = 10000000;
+
+    if((observables[COMMUNICATION_TIME].value != 0) || (observables[ENERGY].value > Detection_Threshold)) { 
+    printf("Cognitive Engine:: Possible PU Detection - Decrementing Utility. %f %f",observables[COMMUNICATION_TIME].value,observables[ENERGY].value);
+    newUtilityValue = newUtilityValue + punishment;
+    } else {
+    printf("Cognitive Engine:: Scan Mode:: No PU detected - Incrementing Utility.");
+    newUtilityValue = newUtilityValue + reward;
+    }
+
+    if(newUtilityValue <= 100)
+    newUtilityValue = 100;
+
+    // Put limit on utility score to prevent a positive feedback loop 
+    if(newUtilityValue >= 800)
+    newUtilityValue = 800;
+
+    obsVals[obsValueIndex] = newUtilityValue;
+
+    //////////////////////////////////////////////
+    //
+    //  END CORE DSA ALGORITHM UTILITY FUNCTION
+    //
+    //////////////////////////////////////////////
+
+
+    size_t returnValueIndex = 0;
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        valList[returnValueIndex] = parameters[i].value;
+        returnValueIndex++;
+    }
+
+    myCBR->Update(nameList, obsList, valList, obsVals, 
+            numberColumns, obsColumns);
+}
+
+
+void 
+DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \
+    std::string service)
+{
+    LOG("Cognitive Engine:: Receiving feedback.\n");
+}
+
+
+void
+DSA_CE::BuildCognitiveEngine()
+{
+    string filename = "ex1";
+    string tablename = "data";
+
+    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
+                             radioInfo->numObservables + 1;
+
+    string cols[numberColumns];
+
+    size_t columnIndex = 0;
+    for (size_t i = 0; i < radioInfo->numUtilities; i++){
+        cols[columnIndex] = uList[i].name;
+        columnIndex++;
+    }   
+
+    string paramCols[radioInfo->numParameters];
+    size_t paramColumnIndex = 0;
+    // Also need to make parameters the unique key 
+    for (size_t i = 0; i < radioInfo->numParameters; i++){
+        cols[columnIndex] = pList[i].name;
+        paramCols[paramColumnIndex] = pList[i].name;
+        columnIndex++;
+        paramColumnIndex++;
+    }  
+
+    for (size_t i = 0; i < radioInfo->numObservables; i++){
+        cols[columnIndex] = oList[i].name;
+        columnIndex++;
+    }   
+   
+    std::string utility_name = "utility"; 
+    cols[columnIndex] = utility_name;
+
+    myCBR = new CBR(filename, tablename, cols, paramCols, numberColumns, radioInfo->numParameters);
+}
+
+
+void 
+DSA_CE::PerformUpdatePerformance()
+{
+    /* Receive Set of current Parameters */
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numParameters = atoi(buffer);
+
+    Parameter *p = new Parameter[numParameters];
+
+    for(size_t i = 0; i < numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        p[i].value = atof(buffer);
+    } 
+
+    /* Receive Set of Observables */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    ReceiveFeedback(o,p);
+
+    delete [] o;
+    delete [] p;
+}
+
+
+void
+DSA_CE::PerformRequestOptimizationService()
+{
+    // THIS IS CURRENTLY IN DEMO MODE            
+
+
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving service name\n");
+
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    LOG("\nCognitive Engine:: Got service name, %s\n", buffer);
+
+    /* Receive Set of Observables */
+    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numObservables = atoi(buffer);
+
+    Observable *o = new Observable[numObservables];
+
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }  
+
+    /* Receive Set of current Parameters */
+    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
+
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numCurrentParameters = atoi(buffer);
+
+    Parameter *cp = new Parameter[numCurrentParameters];
+
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        cp[i].value = atof(buffer);
+    }  
+    LOG("Cognitive Engine:: Processing parameters....\n");
+
+    // TODO need to actually do something with the observables here
+   
+    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
+    char numParametersChar[10];
+    sprintf(numParametersChar, "%i", radioInfo->numParameters);
+    SendMessage(commandSocketFD, numParametersChar);
+    for(size_t i = 0; i < radioInfo->numParameters; i++) {
+        SendMessage(commandSocketFD, "test");
+        SendMessage(commandSocketFD, "00");
+    }
+
+    delete [] o;
+    delete [] cp;
+}
+
+
+void
+DSA_CE::PerformRequestOptimization()
+{
+	/* Receive Set of Observables */
+	LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
+
+    char buffer[256];
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD,buffer);
+	uint32_t numObservables = atoi(buffer);
+
+	Observable *o = new Observable[numObservables];
+
+	for(size_t i = 0; i < numObservables; i++) {
+		memset(buffer, 0, 256);
+		ReadMessage(commandSocketFD, buffer);
+		o[i].name = std::string(buffer);
+
+		memset(buffer, 0, 256);
+		ReadMessage(commandSocketFD, buffer);
+		o[i].value = atof(buffer);
+	}  
+
+	/* Receive Set of current Parameters */
+	LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
+
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD, buffer);
+	uint32_t numCurrentParameters = atoi(buffer);
+
+	Parameter *cp = new Parameter[numCurrentParameters];
+
+	for(size_t i = 0; i < numCurrentParameters; i++) {
+		memset(buffer, 0, 256);
+		ReadMessage(commandSocketFD, buffer);
+		cp[i].name = std::string(buffer);
+
+		memset(buffer, 0, 256);
+		ReadMessage(commandSocketFD, buffer);
+		cp[i].value = atof(buffer);
+	}  
+	LOG("Cognitive Engine:: Processing parameters....\n");
+
+	Parameter *solutionSet;
+	
+	solutionSet = GetSolution(o,cp);
+
+	// TODO need to actually do something with the observables here
+   
+	LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
+	char numParametersChar[10];
+	char solutionValue[50];
+	sprintf(numParametersChar, "%i", radioInfo->numParameters);
+	SendMessage(commandSocketFD, numParametersChar);
+	for(size_t i = 0; i < radioInfo->numParameters; i++) {
+		SendMessage(commandSocketFD, solutionSet[i].name.c_str());
+		memset(solutionValue, 0, 50);
+		sprintf(solutionValue, "%f", solutionSet[i].value);
+		SendMessage(commandSocketFD, solutionValue);
+	}
+
+	delete [] o;
+	delete [] cp;
+}
+
+
+void
+DSA_CE::PerformQueryComponentType()
+{
+	SendComponentType();
+}
+
+
+void
+DSA_CE::PerformConnectSML()
+{
+	/* This command implies that we are disconnecting from the shell and
+	 * connecting to a SML component. */
+	char serverName[256];
+	char serverPort[256];
+	// TODO is this going to end up being too slow?
+	memset(serverName, 0, 256);
+	memset(serverPort, 0, 256);
+
+	ReadMessage(commandSocketFD, serverName);
+	ReadMessage(commandSocketFD, serverPort);
+
+	/* Only continue if we are currently connected to a shell. */
+	if(!SML_present) {
+		DeregisterComponent();
+
+		shutdown(commandSocketFD, 2);
+		close(commandSocketFD);
+
+		ConnectToRemoteComponent(serverName, serverPort, true);
+	}
+}
+
+
+void
+DSA_CE::PerformDisconnectSML()
+{
+	/* This command implies that we are disconnecting from the SML and
+	 * connecting to a shell component. */
+	char serverName[256];
+	char serverPort[256];
+	// TODO is this going to end up being too slow?
+	memset(serverName, 0, 256);
+	memset(serverPort, 0, 256);
+
+	ReadMessage(commandSocketFD, serverName);
+	ReadMessage(commandSocketFD, serverPort);
+
+	/* We only want to do this if we are actually connected to an SML
+	 * currently. */
+	if(SML_present) {
+		DeregisterServices();
+
+		shutdown(commandSocketFD, 2);
+		close(commandSocketFD);
+
+		ConnectToRemoteComponent(serverName, serverPort, false);
+	}
+}
+
+
+void
+DSA_CE::PerformResetEngineCognitive()
+{
+	Reset();
+}
+
+
+void
+DSA_CE::PerformShutdownEngineCognitive()
+{
+	Shutdown();
+}
+ 
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/Makefile.am	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/Makefile.am	(revision 545)
@@ -0,0 +1,26 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = DSA_Demo
+
+DSA_Demo_SOURCES = DSA_CognitiveEngine.cpp DSA_Demo.cpp
+DSA_Demo_DEPENDENCIES = ../libce.a ../libcbr.a
+DSA_Demo_LDADD = -lsqlite3 ../libce.a ../libcbr.a $(CROSS_SOCKETCOMM_LA) 
+
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.h	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.h	(revision 545)
@@ -0,0 +1,123 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+#ifndef DSA_COGNITIVEENGINE_H
+#define DSA_COGNITIVEENGINE_H
+
+
+/*! Declares a CE based on the default CBR for example purposes. */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <cmath>
+#include <string>
+
+#include "vtcross/cbr.h"
+#include "vtcross/cognitive_engine.h"
+#include "vtcross/common.h"
+#include "vtcross/components.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+
+#define INTERFERENCE 0
+#define CHANNEL 1
+#define ENERGY 0
+#define COMMUNICATION_TIME 1
+#define UTILITY 4
+
+
+class DSA_CE : public CognitiveEngine
+{
+    public:
+        /*! Default constructor. */
+        DSA_CE();
+
+        /*! Default destructor. */
+        ~DSA_CE();
+
+        /*! \brief Preferred constructor.
+         *
+         * Overloaded constructor that creates a cognitive engine object and
+         * connects it to either the shell or an SML, depening on the SML bool.
+         *
+         * The 'numFields' parameter sets how large the parameter, observable,
+         * and utility arrays should be upon instantiation.
+         */
+        DSA_CE(const char* serverName, const char* serverPort, \
+                const int32_t numFields, const bool SML);
+
+        void RegisterServices();
+        void DeregisterServices();
+
+        /*! \brief Request that the CE optimize a set of parameters. 
+         *
+         * Find the most optimal set of transmission parameters given certain
+         * observables and possibly a service if the SML component is present
+         * and active. */
+        Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters);
+        Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters, std::string service);
+
+        /*! \brief Receive feedback from the radio 
+         *
+         * Receive a feedback from the radio regarding the performance of a
+         * certain set of parameters, possibly associated with a service.
+         *
+         * Feedback is a single set of performance statistics that is achieved
+         * corresponding to a specific set of transmission parameters.  Feedback
+         * helps a Cognitive Engine make better future decisions based upon 
+         * more accurate performance statistics. 
+         */
+        void ReceiveFeedback(Observable *observables,Parameter *parameters);
+        void ReceiveFeedback(Observable *observables, Parameter *parameters, \
+                std::string service);
+
+
+        /*! \brief Initialize the CE and prepare it for operation. 
+         *
+         * BuildCognitiveEngine performs the CE implementation specific work
+         * that defines the internals of a CE.  For example, a CBR CE engine
+         * would build the case-base reasoner or create the database, a neural
+         * network based CE may perform the initial training, a GA based CE
+         * may build the chromosome structure.
+         */
+        void BuildCognitiveEngine();
+
+        /*! \brief Each of these functions responds to a specific command.
+         *
+         * These functions are left principally un-implemented. It is the duty
+         * of child classes to implement these functions, as they define the
+         * cognitive engine's functionality.
+         */
+        void PerformUpdatePerformance();
+        void PerformRequestOptimizationService();
+        void PerformRequestOptimization();
+        void PerformQueryComponentType();
+        void PerformConnectSML();
+        void PerformDisconnectSML();
+        void PerformResetEngineCognitive();
+        void PerformShutdownEngineCognitive();
+
+        CBR *myCBR;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_Demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_Demo.cpp	(revision 545)
+++ vtcross/branches/nikhil/crossmodel2/src/cognitive_engines/DSA_CE/DSA_Demo.cpp	(revision 545)
@@ -0,0 +1,49 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/* TODO DESCRIPTION OF FILE.
+ *
+ * This file is a temporary demo of a policy engine using some of our socket
+ * communication functions. This is *not* an actual implementation of our
+ * defined PolicyEngine class.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include "DSA_CognitiveEngine.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    if(argc < 3)
+       ERROR(1, "Usage: %s hostname port\n", argv[0]);
+    
+    DSA_CE cognitiveEngine(argv[1], argv[2], 10, false);
+
+    LOG("Waiting for signal...\n");
+    while(1) {
+        cognitiveEngine.WaitForSignal();
+    }
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/error.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/error.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/error.h	(revision 518)
@@ -0,0 +1,33 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header defines macros for printing to standard error out.  The macros
+ * in this file should be used rather than printing to stderr with fprintf or
+ * exiting with a hard-coded 'exit' call.
+ */
+
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <cstdio>
+
+#define ERROR(exit_code, ...) { \
+    fprintf(stderr, __VA_ARGS__); \
+    exit(exit_code); }
+
+#define WARNING(...) fprintf(stderr, __VA_ARGS__)
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/libvtcross.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/libvtcross.h	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/libvtcross.h	(revision 554)
@@ -0,0 +1,50 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! CROSS Cognitive Radio API
+ *
+ * This header exports all public functions that comprise the CROSS function
+ * library.  These are the functions that are used by the host application to
+ * control the CROSS radio.  
+ *
+ * PUT MORE STUFF HERE
+ */
+
+#ifndef LIBCROSS_H
+#define LIBCROSS_H
+
+#include <stdint.h>
+#include <string>
+
+#include "components.h"
+#include "containers.h"
+
+
+/*! \brief Tell the system where the Shell component is located. 
+ *
+ * Sets the location of the shell component that the client code will be
+ * communicating with. Note that this can be a local or remote destination.
+ */
+
+void SetCrossShellLocation(std::string hostname, std::string port);
+
+Parameter* GetOptimalParameters(Observable *radioObservables, uint32_t numObservables, Parameter *currentParameters, uint32_t numCurrentParameters, Utility *radioUtilities, uint32_t numUtilities);
+
+bool UpdateParameterPerformance(Parameter *p, uint32_t numParameters, Observable *o, uint32_t numObservables, Utility *u, uint32_t numUtilities);
+
+uint32_t GetNum(std::string);
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cognitive_engine.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cognitive_engine.h	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cognitive_engine.h	(revision 554)
@@ -0,0 +1,151 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header exports the declaration for the Cognitive Engine component type.
+ */
+
+#ifndef COGNITIVE_ENGINE_H
+#define COGNITIVE_ENGINE_H
+
+
+#include "components.h"
+
+
+/*! \brief Cognitive Engine class declaration.
+ *
+ * This is the declaration for the default cognitive engine class.  Note that
+ * most of the below functions are implemented in CognitiveEngine.cpp - however,
+ * the functionality is very non-specific.
+ *
+ * Each of the 'Perform*' functions are left un-implemented, for the most part.
+ *
+ * The purpose of this class is to act as a non-abstract parent class.
+ * Cognitive Engines should be built by publically inherting from this class,
+ * and overloading the 'Perform*' functions - thus creating new and specific
+ * cognitive engine functionality, without the need to rewrite or copy/paste the
+ * rest of the code. Other functions that need to be overloaded include:
+ *  1
+ *  2
+ *  3
+ *
+ * Note, however, that all functions are virtual.  Any function may be
+ * overloaded by the child class, if desired.
+ */
+class CognitiveEngine : public Engine
+{
+    public:
+        /*! Default constructor. */
+        CognitiveEngine();
+
+        /*! Default destructor. */
+        ~CognitiveEngine();
+
+        /*! \brief Preferred constructor.
+         *
+         * Overloaded constructor that creates a cognitive engine object and
+         * connects it to either the shell or an SML, depening on the SML bool.
+         *
+         * The 'numFields' parameter sets how large the parameter, observable,
+         * and utility arrays should be upon instantiation.
+         */
+        CognitiveEngine(const char* serverName, const char* serverPort, \
+                const int32_t numFields, const bool SML);
+        
+        virtual void SendComponentType();
+        virtual void ConnectToRemoteComponent(const char* serverName, \
+                const char* serverPort, const bool SML);
+        virtual void WaitForSignal();
+        virtual void Shutdown();
+        virtual void Reset();
+        virtual void RegisterComponent();
+        virtual void DeregisterComponent();
+
+        /*! \brief Receive radio XML configuration.
+         * 
+         * Receive the transmitted radio configuration from the radio itself
+         * (the CE will not always be local to the radio). This gets passed
+         * through either the Shell or the SML. */
+        virtual void ReceiveRadioConfiguration();
+
+        /*! \brief Receive an 'experience' report from the radio.
+         *
+         * An experience report can be used to build the transmission history
+         * for a CE just starting up so that it has a moving start regarding
+         * parameter optimization. */
+        virtual void ReceiveExperience();
+
+        /*! \brief Request that the CE optimize a set of parameters. 
+         *
+         * Find the most optimal set of transmission parameters given certain
+         * observables and possibly a service if the SML component is present
+         * and active. */
+        virtual Parameter *GetSolution(Observable *observables, \
+                Parameter *currentParameters, Utility *utilities);
+
+
+        /*! \brief Receive feedback from the radio 
+         *
+         * Receive a feedback from the radio regarding the performance of a
+         * certain set of parameters, possibly associated with a service.
+         *
+         * Feedback is a single set of performance statistics that is achieved
+         * corresponding to a specific set of transmission parameters.  Feedback
+         * helps a Cognitive Engine make better future decisions based upon 
+         * more accurate performance statistics. 
+         */
+        virtual void ReceiveFeedback(Observable *observables,Parameter *parameters, Utility *utilities);
+
+
+        /*! \brief Initialize the CE and prepare it for operation. 
+         *
+         * BuildCognitiveEngine performs the CE implementation specific work
+         * that defines the internals of a CE.  For example, a CBR CE engine
+         * would build the case-base reasoner or create the database, a neural
+         * network based CE may perform the initial training, a GA based CE
+         * may build the chromosome structure.
+         */
+        virtual void BuildCognitiveEngine();
+
+        /*! \brief Each of these functions responds to a specific command.
+         *
+         * These functions are left principally un-implemented. It is the duty
+         * of child classes to implement these functions, as they define the
+         * cognitive engine's functionality.
+         */
+        virtual void PerformUpdatePerformance();
+        virtual void PerformRequestOptimization();
+        virtual void PerformResetEngineCognitive();
+        virtual void PerformShutdownEngineCognitive();
+ 
+        /*! \brief Keept track of what this CE is connected to. 
+         *
+         * The SML_present bool reflects whether or not the remote component
+         * this object is connected to is an SML.  If it isn't, then it must be
+         * a shell.  The socketFD stores the socket file descriptor for this
+         * connection.
+         */
+        bool SML_present;
+        int32_t commandSocketFD;
+       
+        // TODO Need a description for these fields.  Are these radio utilites,
+        // parameters, and observables global to the whole system?
+        Utility *uList;
+        Parameter *pList;
+        Observable *oList;
+        struct Radio_Info *radioInfo;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cross_shell.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cross_shell.h	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cross_shell.h	(revision 554)
@@ -0,0 +1,167 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header exports the declaration for the CROSS Shell component, which is
+ * a critical part of every CROSS system. 
+ */
+
+#ifndef CROSS_SHELL_H
+#define CROSS_SHELL_H
+
+
+#include "components.h"
+
+
+/*! \brief Cognitive Radio Shell class declaration. 
+ *
+ * The CROSS Cognitive Radio Shell (CRS) is the central control component of
+ * most CROSS radios.  It is a requirement for any CROSS radio, regardless of
+ * the presence or lack thereof of the SML.
+ */
+class CognitiveRadioShell 
+{
+    public:
+        /*! \brief Default CRS costructor. */
+        CognitiveRadioShell();
+
+        /*! \brief Default CRS destructor. */
+        ~CognitiveRadioShell();
+
+        /*! \brief Preferred CRS constructor.
+         *
+         * Overloaded constructor that creates a CR Shell object and loads the
+         * passed radio configuration XML file.
+         */
+        CognitiveRadioShell(const char* radioConfig, int16_t primaryPort, \
+            int16_t policyPort, int16_t commandPort);
+
+        /*! \brief Request the component type of a remote component. */
+        std::string GetRemoteComponentType(int32_t socketFD);
+
+        /*! \brief Respond to a request to identify component type. */
+        void SendComponentType(int32_t socketFD);
+
+        /*! \brief Shutdown the CRS.
+         *
+         * Since the CRS is the central control component of the CROSS radio,
+         * shutting down the CRS will shutdown the entire radio.
+         */
+        void Shutdown();
+
+        /*! \brief Restart the CRS.
+         *
+         * Restart the CRS component - reloads configuration files, and
+         * re-initializes the CRS component.
+         */
+        void Reset();
+        
+        /*! \brief Start the CRS's socket server. 
+         *
+         * This function will make the CRS create a socket server and begin
+         * listening for incoming connections from other components.
+         */
+        void StartShellServer(); 
+
+        /*! \brief Load the radio configuration.
+         *
+         * This function reads in the radio's XML configuration file, which is
+         * typically located on the same system as the CRS, although it can also
+         * be passed to the CRS from the radio host platform if necessary.
+         */
+        void LoadRadioConfiguration(const char* radioConfig, Parameter* &pList, \
+            Utility* &uList, Observable* &oList, Radio_Info* radioInfo);
+    private:
+        /*! \brief Handle component registration activities.
+         *
+         * Register and Deregister the different components.
+         * TODO Are multiple functions really necessary?  They are all basically
+         * doing the same thing...
+         */
+        void RegisterCognitiveEngine(int32_t socketFD);
+        void DeregisterCognitiveEngine(int32_t socketFD);
+
+
+
+
+        
+        /*! \brief Set the active mission.
+         *
+         * This function handles a request by the radio host platform to set or
+         * change the current active mission in the service management layer.
+         * This command is basically passed through the CRS to the SML.
+         */
+
+
+        /* Handle a message that is received from a component.
+         */
+        int32_t HandleMessage(int32_t socketFD);
+       
+        /*! \brief Send optimization request to CE.
+         *
+         * The host application requested that parameters be optimized - pass
+         * the parameters and command to the CE.
+         *
+         * TODO How is the CE being selected if multiple CEs are available?
+         */
+        void GetOptimalParameters(int32_t socketFD);
+
+        /*! TODO
+         */
+        bool SendRadioConfiguration(int32_t socketFD);
+        bool SendRadioExperience(int32_t socketFD);
+
+        /*! TODO
+         */
+        void UpdateParameterPerformance(int32_t socketFD);
+
+        /*! TODO
+         */
+        bool SML_present;
+        bool PE_present;
+        bool CE_present;
+       
+        /*! TODO
+         */
+        int32_t numberOfCognitiveEngines; 
+
+        /*! TODO
+         */       
+        int16_t primaryPort;
+        int16_t policyPort;
+        int16_t commandPort;
+
+        /*! TODO
+         *
+         * I'm confused as to what exactly these are for... there can be
+         * multiple CEs and PEs, and the CRS _IS_ the command component.
+         * --BCH
+         */
+        int32_t ceSocketFD;
+        int32_t commandSocketFD;
+        int32_t policySocketFD;
+
+        /*! TODO
+         */
+        Utility *utils;
+        Parameter *params;
+        Observable *observables;
+
+        /*! TODO
+         */
+        struct Radio_Info *radio_info;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/Makefile.am	(revision 465)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/Makefile.am	(revision 465)
@@ -0,0 +1,21 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+include_HEADERS = error.h debug.h socketcomm.h cbr.h components.h \
+				  containers.h libvtcross.h common.h config.h \
+				  cross_shell.h service_management_layer.h \
+				  cognitive_engine.h policy_engine.h
+
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/policy_engine.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/policy_engine.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/policy_engine.h	(revision 518)
@@ -0,0 +1,92 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header exports the declaration for the Policy Engine component type.
+ */
+
+#ifndef POLICY_ENGINE_H
+#define POLICY_ENGINE_H
+
+
+#include "components.h"
+
+
+/*! \brief Policy Engine class declaration.  
+ *
+ * All public functions are inherited from parent classes Engine and Component.
+ * Please see those class documentation files for further information regarding
+ * public functions.
+ */
+class PolicyEngine : public Engine
+{
+    public:
+        /*! \brief Default Policy Engine Constructor */
+        PolicyEngine();
+
+        /*! \brief Default Policy Engine Destructor */
+        ~PolicyEngine();
+
+        /*! \brief Preferred Policy Engine Constructor. 
+         *
+         * Overloaded constructor that creates a policy engine object and
+         * connects it to either the shell or an SML, depening on the SML bool.
+         */
+        PolicyEngine(const char* serverName, const char* serverPort, \
+                const bool SML);
+
+        void SendComponentType();
+        void ConnectToRemoteComponent(const char* serverName, \
+                const char* serverPort, const bool SML);
+        void WaitForSignal();
+        void Shutdown();
+        void Reset();
+        void RegisterComponent();
+        void DeregisterComponent();
+
+        void RegisterServices();
+        void DeregisterServices();
+
+    private:
+        /*! \brief Parse and load/reload policies into the policy engine. */
+        void LoadPolicies();
+        void ReloadPolicies();
+
+        /*! \brief Return a validation decision.
+         *
+         * Return a decision made by the policy engine regarding a certain set
+         * of transmission parameters.
+         */
+        void SendPEDecision(struct Parameter pList[], struct Radio_Info *radio_info, \
+                int32_t decision_array[]);
+
+        /*! \brief Perform parameter validation.
+         *
+         * Validate a set of transmission parameters received from the radio.
+         */
+        void ValidateParameters();
+
+        /*! \brief Keep track of what control component this PE is connected to.
+         *
+         * The SML_present bool reflects whether or not the remote component
+         * this object is connected to is an SML.  If it isn't, then it must be
+         * a shell.  The socketFD stores the socket file descriptor for this
+         * connection.
+         */
+        bool SML_present;
+        int32_t commandSocketFD;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/socketcomm.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/socketcomm.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/socketcomm.h	(revision 518)
@@ -0,0 +1,65 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file describes the interface to libsocketcomm, which is the internal
+ * socket communication library that CROSS radios use to communicate between
+ * components.
+ */
+
+#ifndef SOCKET_COMM_H
+#define SOCKET_COMM_H
+
+#include <stdint.h>
+
+#include "containers.h"
+
+
+/*! TODO
+ */
+int32_t ReadMessage(int32_t socketFD, char *msgBuffer);
+
+/*! TODO
+ */
+int32_t SendMessage(int32_t socketFD, const char *message) ;
+
+/*! TODO
+ */
+int32_t GetParameter(int32_t socketFD, struct Parameter pList[], \
+        struct Radio_Info *radio_info);
+
+/*! TODO
+ */
+int32_t GetRequest(int32_t socketFD, struct Parameter pList[], \
+        struct Radio_Info *radio_info);
+
+/*! This is the original function that does what the above function is supposed
+ * to do.
+ */
+int32_t ClientSocket(const char  *serverName, const char *portNumber);
+
+/*! TODO
+ */
+int32_t  AcceptTCPConnection(int32_t servSock);
+
+/*! TODO
+ */
+int32_t CreateTCPServerSocket(uint16_t port);
+
+/*! TODO
+ */
+int32_t InitializeTCPServerPort(int32_t servSock);
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/components.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/components.h	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/components.h	(revision 554)
@@ -0,0 +1,125 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header exports the base declarations for all CROSS radio components.
+ * 
+ * It contains two pure abstract base classes, Component and Engine; Engine 
+ * derives from Component.  All functions contained within the abstract base 
+ * classes are dynamically linked and pure, and all child non-abstract classes
+ * derive using private inheritence.  Class functions of the abstract base 
+ * classes are public for two reasons: (1) To allow for public/protected 
+ * inheritence in other implementations, (2) So that symbolic debuggers can 
+ * navigate the call tree for typecasted objects of derivative classes.
+ *
+ * Note that any new component type declaration MUST include this header and
+ * extend a parent component type.
+ */
+
+#ifndef COMPONENTS_H
+#define COMPONENTS_H
+
+
+#include <cstring>
+#include <stdint.h>
+#include <string>
+
+#include "containers.h"
+#include "socketcomm.h"
+
+
+/*! \brief The Component class is the top-level abstract base class in CROSS.
+ *
+ * Component abstract base class that all component classes should inherit from,
+ * including cognitive and policy engines, and the service management layer.
+ * Defines only functions required by all component types.
+ */
+class Component
+{
+    public:
+        /*! \brief Asks a component to identify itself. 
+         *
+         * Asks the component at the passed socket FD for its component type
+         * string.  Note that this implementation is global for all component
+         * types, so is implemented here.  Should a component need to override
+         * it, that is possible via dynamic binding or overloading.
+         */
+        virtual std::string GetRemoteComponentType(int32_t componentSocketFD)
+        {
+            SendMessage(componentSocketFD, "request_component_type");
+
+            char buffer[256];
+            memset(buffer, 0, 256);
+            ReadMessage(componentSocketFD, buffer);
+
+            return std::string(buffer);
+        }
+
+        /*! \brief Responds to a request for identification.
+         *
+         * Send an indentfying string for this object's component type in
+         * response to a GetRemoteComponentType query.
+         */
+        virtual void SendComponentType() = 0;
+
+        /*! \brief Shutdown the component. */
+        virtual void Shutdown() = 0;
+
+        /*! \brief Reset the component and reload configurations. */
+        virtual void Reset() = 0;
+
+        /*! \brief Compenent registration procedures. */
+        virtual void RegisterComponent() = 0;
+        virtual void DeregisterComponent() = 0;
+};
+
+
+/*! \brief Engine abstract base class declaration.
+ *
+ * Engine abstract base class from which all engine component types should
+ * inherit (e.g. cognitive and policy engines). Inherits all functions from the
+ * ABC Component publically.
+ */
+class Engine : public Component
+{
+    public:
+        /*! \brief Connect to a remote controlling component. 
+         *
+         * Connect to the remote control component, which will always be either
+         * the CROSS shell or SML.  Based on the status of the SML_present
+         * bool, this function will also register the component or services.
+         *
+         * TODO I feel like the name of this function could be changed to be a
+         * little more descriptive? */
+        virtual void ConnectToRemoteComponent(const char* serverName, \
+                const char* serverPort, const bool SML) = 0;
+        
+        /*! \brief Wait for a command signal containing task instructions.
+         *
+         * This is the general run-time loop from which all radio operation
+         * occurs.  Once the Engine has started up and initialized, it will
+         * remain in this function until it receives a command to perform some
+         * action. */
+        virtual void WaitForSignal() = 0;
+
+        /*! \brief Functions for interacting with the service management layer. 
+         *
+         * Register or deregister services that this engine provides with the
+         * service management layer. */
+//        virtual void RegisterServices() = 0;
+//        virtual void DeregisterServices() = 0;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/containers.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/containers.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/containers.h	(revision 518)
@@ -0,0 +1,125 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header contains commonly used data container structs in CROSS
+ * systems.
+ */
+
+#ifndef CONTAINERS_H
+#define CONTAINERS_H
+
+
+#include <netdb.h>
+#include <stdint.h>
+#include <string>
+
+
+/*! TODO
+ *
+ */
+struct Radio_Info {
+    uint32_t numUtilities;
+    uint32_t numParameters;
+    uint32_t numObservables;
+    uint32_t policy_engine;
+    uint32_t policy_socket;
+    uint32_t ce_socket;
+};
+
+
+/*! TODO
+ *
+ */
+struct Utility {
+    std::string name;
+    std::string units;
+    std::string goal;
+    float target;
+    float value;
+};
+
+
+/*! TODO
+ *
+ */
+struct Affect {
+    Utility *u;
+    std::string relation;
+};
+
+
+/*! TODO
+ *
+ */
+struct Parameter{
+    std::string name;
+    std::string units;
+    float min;
+    uint32_t numAffects;
+    Affect affection_list[10];
+    float max;
+    float step;
+    float value;
+};
+
+
+/*! TODO
+ *
+ */
+struct Observable {
+    std::string name;
+    Affect affection_list[10];
+    uint32_t numAffects;
+    float value;
+};
+
+
+/*! TODO
+ *
+ */
+struct Service {
+    std::string name;
+    int32_t socketFD;
+    int32_t componentID;
+    uint16_t num_conds;
+    std::string parameter;
+    std::string input[10];
+    std::string output[10];
+}; 
+
+
+/*! TODO
+ *
+ */
+struct Mission {
+    std::string name;
+    uint32_t missionID;
+    uint32_t numServices;
+    Service *services;
+    std::string input[10];
+    std::string output[10];
+};
+
+/*! Registration data for Cognitive Engines for use in communication.
+ */
+struct CE_Reg {
+    int32_t ID_num;
+    //sockaddr_in *sock_ptr;
+    //socklen_t sock_len;
+    int32_t FD;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cbr.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cbr.h	(revision 544)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/cbr.h	(revision 544)
@@ -0,0 +1,118 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header contains the declaration and a full implementation of 
+ * the CBR class - the default CROSS case-based reasoner, which can be used as a
+ * backend for cognitive engines.
+ */
+
+
+#ifndef CBR_H
+#define CBR_H
+
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+#include <stdint.h>
+#include <string>
+
+#include <sqlite3.h>
+
+#include "vtcross/common.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+
+
+#define DATABASENAME "cross_cbr"
+
+
+/*! \brief Case-Based Reasoner class declaration.
+ *
+ * The CBR class is designed to used as either as-is, or as a parent class.  All
+ * functions are declared virtual, and internal members are 'protected' rather
+ * than private. If you require functionality in a CBR not specifically provided
+ * by this class, include this header in your source file, create a new class
+ * that derives from CBR, and implement your desired functionality over the
+ * original virtual functions as necessary.
+ */
+class CBR
+{
+    public:
+        /*! \brief Constructors for the CBR class. 
+         *
+         * Note that the default constructor
+         * must be defined inline here so that super-calls from child classes
+         * don't fail (i.e. we cannot rely on the compiler-provided constructor. */
+        CBR(){};
+        CBR(std::string _filename, std::string _tablename, std::string _cols[], uint32_t _len);
+        CBR(std::string _filename, std::string _tablename, std::string _cols[], \
+                std::string _primcols[], uint32_t _len, uint32_t _primlen);
+
+        /*! \brief Destructors for the CBR class.
+         *
+         * Destructor for the CBR class. Note that this destructor will be
+         * called automatically by any derived classes, and so child classes
+         * should not repeat the freeing actions performed in this function. */
+        virtual ~CBR();
+
+        /*! \brief Open/Create a sqlite database for the CBR.
+         *
+         * This function opens the CROSS database, or if it has not been
+         * created yet, creates it. */
+        virtual int32_t OpenDatabase();
+
+        /*! \brief  Execute a sqlite command.
+         *
+         * Construct and execute a sqlite3 command and pass the return code back. */
+        virtual int32_t ExecuteCommand();
+
+        /*! \brief Search the sqlite3 database. 
+         *
+         * Execute a sqlite3 search command and store the results in the passed
+         * retvals argument. */
+        virtual int32_t ExecuteSearchCommand(float *_retvals);
+
+        /*! \brief Print the CROSS sqlite database. */
+        virtual void Print();
+
+        /*! \brief Search the CBR database. 
+         *
+         * Search the CROSS database for specific fields and store the results
+         * in the passed retvals argument. */
+        virtual int32_t Search(std::string _names[], int32_t *_ops, float *_vals, \
+                uint32_t _n, float *_retvals);
+        virtual int32_t SearchSum(std::string _name, float *_retvals);
+        virtual int32_t SearchRand(std::string _names[], int32_t *_ops, float *_vals, uint32_t _n, \
+            float *_retvals);
+
+        /*! \brief Update an entry in the CBR database.  */
+        virtual int32_t Update(std::string _where[], std::string _set[], float *_wherevals, \
+                float *_setvals, uint32_t _wherelen, uint32_t _setlen);
+
+
+        /*! \brief Add a row to the CROSS sqlite3 database. */
+        virtual int32_t AddRow(std::string _cols[], float *_vals, uint32_t _len);
+
+    protected:
+        std::string filename;
+        std::string tablename;
+        std::string command;
+
+        sqlite3 *db; 
+        uint32_t numColumns;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/debug.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/debug.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/debug.h	(revision 518)
@@ -0,0 +1,37 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header defines macros for log functions and debug statements.
+ * Generally, it is recommended that this header be included in every source
+ * file.  The functions included in this file should be used rather than
+ * hard-coding 'printf's or 'cout's in your code.
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <cstdio>
+
+extern bool VTCROSS_DEBUG;
+
+#define DEBUG(...) \
+    if(VTCROSS_DEBUG) {\
+        fprintf(stderr, __VA_ARGS__);\
+    }
+
+#define LOG(...) fprintf(stdout, __VA_ARGS__)
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/common.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/common.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/common.h	(revision 518)
@@ -0,0 +1,27 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file is included in every source file of the CROSS system.  It 
+ * declares global flags and includes. */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#ifdef HAVE_CONFIG_H
+    #include "config.h"
+#endif
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/vtcross/service_management_layer.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/vtcross/service_management_layer.h	(revision 518)
+++ vtcross/branches/nikhil/crossmodel2/src/include/vtcross/service_management_layer.h	(revision 518)
@@ -0,0 +1,143 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This header exports the declaration for the Service Management Layer
+ * component.
+ */
+
+#ifndef SML_H
+#define SML_H
+
+
+#include "components.h"
+
+
+/*! \brief Service Management Layer (SML) class declaration.  
+ *
+ * The functions listed here are required by the CROSS API for 
+ * service-oriented CROSS radio architectures.  Note that most public functions
+ * are documented in the parent class, Component.
+ */
+class ServiceManagementLayer : public Component
+{
+    public:
+        /*! \brief Default SML Constructor. */
+        ServiceManagementLayer();
+
+        /*! \brief Default SML Destructor. */
+        ~ServiceManagementLayer();
+
+        /*! \brief Preferred SML Constructor.
+         *
+         * Overloaded constructor that creates an SML and connects it to the
+         * shell with the passed hostname and port.
+         */
+        ServiceManagementLayer(const char* SML_Config, const char* serverName, \
+                const char* serverPort, int16_t clientPort);
+
+        /*! \brief Connect the SML to a remote Shell control component. 
+         *
+         * Connect and register with the shell component at the passed hostname
+         * and port.
+         */
+        void ConnectToShell(const char* serverName, const char* serverPort);
+
+        void SendComponentType();
+        void MessageHandler(int32_t ID);
+        void Shutdown();
+        void Reset();
+        void RegisterComponent();
+        void DeregisterComponent();
+
+        /*! \brief Starts the SML Server and watches it for incoming messages
+         *
+         * TODO
+         */
+        void StartSMLServer();
+
+    private: 
+        /*! \brief Pass the radio configuration onto another component. 
+         *
+         * Receive the radio configuration settings from the shell and pass them
+         * on to another component.
+         */
+        void TransferRadioConfiguration(int32_t ID);
+
+        /*! \brief Pass a radio experience onto another component. 
+         *
+         * Receive information regarding a completed 'experience' and pass it on
+         * to the appropriate cognitive engine.
+         */
+        void TransferExperience(int32_t ID);
+        
+        /*! Listen for other components registering their available services with
+         * the SML. 
+         */
+        void ReceiveServices(int32_t ID);
+        void DeregisterServices(int32_t ID);
+
+        /*! Change the active mission of the radio to a new one and adjust radio
+         * behavoir appropriately.
+         */
+        void SetActiveMission();
+
+        /*! TODO
+         */
+        void RegisterCognitiveEngine(int32_t ID);
+        void DeregisterCognitiveEngine(int32_t ID);
+
+        /*! List all services provided to the radio by registered components.
+         */
+        void ListServices();
+
+        /*! Load/Relead the XML configuration file. 
+         */
+        void ReloadConfiguration();
+        void LoadConfiguration(const char *SML_Config, Mission* &mList);
+
+        /*! Create and initialize the DB to hold the services
+        */
+        void CreateServicesDB();
+        void CreateDataDB();
+
+        /*! TODO
+         */
+        void PerformActiveMission();
+        void TransactData(int32_t sourceID);
+
+        /*! The socket file descriptor information for the shell which this SML
+         * is connected to.
+         */
+        int32_t shellSocketFD;
+
+        /*! TODO
+         */
+        int16_t CEPort;
+        int16_t SMLport;
+
+        uint32_t numberOfCognitiveEngines;
+
+        int32_t cogEngSrv;
+        int32_t activeMission;
+
+        uint32_t Current_ID; 
+
+        bool CE_Present;
+        CE_Reg *CE_List;
+        Mission *miss;
+};
+
+#endif
Index: vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinystr.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinystr.h	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinystr.h	(revision 161)
@@ -0,0 +1,319 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*	The support for explicit isn't that universal, and it isn't really
+	required - it is used to check that the TiXmlString class isn't incorrectly
+	used. Be nice to old compilers and macro it here:
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+	// Microsoft visual studio, version 6 and higher.
+	#define TIXML_EXPLICIT explicit
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+	// GCC version 3 and higher.s
+	#define TIXML_EXPLICIT explicit
+#else
+	#define TIXML_EXPLICIT
+#endif
+
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef size_t size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString ( const TiXmlString & copy) : rep_(0)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
Index: vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/Makefile.am	(revision 411)
@@ -0,0 +1,18 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+
+include_HEADERS = tinystr.h tinyxml.h
Index: vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinyxml.h
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinyxml.h	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/include/tinyxml/tinyxml.h	(revision 161)
@@ -0,0 +1,1802 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#include <sstream>
+	#define TIXML_STRING		std::string
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING		TiXmlString
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
+
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		// Microsoft visual studio, version 2005 and higher.
+		#define TIXML_SNPRINTF _snprintf_s
+		#define TIXML_SNSCANF  _snscanf_s
+		#define TIXML_SSCANF   sscanf_s
+	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+		#define TIXML_SSCANF   sscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+		#define TIXML_SSCANF   sscanf
+	#else
+		#define TIXML_SSCANF   sscanf
+	#endif
+#endif	
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 5;
+const int TIXML_PATCH_VERSION = 3;
+
+/*	Internal structure for tracking location of items 
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+/**
+	If you call the Accept() method, it requires being passed a TiXmlVisitor
+	class to handle callbacks. For nodes that contain other nodes (Document, Element)
+	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+	are simple called with Visit().
+
+	If you return 'true' from a Visit method, recursive parsing will continue. If you return
+	false, <b>no children of this node or its sibilings</b> will be Visited.
+
+	All flavors of Visit methods have a default implementation that returns 'true' (continue 
+	visiting). You need to only override methods that are interesting to you.
+
+	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+	You should never change the document from a callback.
+
+	@sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+	virtual ~TiXmlVisitor() {}
+
+	/// Visit a document.
+	virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )			{ return true; }
+	/// Visit a document.
+	virtual bool VisitExit( const TiXmlDocument& /*doc*/ )			{ return true; }
+
+	/// Visit an element.
+	virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )	{ return true; }
+	/// Visit an element.
+	virtual bool VisitExit( const TiXmlElement& /*element*/ )		{ return true; }
+
+	/// Visit a declaration
+	virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )	{ return true; }
+	/// Visit a text node
+	virtual bool Visit( const TiXmlText& /*text*/ )					{ return true; }
+	/// Visit a comment node
+	virtual bool Visit( const TiXmlComment& /*comment*/ )			{ return true; }
+	/// Visit an unknow node
+	virtual bool Visit( const TiXmlUnknown& /*unknown*/ )			{ return true; }
+};
+
+// Only used by Attribute::Query functions
+enum 
+{ 
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0)		{}
+	virtual ~TiXmlBase()			{}
+
+	/**	All TinyXml classes can print themselves to a filestream
+		or the string class (TiXmlString in non-STL mode, std::string
+		in STL mode.) Either or both cfile and str can be null.
+		
+		This is a formatted print, and will insert 
+		tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		value is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
+	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
+	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p, 
+								TiXmlParsingData* data, 
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
+		or they will be transformed into entities!
+	*/
+	static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+		TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+	inline static bool IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+	inline static bool IsWhiteSpace( int c )
+	{
+		if ( c < 256 )
+			return IsWhiteSpace( (char) c );
+		return false;	// Again, only truly correct for English/Latin...but usually works.
+	}
+
+	#ifdef TIXML_USE_STL
+	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((const unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+	
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */	
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	const TIXML_STRING& ValueTStr() const { return value; }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const		{ return firstChild; }	///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()						{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	/// The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * _value ) {
+		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+		// call the method, cast the return back to non-const.
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+	}
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * _value ) {
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+	}
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char *_prev ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char* _next ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char *_next ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+	}
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * _value ) const;
+	TiXmlElement* FirstChildElement( const char * _value ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument() {
+		return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+	}
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller. 
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
+		XML tree will be conditionally visited and the host will be called back
+		via the TiXmlVisitor interface.
+
+		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+		interface versus any other.)
+
+		The interface has been based on ideas from:
+
+		- http://www.saxproject.org/
+		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
+
+		Which are both good references for "visiting".
+
+		An example of using Accept():
+		@verbatim
+		TiXmlPrinter printer;
+		tinyxmlDoc.Accept( &printer );
+		const char* xmlcstr = printer.CStr();
+		@endverbatim
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
+	#ifdef TIXML_USE_STL
+	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
+	#endif
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	// Get the tinyxml string representation
+	const TIXML_STRING& NameTStr() const { return name; }
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	{ name = _name; }	
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
+	}
+
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
+	}
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	const TiXmlAttribute*	Find( const char* _name ) const;
+	TiXmlAttribute*	Find( const char* _name ) {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
+	}
+	#ifdef TIXML_USE_STL
+	const TiXmlAttribute*	Find( const std::string& _name ) const;
+	TiXmlAttribute*	Find( const std::string& _name ) {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
+	}
+
+	#endif
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	void operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/	
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+    #ifdef TIXML_USE_STL
+	/** Template form of the attribute query which will try to read the
+		attribute into the specified type. Very easy, very powerful, but
+		be careful to make sure to call this with the correct type.
+		
+		NOTE: This method doesn't work correctly for 'string' types.
+
+		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+	*/
+	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+
+		std::stringstream sstream( node->ValueStr() );
+		sstream >> *outValue;
+		if ( !sstream.fail() )
+			return TIXML_SUCCESS;
+		return TIXML_WRONG_TYPE;
+	}
+	/*
+	 This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
+	 but template specialization is hard to get working cross-compiler. Leaving the bug for now.
+	 
+	// The above will fail for std::string because the space character is used as a seperator.
+	// Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
+	template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+		*outValue = node->ValueStr();
+		return TIXML_SUCCESS;
+	}
+	*/
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const std::string* Attribute( const std::string& name ) const;
+	const std::string* Attribute( const std::string& name, int* i ) const;
+	const std::string* Attribute( const std::string& name, double* d ) const;
+	int QueryIntAttribute( const std::string& name, int* _value ) const;
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+	
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text". 
+		
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo> 
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo> 
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the 
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+	/// Construct a comment from text.
+	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
+		SetValue( _value );
+	}
+	TiXmlComment( const TiXmlComment& );
+	void operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output 
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with 
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as 
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
+
+	// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA() const				{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	void operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	void operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+	/** Load a file using the given FILE*. Returns true if successful. Note that this method
+		doesn't stream - the entire object pointed at by the FILE*
+		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+		file location. Streaming may be added in the future.
+	*/
+	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given FILE*. Returns true if successful.
+	bool SaveFile( FILE* ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+//		StringToBuffer f( filename );
+//		return ( f.buffer && LoadFile( f.buffer, encoding ));
+		return LoadFile( filename.c_str(), encoding );
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+//		StringToBuffer f( filename );
+//		return ( f.buffer && SaveFile( f.buffer ));
+		return SaveFile( filename.c_str() );
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/	
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1, 
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow() const	{ return errorLocation.row+1; }
+	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+		
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false; 
+												errorId = 0; 
+												errorDesc = ""; 
+												errorLocation.row = errorLocation.col = 0; 
+												//errorLocation.last = 0; 
+											}
+
+	/** Write the document to standard out using formatted printing ("pretty print"). */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/* Write the document to a string using formatted printing ("pretty print"). This
+		will allocate a character array (new char[]) and return it as a pointer. The
+		calling code pust call delete[] on the return char* to avoid a memory leak.
+	*/
+	//char* PrintToMemory() const; 
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0; 
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
+	a linear walk to find the element, so this code would iterate much more than it needs 
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/** Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* ToNode() const			{ return node; } 
+	/** Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/**	Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/** Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+	/** @deprecated use ToNode. 
+		Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* Node() const			{ return ToNode(); } 
+	/** @deprecated use ToElement. 
+		Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* Element() const	{ return ToElement(); }
+	/**	@deprecated use ToText()
+		Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* Text() const			{ return ToText(); }
+	/** @deprecated use ToUnknown()
+		Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
+
+private:
+	TiXmlNode* node;
+};
+
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+	-# Print to memory (especially in non-STL mode)
+	-# Control formatting (line endings, etc.)
+
+	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+	Before calling Accept() you can call methods to control the printing
+	of the XML document. After TiXmlNode::Accept() is called, the printed document can
+	be accessed via the CStr(), Str(), and Size() methods.
+
+	TiXmlPrinter uses the Visitor API.
+	@verbatim
+	TiXmlPrinter printer;
+	printer.SetIndent( "\t" );
+
+	doc.Accept( &printer );
+	fprintf( stdout, "%s", printer.CStr() );
+	@endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
+
+	virtual bool VisitEnter( const TiXmlDocument& doc );
+	virtual bool VisitExit( const TiXmlDocument& doc );
+
+	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+	virtual bool VisitExit( const TiXmlElement& element );
+
+	virtual bool Visit( const TiXmlDeclaration& declaration );
+	virtual bool Visit( const TiXmlText& text );
+	virtual bool Visit( const TiXmlComment& comment );
+	virtual bool Visit( const TiXmlUnknown& unknown );
+
+	/** Set the indent characters for printing. By default 4 spaces
+		but tab (\t) is also useful, or null/empty string for no indentation.
+	*/
+	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
+	/// Query the indention string.
+	const char* Indent()							{ return indent.c_str(); }
+	/** Set the line breaking string. By default set to newline (\n). 
+		Some operating systems prefer other characters, or can be
+		set to the null/empty string for no indenation.
+	*/
+	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
+	/// Query the current line breaking string.
+	const char* LineBreak()							{ return lineBreak.c_str(); }
+
+	/** Switch over to "stream printing" which is the most dense formatting without 
+		linebreaks. Common when the XML is needed for network transmission.
+	*/
+	void SetStreamPrinting()						{ indent = "";
+													  lineBreak = "";
+													}	
+	/// Return the result.
+	const char* CStr()								{ return buffer.c_str(); }
+	/// Return the length of the result string.
+	size_t Size()									{ return buffer.size(); }
+
+	#ifdef TIXML_USE_STL
+	/// Return the result.
+	const std::string& Str()						{ return buffer; }
+	#endif
+
+private:
+	void DoIndent()	{
+		for( int i=0; i<depth; ++i )
+			buffer += indent;
+	}
+	void DoLineBreak() {
+		buffer += lineBreak;
+	}
+
+	int depth;
+	bool simpleTextPrint;
+	TIXML_STRING buffer;
+	TIXML_STRING indent;
+	TIXML_STRING lineBreak;
+};
+
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+
Index: vtcross/branches/nikhil/crossmodel2/src/include/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/include/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/include/Makefile.am	(revision 411)
@@ -0,0 +1,17 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = vtcross tinyxml
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/transmit_path.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/transmit_path.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/transmit_path.py	(revision 502)
@@ -0,0 +1,118 @@
+#
+# Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, blks2
+from gnuradio import eng_notation
+
+import copy
+import sys
+
+# /////////////////////////////////////////////////////////////////////////////
+#                              transmit path
+# /////////////////////////////////////////////////////////////////////////////
+
+class transmit_path(gr.hier_block2):
+    def __init__(self, modulator_class, options):
+        '''
+        See below for what options should hold
+        '''
+	gr.hier_block2.__init__(self, "transmit_path",
+				gr.io_signature(0, 0, 0),                    # Input signature
+				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+        
+        options = copy.copy(options)    # make a copy so we can destructively modify
+
+        self._verbose            = options.verbose
+        self._tx_amplitude       = options.tx_amplitude    # digital amplitude sent to USRP
+        self._bitrate            = options.bitrate         # desired bit rate
+        self._samples_per_symbol = options.samples_per_symbol  # desired samples/baud
+
+        self._modulator_class = modulator_class         # the modulator_class we are using
+
+        # Get mod_kwargs
+        mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
+    
+        # transmitter
+	modulator = self._modulator_class(**mod_kwargs)
+        self.packet_transmitter = \
+            blks2.mod_pkts(modulator,
+                           access_code=None,
+                           msgq_limit=4,
+                           pad_for_usrp=True)
+
+        self.amp = gr.multiply_const_cc(1)
+        self.set_tx_amplitude(self._tx_amplitude)
+
+        # Display some information about the setup
+        if self._verbose:
+            self._print_verbage()
+
+        # Connect components in the flowgraph
+        self.connect(self.packet_transmitter, self.amp, self)
+
+    def set_tx_amplitude(self, ampl):
+        """
+        Sets the transmit amplitude sent to the USRP in volts
+        @param: ampl 0 <= ampl < 1.
+        """
+        self._tx_amplitude = max(0.0, min(ampl, 1))
+        self.amp.set_k(self._tx_amplitude)
+        
+    def send_pkt(self, payload='', eof=False):
+        """
+        Calls the transmitter method to send a packet
+        """
+        return self.packet_transmitter.send_pkt(payload, eof)
+        
+    def bitrate(self):
+        return self._bitrate
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def add_options(normal, expert):
+        """
+        Adds transmitter-specific options to the Options Parser
+        """
+        if not normal.has_option('--bitrate'):
+            normal.add_option("-r", "--bitrate", type="eng_float", default=100e3,
+                              help="specify bitrate [default=%default].")
+        normal.add_option("", "--tx-amplitude", type="eng_float", default=0.250, metavar="AMPL",
+                          help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]")
+        normal.add_option("-v", "--verbose", action="store_true", default=False)
+
+        expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+                          help="set samples/symbol [default=%default]")
+        expert.add_option("", "--log", action="store_true", default=False,
+                          help="Log all parts of flow graph to file (CAUTION: lots of data)")
+
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+    def _print_verbage(self):
+        """
+        Prints information about the transmit path
+        """
+        print "Tx amplitude     %s"    % (self._tx_amplitude)
+        print "modulation:      %s"    % (self._modulator_class.__name__)
+        print "bitrate:         %sb/s" % (eng_notation.num_to_str(self._bitrate))
+        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
+        
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/receive_path.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/receive_path.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/receive_path.py	(revision 502)
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, blks2
+from gnuradio import eng_notation
+import copy
+import sys
+
+# /////////////////////////////////////////////////////////////////////////////
+#                              receive path
+# /////////////////////////////////////////////////////////////////////////////
+
+class receive_path(gr.hier_block2):
+    def __init__(self, demod_class, rx_callback, options):
+	gr.hier_block2.__init__(self, "receive_path",
+				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+				gr.io_signature(0, 0, 0))                    # Output signature
+
+        
+        options = copy.copy(options)    # make a copy so we can destructively modify
+
+        self._verbose            = options.verbose
+        self._bitrate            = options.bitrate         # desired bit rate
+        self._samples_per_symbol = options.samples_per_symbol  # desired samples/symbol
+
+        self._rx_callback   = rx_callback      # this callback is fired when there's a packet available
+        self._demod_class   = demod_class      # the demodulator_class we're using
+
+        # Get demod_kwargs
+        demod_kwargs = self._demod_class.extract_kwargs_from_options(options)
+
+        # Design filter to get actual channel we want
+        sw_decim = 1
+        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
+                                          sw_decim * self._samples_per_symbol, # sampling rate
+                                          1.0,                  # midpoint of trans. band
+                                          0.5,                  # width of trans. band
+                                          gr.firdes.WIN_HANN)   # filter type
+        self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
+        
+        # receiver
+        self.packet_receiver = \
+            blks2.demod_pkts(self._demod_class(**demod_kwargs),
+                             access_code=None,
+                             callback=self._rx_callback,
+                             threshold=-1)
+
+        # Carrier Sensing Blocks
+        alpha = 0.001
+        thresh = 30   # in dB, will have to adjust
+        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
+
+        # Display some information about the setup
+        if self._verbose:
+            self._print_verbage()
+
+	# connect block input to channel filter
+	self.connect(self, self.channel_filter)
+
+        # connect the channel input filter to the carrier power detector
+        self.connect(self.channel_filter, self.probe)
+
+        # connect channel filter to the packet receiver
+        self.connect(self.channel_filter, self.packet_receiver)
+
+    def bitrate(self):
+        return self._bitrate
+
+    def samples_per_symbol(self):
+        return self._samples_per_symbol
+
+    def carrier_sensed(self):
+        """
+        Return True if we think carrier is present.
+        """
+        #return self.probe.level() > X
+        return self.probe.unmuted()
+
+    def carrier_threshold(self):
+        """
+        Return current setting in dB.
+        """
+        return self.probe.threshold()
+
+    def set_carrier_threshold(self, threshold_in_db):
+        """
+        Set carrier threshold.
+
+        @param threshold_in_db: set detection threshold
+        @type threshold_in_db:  float (dB)
+        """
+        self.probe.set_threshold(threshold_in_db)
+    
+        
+    def add_options(normal, expert):
+        """
+        Adds receiver-specific options to the Options Parser
+        """
+        if not normal.has_option("--bitrate"):
+            normal.add_option("-r", "--bitrate", type="eng_float", default=100e3,
+                              help="specify bitrate [default=%default].")
+        normal.add_option("-v", "--verbose", action="store_true", default=False)
+        expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+                          help="set samples/symbol [default=%default]")
+        expert.add_option("", "--log", action="store_true", default=False,
+                          help="Log all parts of flow graph to files (CAUTION: lots of data)")
+
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+
+    def _print_verbage(self):
+        """
+        Prints information about the receive path
+        """
+        print "\nReceive Path:"
+        print "modulation:      %s"    % (self._demod_class.__name__)
+        print "bitrate:         %sb/s" % (eng_notation.num_to_str(self._bitrate))
+        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/pick_bitrate.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/pick_bitrate.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/pick_bitrate.py	(revision 502)
@@ -0,0 +1,153 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import eng_notation
+
+_default_bitrate = 500e3
+
+_valid_samples_per_symbol = (2,3,4,5,6,7)
+
+def _gen_tx_info(converter_rate, xrates):
+    results = []
+    for samples_per_symbol in _valid_samples_per_symbol:
+        for interp in xrates:
+            bitrate = converter_rate / interp / samples_per_symbol
+            results.append((bitrate, samples_per_symbol, interp))
+    results.sort()
+    return results
+
+def _gen_rx_info(converter_rate, xrates):
+    results = []
+    for samples_per_symbol in _valid_samples_per_symbol:
+        for decim in xrates:
+            bitrate = converter_rate / decim / samples_per_symbol
+            results.append((bitrate, samples_per_symbol, decim))
+    results.sort()
+    return results
+    
+def _filter_info(info, samples_per_symbol, xrate):
+    if samples_per_symbol is not None:
+        info = [x for x in info if x[1] == samples_per_symbol]
+    if xrate is not None:
+        info = [x for x in info if x[2] == xrate]
+    return info
+
+def _pick_best(target_bitrate, bits_per_symbol, info):
+    """
+    @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate)
+    """
+    if len(info) == 0:
+        raise RuntimeError, "info is zero length!"
+
+    if target_bitrate is None:     # return the fastest one
+        return info[-1]
+    
+    # convert bit rate to symbol rate
+    target_symbolrate = target_bitrate / bits_per_symbol
+    
+    # Find the closest matching symbol rate.
+    # In the event of a tie, the one with the lowest samples_per_symbol wins.
+    # (We already sorted them, so the first one is the one we take)
+
+    best = info[0]
+    best_delta = abs(target_symbolrate - best[0])
+    for x in info[1:]:
+        delta = abs(target_symbolrate - x[0])
+        if delta < best_delta:
+            best_delta = delta
+            best = x
+
+    # convert symbol rate back to bit rate
+    return ((best[0] * bits_per_symbol),) + best[1:]
+
+def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                  xrate, converter_rate, xrates, gen_info):
+    """
+    @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate)
+    """
+    if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1:
+        raise ValueError, "bits_per_symbol must be an int >= 1"
+    
+    if samples_per_symbol is not None and xrate is not None:  # completely determined
+        return (float(converter_rate) / xrate / samples_per_symbol,
+                samples_per_symbol, xrate)
+
+    if bitrate is None and samples_per_symbol is None and xrate is None:
+        bitrate = _default_bitrate
+
+    # now we have a target bitrate and possibly an xrate or
+    # samples_per_symbol constraint, but not both of them.
+
+    ret = _pick_best(bitrate, bits_per_symbol,
+                      _filter_info(gen_info(converter_rate, xrates), samples_per_symbol, xrate))
+    print "Actual Bitrate:", eng_notation.num_to_str(ret[0])
+    return ret
+    
+# ---------------------------------------------------------------------------------------
+
+def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                    interp_rate, converter_rate, possible_interps):
+    """
+    Given the 4 input parameters, return at configuration that matches
+
+    @param bitrate: desired bitrate or None
+    @type bitrate: number or None
+    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+    @type bits_per_symbol: integer >= 1
+    @param samples_per_symbol: samples/baud (aka samples/symbol)
+    @type samples_per_symbol: number or None
+    @param interp_rate: USRP interpolation factor
+    @type interp_rate: integer or None
+    @param converter_rate: converter sample rate in Hz
+    @type converter_rate: number
+    @param possible_interps: a list of possible rates
+    @type possible_interps: a list of integers
+
+    @returns tuple (bitrate, samples_per_symbol, interp_rate)
+    """
+    print "Requested TX Bitrate:", bitrate and eng_notation.num_to_str(bitrate) or 'Auto',
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                         interp_rate, converter_rate, possible_interps, _gen_tx_info)
+
+
+def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                    decim_rate, converter_rate, possible_decims):
+    """
+    Given the 4 input parameters, return at configuration that matches
+
+    @param bitrate: desired bitrate or None
+    @type bitrate: number or None
+    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+    @type bits_per_symbol: integer >= 1
+    @param samples_per_symbol: samples/baud (aka samples/symbol)
+    @type samples_per_symbol: number or None
+    @param decim_rate: USRP decimation factor
+    @type decim_rate: integer or None
+    @param converter_rate: converter sample rate in Hz
+    @type converter_rate: number
+    @param possible_decims: a list of possible rates
+    @type possible_decims: a list of integers
+
+    @returns tuple (bitrate, samples_per_symbol, decim_rate)
+    """
+    print "Requested RX Bitrate:", bitrate and eng_notation.num_to_str(bitrate) or 'Auto'
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+                         decim_rate, converter_rate, possible_decims, _gen_rx_info)
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/benchmark_dsa.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/benchmark_dsa.py	(revision 517)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/benchmark_dsa.py	(revision 517)
@@ -0,0 +1,445 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
+#
+# Copyright 2009 Virginia Polytechnic Institute and State University 
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gru, modulation_utils
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from numpy import random
+import random, time, struct, sys, math
+from datetime import datetime
+
+# from current dir
+#from transmit_path import transmit_path
+#from receive_path import receive_path
+
+import usrp_transmit_path
+import usrp_receive_path
+
+
+try:
+    from cross import *
+    cross_import = True
+except ImportError:
+    cross_import = False
+
+global sync_status,mode,ch,data_packet_delivery_count,n_rcvd, n_right
+sync_status = False
+
+#Defining modes of operation
+# sync: the two nodes are trying to rendezvous on a common channel
+# traffic: the two node are communicating information to each other
+mode = "sync" #Default mode is sync
+data_packet_delivery_count = 0
+
+class my_top_block(gr.top_block):
+
+    def __init__(self, mod_class, demod_class,
+            rx_callback, options_tx,options_rx):
+
+        gr.top_block.__init__(self)
+        self.rxpath = usrp_receive_path.usrp_receive_path(demod_class, rx_callback, options_rx)
+        self.txpath = usrp_transmit_path.usrp_transmit_path(mod_class, options_tx)
+        self.connect(self.txpath);
+        self.connect(self.rxpath);
+
+
+def main():
+
+    global stats_array, count_array, time_array, n_rcvd
+    global n_right, sync_status, mode, ch, data_packet_delivery_count
+    global n_attempts, return_flag, crossShellHost, crossShellPort
+    data_packet_delivery_count_previous = 0
+    n_rcvd = 0
+    n_right = 0
+    n_attempts = 5
+    return_flag = 0
+
+    count_array = [ 0, 0, 0, 0, 0]
+    time_array = [ 0, 0, 0, 0, 0]
+    stats_array = [ 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0]
+
+
+    def send_pkt(self, payload='', eof=False):
+        return self.txpath.send_pkt(payload, eof)
+
+
+    def get_real_channel(channel):
+
+        real_channel = 1;
+
+        get_channel = {
+            1: 1,
+            2: 7,
+            3: 8,
+            4: 14 
+        }
+
+        real_channel = get_channel[channel]
+
+        return real_channel
+
+
+    def get_average_time(channel,absent_time):
+
+        global count_array, time_array
+
+        count_array[channel] = count_array[channel] + 1
+        average_time = (time_array[channel] + absent_time) / count_array[channel]    
+    
+        return average_time
+
+
+    def get_freq(hop_freq,probe_level,absent_time,cross):
+
+        # Convert hop_freq to our unique channel list
+
+        if cross == True:
+
+            freq_channel = {
+                462562500: 1,
+                462712500: 2,
+                467562500: 3,
+                467712500: 4,
+            }
+
+            currentParameters = Parameter(1)
+            currentParameters[0].name = "channel"
+            currentParameters[0].value = freq_channel[hop_freq] 
+
+            o = Observable(2)
+            o[0].value = probe_level
+            o[0].name = "energy"
+    
+            o[1].value = absent_time 
+            o[1].name = "communication_time"
+        
+            # If time == 0 then we are scanning and we dont want to 
+            #  use this time in the averaging process.
+            if absent_time != 0:
+                try:
+                    UpdateParameterPerformance(currentParameters,1,o,1)
+                except:
+                    print "fail"
+            else:
+                # Get the average communication time
+                average_time = get_average_time(freq_channel[hop_freq], absent_time)
+                o[1].value = average_time 
+                o[1].name = "communication_time"
+                try:
+                    UpdateParameterPerformance(currentParameters,1,o,2)
+                except:
+                    print "fail"
+
+            p = Parameter(1)
+            p = GetOptimalParameters(o,2,currentParameters,1);
+        
+            channel = get_real_channel(int(p[0].value))
+        else:
+            channel = int(random.choice([1,7,8,14]))
+            
+        if channel < 8:
+            hop_freq = float(1e6 * (462.5625+(channel-1)*0.025))#setting the centre freq frequency for sending packets
+        else:
+            hop_freq = float(1e6 * (467.5625+(channel-8)*0.025))#setting the centre freq frequency for sending packets    
+        
+        stats_array[channel] = stats_array[channel] + 1
+	print "\nChannel DSA Selection Statistics (Channel #: Number times selected)"
+        print "1: ", stats_array[1], " 7: ",stats_array[7], " 8: ",stats_array[8], " 14: ", stats_array[14]
+        return channel,hop_freq #returning the channel number and hop frequency
+    
+
+    def rx_callback(ok, payload):
+        
+        global n_rcvd, n_right,sync_status,mode,ch,data_packet_delivery_count
+        ########################## sync ####################################
+        if mode == "sync":
+            if ok:
+                (pktno,) = struct.unpack('!H', payload[0:2])
+                (sync_signal,) = struct.unpack('!s', payload[2]) 
+                (data_channel,) = struct.unpack('!H', payload[3:5])
+                                  
+                if str(sync_signal) == 'o' and str(data_channel) == str(ch):
+                    sync_status = True
+                    #tb.stop()
+                                               
+                if str(sync_signal) == 's' and str(data_channel) == str(ch): 
+                    sync_status = True
+                    data = 'o'
+                    pktno=0
+                    ack_payload = struct.pack('!HsH', pktno & 0xffff,data,ch & 0xffff) #+ data
+                    send_pkt(tb,ack_payload) #sending back the acknowledgement
+        ###################################################################
+            
+        ######################### traffic #################################
+        if mode == "traffic":
+            if ok: 
+                (data_header,) = struct.unpack('!s', payload[0])
+                if data_header == 'd':
+                    data_packet_delivery_count = data_packet_delivery_count +1
+                    comm = struct.unpack('!14s', payload[1:15])
+                    data = 'dI am fine.....' #Sending this message
+                    payload = struct.pack('!15s', data)
+                    send_pkt(tb,payload)
+                
+        ##############################################################
+
+        n_rcvd += 1
+        if ok:
+            n_right += 1
+
+    mods = modulation_utils.type_1_mods()
+    demods = modulation_utils.type_1_demods()
+
+    # Set default values for the CROSS shell location. These can be overridden
+    # via command-line parameters
+    crossShellHost = "localhost"
+    crossShellPort = "40000"
+
+    #setting up the tx options parser
+
+    parser_tx = OptionParser(option_class=eng_option, conflict_handler="resolve")
+    
+    parser_tx.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
+            default='gmsk',help="Select modulation from: %s [default=%%default]" 
+            % (', '.join(mods.keys()),))
+    parser_tx.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser_tx.add_option("-M", "--megabytes", type="eng_float", default=1.0,
+                      help="set megabytes to transmit [default=%default]")
+    parser_tx.add_option("","--discontinuous", action="store_true", default=False,
+                      help="enable discontinous transmission (bursts of 5 packets)") 
+    parser_tx.add_option("","--from-file", default=None,
+                          help="use file for packet contents")
+    parser_tx.add_option("-n", "--hostname", action="store", type="string", dest="crossShellHost",
+            default="localhost", help="Set the hostname/IP for the VTCROSS shell");
+    parser_tx.add_option("-p", "--port", action="store", type="string", dest="crossShellPort",
+            default="40000", help="Set the port for the VTCROSS shell");
+ 
+    expert_grp_tx = parser_tx.add_option_group("Expert_tx")
+    dsa_grp = parser_tx.add_option_group("DSA Options")
+    dsa_grp.add_option("-c", "--cross", action="store_true", default=False,
+            help="Use the CROSS CBR Cognitive Engine for DSA channel decisions [default=off (random selection)].")
+        
+    dsa_grp.add_option("-T", "--threshold", type="eng_float", default=1.5e8,
+                          help="set primary user sensing energy threshold [default=%default]")
+  
+
+    usrp_transmit_path.add_options(parser_tx, expert_grp_tx)
+    parser_tx.remove_option('-f');
+    parser_tx.remove_option('--tx-freq');
+
+    for mod in mods.values():
+        mod.add_options(expert_grp_tx)
+
+
+    (options_tx, args_tx) = parser_tx.parse_args ()
+
+    if len(args_tx) != 0:
+        parser_tx.print_help()
+        sys.exit(1)
+    
+    ############# Setting some default values for tx side of the block
+    options_tx.tx_freq = 462.5625e6
+    options_tx.samples_per_symbol =  2
+    options_tx.modulation = 'dbpsk'
+    options_tx.fusb_block_size = 4096
+    options_tx.fusb_nblocks = 16
+    options_tx.bitrate = 0.0125e6
+    #############
+
+    if options_tx.tx_freq is None:
+        sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
+        parser_tx.print_help(sys.stderr)
+        sys.exit(1)
+
+    parser_rx = OptionParser (option_class=eng_option, conflict_handler="resolve")
+    expert_grp_rx = parser_rx.add_option_group("Expert_rx")
+    usrp_receive_path.add_options(parser_rx, expert_grp_rx)
+    
+    parser_rx.remove_option('-f');
+        
+    parser_rx.add_option("-c", "--cross", action="store_true", default=False,
+            help="Use the CROSS engine for DSA decisions: default is random.")
+    parser_rx.add_option("-T", "--threshold", type="eng_float", default=1.5e8,
+                          help="set primary user sensing energy threshold [default=%default]")
+    parser_rx.add_option("-n", "--hostname", action="store", type="string", dest="crossShellHost",
+            default="localhost", help="Set the hostname/IP for the VTCROSS shell");
+    parser_rx.add_option("-p", "--port", action="store", type="string", dest="crossShellPort",
+            default="40000", help="Set the port for the VTCROSS shell");
+ 
+
+
+    (options_rx, args_rx) = parser_rx.parse_args ()
+
+    ############# Setting some default values for rx side of the block
+    options_rx.rx_freq = 462.5625e6 #setting default rx_freq value
+    options_rx.samples_per_symbol =  2
+    options_rx.modulation = 'dbpsk'
+    options_rx.fusb_block_size = 4096
+    options_rx.fusb_nblocks = 16
+    options_rx.bitrate = 0.0125e6
+    #############
+
+
+    if options_rx.cross == True:
+        if cross_import == False:
+            print "\n\n[[ CROSS Import failed..  Defaulting to RANDOM channel selection ]]"
+            print "[[ Using the RANDOM channel selection algorithm ]]\n\n"
+            options_rx.cross = False
+        else:
+            print "[[ Using the CROSS DSA Cognitive Engine ]]"
+            crossShellHost = options_rx.crossShellHost
+            crossShellPort = options_rx.crossShellPort
+            print "[[ VTCROSS shell located at " + crossShellHost + ":" + crossShellPort + " ]]"
+            SetCrossShellLocation(crossShellHost, crossShellPort)
+    else:
+        print "[[ Using the RANDOM channel selection algorithm ]]\n\n"
+        
+    # build the graph
+
+    tb = my_top_block(mods[options_tx.modulation],
+                      demods[options_rx.modulation],
+                      rx_callback,options_tx,
+                      options_rx)
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: failed to enable realtime scheduling"
+    
+    tb.start()
+
+    #listening to random frequencies untill a match is found
+    running = True
+    ch_energy = tb.rxpath.probe.level() #setting initial value
+    hop_freq = options_tx.tx_freq #  = options_rx.rx_freq...same for tx and rx side
+       
+    # Scan all channels first for inital data
+    #time.sleep(0.1)
+
+    print "\n[[ Scanning channels for network nodes ]]\n"
+    while running:
+        ################################################sync mode####################################
+        if mode == "sync":
+	    if sync_status != True:
+                    
+                if return_flag == 0:
+                    ch,hop_freq = get_freq(hop_freq,ch_energy,0,options_rx.cross)
+                else:
+                    ch,hop_freq = get_freq(hop_freq,ch_energy,elapsed_time,options_rx.cross)
+                    return_flag = 0
+
+
+		
+
+
+                tb.txpath.u.set_center_freq(hop_freq)
+                tb.rxpath.u.set_center_freq(hop_freq)
+              
+                ch_energy = tb.rxpath.probe.level() #check if primary user is present
+                
+                if int(ch_energy) > 1.5e8: #if primary user is there then dont transmit on this channel
+                    continue
+                
+                nbytes = 5 #int(1e6 * .0003)
+                pkt_size = 5
+                n = 0
+                pktno = 0
+                while n < nbytes:
+                    if options_tx.from_file is None:
+                        data = 's'
+                    else:
+                        data = source_file.read(pkt_size - 2)
+                        if data == '':
+                            break;
+
+                    payload = struct.pack('!HsH', pktno & 0xffff,data,ch & 0xffff) #+ data
+                            
+                    send_pkt(tb,payload)
+                    n += len(payload)
+                    sys.stderr.write('.')
+                    if options_tx.discontinuous and pktno % 5 == 4:
+                        time.sleep(1)
+                        pktno += 1
+                time.sleep(0.1)
+                    
+            else:
+                print "\n\n[[ Network Node Found: Commencing communications on CHANNEL ", ch, " ]]\n";
+                n_attempts_counter = 0
+                mode = "traffic"
+                data_packet_delivery_count = 0
+                sync_status="False"
+                start_time = datetime.now() #measuring the time for which the primary user is away
+    
+        ################################################end of sync mode####################################
+
+        ################################################Communications mode#################################
+        if mode == "traffic":
+            nbytes = 15
+            pkt_size = 15
+            data_pktno = 0
+            n = 0
+            while n < nbytes:
+                if options_tx.from_file is None:
+                    data = 'dHi how are you' #Sending this message
+                else:
+                    data = source_file.read(pkt_size - 2)
+                    if data == '':
+                        break;
+    
+            
+                payload = struct.pack('!15s', data)
+                                       
+                send_pkt(tb,payload)
+                n += len(payload)
+                sys.stderr.write('.')
+                if options_tx.discontinuous and data_pktno % 5 == 4:
+                    time.sleep(1)
+                data_pktno += 1
+                time.sleep(0.2 + 0.05*int(random.choice([0,1,2,3])))
+
+                if data_packet_delivery_count == data_packet_delivery_count_previous: #checking if the data packet delivery has stagnated
+                    n_attempts_counter += 1
+                    if n_attempts_counter > n_attempts: #get out of the data channel as it seems that the other node is still trying to rendezvous
+                        mode = "sync"
+                        continue
+		else:
+		    data_packet_delivery_count_previous = 0
+		    data_packet_delivery_count = 0
+
+		data_packet_delivery_count_previous = data_packet_delivery_count
+                ch_energy = tb.rxpath.probe.level() #check if primary user is present
+                if int(ch_energy) > 1.8e8: #if primary user is there then dont transmit on this channel
+                    stop_time = datetime.now()    
+                    _elapsed_time  = start_time - stop_time
+                    elapsed_time = _elapsed_time.seconds
+                    print "\n[[ Primary User Detected:  Evacuating Current Channel ]]\n"
+                    print "\n[[ Scanning channels for network nodes ]]\n"
+                    mode = "sync"
+                    return_flag = 1
+                
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_options.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_options.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_options.py	(revision 502)
@@ -0,0 +1,123 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+_parser_to_groups_dict = dict()
+class _parser_groups(object):
+    def __init__(self, parser):
+        self.usrpx_grp = parser.add_option_group("General USRP Options")
+        self.usrp1_grp = parser.add_option_group("USRP1 Specific Options")
+        self.usrp1exp_grp = parser.add_option_group("USRP1 Expert Options")
+        self.usrp2_grp = parser.add_option_group("USRP2 Specific Options")
+
+import generic_usrp
+
+def _add_options(parser):
+    """
+    Add options to manually choose between usrp or usrp2.
+    Add options for usb. Add options common to source and sink.
+    @param parser: instance of OptionParser
+    @return the parser group
+    """
+    #cache groups so they dont get added twice on tranceiver apps
+    if not _parser_to_groups_dict.has_key(parser): _parser_to_groups_dict[parser] = _parser_groups(parser)
+    pg = _parser_to_groups_dict[parser]
+    #pick usrp or usrp2
+    pg.usrpx_grp.add_option("-u", "--usrpx", type="string", default=None,
+                      help="specify which usrp model: 1 for USRP, 2 for USRP2 [default=auto]")
+    #fast usb options
+    pg.usrp1exp_grp.add_option("-B", "--fusb-block-size", type="int", default=0,
+                      help="specify fast usb block size [default=%default]")
+    pg.usrp1exp_grp.add_option("-N", "--fusb-nblocks", type="int", default=0,
+                      help="specify number of fast usb blocks [default=%default]")
+    #lo offset
+    pg.usrpx_grp.add_option("--lo-offset", type="eng_float", default=None,
+                      help="set LO Offset in Hz [default=automatic].")
+    #usrp options
+    pg.usrp1_grp.add_option("-w", "--which", type="int", default=0,
+                      help="select USRP board [default=%default]")
+    #usrp2 options
+    pg.usrp2_grp.add_option("-e", "--interface", type="string", default="eth0",
+                      help="Use USRP2 at specified Ethernet interface [default=%default]")
+    pg.usrp2_grp.add_option("-a", "--mac-addr", type="string", default="",
+                      help="Use USRP2 at specified MAC address [default=None]")
+    return pg
+
+def add_rx_options(parser):
+    """
+    Add receive specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.add_option("--rx-gain", type="eng_float", default=None, metavar="GAIN",
+                      help="set receiver gain in dB [default=midpoint].  See also --show-rx-gain-range")
+    pg.usrpx_grp.add_option("--show-rx-gain-range", action="store_true", default=False, 
+                      help="print min and max Rx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decimation rate to DECIM [default=%default]")
+
+def create_usrp_source(options):
+    u = generic_usrp.generic_usrp_source_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.rx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.rx_gain,
+    )
+    if options.show_rx_gain_range:
+        print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
+
+def add_tx_options(parser):
+    """
+    Add transmit specific usrp options.
+    @param parser: instance of OptionParser
+    """
+    pg = _add_options(parser)
+    pg.usrp1_grp.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    pg.usrpx_grp.add_option("--tx-gain", type="eng_float", default=None, metavar="GAIN",
+                      help="set transmitter gain in dB [default=midpoint].  See also --show-tx-gain-range")
+    pg.usrpx_grp.add_option("--show-tx-gain-range", action="store_true", default=False, 
+                      help="print min and max Tx gain available on selected daughterboard")
+    pg.usrpx_grp.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+
+def create_usrp_sink(options):
+    u = generic_usrp.generic_usrp_sink_c(
+        usrpx=options.usrpx,
+        which=options.which,
+        subdev_spec=options.tx_subdev_spec,
+        interface=options.interface,
+        mac_addr=options.mac_addr,
+        fusb_block_size=options.fusb_block_size,
+        fusb_nblocks=options.fusb_nblocks,
+        lo_offset=options.lo_offset,
+        gain=options.tx_gain,
+    )
+    if options.show_tx_gain_range:
+        print "Tx Gain Range: minimum = %g, maximum = %g, step size = %g"%tuple(u.gain_range())
+    return u
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/generic_usrp.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/generic_usrp.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/generic_usrp.py	(revision 502)
@@ -0,0 +1,239 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+USRP1_TYPE = 'usrp1'
+USRP2_TYPE = 'usrp2'
+DUMMY_TYPE = 'dummy'
+#usrp2 rates common for decim and interp
+_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
+#dummy common rates
+_DUMMY_XRATES = range(4, 512, 2)
+_DUMMY_CONVERTER_RATE = 100e6
+#dummy freq result
+class _dummy_freq_result(object):
+    def __init__(self, target_freq):
+        self.baseband_freq = target_freq
+        self.dxc_freq = 0
+        self.residual_freq = 0
+from gnuradio import gr, usrp, usrp2
+
+########################################################################
+# generic usrp common stuff
+########################################################################
+class _generic_usrp_base(object):
+
+    def __init__(self, which=0, subdev_spec=None, interface="", mac_addr="",
+        fusb_block_size=0, fusb_nblocks=0, usrpx=None, lo_offset=None, gain=None):
+        self._lo_offset = lo_offset
+        #usrp options
+        self._which = which
+        self._subdev_spec = subdev_spec
+        #usrp2 options
+        self._interface = interface
+        self._mac_addr = mac_addr
+        #fusb options
+        self._fusb_block_size = fusb_block_size
+        self._fusb_nblocks = fusb_nblocks
+        #pick which usrp model
+        if usrpx == '0': self._setup_usrpx(DUMMY_TYPE)
+        elif usrpx == '1' or self._subdev_spec: self._setup_usrpx(USRP1_TYPE)
+        elif usrpx == '2' or self._mac_addr: self._setup_usrpx(USRP2_TYPE)
+        else: #automatic
+            try: self._setup_usrpx(USRP2_TYPE)
+            except:
+                try: self._setup_usrpx(USRP1_TYPE)
+                except: raise Exception, 'Failed to automatically setup a usrp device.'
+        #post usrp setup
+        if self._lo_offset is not None:
+            self.set_lo_offset(self._lo_offset)
+        self.set_gain(gain)
+        self.set_auto_tr(True)
+
+    def _setup_usrpx(self, type):
+        """
+        Call the appropriate setup method.
+        @param type the usrp type constant
+        """
+        self._type = type
+        if self._type == USRP1_TYPE: self._setup_usrp1()
+        elif self._type == USRP2_TYPE: self._setup_usrp2()
+        elif self._type == DUMMY_TYPE: self._setup_dummy()
+
+    def __str__(self):
+        if self._type == USRP1_TYPE: return self._subdev.side_and_name()
+        elif self._type == USRP2_TYPE:
+            return 'Interface: %s    MAC Address: %s    D-Board ID: 0x%.2x'%(
+                self._u.interface_name(), self._u.mac_addr(), self._u.daughterboard_id())
+        elif self._type == DUMMY_TYPE: return 'Dummy USRP Device'
+
+    def gain(self): return self._gain
+
+    def set_gain(self, gain=None):
+        #automatic gain calculation
+        r = self.gain_range()
+        if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
+        #set gain for usrp
+        self._gain = gain
+        if self._type == USRP1_TYPE: return self._subdev.set_gain(gain)
+        elif self._type == USRP2_TYPE: return self._u.set_gain(gain)
+        elif self._type == DUMMY_TYPE: return True
+
+    def gain_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.gain_range()
+        elif self._type == USRP2_TYPE: return self._u.gain_range()
+        elif self._type == DUMMY_TYPE: return (0, 0, 0)
+
+    def set_center_freq(self, target_freq):
+        if self._type == USRP1_TYPE:
+            return self._u.tune(self._dxc, self._subdev, target_freq)
+        elif self._type == USRP2_TYPE:
+            return self._u.set_center_freq(target_freq)
+        elif self._type == DUMMY_TYPE: return _dummy_freq_result(target_freq)
+
+    def freq_range(self):
+        if self._type == USRP1_TYPE: return self._subdev.freq_range()
+        elif self._type == USRP2_TYPE: return self._u.freq_range()
+        elif self._type == DUMMY_TYPE: return (-10e9, 10e9, 100e3)
+
+    def set_lo_offset(self, lo_offset):
+        if self._type == USRP1_TYPE: return self._subdev.set_lo_offset(lo_offset)
+        elif self._type == USRP2_TYPE: return self._u.set_lo_offset(lo_offset)
+        elif self._type == DUMMY_TYPE: return True
+
+    def set_auto_tr(self, enable):
+        if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
+
+    def __del__(self):
+        try: # Avoid weak reference error
+            del self._u
+            del self._subdev
+        except: pass
+
+########################################################################
+# generic usrp source
+########################################################################
+class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp source that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_source",
+            gr.io_signature(0, 0, 0), # Input signature
+            gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        self.connect(self._u, self)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_decim(self, decim):
+        if decim not in self.get_decim_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
+        elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_decim_rates(self):
+        if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def adc_rate(self):
+        if self._type == USRP1_TYPE: return self._u.adc_rate()
+        if self._type == USRP2_TYPE: return self._u.adc_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        self._u = usrp.source_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
+        self._dxc = 0
+
+    def _setup_usrp2(self):
+        self._u = usrp2.source_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
+
+########################################################################
+# generic usrp sink
+########################################################################
+class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
+    """
+    Create a generic usrp sink that represents usrp and usrp2.
+    Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
+    Provide generic access methods so the API looks the same for both.
+    """
+
+    def __init__(self, **kwargs):
+        gr.hier_block2.__init__(self, "generic_usrp_sink",
+            gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+            gr.io_signature(0, 0, 0)) # Output signature
+        _generic_usrp_base.__init__(self, **kwargs)
+        if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
+            self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
+        else: self.connect(self, self._u)
+
+    ####################################################################
+    # generic access methods
+    ####################################################################
+    def set_interp(self, interp):
+        if interp not in self.get_interp_rates(): return False
+        if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
+        elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
+        elif self._type == DUMMY_TYPE: return True
+
+    def get_interp_rates(self):
+        if self._type == USRP1_TYPE: return range(16, 512+1, 4)
+        if self._type == USRP2_TYPE: return _USRP2_RATES
+        elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
+
+    def dac_rate(self):
+        if self._type == USRP1_TYPE: return self._u.dac_rate()
+        if self._type == USRP2_TYPE: return self._u.dac_rate()
+        elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
+
+    ####################################################################
+    # setup usrp methods
+    ####################################################################
+    def _setup_usrp1(self):
+        self._u = usrp.sink_c (self._which,
+                                fusb_block_size=self._fusb_block_size,
+                                fusb_nblocks=self._fusb_nblocks)
+        # determine the daughterboard subdevice we're using
+        if self._subdev_spec is None:
+            self._subdev_spec = usrp.pick_tx_subdevice(self._u)
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
+        self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
+        self._dxc = self._subdev.which()
+
+    def _setup_usrp2(self): self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
+
+    def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/README
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/README	(revision 528)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/README	(revision 528)
@@ -0,0 +1,64 @@
+benchmark_dsa.py - GNU radio Dynamic Spectrum Access example script
+
+Summary:
+This script implements a extremely simple DSA algorithm and 
+rendezvous protocol.  When two nodes are running this script, they
+will dynamically change frequencies  until they rendezvous and begin
+communication.  
+
+Operation:
+In order to run this script several GNUradio utilities scripts must be
+located in the same directory as the benchmark_dsa.py script.  The 
+easiest way to do this is to copy benchmark_dsa.py into the following
+GNUradio source directory:
+
+<gnuradio_top_srcdir>/gnuradio-examples/python/digital/
+
+
+General Information:
+The purpose of this script is to demonstrate simple dynamic spectrum
+access.  In our case we do a simple probe using the gr.probe_avg_mag_sqrd_cf
+component to get a ROUGH estimate of the energy.  An energy threshold is
+used to determine if another signal is present in the channel.  This
+threshold can be set from the command line using the --threshold arg.
+By default it is set to 1.5e8.  We calibrated this using the following:
+
+USRP1
+RFX400 USRP daughterboard
+Standard 2-way FRS radios
+
+The threshold should be set accord to your specific environment and will
+most likely be different for everyone.
+
+If a primary user is detected, the script will change channels to avoid 
+causing interference.  The channel selection is the fun part.  By default
+the script simply picks a random channel from the STATICLY available 
+channel list that we've hardcoded in.  Also available is intgration into
+our open source cognitive engine system which uses a case-based reasoning
+system to select a channel based on previous environments.  
+
+For example, the CROSS system, when requested, will query it's database
+and observe that channel A has previously seen a primary user, in this
+case the probability that channel A is selected as the next channel to
+hop is will be small compared to other channels that have seen seen primary
+users.  To use the CROSS system, CROSS must be built and installed 
+(https://cornet.wireless.vt.edu/trac/wiki/Cross/BuildGuide) and you must
+supply the --cross argument.  DSA algorithms are ongoing research items
+at many institutions and this is just a VERY SIMPLE implementation to get
+others started.
+
+Also worth noting is the rendezvous method.  To get the full functionality
+two of these nodes must be running. Each node decides on it's own which
+channel to move to next if scanning for other nodes or if a primary
+user is detected.  At each channel hop, a beacon is transmitted.  This 
+beacon is used by other nodes in the channel to identify each other. 
+If a beacon is seen on a channel, an ACK beacon is sent and both nodes
+settle on the current channel and begin communication.  
+
+Again this is still a work in progress but hopefully others can gain 
+some insight into spectrum sensing and DSA using GNUradio, the USRP, or
+the Virginia Tech Cognitive Radio Open Source System.
+
+For questions or comments related to CROSS, please get in touch with us!
+http://www.cornet.wireless.vt.edu/trac/wiki/Cross/Contact
+
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_transmit_path.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_transmit_path.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_transmit_path.py	(revision 502)
@@ -0,0 +1,90 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr
+import usrp_options
+import transmit_path
+from pick_bitrate import pick_tx_bitrate
+from gnuradio import eng_notation
+
+def add_freq_option(parser):
+    """
+    Hackery that has the -f / --freq option set both tx_freq and rx_freq
+    """
+    def freq_callback(option, opt_str, value, parser):
+        parser.values.rx_freq = value
+        parser.values.tx_freq = value
+
+    if not parser.has_option('--freq'):
+        parser.add_option('-f', '--freq', type="eng_float",
+                          action="callback", callback=freq_callback,
+                          help="set Tx and/or Rx frequency to FREQ [default=%default]",
+                          metavar="FREQ")
+
+def add_options(parser, expert):
+    add_freq_option(parser)
+    usrp_options.add_tx_options(parser)
+    transmit_path.transmit_path.add_options(parser, expert)
+    expert.add_option("", "--tx-freq", type="eng_float", default=None,
+                          help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_transmit_path(gr.hier_block2):
+    def __init__(self, modulator_class, options):
+        '''
+        See below for what options should hold
+        '''
+        gr.hier_block2.__init__(self, "usrp_transmit_path",
+                gr.io_signature(0, 0, 0),                    # Input signature
+                gr.io_signature(0, 0, 0)) # Output signature
+        if options.tx_freq is None:
+            sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
+            raise SystemExit
+        tx_path = transmit_path.transmit_path(modulator_class, options)
+        for attr in dir(tx_path): #forward the methods
+            if not attr.startswith('_') and not hasattr(self, attr):
+                setattr(self, attr, getattr(tx_path, attr))
+        #setup usrp
+        self._modulator_class = modulator_class
+        self._setup_usrp_sink(options)
+        #connect
+        self.connect(tx_path, self.u)
+
+    def _setup_usrp_sink(self, options):
+        """
+        Creates a USRP sink, determines the settings for best bitrate,
+        and attaches to the transmitter's subdevice.
+        """
+        self.u = usrp_options.create_usrp_sink(options)
+        dac_rate = self.u.dac_rate()
+        if options.verbose:
+            print 'USRP Sink:', self.u
+        (self._bitrate, self._samples_per_symbol, self._interp) = \
+                        pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), \
+                                        options.samples_per_symbol, options.interp, dac_rate, \
+                                        self.u.get_interp_rates())
+
+        self.u.set_interp(self._interp)
+        self.u.set_auto_tr(True)
+
+        if not self.u.set_center_freq(options.tx_freq):
+            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq))
+            raise ValueError, eng_notation.num_to_str(options.tx_freq)
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_receive_path.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_receive_path.py	(revision 502)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/gnuradio-examples/usrp_receive_path.py	(revision 502)
@@ -0,0 +1,86 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr
+import usrp_options
+import receive_path
+from pick_bitrate import pick_rx_bitrate
+from gnuradio import eng_notation
+
+def add_freq_option(parser):
+    """
+    Hackery that has the -f / --freq option set both tx_freq and rx_freq
+    """
+    def freq_callback(option, opt_str, value, parser):
+        parser.values.rx_freq = value
+        parser.values.tx_freq = value
+
+    if not parser.has_option('--freq'):
+        parser.add_option('-f', '--freq', type="eng_float",
+                          action="callback", callback=freq_callback,
+                          help="set Tx and/or Rx frequency to FREQ [default=%default]",
+                          metavar="FREQ")
+
+def add_options(parser, expert):
+    add_freq_option(parser)
+    usrp_options.add_rx_options(parser)
+    receive_path.receive_path.add_options(parser, expert)
+    expert.add_option("", "--rx-freq", type="eng_float", default=None,
+                          help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_receive_path(gr.hier_block2):
+
+    def __init__(self, demod_class, rx_callback, options):
+        '''
+        See below for what options should hold
+        '''
+        gr.hier_block2.__init__(self, "usrp_receive_path",
+                gr.io_signature(0, 0, 0),                    # Input signature
+                gr.io_signature(0, 0, 0)) # Output signature
+        if options.rx_freq is None:
+            sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
+            raise SystemExit
+        rx_path = receive_path.receive_path(demod_class, rx_callback, options)
+        for attr in dir(rx_path): #forward the methods
+            if not attr.startswith('_') and not hasattr(self, attr):
+                setattr(self, attr, getattr(rx_path, attr))
+        #setup usrp
+        self._demod_class = demod_class
+        self._setup_usrp_source(options)
+        #connect
+        self.connect(self.u, rx_path)
+
+    def _setup_usrp_source(self, options):
+        self.u = usrp_options.create_usrp_source(options)
+        adc_rate = self.u.adc_rate()
+        if options.verbose:
+            print 'USRP Source:', self.u
+        (self._bitrate, self._samples_per_symbol, self._decim) = \
+                        pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
+                                        options.samples_per_symbol, options.decim, adc_rate,  \
+                                        self.u.get_decim_rates())
+
+        self.u.set_decim(self._decim)
+
+        if not self.u.set_center_freq(options.rx_freq):
+            print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq))
+            raise ValueError, eng_notation.num_to_str(options.rx_freq)
Index: vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/libcross_demo.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/libcross_demo.py	(revision 416)
+++ vtcross/branches/nikhil/crossmodel2/src/cross-examples/python/libcross_demo.py	(revision 416)
@@ -0,0 +1,41 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+# Simple Python demonstration script for using
+# the CROSS system.
+#
+# Use with demo.xml shell configuration file
+#   Instructions:
+# 	Start shell with demo.xml config from the examples directory
+#	Start cognitive engine
+#	Run this script
+#	
+
+from cross import *
+
+p = Parameter(1)
+currentParameters = Parameter(1)
+o = Observable(1)
+
+o[0].value = 15.00
+o[0].name = "energy"
+
+currentParameters[0].name = "channel"
+currentParameters[0].value = 3 
+
+p = GetOptimalParameters(o,1,currentParameters,1);
+
+print p[0].name, p[0].value
+
+
Index: vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/socketcomm.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/socketcomm.cpp	(revision 498)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/socketcomm.cpp	(revision 498)
@@ -0,0 +1,266 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/* TODO DESCRIPTION OF FILE.
+ */
+
+
+#include <arpa/inet.h>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <string>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+
+// TODO can someone write a description of how this function is operating? I'm
+// not sure I understand why it is making two separate blocking calls to recv
+//
+// TODO also, it appears that this function can, at maximum, receive 256 bytes
+// without causing a buffer overflow. can someone confirm/deny?
+int32_t
+ReadMessage(int32_t socketFD, char* msgBuffer)
+{
+
+    // Peek at the buffer to get real message length.
+    // Messages are termination with a "\0" to denote EOM.
+    ssize_t msgLength = recv(socketFD, msgBuffer, 256, MSG_PEEK);
+    if(msgLength <= 0) {
+        //ERROR(1, "Remote component closed connection. 1\n");
+        //LOG("Client closed connection.\n");
+	return -1;
+    }
+    size_t i;
+    for(i = 0; i < 256; i++) {
+        if(strcmp(&msgBuffer[i], "\0") == 0)
+            break;
+    }
+
+    // Read the message into msgBuffer
+    msgLength = recv(socketFD, msgBuffer, i + 1, 0);
+    if(msgLength <= 0) {
+        //ERROR(1, "Remote component closed connection. 1\n");
+        //LOG("Client closed connection.\n");
+	return -1;
+    }
+
+    return 1;
+}
+
+
+int32_t 
+ClientSocket(const char* serverName, const char* serverPort)
+{
+    int32_t socketFD;
+    int32_t portNumber;
+
+    struct sockaddr_in serv_addr;
+    struct hostent *server;
+    
+    server = gethostbyname(serverName);
+    if(server == NULL)
+        ERROR(1, "SocketComm::ClientSocket - No server found by that hostname.\n");
+
+    portNumber = atoi(serverPort);
+
+    socketFD = socket(AF_INET, SOCK_STREAM, 0);
+    if(socketFD < 0) 
+        ERROR(1, "SocketComm::ClientSocket - Error opening socket\n");
+
+    memset((void *) &serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_port = htons(portNumber);
+    memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, \
+            server->h_length);
+
+    if(connect(socketFD, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
+        ERROR(1, "SocketComm::ClientSocket - Error connecting to remote socket.\n");
+
+    return socketFD;
+}
+
+    
+// TODO this function is here to handle calls to send const char* messages. Note
+// that the std::string.c_str() function auto-appends a null character at the
+// end of the cstring, so the strcat function call in the previous function
+// isn't necessary here... I think... although I still don't really understand
+// what exactly that call is for.
+int32_t
+SendMessage(int32_t socketFD, const char* message) 
+{
+    ssize_t numSentBytes = send(socketFD, message, (strlen(message) + 1), 0);
+    if(numSentBytes < 0) {
+        ERROR(1, "Error sending to server %i (%i): %s\n",socketFD, numSentBytes, message);
+    }
+    else if(numSentBytes == 0) {
+        LOG("socket_comm::SendMessage - Server closed the socket.\n");
+    }
+   
+    return numSentBytes;
+}
+
+
+// TODO This function is currently returning 1... always... is this necessary?
+// If we want a fail/success return type, then why aren't we ever returning a
+// failure?
+int32_t 
+GetParameter(int32_t socketFD, struct Parameter pList[], \
+        struct Radio_Info *radio_info)
+{
+    char buffer[256];
+    memset(buffer, 0, 256);
+
+    ReadMessage(socketFD, buffer);
+    radio_info->numParameters = atoi(buffer);
+    LOG("socket_comm::GetParameter - Number of parameters: %d\n", \
+            radio_info->numParameters);
+    
+    for(size_t i = 0; i < radio_info->numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Name: %s\n", buffer);
+        pList[i].name = std::string(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Units: %s\n", buffer);
+        pList[i].units = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Min: %s\n", buffer);
+        pList[i].min = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Max: %s\n", buffer);
+        pList[i].max = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Step: %s\n", buffer);
+        pList[i].step = atof(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        LOG("socket_comm::GetParameter - Value: %s\n", buffer);
+        pList[i].value = atof(buffer);
+    }
+
+    return 1;
+}
+
+
+// TODO if we are just returing fail/success here, then why not return a bool
+// instead of an entire 32 bit integer?  Seems wasteful.
+int32_t 
+GetRequest(int32_t socketFD, struct Parameter pList[], struct Radio_Info *radio_info)
+{
+    char buffer[256];
+    memset(buffer, 0, 256);
+   
+    ReadMessage(socketFD, buffer);
+
+    if(strcmp(buffer, "val") != 0) {
+        LOG("socket_comm::GetRequest - Unexpected control data received.\n\n");
+        return 0;
+    }
+
+    LOG("socket_comm::GetRequest - Getting parameters.\n\n");
+    GetParameter(socketFD, pList, radio_info);
+
+    return 1;
+}
+
+
+int32_t 
+AcceptTCPConnection(int32_t serverSock)
+{
+    struct sockaddr_in echoClientAddr;
+
+    uint32_t clientLength = sizeof(echoClientAddr);
+
+    int32_t clientSocket = accept(serverSock, NULL, NULL);
+    if(clientSocket < 0) { 
+        //WARNING("ALERT: Could not establish connection with client socket.\n");
+        return clientSocket;
+    }
+    //LOG("Handling client %s\n", inet_ntoa(echoClientAddr.sin_addr));
+
+    return clientSocket;
+}
+
+
+int32_t 
+CreateTCPServerSocket(uint16_t port)
+{
+    struct sockaddr_in echoServerAddr;
+
+    int32_t localSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (localSocket < 0)
+        ERROR(1, "socket() failed\n");
+      
+    /* Construct the local address structure */
+    memset(&echoServerAddr, 0, sizeof(echoServerAddr));
+    echoServerAddr.sin_family = AF_INET;
+    echoServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    echoServerAddr.sin_port = htons(port);
+
+    /* Bind to the local address */
+    if(bind(localSocket, (struct sockaddr *) &echoServerAddr, \
+            sizeof(echoServerAddr)) < 0)
+        ERROR(1, "bind() failed\n");
+
+    /* Mark the socket so it will listen for incoming connections */
+    if(listen(localSocket, 5) < 0)
+        ERROR(1, "listen() failed\n");
+
+    return localSocket;
+}
+
+int32_t
+InitializeTCPServerPort(int32_t servSock)
+{
+    int32_t rc, on = 1;
+
+    rc = setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
+    if(rc < 0) {
+        shutdown(servSock, 2);
+        close(servSock);
+        ERROR(1,"setsockopt() failed\n");
+    }
+
+    rc = ioctl(servSock, FIONBIO, (char*)&on);
+    if(rc < 0) {
+        shutdown(servSock, 2);
+        close(servSock);
+        ERROR(1,"ioctl() failed\n");
+    }
+
+    return 1;
+}
Index: vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/socketcomm/Makefile.am	(revision 411)
@@ -0,0 +1,20 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+lib_LTLIBRARIES = libsocketcomm.la
+libsocketcomm_la_SOURCES = socketcomm.cpp
Index: vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlerror.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlerror.cpp	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlerror.cpp	(revision 161)
@@ -0,0 +1,53 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
+};
Index: vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlparser.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlparser.cpp	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxmlparser.cpp	(revision 161)
@@ -0,0 +1,1638 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include <ctype.h>
+#include <stddef.h>
+
+#include "tinyxml.h"
+
+//#define DEBUG_PARSER
+#if defined( DEBUG_PARSER )
+#	if defined( DEBUG ) && defined( _MSC_VER )
+#		include <windows.h>
+#		define TIXML_LOG OutputDebugString
+#	else
+#		define TIXML_LOG printf
+#	endif
+#endif
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor()	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
+// "assign" optimization removes over 10% of the execution time.
+//
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	// Oddly, not supported on some comilers,
+	//name->clear();
+	// So use this:
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		const char* start = p;
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			//(*name) += *p; // expensive
+			++p;
+		}
+		if ( p-start > 0 ) {
+			name->assign( start, p-start );
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
+					// Just writes strange XML.
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	if ( p ) 
+		p += strlen( endTag );
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		cdata text (which looks like another node)
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				// Early out if we find the CDATA id.
+				if ( c == '[' && tag->size() >= 9 )
+				{
+					size_t len = tag->size();
+					const char* start = tag->c_str() + len - 9;
+					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
+						assert( !closingTag );
+						break;
+					}
+				}
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+	endTag += ">";
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p ) {
+				// We were looking for the end tag, but found nothing.
+				// Fix for [ 1663758 ] Failure to report error on bad XML
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			#ifdef TIXML_USE_STL
+			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
+			#else
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			#endif
+			if ( node )
+			{
+				node->SetValue( attrib->Value() );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+				    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+
+	// [ 1475201 ] TinyXML parses entities in comments
+	// Oops - ReadText doesn't work, because we don't want to parse the entities.
+	// p = ReadText( p, &value, false, endTag, false, encoding );
+	//
+	// from the XML spec:
+	/*
+	 [Definition: Comments may appear anywhere in a document outside other markup; in addition, 
+	              they may appear within the document type declaration at places allowed by the grammar. 
+				  They are not part of the document's character data; an XML processor MAY, but need not, 
+				  make it possible for an application to retrieve the text of comments. For compatibility, 
+				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity 
+				  references MUST NOT be recognized within comments.
+
+				  An example of a comment:
+
+				  <!-- declarations for <head> & <body> -->
+	*/
+
+    value = "";
+	// Keep all the white space.
+	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
+	{
+		value.append( p, 1 );
+		++p;
+	}
+	if ( p ) 
+		p += strlen( endTag );
+
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+//	int tabsize = 4;
+//	if ( document )
+//		tabsize = document->TabSize();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+	const char SINGLE_QUOTE = '\'';
+	const char DOUBLE_QUOTE = '\"';
+
+	if ( *p == SINGLE_QUOTE )
+	{
+		++p;
+		end = "\'";		// single quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == DOUBLE_QUOTE )
+	{
+		++p;
+		end = "\"";		// double quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p											// existence
+				&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )							// tag end
+		{
+			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
+				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
+				// We did not have an opening quote but seem to have a 
+				// closing one. Give up and throw an error.
+				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+				return 0;
+			}
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();	
+		if ( !cdata && (c == '<' ) ) 
+		{
+			return;
+		}
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+		in->get();	// "commits" the peek made above
+
+		if ( cdata && c == '>' && tag->size() >= 3 ) {
+			size_t len = tag->size();
+			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
+				// terminator of cdata.
+				return;
+			}
+		}    
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxml.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxml.cpp	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinyxml.cpp	(revision 161)
@@ -0,0 +1,1888 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#include <iostream>
+#endif
+
+#include "tinyxml.h"
+
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+// Microsoft compiler security
+FILE* TiXmlFOpen( const char* filename, const char* mode )
+{
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		FILE* fp = 0;
+		errno_t err = fopen_s( &fp, filename, mode );
+		if ( !err && fp )
+			return fp;
+		return 0;
+	#else
+		return fopen( filename, mode );
+	#endif
+}
+
+void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
+	if ( node->Type() == TiXmlNode::DOCUMENT )
+	{
+		delete node;
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( replaceThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
+	#else
+	TiXmlAttribute* node = attributeSet.Find( name );
+	#endif
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char* TiXmlElement::Attribute( const char* name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return node->Value();
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return &node->ValueStr();
+	return 0;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, int* i ) const
+{
+	const char* s = Attribute( name );
+	if ( i )
+	{
+		if ( s ) {
+			*i = atoi( s );
+		}
+		else {
+			*i = 0;
+		}
+	}
+	return s;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const std::string* s = Attribute( name );
+	if ( i )
+	{
+		if ( s ) {
+			*i = atoi( s->c_str() );
+		}
+		else {
+			*i = 0;
+		}
+	}
+	return s;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, double* d ) const
+{
+	const char* s = Attribute( name );
+	if ( d )
+	{
+		if ( s ) {
+			*d = atof( s );
+		}
+		else {
+			*d = 0;
+		}
+	}
+	return s;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
+{
+	const std::string* s = Attribute( name );
+	if ( d )
+	{
+		if ( s ) {
+			*d = atof( s->c_str() );
+		}
+		else {
+			*d = 0;
+		}
+	}
+	return s;
+}
+#endif
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryIntValue( ival );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryIntValue( ival );
+}
+#endif
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryDoubleValue( dval );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryDoubleValue( dval );
+}
+#endif
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	char buf[64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
+	#else
+		sprintf( buf, "%d", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+   std::ostringstream oss;
+   oss << val;
+   SetAttribute( name, oss.str() );
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	char buf[256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
+	#else
+		sprintf( buf, "%f", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING _name( cname );
+	TIXML_STRING _value( cvalue );
+	#else
+	const char* _name = cname;
+	const char* _value = cvalue;
+	#endif
+
+	TiXmlAttribute* node = attributeSet.Find( _name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+#endif
+
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	assert( cfile );
+	for ( i=0; i<depth; i++ ) {
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	// See STL_STRING_BUG below.
+	//StringToBuffer buf( value );
+
+	return LoadFile( Value(), encoding );
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	// See STL_STRING_BUG below.
+//	StringToBuffer buf( value );
+//
+//	if ( buf.buffer && SaveFile( buf.buffer ) )
+//		return true;
+//
+//	return false;
+	return SaveFile( Value() );
+}
+
+bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
+{
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// Add an extra string to avoid the crash.
+	TIXML_STRING filename( _filename );
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = TiXmlFOpen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		bool result = LoadFile( file, encoding );
+		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
+
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file ) 
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length <= 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// If we have a file, assume it is all one big XML file, and read it in.
+	// The document parser may decide the document ends sooner than the entire file, however.
+	TIXML_STRING data;
+	data.reserve( length );
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external 
+	// parsed entities (including the document entity) on input, before parsing, by translating 
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		delete [] buf;
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	const char* lastPos = buf;
+	const char* p = buf;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		if ( *p == 0xa ) {
+			// Newline character. No special rules for this. Append all the characters
+			// since the last string, and include the newline.
+			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
+			++p;									// move past the newline
+			lastPos = p;							// and point to the new buffer (may be 0)
+			assert( p <= (buf+length) );
+		}
+		else if ( *p == 0xd ) {
+			// Carriage return. Append what we have so far, then
+			// handle moving forward in the buffer.
+			if ( (p-lastPos) > 0 ) {
+				data.append( lastPos, p-lastPos );	// do not add the CR
+			}
+			data += (char)0xa;						// a proper newline
+
+			if ( *(p+1) == 0xa ) {
+				// Carriage return - new line sequence
+				p += 2;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+			else {
+				// it was followed by something else...that is presumably characters again.
+				++p;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+		}
+		else {
+			++p;
+		}
+	}
+	// Handle any left over characters.
+	if ( p-lastPos ) {
+		data.append( lastPos, p-lastPos );
+	}		
+	delete [] buf;
+	buf = 0;
+
+	Parse( data.c_str(), 0, encoding );
+
+	if (  Error() )
+        return false;
+    else
+		return true;
+}
+
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = TiXmlFOpen( filename, "w" );
+	if ( fp )
+	{
+		bool result = SaveFile( fp );
+		fclose( fp );
+		return result;
+	}
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM ) 
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return (ferror(fp) == 0);
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorId = errorId;
+	target->errorDesc = errorDesc;
+	target->tabsize = tabsize;
+	target->errorLocation = errorLocation;
+	target->useMicrosoftBOM = useMicrosoftBOM;
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+
+bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+*/
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+*/
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	TIXML_STRING n, v;
+
+	EncodeString( name, &n );
+	EncodeString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos) {
+		if ( cfile ) {
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
+		}
+	}
+	else {
+		if ( cfile ) {
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
+		}
+	}
+}
+
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
+	#else
+		sprintf (buf, "%lf", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( int i=0; i<depth; i++ )
+	{
+		fprintf( cfile,  "    " );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		EncodeString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml " );
+	if ( str )	 (*str) += "<?xml ";
+
+	if ( !version.empty() ) {
+		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
+		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
+	}
+	if ( !encoding.empty() ) {
+		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
+	}
+	if ( !standalone.empty() ) {
+		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf( cfile, "?>" );
+	if ( str )	 (*str) += "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+    #ifdef TIXML_USE_STL
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
+	#else
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	#endif
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+
+#ifdef TIXML_USE_STL
+const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
+{
+	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+/*
+TiXmlAttribute*	TiXmlAttributeSet::Find( const std::string& name )
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+*/
+#endif
+
+
+const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
+{
+	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+/*
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char* name )
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+*/
+
+#ifdef TIXML_USE_STL	
+std::istream& operator>> (std::istream & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+#ifdef TIXML_USE_STL	
+std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out << printer.Str();
+
+	return out;
+}
+
+
+std::string& operator<< (std::string& out, const TiXmlNode& base )
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out.append( printer.Str() );
+
+	return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += element.Value();
+
+	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
+	{
+		buffer += " ";
+		attrib->Print( 0, 0, &buffer );
+	}
+
+	if ( !element.FirstChild() ) 
+	{
+		buffer += " />";
+		DoLineBreak();
+	}
+	else 
+	{
+		buffer += ">";
+		if (    element.FirstChild()->ToText()
+			  && element.LastChild() == element.FirstChild()
+			  && element.FirstChild()->ToText()->CDATA() == false )
+		{
+			simpleTextPrint = true;
+			// no DoLineBreak()!
+		}
+		else
+		{
+			DoLineBreak();
+		}
+	}
+	++depth;	
+	return true;
+}
+
+
+bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
+{
+	--depth;
+	if ( !element.FirstChild() ) 
+	{
+		// nothing.
+	}
+	else 
+	{
+		if ( simpleTextPrint )
+		{
+			simpleTextPrint = false;
+		}
+		else
+		{
+			DoIndent();
+		}
+		buffer += "</";
+		buffer += element.Value();
+		buffer += ">";
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlText& text )
+{
+	if ( text.CDATA() )
+	{
+		DoIndent();
+		buffer += "<![CDATA[";
+		buffer += text.Value();
+		buffer += "]]>";
+		DoLineBreak();
+	}
+	else if ( simpleTextPrint )
+	{
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+	}
+	else
+	{
+		DoIndent();
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
+{
+	DoIndent();
+	declaration.Print( 0, 0, &buffer );
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlComment& comment )
+{
+	DoIndent();
+	buffer += "<!--";
+	buffer += comment.Value();
+	buffer += "-->";
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += unknown.Value();
+	buffer += ">";
+	DoLineBreak();
+	return true;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/Makefile.am	(revision 411)
@@ -0,0 +1,21 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include/tinyxml
+
+noinst_LIBRARIES = libtinyxml.a
+libtinyxml_a_SOURCES = tinystr.cpp tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp
Index: vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinystr.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinystr.cpp	(revision 161)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/tinyxml/tinystr.cpp	(revision 161)
@@ -0,0 +1,116 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
+
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
Index: vtcross/branches/nikhil/crossmodel2/src/lib/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/lib/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/lib/Makefile.am	(revision 411)
@@ -0,0 +1,17 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = socketcomm tinyxml
Index: vtcross/branches/nikhil/crossmodel2/src/policy_engines/policy_demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/policy_engines/policy_demo.cpp	(revision 465)
+++ vtcross/branches/nikhil/crossmodel2/src/policy_engines/policy_demo.cpp	(revision 465)
@@ -0,0 +1,52 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/* TODO DESCRIPTION OF FILE.
+ *
+ * This file is a temporary demo of a policy engine using some of our socket
+ * communication functions. This is *not* an actual implementation of our
+ * defined PolicyEngine class.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/policy_engine.h"
+#include "vtcross/socketcomm.h"
+
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    if(argc < 3)
+       ERROR(1, "Usage: %s hostname port\n", argv[0]);
+    
+    PolicyEngine policyEngine(argv[1], argv[2], false);
+
+    LOG("Waiting for signal...\n");
+    while(1) {
+//        policyEngine.WaitForSignal();
+    }
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/policy_engines/PolicyEngine.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/policy_engines/PolicyEngine.cpp	(revision 521)
+++ vtcross/branches/nikhil/crossmodel2/src/policy_engines/PolicyEngine.cpp	(revision 521)
@@ -0,0 +1,306 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This is a reference implementation for the CROSS Policy Engine.
+ *
+ * Note that this implementation is NOT complete.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/policy_engine.h"
+#include "vtcross/socketcomm.h"
+
+
+PolicyEngine::PolicyEngine()
+{
+    LOG("Creating Policy Engine.\n");
+    SML_present = false;
+    commandSocketFD = -1;
+    LoadPolicies();
+}
+
+
+PolicyEngine::~PolicyEngine()
+{
+}
+
+
+PolicyEngine::PolicyEngine(const char* serverName, const char* serverPort, \
+        const bool SML)
+{
+    LOG("Creating Policy Engine.\n");
+
+    ConnectToRemoteComponent(serverName, serverPort, SML);
+
+    LoadPolicies();
+}
+
+
+void
+PolicyEngine::SendComponentType()
+{
+    SendMessage(commandSocketFD, "response_engine_policy");
+    LOG("Policy Engine responded to GetRemoteComponentType query.\n");
+}
+
+
+void
+PolicyEngine::ConnectToRemoteComponent(const char* serverName, \
+        const char* serverPort, const bool SML)
+{
+    commandSocketFD = ClientSocket(serverName, serverPort);
+
+    SML_present = SML;
+
+    if(SML) {
+        RegisterServices();
+        LOG("Policy Engine connected to SML at %s.\n", serverName);
+    }
+    else {
+        RegisterComponent();
+        LOG("Policy Engine connected to shell at %s.\n", serverName);
+    }
+}
+
+
+void 
+PolicyEngine::WaitForSignal()
+{
+    char buffer[256];
+
+    while(true) {
+        memset(buffer, 0, 256);
+       
+        ReadMessage(commandSocketFD, buffer);
+
+        // TODO this is ugly... is there a better way? Doesn't strcmp compare the
+        // whole string?  We only need to compare until we find a single different
+        // byte...
+        //
+        // If we send integer op codes rather than strings, this process will be
+        // MUCH faster since instead of donig string compares we can simply
+        // switch on the integer value...
+        if(strcmp(buffer, "validate_parameters") == 0) {
+            ValidateParameters();
+        }
+        else if(strcmp(buffer, "query_component_type") == 0) {
+            SendComponentType();
+        }
+        else if(strcmp(buffer, "connect_sml") == 0) {
+            /* This command implies that we are disconnecting from the shell and
+             * connecting to a SML component. */
+            char serverName[256];
+            char serverPort[256];
+            // TODO is this going to end up being too slow?
+            memset(serverName, 0, 256);
+            memset(serverPort, 0, 256);
+
+            ReadMessage(commandSocketFD, serverName);
+            ReadMessage(commandSocketFD, serverPort);
+
+            /* Only continue if we are currently connected to a shell. */
+            if(!SML_present) {
+                DeregisterComponent();
+
+                shutdown(commandSocketFD, 2);
+                close(commandSocketFD);
+
+                ConnectToRemoteComponent(serverName, serverPort, true);
+            }
+        }
+        else if(strcmp(buffer, "disconnect_sml") == 0) {
+            /* This command implies that we are disconnecting from the SML and
+             * connecting to a shell component. */
+            char serverName[256];
+            char serverPort[256];
+            // TODO is this going to end up being too slow?
+            memset(serverName, 0, 256);
+            memset(serverPort, 0, 256);
+
+            ReadMessage(commandSocketFD, serverName);
+            ReadMessage(commandSocketFD, serverPort);
+
+            /* We only want to do this if we are actually connected to an SML
+             * currently. */
+            if(SML_present) {
+                DeregisterServices();
+
+                shutdown(commandSocketFD, 2);
+                close(commandSocketFD);
+
+                ConnectToRemoteComponent(serverName, serverPort, false);
+            }
+        }
+        else if(strcmp(buffer, "reload_engine_configs") == 0) {
+            ReloadPolicies();
+        }
+        else if(strcmp(buffer, "reset_engine_policy") == 0) {
+            Reset();
+        }
+        else if(strcmp(buffer, "shutdown_engine_policy") == 0) {
+            Shutdown();
+        }
+    }
+}
+
+
+void 
+PolicyEngine::Shutdown()
+{
+    if(SML_present)
+        DeregisterServices();
+    else
+        DeregisterComponent();
+
+    // TODO should something else be happening here?
+}
+
+
+void
+PolicyEngine::Reset()
+{
+    LOG("Resetting Policy Engine.\n");
+
+    if(SML_present)
+        DeregisterServices();
+    else
+        DeregisterComponent();
+}
+
+
+void
+PolicyEngine::RegisterComponent()
+{
+    SendMessage(commandSocketFD, "register_engine_policy");
+    LOG("Policy Engine:: Registration message sent to shell.\n");
+}
+
+
+void 
+PolicyEngine::DeregisterComponent()
+{
+    SendMessage(commandSocketFD, "deregister_engine_policy");
+    LOG("Policy Engine:: Deregistration message sent to shell.\n");
+
+    shutdown(commandSocketFD, 2);
+    close(commandSocketFD);
+    commandSocketFD = -1;
+    LOG("Policy Engine:: Shell socket closed.\n");
+}
+
+
+void 
+PolicyEngine::RegisterServices()
+{
+    LOG("Policy Engine:: Registering services.\n");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "policy_geo");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "policy_time");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "policy_spectrum");
+
+    SendMessage(commandSocketFD, "register_service");
+    SendMessage(commandSocketFD, "policy_spacial");
+}
+
+
+void 
+PolicyEngine::DeregisterServices()
+{
+    LOG("Policy Engine:: Deregistering services.\n");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "policy_geo");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "policy_time");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "policy_spectrum");
+
+    SendMessage(commandSocketFD, "deregister_service");
+    SendMessage(commandSocketFD, "policy_spacial");
+
+    shutdown(commandSocketFD, 2);
+    close(commandSocketFD);
+    commandSocketFD = -1;
+    LOG("Policy Engine:: SML socket closed.\n");
+}
+
+
+void 
+PolicyEngine::LoadPolicies()
+{
+    LOG("PolicyEngine:: Loading policies.\n");
+}
+
+
+void 
+PolicyEngine::ReloadPolicies()
+{
+    LOG("PolicyEngine:: Reloading policies.\n");
+}
+
+
+void 
+PolicyEngine::SendPEDecision(struct Parameter pList[], \
+        struct Radio_Info *radio_info, int32_t decision_array[])
+{
+    char var[50];
+ 
+    for (size_t i = 0; i < radio_info->numParameters; i++) {
+        sprintf(var, "%i", decision_array[i]);
+        SendMessage(commandSocketFD, var);
+    }
+}
+
+
+void 
+PolicyEngine::ValidateParameters()
+{
+    LOG("Policy Engine:: Preparing to receive parameters for validation....\n");
+
+    int32_t decision_array[10];
+    struct Parameter pList[10];
+    struct Radio_Info radio_info;
+
+    if(GetRequest(commandSocketFD, pList, &radio_info)) {
+        LOG("Policy Engine:: Validating Transmission Parameters.\n");
+        for (size_t i = 0; i < radio_info.numParameters; i++)
+            decision_array[i] = 1;
+
+        LOG("Policy Engine:: Sending Policy decision to Server.\n");
+        SendPEDecision(pList, &radio_info, decision_array);
+
+        LOG("Policy Engine:: Policies Validated.\n");
+    }
+    else
+        ERROR(1, "Call to GetRequest in ValidateParameters failed.\n");
+
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/policy_engines/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/policy_engines/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/policy_engines/Makefile.am	(revision 411)
@@ -0,0 +1,24 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = policy_demo
+
+policy_demo_SOURCES = PolicyEngine.cpp policy_demo.cpp
+policy_demo_LDADD = $(CROSS_SOCKETCOMM_LA) 
Index: vtcross/branches/nikhil/crossmodel2/src/shell/CognitiveRadioShell.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/CognitiveRadioShell.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/CognitiveRadioShell.cpp	(revision 554)
@@ -0,0 +1,818 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! This file provides the default implementation of the Cognitive Radio Shell.
+ *
+ * The CRS acts as the central control component in a CROSS radio system.  It
+ * handles component registration and message passing.
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <string>
+
+#include <arpa/inet.h>
+#include <iostream>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "tinyxml/tinyxml.h"
+#include "tinyxml/tinystr.h"
+
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/cross_shell.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/socketcomm.h"
+
+
+CognitiveRadioShell::CognitiveRadioShell()
+{
+    LOG("Creating Cognitive Radio Shell.\n");
+
+    SML_present = false;
+    PE_present = false;
+    CE_present = false;
+
+    params = new Parameter[10];
+    observables = new Observable[10];
+    utils = new Utility[10];
+    radio_info = new Radio_Info;
+}
+
+
+CognitiveRadioShell::~CognitiveRadioShell()
+{
+    delete [] params;
+    delete [] observables;
+    delete [] utils;
+    delete radio_info;
+}
+
+
+CognitiveRadioShell::CognitiveRadioShell(const char* radioConfig, int16_t p1, \
+        int16_t p2, int16_t p3)
+{
+    LOG("Creating Cognitive Radio Shell.\n");
+
+    SML_present = false;
+    PE_present = false;
+    CE_present = false;
+
+    params = new Parameter[10];
+    observables = new Observable[10];
+    utils = new Utility[10];
+    radio_info = new Radio_Info;
+
+    LoadRadioConfiguration(radioConfig, params, utils, observables, radio_info);
+
+    primaryPort = p1;
+    policyPort = p2;
+    commandPort = p3;
+}
+
+
+void
+CognitiveRadioShell::SendComponentType(int32_t socketFD)
+{
+    SendMessage(socketFD, "response_shell");
+    LOG("Cognitive Radio Shell responded to GetRemoteComponentType query.\n");
+}
+
+
+std::string 
+CognitiveRadioShell::GetRemoteComponentType(int32_t socketFD)
+{
+    SendMessage(socketFD, "request_component_type");
+
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(socketFD, buffer);
+
+    return std::string(buffer);
+}
+
+
+void 
+CognitiveRadioShell::Shutdown()
+{
+    LOG("Shutting down Cognitive Radio Shell.\n");
+}
+
+
+void
+CognitiveRadioShell::Reset()
+{
+    LOG("Resetting Cognitive Radio Shell.\n");
+}
+
+
+bool
+CognitiveRadioShell::SendRadioConfiguration(int32_t socketFD)
+{
+    LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n");
+
+    char counter[55];
+    char var[50];
+
+    /* Send utilities */
+    sprintf(counter, "%d", radio_info->numUtilities);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < radio_info->numUtilities; i++) {
+        SendMessage(socketFD, utils[i].name.c_str());
+        SendMessage(socketFD, utils[i].units.c_str());
+        SendMessage(socketFD, utils[i].goal.c_str());
+        sprintf(var,"%f", utils[i].target);
+        SendMessage(socketFD, var);
+    }
+
+    /* Send parameters */
+    sprintf(counter,"%i",radio_info->numParameters);
+    SendMessage(socketFD,counter);
+    for(size_t i = 0; i < radio_info->numParameters; i++) {
+        SendMessage(socketFD, params[i].name.c_str());
+        SendMessage(socketFD, params[i].units.c_str());
+        sprintf(var, "%f", params[i].min);
+        SendMessage(socketFD,var);
+        sprintf(var, "%f", params[i].max);
+        SendMessage(socketFD, var);
+        sprintf(var, "%f", params[i].step);
+        SendMessage(socketFD, var);
+
+        sprintf(counter, "%i", params[i].numAffects); 
+        SendMessage(socketFD, counter);
+        for(size_t j = 0; j < params[i].numAffects; j++) {
+            SendMessage(socketFD, params[i].affection_list[j].u->name.c_str());
+            SendMessage(socketFD, params[i].affection_list[j].relation.c_str());
+        }
+    }
+
+    /* Send observables */
+    sprintf(counter,"%i",radio_info->numObservables);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < radio_info->numObservables; i++) {
+        SendMessage(socketFD, observables[i].name.c_str());
+        
+        sprintf(counter, "%i", observables[i].numAffects); 
+        SendMessage(socketFD, counter);
+        for(size_t j = 0; j < observables[i].numAffects; j++) {
+            SendMessage(socketFD, observables[i].affection_list[j].u->name.c_str());
+            SendMessage(socketFD, observables[i].affection_list[j].relation.c_str());
+        }
+    }
+
+    
+    /* Receive ACK for radio configuration */
+    char buffer[256];
+    memset(buffer, 0, 256); 
+    ReadMessage(socketFD, buffer);
+
+    if(strcmp(buffer, "receive_config_ack") != 0) {
+        LOG("Cognitive Radio Shell:: Unexpected response: %s\n", buffer);
+        return false;
+    }
+
+    return true;
+}
+
+bool
+CognitiveRadioShell::SendRadioExperience(int32_t socketFD)
+{
+
+    LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n");
+    int32_t numberExp = 4;
+    char numberExpString[50];
+
+    sprintf(numberExpString, "%d", numberExp);
+    SendMessage(socketFD, "test");
+
+    char buffer[256];
+    memset(buffer, 0, 256); 
+    ReadMessage(socketFD, buffer);
+    if(strcmp(buffer, "receive_exp_ack") != 0) {
+        WARNING("Cognitive Radio Shell:: Unexpected response: %s\n", buffer);
+        return false;
+    }
+
+    return true;
+}
+
+
+void
+CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
+{
+    LOG("Cognitive Radio Shell:: Received registration from Cognitive Engine on socket %d.\n", \
+            socketFD);
+   
+    SendMessage(socketFD, "register_ack");
+    SendRadioConfiguration(socketFD);
+    SendRadioExperience(socketFD);
+
+    numberOfCognitiveEngines++;
+    
+    /* More efficient to always set to true than add a conditional branch to the
+     * code. */
+    CE_present = true;
+}
+
+
+void 
+CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
+{
+    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
+
+    numberOfCognitiveEngines--;
+    if(numberOfCognitiveEngines == 0)
+        CE_present = false;
+
+    SendMessage(socketFD, "deregister_ack");
+    shutdown(socketFD, 2);
+    close(socketFD);
+    LOG("Cognitive Radio Shell:: Socket %d closed.\n", socketFD);
+}
+
+
+void 
+CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \
+        Parameter* &pList, Utility* &uList, Observable* &oList, \
+        Radio_Info* radioInfo)
+{
+    TiXmlElement *pElem;
+    TiXmlElement *pChild;
+    TiXmlElement *pChild1;
+    TiXmlElement *pSecondChild;
+    TiXmlHandle hRoot(0);
+
+    int32_t count = 0;
+    size_t item_count = 0;
+    size_t affect_count = 0;
+    uint32_t attribute_count = 0;
+    bool match_found = false;
+
+    LOG("Cognitive Radio Shell:: Loading radio configuration.\n");
+
+    TiXmlDocument doc( radioConfig );
+    bool loadOkay = doc.LoadFile();
+    if(!loadOkay)
+        ERROR(1, "Loading radio configuration failed: %s\n", radioConfig);
+
+    TiXmlHandle hDoc(&doc);
+    
+    pElem = hDoc.FirstChildElement().Element();
+
+    if(!pElem) 
+        ERROR(1, "No valid root!");
+
+    hRoot = TiXmlHandle(pElem);
+
+    pElem = hRoot.FirstChild("utilities").Element();
+    pChild1 = hRoot.Child("utilities", count).Element();
+
+    for(pChild = pChild1->FirstChildElement("utility"); pChild; \
+        pChild = pChild->NextSiblingElement()) {
+
+        const char *uName = pChild->Attribute("name");
+        if(uName)
+            uList[item_count].name = uName;    
+
+        const char *uUnits = pChild->Attribute("units");
+        if(uUnits) 
+            uList[item_count].units = uUnits;
+
+        const char *uGoal = pChild->Attribute("goal");
+        if(uGoal) 
+            uList[item_count].goal = uGoal;
+
+        if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS) 
+            uList[item_count].target = -1;
+
+        item_count++;
+    }
+
+    radio_info->numUtilities = item_count;    
+    LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities);
+
+    item_count = 0;
+    pElem = hRoot.FirstChild("observables").Element();
+    pChild1 = hRoot.Child("observables", count).Element();
+
+    for(pChild = pChild1->FirstChildElement("observable"); pChild; \
+        pChild = pChild->NextSiblingElement()) {
+
+        const char *oName = pChild->Attribute("name");
+        if(oName) 
+            oList[item_count].name = oName;
+        
+        affect_count = 0;
+        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
+            pSecondChild = pSecondChild->NextSiblingElement()) {
+
+            const char *oUtilName = pSecondChild->Attribute("utility");
+            if(oUtilName) {
+                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) {
+                    if(uList[attribute_count].name == oUtilName) {
+
+                        oList[item_count].affection_list[affect_count].u = &uList[attribute_count];
+                        const char *oRelate = pSecondChild->Attribute("relationship");
+                        if(oRelate) 
+                            oList[item_count].affection_list[affect_count].relation = oRelate;
+
+                        affect_count++;
+                        match_found = true;
+                        break;
+                    }
+                }
+            }
+
+  
+//////////////////WE are not looking for relationship between them..            
+//            if(!match_found) { 
+//                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
+//                    oList[item_count].name.c_str(), oUtilName);
+//            }
+//            else
+//                match_found = false;    
+        }
+        oList[item_count].numAffects = affect_count; 
+        item_count++;
+    }
+
+    radioInfo->numObservables = item_count;    
+    LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables);
+
+    pElem = hRoot.FirstChild("parameters").Element();
+    pChild1 = hRoot.Child("parameters", count).Element();
+    
+    item_count = 0;
+    for(pChild = pChild1->FirstChildElement("parameter"); pChild; \
+        pChild = pChild->NextSiblingElement()) {
+
+        const char *pName = pChild->Attribute("name");
+        if(pName) 
+            pList[item_count].name = pName;    
+
+        const char *pUnits = pChild->Attribute("units");
+        if(pUnits) 
+            pList[item_count].units = pUnits;
+
+        if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS) 
+            pList[item_count].min = -1;
+
+        if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS) 
+            pList[item_count].max = -1;
+
+        if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS) 
+            pList[item_count].step = -1;
+        
+        affect_count = 0;
+        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
+
+            pSecondChild = pSecondChild->NextSiblingElement()) {
+            const char *pUtilName = pSecondChild->Attribute("utility");
+            if(pUtilName) {
+                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) {
+                    if(uList[attribute_count].name == pUtilName) {
+                        pList[item_count].affection_list[affect_count].u = &uList[attribute_count];    
+
+                        const char *pRelate = pSecondChild->Attribute("relationship");
+                        if(pRelate)
+                            pList[item_count].affection_list[affect_count].relation = pRelate;
+                        else
+                            LOG("Error: No relation found.\n");
+
+                        match_found = true;
+                        affect_count++;
+                        break;
+                    }
+                }
+            }
+
+//            if(!match_found) {
+//                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
+//                    pList[item_count].name.c_str(), pUtilName);
+//            }
+
+//            match_found = false;    
+        }
+
+        pList[item_count].numAffects = affect_count;
+        item_count++;
+    }
+
+    radioInfo->numParameters = item_count;
+    LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters);
+}
+
+
+void
+CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
+{
+    char buffer[256];
+    char counter[55];
+    char var[50];
+
+    /* Receive Set of Observables */
+    LOG("Cognitive Radio Shell:: Got request for optimization.\n");
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numObservables = atoi(buffer);
+  
+    LOG("Cognitive Radio Shell:: Attempting to get %i observables.\n", numObservables);
+    Observable *o = new Observable[numObservables];
+ 
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+   
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }
+
+    /* Receive Set of Current Parameters */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numCurrentParameters = atoi(buffer);
+  
+    LOG("Cognitive Radio Shell:: Attempting to get %i parameters.\n",numCurrentParameters);
+    Parameter *cp = new Parameter[numCurrentParameters];
+
+    for (size_t i = 0; i < numCurrentParameters; i++){
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD,buffer);
+        cp[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD,buffer);
+        cp[i].value = atof(buffer);
+    }
+////////////// NEW    INCLUSION ///////////////////
+
+/* Receive Set of Utilities */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numUtilities = atoi(buffer);
+
+    LOG("Cognitive Radio Shell:: Attempting to get %i utilities.\n",numUtilities);
+    Utility *u = new Utility[numUtilities];
+
+    for (size_t i = 0;i < numUtilities; i++){
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD,buffer);
+	u[i].name = std::string(buffer);
+
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD,buffer);
+	u[i].value = atof(buffer);
+    }
+
+///////////////////////////////////////
+
+    /* Send to Cognitive Engine 
+     * TODO: With multiple CEs we need to make a decision about where
+     * to send this information
+     */
+    SendMessage(ceSocketFD,"request_optimization");
+
+    LOG("Cognitive Radio Shell:: Passing on observables.\n");
+    sprintf(counter,"%i",numObservables);
+    SendMessage(ceSocketFD,counter);
+    for(size_t i = 0; i < numObservables; i++) {
+        SendMessage(ceSocketFD,o[i].name.c_str());
+        sprintf(var,"%f",o[i].value);
+        SendMessage(ceSocketFD,var);
+    }
+        
+    LOG("Cognitive Radio Shell:: Passing on current parameters.\n");
+    sprintf(counter,"%i",numCurrentParameters);
+    SendMessage(ceSocketFD,counter);
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        SendMessage(ceSocketFD,cp[i].name.c_str());
+        sprintf(var,"%f",cp[i].value);
+        SendMessage(ceSocketFD,var); 
+    }
+
+/////////////  NEW  ////////////////////////////////////////////////////////
+    LOG("Cognitive Radio Shell:: Passing on utilities.\n");
+    sprintf(counter,"%i",numUtilities);
+    SendMessage(ceSocketFD,counter);
+    for(size_t i = 0; i < numUtilities; i++) {
+	SendMessage(ceSocketFD,u[i].name.c_str());
+        sprintf(var,"%f",u[i].value);
+  	SendMessage(ceSocketFD,var);
+    }
+
+////////////// END of NEW /////////////////////////////////////
+
+    /* Receive Set of Parameters */
+    LOG("Cognitive Radio Shell:: Receiving optimized parameters.\n");
+    memset(buffer, 0, 256);
+    ReadMessage(ceSocketFD, buffer);
+    uint32_t numParameters = atoi(buffer);
+   
+    Parameter *p = new Parameter[numParameters];
+ 
+    for(size_t i = 0; i < numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(ceSocketFD, buffer);
+        p[i].name = std::string(buffer);
+    
+        memset(buffer, 0, 256);
+        ReadMessage(ceSocketFD, buffer);
+        p[i].value = atof(buffer);
+    }
+
+    /* Send to Application 
+     */
+    LOG("Cognitive Radio Shell:: Sending optimized parameters to Application.\n");
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numParameters);
+    SendMessage(commandSocketFD, counter);
+    for(size_t i = 0; i < numParameters; i++) {
+        SendMessage(commandSocketFD, p[i].name.c_str());
+        sprintf(var, "%f", p[i].value);
+        SendMessage(commandSocketFD, var);
+    }
+
+    delete [] o;
+    delete [] u;
+    delete [] p;
+}
+
+
+void
+CognitiveRadioShell::UpdateParameterPerformance(int32_t socketFD)
+{
+    char counter[55];
+    char var[50];
+    char buffer[256];
+
+    /* Receive Set of Parameters */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD,buffer);
+    uint32_t numParameters = atoi(buffer);
+  
+    Parameter *p = new Parameter[numParameters];
+
+    for (size_t i = 0; i < numParameters; i++){
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD,buffer);
+        p[i].name = std::string(buffer);
+
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD,buffer);
+        p[i].value = atof(buffer);
+    }
+
+    /* Receive Set of Observables */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numObservables = atoi(buffer);
+  
+    Observable *o = new Observable[numObservables];
+ 
+    for(size_t i = 0; i < numObservables; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].name = std::string(buffer);
+   
+        memset(buffer, 0, 256);
+        ReadMessage(commandSocketFD, buffer);
+        o[i].value = atof(buffer);
+    }
+
+    /* Receive Set of Utilities */
+    memset(buffer, 0, 256);
+    ReadMessage(commandSocketFD, buffer);
+    uint32_t numUtilities = atoi(buffer);
+
+    Utility *u = new Utility[numUtilities];
+
+    for(size_t i = 0; i < numUtilities; i++) {
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD, buffer);
+	u[i].name = std::string(buffer);
+
+	memset(buffer, 0, 256);
+	ReadMessage(commandSocketFD, buffer);
+	u[i].value = atof(buffer);
+    }
+
+    SendMessage(ceSocketFD, "update_performance");
+   
+    /* Send Parameters */
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numParameters);
+    SendMessage(ceSocketFD, counter);
+    
+    for(size_t i = 0; i < numParameters; i++) {
+        SendMessage(ceSocketFD,p[i].name.c_str());
+        sprintf(var,"%f",p[i].value);
+        SendMessage(ceSocketFD,var);  
+    }   
+    
+    /* Send Observables */
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numObservables);
+    SendMessage(ceSocketFD, counter);
+    for(size_t i = 0; i < numObservables; i++) {
+        SendMessage(ceSocketFD, o[i].name.c_str());
+        sprintf(var, "%f", o[i].value);
+        SendMessage(ceSocketFD, var); 
+    }   
+
+     /* Send Utilities */
+     memset(counter, 0, 55);
+     sprintf(counter, "%i", numUtilities);
+     SendMessage(ceSocketFD,counter);
+     for(size_t i = 0; i < numUtilities; i++) {
+	SendMessage(ceSocketFD, u[i].name.c_str());
+	sprintf(var, "%f", u[i].value);
+	SendMessage(ceSocketFD, var);
+     }
+
+
+    delete [] p;
+    delete [] o;
+    delete [] u;
+}
+
+
+int32_t
+CognitiveRadioShell::HandleMessage(int32_t socketFD)
+{
+    char buffer[256];
+    int ret = 0;
+    
+    ret = ReadMessage(socketFD, buffer);
+    if(ret == -1)
+        return ret;
+
+    // TODO trying to read this code block makes my eyes bleed
+    if(strcmp(buffer, "register_engine_cognitive") == 0) { 
+        RegisterCognitiveEngine(socketFD);
+    } else if(strcmp(buffer, "deregister_engine_cognitive") == 0) {
+        DeregisterCognitiveEngine(socketFD);
+    } else if(strcmp(buffer, "update_performance") == 0) {
+        UpdateParameterPerformance(socketFD);
+    } else if(strcmp(buffer, "get_number_utilities") == 0) {
+        char numUtilities[20];
+        sprintf(numUtilities, "%i", radio_info->numUtilities);
+        SendMessage(commandSocketFD, numUtilities);
+    } else if(strcmp(buffer, "get_number_observables") == 0) {
+        char numObservables[20];
+        sprintf(numObservables, "%i", radio_info->numObservables);
+        SendMessage(commandSocketFD, numObservables);
+    } else if(strcmp(buffer, "get_number_parameters") == 0) {
+        char numParameters[20];
+        sprintf(numParameters, "%i", radio_info->numParameters);
+        SendMessage(commandSocketFD, numParameters);
+    } else if(strcmp(buffer, "request_optimization") == 0) {
+        /* Receive optimization request and current environment */
+        GetOptimalParameters(socketFD);  
+    } 
+
+    return ret;
+}
+
+
+void
+CognitiveRadioShell::StartShellServer()
+{
+    struct timeval selTimeout;
+    int32_t primary = 0;
+    int32_t policy = 1;
+    int32_t command = 2;
+    int32_t running = 1;
+    int32_t port, rc, new_sd = 1;
+    int32_t desc_ready = 1;
+    int32_t timeout = 50;
+    int32_t ret = 0;;
+    fd_set sockSet;
+   
+    int32_t *servSock = new int32_t[3];
+
+    servSock[primary] = CreateTCPServerSocket(primaryPort);
+    servSock[policy] = CreateTCPServerSocket(policyPort);
+    servSock[command] = CreateTCPServerSocket(commandPort);
+
+    int32_t maxDescriptor; 
+
+    if(servSock[primary] > servSock[policy])
+        maxDescriptor = servSock[primary];
+    else 
+        maxDescriptor = servSock[policy];
+
+    if(servSock[command] > maxDescriptor)
+        maxDescriptor = servSock[command];
+
+    if(InitializeTCPServerPort(servSock[primary]) == -1)
+        ERROR(1,"Error initializing primary port\n");
+ 
+    if(InitializeTCPServerPort(servSock[policy]) == -1)
+        ERROR(1,"Error initializing policy port\n");
+
+    if(InitializeTCPServerPort(servSock[command]) == -1)
+        ERROR(1,"Error initializing command port\n");
+
+    FD_ZERO(&sockSet);
+    
+    while(running) {
+        /* Zero socket descriptor vector and set for server sockets */
+        /* This must be reset every time select() is called */
+        FD_SET(servSock[primary], &sockSet);
+        FD_SET(servSock[policy], &sockSet);
+        FD_SET(servSock[command], &sockSet);
+
+        /* Timeout specification */
+        /* This must be reset every time select() is called */
+        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
+        selTimeout.tv_usec = 0;            /* 0 microseconds */
+
+        /* Suspend program until descriptor is ready or timeout */
+        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout); 
+        if(rc == 0)
+            LOG("No echo requests for %i secs...Server still alive\n", timeout);
+        else {
+            desc_ready = rc;
+
+            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
+                if(FD_ISSET(port, &sockSet)) {
+                    desc_ready -= 1;
+                    /* Check if request is new or on an existing open descriptor */
+                    if((port == servSock[primary]) || \
+                            (port == servSock[policy]) || \
+                            (port == servSock[command])) { 
+                        do {
+                            new_sd = AcceptTCPConnection(port);
+                            if(new_sd < 0)
+                                break;
+                            if(port == servSock[primary])
+                                ceSocketFD = new_sd;
+                            if(port == servSock[command])
+                                commandSocketFD = new_sd;
+                            if(port == servSock[policy])
+                                policySocketFD = new_sd;
+
+                            ret = HandleMessage(new_sd);
+
+                            if(ret == -1) {
+                                FD_CLR(new_sd,&sockSet);
+                                close(new_sd);
+                                break;
+                            }
+
+                            FD_SET(new_sd,&sockSet);
+                            if(new_sd > maxDescriptor) 
+                                maxDescriptor = new_sd;
+
+                        } while(new_sd != -1);
+                    } 
+                    else {
+                        ret = HandleMessage(port);
+                        if(ret == -1) {
+                            FD_CLR(port,&sockSet);
+                            close(port);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    LOG("Closing it all.\n\n");
+
+    /* Close sockets */
+    close(servSock[primary]);
+    close(servSock[policy]);
+    close(servSock[command]);
+
+    /* Free list of sockets */
+    delete servSock;
+
+    return;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/shell/configs/demo.xml
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/configs/demo.xml	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/configs/demo.xml	(revision 554)
@@ -0,0 +1,25 @@
+<!--
+This is an example XML file to interface with our cognitive engine.
+The library shall create a new table "myengine" with the following cols:
+  throughput spectral_efficiency log10_ber mod_scheme tx_power SNR
+-->
+<engine name="myengine" filename="myengine.sql">
+
+    <!-- utilities : QoS metrics -->
+    <utilities>
+        <utility name="throughput" units="kbps" goal="max" target="517" /> 
+        <utility name="PER" units="none" goal="min" target="1.2" />
+    </utilities>
+
+    <!-- radio parameters -->
+    <parameters>
+        <parameter name="bandwidth" units="hz" min="1" max="255" step="10">
+        </parameter>
+        <parameter name="tx_power" units="dBm" min="1" max="255" step="1">
+        </parameter>
+    </parameters>
+
+    <!-- link/channel observations -->
+    <observables>
+    </observables>
+</engine>
Index: vtcross/branches/nikhil/crossmodel2/src/shell/configs/ossie_demo.xml
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/configs/ossie_demo.xml	(revision 457)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/configs/ossie_demo.xml	(revision 457)
@@ -0,0 +1,26 @@
+<!--
+This is an example XML file to interface with our cognitive engine.
+The library shall create a new table "myengine" with the following cols:
+  throughput spectral_efficiency log10_ber mod_scheme tx_power SNR
+-->
+<engine name="myengine" filename="myengine.sql">
+
+    <!-- utilities : QoS metrics -->
+    <utilities>
+        <utility name="biterrorrate" units="" goal="min" target=".025" /> 
+    </utilities>
+
+    <!-- radio parameters -->
+    <parameters>
+        <parameter name="tx_power" units="dBm" min="1" max="255" step="1">
+            <affect utility="biterrorrate" relationship="improve"/>
+        </parameter>
+    </parameters>
+
+    <!-- link/channel observations -->
+    <observables>
+        <observable name="ber">
+            <affect utility="biterrorrate" relationship="improve" />
+        </observable>
+    </observables>
+</engine>
Index: vtcross/branches/nikhil/crossmodel2/src/shell/configs/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/configs/Makefile.am	(revision 452)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/configs/Makefile.am	(revision 452)
@@ -0,0 +1,18 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = demo.xml dsa_gnuradio.xml example.xml Makefile.am ossie_demo.xml 
+
Index: vtcross/branches/nikhil/crossmodel2/src/shell/configs/example.xml
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/configs/example.xml	(revision 375)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/configs/example.xml	(revision 375)
@@ -0,0 +1,34 @@
+<!--
+This is an example XML file to interface with our cognitive engine.
+The library shall create a new table "myengine" with the following cols:
+  throughput spectral_efficiency log10_ber mod_scheme tx_power SNR
+-->
+<engine name="myengine" filename="myengine.sql">
+
+    <!-- utilities : QoS metrics -->
+    <utilities>
+        <utility name="throughput" units="kbps" goal="max" target="125" />
+        <utility name="spectral_efficiency" units="b/s/Hz" goal="max" />
+        <utility name="log10_ber" units="none" goal="min" target="-3" />
+    </utilities>
+
+    <!-- radio parameters -->
+    <parameters>
+        <parameter name="mod_scheme" min="1" max="4" step="1">
+            <!-- BPSK, QPSK, 8-PSK, 16-QAM -->
+            <affect utility="throughput" relationship="improve" />
+            <affect utility="spectral_efficiency" relationship="improve" />
+            <affect utility="log10_ber" relationship="degrade" />
+        </parameter>
+        <parameter name="tx_power" units="dBm" min="-30.0" max="0.0" step="0.1">
+            <affect utility="log10_ber" relationship="improve"/>
+        </parameter>
+    </parameters>
+
+    <!-- link/channel observations -->
+    <observables>
+        <observable name="SNR">
+            <affect utility="log10_ber" relationship="improve" />
+        </observable>
+    </observables>
+</engine>
Index: vtcross/branches/nikhil/crossmodel2/src/shell/configs/dsa_gnuradio.xml
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/configs/dsa_gnuradio.xml	(revision 393)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/configs/dsa_gnuradio.xml	(revision 393)
@@ -0,0 +1,24 @@
+<engine name="dsa" filename="dsa.sql">
+
+    <!-- utilities : QoS metrics -->
+    <utilities>
+        <utility name="interference" units="dB" goal="min" /> 
+    </utilities>
+
+    <!-- radio parameters -->
+    <parameters>
+        <parameter name="channel" units="none" min="1" max="4" step="1">
+            <affect utility="interference" relationship="n/a" />
+        </parameter>
+    </parameters>
+
+    <!-- link/channel observations -->
+    <observables>
+        <observable name="energy">
+            <affect utility="interference" relationship="n/a" />
+        </observable>
+        <observable name="communication_time">
+            <affect utility="interference" relationship="n/a" />
+        </observable>
+    </observables>
+</engine>
Index: vtcross/branches/nikhil/crossmodel2/src/shell/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/Makefile.am	(revision 452)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/Makefile.am	(revision 452)
@@ -0,0 +1,25 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = shell_demo
+
+shell_demo_SOURCES = CognitiveRadioShell.cpp shell_demo.cpp
+shell_demo_LDADD = $(CROSS_XML_A) $(CROSS_SOCKETCOMM_LA) 
+
+SUBDIRS = configs
Index: vtcross/branches/nikhil/crossmodel2/src/shell/shell_demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/shell/shell_demo.cpp	(revision 465)
+++ vtcross/branches/nikhil/crossmodel2/src/shell/shell_demo.cpp	(revision 465)
@@ -0,0 +1,41 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/* TODO DESCRIPTION OF FILE.
+ */
+
+
+#include <cstdlib>
+#include <stdint.h>
+
+#include "vtcross/common.h"
+#include "vtcross/cross_shell.h"
+#include "vtcross/error.h"
+
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    if(argc < 3)
+       ERROR(1, "Usage: ./shell_demo config_file primary_port policy_port command_port\n", argv[0]);
+    
+    CognitiveRadioShell cognitiveRadioShell(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
+
+    cognitiveRadioShell.StartShellServer();
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/service_management_layer/sml_demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/service_management_layer/sml_demo.cpp	(revision 465)
+++ vtcross/branches/nikhil/crossmodel2/src/service_management_layer/sml_demo.cpp	(revision 465)
@@ -0,0 +1,52 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+#include <string>
+#include <stdlib.h> 
+
+#include <arpa/inet.h>
+#include <iostream>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "sqlite3.h"
+
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/service_management_layer.h"
+#include "vtcross/socketcomm.h"
+
+
+int main(int argc, char *argv[])
+{  
+
+    if(argc < 5)
+       ERROR(1, "Usage: %s config hostname shell_port client_port\n", argv[0]);
+ 
+    ServiceManagementLayer SML(argv[1], argv[2], argv[3], atoi(argv[4]));
+    SML.StartSMLServer();     
+}
Index: vtcross/branches/nikhil/crossmodel2/src/service_management_layer/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/service_management_layer/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/src/service_management_layer/Makefile.am	(revision 411)
@@ -0,0 +1,24 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+AM_CXXFLAGS = -Wall -g
+
+bin_PROGRAMS = sml_demo
+
+sml_demo_SOURCES = ServiceManagementLayer.cpp sml_demo.cpp
+sml_demo_LDADD = -ldl -lpthread -lsqlite3  $(CROSS_XML_A) $(CROSS_SOCKETCOMM_LA) 
Index: vtcross/branches/nikhil/crossmodel2/src/service_management_layer/ServiceManagementLayer.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/service_management_layer/ServiceManagementLayer.cpp	(revision 521)
+++ vtcross/branches/nikhil/crossmodel2/src/service_management_layer/ServiceManagementLayer.cpp	(revision 521)
@@ -0,0 +1,1643 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! Inter-component communication handled by sockets and FD's.  
+ * Server support has been completely implemented and tested.
+ *
+ * Services are stored in a SQLite DB by the ID of the CE that registered them.  Service
+ * support has been completely implemented and tested.
+ *
+ * Missions are loaded from an XML file, connected with services provided by components,
+ * and run.  See the documentation for the "PerformActiveMission" below for important 
+ * info.
+ */
+
+
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include <arpa/inet.h>
+#include <iostream>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <sqlite3.h>
+#include <string>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "tinyxml/tinyxml.h"
+#include "tinyxml/tinystr.h"
+
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/common.h"
+#include "vtcross/containers.h"
+#include "vtcross/service_management_layer.h"
+#include "vtcross/socketcomm.h"
+
+
+using namespace std;
+
+
+/* Internal structs used to keep track of sqlite database information. */
+struct services_s {
+    string filename;
+    string tablename;
+    string command;
+    sqlite3 *db; 
+    unsigned int num_columns;
+};
+
+struct data_s {
+    string filename;
+    string tablename;
+    string command;
+    sqlite3 *db; 
+    unsigned int num_columns;
+};
+
+typedef struct services_s *services_DB_t;
+typedef struct data_s *data_DB_t;
+
+/* Global tracking of the services and parameters that this instance of SML is
+ * aware of. */
+services_DB_t services_DB;
+data_DB_t data_DB;
+
+/* The filename of the SML configuration, used if the SML is told to reload it's
+ * configuration. */
+string _SML_Config;
+
+/* Keeps track of whether or not the 'shell' component is used by the active
+ * mission. */
+bool shellUsed;
+
+
+/* Callback function used internally by some of the SQLite3 commands for debug
+ * output. Code provided by sqlite documentation. */
+int32_t 
+callback(void *notUsed, int32_t argc, char **argv, char **azColName)
+{
+    for(size_t i = 0; i < argc; i++) {
+        LOG("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+    }
+
+    LOG("\n");
+    return 0;
+}
+
+
+ServiceManagementLayer::ServiceManagementLayer()
+{
+    LOG("Creating Service Management Layer.\n");
+
+    shellSocketFD = -1;
+    numberOfCognitiveEngines = 0;
+    CE_Present = false;
+    cogEngSrv = 1;
+}
+
+
+/* Free and clear the DB's associated with this SML in the destructor.
+ *
+ * Note that exiting with an error condition will cause SML to not be destructed,
+ * resulting in the DB's staying in memory until the destructor is encountered in 
+ * future executions. */
+ServiceManagementLayer::~ServiceManagementLayer()
+{
+    char *errorMsg;
+    int32_t rc;         /* sqlite command return code */
+
+    services_DB->command = "drop table ";
+    services_DB->command.append(services_DB->tablename);
+    rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::Destructor services 'drop table' error: %s\n", errorMsg);
+
+    services_DB->command = "vacuum";
+    rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::Destructor services 'vacuum' error: %s\n", errorMsg);
+
+    free(services_DB);
+
+    data_DB->command = "drop table ";
+    data_DB->command.append(data_DB->tablename);
+    rc = sqlite3_exec(data_DB->db, data_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::Destructor data 'drop table' error: %s\n", errorMsg);
+
+    data_DB->command = "vacuum";
+    rc = sqlite3_exec(data_DB->db, data_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::Destructor data 'vacuum' error: %s\n", errorMsg);
+
+    free(data_DB);
+}
+
+
+/* Note that sizes of CE_List, miss, and service are hardcoded for now.
+ * Also, their sizes are hardcoded into the code in various places; a fix 
+ * for a future version. */
+ServiceManagementLayer::ServiceManagementLayer(const char* SML_Config, \
+    const char* serverName, const char* serverPort, int16_t clientPort)
+{
+    LOG("Creating Service Management Layer.\n");
+
+    _SML_Config = string(SML_Config);
+    SMLport = clientPort;
+
+    ConnectToShell(serverName, serverPort);
+    CE_List = new CE_Reg[10];
+
+    miss = new Mission[10];
+    for(size_t i = 0; i < 10; i++) {
+        miss[i].services = new Service[30];
+    }
+
+    Current_ID = 0;
+
+    LoadConfiguration(SML_Config, miss);
+
+    CreateServicesDB();
+    CreateDataDB();
+}
+
+
+/* CALLED BY: constructor
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Create and initialize a DB to hold the services registered by components
+ */
+void
+ServiceManagementLayer::CreateServicesDB()
+{
+    sqlite3_stmt *ppStmt;   /* OUT: Statement handle */
+    const char *pzTail;     /* OUT: Pointer to unused portion of zSql */
+    int32_t rc;             /* sqlite command return code */
+
+    services_DB = new services_s;
+    services_DB->filename="Services_Table";
+    sqlite3_open(services_DB->filename.c_str(), &(services_DB->db));
+
+    services_DB->tablename="Services";
+
+    /* If program execution ends in anything other than a ordered shutdown, DB's will still 
+     * be there for next run. Need to get rid of it so that old data isn't inadvertantly 
+     * used in the next execution cycle. */
+    services_DB->command = "DROP TABLE if EXISTS Services;";     
+
+    rc = sqlite3_prepare_v2(services_DB->db, services_DB->command.c_str(), 128, &ppStmt, &pzTail);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateServicesDB 'prepare_stmt' error %d\n", rc);
+
+    rc = sqlite3_step(ppStmt);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateServicesDB 'step' error\n");
+
+    services_DB->num_columns = 2;
+
+    /* Generate command */
+    services_DB->command="CREATE TABLE ";
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append("(ID_Num INT, Service_Name TEXT);");
+
+    /* Execute create table command */
+    rc = sqlite3_prepare_v2(services_DB->db, services_DB->command.c_str(), 128, &ppStmt, &pzTail);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateServicesDB 'prepare_stmt' error %d\n", rc);
+
+    rc = sqlite3_step(ppStmt);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateServicesDB 'step' error\n");
+}
+
+
+/* CALLED BY: constructor
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Create and initialize a DB to hold the data sent by components
+ */
+void
+ServiceManagementLayer::CreateDataDB()
+{
+    sqlite3_stmt *ppStmt;   /* OUT: Statement handle */
+    const char *pzTail;     /* OUT: Pointer to unused portion of zSql */
+    int32_t rc;             /* sqlite command return code */
+
+    data_DB = new data_s;
+
+    data_DB->filename="Data_Table";
+    sqlite3_open(data_DB->filename.c_str(), &(data_DB->db));
+
+    data_DB->tablename = "Data";
+    data_DB->command = "DROP TABLE if EXISTS Data;";     
+
+    rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), 128, &ppStmt, &pzTail);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateDataDB 'prepare_stmt' error %d\n", rc);
+
+    rc = sqlite3_step(ppStmt);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateDataDB 'step' error\n");
+
+    data_DB->num_columns = 2;
+
+    /* First column is the name of the data (corresponding to the name of the output/input pair)
+     * It is the primary key so any subsequent data with the same name will replace the row. */
+    data_DB->command = "CREATE TABLE ";
+    data_DB->command.append(data_DB->tablename);
+    data_DB->command.append("(Tag TEXT PRIMARY KEY ON CONFLICT REPLACE, Data TEXT);");
+
+    rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), 128, &ppStmt, &pzTail);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateDataDB 'prepare_stmt' error %d\n", rc);
+
+    rc = sqlite3_step(ppStmt);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::CreateDataDB 'step' error\n");
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Sends a message identifying this component as an SML to the Shell
+ */
+void 
+ServiceManagementLayer::SendComponentType()
+{
+    SendMessage(shellSocketFD, "response_sml");
+    LOG("SML responded to GetRemoteComponentType query.\n");
+}
+
+
+/* CALLED BY: constructor
+ * INPUTS: |serverName| the IPv4 name of the server (127.0.0.1 for localhost)
+ *         |serverPort| the port on the server to connect to
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Connecting to the shell takes 2 steps
+ * 1) Establish a client socket for communication
+ * 2) Run the initial Registration/handshake routine
+ */
+void 
+ServiceManagementLayer::ConnectToShell(const char* serverName, \
+        const char* serverPort)
+{
+    shellSocketFD = ClientSocket(serverName, serverPort);
+    RegisterComponent();
+}
+
+
+/* CALLED BY: StartSMLServer
+ * INPUTS: |ID| The ID number of the CE that has a message wating
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Called whenever a socket is identified as being ready for communication
+ *              This funciton reads the message and calls the appropriate helper
+ */ 
+void
+ServiceManagementLayer::MessageHandler(int32_t ID)
+{
+    char buffer[256];    
+    memset(buffer, 0, 256);  
+    int32_t _FD;  
+    
+    if(ID != -1)
+        _FD = CE_List[ID].FD;
+    else 
+        _FD = shellSocketFD;
+
+    ReadMessage(_FD, buffer);
+   
+    /* Go down the list to call the appropriate function */
+    if(strcmp(buffer, "query_component_type") == 0) {
+        SendComponentType();
+    }
+    else if(strcmp(buffer, "reset_sml") == 0) {
+        Reset();
+    }
+    else if(strcmp(buffer, "shutdown_sml") == 0) {
+        Shutdown();
+    }
+    else if(strcmp(buffer, "register_engine_cognitive") == 0) {
+        RegisterCognitiveEngine(ID);
+    }
+    else if(strcmp(buffer, "register_service") == 0) {
+        ReceiveServices(ID);
+    }
+    else if(strcmp(buffer, "send_component_type") == 0) {
+        SendComponentType();
+    }
+    else if(strcmp(buffer, "list_services") == 0) {
+        ListServices();
+    }
+    else if(strcmp(buffer, "set_active_mission") == 0) {
+        SetActiveMission();
+    }
+    else if(strcmp(buffer, "request_optimization") == 0) {
+        PerformActiveMission();
+    }
+    else if(strcmp(buffer, "deregister_engine_cognitive") == 0) {
+        DeregisterCognitiveEngine(ID);
+    }
+    else if(strcmp(buffer, "deregister_service") == 0) {
+        DeregisterServices(ID);
+    }
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Deregisters the component from the Shell.
+ */ 
+void 
+ServiceManagementLayer::Shutdown()
+{
+    DeregisterComponent();
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Deregisters the component from the Shell
+ */
+void 
+ServiceManagementLayer::Reset()
+{
+    DeregisterComponent();
+    ReloadConfiguration();
+}
+
+
+/* CALLED BY: ConnectToShell
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Sends the registration message to the Shell
+ */
+void 
+ServiceManagementLayer::RegisterComponent()
+{
+    SendMessage(shellSocketFD, "register_sml");
+    LOG("ServiceManagementLayer:: Registration message sent.\n");
+}
+
+
+/* CALLED BY: Shutdown
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Closes the client socket with the shell, sends a deregstration message
+ */
+void 
+ServiceManagementLayer::DeregisterComponent()
+{
+    SendMessage(shellSocketFD, "deregister_sml");
+    LOG("ServiceManagementLayer:: Deregistration message sent.\n");
+
+    shutdown(shellSocketFD, 2);
+    close(shellSocketFD);
+    shellSocketFD = -1;
+    LOG("ServiceManagementLayer:: Shell socket closed.\n");
+}
+
+
+/* CALLED BY: RegisterCognitiveEngine
+ * INPUTS: |ID| The ID number of the component where the data is to be transfered to
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Streams config data directly from the shell to the CE, and checks
+ * for an "ack" message from the CE after every sent message 
+ * to know when to stop communication.
+ * 
+ * NOTE: Modified to check the incoming message buffer rather than the outgoing 
+ * message buffer to avoid a portion of the delay. May change this again to handle 
+ * data more inteligently, taking advantage of it's properties.
+ */
+void 
+ServiceManagementLayer::TransferRadioConfiguration(int32_t ID)
+{
+    struct timeval selTimeout;
+    fd_set sockSet;
+    int32_t rc = 1;
+    char buffer[256];
+
+    /* Send data until the CE sends an ACK message back */
+    while(rc != 0) {
+        memset(buffer, 0, 256);
+
+        /* Receive data from Shell */
+        ReadMessage(shellSocketFD, buffer);
+
+        /* Send data to CE */
+        SendMessage(CE_List[ID].FD, buffer);
+        FD_ZERO(&sockSet);
+        FD_SET(shellSocketFD, &sockSet);
+        selTimeout.tv_sec = 0;
+        selTimeout.tv_usec = 5000;
+
+        /* Check ifthere is a message on the shell ready to be processed */
+        rc = select(shellSocketFD + 1, &sockSet, NULL, NULL, &selTimeout);
+    }
+
+    memset(buffer, 0, 256);
+    ReadMessage(CE_List[ID].FD, buffer);
+    SendMessage(shellSocketFD, buffer);
+}
+
+
+/* CALLED BY: RegisterCognitiveEngine
+ * INPUTS: |ID| The ID number of the component where the data is to be transfered to
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Simmilar to TransferRadioConfig, just with Experience data
+ * 
+ * NOTE: Modified to check the incoming message buffer rather than the outgoing 
+ * message buffer to avoid a portion of the delay. May change this again to handle 
+ * data more inteligently, taking advantage of it's properties.
+ */
+void 
+ServiceManagementLayer::TransferExperience(int32_t ID)
+{
+    struct timeval selTimeout;
+    fd_set sockSet;
+    int32_t rc = 1;
+    char buffer[256];
+    /* Send data until the CE sends an ACK message back */
+    while(rc != 0) {
+        memset(buffer, 0, 256);
+
+        /* Receive data from Shell */
+        ReadMessage(shellSocketFD, buffer);
+
+        /* Send data to CE */
+        SendMessage(CE_List[ID].FD, buffer);
+        FD_ZERO(&sockSet);
+        FD_SET(shellSocketFD, &sockSet);
+        selTimeout.tv_sec = 0;
+        selTimeout.tv_usec = 5000;
+
+        /* Check ifthere is a message on the shell ready to be processed */
+        rc = select(shellSocketFD + 1, &sockSet, NULL, NULL, &selTimeout);
+    }
+
+    memset(buffer, 0, 256);
+    ReadMessage(CE_List[ID].FD, buffer);
+    SendMessage(shellSocketFD, buffer);
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: |ID| The ID number of the component where service is located
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Inserts a service into the DB with the ID of the component where it exists
+ */
+void 
+ServiceManagementLayer::ReceiveServices(int32_t ID)
+{
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(CE_List[ID].FD, buffer);
+
+    /* Generate command */
+    services_DB->command = "insert into ";
+    services_DB->command.append(services_DB->tablename); 
+    services_DB->command.append(" (ID_Num, Service_Name) values(");
+
+    char temp[3];
+    memset(temp, 0, 3);
+    sprintf(temp, "%d", ID);
+
+    services_DB->command.append(temp);
+    services_DB->command.append(", '");
+    services_DB->command.append(buffer);
+    services_DB->command.append("');");
+    
+    /* Execute add command */
+    char *errorMsg;
+    int rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("ServiceManagementLayer::RecieveServices DB Error %s\n", errorMsg);
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: This method associates the services that components provide with the 
+ * services that are requested in the mission. Each service in the mission is given 
+ * the ID and FD of a component that has registered to provide that service. Deregistration 
+ * is okay until this method is called without a reload, but ifderegistration occurs after this
+ * method is called it needs to be called again even ifother engines also provide the services
+ */
+void 
+ServiceManagementLayer::SetActiveMission()
+{
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(shellSocketFD, buffer);
+
+    uint32_t missID = atoi(buffer);
+    for(activeMission = 0; activeMission < 10; activeMission++) {
+        /* Find the active mission by comparing mission ID's */
+        if(miss[activeMission].missionID == missID)
+            break;
+    }
+
+    LOG("ServiceManagementLayer:: Received Set Active Mission command: %i.\n", missID);
+
+    /* For each service in the mission */
+    for(size_t i = 0; i < miss[activeMission].numServices; i++) {
+        /* Check whether the current service is an actual service or a conditional */
+        if(miss[activeMission].services[i].name.compare("if") && \
+                miss[activeMission].services[i].name.compare("dowhile") && \
+                miss[activeMission].services[i].name.compare("shell")) {
+                /* ifit is a service, search the database of registered services to find 
+                 * the ID of the component that registered it */
+                services_DB->command="select ";
+                services_DB->command.append(services_DB->tablename);
+                services_DB->command.append(".* from ");
+                services_DB->command.append( services_DB->tablename);
+                services_DB->command.append(" where Service_Name=='");
+                services_DB->command.append(miss[activeMission].services[i].name);
+                services_DB->command.append("';");
+    
+                sqlite3_stmt * pStatement;
+                int32_t rc = sqlite3_prepare_v2(services_DB->db, services_DB->command.c_str(), \
+                        -1, &pStatement, NULL);
+                if(rc == SQLITE_OK) { 
+                    if(sqlite3_step(pStatement) == SQLITE_ROW)
+                        miss[activeMission].services[i].componentID = sqlite3_column_int(pStatement, 0); 
+                    else {
+                        WARNING("services_DB:: Mission requires service %s ", \
+                                miss[activeMission].services[i].name.c_str());
+                        WARNING("not provided by any connected component.\n");
+                        rc = 31337;
+                    }
+                } else {
+                    WARNING("services_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                            rc, services_DB->command.c_str());
+                }
+
+                sqlite3_finalize(pStatement);
+                miss[activeMission].services[i].socketFD = \
+                    CE_List[miss[activeMission].services[i].componentID].FD;
+        }
+        /* TODO Nothing to be done for conditionals at this stage */
+    }
+ 
+    SendMessage(shellSocketFD, "ack");
+    LOG("ServiceManagementLayer:: Done setting active mission.\n");
+}
+
+
+/* CALLED BY: PerformActiveMission
+ * INPUTS: |sourceID| ID of the service that is being processed
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: This is a helper method for the "PerformActiveMission" function
+ * NOTE: This function has changed drastically from the previous implementation
+ * 
+ * Takes an ID of a service. For that service, finds inputs in DB and forwords 
+ * those on to the engine after sending comm-starting messages. Afterwords, listenes 
+ * for the outputs so that it can store those in the database for future services or 
+ * the overall output
+ */
+void
+ServiceManagementLayer::TransactData(int32_t sourceID)
+{
+    char buffer[256];
+    std::string data;
+    char *token;
+
+   /* Send a message directly to the shell */
+   if(miss[activeMission].services[sourceID].name.find("shell") != string::npos) {
+       shellUsed=true;
+
+       int32_t k = 0;
+       while((k < 10) && (!miss[activeMission].input[k].empty())) {
+           k++;
+       }
+
+       sprintf(buffer, "%d", k);
+       SendMessage(shellSocketFD, buffer);
+       for(int32_t t = 0; t < k; t++) {
+           memset(buffer, 0 , 256);
+           data_DB->command="select ";
+           data_DB->command.append(data_DB->tablename);
+           data_DB->command.append(".* from ");
+           data_DB->command.append(data_DB->tablename);
+           data_DB->command.append(" where Tag=='");
+           data_DB->command.append(miss[activeMission].input[t]);
+           data_DB->command.append("';");
+           sqlite3_stmt * pStatement;
+
+           int32_t rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), \
+                   -1, &pStatement, NULL);
+           if(rc == SQLITE_OK) { 
+               if(sqlite3_step(pStatement) == SQLITE_ROW)
+                   data=((const char*) sqlite3_column_text(pStatement, 1)); 
+               else {
+                   LOG("3data_DB:: Data not yet in DB., %s\n", data_DB->command.c_str());
+                   rc = 31337;
+               }
+           } 
+           else {
+               WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                       rc,data_DB->command.c_str());
+           }
+
+           sqlite3_finalize(pStatement);
+           token = strtok((char *) data.c_str(), "@");
+           token = strtok(NULL, "@");
+           SendMessage(shellSocketFD, token);
+           token = strtok(NULL, "@");
+           SendMessage(shellSocketFD, token);
+       }
+
+       return;
+   } 
+
+    /* ifthis is a service command and not a shell command... */
+    /* Transmission starting messages */
+    SendMessage(miss[activeMission].services[sourceID].socketFD, "request_optimization_service");
+    SendMessage(miss[activeMission].services[sourceID].socketFD, \
+            miss[activeMission].services[sourceID].name.c_str());
+}
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: This function works by first sending the inputs from the shell to 
+ * the appropriate components. The first service should begin immeadiately, as 
+ * should any others who have all of their input parameters. When they complete, 
+ * the output path is found and the data is transfered as it becomes available
+ * Presumably at this point the second function has all of it's parameters, so it 
+ * begins to compute, and the cycle repeats.
+ * 
+ * Rules for active missions (currently)
+ * -Five inputs/outputs per service and per mission
+ * -All ordering constraints have been relaxed in this version; all data is stored 
+ *  locally and only sent when requested
+ * -ifand while support fully implemented - up to three levels (if's can be nested, but dowhiles cannot)
+ * -For dowhiles, assumes loop condition determined on last line
+ *
+ * -IMPORTANT: DB uses '@' to seperate individual statements; using '@' in the data 
+ *  stream will result in incorrect behavior
+ */
+void
+ServiceManagementLayer::PerformActiveMission()
+{
+    shellUsed = false;
+    std::string data_param;
+    std::string data_obsv;
+    std::string data;
+    std::string input;
+    std::string check;
+
+    char buffer[256];
+    char buffer1[256];
+    std::string token, token2;
+    std::string data2;
+
+    int32_t rc;
+    char *errorMsg;
+
+    LOG("ServiceManagementLayer:: Received PerformActiveMission command.\n");
+
+    /* Get the inputs */
+    memset(buffer, 0, 256);
+    ReadMessage(shellSocketFD, buffer);
+
+    /* Receive Set of Parameters */
+    memset(buffer, 0, 256);
+    ReadMessage(shellSocketFD, buffer);
+    int32_t t = atoi(buffer);
+    for(size_t m = 0; m < t; m++) {
+        memset(buffer1, 0, 256);
+        ReadMessage(shellSocketFD, buffer1);
+        data_DB->command="insert into ";
+        data_DB->command.append(data_DB->tablename); 
+        data_DB->command.append(" (Tag, Data) ");
+
+        memset(buffer, 0, 256);
+        ReadMessage(shellSocketFD, buffer);
+        data_DB->command.append(" values('");
+        data_DB->command.append(buffer1);
+        data_DB->command.append("', '1@");
+        data_DB->command.append(buffer1);
+        data_DB->command.append("@");
+        data_DB->command.append(buffer);
+        data_DB->command.append("');");
+
+        rc = sqlite3_exec(data_DB->db, data_DB->command.c_str(), callback, 0, &errorMsg);
+        if((rc != SQLITE_OK) && (rc != 101))
+           WARNING("SQL error: %s\n", errorMsg);
+    }
+
+    int32_t numstatements[3] = {0 ,0 ,0};
+    for(size_t i; i < miss[activeMission].numServices; i++) {
+        if(miss[activeMission].services[i].name.compare("if") == 0) {
+            input.clear();
+            check.clear();
+
+            for(size_t t = 0; t < 10; t++) {
+                if(!miss[activeMission].services[i].output[t].empty()) {
+                    input = miss[activeMission].services[i - numstatements[0] - 1].output[t];
+
+                    data_DB->command="SELECT ";
+                    data_DB->command.append(data_DB->tablename);
+                    data_DB->command.append(".* from ");
+                    data_DB->command.append(data_DB->tablename);
+                    data_DB->command.append(" where Tag=='");
+                    data_DB->command.append(input);
+                    data_DB->command.append("';");
+
+                    sqlite3_stmt *pStatement;
+                    rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), \
+                            -1, &pStatement, NULL);
+                    if(rc == SQLITE_OK) { 
+                        if(sqlite3_step(pStatement) == SQLITE_ROW)
+                             data = (const char *) sqlite3_column_text(pStatement, 1); 
+                        else {
+                            WARNING("1 data_DB:: Data not yet in DB.\n");
+                            rc=31337;
+                        }
+                    } else {
+                        WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                rc,data_DB->command.c_str());
+                    }
+
+                    sqlite3_finalize(pStatement);
+                    int32_t pos = data.find_last_of("@", data.length() - 2);
+                    token = data.substr(pos + 1);
+                    token.erase(token.length() - 1);
+                    data.clear();
+                    break;
+                }
+            }
+
+            bool doit = false;
+            if(miss[activeMission].services[i].output[t].find(">") != string::npos) {
+                std::string data2;
+                data_DB->command="SELECT ";
+                data_DB->command.append(data_DB->tablename);
+                data_DB->command.append(".* from ");
+                data_DB->command.append(data_DB->tablename);
+                data_DB->command.append(" where Tag=='");
+                data_DB->command.append(miss[activeMission].services[i].output[t].erase(0, 1));
+                data_DB->command.append("';");
+                sqlite3_stmt *pStatement;
+
+                rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), \
+                        -1, &pStatement, NULL);
+                if(rc == SQLITE_OK) { 
+                    if(sqlite3_step(pStatement) == SQLITE_ROW)
+                         data2 = (const char *) sqlite3_column_text(pStatement, 1); 
+                    else {
+                        WARNING("2 data_DB:: Data not yet in DB.\n");
+                        rc = 31337;
+                    }
+                } else {
+                    WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                            rc, data_DB->command.c_str());
+                }
+
+                sqlite3_finalize(pStatement);
+
+                int32_t pos = data2.find_last_of("@", data2.length() - 2);
+                token2 = data2.substr(pos + 1);
+                token2.erase(token2.length() - 1);
+                if(atof(token.c_str()) > atof(token2.c_str()))
+                    doit = true;
+            }
+            else if(miss[activeMission].services[i].output[t].find(token) != string::npos)
+                doit = true;
+
+            if(doit) {
+                for(size_t k = i + 1; k <= i+miss[activeMission].services[i].num_conds; k++) { 
+                    if(miss[activeMission].services[k].name.compare("if") == 0) {
+                        input.clear();
+                        check.clear();
+                        for(size_t t = 0; t < 10; t++) {
+                            if(!miss[activeMission].services[k].output[t].empty()) {
+                                input = miss[activeMission].services[k - numstatements[1] - 1].output[t];
+                                data_DB->command="SELECT ";
+                                data_DB->command.append(data_DB->tablename);
+                                data_DB->command.append(".* from ");
+                                data_DB->command.append(data_DB->tablename);
+                                data_DB->command.append(" where Tag=='");
+                                data_DB->command.append(input);
+                                data_DB->command.append("';");
+
+                                sqlite3_stmt *pStatement;
+                                rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), \
+                                        -1, &pStatement, NULL);
+                                if(rc == SQLITE_OK) { 
+                                    if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                         data = (const char *) sqlite3_column_text(pStatement, 1); 
+                                    else {
+                                        WARNING("3 data_DB:: Data not yet in DB.\n");
+                                        rc = 31337;
+                                    }
+                                } else {
+                                    WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                            rc,data_DB->command.c_str());
+                                }
+
+                                sqlite3_finalize(pStatement);
+                                int32_t pos = data.find_last_of("@", data.length() - 2);
+                                token = data.substr(pos + 1);
+                                token.erase(token.length() - 1);
+                                break;
+                            }
+                        }
+
+                        bool doit = false;
+                        if(miss[activeMission].services[k].output[t].find(">") != string::npos) {
+                            std::string data2;
+                            data_DB->command="SELECT ";
+                            data_DB->command.append(data_DB->tablename);
+                            data_DB->command.append(".* from ");
+                            data_DB->command.append(data_DB->tablename);
+                            data_DB->command.append(" where Tag=='");
+                            data_DB->command.append(miss[activeMission].services[k].output[t].erase(0, 1));
+                            data_DB->command.append("';");
+
+                            sqlite3_stmt *pStatement;
+                            rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), \
+                                    -1, &pStatement, NULL);
+                            if(rc == SQLITE_OK) { 
+                                if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                     data2 = (const char *) sqlite3_column_text(pStatement, 1); 
+                                else {
+                                    WARNING("4 data_DB:: Data not yet in DB.\n");
+                                    rc = 31337;
+                                }
+                            } else {
+                                WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                        rc, data_DB->command.c_str());
+                            }
+
+                            sqlite3_finalize(pStatement);
+                            int32_t pos = data2.find_last_of("@", data2.length() - 2);
+                            token2 = data2.substr(pos + 1);
+                            token2.erase(token2.length() - 1);
+                            if(atof(token.c_str()) > atof(token2.c_str()))
+                                doit = true;
+                        }
+                        else if(miss[activeMission].services[k].output[t].find(token) != string::npos)
+                            doit=true;
+
+                        if(doit) {
+                            for(size_t j = k + 1; j <= k+miss[activeMission].services[k].num_conds; j++) { 
+                                if(miss[activeMission].services[j].name.compare("if") == 0) {
+                                    input.clear();
+                                    check.clear();
+                                    for(t = 0; t < 10; t++) {
+                                        if(!miss[activeMission].services[j].output[t].empty()) {
+                                            input = miss[activeMission].services[j - numstatements[2] - 1].output[t];
+
+                                            data_DB->command="SELECT ";
+                                            data_DB->command.append(data_DB->tablename);
+                                            data_DB->command.append(".* from ");
+                                            data_DB->command.append(data_DB->tablename);
+                                            data_DB->command.append(" where Tag=='");
+                                            data_DB->command.append(input);
+                                            data_DB->command.append("';");
+
+                                            sqlite3_stmt *pStatement;
+
+                                            rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), -1, &pStatement, NULL);
+                                            if(rc == SQLITE_OK) { 
+                                                if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                                     data = (const char *) sqlite3_column_text(pStatement, 1); 
+                                                else {
+                                                    WARNING("5 data_DB:: Data not yet in DB.\n");
+                                                    rc = 31337;
+                                                }
+                                            } else {
+                                                WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                                        rc, data_DB->command.c_str());
+                                            }
+
+                                            sqlite3_finalize(pStatement);
+                                            int32_t pos = data.find_last_of("@", data.length()-2);
+                                            token = data.substr(pos+1);
+                                            token.erase(token.length()-1);
+                                            data.clear();
+                                            break;
+                                        }
+                                    }
+
+                                    bool doit = false;
+                                    if(miss[activeMission].services[j].output[t].find(">") != string::npos) {
+                                        data_DB->command="SELECT ";
+                                        data_DB->command.append(data_DB->tablename);
+                                        data_DB->command.append(".* from ");
+                                        data_DB->command.append(data_DB->tablename);
+                                        data_DB->command.append(" where Tag=='");
+                                        data_DB->command.append(miss[activeMission].services[j].output[t].erase(0, 1));
+                                        data_DB->command.append("';");
+
+                                        sqlite3_stmt *pStatement;
+                                        rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), -1, &pStatement, NULL);
+                                        if(rc == SQLITE_OK) { 
+                                            if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                                 data2 = (const char *) sqlite3_column_text(pStatement, 1); 
+                                            else {
+                                                WARNING("6 data_DB:: Data not yet in DB.\n");
+                                                rc=31337;
+                                            }
+                                        } else {
+                                            WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                                    rc, data_DB->command.c_str());
+                                        }
+
+                                        sqlite3_finalize(pStatement);
+
+                                        int32_t pos = data2.find_last_of("@", data2.length()-2);
+                                        token2 = data2.substr(pos + 1);
+                                        token2.erase(token2.length()-1);
+
+                                        if(atof(token.c_str()) > atof(token2.c_str()))
+                                            doit=true;
+
+                                        data.clear();
+                                    }
+
+                                    else if(miss[activeMission].services[j].output[t].find(token) != string::npos)
+                                        doit = true;
+
+                                    if(doit) {
+                                        for(size_t l = j + 1; l <= j + miss[activeMission].services[j].num_conds; l++) { 
+                                            TransactData(l);
+                                        }
+                                    }
+
+                                    numstatements[2] += miss[activeMission].services[j].num_conds + 1;
+                                    j += miss[activeMission].services[j].num_conds;
+                                } else if(miss[activeMission].services[j].name.compare("dowhile") == 0) {
+                                    numstatements[0]=0;
+
+                                    while(true) {
+                                        uint32_t l;
+                                        for(l = j + 1; l <= j+miss[activeMission].services[j].num_conds; l++) { 
+                                            TransactData(l);
+                                        }
+
+                                        data.clear();
+                                        input.clear();
+                                        check.clear();
+
+                                        int32_t t;
+                                        for(t = 0; t < 10; t++) {
+                                            if(!miss[activeMission].services[j].output[t].empty()){
+                                                input=miss[activeMission].services[l-2].output[t];
+                                                data_DB->command="SELECT ";
+                                                data_DB->command.append(data_DB->tablename);
+                                                data_DB->command.append(".* from ");
+                                                data_DB->command.append(data_DB->tablename);
+                                                data_DB->command.append(" where Tag=='");
+                                                data_DB->command.append(input);
+                                                data_DB->command.append("';");
+                                                sqlite3_stmt *pStatement;
+
+                                                rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), -1, &pStatement, NULL);
+                                                if(rc == SQLITE_OK){ 
+                                                    if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                                         data = (const char *) sqlite3_column_text(pStatement, 1); 
+                                                    else {
+                                                        WARNING("7 data_DB:: Data not yet in DB.: %s\n", data_DB->command.c_str());
+                                                        rc = 31337;
+                                                    }
+                                                } else {
+                                                    WARNING("data_DB:: SQL statement error. rc = %i\n%s\n", \
+                                                            rc, data_DB->command.c_str());
+                                                }
+
+                                                sqlite3_finalize(pStatement);
+                                                int32_t pos = data.find_last_of("@", data.length() - 2);
+                                                token = data.substr(pos + 1);
+                                                token.erase(token.length() - 1);
+                                                break;
+                                            }
+                                        }
+
+                                        if(miss[activeMission].services[j].output[t].find(token) == string::npos) {
+                                            break;
+                                        }
+                                    }
+
+                                    j += miss[activeMission].services[j].num_conds;
+                                } else {
+                                    numstatements[2] = 0;
+                                    TransactData(j);
+                                }
+                            }
+                        }
+
+                        numstatements[1] += miss[activeMission].services[k].num_conds + 1;
+                        k += miss[activeMission].services[k].num_conds;
+                    } else if(miss[activeMission].services[k].name.compare("dowhile") == 0) {
+                        numstatements[0] = 0;
+                        while(true) {
+                            int32_t j;
+                            for(j = k + 1; j <= k + miss[activeMission].services[k].num_conds; j++) {
+                                TransactData(j);
+                            }
+
+                            data.clear();
+                            input.clear();
+                            check.clear();
+                            int32_t t;
+                            for(t = 0; t < 10; t++) {
+                                if(!miss[activeMission].services[k].output[t].empty()) {
+                                    input = miss[activeMission].services[j - 1].output[t];
+                                    data_DB->command="SELECT ";
+                                    data_DB->command.append(data_DB->tablename);
+                                    data_DB->command.append(".* from ");
+                                    data_DB->command.append(data_DB->tablename);
+                                    data_DB->command.append(" where Tag=='");
+                                    data_DB->command.append(input);
+                                    data_DB->command.append("';");
+
+                                    sqlite3_stmt *pStatement;
+                                    rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), -1, &pStatement, NULL);
+                                    if(rc == SQLITE_OK) { 
+                                        if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                             data = (const char *) sqlite3_column_text(pStatement, 1); 
+                                        else {
+                                            WARNING("8 data_DB:: Data not yet in DB.\n");
+                                            rc = 31337;
+                                        }
+                                    } else {
+                                        WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                                rc, data_DB->command.c_str());
+                                    }
+
+                                    sqlite3_finalize(pStatement);
+                                    int32_t pos = data.find_last_of("@", data.length() - 2);
+                                    token = data.substr(pos + 1);
+                                    token.erase(token.length() - 1);
+                                    break;
+                                }
+                            }
+
+                            if(miss[activeMission].services[k].output[t].find(token) == string::npos) {
+                                break;
+                            }
+                        }
+
+                        k += miss[activeMission].services[k].num_conds;
+                    } else{
+                        numstatements[1] = 0;
+                        TransactData(k);
+                    }
+                }
+            }
+
+            numstatements[0] += miss[activeMission].services[i].num_conds + 1;
+            i += miss[activeMission].services[i].num_conds;
+        } else if(miss[activeMission].services[i].name.compare("dowhile") == 0) {
+            numstatements[0] = 0;
+            while(true) {
+                uint32_t k;
+                for(k = i + 1; k <= i + miss[activeMission].services[i].num_conds; k++){ 
+                    TransactData(k);
+                }
+
+                data.clear();
+                input.clear();
+                check.clear();
+                int32_t t;
+                for(t = 0; t < 10; t++){
+                    if(!miss[activeMission].services[i].output[t].empty()) {
+                        input = miss[activeMission].services[k - 1].output[t];
+                        data_DB->command="SELECT ";
+                        data_DB->command.append(data_DB->tablename);
+                        data_DB->command.append(".* from ");
+                        data_DB->command.append(data_DB->tablename);
+                        data_DB->command.append(" where Tag=='");
+                        data_DB->command.append(input);
+                        data_DB->command.append("';");
+
+                        sqlite3_stmt *pStatement;
+                        rc = sqlite3_prepare_v2(data_DB->db, data_DB->command.c_str(), -1, &pStatement, NULL);
+                        if(rc == SQLITE_OK) { 
+                            if(sqlite3_step(pStatement) == SQLITE_ROW)
+                                 data = (const char *) sqlite3_column_text(pStatement, 1); 
+                            else {
+                                WARNING("10data_DB:: Data not yet in DB.\n");
+                                rc = 31337;
+                            }
+                        } else {
+                            WARNING("data_DB:: Error executing SQL statement. rc = %i\n%s\n", \
+                                    rc, data_DB->command.c_str());
+                        }
+
+                        sqlite3_finalize(pStatement);
+                        int32_t pos = data.find_last_of("@", data.length()-2);
+                        token = data.substr(pos + 1);
+                        token.erase(token.length() - 1);
+                        break;
+                    }
+                }
+
+                if(miss[activeMission].services[i].output[t].find(token) == string::npos) {
+                    break;
+                }
+            }
+
+            i += miss[activeMission].services[i].num_conds;
+        } else{
+            numstatements[0] = 0;
+            TransactData(i);
+        }
+    }
+
+    int32_t i = 0;
+    data.clear();
+
+    if(!shellUsed) {
+        int k = 0;
+        while(k < 10 && !miss[activeMission].input[k].empty()) {
+            k++;
+        }
+
+        sprintf(buffer, "%d", k);
+        SendMessage(shellSocketFD, buffer);
+
+        for(size_t t = 0; t < k; t++) {
+            SendMessage(shellSocketFD, miss[activeMission].input[t].c_str()); 
+            SendMessage(shellSocketFD, "0");
+        }
+    }
+
+    LOG("ServiceManagementLayer:: Done performing active mission.\n");
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Print a list of the services currently registered and the ID's of the components that registered them
+ */
+void 
+ServiceManagementLayer::ListServices()
+{
+    services_DB->command="select ";
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append(".* from ");
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append(";");
+
+    // Execute print (select all) command
+    char *errorMsg;
+    int32_t rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("SQL error: %s\n", errorMsg);
+
+    LOG("database %s, table %s:\n", services_DB->filename.c_str(), services_DB->tablename.c_str());
+}
+
+
+/* CALLED BY: Reset
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Clear and reinitialize the mission array, then reload the configuration file
+ */
+void 
+ServiceManagementLayer::ReloadConfiguration()
+{
+    LOG("ServiceManagementLayer:: Reloading Configuration.\n");
+
+    free(miss);
+
+    miss = new Mission[10];
+    for(size_t i = 0; i < 10; i++)
+        miss[i].services = new Service[30];
+
+    LoadConfiguration(_SML_Config.c_str(), miss);
+}
+
+
+/* CALLED BY: constructor
+ * INPUTS: |SML_Config| Address (either relitive or full) of the XML file containing mission data
+ *        |mList| Mission array to be modified 
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: IMPORTANT - See formatting instructions for correct parsing of data
+ * Can currently handle 10 inputs and 10 outputs per service, but easily expandable
+ * Also, can handle two layer of nested conditional statements, but could
+ * be expanded to meet additional needs.
+ * 
+ * Components assigned to mission during "set active mission" stage so that
+ * components can still continue to register after the configuration is loaded
+ */
+void 
+ServiceManagementLayer::LoadConfiguration(const char *SML_Config, Mission* &mList)
+{
+    TiXmlElement *pMission;
+    TiXmlElement *pService;
+    TiXmlElement *pChild0, *pChild1, *pChild2, *pChild3, *pChild4;
+    TiXmlHandle hRoot(0);
+
+    LOG("ServiceManagementLayer:: Loading Configuration.\n");
+
+    TiXmlDocument doc(".");
+    doc.LoadFile(SML_Config);
+    bool loadOkay = doc.LoadFile();
+    if(!loadOkay)
+        WARNING("Loading SML configuration failed: %s\n", SML_Config);
+
+    TiXmlHandle hDoc(&doc);
+    
+    pMission = hDoc.FirstChildElement().Element();
+
+    if(!pMission) 
+        WARNING("No valid root!");
+
+    hRoot = TiXmlHandle(pMission);
+    pService = pMission->FirstChildElement();
+
+    int32_t mission_num = 0;
+
+    /* Iterate through the missions */
+    for(pChild0 = pMission->FirstChildElement(); pChild0 ; pChild0 = pChild0->NextSiblingElement())  {
+        int32_t service_num = 0;
+        uint16_t cond_array[] = {0, 0, 0};
+    
+        for(pChild1  = (pChild0->FirstChildElement())->FirstChildElement(); pChild1; \
+                pChild1  = pChild1->NextSiblingElement()) {
+
+            int32_t conditional_0 = service_num;
+            for(pChild2 = pChild1->FirstChildElement(); pChild2; pChild2 = pChild2->NextSiblingElement()) {
+                service_num++;
+
+                int32_t conditional_1 = service_num;
+                for(pChild3 = pChild2->FirstChildElement(); pChild3; pChild3 = pChild3->NextSiblingElement()) {
+                    service_num++;
+                    int32_t conditional_2 = service_num;
+                    for(pChild4 = pChild3->FirstChildElement(); pChild4; pChild4 = pChild4->NextSiblingElement()) {
+                        service_num++;
+                        if(pChild4->Attribute("name"))
+                            mList[mission_num].services[service_num].name = pChild4->Attribute("name");
+                        else
+                            mList[mission_num].services[service_num].name = pChild4->Value();
+
+                        for(size_t i = 1; i <= 10; i++) {
+                            char buffer[9]="input";
+                            sprintf(buffer, "%s%d", buffer, i); 
+                            if(pChild4->Attribute(buffer))
+                                mList[mission_num].services[service_num].input[i - 1] = pChild4->Attribute(buffer);
+
+                            char buffer2[9]="output";
+                            sprintf(buffer2, "%s%d", buffer2, i); 
+                            if(pChild4->Attribute(buffer2))
+                                mList[mission_num].services[service_num].output[i - 1] = pChild4->Attribute(buffer2);
+                        }
+
+                        if(pChild4->Attribute("parameter"))
+                            mList[mission_num].services[service_num].parameter = pChild4->Attribute("parameter");
+
+                        cond_array[2]++;
+                    }
+
+                    if(!strcmp(pChild3->Value(), "shell") || conditional_2 != service_num) {
+                        mList[mission_num].services[conditional_2].name = pChild3->Value();
+                    } else {
+                        mList[mission_num].services[service_num].name = pChild3->Attribute("name");
+                    }
+
+                    for(size_t i = 1; i <= 10; i++) {
+                        char buffer[9]="input";
+                        sprintf(buffer, "%s%d", buffer, i); 
+                        if(pChild3->Attribute(buffer))
+                            mList[mission_num].services[conditional_2].input[i - 1] = pChild3->Attribute(buffer);
+
+                        char buffer2[9]="output";
+                        sprintf(buffer2, "%s%d", buffer2, i); 
+                        if(pChild3->Attribute(buffer2))
+                            mList[mission_num].services[conditional_2].output[i - 1] = pChild3->Attribute(buffer2);
+                    }
+
+                    if(pChild3->Attribute("parameter"))
+                        mList[mission_num].services[conditional_2].parameter = pChild3->Attribute("parameter");
+
+                    mList[mission_num].services[conditional_2].num_conds = cond_array[2];
+                    cond_array[1] += cond_array[2] + 1;
+                    cond_array[2] = 0;
+                }
+
+                if(!strcmp(pChild2->Value(), "shell") || (conditional_1 != service_num)) {
+                    mList[mission_num].services[conditional_1].name = pChild2->Value();
+                } else{
+                    mList[mission_num].services[service_num].name = pChild2->Attribute("name");
+                }
+
+                for(int i = 1; i <= 10; i++) {
+                    char buffer[9]="input";
+                    sprintf(buffer, "%s%d", buffer, i); 
+                    if(pChild2->Attribute(buffer))
+                        mList[mission_num].services[conditional_1].input[i - 1] = pChild2->Attribute(buffer);
+
+                    char buffer2[9]="output";
+                    sprintf(buffer2, "%s%d", buffer2, i); 
+                    if(pChild2->Attribute(buffer2))
+                        mList[mission_num].services[conditional_1].output[i - 1] = pChild2->Attribute(buffer2);
+                }
+
+                if(pChild2->Attribute("parameter"))
+                    mList[mission_num].services[conditional_1].parameter = pChild2->Attribute("parameter");
+
+                mList[mission_num].services[conditional_1].num_conds = cond_array[1];
+                cond_array[0] += cond_array[1] + 1;
+                cond_array[1] = 0;
+            }
+        
+            if(!strcmp(pChild1->Value(), "shell") || conditional_0 != service_num) {
+                mList[mission_num].services[conditional_0].name = pChild1->Value();
+            } else{
+                mList[mission_num].services[conditional_0].name = pChild1->Attribute("name");
+            }
+
+            for(size_t i = 1; i <= 10; i++) {
+                char buffer[9]="input";
+                sprintf(buffer, "%s%d", buffer, i); 
+                if(pChild1->Attribute(buffer))
+                    mList[mission_num].services[conditional_0].input[i-1] = pChild1->Attribute(buffer);
+
+                char buffer2[9]="output";
+                sprintf(buffer2, "%s%d", buffer2, i); 
+                if(pChild1->Attribute(buffer2))
+                    mList[mission_num].services[conditional_0].output[i-1] = pChild1->Attribute(buffer2);
+            }
+
+            if(pChild1->Attribute("parameter"))
+                mList[mission_num].services[conditional_0].parameter = pChild1->Attribute("parameter");
+            mList[mission_num].services[conditional_0].num_conds = cond_array[0];
+                cond_array[0] = 0;
+
+            service_num++;
+        }
+    
+        mList[mission_num].numServices = service_num;
+        mList[mission_num].name = pChild0->Attribute("name");
+        mList[mission_num].missionID = atoi(pChild0->Attribute("id"));
+
+        for(size_t i = 1; i <= 10; i++) {
+            char buffer[9]="param";
+            sprintf(buffer, "%s%d", buffer, i); 
+            if(pChild0->Attribute(buffer)){
+                mList[mission_num].input[i-1] = pChild0->Attribute(buffer);
+            }
+        }
+
+        mission_num++;
+    }
+
+    LOG("ServiceManagementLayer:: Done Loading Configuration\n");
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: |ID| The ID number of the engine to be registered
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Sends a registration message onto the shell and sends the ACK back to the component
+ */
+void
+ServiceManagementLayer::RegisterCognitiveEngine(int32_t ID)
+{
+    SendMessage(shellSocketFD, "register_engine_cognitive");
+
+    LOG("ServiceManagementLayer:: CE registration message forwarded to shell.\n");
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(shellSocketFD, buffer);
+    SendMessage(CE_List[ID].FD, buffer);
+
+    TransferRadioConfiguration(ID);
+    memset(buffer, 0, 256);
+    TransferExperience(ID);
+    memset(buffer, 0, 256);
+    numberOfCognitiveEngines++;
+    CE_Present = true;
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: |ID| The ID number of the engine to have it's services deregistered
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Deletes individual services from the DB
+ * NOTE THAT this function only needs to be called ifservice deregistration is going
+ * to be done at a different time than component deregistration; it is handled
+ * more efficiently and directly during that deregistration process.
+ */
+void 
+ServiceManagementLayer::DeregisterServices(int32_t ID)
+{
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(CE_List[ID].FD, buffer); 
+    services_DB->command="DELETE FROM ";
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append(" WHERE ID_Num IN (SELECT ");
+
+    char tmp[3];
+    memset(tmp,0,3);
+    sprintf(tmp, "%d", ID);
+    services_DB->command.append(tmp);
+    services_DB->command.append(" FROM ");
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append(" WHERE Service_Name");
+    services_DB->command.append("=='");
+    services_DB->command.append(buffer);
+    services_DB->command.append("');");
+
+    char *errorMsg;
+    int32_t rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("SQL error: %s\n", errorMsg);
+}
+
+
+/* CALLED BY: MessageHandler
+ * INPUTS: |ID| The ID number of the engine to have it's services deregistered
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Deletes the contact info for the cognitive engine, forwards a deregistration message to the shell
+ * Also, deletes the services from the DB
+ */
+void 
+ServiceManagementLayer::DeregisterCognitiveEngine(int32_t ID)
+{
+    LOG("ServiceManagementLayer:: CE deregistration message forwarded to shell.\n");
+
+    numberOfCognitiveEngines--;
+    if(numberOfCognitiveEngines == 0)
+        CE_Present = false;
+
+    SendMessage(shellSocketFD, "deregister_engine_cognitive");
+    char buffer[256];
+    memset(buffer, 0, 256);
+    ReadMessage(shellSocketFD, buffer);
+    SendMessage(CE_List[ID].FD, buffer);
+    if(strcmp("deregister_ack", buffer) != 0) {
+        ERROR(1, "SML:: Failed to close CE socket\n");
+    }
+
+    //Deregister the services
+    services_DB->command="DELETE FROM ";
+    services_DB->command.append(services_DB->tablename);
+    services_DB->command.append(" WHERE ");
+    services_DB->command.append("ID_Num");
+    services_DB->command.append("==");
+
+    char tmp[3];
+    memset(tmp,0,3);
+    sprintf(tmp, "%d", ID);
+    services_DB->command.append(tmp);
+    services_DB->command.append(";");
+
+    char *errorMsg;
+    int32_t rc = sqlite3_exec(services_DB->db, services_DB->command.c_str(), callback, 0, &errorMsg);
+    if((rc != SQLITE_OK) && (rc != 101))
+        WARNING("SQL error: %s\n", errorMsg);
+
+    CE_List[ID].FD = -1;
+    CE_List[ID].ID_num = -1;
+
+    LOG("Cognitive Radio Shell:: CE Socket closed for engine #%d.\n", ID);
+}
+
+
+/* CALLED BY: test class
+ * INPUTS: <none>
+ * OUTPUTS: <none>
+ *
+ * DESCRIPTION: Sets up a server socket and listens for communication on either that or the shell socket
+ */
+void
+ServiceManagementLayer::StartSMLServer()
+{
+    struct timeval selTimeout;
+    int32_t running = 1;
+    int32_t port, rc, new_sd = 1;
+    int32_t desc_ready = 1;
+    fd_set sockSet, shellSet;
+
+    cogEngSrv = CreateTCPServerSocket(SMLport);
+    int32_t maxDescriptor = cogEngSrv;
+
+    if(InitializeTCPServerPort(cogEngSrv) == -1)
+        ERROR(1,"Error initializing primary port\n");
+
+    while (running) {
+        /* Zero socket descriptor vector and set for server sockets */
+        /* This must be reset every time select() is called */
+        FD_ZERO(&sockSet);
+        FD_SET(cogEngSrv, &sockSet);
+        
+        for(uint16_t k = 0; k < Current_ID; k++){
+            if(CE_List[k].ID_num != -1)
+                FD_SET(CE_List[k].FD, &sockSet);
+        }
+
+        /* Timeout specification */
+        /* This must be reset every time select() is called */
+        selTimeout.tv_sec = 0;      /* timeout (secs.) */
+        selTimeout.tv_usec = 0;     /* 0 microseconds */
+
+        /* Changed both to zero so that select will check messages from the shell
+         * instead of blocking when there is no command from the CE's to be processed */
+
+        /* Check ifthere is a message on the socket waiting to be read */
+        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout); 
+        if(rc == 0) {
+            FD_ZERO(&shellSet);
+            FD_SET(shellSocketFD, &shellSet);
+            selTimeout.tv_sec = 0;
+            selTimeout.tv_usec = 0;
+
+            /* Check if there is a message on the shell socket ready to be processed */
+            select(shellSocketFD + 1, &shellSet, NULL, NULL, &selTimeout);
+            if(FD_ISSET(shellSocketFD, &shellSet)){
+                MessageHandler(-1);}
+        } else { 
+            desc_ready = rc;
+            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
+                if(FD_ISSET(port, &sockSet)) {
+                    desc_ready -= 1;
+
+                    /* Check ifrequest is new or on an existing open descriptor */
+                    if(port == cogEngSrv) { 
+                        /* If new, assign it a descriptor and give it an ID */
+                        new_sd = AcceptTCPConnection(port);
+             
+                        if(new_sd < 0) 
+                            break;
+
+                        CE_List[Current_ID].FD = new_sd;
+                        CE_List[Current_ID].ID_num = Current_ID;
+                        MessageHandler(Current_ID);
+                        Current_ID++;
+    
+                        FD_SET(new_sd,&sockSet);
+                        if(new_sd > maxDescriptor) 
+                           maxDescriptor = new_sd;
+                    } else {
+                        /* If old, figure out which ID it coresponds to and handle it accordingly */
+                        for(size_t z = 0; z < Current_ID; z++) {
+                            if(CE_List[z].FD == port) {
+                                MessageHandler(z);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }        
+
+    /* Close sockets */
+    close(cogEngSrv);
+
+    return;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/Makefile.am	(revision 429)
+++ vtcross/branches/nikhil/crossmodel2/src/Makefile.am	(revision 429)
@@ -0,0 +1,19 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+
+SUBDIRS = lib include policy_engines cognitive_engines service_management_layer \
+		  libvtcross shell
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross_demo.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross_demo.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross_demo.cpp	(revision 554)
@@ -0,0 +1,96 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+
+#include <cstdlib>
+#include <cstring>
+#include <stdint.h>
+
+#include "vtcross/debug.h"
+#include "vtcross/error.h"
+#include "vtcross/libvtcross.h"
+#include "vtcross/socketcomm.h"
+#include <iostream>
+
+int32_t 
+main(int32_t argc, char *argv[])
+{
+    /* Set the location to localhost for this simple demo. */
+    SetCrossShellLocation("localhost", "40000");
+
+
+// need to include utilties also in system,.. 
+
+        Observable *o = new Observable[10];
+        Parameter *currentParameters = new Parameter[10];
+        Utility *u = new Utility[10];
+        Parameter *p;
+
+        uint32_t numParameters;
+        uint32_t numObservables;
+        uint32_t numUtilities;
+
+        u[0].name = "throughput";
+//        u[0].value = 15
+        u[1].name = "PER";
+//        u[1].value = 12.00;
+
+        numParameters = GetNum("parameters");
+        numObservables = GetNum("observables");
+        numUtilities = GetNum("utilities");
+
+
+// This is for loop for performing 10 cycles of updates.. with CBR
+    for(size_t i = 0; i < 10; i++) {
+
+        if(i == 0) {
+            currentParameters[0].name = "bandwidth";
+            currentParameters[0].value = 200.0;
+            currentParameters[1].name = "tx_power";
+            currentParameters[1].value = 10.0;
+        } else {
+            currentParameters[0].value = p[0].value;
+            currentParameters[1].value = p[1].value;
+        }
+
+        LOG("Application:: Requesting parameter optimization.\n");
+
+        p = GetOptimalParameters(o,0,currentParameters,2,u,2);
+
+        LOG("Application:: Received the following parameters.\n");
+        
+        for(size_t i = 0; i < numParameters; i++) {
+            LOG("%s:: %f\n", p[i].name.c_str(), p[i].value);
+        }
+
+///        Try them out! Do they work? 
+        u[0].value = 2*p[0].value + 1*p[1].value + ((rand()*2.0/RAND_MAX - 1)*10.0);
+        u[1].value = 12-p[0].value/50 - p[1].value/3 + ((rand()*2.0/RAND_MAX - 1.0)*0.1);
+
+	if (u[1].value < 0) 
+		u[1].value = 0; 
+
+	LOG("utilities\n %s : %f \n %s : %f \n",u[0].name.c_str(),u[0].value,u[1].name.c_str(),u[1].value);	
+
+        UpdateParameterPerformance(p, numParameters, o, numObservables, u, numUtilities);    
+
+	usleep(1000);        
+ 
+    }
+
+    return 0;
+}
+
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/Makefile.am	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/Makefile.am	(revision 554)
@@ -0,0 +1,29 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+lib_LTLIBRARIES = libvtcross.la
+bin_PROGRAMS = libvtcross_demo 
+
+libvtcross_la_SOURCES = libvtcross.cpp
+libvtcross_la_LDFLAGS = -version-info 1:0:0
+libvtcross_la_LIBADD = $(CROSS_SOCKETCOMM_LA) 
+
+libvtcross_demo_SOURCES = libvtcross_demo.cpp
+libvtcross_demo_LDADD = $(CROSS_LA) 
+
+SUBDIRS = . swig
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/libvtcross.i
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/libvtcross.i	(revision 439)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/libvtcross.i	(revision 439)
@@ -0,0 +1,78 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+%module cross
+%{
+#include "vtcross/libvtcross.h"
+#include "vtcross/containers.h"
+%}
+
+%typemap(in) uint32_t = int;
+
+%include "std_string.i"
+
+%include "vtcross/containers.h"
+%include "vtcross/libvtcross.h"
+
+%apply const std::string & { std::string * };
+
+%extend Parameter {
+
+    Parameter(int nparameters) {
+        Parameter * p = new Parameter[nparameters]; 
+        return p;
+    };
+
+    ~Parameter() {
+        delete [] $self;
+    };
+
+    Parameter *__getitem__(int i) {
+        return self+i;
+    };
+
+
+};
+
+%extend Observable {
+    Observable(int nobservables) {
+        Observable * o = new Observable[nobservables]; 
+        return o;
+    };
+
+    ~Observable() {
+        delete [] $self; 
+    };
+
+    Observable *__getitem__(int i) {
+        return self+i;
+    };
+};
+
+%extend Utility {
+    Utility(int nutilities) {
+        Utility * u = new Utility[nutilities]; 
+        return u;
+    };
+
+    ~Utility() {
+        delete [] $self;
+    };
+
+    Utility *__getitem__(int i) {
+        return self+i;
+    };
+};
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/__init__.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/__init__.py	(revision 412)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/__init__.py	(revision 412)
@@ -0,0 +1,16 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+from cross import *
+
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/Makefile.am	(revision 439)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/swig/Makefile.am	(revision 439)
@@ -0,0 +1,31 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+include $(top_srcdir)/Makefile.common
+
+BUILT_SOURCES = $(srcdir)/libvtcross_wrap.cpp
+SWIG_SOURCES = libvtcross.i
+
+INCLUDES = -I$(top_srcdir)/src/include
+
+pkgpython_PYTHON = cross.py __init__.py
+pkgpyexec_LTLIBRARIES = _cross.la
+
+_cross_la_SOURCES = libvtcross_wrap.cpp $(SWIG_SOURCES)
+_cross_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src/libvtcross
+_cross_la_LDFLAGS = -module -avoid-version
+_cross_la_LIBADD = $(CROSS_LA) $(CROSS_SOCKETCOMM_LA)
+
+$(srcdir)/libvtcross_wrap.cpp : $(SWIG_SOURCES)
+	$(SWIG) $(SWIG_PYTHON_OPT) $(INCLUDES) -o $@ $<
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/libcross_demo.py
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/libcross_demo.py	(revision 557)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/libcross_demo.py	(revision 557)
@@ -0,0 +1,76 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+
+# Simple Python demonstration script for using
+# the CROSS system.
+#
+# Use with demo.xml shell configuration file
+#   Instructions:
+# 	Start shell with demo.xml config from the examples directory
+#	Start cognitive engine
+#	Run this script
+#	
+
+from cross.cross import *
+
+import time
+
+def main():
+	CN1 = "localhost"
+	CN2 = "40000"
+
+	SetCrossShellLocation(CN1,CN2)
+
+	p = Parameter(2)
+	currentParameters = Parameter(2)
+	o = Observable(2)
+	u = Utility(2)
+
+	u[0].name = "throughput"
+	u[1].name = "PER"
+
+	numParameters = GetNum("parameters");
+	numObservables = GetNum("observables");
+	numUtilities = GetNum("utilities");
+
+	for i in range(0,10):
+		if i is 1:
+			currentParameters[0].name = "bandwidth"
+			currentParameters[0].value = 200.0 
+
+			currentParameters[1].name = "bandwidth"
+			currentParameters[1].value = 10.0 
+		else:
+			currentParameters[0].value = p[0].value 
+			currentParameters[1].value = p[1].value
+
+		print "Application:: Requesting parameter optimization"
+
+		p = GetOptimalParameters(o,0,currentParameters,2,u,2)
+
+		print "Application:: Receive the following parameters.\n"
+
+		u[0].value = 2*p[0].value + 1*p[1].value
+		u[1].value = 12 - p[0].value/50 - p[1].value/3
+
+		print "utilities " + u[0].name + " = " + str(u[0].value) + "\n"
+        	print "utilities " + u[1].name + " = " + str(u[1].value) + "\n"
+ 
+		time.sleep(0.5)
+
+		UpdateParameterPerformance(p, 2, o, 0, u, 2)
+
+if __name__ == "__main__":
+	main()
Index: vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross.cpp
===================================================================
--- vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross.cpp	(revision 554)
+++ vtcross/branches/nikhil/crossmodel2/src/libvtcross/libvtcross.cpp	(revision 554)
@@ -0,0 +1,187 @@
+/*
+ Copyright 2009 Virginia Polytechnic Institute and State University  
+
+ Licensed under the Apache License, Version 2.0 (the "License"); 
+ you may not use this file except in compliance with the License. 
+ You may obtain a copy of the License at 
+ 
+ http://www.apache.org/licenses/LICENSE-2.0 
+
+ Unless required by applicable law or agreed to in writing, software 
+ distributed under the License is distributed on an "AS IS" BASIS, 
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ See the License for the specific language governing permissions and 
+ limitations under the License. 
+*/
+
+/*! Implementation file for the VCROSS Cognitive Radio public API defined in
+ * include/libvtcross.h.
+ *
+ * libvtcross provides the interface that radio host platforms and applications
+ * use to talk to the CROSS radio system.  All external communication with the
+ * CROSS radio occurs through this library.
+ */
+
+#include <cstdlib>
+#include <string>
+
+#include "vtcross/common.h"
+#include "vtcross/debug.h"
+#include "vtcross/libvtcross.h"
+
+using namespace std;
+
+
+/* Strings that store the remote (or local) shell location for use within the
+ * ConnectToShell() function.  Note that these values must be set with the
+ * SetCrossShellLocation public function within the client code. */
+string shellHostname;
+string shellPort;
+
+
+uint32_t
+ConnectToShell()
+{
+    return ClientSocket(shellHostname.c_str(), shellPort.c_str());
+}
+
+
+void
+SetCrossShellLocation(string hostname, string port)
+{
+    shellHostname = hostname;
+    shellPort = port;
+}
+
+
+// TODO the following three functions all do exactly the same thing.  Why not
+// simply combine them?
+
+Parameter* 
+GetOptimalParameters(Observable *radioObservables, uint32_t numObservables, Parameter *currentParameters, uint32_t numCurrentParameters, Utility *radioUtilities, uint32_t numUtilities)
+{
+    char var[50];
+    char counter[55];
+    char buffer[256];
+
+    uint32_t socketFD = ConnectToShell();
+    SendMessage(socketFD, "request_optimization");
+
+    /* Get number of observables to send.  This information needs to be 
+     * sent to the Cognitive Radio Shell also.   
+     */
+
+    /* Send Observables */
+    sprintf(counter, "%i", numObservables);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < numObservables; i++) {
+        SendMessage(socketFD, radioObservables[i].name.c_str());
+        sprintf(var, "%f", radioObservables[i].value);
+        SendMessage(socketFD, var);    
+    }
+
+    /* Send Parameters */
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numCurrentParameters);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < numCurrentParameters; i++) {
+        SendMessage(socketFD,currentParameters[i].name.c_str());
+        sprintf(var,"%f",currentParameters[i].value);
+        SendMessage(socketFD,var);    
+    }
+
+    /* Send Utilities */
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numUtilities);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < numUtilities; i++) {
+        SendMessage(socketFD,radioUtilities[i].name.c_str());
+        sprintf(var,"%f",radioUtilities[i].value);
+        SendMessage(socketFD,var);
+    }
+	
+
+    /* Receive Set of Parameters */
+    memset(buffer, 0, 256);
+    ReadMessage(socketFD, buffer);
+    uint32_t numParameters = atoi(buffer);
+    Parameter *pList = new Parameter[numParameters];
+    
+    for(ssize_t i = 0; i < numParameters; i++) {
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        pList[i].name = std::string(buffer);
+        
+        memset(buffer, 0, 256);
+        ReadMessage(socketFD, buffer);
+        pList[i].value = atof(buffer);
+    }   
+
+    close(socketFD);
+    return pList;
+}
+
+bool
+UpdateParameterPerformance(Parameter *p, uint32_t numParameters, Observable *o, uint32_t numObservables, Utility *u, uint32_t numUtilities)
+{
+    char counter[55];
+    char var[50];
+
+    uint32_t socketFD = ConnectToShell();
+    SendMessage(socketFD, "update_performance");
+    
+    // Send Parameters 
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numParameters);
+    SendMessage(socketFD, counter);
+    
+    for(size_t i = 0; i < numParameters; i++) {
+        SendMessage(socketFD, p[i].name.c_str());
+        sprintf(var, "%f", p[i].value);
+        SendMessage(socketFD, var);    
+    }
+    
+    // Send Observables
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numObservables);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < numObservables; i++) {
+        SendMessage(socketFD, o[i].name.c_str());
+        sprintf(var, "%f", o[i].value);
+        SendMessage(socketFD, var);    
+    }
+
+    // Send Utilities
+    memset(counter, 0, 55);
+    sprintf(counter, "%i", numUtilities);
+    SendMessage(socketFD, counter);
+    for(size_t i = 0; i < numUtilities; i++) {
+	SendMessage(socketFD, u[i].name.c_str());
+	sprintf(var, "%f", u[i].value);
+	SendMessage(socketFD, var);
+    }
+	
+}
+
+uint32_t GetNum(string type)
+{
+
+	char buffer[256];
+	uint32_t socketfd = ConnectToShell();
+	
+	if (type == "parameters")
+		SendMessage(socketfd, "get_number_parameters");
+	else if (type == "utilities")
+		SendMessage(socketfd, "get_number_utilities");
+	else if (type == "observables")
+		SendMessage(socketfd, "get_number_observables");	
+	else
+		LOG("Type not included, either 'parameters' or 'utilities' or 'observables'");	
+
+	memset(buffer, 0, 256);
+	ReadMessage(socketfd, buffer);
+	uint32_t number = atoi(buffer);
+	return number;
+
+
+}
Index: vtcross/branches/nikhil/crossmodel2/COPYING
===================================================================
--- vtcross/branches/nikhil/crossmodel2/COPYING	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/COPYING	(revision 411)
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
Index: vtcross/branches/nikhil/crossmodel2/Makefile.am
===================================================================
--- vtcross/branches/nikhil/crossmodel2/Makefile.am	(revision 411)
+++ vtcross/branches/nikhil/crossmodel2/Makefile.am	(revision 411)
@@ -0,0 +1,21 @@
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+ACLOCAL_AMFLAGS = -I m4
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src doc
+
+
Index: vtcross/branches/nikhil/crossmodel2/reconf
===================================================================
--- vtcross/branches/nikhil/crossmodel2/reconf	(revision 429)
+++ vtcross/branches/nikhil/crossmodel2/reconf	(revision 429)
@@ -0,0 +1,34 @@
+#!/bin/sh
+# Copyright 2009 Virginia Polytechnic Institute and State University  
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at 
+# 
+# http://www.apache.org/licenses/LICENSE-2.0 
+#
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License. 
+
+echo -n "Running libtoolize... "
+libtoolize && \
+echo " done!"
+
+echo -n "Running aclocal... "
+aclocal -I config&& \
+echo " done!"
+
+echo -n "Running autoconf... "
+autoconf && \
+echo " done!"
+
+echo -n "Running autoheader... "
+autoheader && \
+echo " done!"
+
+echo -n "Running automake... "
+automake --add-missing
+echo " done!"
Index: vtcross/branches/nikhil/crossmodel2/README
===================================================================
--- vtcross/branches/nikhil/crossmodel2/README	(revision 430)
+++ vtcross/branches/nikhil/crossmodel2/README	(revision 430)
@@ -0,0 +1,19 @@
+# 
+# Virginia Tech Cognitive Radio Open Source Systems
+# 
+
+All files are handled by root-level autofoo magic. In the top-level directory,
+run the following commands to build the system:
+
+$ ./reconf
+$ ./configure
+$ make
+
+The system can be run in-place.  If you wish to install VTCROSS to your system,
+you may do so by issuing (as root) the command:
+
+# make install
+
+
+https://www.cornet.wireless.vt.edu/trac/wiki/Cross
+
