From a3df9dd120e963d043a1a2fcd7f5e1ead9bef8eb Mon Sep 17 00:00:00 2001
From: Dmitry Marakasov <amdmi3@amdmi3.ru>
Date: Thu, 1 Sep 2011 23:01:48 +0400
Subject: [PATCH 01/85] Fix bashisms in configure.ac

---
 configure.ac | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 25e73b4e3..1dcd3d14b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -530,7 +530,7 @@ case "${host}" in
 
 esac
 
-if test "$OPENAL_OK" == "no"; then
+if test "$OPENAL_OK" = "no"; then
     echo
     echo "You *must* have the openal library installed on your system to build"
     echo "SimGear!"
@@ -541,7 +541,7 @@ if test "$OPENAL_OK" == "no"; then
     exit
 fi
 
-if test "$ALUT_OK" == "no"; then
+if test "$ALUT_OK" = "no"; then
     echo
     echo "You *must* have the alut library installed on your system to build"
     echo "SimGear!"

From 065f4ee5cb141d34ffb7a21770738023436294fb Mon Sep 17 00:00:00 2001
From: Martin Spott <Martin.Spott@mgras.net>
Date: Mon, 5 Sep 2011 20:25:30 +0200
Subject: [PATCH 02/85] Make HLA configurable. Permit un-breaking of FlightGear
 CMake builds on setups with a working HLA RTI installed, accommodating with
 recent changes to SimGear CMake.

---
 CMakeLists.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8553454e..581cb638f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,6 +56,7 @@ option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
 option(ENABLE_FGADMIN "Set to ON to build FlightGear with FGADMIN" ON)
 option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
 option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient support" ON)
+option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
 option(WITH_FGPANEL "Set to ON to build the fgpanel application" ON)
 
 set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
@@ -178,10 +179,12 @@ endif(HAVE_RT)
 endif(NOT CLOCK_GETTIME_IN_LIBC)
 endif(HAVE_CLOCK_GETTIME)
 
-find_package(RTI)
-if(RTI_FOUND)
-  set(FG_HAVE_HLA 1)
-endif()
+if(ENABLE_RTI)
+    find_package(RTI)
+    if(RTI_FOUND)
+        set(FG_HAVE_HLA 1)
+    endif(RTI_FOUND)
+endif(ENABLE_RTI)
 
 if(CMAKE_COMPILER_IS_GNUCXX)
     set(WARNING_FLAGS -Wall)

From c158619e3cd8900f87152d8462a8aafdee5a4141 Mon Sep 17 00:00:00 2001
From: Martin Spott <Martin.Spott@mgras.net>
Date: Mon, 5 Sep 2011 23:44:00 +0200
Subject: [PATCH 03/85] Disable building fgadmin if FLTK's fluid command is
 unavailable.

---
 utils/CMakeLists.txt | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 5ba92f6f8..07d539f35 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -3,7 +3,11 @@ add_subdirectory(fgviewer)
 add_subdirectory(GPSsmooth)
 
 if (FLTK_FOUND)
-    add_subdirectory(fgadmin)
+    if (EXISTS ${FLTK_BIN_DIR}/fluid)
+        add_subdirectory(fgadmin)
+    else ()
+        message(STATUS "fluid executable not found, disabling fgadmin")
+    endif ()
 endif (FLTK_FOUND)
 
 if (WITH_FGPANEL)

From 6b6238293f617c005a53c6a88d5371e12093da3a Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Thu, 1 Sep 2011 21:05:50 +0200
Subject: [PATCH 04/85] Revert to simgears thread support. Flightgear side.

For all source directories outside of simgear/scene,
which really depends very hard on osg, avoid using osg
classes. This should reenable the use of some basic and
scenegraph independent parts of simgear without the
the need for osg.
---
 CMakeModules/FindSimGear.cmake | 28 ++++++++++++++--------------
 utils/GPSsmooth/CMakeLists.txt | 12 ++++++------
 utils/TerraSync/CMakeLists.txt | 10 +++++-----
 utils/fgpanel/CMakeLists.txt   |  3 +--
 utils/fgviewer/CMakeLists.txt  |  9 +++++----
 5 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index b8c446bba..c7dc1b3e2 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -1,7 +1,7 @@
 # Locate SimGear
 # This module defines
 # SIMGEAR_LIBRARIES
-# SIMGEAR_FOUND, if false, do not try to link to SimGear 
+# SIMGEAR_FOUND, if false, do not try to link to SimGear
 # SIMGEAR_INCLUDE_DIR, where to find the headers
 #
 # $SIMGEAR_DIR is an environment variable that would
@@ -30,7 +30,7 @@
 # /System/Library/Frameworks/SimGear.framework/Headers
 #
 # On OS X, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of 
+# People will have to manually change the cache values of
 # SimGear_LIBRARIES to override this selection or set the CMake environment
 # CMAKE_INCLUDE_PATH to modify the search paths.
 
@@ -38,7 +38,7 @@ include(SelectLibraryConfigurations)
 
 FIND_PATH(SIMGEAR_INCLUDE_DIR simgear/math/SGMath.hxx
   HINTS $ENV{SIMGEAR_DIR}
-  PATH_SUFFIXES include 
+  PATH_SUFFIXES include
   PATHS
   ~/Library/Frameworks
   /Library/Frameworks
@@ -103,9 +103,9 @@ macro(find_sg_component comp libs)
 endmacro()
 
 
-if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")  
+if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
     set(SIMGEAR_LIBRARIES "") # clear value
-    
+
     if(NOT MSVC)
         # Olaf indicates that linking the threads libs causes failures
         # on MSVC builds
@@ -115,7 +115,7 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
   # note the order here affects the order Simgear libraries are
   # linked in, and hence ability to link when using a traditional
   # linker such as GNU ld on Linux
-    set(comps 
+    set(comps
         ephem
         tsync
         environment
@@ -123,13 +123,12 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
         sky
         material
         tgdb
-        model    
+        model
         screen
         bucket
         bvh
         util route
         timing
-        ${thread_lib}
         io
         serial
         sound
@@ -137,10 +136,11 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
         props
         xml
         misc
-        debug 
+        ${thread_lib}
+        debug
         magvar
         math)
-    
+
     foreach(component ${comps})
         find_sg_component(${component} SIMGEAR_LIBRARIES)
     endforeach()
@@ -157,14 +157,14 @@ SET(CMAKE_REQUIRED_INCLUDES ${SIMGEAR_INCLUDE_DIR})
 check_cxx_source_runs(
     "#include <cstdio>
     #include \"simgear/version.h\"
-    
+
     #define xstr(s) str(s)
     #define str(s) #s
-     
+
     #define MIN_MAJOR ${SimGear_FIND_VERSION_MAJOR}
     #define MIN_MINOR ${SimGear_FIND_VERSION_MINOR}
     #define MIN_MICRO ${SimGear_FIND_VERSION_PATCH}
-    
+
     int main() {
         int major, minor, micro;
 
@@ -185,6 +185,6 @@ check_cxx_source_runs(
     SIMGEAR_VERSION_OK)
 
 include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SimGear DEFAULT_MSG 
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SimGear DEFAULT_MSG
      SIMGEAR_LIBRARIES SIMGEAR_INCLUDE_DIR SIMGEAR_VERSION_OK)
 
diff --git a/utils/GPSsmooth/CMakeLists.txt b/utils/GPSsmooth/CMakeLists.txt
index 453e2369c..5a586d0c4 100644
--- a/utils/GPSsmooth/CMakeLists.txt
+++ b/utils/GPSsmooth/CMakeLists.txt
@@ -3,10 +3,11 @@ add_executable(GPSsmooth gps.cxx gps_main.cxx)
 add_executable(MIDGsmooth MIDG-II.cxx MIDG_main.cxx)
 add_executable(UGsmooth UGear.cxx UGear_command.cxx UGear_main.cxx UGear_telnet.cxx)
 
-target_link_libraries(GPSsmooth 
+target_link_libraries(GPSsmooth
 	${SIMGEAR_IO_LIBRARY}
 	${SIMGEAR_MISC_LIBRARY}
 	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_THREADS_LIBRARY}
 	${SIMGEAR_TIMING_LIBRARY}
 	${SIMGEAR_DEBUG_LIBRARY}
 	${PLIB_SG_LIBRARY}
@@ -15,18 +16,17 @@ target_link_libraries(GPSsmooth
 	${WINMM_LIBRARY}
 	${WINSOCK_LIBRARY}
 	${ZLIB_LIBRARIES}
-  ${OPENTHREADS_LIBRARIES}
 	${RT_LIBRARY}
 )
 
-target_link_libraries(MIDGsmooth 
+target_link_libraries(MIDGsmooth
 	${SIMGEAR_IO_LIBRARY}
 	${SIMGEAR_MATH_LIBRARY}
 	${SIMGEAR_SERIAL_LIBRARY}
 	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_THREADS_LIBRARY}
 	${SIMGEAR_TIMING_LIBRARY}
 	${SIMGEAR_DEBUG_LIBRARY}
-  ${OPENTHREADS_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
@@ -34,15 +34,15 @@ target_link_libraries(MIDGsmooth
 	${RT_LIBRARY}
 )
 
-target_link_libraries(UGsmooth 
+target_link_libraries(UGsmooth
 	${SIMGEAR_DEBUG_LIBRARY}
 	${SIMGEAR_IO_LIBRARY}
 	${SIMGEAR_MATH_LIBRARY}
 	${SIMGEAR_MISC_LIBRARY}
 	${SIMGEAR_SERIAL_LIBRARY}
 	${SIMGEAR_STRUCTURE_LIBRARY}
+	${SIMGEAR_THREADS_LIBRARY}
 	${SIMGEAR_TIMING_LIBRARY}
-  ${OPENTHREADS_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index 25c01f084..0fc13133e 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -1,17 +1,17 @@
 
-	
+
 add_executable(terrasync terrasync.cxx)
 
-target_link_libraries(terrasync 
+target_link_libraries(terrasync
 	${SIMGEAR_LIBRARIES}
-  ${OPENTHREADS_LIBRARIES}
 	${ZLIB_LIBRARIES}
-    ${WINSOCK_LIBRARY})
+    ${WINSOCK_LIBRARY}
+    ${RT_LIBRARY})
 
 if(LIBSVN_FOUND)
 	target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
 	set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS "${APR_CFLAGS}")
-	
+
 	IF(APPLE)
 	    set_property(SOURCE terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
 	ELSE()
diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt
index 3595bf164..9feca02e6 100644
--- a/utils/fgpanel/CMakeLists.txt
+++ b/utils/fgpanel/CMakeLists.txt
@@ -16,14 +16,13 @@ if(GLUT_FOUND)
 		panel_io.cxx)
 
 	target_link_libraries(fgpanel 
-		${RT_LIBRARY}
 		${PNG_LIBRARIES}
 		${GLUT_LIBRARIES}
 		${SIMGEAR_LIBRARIES}
-    ${OPENTHREADS_LIBRARIES}
 		${OPENGL_LIBRARIES}
 		${ZLIB_LIBRARIES}
 		${PLIB_LIBRARIES}
+		${RT_LIBRARY}
 		)
 
 	install(TARGETS fgpanel RUNTIME DESTINATION bin)
diff --git a/utils/fgviewer/CMakeLists.txt b/utils/fgviewer/CMakeLists.txt
index f6654788b..5872d8a80 100644
--- a/utils/fgviewer/CMakeLists.txt
+++ b/utils/fgviewer/CMakeLists.txt
@@ -1,11 +1,12 @@
 
 add_executable(fgviewer fgviewer.cxx)
 
-target_link_libraries(fgviewer 
+target_link_libraries(fgviewer
 	${SIMGEAR_LIBRARIES}
-	${OPENSCENEGRAPH_LIBRARIES} 
+	${OPENSCENEGRAPH_LIBRARIES}
 	${OPENGL_LIBRARIES}
 	${ZLIB_LIBRARIES}
-	${PLIB_LIBRARIES})
-	
+	${PLIB_LIBRARIES}
+        ${RT_LIBRARY})
+
 install(TARGETS fgviewer RUNTIME DESTINATION bin)

From 938d4f3752515d46a1966500edeb2581993c9c07 Mon Sep 17 00:00:00 2001
From: Csaba Halasz <Csaba.Halasz@gmail.com>
Date: Wed, 7 Sep 2011 22:14:36 +0200
Subject: [PATCH 05/85] autotools build updated with sgthreads library

---
 src/Main/Makefile.am        | 2 +-
 utils/GPSsmooth/Makefile.am | 6 +++---
 utils/TerraSync/Makefile.am | 2 +-
 utils/fgviewer/Makefile.am  | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am
index 65d2ccd3b..48ed32eef 100644
--- a/src/Main/Makefile.am
+++ b/src/Main/Makefile.am
@@ -113,7 +113,7 @@ fgfs_LDADD = \
 	-lsgroute -lsgsky -lsgsound -lsgephem -lsgtgdb -lsgmodel -lsgbvh \
 	-lsgmaterial -lsgutil -lsgtiming -lsgio -lsgscreen -lsgmath -lsgbucket \
 	-lsgprops -lsgdebug -lsgmagvar -lsgmisc -lsgnasal -lsgxml -lsgsound \
-	-lsgserial -lsgstructure -lsgenvironment -lsgtsync\
+	-lsgserial -lsgstructure -lsgenvironment -lsgtsync -lsgthreads \
         $(fgfs_PLIB_LIBS) \
 	$(OSG_LIBS) \
 	$(thread_LIBS) \
diff --git a/utils/GPSsmooth/Makefile.am b/utils/GPSsmooth/Makefile.am
index b3c7ee6b4..ccd7451ee 100644
--- a/utils/GPSsmooth/Makefile.am
+++ b/utils/GPSsmooth/Makefile.am
@@ -16,7 +16,7 @@ GPSsmooth_SOURCES = \
 	gps_main.cxx
 
 GPSsmooth_LDADD = \
-        $(GPSsmooth_PLIB_LIBS) -lsgio -lsgtiming -lsgmisc -lsgdebug -lsgstructure \
+        $(GPSsmooth_PLIB_LIBS) -lsgio -lsgtiming -lsgmisc -lsgdebug -lsgstructure -lsgthreads \
 	$(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 MIDGsmooth_SOURCES = \
@@ -25,7 +25,7 @@ MIDGsmooth_SOURCES = \
 
 MIDGsmooth_LDADD = \
         $(MIDGsmooth_PLIB_LIBS) -lsgio -lsgserial -lsgtiming \
-        -lsgmath -lsgbucket -lsgmisc -lsgdebug -lsgstructure \
+        -lsgmath -lsgbucket -lsgmisc -lsgdebug -lsgstructure -lsgthreads \
 	$(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 UGsmooth_SOURCES = \
@@ -37,7 +37,7 @@ UGsmooth_SOURCES = \
 
 UGsmooth_LDADD = \
         $(UGsmooth_PLIB_LIBS) -lsgio -lsgserial -lsgtiming \
-        -lsgmath -lsgbucket -lsgmisc -lsgdebug -lsgstructure \
+        -lsgmath -lsgbucket -lsgmisc -lsgdebug -lsgstructure -lsgthreads \
         $(joystick_LIBS) $(network_LIBS) $(base_LIBS) -lz
 
 INCLUDES = -I$(top_srcdir)/src
diff --git a/utils/TerraSync/Makefile.am b/utils/TerraSync/Makefile.am
index 3932be524..ea3d29f51 100644
--- a/utils/TerraSync/Makefile.am
+++ b/utils/TerraSync/Makefile.am
@@ -6,4 +6,4 @@ terrasync_SOURCES = terrasync.cxx
 
 AM_CPPFLAGS = $(svn_CPPFLAGS)
 
-terrasync_LDADD = -lsgio -lsgstructure -lsgmisc -lsgdebug $(network_LIBS) $(svn_LIBS)
+terrasync_LDADD = -lsgio -lsgstructure -lsgmisc -lsgdebug -lsgthreads $(network_LIBS) $(svn_LIBS)
diff --git a/utils/fgviewer/Makefile.am b/utils/fgviewer/Makefile.am
index 1932bb8fd..56a367971 100644
--- a/utils/fgviewer/Makefile.am
+++ b/utils/fgviewer/Makefile.am
@@ -19,5 +19,5 @@ endif
 fgviewer_SOURCES = fgviewer.cxx
 fgviewer_LDADD = \
 	-lsgtgdb -lsgmaterial -lsgmodel -lsgbvh -lsgutil -lsgio -lsgbucket \
-	-lsgmath -lsgprops -lsgdebug -lsgmisc -lsgxml -lsgstructure \
+	-lsgmath -lsgprops -lsgdebug -lsgmisc -lsgxml -lsgstructure -lsgthreads \
 	$(fgviewer_PLIB_LIBS) $(OSG_LIBS) $(opengl_LIBS) $(thread_LIBS) -lz

From d09575e646c83675420536f41efed9548f903a94 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Thu, 8 Sep 2011 00:49:23 +0200
Subject: [PATCH 06/85] autotools build updated with sgthreads library

---
 src/Main/Makefile.am | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am
index 48ed32eef..f6dab96a7 100644
--- a/src/Main/Makefile.am
+++ b/src/Main/Makefile.am
@@ -129,8 +129,8 @@ fgfs_LDFLAGS = $(fgfs_PLIB_FW) $(fgfs_OSG_FW) $(LDFLAGS)
 metar_SOURCES = metar_main.cxx
 
 metar_LDADD = \
-        -lsgenvironment -lsgio -lsgbucket -lsgmisc -lsgstructure -lsgdebug \
-        $(network_LIBS) \
+        -lsgenvironment -lsgio -lsgthreads -lsgbucket -lsgmisc -lsgstructure \
+        -lsgdebug $(network_LIBS) $(thread_LIBS) \
         -lz $(base_LIBS)
 
 

From a5a8090d52fafff6f0cd5b09bcec4f92cdd2ed19 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Thu, 8 Sep 2011 13:59:40 +0100
Subject: [PATCH 07/85] Cmake: Split simgear libraries into core and scene
 (only scene uses OSG). Fix linkage issues, and make helper binaries (yasim,
 terrasync) link against less stuff.

---
 CMakeLists.txt                 |  6 ++++++
 CMakeModules/FindSimGear.cmake | 35 +++++++++++++++++++---------------
 src/FDM/YASim/CMakeLists.txt   |  2 +-
 src/Input/CMakeLists.txt       |  4 ++--
 utils/GPSsmooth/CMakeLists.txt | 24 +++--------------------
 utils/TerraSync/CMakeLists.txt |  2 +-
 utils/fgpanel/CMakeLists.txt   |  2 +-
 7 files changed, 34 insertions(+), 41 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 581cb638f..54977bc47 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,12 @@ file(READ version versionFile)
 string(STRIP ${versionFile} FLIGHTGEAR_VERSION) 
 
 #packaging
+
+# split version string into components, note CMAKE_MATCH_0 is the entire regexp match
+string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CPACK_PACKAGE_VERSION ${FLIGHTGEAR_VERSION} )
+set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) 
+set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
+set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
 SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
 SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
 
diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index c7dc1b3e2..f568d4b01 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -105,29 +105,19 @@ endmacro()
 
 if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
     set(SIMGEAR_LIBRARIES "") # clear value
-
-    if(NOT MSVC)
-        # Olaf indicates that linking the threads libs causes failures
-        # on MSVC builds
-        set(thread_lib threads)
-    endif(NOT MSVC)
-
+    set(SIMGEAR_CORE_LIBRARIES "") # clear value
+    
   # note the order here affects the order Simgear libraries are
   # linked in, and hence ability to link when using a traditional
   # linker such as GNU ld on Linux
     set(comps
-        ephem
         tsync
         environment
         nasal
-        sky
-        material
-        tgdb
-        model
-        screen
         bucket
         bvh
-        util route
+        util 
+        route
         timing
         io
         serial
@@ -136,14 +126,29 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
         props
         xml
         misc
-        ${thread_lib}
+        threads
         debug
         magvar
         math)
 
+    set(scene_comps
+        ephem
+        sky
+        material
+        tgdb
+        model
+        screen)
+            
     foreach(component ${comps})
+        find_sg_component(${component} SIMGEAR_CORE_LIBRARIES)
+    endforeach()
+        
+    foreach(component ${scene_comps})
         find_sg_component(${component} SIMGEAR_LIBRARIES)
     endforeach()
+    
+    # again link order matters - scene libraires depend on core ones
+    list(APPEND SIMGEAR_LIBRARIES ${SIMGEAR_CORE_LIBRARIES})
 endif()
 
 # now we've found SimGear, check its version
diff --git a/src/FDM/YASim/CMakeLists.txt b/src/FDM/YASim/CMakeLists.txt
index 2118993a5..1f91a8ed7 100644
--- a/src/FDM/YASim/CMakeLists.txt
+++ b/src/FDM/YASim/CMakeLists.txt
@@ -37,7 +37,7 @@ add_executable(yasim yasim-test.cpp)
 
 target_link_libraries(yasim 
 	fgYASim
-	${SIMGEAR_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARIES}
 	${ZLIB_LIBRARIES})
 
 install(TARGETS yasim RUNTIME DESTINATION bin)
diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index 1a2df52d2..27634bc4e 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -36,15 +36,15 @@ if(WIN32)
 endif(WIN32)
 
 target_link_libraries(fgjs 
+    ${SIMGEAR_CORE_LIBRARIES}
     ${SOCKETS_LIBRARY}
-	${SIMGEAR_LIBRARIES}
 	${PLIB_LIBRARIES}
 	${ZLIB_LIBRARY})
 
 add_executable(js_demo js_demo.cxx)
 
 target_link_libraries(js_demo 
-	${SIMGEAR_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_LIBRARIES}
 	${ZLIB_LIBRARY})
 
diff --git a/utils/GPSsmooth/CMakeLists.txt b/utils/GPSsmooth/CMakeLists.txt
index 5a586d0c4..5e90617c6 100644
--- a/utils/GPSsmooth/CMakeLists.txt
+++ b/utils/GPSsmooth/CMakeLists.txt
@@ -4,12 +4,7 @@ add_executable(MIDGsmooth MIDG-II.cxx MIDG_main.cxx)
 add_executable(UGsmooth UGear.cxx UGear_command.cxx UGear_main.cxx UGear_telnet.cxx)
 
 target_link_libraries(GPSsmooth
-	${SIMGEAR_IO_LIBRARY}
-	${SIMGEAR_MISC_LIBRARY}
-	${SIMGEAR_STRUCTURE_LIBRARY}
-	${SIMGEAR_THREADS_LIBRARY}
-	${SIMGEAR_TIMING_LIBRARY}
-	${SIMGEAR_DEBUG_LIBRARY}
+	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${ZLIB_LIBRARIES}
@@ -20,13 +15,7 @@ target_link_libraries(GPSsmooth
 )
 
 target_link_libraries(MIDGsmooth
-	${SIMGEAR_IO_LIBRARY}
-	${SIMGEAR_MATH_LIBRARY}
-	${SIMGEAR_SERIAL_LIBRARY}
-	${SIMGEAR_STRUCTURE_LIBRARY}
-	${SIMGEAR_THREADS_LIBRARY}
-	${SIMGEAR_TIMING_LIBRARY}
-	${SIMGEAR_DEBUG_LIBRARY}
+	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
@@ -35,14 +24,7 @@ target_link_libraries(MIDGsmooth
 )
 
 target_link_libraries(UGsmooth
-	${SIMGEAR_DEBUG_LIBRARY}
-	${SIMGEAR_IO_LIBRARY}
-	${SIMGEAR_MATH_LIBRARY}
-	${SIMGEAR_MISC_LIBRARY}
-	${SIMGEAR_SERIAL_LIBRARY}
-	${SIMGEAR_STRUCTURE_LIBRARY}
-	${SIMGEAR_THREADS_LIBRARY}
-	${SIMGEAR_TIMING_LIBRARY}
+	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index 0fc13133e..6c81e0f24 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -3,7 +3,7 @@
 add_executable(terrasync terrasync.cxx)
 
 target_link_libraries(terrasync
-	${SIMGEAR_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARIES}
 	${ZLIB_LIBRARIES}
     ${WINSOCK_LIBRARY}
     ${RT_LIBRARY})
diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt
index 9feca02e6..3307beb77 100644
--- a/utils/fgpanel/CMakeLists.txt
+++ b/utils/fgpanel/CMakeLists.txt
@@ -18,7 +18,7 @@ if(GLUT_FOUND)
 	target_link_libraries(fgpanel 
 		${PNG_LIBRARIES}
 		${GLUT_LIBRARIES}
-		${SIMGEAR_LIBRARIES}
+		${SIMGEAR_CORE_LIBRARIES}
 		${OPENGL_LIBRARIES}
 		${ZLIB_LIBRARIES}
 		${PLIB_LIBRARIES}

From 099bfd988ba83adb6d757e560f39d9c575bd2ff1 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Fri, 9 Sep 2011 21:38:02 +0200
Subject: [PATCH 08/85] fgfs and fgpanel need to be linked with the winsock
 library (on Windows)

---
 src/Main/CMakeLists.txt      | 1 +
 utils/fgpanel/CMakeLists.txt | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
index 5818335d3..dd1f6d6a9 100644
--- a/src/Main/CMakeLists.txt
+++ b/src/Main/CMakeLists.txt
@@ -80,6 +80,7 @@ target_link_libraries(fgfs
 	${ZLIB_LIBRARIES}
 	${PLIB_LIBRARIES}
 	${LIBSVN_LIBRARIES}
+	${WINSOCK_LIBRARY}
 	${RT_LIBRARY})
 
 install(TARGETS fgfs RUNTIME DESTINATION bin)
diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt
index 3307beb77..48d905600 100644
--- a/utils/fgpanel/CMakeLists.txt
+++ b/utils/fgpanel/CMakeLists.txt
@@ -22,6 +22,7 @@ if(GLUT_FOUND)
 		${OPENGL_LIBRARIES}
 		${ZLIB_LIBRARIES}
 		${PLIB_LIBRARIES}
+		${WINSOCK_LIBRARY}
 		${RT_LIBRARY}
 		)
 

From 549c5eccb9e18b6db2f469ca9d38e35dda4e33f1 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sun, 11 Sep 2011 11:22:10 +0200
Subject: [PATCH 09/85] cmake: Factor out common simgear dependency libs.

Factor out and use this core simgear depenency
library cmake variable.
---
 CMakeLists.txt                   | 32 ++------------------------------
 CMakeModules/FindSimGear.cmake   | 26 +++++++++++++++++++++++++-
 src/FDM/YASim/CMakeLists.txt     |  2 +-
 src/Input/CMakeLists.txt         | 11 +++--------
 src/Main/CMakeLists.txt          |  7 +++----
 utils/GPSsmooth/CMakeLists.txt   | 12 +++---------
 utils/TerraSync/CMakeLists.txt   |  5 ++---
 utils/fgadmin/src/CMakeLists.txt |  2 +-
 utils/fgpanel/CMakeLists.txt     |  4 +---
 utils/fgviewer/CMakeLists.txt    |  4 ++--
 10 files changed, 43 insertions(+), 62 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 54977bc47..b0d702a18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -158,33 +158,6 @@ check_cxx_source_compiles(
     "
     HAVE_CULLSETTINGS_CLEAR_MASK)
 
-# library required by simgear
-# XXX This should go in a module and only run if simgear is not shared.
-
-if(HAVE_UNISTD_H)
-set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
-check_cxx_source_compiles(
-   "#include <unistd.h>
-    #if !defined(_POSIX_TIMERS) || (0 >= _POSIX_TIMERS)
-    #error clock_gettime is not supported
-    #endif
-
-    int main() { return 0; }
-    "
-    HAVE_CLOCK_GETTIME)    
-endif(HAVE_UNISTD_H)
-
-set(RT_LIBRARY "")
-if(HAVE_CLOCK_GETTIME)
-check_function_exists(clock_gettime CLOCK_GETTIME_IN_LIBC)
-if(NOT CLOCK_GETTIME_IN_LIBC)
-check_library_exists(rt clock_gettime "" HAVE_RT)
-if(HAVE_RT)
-set(RT_LIBRARY rt)
-endif(HAVE_RT)
-endif(NOT CLOCK_GETTIME_IN_LIBC)
-endif(HAVE_CLOCK_GETTIME)
-
 if(ENABLE_RTI)
     find_package(RTI)
     if(RTI_FOUND)
@@ -211,7 +184,6 @@ if(WIN32)
     endif(MSVC)
 
     set(NOMINMAX 1)
-    set( WINSOCK_LIBRARY "ws2_32.lib" )
 endif(WIN32)    
 
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} -D_REENTRANT")
@@ -219,9 +191,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${MSVC_FLAGS} -D_REENTR
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
 
 include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
-    ${Boost_INCLUDE_DIRS}
+	${Boost_INCLUDE_DIRS}
 	${ZLIB_INCLUDE_DIR}
-    ${ALUT_INCLUDE_DIR}
+	${ALUT_INCLUDE_DIR}
 	${OPENAL_INCLUDE_DIR}
 	${SIMGEAR_INCLUDE_DIR}
 	${PLIB_INCLUDE_DIR} )
diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index f568d4b01..7481fadb4 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -63,6 +63,10 @@ FIND_LIBRARY(SIMGEAR_LIBRARIES
   /opt
 )
 
+# dependent packages
+find_package(ZLIB REQUIRED)
+find_package(Threads REQUIRED)
+
 macro(find_sg_component comp libs)
     set(compLib "sg${comp}")
     string(TOUPPER "SIMGEAR_${comp}" compLibBase)
@@ -146,9 +150,29 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
     foreach(component ${scene_comps})
         find_sg_component(${component} SIMGEAR_LIBRARIES)
     endforeach()
-    
+
     # again link order matters - scene libraires depend on core ones
     list(APPEND SIMGEAR_LIBRARIES ${SIMGEAR_CORE_LIBRARIES})
+
+    set(SIMGEAR_CORE_LIBRARY_DEPENDENCIES
+        ${CMAKE_THREAD_LIBS_INIT}
+        ${ZLIB_LIBRARY})
+
+    if(WIN32)
+        list(APPEND SIMGEAR_CORE_LIBRARY_DEPENDENCIES ${WINSOCK_LIBRARY})
+    endif(WIN32)
+
+    if(NOT MSVC)
+        # basic timing routines on non windows systems, may be also cygwin?!
+        check_function_exists(clock_gettime clock_gettime_in_libc)
+        if(NOT clock_gettime_in_libc)
+            check_library_exists(rt clock_gettime "" have_rt)
+            if(have_rt)
+                list(APPEND SIMGEAR_CORE_LIBRARY_DEPENDENCIES rt)
+            endif(have_rt)
+        endif(NOT clock_gettime_in_libc)
+    endif(NOT MSVC)
+
 endif()
 
 # now we've found SimGear, check its version
diff --git a/src/FDM/YASim/CMakeLists.txt b/src/FDM/YASim/CMakeLists.txt
index 1f91a8ed7..d129acef2 100644
--- a/src/FDM/YASim/CMakeLists.txt
+++ b/src/FDM/YASim/CMakeLists.txt
@@ -38,7 +38,7 @@ add_executable(yasim yasim-test.cpp)
 target_link_libraries(yasim 
 	fgYASim
 	${SIMGEAR_CORE_LIBRARIES}
-	${ZLIB_LIBRARIES})
+        ${SIMGEAR_CORE_LIBRARY_DEPENDENCIES})
 
 install(TARGETS yasim RUNTIME DESTINATION bin)
 	
diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index 27634bc4e..eb9916107 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -31,22 +31,17 @@ set(FGJS_SOURCES
 	
 add_executable(fgjs ${FGJS_SOURCES})
 
-if(WIN32)
-   set(SOCKETS_LIBRARY wsock32.lib)
-endif(WIN32)
-
 target_link_libraries(fgjs 
     ${SIMGEAR_CORE_LIBRARIES}
-    ${SOCKETS_LIBRARY}
-	${PLIB_LIBRARIES}
-	${ZLIB_LIBRARY})
+    ${PLIB_LIBRARIES}
+    ${SIMGEAR_CORE_LIBRARY_DEPENDENCIES})
 
 add_executable(js_demo js_demo.cxx)
 
 target_link_libraries(js_demo 
 	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_LIBRARIES}
-	${ZLIB_LIBRARY})
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES})
 
 flightgear_component(Input "${SOURCES}")
 
diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
index dd1f6d6a9..b7c7e961f 100644
--- a/src/Main/CMakeLists.txt
+++ b/src/Main/CMakeLists.txt
@@ -71,16 +71,15 @@ endif()
 
 target_link_libraries(fgfs
 	${FG_LIBS}
-	${HLA_LIBRARIES}
 	${SIMGEAR_LIBRARIES}
 	${OPENSCENEGRAPH_LIBRARIES}
 	${OPENAL_LIBRARY}
 	${OPENGL_LIBRARIES}
 	${ALUT_LIBRARY}
-	${ZLIB_LIBRARIES}
 	${PLIB_LIBRARIES}
 	${LIBSVN_LIBRARIES}
-	${WINSOCK_LIBRARY}
-	${RT_LIBRARY})
+	${HLA_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
+)
 
 install(TARGETS fgfs RUNTIME DESTINATION bin)
diff --git a/utils/GPSsmooth/CMakeLists.txt b/utils/GPSsmooth/CMakeLists.txt
index 5e90617c6..2cd60a8cc 100644
--- a/utils/GPSsmooth/CMakeLists.txt
+++ b/utils/GPSsmooth/CMakeLists.txt
@@ -7,11 +7,8 @@ target_link_libraries(GPSsmooth
 	${SIMGEAR_CORE_LIBRARIES}
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
-	${ZLIB_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
 	${WINMM_LIBRARY}
-	${WINSOCK_LIBRARY}
-	${ZLIB_LIBRARIES}
-	${RT_LIBRARY}
 )
 
 target_link_libraries(MIDGsmooth
@@ -19,8 +16,7 @@ target_link_libraries(MIDGsmooth
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
-	${WINSOCK_LIBRARY}
-	${RT_LIBRARY}
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
 )
 
 target_link_libraries(UGsmooth
@@ -28,9 +24,7 @@ target_link_libraries(UGsmooth
 	${PLIB_SG_LIBRARY}
 	${PLIB_UL_LIBRARY}
 	${WINMM_LIBRARY}
-	${WINSOCK_LIBRARY}
-	${ZLIB_LIBRARIES}
-	${RT_LIBRARY}
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
 )
 
 install(TARGETS GPSsmooth MIDGsmooth UGsmooth RUNTIME DESTINATION bin)
diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index 6c81e0f24..d3819794d 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -4,9 +4,8 @@ add_executable(terrasync terrasync.cxx)
 
 target_link_libraries(terrasync
 	${SIMGEAR_CORE_LIBRARIES}
-	${ZLIB_LIBRARIES}
-    ${WINSOCK_LIBRARY}
-    ${RT_LIBRARY})
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
+)
 
 if(LIBSVN_FOUND)
 	target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
diff --git a/utils/fgadmin/src/CMakeLists.txt b/utils/fgadmin/src/CMakeLists.txt
index d0e0812fd..e0f623b60 100644
--- a/utils/fgadmin/src/CMakeLists.txt
+++ b/utils/fgadmin/src/CMakeLists.txt
@@ -7,9 +7,9 @@ add_dependencies(fgadmin FGAdminUI)
 
 target_link_libraries(fgadmin FGAdminUI
 	${SIMGEAR_LIBRARIES}
-	${ZLIB_LIBRARIES}
 	${PLIB_LIBRARIES}
 	${FLTK_LIBRARIES}
+	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
 )
 	
 install(TARGETS fgadmin RUNTIME DESTINATION bin)
diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt
index 48d905600..ed0b991fb 100644
--- a/utils/fgpanel/CMakeLists.txt
+++ b/utils/fgpanel/CMakeLists.txt
@@ -20,10 +20,8 @@ if(GLUT_FOUND)
 		${GLUT_LIBRARIES}
 		${SIMGEAR_CORE_LIBRARIES}
 		${OPENGL_LIBRARIES}
-		${ZLIB_LIBRARIES}
 		${PLIB_LIBRARIES}
-		${WINSOCK_LIBRARY}
-		${RT_LIBRARY}
+		${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
 		)
 
 	install(TARGETS fgpanel RUNTIME DESTINATION bin)
diff --git a/utils/fgviewer/CMakeLists.txt b/utils/fgviewer/CMakeLists.txt
index 5872d8a80..9a803e90a 100644
--- a/utils/fgviewer/CMakeLists.txt
+++ b/utils/fgviewer/CMakeLists.txt
@@ -5,8 +5,8 @@ target_link_libraries(fgviewer
 	${SIMGEAR_LIBRARIES}
 	${OPENSCENEGRAPH_LIBRARIES}
 	${OPENGL_LIBRARIES}
-	${ZLIB_LIBRARIES}
 	${PLIB_LIBRARIES}
-        ${RT_LIBRARY})
+        ${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
+)
 
 install(TARGETS fgviewer RUNTIME DESTINATION bin)

From 7375166c2b426f672cbada959cd2925525730777 Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Sun, 11 Sep 2011 11:42:21 +0200
Subject: [PATCH 10/85] New version of JSBSim, a big rewrite.

---
 src/FDM/JSBSim/CMakeLists.txt                 |  87 ++-
 src/FDM/JSBSim/FGFDMExec.cpp                  | 501 ++++++++----
 src/FDM/JSBSim/FGFDMExec.h                    | 112 +--
 src/FDM/JSBSim/FGJSBBase.cpp                  |   5 +-
 src/FDM/JSBSim/FGJSBBase.h                    |  21 +-
 src/FDM/JSBSim/JSBSim.cxx                     |  91 ++-
 src/FDM/JSBSim/JSBSim.hxx                     |  23 +-
 .../initialization/FGInitialCondition.cpp     |  39 +-
 .../initialization/FGInitialCondition.h       |  10 +-
 src/FDM/JSBSim/initialization/FGTrimAxis.cpp  |  26 +-
 src/FDM/JSBSim/input_output/FGScript.cpp      |  18 +-
 src/FDM/JSBSim/input_output/FGScript.h        |   9 +-
 src/FDM/JSBSim/input_output/FGXMLElement.cpp  |   6 +-
 src/FDM/JSBSim/math/FGFunction.cpp            | 412 +++++++++-
 src/FDM/JSBSim/math/FGFunction.h              | 103 ++-
 src/FDM/JSBSim/math/FGLocation.h              |  13 +-
 src/FDM/JSBSim/math/FGModelFunctions.h        |   4 +-
 src/FDM/JSBSim/math/LagrangeMultiplier.h      |  67 ++
 src/FDM/JSBSim/math/Makefile.am               |   2 +-
 src/FDM/JSBSim/models/FGAccelerations.cpp     | 397 ++++++++++
 src/FDM/JSBSim/models/FGAccelerations.h       | 230 ++++++
 src/FDM/JSBSim/models/FGAerodynamics.cpp      | 125 +--
 src/FDM/JSBSim/models/FGAerodynamics.h        |  30 +-
 src/FDM/JSBSim/models/FGAircraft.cpp          |  59 +-
 src/FDM/JSBSim/models/FGAircraft.h            |  31 +-
 src/FDM/JSBSim/models/FGAtmosphere.cpp        | 730 +++---------------
 src/FDM/JSBSim/models/FGAtmosphere.h          | 392 ++++------
 src/FDM/JSBSim/models/FGAuxiliary.cpp         | 313 ++++----
 src/FDM/JSBSim/models/FGAuxiliary.h           | 100 ++-
 src/FDM/JSBSim/models/FGBuoyantForces.cpp     |   4 +-
 src/FDM/JSBSim/models/FGBuoyantForces.h       |  10 +-
 src/FDM/JSBSim/models/FGExternalReactions.cpp |  27 +-
 src/FDM/JSBSim/models/FGExternalReactions.h   |   9 +-
 src/FDM/JSBSim/models/FGFCS.cpp               |  28 +-
 src/FDM/JSBSim/models/FGFCS.h                 |  39 +-
 src/FDM/JSBSim/models/FGGasCell.cpp           |  35 +-
 src/FDM/JSBSim/models/FGGasCell.h             |  27 +-
 src/FDM/JSBSim/models/FGGroundReactions.cpp   |  77 +-
 src/FDM/JSBSim/models/FGGroundReactions.h     |  22 +-
 src/FDM/JSBSim/models/FGInertial.cpp          |  18 +-
 src/FDM/JSBSim/models/FGInertial.h            |  11 +-
 src/FDM/JSBSim/models/FGLGear.cpp             | 238 +++---
 src/FDM/JSBSim/models/FGLGear.h               |  67 +-
 src/FDM/JSBSim/models/FGMassBalance.cpp       |  46 +-
 src/FDM/JSBSim/models/FGMassBalance.h         |  17 +-
 src/FDM/JSBSim/models/FGModel.h               |   4 +-
 src/FDM/JSBSim/models/FGOutput.cpp            |  39 +-
 src/FDM/JSBSim/models/FGPropagate.cpp         | 364 +--------
 src/FDM/JSBSim/models/FGPropagate.h           | 126 +--
 src/FDM/JSBSim/models/FGPropulsion.cpp        | 192 ++++-
 src/FDM/JSBSim/models/FGPropulsion.h          |  13 +-
 src/FDM/JSBSim/models/Makefile.am             |   4 +-
 src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp   |  44 +-
 src/FDM/JSBSim/models/atmosphere/FGMars.cpp   |  19 +-
 .../atmosphere/FGStandardAtmosphere.cpp       | 179 +----
 .../models/atmosphere/FGStandardAtmosphere.h  | 136 +---
 src/FDM/JSBSim/models/atmosphere/FGWinds.cpp  | 553 +++++++++++++
 src/FDM/JSBSim/models/atmosphere/FGWinds.h    | 349 +++++++++
 src/FDM/JSBSim/models/atmosphere/Makefile.am  |   4 +-
 .../models/flight_control/FGAccelerometer.cpp |  12 +-
 .../models/flight_control/FGAccelerometer.h   |  12 +-
 .../models/flight_control/FGActuator.cpp      |  13 +-
 .../JSBSim/models/flight_control/FGActuator.h |  13 +-
 .../JSBSim/models/flight_control/FGGyro.cpp   |   8 +-
 src/FDM/JSBSim/models/flight_control/FGGyro.h |  10 +-
 .../JSBSim/models/flight_control/FGSensor.cpp |   4 +-
 .../JSBSim/models/flight_control/FGSensor.h   |  34 +-
 .../JSBSim/models/flight_control/Makefile.am  |   4 +-
 .../JSBSim/models/propulsion/FGElectric.cpp   |  25 +-
 src/FDM/JSBSim/models/propulsion/FGElectric.h |   9 +-
 src/FDM/JSBSim/models/propulsion/FGEngine.cpp | 150 ++--
 src/FDM/JSBSim/models/propulsion/FGEngine.h   |  85 +-
 src/FDM/JSBSim/models/propulsion/FGForce.cpp  |  16 +-
 src/FDM/JSBSim/models/propulsion/FGNozzle.cpp |  15 +-
 src/FDM/JSBSim/models/propulsion/FGNozzle.h   |   5 +-
 src/FDM/JSBSim/models/propulsion/FGPiston.cpp | 223 ++++--
 src/FDM/JSBSim/models/propulsion/FGPiston.h   |  10 +-
 .../JSBSim/models/propulsion/FGPropeller.cpp  |  30 +-
 src/FDM/JSBSim/models/propulsion/FGRocket.cpp | 117 +--
 src/FDM/JSBSim/models/propulsion/FGRocket.h   |  40 +-
 src/FDM/JSBSim/models/propulsion/FGRotor.cpp  | 102 +--
 src/FDM/JSBSim/models/propulsion/FGTank.cpp   |  13 +-
 src/FDM/JSBSim/models/propulsion/FGTank.h     |   7 +-
 src/FDM/JSBSim/models/propulsion/FGThruster.h |  18 +-
 .../JSBSim/models/propulsion/FGTurbine.cpp    |  66 +-
 src/FDM/JSBSim/models/propulsion/FGTurbine.h  |   9 +-
 .../JSBSim/models/propulsion/FGTurboProp.cpp  |  74 +-
 .../JSBSim/models/propulsion/FGTurboProp.h    |   9 +-
 src/Main/Makefile.am                          |   2 +-
 89 files changed, 4428 insertions(+), 3364 deletions(-)
 mode change 100644 => 100755 src/FDM/JSBSim/math/FGFunction.h
 mode change 100644 => 100755 src/FDM/JSBSim/math/FGModelFunctions.h
 create mode 100755 src/FDM/JSBSim/math/LagrangeMultiplier.h
 create mode 100644 src/FDM/JSBSim/models/FGAccelerations.cpp
 create mode 100644 src/FDM/JSBSim/models/FGAccelerations.h
 mode change 100644 => 100755 src/FDM/JSBSim/models/atmosphere/FGMars.cpp
 create mode 100644 src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
 create mode 100644 src/FDM/JSBSim/models/atmosphere/FGWinds.h
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGGyro.cpp
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGGyro.h
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGSensor.cpp
 mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGSensor.h
 mode change 100644 => 100755 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
 mode change 100644 => 100755 src/FDM/JSBSim/models/propulsion/FGTurboProp.h

diff --git a/src/FDM/JSBSim/CMakeLists.txt b/src/FDM/JSBSim/CMakeLists.txt
index afc377ddd..c0082591a 100644
--- a/src/FDM/JSBSim/CMakeLists.txt
+++ b/src/FDM/JSBSim/CMakeLists.txt
@@ -1,5 +1,86 @@
 include(FlightGearComponent)
 
+set(HEADERS
+    FGFDMExec.h
+    FGJSBBase.h
+    JSBSim.hxx
+    initialization/FGInitialCondition.h
+    initialization/FGTrim.h
+    initialization/FGTrimAxis.h
+    input_output/FGXMLParse.h
+    input_output/FGXMLFileRead.h
+    input_output/FGPropertyManager.h
+    input_output/FGScript.h
+    input_output/FGfdmSocket.h
+    input_output/string_utilities.h
+    input_output/FGXMLElement.h
+    input_output/net_fdm.hxx
+    input_output/FGGroundCallback.h
+    math/FGParameter.h
+    math/LagrangeMultiplier.h
+    math/FGColumnVector3.h
+    math/FGCondition.h
+    math/FGFunction.h
+    math/FGLocation.h
+    math/FGMatrix33.h
+    math/FGModelFunctions.h
+    math/FGPropertyValue.h
+    math/FGQuaternion.h
+    math/FGRealValue.h
+    math/FGRungeKutta.h
+    math/FGTable.h
+    models/FGAccelerations.h
+    models/FGAerodynamics.h
+    models/FGAircraft.h
+    models/FGAtmosphere.h
+    models/FGAuxiliary.h
+    models/FGBuoyantForces.h
+    models/FGExternalForce.h
+    models/FGExternalReactions.h
+    models/FGFCS.h
+    models/FGGasCell.h
+    models/FGGroundReactions.h
+    models/FGInertial.h
+    models/FGInput.h
+    models/FGLGear.h
+    models/FGMassBalance.h
+    models/FGModel.h
+    models/FGOutput.h
+    models/FGPropagate.h
+    models/FGPropulsion.h
+    models/atmosphere/FGMSIS.h
+    models/atmosphere/FGStandardAtmosphere.h
+    models/atmosphere/FGMars.h
+    models/atmosphere/FGWinds.h
+    models/flight_control/FGAccelerometer.h
+    models/flight_control/FGActuator.h
+    models/flight_control/FGDeadBand.h
+    models/flight_control/FGFCSComponent.h
+    models/flight_control/FGFCSFunction.h
+    models/flight_control/FGFilter.h
+    models/flight_control/FGGain.h
+    models/flight_control/FGGyro.h
+    models/flight_control/FGKinemat.h
+    models/flight_control/FGMagnetometer.h
+    models/flight_control/FGPID.h
+    models/flight_control/FGSensor.h
+    models/flight_control/FGSensorOrientation.h
+    models/flight_control/FGSummer.h
+    models/flight_control/FGSwitch.h
+    models/propulsion/FGElectric.h
+    models/propulsion/FGEngine.h
+    models/propulsion/FGForce.h
+    models/propulsion/FGNozzle.h
+    models/propulsion/FGPiston.h
+    models/propulsion/FGPropeller.h
+    models/propulsion/FGRocket.h
+    models/propulsion/FGRotor.h
+    models/propulsion/FGTank.h
+    models/propulsion/FGThruster.h
+    models/propulsion/FGTurbine.h
+    models/propulsion/FGTurboProp.h
+    )
+
 set(SOURCES
     FGFDMExec.cpp
     FGJSBBase.cpp
@@ -24,6 +105,7 @@ set(SOURCES
     math/FGRealValue.cpp
     math/FGRungeKutta.cpp
     math/FGTable.cpp
+    models/FGAccelerations.cpp
     models/FGAerodynamics.cpp
     models/FGAircraft.cpp
     models/FGAtmosphere.cpp
@@ -44,7 +126,9 @@ set(SOURCES
     models/FGPropulsion.cpp
     models/atmosphere/FGMSIS.cpp
     models/atmosphere/FGMSISData.cpp
+    models/atmosphere/FGStandardAtmosphere.cpp
     models/atmosphere/FGMars.cpp
+    models/atmosphere/FGWinds.cpp
     models/flight_control/FGAccelerometer.cpp
     models/flight_control/FGActuator.cpp
     models/flight_control/FGDeadBand.cpp
@@ -52,7 +136,6 @@ set(SOURCES
     models/flight_control/FGFCSFunction.cpp
     models/flight_control/FGFilter.cpp
     models/flight_control/FGGain.cpp
-    models/flight_control/FGGradient.cpp
     models/flight_control/FGGyro.cpp
     models/flight_control/FGKinemat.cpp
     models/flight_control/FGMagnetometer.cpp
@@ -76,4 +159,4 @@ set(SOURCES
     
 include_directories(${PROJECT_SOURCE_DIR}/src/FDM/JSBSim)
 
-flightgear_component(JSBSim "${SOURCES}")
+flightgear_component(JSBSim "${SOURCES}" "${HEADERS}")
diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp
index bcfe557f1..624f10354 100644
--- a/src/FDM/JSBSim/FGFDMExec.cpp
+++ b/src/FDM/JSBSim/FGFDMExec.cpp
@@ -41,10 +41,13 @@ COMMENTS, REFERENCES,  and NOTES
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <iostream>
+#include <iterator>
+#include <cstdlib>
+
 #include "FGFDMExec.h"
-#include "models/FGAtmosphere.h"
-#include "models/atmosphere/FGMSIS.h"
-#include "models/atmosphere/FGMars.h"
+#include "models/atmosphere/FGStandardAtmosphere.h"
+#include "models/atmosphere/FGWinds.h"
 #include "models/FGFCS.h"
 #include "models/FGPropulsion.h"
 #include "models/FGMassBalance.h"
@@ -54,24 +57,20 @@ INCLUDES
 #include "models/FGAerodynamics.h"
 #include "models/FGInertial.h"
 #include "models/FGAircraft.h"
+#include "models/FGAccelerations.h"
 #include "models/FGPropagate.h"
 #include "models/FGAuxiliary.h"
 #include "models/FGInput.h"
 #include "models/FGOutput.h"
 #include "initialization/FGInitialCondition.h"
-//#include "initialization/FGTrimAnalysis.h" // Remove until later
 #include "input_output/FGPropertyManager.h"
 #include "input_output/FGScript.h"
 
-#include <iostream>
-#include <iterator>
-#include <cstdlib>
-
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.95 2011/05/20 10:35:25 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.113 2011/09/07 02:37:04 jberndt Exp $";
 static const char *IdHdr = ID_FDMEXEC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -87,19 +86,6 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
   Frame           = 0;
   Error           = 0;
   GroundCallback  = 0;
-  Atmosphere      = 0;
-  FCS             = 0;
-  Propulsion      = 0;
-  MassBalance     = 0;
-  Aerodynamics    = 0;
-  Inertial        = 0;
-  GroundReactions = 0;
-  ExternalReactions = 0;
-  BuoyantForces   = 0;
-  Aircraft        = 0;
-  Propagate       = 0;
-  Auxiliary       = 0;
-  Input           = 0;
   IC              = 0;
   Trim            = 0;
   Script          = 0;
@@ -111,6 +97,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
   holding = false;
   Terminate = false;
   StandAlone = false;
+  firstPass = true;
 
   sim_time = 0.0;
   dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
@@ -197,7 +184,7 @@ FGFDMExec::~FGFDMExec()
 
   PropertyCatalog.clear();
 
-  FDMctr--;
+  if (FDMctr > 0) (*FDMctr)--;
 
   Debug(1);
 }
@@ -208,44 +195,54 @@ bool FGFDMExec::Allocate(void)
 {
   bool result=true;
 
-  Atmosphere      = new FGAtmosphere(this);
-  FCS             = new FGFCS(this);
-  Propulsion      = new FGPropulsion(this);
-  MassBalance     = new FGMassBalance(this);
-  Aerodynamics    = new FGAerodynamics (this);
-  Inertial        = new FGInertial(this);
+  Models.resize(eNumStandardModels);
 
-  GroundCallback  = new FGGroundCallback(Inertial->GetRefRadius());
+  // See the eModels enum specification in the header file. The order of the enums
+  // specifies the order of execution. The Models[] vector is the primary
+  // storage array for the list of models.
+  Models[ePropagate]         = new FGPropagate(this);
+  Models[eInput]             = new FGInput(this);
+  Models[eInertial]          = new FGInertial(this);
+  Models[eAtmosphere]        = new FGStandardAtmosphere(this);
+  Models[eWinds]             = new FGWinds(this);
+  Models[eAuxiliary]         = new FGAuxiliary(this);
+  Models[eSystems]           = new FGFCS(this);
+  Models[ePropulsion]        = new FGPropulsion(this);
+  Models[eAerodynamics]      = new FGAerodynamics (this);
 
-  GroundReactions = new FGGroundReactions(this);
-  ExternalReactions = new FGExternalReactions(this);
-  BuoyantForces   = new FGBuoyantForces(this);
-  Aircraft        = new FGAircraft(this);
-  Propagate       = new FGPropagate(this);
-  Auxiliary       = new FGAuxiliary(this);
-  Input           = new FGInput(this);
+  GroundCallback  = new FGGroundCallback(((FGInertial*)Models[eInertial])->GetRefRadius());
 
-  // Schedule a model. The second arg (the integer) is the pass number. For
-  // instance, the atmosphere model could get executed every fifth pass it is called.
-  
-  Schedule(Input,           1);   // Input model is Models[0]
-  Schedule(Atmosphere,      1);   // Input model is Models[1]
-  Schedule(FCS,             1);   // Input model is Models[2]
-  Schedule(Propulsion,      1);   // Input model is Models[3]
-  Schedule(MassBalance,     1);   // Input model is Models[4]
-  Schedule(Aerodynamics,    1);   // Input model is Models[5]
-  Schedule(Inertial,        1);   // Input model is Models[6]
-  Schedule(GroundReactions, 1);   // Input model is Models[7]
-  Schedule(ExternalReactions, 1); // Input model is Models[8]
-  Schedule(BuoyantForces,   1);   // Input model is Models[9]
-  Schedule(Aircraft,        1);   // Input model is Models[10]
-  Schedule(Propagate,       1);   // Input model is Models[11]
-  Schedule(Auxiliary,       1);   // Input model is Models[12]
+  Models[eGroundReactions]   = new FGGroundReactions(this);
+  Models[eExternalReactions] = new FGExternalReactions(this);
+  Models[eBuoyantForces]     = new FGBuoyantForces(this);
+  Models[eMassBalance]       = new FGMassBalance(this);
+  Models[eAircraft]          = new FGAircraft(this);
+  Models[eAccelerations]     = new FGAccelerations(this);
 
-  // Initialize models so they can communicate with each other
+  // Assign the Model shortcuts for internal executive use only.
+  Propagate = (FGPropagate*)Models[ePropagate];
+  Inertial = (FGInertial*)Models[eInertial];
+  Atmosphere = (FGAtmosphere*)Models[eAtmosphere];
+  Winds = (FGWinds*)Models[eWinds];
+  Auxiliary = (FGAuxiliary*)Models[eAuxiliary];
+  FCS = (FGFCS*)Models[eSystems];
+  Propulsion = (FGPropulsion*)Models[ePropulsion];
+  Aerodynamics = (FGAerodynamics*)Models[eAerodynamics];
+  GroundReactions = (FGGroundReactions*)Models[eGroundReactions];
+  ExternalReactions = (FGExternalReactions*)Models[eExternalReactions];
+  BuoyantForces = (FGBuoyantForces*)Models[eBuoyantForces];
+  MassBalance = (FGMassBalance*)Models[eMassBalance];
+  Aircraft = (FGAircraft*)Models[eAircraft];
+  Accelerations = (FGAccelerations*)Models[eAccelerations];
 
-  vector <FGModel*>::iterator it;
-  for (it = Models.begin(); it != Models.end(); ++it) (*it)->InitModel();
+  // Initialize planet (environment) constants
+  LoadPlanetConstants();
+
+  // Initialize models
+  for (unsigned int i = 0; i < Models.size(); i++) {
+    LoadInputs(i);
+    Models[i]->InitModel();
+  }
 
   IC = new FGInitialCondition(this);
 
@@ -258,24 +255,14 @@ bool FGFDMExec::Allocate(void)
 
 bool FGFDMExec::DeAllocate(void)
 {
-  delete Input;
-  delete Atmosphere;
-  delete FCS;
-  delete Propulsion;
-  delete MassBalance;
-  delete Aerodynamics;
-  delete Inertial;
-  delete GroundReactions;
-  delete ExternalReactions;
-  delete BuoyantForces;
-  delete Aircraft;
-  delete Propagate;
-  delete Auxiliary;
-  delete Script;
+
+  for (unsigned int i=0; i<eNumStandardModels; i++) delete Models[i];
+  Models.clear();
 
   for (unsigned i=0; i<Outputs.size(); i++) delete Outputs[i];
   Outputs.clear();
 
+  delete Script;
   delete IC;
   delete Trim;
 
@@ -283,23 +270,6 @@ bool FGFDMExec::DeAllocate(void)
 
   Error       = 0;
 
-  Input           = 0;
-  Atmosphere      = 0;
-  FCS             = 0;
-  Propulsion      = 0;
-  MassBalance     = 0;
-  Aerodynamics    = 0;
-  Inertial        = 0;
-  GroundReactions = 0;
-  ExternalReactions = 0;
-  BuoyantForces   = 0;
-  Aircraft        = 0;
-  Propagate       = 0;
-  Auxiliary       = 0;
-  Script          = 0;
-
-  Models.clear();
-
   modelLoaded = false;
   return modelLoaded;
 }
@@ -321,22 +291,252 @@ bool FGFDMExec::Run(void)
   Debug(2);
 
   for (unsigned int i=1; i<ChildFDMList.size(); i++) {
-    ChildFDMList[i]->AssignState(Propagate); // Transfer state to the child FDM
+    ChildFDMList[i]->AssignState( (FGPropagate*)Models[ePropagate] ); // Transfer state to the child FDM
     ChildFDMList[i]->Run();
   }
 
+  if (firstPass && !IntegrationSuspended()) {
+    // Outputs the initial conditions
+    for (unsigned int i = 0; i < Outputs.size(); i++)
+      Outputs[i]->Run(holding);
+
+    firstPass = false;
+  }
+
   // returns true if success, false if complete
   if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript();
 
-  vector <FGModel*>::iterator it;
-  for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(holding);
-
   IncrTime();
+
+  for (unsigned int i = 0; i < Models.size(); i++) {
+    LoadInputs(i);
+    Models[i]->Run(holding);
+  }
+
   if (Terminate) success = false;
 
   return (success);
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFDMExec::LoadInputs(unsigned int idx)
+{
+  switch(idx) {
+  case ePropagate:
+    Propagate->in.vPQRidot     = Accelerations->GetPQRidot();
+    Propagate->in.vQtrndot     = Accelerations->GetQuaterniondot();
+    Propagate->in.vUVWidot     = Accelerations->GetUVWidot();
+    Propagate->in.DeltaT       = dT;
+    break;
+  case eInput:
+    break;
+  case eInertial:
+    Inertial->in.Radius        = Propagate->GetRadius();
+    Inertial->in.Latitude      = Propagate->GetLatitude();
+    break;
+  case eAtmosphere:
+    Atmosphere->in.altitudeASL = Propagate->GetAltitudeASL();
+    break;
+  case eWinds:
+    Winds->in.AltitudeASL      = Propagate->GetAltitudeASL();
+    Winds->in.DistanceAGL      = Propagate->GetDistanceAGL();
+    Winds->in.Tl2b             = Propagate->GetTl2b();
+    Winds->in.Tw2b             = Auxiliary->GetTw2b();
+    Winds->in.V                = Auxiliary->GetVt();
+    Winds->in.totalDeltaT      = dT * Winds->GetRate();
+    break;
+  case eAuxiliary:
+    Auxiliary->in.Pressure     = Atmosphere->GetPressure();
+    Auxiliary->in.Density      = Atmosphere->GetDensity();
+    Auxiliary->in.DensitySL    = Atmosphere->GetDensitySL();
+    Auxiliary->in.PressureSL   = Atmosphere->GetPressureSL();
+    Auxiliary->in.Temperature  = Atmosphere->GetTemperature();
+    Auxiliary->in.SoundSpeed   = Atmosphere->GetSoundSpeed();
+    Auxiliary->in.KinematicViscosity = Atmosphere->GetKinematicViscosity();
+    Auxiliary->in.DistanceAGL  = Propagate->GetDistanceAGL();
+    Auxiliary->in.Mass         = MassBalance->GetMass();
+    Auxiliary->in.Tl2b         = Propagate->GetTl2b();
+    Auxiliary->in.Tb2l         = Propagate->GetTb2l();
+    Auxiliary->in.vPQR         = Propagate->GetPQR();
+    Auxiliary->in.vPQRdot      = Accelerations->GetPQRdot();
+    Auxiliary->in.vUVW         = Propagate->GetUVW();
+    Auxiliary->in.vUVWdot      = Accelerations->GetUVWdot();
+    Auxiliary->in.vVel         = Propagate->GetVel();
+    Auxiliary->in.vBodyAccel   = Accelerations->GetBodyAccel();
+    Auxiliary->in.ToEyePt      = MassBalance->StructuralToBody(Aircraft->GetXYZep());
+    Auxiliary->in.VRPBody      = MassBalance->StructuralToBody(Aircraft->GetXYZvrp());
+    Auxiliary->in.RPBody       = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
+    Auxiliary->in.vFw          = Aerodynamics->GetvFw();
+    Auxiliary->in.vLocation    = Propagate->GetLocation();
+    Auxiliary->in.Latitude     = Propagate->GetLatitude();
+    Auxiliary->in.Longitude    = Propagate->GetLongitude();
+    Auxiliary->in.CosTht       = Propagate->GetCosEuler(eTht);
+    Auxiliary->in.SinTht       = Propagate->GetSinEuler(eTht);
+    Auxiliary->in.CosPhi       = Propagate->GetCosEuler(ePhi);
+    Auxiliary->in.SinPhi       = Propagate->GetSinEuler(ePhi);
+    Auxiliary->in.Psi          = Propagate->GetEuler(ePsi);
+    Auxiliary->in.TotalWindNED = Winds->GetTotalWindNED();
+    Auxiliary->in.TurbPQR      = Winds->GetTurbPQR();
+    Auxiliary->in.WindPsi      = Winds->GetWindPsi();
+    Auxiliary->in.Vwind        = Winds->GetTotalWindNED().Magnitude();
+    break;
+  case eSystems:
+    // Dynamic inputs come into the components that FCS manages through properties
+    break;
+  case ePropulsion:
+    Propulsion->in.SLPressure       = Atmosphere->GetPressureSL();
+    Propulsion->in.Pressure         = Atmosphere->GetPressure();
+    Propulsion->in.PressureRatio    = Atmosphere->GetPressureRatio();
+    Propulsion->in.Temperature      = Atmosphere->GetTemperature();
+    Propulsion->in.DensityRatio     = Atmosphere->GetDensityRatio();
+    Propulsion->in.Density          = Atmosphere->GetDensity();
+    Propulsion->in.Soundspeed       = Atmosphere->GetSoundSpeed();
+    Propulsion->in.TotalPressure    = Auxiliary->GetTotalPressure();
+    Propulsion->in.TotalTempearture = Auxiliary->GetTotalTemperature();
+    Propulsion->in.Vc               = Auxiliary->GetVcalibratedKTS();
+    Propulsion->in.Vt               = Auxiliary->GetVt();
+    Propulsion->in.qbar             = Auxiliary->Getqbar();
+    Propulsion->in.TAT_c            = Auxiliary->GetTAT_C();
+    Propulsion->in.AeroUVW          = Auxiliary->GetAeroUVW();
+    Propulsion->in.AeroPQR          = Auxiliary->GetAeroPQR();
+    Propulsion->in.alpha            = Auxiliary->Getalpha();
+    Propulsion->in.beta             = Auxiliary->Getbeta();
+    Propulsion->in.TotalDeltaT      = dT * Propulsion->GetRate();
+    Propulsion->in.ThrottlePos      = FCS->GetThrottlePos();
+    Propulsion->in.MixturePos       = FCS->GetMixturePos();
+    Propulsion->in.ThrottleCmd      = FCS->GetThrottleCmd();
+    Propulsion->in.MixtureCmd       = FCS->GetMixtureCmd();
+    Propulsion->in.PropAdvance      = FCS->GetPropAdvance();
+    Propulsion->in.PropFeather      = FCS->GetPropFeather();
+    Propulsion->in.H_agl            = Propagate->GetDistanceAGL();
+    Propulsion->in.PQR              = Propagate->GetPQR();
+    break;
+  case eAerodynamics:
+    Aerodynamics->in.Alpha     = Auxiliary->Getalpha();
+    Aerodynamics->in.Beta      = Auxiliary->Getbeta();
+    Aerodynamics->in.Qbar      = Auxiliary->Getqbar();
+    Aerodynamics->in.Vt        = Auxiliary->GetVt();
+    Aerodynamics->in.Tb2w      = Auxiliary->GetTb2w();
+    Aerodynamics->in.Tw2b      = Auxiliary->GetTw2b();
+    Aerodynamics->in.RPBody    = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
+    break;
+  case eGroundReactions:
+    // There are no external inputs to this model.
+    GroundReactions->in.Vground         = Auxiliary->GetVground();
+    GroundReactions->in.VcalibratedKts  = Auxiliary->GetVcalibratedKTS();
+    GroundReactions->in.Temperature     = Atmosphere->GetTemperature();
+    GroundReactions->in.TakeoffThrottle = (FCS->GetThrottlePos().size() > 0) ? (FCS->GetThrottlePos(0) > 0.90) : false;
+    GroundReactions->in.SteerPosDeg     = FCS->GetSteerPosDeg();
+    GroundReactions->in.BrakePos        = FCS->GetBrakePos();
+    GroundReactions->in.FCSGearPos      = FCS->GetGearPos();
+    GroundReactions->in.EmptyWeight     = MassBalance->GetEmptyWeight();
+    GroundReactions->in.Tb2l            = Propagate->GetTb2l();
+    GroundReactions->in.Tec2l           = Propagate->GetTec2l();
+    GroundReactions->in.Tec2b           = Propagate->GetTec2b();
+    GroundReactions->in.PQR             = Propagate->GetPQR();
+    GroundReactions->in.UVW             = Propagate->GetUVW();
+    GroundReactions->in.DistanceAGL     = Propagate->GetDistanceAGL();
+    GroundReactions->in.DistanceASL     = Propagate->GetAltitudeASL();
+    GroundReactions->in.TotalDeltaT     = dT * GroundReactions->GetRate();
+    GroundReactions->in.WOW             = GroundReactions->GetWOW();
+    GroundReactions->in.Location        = Propagate->GetLocation();
+    for (unsigned int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
+      GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation());
+    }
+    break;
+  case eExternalReactions:
+    // There are no external inputs to this model.
+    break;
+  case eBuoyantForces:
+    BuoyantForces->in.Density     = Atmosphere->GetDensity();
+    BuoyantForces->in.Pressure    = Atmosphere->GetPressure();
+    BuoyantForces->in.Temperature = Atmosphere->GetTemperature();
+    BuoyantForces->in.gravity     = Inertial->gravity();
+    break;
+  case eMassBalance:
+    MassBalance->in.GasInertia  = BuoyantForces->GetGasMassInertia();
+    MassBalance->in.GasMass     = BuoyantForces->GetGasMass();
+    MassBalance->in.GasMoment   = BuoyantForces->GetGasMassMoment();
+    MassBalance->in.TanksWeight = Propulsion->GetTanksWeight();
+    MassBalance->in.TanksMoment = Propulsion->GetTanksMoment();
+    MassBalance->in.TankInertia = Propulsion->CalculateTankInertias();
+    break;
+  case eAircraft:
+    Aircraft->in.AeroForce     = Aerodynamics->GetForces();
+    Aircraft->in.PropForce     = Propulsion->GetForces();
+    Aircraft->in.GroundForce   = GroundReactions->GetForces();
+    Aircraft->in.ExternalForce = ExternalReactions->GetForces();
+    Aircraft->in.BuoyantForce  = BuoyantForces->GetForces();
+    Aircraft->in.AeroMoment    = Aerodynamics->GetMoments();
+    Aircraft->in.PropMoment    = Propulsion->GetMoments();
+    Aircraft->in.GroundMoment  = GroundReactions->GetMoments();
+    Aircraft->in.ExternalMoment = ExternalReactions->GetMoments();
+    Aircraft->in.BuoyantMoment = BuoyantForces->GetMoments();
+    Aircraft->in.Weight        = MassBalance->GetWeight();
+    Aircraft->in.Tl2b          = Propagate->GetTl2b();
+    break;
+  case eAccelerations:
+    Accelerations->in.J        = MassBalance->GetJ();
+    Accelerations->in.Jinv     = MassBalance->GetJinv();
+    Accelerations->in.Ti2b     = Propagate->GetTi2b();
+    Accelerations->in.Tb2i     = Propagate->GetTb2i();
+    Accelerations->in.Tec2b    = Propagate->GetTec2b();
+    Accelerations->in.Tl2b     = Propagate->GetTl2b();
+    Accelerations->in.qAttitudeECI = Propagate->GetQuaternionECI();
+    Accelerations->in.Moment   = Aircraft->GetMoments();
+    Accelerations->in.GroundMoment  = GroundReactions->GetMoments();
+    Accelerations->in.Force    = Aircraft->GetForces();
+    Accelerations->in.GroundForce   = GroundReactions->GetForces();
+    Accelerations->in.GAccel   = Inertial->GetGAccel(Propagate->GetRadius());
+    Accelerations->in.J2Grav  = Inertial->GetGravityJ2(Propagate->GetLocation());
+    Accelerations->in.vPQRi    = Propagate->GetPQRi();
+    Accelerations->in.vPQR     = Propagate->GetPQR();
+    Accelerations->in.vUVW     = Propagate->GetUVW();
+    Accelerations->in.vInertialPosition = Propagate->GetInertialPosition();
+    Accelerations->in.DeltaT   = dT;
+    Accelerations->in.Mass     = MassBalance->GetMass();
+    Accelerations->in.MultipliersList = GroundReactions->GetMultipliersList();
+    Accelerations->in.TerrainVelocity = Propagate->GetTerrainVelocity();
+    Accelerations->in.TerrainAngularVel = Propagate->GetTerrainAngularVelocity();
+    break;
+  default:
+    break;
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFDMExec::LoadPlanetConstants(void)
+{
+  Propagate->in.vOmegaPlanet     = Inertial->GetOmegaPlanet();
+  Accelerations->in.vOmegaPlanet = Inertial->GetOmegaPlanet();
+  Propagate->in.RefRadius        = Inertial->GetRefRadius();
+  Propagate->in.SemiMajor        = Inertial->GetSemimajor();
+  Propagate->in.SemiMinor        = Inertial->GetSemiminor();
+  Auxiliary->in.SLGravity        = Inertial->SLgravity();
+  Auxiliary->in.ReferenceRadius  = Inertial->GetRefRadius();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFDMExec::LoadModelConstants(void)
+{
+  Winds->in.wingspan             = Aircraft->GetWingSpan();
+  FCS->in.NumGear                = GroundReactions->GetNumGearUnits();
+  Aerodynamics->in.Wingarea      = Aircraft->GetWingArea();
+  Aerodynamics->in.Wingchord     = Aircraft->Getcbar();
+  Aerodynamics->in.Wingincidence = Aircraft->GetWingIncidence();
+  Aerodynamics->in.Wingspan      = Aircraft->GetWingSpan();
+  Auxiliary->in.Wingspan         = Aircraft->GetWingSpan();
+  Auxiliary->in.Wingchord        = Aircraft->Getcbar();
+  for (unsigned int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
+    GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation());
+  }
+
+  LoadPlanetConstants();
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // This call will cause the sim time to reset to 0.0
 
@@ -357,12 +557,15 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
   Setsim_time(0.0);
 
   Propagate->SetInitialState( FGIC );
-
+  LoadInputs(eAccelerations);
+  Accelerations->Run(false);
+  LoadInputs(ePropagate);
+  Propagate->InitializeDerivatives();
+  LoadInputs(eAtmosphere);
   Atmosphere->Run(false);
-  Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(),
+  Winds->SetWindNED( FGIC->GetWindNFpsIC(),
                           FGIC->GetWindEFpsIC(),
                           FGIC->GetWindDFpsIC() );
-
   Auxiliary->Run(false);
 }
 
@@ -397,6 +600,23 @@ void FGFDMExec::ResetToInitialConditions(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+bool FGFDMExec::SetOutputFileName(const string& fname)
+{
+  if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
+  else return false;
+  return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+string FGFDMExec::GetOutputFileName(void)
+{
+  if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
+  else return string("");
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGFDMExec::SetGroundCallback(FGGroundCallback* p)
 {
   delete GroundCallback;
@@ -408,6 +628,7 @@ void FGFDMExec::SetGroundCallback(FGGroundCallback* p)
 vector <string> FGFDMExec::EnumerateFDMs(void)
 {
   vector <string> FDMList;
+  FGAircraft* Aircraft = (FGAircraft*)Models[eAircraft];
 
   FDMList.push_back(Aircraft->GetAircraftName());
 
@@ -493,7 +714,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the metrics element. This element is REQUIRED.
     element = document->FindElement("metrics");
     if (element) {
-      result = Aircraft->Load(element);
+      result = ((FGAircraft*)Models[eAircraft])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -506,7 +727,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the mass_balance element. This element is REQUIRED.
     element = document->FindElement("mass_balance");
     if (element) {
-      result = MassBalance->Load(element);
+      result = ((FGMassBalance*)Models[eMassBalance])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -519,11 +740,12 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the ground_reactions element. This element is REQUIRED.
     element = document->FindElement("ground_reactions");
     if (element) {
-      result = GroundReactions->Load(element);
+      result = ((FGGroundReactions*)Models[eGroundReactions])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft ground_reactions element has problems in file " << aircraftCfgFileName << endl;
         return result;
       }
+      ((FGFCS*)Models[eSystems])->AddGear(((FGGroundReactions*)Models[eGroundReactions])->GetNumGearUnits());
     } else {
       cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
       return false;
@@ -532,7 +754,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the external_reactions element. This element is OPTIONAL.
     element = document->FindElement("external_reactions");
     if (element) {
-      result = ExternalReactions->Load(element);
+      result = ((FGExternalReactions*)Models[eExternalReactions])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -542,7 +764,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the buoyant_forces element. This element is OPTIONAL.
     element = document->FindElement("buoyant_forces");
     if (element) {
-      result = BuoyantForces->Load(element);
+      result = ((FGBuoyantForces*)Models[eBuoyantForces])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -552,17 +774,19 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the propulsion element. This element is OPTIONAL.
     element = document->FindElement("propulsion");
     if (element) {
-      result = Propulsion->Load(element);
+      result = ((FGPropulsion*)Models[ePropulsion])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
         return result;
       }
+      for (unsigned int i=0; i<((FGPropulsion*)Models[ePropulsion])->GetNumEngines(); i++)
+        ((FGFCS*)Models[eSystems])->AddThrottle();
     }
 
     // Process the system element[s]. This element is OPTIONAL, and there may be more than one.
     element = document->FindElement("system");
     while (element) {
-      result = FCS->Load(element, FGFCS::stSystem);
+      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stSystem);
       if (!result) {
         cerr << endl << "Aircraft system element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -573,7 +797,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the autopilot element. This element is OPTIONAL.
     element = document->FindElement("autopilot");
     if (element) {
-      result = FCS->Load(element, FGFCS::stAutoPilot);
+      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stAutoPilot);
       if (!result) {
         cerr << endl << "Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -583,7 +807,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the flight_control element. This element is OPTIONAL.
     element = document->FindElement("flight_control");
     if (element) {
-      result = FCS->Load(element, FGFCS::stFCS);
+      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stFCS);
       if (!result) {
         cerr << endl << "Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -593,7 +817,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the aerodynamics element. This element is OPTIONAL, but almost always expected.
     element = document->FindElement("aerodynamics");
     if (element) {
-      result = Aerodynamics->Load(element);
+      result = ((FGAerodynamics*)Models[eAerodynamics])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -605,7 +829,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     // Process the input element. This element is OPTIONAL.
     element = document->FindElement("input");
     if (element) {
-      result = Input->Load(element);
+      result = ((FGInput*)Models[eInput])->Load(element);
       if (!result) {
         cerr << endl << "Aircraft input element has problems in file " << aircraftCfgFileName << endl;
         return result;
@@ -616,13 +840,12 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
     unsigned int idx=0;
     typedef double (FGOutput::*iOPMF)(void) const;
     typedef int (FGFDMExec::*iOPV)(void) const;
-    typedef void (FGFDMExec::*vOPI)(int) const;
     element = document->FindElement("output");
     while (element) {
       if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
       FGOutput* Output = new FGOutput(this);
       Output->InitModel();
-      Schedule(Output, 1);
+      Schedule(Output);
       result = Output->Load(element);
       if (!result) {
         cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
@@ -647,11 +870,16 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
       }
     }
 
+    // Since all vehicle characteristics have been loaded, place the values in the Inputs
+    // structure for the FGModel-derived classes.
+    LoadModelConstants();
+
     modelLoaded = true;
 
     if (debug_lvl > 0) {
-      MassBalance->Run(false); // Update all mass properties for the report.
-      MassBalance->GetMassPropertiesReport();
+      LoadInputs(eMassBalance); // Update all input mass properties for the report.
+      Models[eMassBalance]->Run(false);  // Update all mass properties for the report.
+      ((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport();
 
       cout << endl << fgblue << highint
            << "End of vehicle configuration loading." << endl
@@ -667,6 +895,8 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
          << fgdef << endl;
   }
 
+  for (unsigned int i=0; i< Models.size(); i++) LoadInputs(i);
+
   if (result) {
     struct PropertyCatalogStructure masterPCS;
     masterPCS.base_string = "";
@@ -679,6 +909,13 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+string FGFDMExec::GetPropulsionTankReport()
+{
+  return ((FGPropulsion*)Models[ePropulsion])->GetPropulsionTankReport();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
 {
   struct PropertyCatalogStructure* pcsNew = new struct PropertyCatalogStructure;
@@ -760,7 +997,7 @@ bool FGFDMExec::ReadPrologue(Element* el) // el for ReadPrologue is the document
   if (!el) return false;
 
   string AircraftName = el->GetAttributeValue("name");
-  Aircraft->SetAircraftName(AircraftName);
+  ((FGAircraft*)Models[eAircraft])->SetAircraftName(AircraftName);
 
   if (debug_lvl & 1) cout << underon << "Reading Aircraft Configuration File"
             << underoff << ": " << highint << AircraftName << normint << endl;
@@ -899,7 +1136,7 @@ void FGFDMExec::EnableOutput(void)
 
 void FGFDMExec::ForceOutput(int idx)
 {
-  if (idx >= 0 && idx < Outputs.size()) Outputs[idx]->Print();
+  if (idx >= (int)0 && idx < (int)Outputs.size()) Outputs[idx]->Print();
 }
 	
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -911,7 +1148,7 @@ bool FGFDMExec::SetOutputDirectives(const string& fname)
   FGOutput* Output = new FGOutput(this);
   Output->SetDirectivesFile(RootDir + fname);
   Output->InitModel();
-  Schedule(Output, 1);
+  Schedule(Output);
   result = Output->Load(0);
 
   if (result) {
@@ -943,38 +1180,6 @@ void FGFDMExec::DoTrim(int mode)
   sim_time = saved_time;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFDMExec::UseAtmosphereMSIS(void)
-{
-  FGAtmosphere *oldAtmosphere = Atmosphere;
-  Atmosphere = new MSIS(this);
-  if (!Atmosphere->InitModel()) {
-    cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl;
-    Error+=1;
-  }
-  Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled
-                          // to the new atmosphere.
-  delete oldAtmosphere;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFDMExec::UseAtmosphereMars(void)
-{
-/*
-  FGAtmosphere *oldAtmosphere = Atmosphere;
-  Atmosphere = new FGMars(this);
-  if (!Atmosphere->InitModel()) {
-    cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl;
-    Error+=1;
-  }
-  Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled
-                          // to the new atmosphere.
-  delete oldAtmosphere;
-*/
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
@@ -1000,10 +1205,10 @@ void FGFDMExec::Debug(int from)
 
   if (debug_lvl & 1 && IdFDM == 0) { // Standard console startup message output
     if (from == 0) { // Constructor
-      cout << "\n\n     " << highint << underon << "JSBSim Flight Dynamics Model v"
-                                     << JSBSim_version << underoff << normint << endl;
-      cout << halfint << "            [JSBSim-ML v" << needed_cfg_version << "]\n\n";
-      cout << normint << "JSBSim startup beginning ...\n\n";
+      cout << "\n\n     " 
+           << "JSBSim Flight Dynamics Model v" << JSBSim_version << endl;
+      cout << "            [JSBSim-ML v" << needed_cfg_version << "]\n\n";
+      cout << "JSBSim startup beginning ...\n\n";
     } else if (from == 3) {
       cout << "\n\nJSBSim startup complete\n\n";
     }
diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h
index e745b2224..4295348d0 100644
--- a/src/FDM/JSBSim/FGFDMExec.h
+++ b/src/FDM/JSBSim/FGFDMExec.h
@@ -44,8 +44,6 @@ INCLUDES
 #include <vector>
 #include <string>
 
-#include "models/FGOutput.h"
-#include "models/FGInput.h"
 #include "initialization/FGTrim.h"
 #include "FGJSBBase.h"
 #include "input_output/FGPropertyManager.h"
@@ -58,7 +56,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.64 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.71 2011/09/07 02:37:04 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -71,6 +69,8 @@ class FGTrim;
 class FGAerodynamics;
 class FGAircraft;
 class FGAtmosphere;
+class FGAccelerations;
+class FGWinds;
 class FGAuxiliary;
 class FGBuoyantForces;
 class FGExternalReactions;
@@ -181,7 +181,7 @@ CLASS DOCUMENTATION
                                 property actually maps toa function call of DoTrim().
 
     @author Jon S. Berndt
-    @version $Revision: 1.64 $
+    @version $Revision: 1.71 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -224,6 +224,25 @@ public:
   /// Default destructor
   ~FGFDMExec();
 
+  // This list of enums is very important! The order in which models are listed here
+  // determines the order of execution of the models.
+  enum eModels { ePropagate=0,
+                 eInput,
+                 eInertial,
+                 eAtmosphere,
+                 eWinds,
+                 eAuxiliary,
+                 eSystems,
+                 ePropulsion,
+                 eAerodynamics,
+                 eGroundReactions,
+                 eExternalReactions,
+                 eBuoyantForces,
+                 eMassBalance,
+                 eAircraft,
+                 eAccelerations,
+                 eNumStandardModels };
+
   /** Unbind all tied JSBSim properties. */
   void Unbind(void) {instance->Unbind();}
 
@@ -236,8 +255,9 @@ public:
       one is at this time not recommended.
       @param model A pointer to the model being scheduled.
       @param rate The rate at which to execute the model as described above.
+                  Default is every frame (rate=1).
       @return Currently returns 0 always. */
-  void Schedule(FGModel* model, int rate);
+  void Schedule(FGModel* model, int rate=1);
 
   /** This function executes each scheduled model in succession.
       @return true if successful, false if sim should be ended  */
@@ -309,31 +329,35 @@ public:
   /// @name Top-level executive State and Model retrieval mechanism
   //@{
   /// Returns the FGAtmosphere pointer.
-  FGAtmosphere* GetAtmosphere(void)    {return Atmosphere;}
+  FGAtmosphere* GetAtmosphere(void)    {return (FGAtmosphere*)Models[eAtmosphere];}
+  /// Returns the FGAccelerations pointer.
+  FGAccelerations* GetAccelerations(void)    {return (FGAccelerations*)Models[eAccelerations];}
+  /// Returns the FGWinds pointer.
+  FGWinds* GetWinds(void)    {return (FGWinds*)Models[eWinds];}
   /// Returns the FGFCS pointer.
-  FGFCS* GetFCS(void)                  {return FCS;}
+  FGFCS* GetFCS(void)                  {return (FGFCS*)Models[eSystems];}
   /// Returns the FGPropulsion pointer.
-  FGPropulsion* GetPropulsion(void)    {return Propulsion;}
+  FGPropulsion* GetPropulsion(void)    {return (FGPropulsion*)Models[ePropulsion];}
   /// Returns the FGAircraft pointer.
-  FGMassBalance* GetMassBalance(void)  {return MassBalance;}
+  FGMassBalance* GetMassBalance(void)  {return (FGMassBalance*)Models[eMassBalance];}
   /// Returns the FGAerodynamics pointer
-  FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
+  FGAerodynamics* GetAerodynamics(void){return (FGAerodynamics*)Models[eAerodynamics];}
   /// Returns the FGInertial pointer.
-  FGInertial* GetInertial(void)        {return Inertial;}
+  FGInertial* GetInertial(void)        {return (FGInertial*)Models[eInertial];}
   /// Returns the FGGroundReactions pointer.
-  FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
+  FGGroundReactions* GetGroundReactions(void) {return (FGGroundReactions*)Models[eGroundReactions];}
   /// Returns the FGExternalReactions pointer.
-  FGExternalReactions* GetExternalReactions(void) {return ExternalReactions;}
+  FGExternalReactions* GetExternalReactions(void) {return (FGExternalReactions*)Models[eExternalReactions];}
   /// Returns the FGBuoyantForces pointer.
-  FGBuoyantForces* GetBuoyantForces(void) {return BuoyantForces;}
+  FGBuoyantForces* GetBuoyantForces(void) {return (FGBuoyantForces*)Models[eBuoyantForces];}
   /// Returns the FGAircraft pointer.
-  FGAircraft* GetAircraft(void)        {return Aircraft;}
+  FGAircraft* GetAircraft(void)        {return (FGAircraft*)Models[eAircraft];}
   /// Returns the FGPropagate pointer.
-  FGPropagate* GetPropagate(void)      {return Propagate;}
+  FGPropagate* GetPropagate(void)      {return (FGPropagate*)Models[ePropagate];}
   /// Returns the FGAuxiliary pointer.
-  FGAuxiliary* GetAuxiliary(void)      {return Auxiliary;}
+  FGAuxiliary* GetAuxiliary(void)      {return (FGAuxiliary*)Models[eAuxiliary];}
   /// Returns the FGInput pointer.
-  FGInput* GetInput(void)              {return Input;}
+  FGInput* GetInput(void)              {return (FGInput*)Models[eInput];}
   /// Returns the FGGroundCallback pointer.
   FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
   /// Retrieves the script object
@@ -408,19 +432,12 @@ public:
   /** Sets (or overrides) the output filename
       @param fname the name of the file to output data to
       @return true if successful, false if there is no output specified for the flight model */
-  bool SetOutputFileName(const string& fname) {
-    if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
-    else return false;
-    return true;
-  }
+  bool SetOutputFileName(const string& fname);
 
   /** Retrieves the current output filename.
       @return the name of the output file for the first output specified by the flight model.
               If none is specified, the empty string is returned. */
-  string GetOutputFileName(void) {
-    if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
-    else return string("");
-  }
+  string GetOutputFileName(void);
 
   /** Executes trimming in the selected mode.
   *   @param mode Specifies how to trim:
@@ -474,17 +491,13 @@ public:
 
   vector<string>& GetPropertyCatalog(void) {return PropertyCatalog;}
 
-  /// Use the MSIS atmosphere model.
-  void UseAtmosphereMSIS(void);
-
-  /// Use the Mars atmosphere model. (Not operative yet.)
-  void UseAtmosphereMars(void);
-
   void SetTrimStatus(bool status){ trim_status = status; }
   bool GetTrimStatus(void) const { return trim_status; }
   void SetTrimMode(int mode){ ta_mode = mode; }
   int GetTrimMode(void) const { return ta_mode; }
 
+  string GetPropulsionTankReport();
+
   /// Returns the cumulative simulation time in seconds.
   double GetSimTime(void) const { return sim_time; }
 
@@ -545,6 +558,7 @@ private:
   bool Constructing;
   bool modelLoaded;
   bool IsChild;
+  bool firstPass;
   string modelName;
   string AircraftPath;
   string FullAircraftPath;
@@ -554,23 +568,26 @@ private:
   string Release;
   string RootDir;
 
+  // Standard Model pointers - shortcuts for internal executive use only.
+  FGPropagate* Propagate;
+  FGInertial* Inertial;
+  FGAtmosphere* Atmosphere;
+  FGWinds* Winds;
+  FGAuxiliary* Auxiliary;
+  FGFCS* FCS;
+  FGPropulsion* Propulsion;
+  FGAerodynamics* Aerodynamics;
+  FGGroundReactions* GroundReactions;
+  FGExternalReactions* ExternalReactions;
+  FGBuoyantForces* BuoyantForces;
+  FGMassBalance* MassBalance;
+  FGAircraft* Aircraft;
+  FGAccelerations* Accelerations;
+
   bool trim_status;
   int ta_mode;
 
   FGGroundCallback*   GroundCallback;
-  FGAtmosphere*       Atmosphere;
-  FGFCS*              FCS;
-  FGPropulsion*       Propulsion;
-  FGMassBalance*      MassBalance;
-  FGAerodynamics*     Aerodynamics;
-  FGInertial*         Inertial;
-  FGGroundReactions*  GroundReactions;
-  FGExternalReactions* ExternalReactions;
-  FGBuoyantForces*    BuoyantForces;
-  FGAircraft*         Aircraft;
-  FGPropagate*        Propagate;
-  FGAuxiliary*        Auxiliary;
-  FGInput*            Input;
   FGScript*           Script;
   FGInitialCondition* IC;
   FGTrim*             Trim;
@@ -591,6 +608,9 @@ private:
   bool ReadChild(Element*);
   bool ReadPrologue(Element*);
   void ResetToInitialConditions(int mode);
+  void LoadInputs(unsigned int idx);
+  void LoadPlanetConstants(void);
+  void LoadModelConstants(void);
   bool Allocate(void);
   bool DeAllocate(void);
   void Initialize(FGInitialCondition *FGIC);
diff --git a/src/FDM/JSBSim/FGJSBBase.cpp b/src/FDM/JSBSim/FGJSBBase.cpp
index d34075e70..ccf098b59 100644
--- a/src/FDM/JSBSim/FGJSBBase.cpp
+++ b/src/FDM/JSBSim/FGJSBBase.cpp
@@ -44,7 +44,7 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.30 2011/06/13 11:47:04 jberndt Exp $";
+static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.31 2011/07/27 03:55:48 jberndt Exp $";
 static const char *IdHdr = ID_JSBBASE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -228,7 +228,8 @@ FGJSBBase::Message* FGJSBBase::ProcessNextMessage(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGJSBBase::disableHighLighting(void) {
+void FGJSBBase::disableHighLighting(void)
+{
   highint[0]='\0';
   halfint[0]='\0';
   normint[0]='\0';
diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h
index 69d9f9c09..50735c3f7 100644
--- a/src/FDM/JSBSim/FGJSBBase.h
+++ b/src/FDM/JSBSim/FGJSBBase.h
@@ -43,27 +43,20 @@ INCLUDES
 #include <string>
 #include <cmath>
 
+using std::min;
+using std::max;
+
 #include "input_output/string_utilities.h"
 
 #ifndef M_PI
 #  define M_PI 3.14159265358979323846
 #endif
 
-#if defined(_MSC_VER) && (_MSC_VER < 1300)
-namespace std
-{
-  template <class T> inline T max(const T& a, const T& b)
-  {
-    return (a > b) ? a : b;
-  }
-}
-#endif
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $"
+#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.33 2011/06/27 03:14:25 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -79,7 +72,7 @@ CLASS DOCUMENTATION
 *   This class provides universal constants, utility functions, messaging
 *   functions, and enumerated constants to JSBSim.
     @author Jon S. Berndt
-    @version $Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $
+    @version $Id: FGJSBBase.h,v 1.33 2011/06/27 03:14:25 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -269,7 +262,7 @@ public:
       @return if the two values can be considered equal up to roundoff */
   static bool EqualToRoundoff(double a, double b) {
     double eps = 2.0*DBL_EPSILON;
-    return std::fabs(a - b) <= eps*std::max(std::fabs(a), std::fabs(b));
+    return std::fabs(a - b) <= eps * max(std::fabs(a), std::fabs(b));
   }
 
   /** Finite precision comparison.
@@ -278,7 +271,7 @@ public:
       @return if the two values can be considered equal up to roundoff */
   static bool EqualToRoundoff(float a, float b) {
     float eps = 2.0*FLT_EPSILON;
-    return std::fabs(a - b) <= eps*std::max(std::fabs(a), std::fabs(b));
+    return std::fabs(a - b) <= eps * max(std::fabs(a), std::fabs(b));
   }
 
   /** Finite precision comparison.
diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index 94ca5a1dc..eed3c6873 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -60,6 +60,8 @@
 #include <FDM/JSBSim/models/FGLGear.h>
 #include <FDM/JSBSim/models/FGGroundReactions.h>
 #include <FDM/JSBSim/models/FGPropulsion.h>
+#include <FDM/JSBSim/models/FGAccelerations.h>
+#include <FDM/JSBSim/models/atmosphere/FGWinds.h>
 #include <FDM/JSBSim/models/propulsion/FGEngine.h>
 #include <FDM/JSBSim/models/propulsion/FGPiston.h>
 #include <FDM/JSBSim/models/propulsion/FGTurbine.h>
@@ -138,12 +140,11 @@ FGJSBsim::FGJSBsim( double dt )
 {
     bool result;
     if( TURBULENCE_TYPE_NAMES.empty() ) {
-        TURBULENCE_TYPE_NAMES["ttNone"]     = FGAtmosphere::ttNone;
-        TURBULENCE_TYPE_NAMES["ttStandard"] = FGAtmosphere::ttStandard;
-//      TURBULENCE_TYPE_NAMES["ttBerndt"]   = FGAtmosphere::ttBerndt;
-        TURBULENCE_TYPE_NAMES["ttCulp"]     = FGAtmosphere::ttCulp;
-        TURBULENCE_TYPE_NAMES["ttMilspec"]  = FGAtmosphere::ttMilspec;
-        TURBULENCE_TYPE_NAMES["ttTustin"]   = FGAtmosphere::ttTustin;
+        TURBULENCE_TYPE_NAMES["ttNone"]     = FGWinds::ttNone;
+        TURBULENCE_TYPE_NAMES["ttStandard"] = FGWinds::ttStandard;
+        TURBULENCE_TYPE_NAMES["ttCulp"]     = FGWinds::ttCulp;
+        TURBULENCE_TYPE_NAMES["ttMilspec"]  = FGWinds::ttMilspec;
+        TURBULENCE_TYPE_NAMES["ttTustin"]   = FGWinds::ttTustin;
     }
 
                                 // Set up the debugging level
@@ -177,6 +178,7 @@ FGJSBsim::FGJSBsim( double dt )
     fdmex->SetGroundCallback( new FGFSGroundCallback(this) );
 
     Atmosphere      = fdmex->GetAtmosphere();
+    Winds           = fdmex->GetWinds();
     FCS             = fdmex->GetFCS();
     MassBalance     = fdmex->GetMassBalance();
     Propulsion      = fdmex->GetPropulsion();
@@ -186,6 +188,7 @@ FGJSBsim::FGJSBsim( double dt )
     Inertial        = fdmex->GetInertial();
     Aerodynamics    = fdmex->GetAerodynamics();
     GroundReactions = fdmex->GetGroundReactions();
+    Accelerations   = fdmex->GetAccelerations();
 
     fgic=fdmex->GetIC();
     needTrim=true;
@@ -307,6 +310,7 @@ FGJSBsim::FGJSBsim( double dt )
     
     temperature = fgGetNode("/environment/temperature-degc",true);
     pressure = fgGetNode("/environment/pressure-inhg",true);
+    pressureSL = fgGetNode("/environment/pressure-sea-level-inhg",true);
     density = fgGetNode("/environment/density-slugft3",true);
     ground_wind = fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt",true);
     turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
@@ -354,21 +358,17 @@ void FGJSBsim::init()
     // init method first.
 
     if (fgGetBool("/environment/params/control-fdm-atmosphere")) {
-      Atmosphere->UseExternal();
-      Atmosphere->SetExTemperature(
-                  9.0/5.0*(temperature->getDoubleValue()+273.15) );
-      Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
-      Atmosphere->SetExDensity(density->getDoubleValue());
+      Atmosphere->SetTemperature(temperature->getDoubleValue(), get_Altitude(), FGAtmosphere::eCelsius);
+      Atmosphere->SetPressureSL(pressureSL->getDoubleValue(), FGAtmosphere::eInchesHg);
       // initialize to no turbulence, these values get set in the update loop
-      Atmosphere->SetTurbType(FGAtmosphere::ttNone);
-      Atmosphere->SetTurbGain(0.0);
-      Atmosphere->SetTurbRate(0.0);
-      Atmosphere->SetWindspeed20ft(0.0);
-      Atmosphere->SetProbabilityOfExceedence(0.0);
-    } else {
-      Atmosphere->UseInternal();
+      Winds->SetTurbType(FGWinds::ttNone);
+      Winds->SetTurbGain(0.0);
+      Winds->SetTurbRate(0.0);
+      Winds->SetWindspeed20ft(0.0);
+      Winds->SetProbabilityOfExceedence(0.0);
     }
 
+    fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
     fgic->SetWindNEDFpsIC( -wind_from_north->getDoubleValue(),
                            -wind_from_east->getDoubleValue(),
                            -wind_from_down->getDoubleValue() );
@@ -409,14 +409,14 @@ void FGJSBsim::init()
 
     if ( startup_trim->getBoolValue() ) {
       FGLocation cart(fgic->GetLongitudeRadIC(), fgic->GetLatitudeRadIC(),
-                    fgic->GetSeaLevelRadiusFtIC() + fgic->GetAltitudeASLFtIC());
+                      get_Sea_level_radius() + fgic->GetAltitudeASLFtIC());
       double cart_pos[3], contact[3], d[3], vel[3], agl;
       update_ground_cache(cart, cart_pos, 0.01);
 
       get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact,
                  d, vel, d, &agl);
       double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1]
-           + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC();
+           + contact[2]*contact[2]) - get_Sea_level_radius();
 
       SG_LOG(SG_FLIGHT, SG_INFO, "Ready to trim, terrain elevation is: "
                                  << terrain_alt * SG_METER_TO_FEET );
@@ -664,30 +664,27 @@ bool FGJSBsim::copy_to_JSBsim()
 
     Propagate->SetSeaLevelRadius( get_Sea_level_radius() );
 
-    Atmosphere->SetExTemperature(
-                  9.0/5.0*(temperature->getDoubleValue()+273.15) );
-    Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
-    Atmosphere->SetExDensity(density->getDoubleValue());
+    Atmosphere->SetTemperature(temperature->getDoubleValue(), get_Altitude(), FGAtmosphere::eCelsius);
+    Atmosphere->SetPressureSL(pressureSL->getDoubleValue(), FGAtmosphere::eInchesHg);
 
-    Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]);
-    switch( Atmosphere->GetTurbType() ) {
-//      case FGAtmosphere::ttBerndt:
-        case FGAtmosphere::ttStandard:
-        case FGAtmosphere::ttCulp: {
+    Winds->SetTurbType((FGWinds::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]);
+    switch( Winds->GetTurbType() ) {
+        case FGWinds::ttStandard:
+        case FGWinds::ttCulp: {
             double tmp = turbulence_gain->getDoubleValue();
-            Atmosphere->SetTurbGain(tmp * tmp * 100.0);
-            Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());
+            Winds->SetTurbGain(tmp * tmp * 100.0);
+            Winds->SetTurbRate(turbulence_rate->getDoubleValue());
             break;
         }
-        case FGAtmosphere::ttMilspec:
-        case FGAtmosphere::ttTustin: {
+        case FGWinds::ttMilspec:
+        case FGWinds::ttTustin: {
             // milspec turbulence: 3=light, 4=moderate, 6=severe turbulence
             // turbulence_gain normalized: 0: none, 1/3: light, 2/3: moderate, 3/3: severe
             double tmp = turbulence_gain->getDoubleValue();
-            Atmosphere->SetProbabilityOfExceedence(
+            Winds->SetProbabilityOfExceedence(
               SGMiscd::roundToInt(TurbulenceSeverityTable.GetValue( tmp ) )
             );
-            Atmosphere->SetWindspeed20ft(ground_wind->getDoubleValue());
+            Winds->SetWindspeed20ft(ground_wind->getDoubleValue());
             break;
         }
 
@@ -695,9 +692,9 @@ bool FGJSBsim::copy_to_JSBsim()
             break;
     }
 
-    Atmosphere->SetWindNED( -wind_from_north->getDoubleValue(),
-                            -wind_from_east->getDoubleValue(),
-                            -wind_from_down->getDoubleValue() );
+    Winds->SetWindNED( -wind_from_north->getDoubleValue(),
+                       -wind_from_east->getDoubleValue(),
+                       -wind_from_down->getDoubleValue() );
 //    SG_LOG(SG_FLIGHT,SG_INFO, "Wind NED: "
 //                  << get_V_north_airmass() << ", "
 //                  << get_V_east_airmass()  << ", "
@@ -739,19 +736,19 @@ bool FGJSBsim::copy_from_JSBsim()
                       MassBalance->GetXYZcg(2),
                       MassBalance->GetXYZcg(3) );
 
-    _set_Accels_Body( Aircraft->GetBodyAccel(1),
-                      Aircraft->GetBodyAccel(2),
-                      Aircraft->GetBodyAccel(3) );
+    _set_Accels_Body( Accelerations->GetBodyAccel(1),
+                      Accelerations->GetBodyAccel(2),
+                      Accelerations->GetBodyAccel(3) );
 
-    _set_Accels_CG_Body_N ( Aircraft->GetNcg(1),
-                            Aircraft->GetNcg(2),
-                            Aircraft->GetNcg(3) );
+    _set_Accels_CG_Body_N ( Auxiliary->GetNcg(1),
+                            Auxiliary->GetNcg(2),
+                            Auxiliary->GetNcg(3) );
 
     _set_Accels_Pilot_Body( Auxiliary->GetPilotAccel(1),
                             Auxiliary->GetPilotAccel(2),
                             Auxiliary->GetPilotAccel(3) );
 
-    _set_Nlf( Aircraft->GetNlf() );
+    _set_Nlf( Auxiliary->GetNlf() );
 
     // Velocities
 
@@ -812,7 +809,7 @@ bool FGJSBsim::copy_from_JSBsim()
 
     _set_Gamma_vert_rad( Auxiliary->GetGamma() );
 
-    _set_Earth_position_angle( Inertial->GetEarthPositionAngle() );
+    _set_Earth_position_angle( Propagate->GetEarthPositionAngle() );
 
     _set_Climb_Rate( Propagate->Gethdot() );
 
@@ -1349,7 +1346,7 @@ bool FGJSBsim::update_ground_cache(FGLocation cart, double* cart_pos, double dt)
                       << fgic->GetAltitudeASLFtIC());
 
     SG_LOG(SG_FLIGHT, SG_WARN, "sea level radius = "
-                      << fgic->GetSeaLevelRadiusFtIC());
+                      << get_Sea_level_radius());
 
     SG_LOG(SG_FLIGHT, SG_WARN, "latitude         = "
                       << fgic->GetLatitudeRadIC());
diff --git a/src/FDM/JSBSim/JSBSim.hxx b/src/FDM/JSBSim/JSBSim.hxx
index 4e8cf1880..a0294d5b5 100644
--- a/src/FDM/JSBSim/JSBSim.hxx
+++ b/src/FDM/JSBSim/JSBSim.hxx
@@ -58,6 +58,7 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 class FGAtmosphere;
+class FGWinds;
 class FGFCS;
 class FGPropulsion;
 class FGMassBalance;
@@ -69,6 +70,7 @@ class FGAuxiliary;
 class FGOutput;
 class FGInitialCondition;
 class FGLocation;
+class FGAccelerations;
 }
 
 // Adding it here will cause a namespace clash in FlightGear -EMH-
@@ -221,16 +223,18 @@ private:
     JSBSim::FGInitialCondition *fgic;
     bool needTrim;
 
-    JSBSim::FGAtmosphere*   Atmosphere;
-    JSBSim::FGFCS*          FCS;
-    JSBSim::FGPropulsion*   Propulsion;
-    JSBSim::FGMassBalance*  MassBalance;
-    JSBSim::FGAircraft*     Aircraft;
-    JSBSim::FGPropagate*    Propagate;
-    JSBSim::FGAuxiliary*    Auxiliary;
-    JSBSim::FGAerodynamics* Aerodynamics;
+    JSBSim::FGAtmosphere*      Atmosphere;
+    JSBSim::FGWinds*           Winds;
+    JSBSim::FGFCS*             FCS;
+    JSBSim::FGPropulsion*      Propulsion;
+    JSBSim::FGMassBalance*     MassBalance;
+    JSBSim::FGAircraft*        Aircraft;
+    JSBSim::FGPropagate*       Propagate;
+    JSBSim::FGAuxiliary*       Auxiliary;
+    JSBSim::FGAerodynamics*    Aerodynamics;
     JSBSim::FGGroundReactions* GroundReactions;
-    JSBSim::FGInertial*     Inertial;
+    JSBSim::FGInertial*        Inertial;
+    JSBSim::FGAccelerations*   Accelerations;
 
     int runcount;
     double trim_elev;
@@ -269,6 +273,7 @@ private:
 
     SGPropertyNode_ptr temperature;
     SGPropertyNode_ptr pressure;
+    SGPropertyNode_ptr pressureSL;
     SGPropertyNode_ptr density;
     SGPropertyNode_ptr ground_wind;
     SGPropertyNode_ptr turbulence_gain;
diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
index d1b65f1bc..fabae4c5c 100644
--- a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
+++ b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
@@ -44,6 +44,10 @@ you have chosen your IC's wisely) even after setting it up with this class.
 INCLUDES
 *******************************************************************************/
 
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+
 #include "FGInitialCondition.h"
 #include "FGFDMExec.h"
 #include "math/FGQuaternion.h"
@@ -51,17 +55,15 @@ INCLUDES
 #include "models/FGAtmosphere.h"
 #include "models/FGPropagate.h"
 #include "models/FGPropulsion.h"
+#include "models/FGFCS.h"
 #include "input_output/FGPropertyManager.h"
 #include "input_output/string_utilities.h"
-#include <iostream>
-#include <fstream>
-#include <cstdlib>
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.63 2011/06/13 10:30:22 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.69 2011/08/04 12:46:32 jberndt Exp $";
 static const char *IdHdr = ID_INITIALCONDITION;
 
 //******************************************************************************
@@ -134,7 +136,7 @@ void FGInitialCondition::InitializeIC(void)
   terrain_elevation = 0;
   sea_level_radius = fdmex->GetInertial()->GetRefRadius();
   position.SetPosition(0., 0., sea_level_radius);
-  position.SetEarthPositionAngle(fdmex->GetInertial()->GetEarthPositionAngle());
+  position.SetEarthPositionAngle(fdmex->GetPropagate()->GetEarthPositionAngle());
   vUVW_NED.InitMatrix();
   p=q=r=0;
   vt=0;
@@ -587,8 +589,9 @@ void FGInitialCondition::SetCrossWindKtsIC(double cross)
 
   // Gram-Schmidt process is used to remove the existing cross wind component
   _vWIND_NED -= DotProduct(_vWIND_NED, _vCROSS) * _vCROSS;
-  // which is now replaced by the new value.
-  _vWIND_NED += cross * _vCROSS;
+  // Which is now replaced by the new value. The input cross wind is expected
+  // in knots, so first convert to fps, which is the internal unit used.
+  _vWIND_NED += (cross * ktstofps) * _vCROSS;
   _vt_NED = vUVW_NED + _vWIND_NED;
   vt = _vt_NED.Magnitude();
 
@@ -604,13 +607,19 @@ void FGInitialCondition::SetHeadWindKtsIC(double head)
 {
   FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
   FGColumnVector3 _vWIND_NED = _vt_NED - vUVW_NED;
-  FGColumnVector3 _vHEAD(cos(psi), sin(psi), 0.);
+  // This is a head wind, so the direction vector for the wind
+  // needs to be set opposite to the heading the aircraft
+  // is taking. So, the cos and sin of the heading (psi)
+  // are negated in the line below.
+  FGColumnVector3 _vHEAD(-cos(psi), -sin(psi), 0.);
 
   // Gram-Schmidt process is used to remove the existing head wind component
   _vWIND_NED -= DotProduct(_vWIND_NED, _vHEAD) * _vHEAD;
-  // which is now replaced by the new value.
-  _vWIND_NED += head * _vHEAD;
+  // Which is now replaced by the new value. The input head wind is expected
+  // in knots, so first convert to fps, which is the internal unit used.
+  _vWIND_NED += (head * ktstofps) * _vHEAD;
   _vt_NED = vUVW_NED + _vWIND_NED;
+
   vt = _vt_NED.Magnitude();
 
   calcAeroAngles(_vt_NED);
@@ -644,9 +653,9 @@ void FGInitialCondition::SetWindMagKtsIC(double mag)
   double windMag = _vHEAD.Magnitude();
 
   if (windMag > 0.001)
-    _vHEAD *= mag / windMag;
+    _vHEAD *= (mag*ktstofps) / windMag;
   else
-    _vHEAD = FGColumnVector3(mag, 0., 0.);
+    _vHEAD = FGColumnVector3((mag*ktstofps), 0., 0.);
 
   _vWIND_NED(eU) = _vHEAD(eU);
   _vWIND_NED(eV) = _vHEAD(eV);
@@ -1028,7 +1037,7 @@ bool FGInitialCondition::Load_v2(void)
 {
   FGColumnVector3 vOrient;
   bool result = true;
-  FGColumnVector3 vOmegaEarth = FGColumnVector3(0.0, 0.0, fdmex->GetInertial()->omega());
+  FGColumnVector3 vOmegaEarth = fdmex->GetInertial()->GetOmegaPlanet();
 
   if (document->FindElement("earth_position_angle"))
     position.SetEarthPositionAngle(document->FindElementValueAsNumberConvertTo("earth_position_angle", "RAD"));
@@ -1325,10 +1334,6 @@ void FGInitialCondition::bind(void)
                        &FGInitialCondition::GetAltitudeAGLFtIC,
                        &FGInitialCondition::SetAltitudeAGLFtIC,
                        true);
-  PropertyManager->Tie("ic/sea-level-radius-ft", this,
-                       &FGInitialCondition::GetSeaLevelRadiusFtIC,
-                       &FGInitialCondition::SetSeaLevelRadiusFtIC,
-                       true);
   PropertyManager->Tie("ic/terrain-elevation-ft", this,
                        &FGInitialCondition::GetTerrainElevationFtIC,
                        &FGInitialCondition::SetTerrainElevationFtIC,
diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.h b/src/FDM/JSBSim/initialization/FGInitialCondition.h
index e110ebbb3..3b349e424 100644
--- a/src/FDM/JSBSim/initialization/FGInitialCondition.h
+++ b/src/FDM/JSBSim/initialization/FGInitialCondition.h
@@ -54,7 +54,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
+#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.28 2011/07/10 19:03:49 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -213,7 +213,7 @@ CLASS DOCUMENTATION
    @property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
 
    @author Tony Peden
-   @version "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
+   @version "$Id: FGInitialCondition.h,v 1.28 2011/07/10 19:03:49 jberndt Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -237,7 +237,7 @@ public:
   void SetVequivalentKtsIC(double ve);
 
   /** Set true airspeed initial condition in knots.
-      @param vt True airspeed in knots  */
+      @param vtrue True airspeed in knots  */
   void SetVtrueKtsIC(double vtrue) { SetVtrueFpsIC(vtrue*ktstofps); }
 
   /** Set ground speed initial condition in knots.
@@ -375,10 +375,6 @@ public:
       @return Initial altitude AGL in feet */
   double GetAltitudeAGLFtIC(void) const { return position.GetRadius() - sea_level_radius - terrain_elevation; }
 
-  /** Gets the initial sea level radius.
-      @return Initial sea level radius */
-  double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
-
   /** Gets the initial terrain elevation.
       @return Initial terrain elevation in feet */
   double GetTerrainElevationFtIC(void) const { return terrain_elevation; }
diff --git a/src/FDM/JSBSim/initialization/FGTrimAxis.cpp b/src/FDM/JSBSim/initialization/FGTrimAxis.cpp
index e0378793f..d2baa66df 100644
--- a/src/FDM/JSBSim/initialization/FGTrimAxis.cpp
+++ b/src/FDM/JSBSim/initialization/FGTrimAxis.cpp
@@ -43,19 +43,20 @@ INCLUDES
 #include "models/FGAtmosphere.h"
 #include "FGInitialCondition.h"
 #include "FGTrimAxis.h"
-#include "models/FGAircraft.h"
 #include "models/FGPropulsion.h"
 #include "models/FGAerodynamics.h"
 #include "models/FGFCS.h"
 #include "models/propulsion/FGEngine.h"
 #include "models/FGAuxiliary.h"
 #include "models/FGGroundReactions.h"
+#include "models/FGPropagate.h"
+#include "models/FGAccelerations.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTrimAxis.cpp,v 1.10 2010/07/08 11:36:28 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTrimAxis.cpp,v 1.13 2011/07/28 12:48:19 jberndt Exp $";
 static const char *IdHdr = ID_TRIMAXIS;
 
 /*****************************************************************************/
@@ -167,14 +168,14 @@ FGTrimAxis::~FGTrimAxis(void)
 
 void FGTrimAxis::getState(void) {
   switch(state) {
-  case tUdot: state_value=fdmex->GetPropagate()->GetUVWdot(1)-state_target; break;
-  case tVdot: state_value=fdmex->GetPropagate()->GetUVWdot(2)-state_target; break;
-  case tWdot: state_value=fdmex->GetPropagate()->GetUVWdot(3)-state_target; break;
-  case tQdot: state_value=fdmex->GetPropagate()->GetPQRdot(2)-state_target;break;
-  case tPdot: state_value=fdmex->GetPropagate()->GetPQRdot(1)-state_target; break;
-  case tRdot: state_value=fdmex->GetPropagate()->GetPQRdot(3)-state_target; break;
+  case tUdot: state_value=fdmex->GetAccelerations()->GetUVWdot(1)-state_target; break;
+  case tVdot: state_value=fdmex->GetAccelerations()->GetUVWdot(2)-state_target; break;
+  case tWdot: state_value=fdmex->GetAccelerations()->GetUVWdot(3)-state_target; break;
+  case tQdot: state_value=fdmex->GetAccelerations()->GetPQRdot(2)-state_target;break;
+  case tPdot: state_value=fdmex->GetAccelerations()->GetPQRdot(1)-state_target; break;
+  case tRdot: state_value=fdmex->GetAccelerations()->GetPQRdot(3)-state_target; break;
   case tHmgt: state_value=computeHmgt()-state_target; break;
-  case tNlf:  state_value=fdmex->GetAircraft()->GetNlf()-state_target; break;
+  case tNlf:  state_value=fdmex->GetAuxiliary()->GetNlf()-state_target; break;
   case tAll: break;
   }
 }
@@ -423,9 +424,12 @@ void FGTrimAxis::setThrottlesPct(void) {
   for(unsigned i=0;i<fdmex->GetPropulsion()->GetNumEngines();i++) {
       tMin=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMin();
       tMax=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMax();
-      //cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
+
+      // Both the main throttle setting in FGFCS and the copy of the position
+      // in the Propulsion::Inputs structure need to be set at this time.
       fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
-      //cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl;
+      fdmex->GetPropulsion()->in.ThrottlePos[i] = tMin +control_value*(tMax - tMin);
+
       fdmex->RunIC(); //apply throttle change
       fdmex->GetPropulsion()->GetSteadyState();
   }
diff --git a/src/FDM/JSBSim/input_output/FGScript.cpp b/src/FDM/JSBSim/input_output/FGScript.cpp
index 60d39ed9b..7a88d54ab 100755
--- a/src/FDM/JSBSim/input_output/FGScript.cpp
+++ b/src/FDM/JSBSim/input_output/FGScript.cpp
@@ -41,20 +41,21 @@ COMMENTS, REFERENCES,  and NOTES
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <iostream>
+#include <cstdlib>
+#include <iomanip>
+
 #include "FGScript.h"
 #include "input_output/FGXMLElement.h"
 #include "input_output/FGXMLParse.h"
 #include "initialization/FGTrim.h"
-
-#include <iostream>
-#include <cstdlib>
-#include <iomanip>
+#include "models/FGInput.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGScript.cpp,v 1.46 2011/02/18 12:44:16 jberndt Exp $";
+static const char *IdSrc = "$Id: FGScript.cpp,v 1.48 2011/09/07 02:36:04 jberndt Exp $";
 static const char *IdHdr = ID_FGSCRIPT;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -379,7 +380,12 @@ bool FGScript::RunScript(void)
         for (i=0; i<Events[ev_ctr].SetValue.size(); i++) {
           Events[ev_ctr].OriginalValue[i] = Events[ev_ctr].SetParam[i]->getDoubleValue();
           if (Events[ev_ctr].Functions[i] != 0) { // Parameter should be set to a function value
-            Events[ev_ctr].SetValue[i] = Events[ev_ctr].Functions[i]->GetValue();
+            try {
+              Events[ev_ctr].SetValue[i] = Events[ev_ctr].Functions[i]->GetValue();
+            } catch (string msg) {
+              std::cerr << std::endl << "A problem occurred in the execution of the script. " << msg << endl;
+              throw;
+            }
           }
           switch (Events[ev_ctr].Type[i]) {
           case FG_VALUE:
diff --git a/src/FDM/JSBSim/input_output/FGScript.h b/src/FDM/JSBSim/input_output/FGScript.h
index 1ef0cfaa3..c0f8acb74 100644
--- a/src/FDM/JSBSim/input_output/FGScript.h
+++ b/src/FDM/JSBSim/input_output/FGScript.h
@@ -37,18 +37,19 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGJSBBase.h"
+#include <vector>
+
 #include "FGFDMExec.h"
+#include "FGJSBBase.h"
 #include "math/FGFunction.h"
 #include "math/FGCondition.h"
-#include <vector>
 #include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FGSCRIPT "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
+#define ID_FGSCRIPT "$Id: FGScript.h,v 1.21 2011/08/04 12:46:32 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -157,7 +158,7 @@ CLASS DOCUMENTATION
     comes the &quot;run&quot; section, where the conditions are
     described in &quot;event&quot; clauses.</p>
     @author Jon S. Berndt
-    @version "$Id: FGScript.h,v 1.20 2011/02/11 12:43:28 jberndt Exp $"
+    @version "$Id: FGScript.h,v 1.21 2011/08/04 12:46:32 jberndt Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/input_output/FGXMLElement.cpp b/src/FDM/JSBSim/input_output/FGXMLElement.cpp
index 383603d32..96a03d74b 100755
--- a/src/FDM/JSBSim/input_output/FGXMLElement.cpp
+++ b/src/FDM/JSBSim/input_output/FGXMLElement.cpp
@@ -42,7 +42,7 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.32 2011/02/13 00:42:45 jberndt Exp $";
+static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.33 2011/08/05 12:28:20 jberndt Exp $";
 static const char *IdHdr = ID_XMLELEMENT;
 
 bool Element::converterIsInitialized = false;
@@ -64,6 +64,8 @@ Element::Element(const string& nm)
     // Length
     convert["M"]["FT"] = 3.2808399;
     convert["FT"]["M"] = 1.0/convert["M"]["FT"];
+    convert["CM"]["FT"] = 0.032808399;
+    convert["FT"]["CM"] = 1.0/convert["CM"]["FT"];
     convert["KM"]["FT"] = 3280.8399;
     convert["FT"]["KM"] = 1.0/convert["KM"]["FT"];
     convert["FT"]["IN"] = 12.0;
@@ -73,6 +75,8 @@ Element::Element(const string& nm)
     // Area
     convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
     convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
+    convert["CM2"]["FT2"] = convert["CM"]["FT"]*convert["CM"]["FT"];
+    convert["FT2"]["CM2"] = 1.0/convert["CM2"]["FT2"];
     convert["M2"]["IN2"] = convert["M"]["IN"]*convert["M"]["IN"];
     convert["IN2"]["M2"] = 1.0/convert["M2"]["IN2"];
     convert["FT2"]["IN2"] = 144.0;
diff --git a/src/FDM/JSBSim/math/FGFunction.cpp b/src/FDM/JSBSim/math/FGFunction.cpp
index c0d2e6afd..c3042221e 100755
--- a/src/FDM/JSBSim/math/FGFunction.cpp
+++ b/src/FDM/JSBSim/math/FGFunction.cpp
@@ -43,13 +43,65 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFunction.cpp,v 1.36 2011/04/05 20:20:21 andgi Exp $";
+static const char *IdSrc = "$Id: FGFunction.cpp,v 1.42 2011/09/07 02:36:04 jberndt Exp $";
 static const char *IdHdr = ID_FUNCTION;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+const std::string FGFunction::property_string = "property";
+const std::string FGFunction::value_string = "value";
+const std::string FGFunction::table_string = "table";
+const std::string FGFunction::p_string = "p";
+const std::string FGFunction::v_string = "v";
+const std::string FGFunction::t_string = "t";
+
+const std::string FGFunction::function_string = "function";
+const std::string FGFunction::description_string = "description";
+const std::string FGFunction::sum_string = "sum";
+const std::string FGFunction::difference_string = "difference";
+const std::string FGFunction::product_string = "product";
+const std::string FGFunction::quotient_string = "quotient";
+const std::string FGFunction::pow_string = "pow";
+const std::string FGFunction::exp_string = "exp";
+const std::string FGFunction::log2_string = "log2";
+const std::string FGFunction::ln_string = "ln";
+const std::string FGFunction::log10_string = "log10";
+const std::string FGFunction::abs_string = "abs";
+const std::string FGFunction::sign_string = "sign";
+const std::string FGFunction::sin_string = "sin";
+const std::string FGFunction::cos_string = "cos";
+const std::string FGFunction::tan_string = "tan";
+const std::string FGFunction::asin_string = "asin";
+const std::string FGFunction::acos_string = "acos";
+const std::string FGFunction::atan_string = "atan";
+const std::string FGFunction::atan2_string = "atan2";
+const std::string FGFunction::min_string = "min";
+const std::string FGFunction::max_string = "max";
+const std::string FGFunction::avg_string = "avg";
+const std::string FGFunction::fraction_string = "fraction";
+const std::string FGFunction::mod_string = "mod";
+const std::string FGFunction::random_string = "random";
+const std::string FGFunction::integer_string = "integer";
+const std::string FGFunction::rotation_alpha_local_string = "rotation_alpha_local";
+const std::string FGFunction::rotation_beta_local_string = "rotation_beta_local";
+const std::string FGFunction::rotation_gamma_local_string = "rotation_gamma_local";
+const std::string FGFunction::rotation_bf_to_wf_string = "rotation_bf_to_wf";
+const std::string FGFunction::rotation_wf_to_bf_string = "rotation_wf_to_bf";
+
+const std::string FGFunction::lessthan_string = "lt";
+const std::string FGFunction::lessequal_string = "le";
+const std::string FGFunction::greatthan_string = "gt";
+const std::string FGFunction::greatequal_string = "ge";
+const std::string FGFunction::equal_string = "eq";
+const std::string FGFunction::notequal_string = "nq";
+const std::string FGFunction::and_string = "and";
+const std::string FGFunction::or_string = "or";
+const std::string FGFunction::not_string = "not";
+const std::string FGFunction::ifthen_string = "ifthen";
+const std::string FGFunction::switch_string = "switch";
+
 FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& prefix)
                                       : PropertyManager(propMan), Prefix(prefix)
 {
@@ -59,40 +111,6 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
   cachedValue = -HUGE_VAL;
   invlog2val = 1.0/log10(2.0);
 
-  property_string = "property";
-  value_string = "value";
-  table_string = "table";
-  p_string = "p";
-  v_string = "v";
-  t_string = "t";
-
-  function_string = "function";
-  description_string = "description";
-  sum_string = "sum";
-  difference_string = "difference";
-  product_string = "product";
-  quotient_string = "quotient";
-  pow_string = "pow";
-  exp_string = "exp";
-  log2_string = "log2";
-  ln_string = "ln";
-  log10_string = "log10";
-  abs_string = "abs";
-  sin_string = "sin";
-  cos_string = "cos";
-  tan_string = "tan";
-  asin_string = "asin";
-  acos_string = "acos";
-  atan_string = "atan";
-  atan2_string = "atan2";
-  min_string = "min";
-  max_string = "max";
-  avg_string = "avg";
-  fraction_string = "fraction";
-  mod_string = "mod";
-  random_string = "random";
-  integer_string = "integer";
-
   Name = el->GetAttributeValue("name");
   operation = el->GetName();
 
@@ -116,6 +134,8 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
     Type = eLog10;
   } else if (operation == abs_string) {
     Type = eAbs;
+  } else if (operation == sign_string) {
+    Type = eSign;
   } else if (operation == sin_string) {
     Type = eSin;
   } else if (operation == exp_string) {
@@ -146,6 +166,38 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
     Type = eMod;
   } else if (operation == random_string) {
     Type = eRandom;
+  } else if (operation == rotation_alpha_local_string) {
+    Type = eRotation_alpha_local;
+  } else if (operation == rotation_beta_local_string) {
+    Type = eRotation_beta_local;
+  } else if (operation == rotation_gamma_local_string) {
+    Type = eRotation_gamma_local;
+  } else if (operation == rotation_bf_to_wf_string) {
+    Type = eRotation_bf_to_wf;
+  } else if (operation == rotation_wf_to_bf_string) {
+    Type = eRotation_wf_to_bf;
+  } else if (operation == lessthan_string) {
+    Type = eLT;
+  } else if (operation == lessequal_string) {
+    Type = eLE;
+  } else if (operation == greatthan_string) {
+    Type = eGT;
+  } else if (operation == greatequal_string) {
+    Type = eGE;
+  } else if (operation == equal_string) {
+    Type = eEQ;
+  } else if (operation == notequal_string) {
+    Type = eNE;
+  } else if (operation == and_string) {
+    Type = eAND;
+  } else if (operation == or_string) {
+    Type = eOR;
+  } else if (operation == not_string) {
+    Type = eNOT;
+  } else if (operation == ifthen_string) {
+    Type = eIfThen;
+  } else if (operation == switch_string) {
+    Type = eSwitch;
   } else if (operation != description_string) {
     cerr << "Bad operation " << operation << " detected in configuration file" << endl;
   }
@@ -197,6 +249,7 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
                operation == ln_string ||
                operation == log10_string ||
                operation == abs_string ||
+               operation == sign_string ||
                operation == sin_string ||
                operation == cos_string ||
                operation == tan_string ||
@@ -210,7 +263,23 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, const string& pr
                operation == integer_string ||
                operation == mod_string ||
                operation == random_string ||
-               operation == avg_string )
+               operation == avg_string ||
+               operation == rotation_alpha_local_string||
+               operation == rotation_beta_local_string||
+               operation == rotation_gamma_local_string||
+               operation == rotation_bf_to_wf_string||
+               operation == rotation_wf_to_bf_string ||
+               operation == lessthan_string ||
+               operation == lessequal_string ||
+               operation == greatthan_string ||
+               operation == greatequal_string ||
+               operation == equal_string ||
+               operation == notequal_string ||
+               operation == and_string ||
+               operation == or_string ||
+               operation == not_string ||
+               operation == ifthen_string ||
+               operation == switch_string)
     {
       Parameters.push_back(new FGFunction(PropertyManager, element, Prefix));
     } else if (operation != description_string) {
@@ -245,6 +314,18 @@ void FGFunction::cacheValue(bool cache)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+unsigned int FGFunction::GetBinary(double val) const
+{
+  val = fabs(val);
+  if (val < 1E-9) return 0;
+  else if (val-1 < 1E-9) return 1;
+  else {
+    throw("Malformed conditional check in function definition.");
+  }
+}
+  
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 double FGFunction::GetValue(void) const
 {
   unsigned int i;
@@ -300,6 +381,9 @@ double FGFunction::GetValue(void) const
   case eAbs:
     temp = fabs(temp);
     break;
+  case eSign:
+    temp =  temp < 0 ? -1:1; // 0.0 counts as positive.
+    break;
   case eSin:
     temp = sin(temp);
     break;
@@ -350,6 +434,262 @@ double FGFunction::GetValue(void) const
   case eRandom:
     temp = GaussianRandomNumber();
     break;
+  case eLT:
+    temp = (temp < Parameters[1]->GetValue())?1:0;
+    break;
+  case eLE:
+    temp = (temp <= Parameters[1]->GetValue())?1:0;
+    break;
+  case eGT:
+    temp = (temp > Parameters[1]->GetValue())?1:0;
+    break;
+  case eGE:
+    temp = (temp >= Parameters[1]->GetValue())?1:0;
+    break;
+  case eEQ:
+    temp = (temp == Parameters[1]->GetValue())?1:0;
+    break;
+  case eNE:
+    temp = (temp != Parameters[1]->GetValue())?1:0;
+    break;
+  case eAND:
+    {
+      bool flag = (GetBinary(temp) != 0u);
+      for (i=1; i<Parameters.size() && flag; i++) {
+        flag = (GetBinary(Parameters[i]->GetValue()) != 0);
+      }
+      temp = flag ? 1 : 0;
+    }
+    break;
+  case eOR:
+    {
+      bool flag = (GetBinary(temp) != 0);
+      for (i=1; i<Parameters.size() && !flag; i++) {
+        flag = (GetBinary(Parameters[i]->GetValue()) != 0);
+      }
+      temp = flag ? 1 : 0;
+    }
+    break;
+  case eNOT:
+    temp = (GetBinary(temp) != 0) ? 0 : 1;
+    break;
+  case eIfThen:
+    {
+      i = Parameters.size();
+      if (i != 3) {
+        if (GetBinary(temp) == 1) {
+          temp = Parameters[1]->GetValue();
+        } else {
+          temp = Parameters[2]->GetValue();
+        }
+      } else {
+        throw("Malformed if/then function statement");
+      }
+    }
+    break;
+  case eSwitch:
+    {
+      unsigned int n = Parameters.size()-1;
+      i = int(temp+0.5);
+      if (i >= 0u && i < n) {
+        temp = Parameters[i+1]->GetValue();
+      } else {
+        throw(string("The switch function index selected a value above the range of supplied values"
+                     " - not enough values were supplied."));
+      }
+    }
+    break;
+  case eRotation_alpha_local:
+    if (Parameters.size()==6) // calculates local angle of attack for skydiver body component
+        //Euler angles from the intermediate body frame to the local body frame must be from a z-y-x axis rotation order
+    {
+        double alpha = Parameters[0]->GetValue()*degtorad;
+        double beta = Parameters[1]->GetValue()*degtorad;
+        double gamma = Parameters[2]->GetValue()*degtorad;
+        double phi = Parameters[3]->GetValue()*degtorad;
+        double theta = Parameters[4]->GetValue()*degtorad;
+        double psi = Parameters[5]->GetValue()*degtorad;
+        double cphi2 = cos(-phi/2), ctht2 = cos(-theta/2), cpsi2 = cos(-psi/2);
+        double sphi2 = sin(-phi/2), stht2 = sin(-theta/2), spsi2 = sin(-psi/2);
+        double calpha2 = cos(-alpha/2), salpha2 = sin(-alpha/2);
+        double cbeta2 = cos(beta/2), sbeta2 = sin(beta/2);
+        double cgamma2 = cos(-gamma/2), sgamma2 = sin(-gamma/2);
+        //calculate local body frame to the intermediate body frame rotation quaternion
+        double At = cphi2*ctht2*cpsi2 - sphi2*stht2*spsi2;
+        double Ax = cphi2*stht2*spsi2 + sphi2*ctht2*cpsi2;
+        double Ay = cphi2*stht2*cpsi2 - sphi2*ctht2*spsi2;
+        double Az = cphi2*ctht2*spsi2 + sphi2*stht2*cpsi2;
+        //calculate the intermediate body frame to global wind frame rotation quaternion
+        double Bt = calpha2*cbeta2*cgamma2 - salpha2*sbeta2*sgamma2;
+        double Bx = calpha2*cbeta2*sgamma2 + salpha2*sbeta2*cgamma2;
+        double By = calpha2*sbeta2*sgamma2 + salpha2*cbeta2*cgamma2;
+        double Bz = calpha2*sbeta2*cgamma2 - salpha2*cbeta2*sgamma2;
+        //multiply quaternions
+        double Ct = At*Bt - Ax*Bx - Ay*By - Az*Bz;
+        double Cx = At*Bx + Ax*Bt + Ay*Bz - Az*By;
+        double Cy = At*By - Ax*Bz + Ay*Bt + Az*Bx;
+        double Cz = At*Bz + Ax*By - Ay*Bx + Az*Bt;
+        //calculate alpha_local
+        temp = -atan2(2*(Cy*Ct-Cx*Cz),(Ct*Ct+Cx*Cx-Cy*Cy-Cz*Cz));
+        temp *= radtodeg;
+    } else {
+      temp = 1;
+    }
+    break;
+  case eRotation_beta_local:
+    if (Parameters.size()==6) // calculates local angle of sideslip for skydiver body component
+        //Euler angles from the intermediate body frame to the local body frame must be from a z-y-x axis rotation order
+    {
+        double alpha = Parameters[0]->GetValue()*degtorad; //angle of attack of intermediate body frame
+        double beta = Parameters[1]->GetValue()*degtorad;  //sideslip angle of intermediate body frame
+        double gamma = Parameters[2]->GetValue()*degtorad; //roll angle of intermediate body frame
+        double phi = Parameters[3]->GetValue()*degtorad;   //x-axis Euler angle from the intermediate body frame to the local body frame
+        double theta = Parameters[4]->GetValue()*degtorad; //y-axis Euler angle from the intermediate body frame to the local body frame
+        double psi = Parameters[5]->GetValue()*degtorad;   //z-axis Euler angle from the intermediate body frame to the local body frame
+        double cphi2 = cos(-phi/2), ctht2 = cos(-theta/2), cpsi2 = cos(-psi/2);
+        double sphi2 = sin(-phi/2), stht2 = sin(-theta/2), spsi2 = sin(-psi/2);
+        double calpha2 = cos(-alpha/2), salpha2 = sin(-alpha/2);
+        double cbeta2 = cos(beta/2), sbeta2 = sin(beta/2);
+        double cgamma2 = cos(-gamma/2), sgamma2 = sin(-gamma/2);
+        //calculate local body frame to the intermediate body frame rotation quaternion
+        double At = cphi2*ctht2*cpsi2 - sphi2*stht2*spsi2;
+        double Ax = cphi2*stht2*spsi2 + sphi2*ctht2*cpsi2;
+        double Ay = cphi2*stht2*cpsi2 - sphi2*ctht2*spsi2;
+        double Az = cphi2*ctht2*spsi2 + sphi2*stht2*cpsi2;
+        //calculate the intermediate body frame to global wind frame rotation quaternion
+        double Bt = calpha2*cbeta2*cgamma2 - salpha2*sbeta2*sgamma2;
+        double Bx = calpha2*cbeta2*sgamma2 + salpha2*sbeta2*cgamma2;
+        double By = calpha2*sbeta2*sgamma2 + salpha2*cbeta2*cgamma2;
+        double Bz = calpha2*sbeta2*cgamma2 - salpha2*cbeta2*sgamma2;
+        //multiply quaternions
+        double Ct = At*Bt - Ax*Bx - Ay*By - Az*Bz;
+        double Cx = At*Bx + Ax*Bt + Ay*Bz - Az*By;
+        double Cy = At*By - Ax*Bz + Ay*Bt + Az*Bx;
+        double Cz = At*Bz + Ax*By - Ay*Bx + Az*Bt;
+        //calculate beta_local
+        temp = asin(2*(Cx*Cy+Cz*Ct));
+        temp *= radtodeg;
+    }
+    else // 
+    {temp = 1;}
+    break;
+  case eRotation_gamma_local:
+    if (Parameters.size()==6) // calculates local angle of attack for skydiver body component
+        //Euler angles from the intermediate body frame to the local body frame must be from a z-y-x axis rotation order
+        {
+        double alpha = Parameters[0]->GetValue()*degtorad; //angle of attack of intermediate body frame
+        double beta = Parameters[1]->GetValue()*degtorad;  //sideslip angle of intermediate body frame
+        double gamma = Parameters[2]->GetValue()*degtorad; //roll angle of intermediate body frame
+        double phi = Parameters[3]->GetValue()*degtorad;   //x-axis Euler angle from the intermediate body frame to the local body frame
+        double theta = Parameters[4]->GetValue()*degtorad; //y-axis Euler angle from the intermediate body frame to the local body frame
+        double psi = Parameters[5]->GetValue()*degtorad;   //z-axis Euler angle from the intermediate body frame to the local body frame
+        double cphi2 = cos(-phi/2), ctht2 = cos(-theta/2), cpsi2 = cos(-psi/2);
+        double sphi2 = sin(-phi/2), stht2 = sin(-theta/2), spsi2 = sin(-psi/2);
+        double calpha2 = cos(-alpha/2), salpha2 = sin(-alpha/2);
+        double cbeta2 = cos(beta/2), sbeta2 = sin(beta/2);
+        double cgamma2 = cos(-gamma/2), sgamma2 = sin(-gamma/2);
+        //calculate local body frame to the intermediate body frame rotation quaternion
+        double At = cphi2*ctht2*cpsi2 - sphi2*stht2*spsi2;
+        double Ax = cphi2*stht2*spsi2 + sphi2*ctht2*cpsi2;
+        double Ay = cphi2*stht2*cpsi2 - sphi2*ctht2*spsi2;
+        double Az = cphi2*ctht2*spsi2 + sphi2*stht2*cpsi2;
+        //calculate the intermediate body frame to global wind frame rotation quaternion
+        double Bt = calpha2*cbeta2*cgamma2 - salpha2*sbeta2*sgamma2;
+        double Bx = calpha2*cbeta2*sgamma2 + salpha2*sbeta2*cgamma2;
+        double By = calpha2*sbeta2*sgamma2 + salpha2*cbeta2*cgamma2;
+        double Bz = calpha2*sbeta2*cgamma2 - salpha2*cbeta2*sgamma2;
+        //multiply quaternions
+        double Ct = At*Bt - Ax*Bx - Ay*By - Az*Bz;
+        double Cx = At*Bx + Ax*Bt + Ay*Bz - Az*By;
+        double Cy = At*By - Ax*Bz + Ay*Bt + Az*Bx;
+        double Cz = At*Bz + Ax*By - Ay*Bx + Az*Bt;
+        //calculate local roll anlge
+        temp = -atan2(2*(Cx*Ct-Cz*Cy),(Ct*Ct-Cx*Cx+Cy*Cy-Cz*Cz));
+        temp *= radtodeg;
+    }
+    else // 
+    {temp = 1;}
+    break;
+  case eRotation_bf_to_wf:
+    if (Parameters.size()==7) // transforms the input vector from a body frame to a wind frame.  The origin of the vector remains the same.
+    {
+        double rx = Parameters[0]->GetValue();             //x component of input vector
+        double ry = Parameters[1]->GetValue();             //y component of input vector
+        double rz = Parameters[2]->GetValue();             //z component of input vector
+        double alpha = Parameters[3]->GetValue()*degtorad; //angle of attack of the body frame
+        double beta = Parameters[4]->GetValue()*degtorad;  //sideslip angle of the body frame
+        double gamma = Parameters[5]->GetValue()*degtorad; //roll angle of the body frame
+        double index = Parameters[6]->GetValue();
+        double calpha2 = cos(-alpha/2), salpha2 = sin(-alpha/2);
+        double cbeta2 = cos(beta/2), sbeta2 = sin(beta/2);
+        double cgamma2 = cos(-gamma/2), sgamma2 = sin(-gamma/2);
+        //calculate the body frame to wind frame quaternion
+        double qt = calpha2*cbeta2*cgamma2 - salpha2*sbeta2*sgamma2;
+        double qx = calpha2*cbeta2*sgamma2 + salpha2*sbeta2*cgamma2;
+        double qy = calpha2*sbeta2*sgamma2 + salpha2*cbeta2*cgamma2;
+        double qz = calpha2*sbeta2*cgamma2 - salpha2*cbeta2*sgamma2;
+        //calculate the quaternion conjugate
+        double qstart = qt;
+        double qstarx = -qx;
+        double qstary = -qy;
+        double qstarz = -qz;
+        //multiply quaternions v*q
+        double vqt = -rx*qx - ry*qy - rz*qz;
+        double vqx =  rx*qt + ry*qz - rz*qy;
+        double vqy = -rx*qz + ry*qt + rz*qx;
+        double vqz =  rx*qy - ry*qx + rz*qt;
+        //multiply quaternions qstar*vq
+        double Cx = qstart*vqx + qstarx*vqt + qstary*vqz - qstarz*vqy;
+        double Cy = qstart*vqy - qstarx*vqz + qstary*vqt + qstarz*vqx;
+        double Cz = qstart*vqz + qstarx*vqy - qstary*vqx + qstarz*vqt;
+
+        if (index == 1)     temp = Cx;
+        else if (index ==2) temp = Cy;
+        else                temp = Cz;
+    }
+    else // 
+    {temp = 1;}
+    break;
+  case eRotation_wf_to_bf:
+    if (Parameters.size()==7) // transforms the input vector from q wind frame to a body frame.  The origin of the vector remains the same.
+    {
+        double rx = Parameters[0]->GetValue();             //x component of input vector
+        double ry = Parameters[1]->GetValue();             //y component of input vector
+        double rz = Parameters[2]->GetValue();             //z component of input vector
+        double alpha = Parameters[3]->GetValue()*degtorad; //angle of attack of the body frame
+        double beta = Parameters[4]->GetValue()*degtorad;  //sideslip angle of the body frame
+        double gamma = Parameters[5]->GetValue()*degtorad; //roll angle of the body frame
+        double index = Parameters[6]->GetValue();
+        double calpha2 = cos(alpha/2), salpha2 = sin(alpha/2);
+        double cbeta2 = cos(-beta/2), sbeta2 = sin(-beta/2);
+        double cgamma2 = cos(gamma/2), sgamma2 = sin(gamma/2);
+        //calculate the wind frame to body frame quaternion
+        double qt =  cgamma2*cbeta2*calpha2 + sgamma2*sbeta2*salpha2;
+        double qx = -cgamma2*sbeta2*salpha2 + sgamma2*cbeta2*calpha2;
+        double qy =  cgamma2*cbeta2*salpha2 - sgamma2*sbeta2*calpha2;
+        double qz =  cgamma2*sbeta2*calpha2 + sgamma2*cbeta2*salpha2;
+        //calculate the quaternion conjugate
+        double qstart =  qt;
+        double qstarx = -qx;
+        double qstary = -qy;
+        double qstarz = -qz;
+        //multiply quaternions v*q
+        double vqt = -rx*qx - ry*qy - rz*qz;
+        double vqx =  rx*qt + ry*qz - rz*qy;
+        double vqy = -rx*qz + ry*qt + rz*qx;
+        double vqz =  rx*qy - ry*qx + rz*qt;
+        //multiply quaternions qstar*vq
+        double Cx = qstart*vqx + qstarx*vqt + qstary*vqz - qstarz*vqy;
+        double Cy = qstart*vqy - qstarx*vqz + qstary*vqt + qstarz*vqx;
+        double Cz = qstart*vqz + qstarx*vqy - qstary*vqx + qstarz*vqt;
+
+        if (index == 1)     temp = Cx;
+        else if (index ==2) temp = Cy;
+        else                temp = Cz;
+    }
+    else // 
+    {temp = 1;}
+    break;
   default:
     cerr << "Unknown function operation type" << endl;
     break;
diff --git a/src/FDM/JSBSim/math/FGFunction.h b/src/FDM/JSBSim/math/FGFunction.h
old mode 100644
new mode 100755
index 91a811f9a..f3277eb6c
--- a/src/FDM/JSBSim/math/FGFunction.h
+++ b/src/FDM/JSBSim/math/FGFunction.h
@@ -42,7 +42,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FUNCTION "$Id: FGFunction.h,v 1.21 2009/11/18 04:49:02 jberndt Exp $"
+#define ID_FUNCTION "$Id: FGFunction.h,v 1.24 2011/08/06 13:10:00 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -86,6 +86,17 @@ A function definition consists of an operation, a value, a table, or a property
 - avg (takes n args)
 - fraction
 - mod
+- lt (less than, takes 2 args)
+- le (less equal, takes 2 args)
+- gt (greater than, takes 2 args)
+- ge (greater than, takes 2 args)
+- eq (equal, takes 2 args)
+- nq (not equal, takes 2 args)
+- and (takes n args)
+- or (takes n args)
+- not (takes 1 args)
+- if-then (takes 2-3 args)
+- switch (takes 2 or more args)
 - random (Gaussian random number)
 - integer
 
@@ -198,43 +209,65 @@ private:
   bool cached;
   double invlog2val;
   std::string Prefix;
-  std::string description_string;
-  std::string property_string;
-  std::string value_string;
-  std::string table_string;
-  std::string p_string;
-  std::string v_string;
-  std::string t_string;
-  std::string function_string;
-  std::string sum_string;
-  std::string difference_string;
-  std::string product_string;
-  std::string quotient_string;
-  std::string pow_string;
-  std::string exp_string;
-  std::string log2_string;
-  std::string ln_string;
-  std::string log10_string;
-  std::string abs_string;
-  std::string sin_string;
-  std::string cos_string;
-  std::string tan_string;
-  std::string asin_string;
-  std::string acos_string;
-  std::string atan_string;
-  std::string atan2_string;
-  std::string min_string;
-  std::string max_string;
-  std::string avg_string;
-  std::string fraction_string;
-  std::string mod_string;
-  std::string random_string;
-  std::string integer_string;
+  static const std::string description_string;
+  static const std::string property_string;
+  static const std::string value_string;
+  static const std::string table_string;
+  static const std::string p_string;
+  static const std::string v_string;
+  static const std::string t_string;
+  static const std::string function_string;
+  static const std::string sum_string;
+  static const std::string difference_string;
+  static const std::string product_string;
+  static const std::string quotient_string;
+  static const std::string pow_string;
+  static const std::string exp_string;
+  static const std::string log2_string;
+  static const std::string ln_string;
+  static const std::string log10_string;
+  static const std::string abs_string;
+  static const std::string sign_string;
+  static const std::string sin_string;
+  static const std::string cos_string;
+  static const std::string tan_string;
+  static const std::string asin_string;
+  static const std::string acos_string;
+  static const std::string atan_string;
+  static const std::string atan2_string;
+  static const std::string min_string;
+  static const std::string max_string;
+  static const std::string avg_string;
+  static const std::string fraction_string;
+  static const std::string mod_string;
+  static const std::string random_string;
+  static const std::string integer_string;
+  static const std::string rotation_alpha_local_string;
+  static const std::string rotation_beta_local_string;
+  static const std::string rotation_gamma_local_string;
+  static const std::string rotation_bf_to_wf_string;
+  static const std::string rotation_wf_to_bf_string;
+  static const std::string lessthan_string;
+  static const std::string lessequal_string;
+  static const std::string greatthan_string;
+  static const std::string greatequal_string;
+  static const std::string equal_string;
+  static const std::string notequal_string;
+  static const std::string and_string;
+  static const std::string or_string;
+  static const std::string not_string;
+  static const std::string ifthen_string;
+  static const std::string switch_string;
   double cachedValue;
   enum functionType {eTopLevel=0, eProduct, eDifference, eSum, eQuotient, ePow,
-                     eExp, eAbs, eSin, eCos, eTan, eASin, eACos, eATan, eATan2,
-                     eMin, eMax, eAvg, eFrac, eInteger, eMod, eRandom, eLog2, eLn, eLog10} Type;
+                     eExp, eAbs, eSign, eSin, eCos, eTan, eASin, eACos, eATan, eATan2,
+                     eMin, eMax, eAvg, eFrac, eInteger, eMod, eRandom, eLog2, eLn,
+                     eLog10, eLT, eLE, eGE, eGT, eEQ, eNE,  eAND, eOR, eNOT,
+                     eIfThen, eSwitch, eRotation_alpha_local, eRotation_beta_local,
+                     eRotation_gamma_local, eRotation_bf_to_wf, eRotation_wf_to_bf} Type;
   std::string Name;
+
+  unsigned int GetBinary(double) const;
   void bind(void);
   void Debug(int from);
 };
diff --git a/src/FDM/JSBSim/math/FGLocation.h b/src/FDM/JSBSim/math/FGLocation.h
index c60e8ea2e..743d6ea09 100644
--- a/src/FDM/JSBSim/math/FGLocation.h
+++ b/src/FDM/JSBSim/math/FGLocation.h
@@ -48,7 +48,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_LOCATION "$Id: FGLocation.h,v 1.27 2010/11/29 12:33:58 jberndt Exp $"
+#define ID_LOCATION "$Id: FGLocation.h,v 1.28 2011/08/04 12:46:32 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -142,7 +142,7 @@ CLASS DOCUMENTATION
     @see W. C. Durham "Aircraft Dynamics & Control", section 2.2
 
     @author Mathias Froehlich
-    @version $Id: FGLocation.h,v 1.27 2010/11/29 12:33:58 jberndt Exp $
+    @version $Id: FGLocation.h,v 1.28 2011/08/04 12:46:32 jberndt Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -229,6 +229,13 @@ public:
                  respect to the Inertial (ECI) frame in radians. */
   void SetEarthPositionAngle(double EPA) {epa = EPA; mCacheValid = false;}
 
+  /** Increments the Earth position angle.
+      This is the relative orientation of the ECEF frame with respect to the
+      Inertial frame.
+      @param delta delta to the Earth fixed frame (ECEF) rotation offset about the axis with
+                 respect to the Inertial (ECI) frame in radians. */
+  void IncrementEarthPositionAngle(double delta) {epa += delta; mCacheValid = false;}
+
   /** Get the longitude.
       @return the longitude in rad of the location represented with this
       class instance. The returned values are in the range between
@@ -290,6 +297,8 @@ public:
       return -mTec2l(3,3)/cLat;
   }
 
+  double GetEPA() const {return epa;}
+
   /** Get the distance from the center of the earth.
       @return the distance of the location represented with this class
       instance to the center of the earth in ft. The radius value is
diff --git a/src/FDM/JSBSim/math/FGModelFunctions.h b/src/FDM/JSBSim/math/FGModelFunctions.h
old mode 100644
new mode 100755
index 2b3f94e17..b47604b6c
--- a/src/FDM/JSBSim/math/FGModelFunctions.h
+++ b/src/FDM/JSBSim/math/FGModelFunctions.h
@@ -44,7 +44,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_MODELFUNCTIONS "$Id: FGModelFunctions.h,v 1.3 2010/11/17 03:18:37 jberndt Exp $"
+#define ID_MODELFUNCTIONS "$Id: FGModelFunctions.h,v 1.4 2011/06/21 04:41:54 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -76,7 +76,7 @@ DECLARATION: FGModelFunctions
 class FGModelFunctions : public FGJSBBase
 {
 public:
-  ~FGModelFunctions();
+  virtual ~FGModelFunctions();
   void RunPreFunctions(void);
   void RunPostFunctions(void);
   bool Load(Element* el, FGPropertyManager* PropertyManager, std::string prefix="");
diff --git a/src/FDM/JSBSim/math/LagrangeMultiplier.h b/src/FDM/JSBSim/math/LagrangeMultiplier.h
new file mode 100755
index 000000000..b754c5b38
--- /dev/null
+++ b/src/FDM/JSBSim/math/LagrangeMultiplier.h
@@ -0,0 +1,67 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       LaGrangeMultiplier.h
+ Author:       Bertrand Coconnier
+ Date started: 07/01/11
+
+ ------------- Copyright (C) 2011  Bertrand Coconnier -------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser 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 Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef LAGRANGEMULTIPLIER_H
+#define LAGRANGEMULTIPLIER_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_LAGRANGEMULTIPLIER "$Id: LagrangeMultiplier.h,v 1.2 2011/08/21 15:13:22 bcoconni Exp $"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+  
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+struct LagrangeMultiplier {
+  FGColumnVector3 ForceJacobian;
+  FGColumnVector3 MomentJacobian;
+  double Min;
+  double Max;
+  double value;
+};
+
+} // namespace
+
+#endif
diff --git a/src/FDM/JSBSim/math/Makefile.am b/src/FDM/JSBSim/math/Makefile.am
index b97253ac3..5e1282ef0 100644
--- a/src/FDM/JSBSim/math/Makefile.am
+++ b/src/FDM/JSBSim/math/Makefile.am
@@ -6,6 +6,6 @@ libMath_a_SOURCES = FGColumnVector3.cpp FGFunction.cpp FGLocation.cpp FGMatrix33
 
 noinst_HEADERS = FGColumnVector3.h FGFunction.h FGLocation.h FGMatrix33.h \
                  FGParameter.h FGPropertyValue.h FGQuaternion.h FGRealValue.h FGTable.h  \
-                 FGCondition.h FGRungeKutta.h FGModelFunctions.h
+                 FGCondition.h FGRungeKutta.h FGModelFunctions.h LagrangeMultiplier.h
 
 INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
diff --git a/src/FDM/JSBSim/models/FGAccelerations.cpp b/src/FDM/JSBSim/models/FGAccelerations.cpp
new file mode 100644
index 000000000..3df618a4f
--- /dev/null
+++ b/src/FDM/JSBSim/models/FGAccelerations.cpp
@@ -0,0 +1,397 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Module:       FGAccelerations.cpp
+ Author:       Jon S. Berndt
+ Date started: 07/12/11
+ Purpose:      Calculates derivatives of rotational and translational rates, and
+               of the attitude quaternion.
+ Called by:    FGFDMExec
+
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser 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 Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+This class encapsulates the calculation of the derivatives of the state vectors
+UVW and PQR - the translational and rotational rates relative to the planet 
+fixed frame. The derivatives relative to the inertial frame are also calculated
+as a side effect. Also, the derivative of the attitude quaterion is also calculated.
+
+HISTORY
+--------------------------------------------------------------------------------
+07/12/11   JSB   Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES,  and NOTES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+[1] Stevens and Lewis, "Aircraft Control and Simulation", Second edition (2004)
+    Wiley
+[2] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
+    NASA-Ames", NASA CR-2497, January 1975
+[3] Erin Catto, "Iterative Dynamics with Temporal Coherence", February 22, 2005
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include "FGAccelerations.h"
+#include "FGFDMExec.h"
+#include "input_output/FGPropertyManager.h"
+
+using namespace std;
+
+namespace JSBSim {
+
+static const char *IdSrc = "$Id: FGAccelerations.cpp,v 1.8 2011/08/30 20:49:04 bcoconni Exp $";
+static const char *IdHdr = ID_ACCELERATIONS;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS IMPLEMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+FGAccelerations::FGAccelerations(FGFDMExec* fdmex)
+  : FGModel(fdmex)
+{
+  Debug(0);
+  Name = "FGAccelerations";
+  gravType = gtWGS84;
+ 
+  vPQRidot.InitMatrix();
+  vUVWidot.InitMatrix();
+  vGravAccel.InitMatrix();
+  vBodyAccel.InitMatrix();
+  vQtrndot = FGQuaternion(0,0,0);
+
+  bind();
+  Debug(0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGAccelerations::~FGAccelerations(void)
+{
+  Debug(1);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGAccelerations::InitModel(void)
+{
+  vPQRidot.InitMatrix();
+  vUVWidot.InitMatrix();
+  vGravAccel.InitMatrix();
+  vBodyAccel.InitMatrix();
+  vQtrndot = FGQuaternion(0,0,0);
+
+  return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/*
+Purpose: Called on a schedule to calculate derivatives.
+*/
+
+bool FGAccelerations::Run(bool Holding)
+{
+  if (FGModel::Run(Holding)) return true;  // Fast return if we have nothing to do ...
+  if (Holding) return false;
+
+  RunPreFunctions();
+
+  CalculatePQRdot();   // Angular rate derivative
+  CalculateUVWdot();   // Translational rate derivative
+  CalculateQuatdot();  // Angular orientation derivative
+
+  ResolveFrictionForces(in.DeltaT * rate);  // Update rate derivatives with friction forces
+
+  RunPostFunctions();
+
+  Debug(2);
+  return false;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// Compute body frame rotational accelerations based on the current body moments
+//
+// vPQRdot is the derivative of the absolute angular velocity of the vehicle 
+// (body rate with respect to the inertial frame), expressed in the body frame,
+// where the derivative is taken in the body frame.
+// J is the inertia matrix
+// Jinv is the inverse inertia matrix
+// vMoments is the moment vector in the body frame
+// in.vPQRi is the total inertial angular velocity of the vehicle
+// expressed in the body frame.
+// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
+//            Second edition (2004), eqn 1.5-16e (page 50)
+
+void FGAccelerations::CalculatePQRdot(void)
+{
+  // Compute body frame rotational accelerations based on the current body
+  // moments and the total inertial angular velocity expressed in the body
+  // frame.
+
+  vPQRidot = in.Jinv * (in.Moment - in.vPQRi * (in.J * in.vPQRi));
+  vPQRdot = vPQRidot - in.vPQRi * (in.Ti2b * in.vOmegaPlanet);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// Compute the quaternion orientation derivative
+//
+// vQtrndot is the quaternion derivative.
+// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
+//            Second edition (2004), eqn 1.5-16b (page 50)
+
+void FGAccelerations::CalculateQuatdot(void)
+{
+  // Compute quaternion orientation derivative on current body rates
+  vQtrndot = in.qAttitudeECI.GetQDot(in.vPQRi);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// This set of calculations results in the body and inertial frame accelerations
+// being computed.
+// Compute body and inertial frames accelerations based on the current body
+// forces including centripetal and coriolis accelerations for the former.
+// in.vOmegaPlanet is the Earth angular rate - expressed in the inertial frame -
+//   so it has to be transformed to the body frame. More completely,
+//   in.vOmegaPlanet is the rate of the ECEF frame relative to the Inertial
+//   frame (ECI), expressed in the Inertial frame.
+// in.Force is the total force on the vehicle in the body frame.
+// in.vPQR is the vehicle body rate relative to the ECEF frame, expressed
+//   in the body frame.
+// in.vUVW is the vehicle velocity relative to the ECEF frame, expressed
+//   in the body frame.
+// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
+//            Second edition (2004), eqns 1.5-13 (pg 48) and 1.5-16d (page 50)
+
+void FGAccelerations::CalculateUVWdot(void)
+{
+  vBodyAccel = in.Force / in.Mass;
+
+  vUVWdot = vBodyAccel - (in.vPQR + 2.0 * (in.Ti2b * in.vOmegaPlanet)) * in.vUVW;
+
+  // Include Centripetal acceleration.
+  vUVWdot -= in.Ti2b * (in.vOmegaPlanet * (in.vOmegaPlanet * in.vInertialPosition));
+
+  // Include Gravitation accel
+  switch (gravType) {
+    case gtStandard:
+      vGravAccel = in.Tl2b * FGColumnVector3( 0.0, 0.0, in.GAccel );
+      break;
+    case gtWGS84:
+      vGravAccel = in.Tec2b * in.J2Grav;
+      break;
+  }
+
+  vUVWdot += vGravAccel;
+  vUVWidot = in.Tb2i * (vBodyAccel + vGravAccel);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// Resolves the contact forces just before integrating the EOM.
+// This routine is using Lagrange multipliers and the projected Gauss-Seidel
+// (PGS) method.
+// Reference: See Erin Catto, "Iterative Dynamics with Temporal Coherence", 
+//            February 22, 2005
+// In JSBSim there is only one rigid body (the aircraft) and there can be
+// multiple points of contact between the aircraft and the ground. As a
+// consequence our matrix J*M^-1*J^T is not sparse and the algorithm described
+// in Catto's paper has been adapted accordingly.
+// The friction forces are resolved in the body frame relative to the origin
+// (Earth center).
+
+void FGAccelerations::ResolveFrictionForces(double dt)
+{
+  const double invMass = 1.0 / in.Mass;
+  const FGMatrix33& Jinv = in.Jinv;
+  FGColumnVector3 vdot, wdot;
+  vector<LagrangeMultiplier*>& multipliers = *in.MultipliersList;
+  int n = multipliers.size();
+
+  vFrictionForces.InitMatrix();
+  vFrictionMoments.InitMatrix();
+
+  // If no gears are in contact with the ground then return
+  if (!n) return;
+
+  vector<double> a(n*n); // Will contain J*M^-1*J^T
+  vector<double> rhs(n);
+
+  // Assemble the linear system of equations
+  for (int i=0; i < n; i++) {
+    FGColumnVector3 v1 = invMass * multipliers[i]->ForceJacobian;
+    FGColumnVector3 v2 = Jinv * multipliers[i]->MomentJacobian; // Should be J^-T but J is symmetric and so is J^-1
+
+    for (int j=0; j < i; j++)
+      a[i*n+j] = a[j*n+i]; // Takes advantage of the symmetry of J^T*M^-1*J
+    for (int j=i; j < n; j++)
+      a[i*n+j] = DotProduct(v1, multipliers[j]->ForceJacobian)
+               + DotProduct(v2, multipliers[j]->MomentJacobian);
+  }
+
+  // Assemble the RHS member
+
+  // Translation
+  vdot = vUVWdot;
+  if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
+    vdot += (in.vUVW - in.Tec2b * in.TerrainVelocity) / dt;
+
+  // Rotation
+  wdot = vPQRdot;
+  if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
+    wdot += (in.vPQR - in.Tec2b * in.TerrainAngularVel) / dt;
+
+  // Prepare the linear system for the Gauss-Seidel algorithm :
+  // 1. Compute the right hand side member 'rhs'
+  // 2. Divide every line of 'a' and 'rhs' by a[i,i]. This is in order to save
+  //    a division computation at each iteration of Gauss-Seidel.
+  for (int i=0; i < n; i++) {
+    double d = 1.0 / a[i*n+i];
+
+    rhs[i] = -(DotProduct(multipliers[i]->ForceJacobian, vdot)
+              +DotProduct(multipliers[i]->MomentJacobian, wdot))*d;
+    for (int j=0; j < n; j++)
+      a[i*n+j] *= d;
+  }
+
+  // Resolve the Lagrange multipliers with the projected Gauss-Seidel method
+  for (int iter=0; iter < 50; iter++) {
+    double norm = 0.;
+
+    for (int i=0; i < n; i++) {
+      double lambda0 = multipliers[i]->value;
+      double dlambda = rhs[i];
+      
+      for (int j=0; j < n; j++)
+        dlambda -= a[i*n+j]*multipliers[j]->value;
+
+      multipliers[i]->value = Constrain(multipliers[i]->Min, lambda0+dlambda, multipliers[i]->Max);
+      dlambda = multipliers[i]->value - lambda0;
+
+      norm += fabs(dlambda);
+    }
+
+    if (norm < 1E-5) break;
+  }
+
+  // Calculate the total friction forces and moments
+
+  for (int i=0; i< n; i++) {
+    double lambda = multipliers[i]->value;
+    vFrictionForces += lambda * multipliers[i]->ForceJacobian;
+    vFrictionMoments += lambda * multipliers[i]->MomentJacobian;
+  }
+
+  FGColumnVector3 accel = invMass * vFrictionForces;
+  FGColumnVector3 omegadot = Jinv * vFrictionMoments;
+
+  vBodyAccel += accel;
+  vUVWdot += accel;
+  vUVWidot += in.Tb2i * accel;
+  vPQRdot += omegadot;
+  vPQRidot += omegadot;
+}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGAccelerations::InitializeDerivatives(void)
+{
+  // Make an initial run and set past values
+  CalculatePQRdot();           // Angular rate derivative
+  CalculateUVWdot();           // Translational rate derivative
+  CalculateQuatdot();          // Angular orientation derivative
+  ResolveFrictionForces(0.);   // Update rate derivatives with friction forces
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGAccelerations::bind(void)
+{
+  typedef double (FGAccelerations::*PMF)(int) const;
+
+  PropertyManager->Tie("accelerations/pdot-rad_sec2", this, eP, (PMF)&FGAccelerations::GetPQRdot);
+  PropertyManager->Tie("accelerations/qdot-rad_sec2", this, eQ, (PMF)&FGAccelerations::GetPQRdot);
+  PropertyManager->Tie("accelerations/rdot-rad_sec2", this, eR, (PMF)&FGAccelerations::GetPQRdot);
+
+  PropertyManager->Tie("accelerations/udot-ft_sec2", this, eU, (PMF)&FGAccelerations::GetUVWdot);
+  PropertyManager->Tie("accelerations/vdot-ft_sec2", this, eV, (PMF)&FGAccelerations::GetUVWdot);
+  PropertyManager->Tie("accelerations/wdot-ft_sec2", this, eW, (PMF)&FGAccelerations::GetUVWdot);
+
+  PropertyManager->Tie("simulation/gravity-model", &gravType);
+
+  PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAccelerations::GetForces);
+  PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAccelerations::GetForces);
+  PropertyManager->Tie("forces/fbz-total-lbs", this, eZ, (PMF)&FGAccelerations::GetForces);
+  PropertyManager->Tie("moments/l-total-lbsft", this, eL, (PMF)&FGAccelerations::GetMoments);
+  PropertyManager->Tie("moments/m-total-lbsft", this, eM, (PMF)&FGAccelerations::GetMoments);
+  PropertyManager->Tie("moments/n-total-lbsft", this, eN, (PMF)&FGAccelerations::GetMoments);
+
+  PropertyManager->Tie("moments/l-gear-lbsft", this, eL, (PMF)&FGAccelerations::GetGroundMoments);
+  PropertyManager->Tie("moments/m-gear-lbsft", this, eM, (PMF)&FGAccelerations::GetGroundMoments);
+  PropertyManager->Tie("moments/n-gear-lbsft", this, eN, (PMF)&FGAccelerations::GetGroundMoments);
+  PropertyManager->Tie("forces/fbx-gear-lbs", this, eX, (PMF)&FGAccelerations::GetGroundForces);
+  PropertyManager->Tie("forces/fby-gear-lbs", this, eY, (PMF)&FGAccelerations::GetGroundForces);
+  PropertyManager->Tie("forces/fbz-gear-lbs", this, eZ, (PMF)&FGAccelerations::GetGroundForces);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//    The bitmasked value choices are as follows:
+//    unset: In this case (the default) JSBSim would only print
+//       out the normally expected messages, essentially echoing
+//       the config files as they are read. If the environment
+//       variable is not set, debug_lvl is set to 1 internally
+//    0: This requests JSBSim not to output any messages
+//       whatsoever.
+//    1: This value explicity requests the normal JSBSim
+//       startup messages
+//    2: This value asks for a message to be printed out when
+//       a class is instantiated
+//    4: When this value is set, a message is displayed when a
+//       FGModel object executes its Run() method
+//    8: When this value is set, various runtime state variables
+//       are printed out periodically
+//    16: When set various parameters are sanity checked and
+//       a message is printed out when they go out of bounds
+
+void FGAccelerations::Debug(int from)
+{
+  if (debug_lvl <= 0) return;
+
+  if (debug_lvl & 1) { // Standard console startup message output
+    if (from == 0) { // Constructor
+
+    }
+  }
+  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+    if (from == 0) cout << "Instantiated: FGAccelerations" << endl;
+    if (from == 1) cout << "Destroyed:    FGAccelerations" << endl;
+  }
+  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+  }
+  if (debug_lvl & 8 && from == 2) { // Runtime state variables
+  }
+  if (debug_lvl & 16) { // Sanity checking
+  }
+  if (debug_lvl & 64) {
+    if (from == 0) { // Constructor
+      cout << IdSrc << endl;
+      cout << IdHdr << endl;
+    }
+  }
+}
+}
diff --git a/src/FDM/JSBSim/models/FGAccelerations.h b/src/FDM/JSBSim/models/FGAccelerations.h
new file mode 100644
index 000000000..5cc609103
--- /dev/null
+++ b/src/FDM/JSBSim/models/FGAccelerations.h
@@ -0,0 +1,230 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       FGAccelerations.h
+ Author:       Jon S. Berndt
+ Date started: 07/12/11
+
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser 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 Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+HISTORY
+--------------------------------------------------------------------------------
+07/12/11   JSB   Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef FGACCELERATIONS_H
+#define FGACCELERATIONS_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <vector>
+
+#include "models/FGModel.h"
+#include "math/FGColumnVector3.h"
+#include "math/LagrangeMultiplier.h"
+#include "math/FGMatrix33.h"
+#include "math/FGQuaternion.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.7 2011/08/21 15:46:48 bcoconni Exp $"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Handles the calculation of accelerations.
+
+    -Calculate the angular accelerations
+    -Calculate the translational accelerations
+    -Calculate the angular rate
+    -Calculate the translational velocity
+
+    @author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
+    @version $Id: FGAccelerations.h,v 1.7 2011/08/21 15:46:48 bcoconni Exp $
+  */
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGAccelerations : public FGModel {
+public:
+  /** Constructor.
+      @param Executive a pointer to the parent executive object */
+  FGAccelerations(FGFDMExec* Executive);
+
+  /// Destructor
+  ~FGAccelerations();
+  
+  /// These define the indices use to select the gravitation models.
+  enum eGravType {gtStandard, gtWGS84}; 
+
+  /** Initializes the FGAccelerations class after instantiation and prior to first execution.
+      The base class FGModel::InitModel is called first, initializing pointers to the 
+      other FGModel objects (and others).  */
+  bool InitModel(void);
+
+  /** Runs the state propagation model; called by the Executive
+      Can pass in a value indicating if the executive is directing the simulation to Hold.
+      @param Holding if true, the executive has been directed to hold the sim from 
+                     advancing time. Some models may ignore this flag, such as the Input
+                     model, which may need to be active to listen on a socket for the
+                     "Resume" command to be given.
+      @return false if no error */
+  bool Run(bool Holding);
+
+  const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;}
+
+  /** Retrieves the body axis acceleration.
+      Retrieves the computed body axis accelerations based on the
+      applied forces and accounting for a rotating body frame.
+      The vector returned is represented by an FGColumnVector reference. The vector
+      for the acceleration in Body frame is organized (Ax, Ay, Az). The vector
+      is 1-based, so that the first element can be retrieved using the "()" operator.
+      In other words, vUVWdot(1) is Ax. Various convenience enumerators are defined
+      in FGJSBBase. The relevant enumerators for the vector returned by this call are,
+      eX=1, eY=2, eZ=3.
+      units ft/sec^2
+      @return Body axis translational acceleration in ft/sec^2.
+  */
+  const FGColumnVector3& GetUVWdot(void) const { return vUVWdot; }
+
+  const FGColumnVector3& GetUVWidot(void) const { return vUVWidot; }
+
+  /** Retrieves the body axis angular acceleration vector.
+      Retrieves the body axis angular acceleration vector in rad/sec^2. The
+      angular acceleration vector is determined from the applied forces and
+      accounts for a rotating frame.
+      The vector returned is represented by an FGColumnVector reference. The vector
+      for the angular acceleration in Body frame is organized (Pdot, Qdot, Rdot). The vector
+      is 1-based, so that the first element can be retrieved using the "()" operator.
+      In other words, vPQRdot(1) is Pdot. Various convenience enumerators are defined
+      in FGJSBBase. The relevant enumerators for the vector returned by this call are,
+      eP=1, eQ=2, eR=3.
+      units rad/sec^2
+      @return The angular acceleration vector.
+  */
+  const FGColumnVector3& GetPQRdot(void) const {return vPQRdot;}
+  
+  const FGColumnVector3& GetPQRidot(void) const {return vPQRidot;}
+
+  /** Retrieves a body frame acceleration component.
+      Retrieves a body frame acceleration component. The acceleration returned
+      is extracted from the vUVWdot vector (an FGColumnVector). The vector for
+      the acceleration in Body frame is organized (Ax, Ay, Az). The vector is
+      1-based. In other words, GetUVWdot(1) returns Ax. Various convenience
+      enumerators are defined in FGJSBBase. The relevant enumerators for the
+      acceleration returned by this call are, eX=1, eY=2, eZ=3.
+      units ft/sec^2
+      @param idx the index of the acceleration component desired (1-based).
+      @return The body frame acceleration component.
+  */
+  double GetUVWdot(int idx) const { return vUVWdot(idx); }
+
+  FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
+
+  double GetBodyAccel(int idx) const { return vBodyAccel(idx); }
+
+  /** Retrieves a body frame angular acceleration component.
+      Retrieves a body frame angular acceleration component. The angular
+      acceleration returned is extracted from the vPQRdot vector (an
+      FGColumnVector). The vector for the angular acceleration in Body frame
+      is organized (Pdot, Qdot, Rdot). The vector is 1-based. In other words,
+      GetPQRdot(1) returns Pdot (roll acceleration). Various convenience
+      enumerators are defined in FGJSBBase. The relevant enumerators for the
+      angular acceleration returned by this call are, eP=1, eQ=2, eR=3.
+      units rad/sec^2
+      @param axis the index of the angular acceleration component desired (1-based).
+      @return The body frame angular acceleration component.
+  */
+  double GetPQRdot(int axis) const {return vPQRdot(axis);}
+
+  double GetMoments(int idx) const { return in.Moment(idx) + vFrictionMoments(idx); }
+  double GetForces(int idx) const { return in.Force(idx) + vFrictionForces(idx); }
+  double GetGroundMoments(int idx) const { return in.GroundMoment(idx) + vFrictionMoments(idx); }
+  double GetGroundForces(int idx) const { return in.GroundForce(idx) + vFrictionForces(idx); }
+
+  void InitializeDerivatives(void);
+
+  void DumpState(void);
+
+  struct Inputs {
+    FGMatrix33 J;
+    FGMatrix33 Jinv;
+    FGMatrix33 Ti2b;
+    FGMatrix33 Tb2i;
+    FGMatrix33 Tec2b;
+    FGMatrix33 Tl2b;
+    FGQuaternion qAttitudeECI;
+    FGColumnVector3 Moment;
+    FGColumnVector3 GroundMoment;
+    FGColumnVector3 Force;
+    FGColumnVector3 GroundForce;
+    FGColumnVector3 J2Grav;
+    FGColumnVector3 vPQRi;
+    FGColumnVector3 vPQR;
+    FGColumnVector3 vUVW;
+    FGColumnVector3 vInertialPosition;
+    FGColumnVector3 vOmegaPlanet;
+    FGColumnVector3 TerrainVelocity;
+    FGColumnVector3 TerrainAngularVel;
+    double DeltaT;
+    double Mass;
+    double GAccel;
+    std::vector<LagrangeMultiplier*> *MultipliersList;
+  } in;
+
+private:
+
+  FGColumnVector3 vPQRdot, vPQRidot;
+  FGColumnVector3 vUVWdot, vUVWidot;
+  FGQuaternion vQtrndot;
+  FGColumnVector3 vBodyAccel;
+  FGColumnVector3 vGravAccel;
+  FGColumnVector3 vFrictionForces;
+  FGColumnVector3 vFrictionMoments;
+
+  int gravType;
+
+  void CalculatePQRdot(void);
+  void CalculateQuatdot(void);
+  void CalculateUVWdot(void);
+
+  void ResolveFrictionForces(double dt);
+
+  void bind(void);
+  void Debug(int from);
+};
+}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+#endif
diff --git a/src/FDM/JSBSim/models/FGAerodynamics.cpp b/src/FDM/JSBSim/models/FGAerodynamics.cpp
index 4208ef626..13a9b9f17 100644
--- a/src/FDM/JSBSim/models/FGAerodynamics.cpp
+++ b/src/FDM/JSBSim/models/FGAerodynamics.cpp
@@ -40,19 +40,15 @@ INCLUDES
 #include <sstream>
 #include <iomanip>
 #include <cstdlib>
-#include <FGFDMExec.h>
+#include "FGFDMExec.h"
 #include "FGAerodynamics.h"
-#include "FGPropagate.h"
-#include "FGAircraft.h"
-#include "FGAuxiliary.h"
-#include "FGMassBalance.h"
 #include "input_output/FGPropertyManager.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.38 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.41 2011/08/04 12:46:32 jberndt Exp $";
 static const char *IdHdr = ID_AERODYNAMICS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -139,36 +135,31 @@ bool FGAerodynamics::Run(bool Holding)
   if (Holding) return false; // if paused don't execute
 
   unsigned int axis_ctr, ctr;
-  const double alpha=FDMExec->GetAuxiliary()->Getalpha();
-  const double twovel=2*FDMExec->GetAuxiliary()->GetVt();
-  const double qbar = FDMExec->GetAuxiliary()->Getqbar();
-  const double wingarea = FDMExec->GetAircraft()->GetWingArea();  // TODO: Make these constants constant!
-  const double wingspan = FDMExec->GetAircraft()->GetWingSpan();
-  const double wingchord = FDMExec->GetAircraft()->Getcbar();
-  const double wingincidence = FDMExec->GetAircraft()->GetWingIncidence();
+  const double twovel=2*in.Vt;
+
   RunPreFunctions();
 
   // calculate some oft-used quantities for speed
 
   if (twovel != 0) {
-    bi2vel = wingspan / twovel;
-    ci2vel = wingchord / twovel;
+    bi2vel = in.Wingspan / twovel;
+    ci2vel = in.Wingchord / twovel;
   }
-  alphaw = alpha + wingincidence;
-  qbar_area = wingarea * qbar;
+  alphaw = in.Alpha + in.Wingincidence;
+  qbar_area = in.Wingarea * in.Qbar;
 
   if (alphaclmax != 0) {
-    if (alpha > 0.85*alphaclmax) {
-      impending_stall = 10*(alpha/alphaclmax - 0.85);
+    if (in.Alpha > 0.85*alphaclmax) {
+      impending_stall = 10*(in.Alpha/alphaclmax - 0.85);
     } else {
       impending_stall = 0;
     }
   }
 
   if (alphahystmax != 0.0 && alphahystmin != 0.0) {
-    if (alpha > alphahystmax) {
+    if (in.Alpha > alphahystmax) {
        stall_hyst = 1;
-    } else if (alpha < alphahystmin) {
+    } else if (in.Alpha < alphahystmin) {
        stall_hyst = 0;
     }
   }
@@ -188,16 +179,16 @@ bool FGAerodynamics::Run(bool Holding)
 
   switch (axisType) {
     case atBodyXYZ:       // Forces already in body axes; no manipulation needed
-      vFw = GetTb2w()*vFnative;
+      vFw = in.Tb2w*vFnative;
       vForces = vFnative;
       break;
     case atLiftDrag:      // Copy forces into wind axes
       vFw = vFnative;
       vFw(eDrag)*=-1; vFw(eLift)*=-1;
-      vForces = GetTw2b()*vFw;
+      vForces = in.Tw2b*vFw;
       break;
     case atAxialNormal:   // Convert native forces into Axial|Normal|Side system
-      vFw = GetTb2w()*vFnative;
+      vFw = in.Tb2w*vFnative;
       vFnative(eX)*=-1; vFnative(eZ)*=-1;
       vForces = vFnative;
       break;
@@ -207,19 +198,23 @@ bool FGAerodynamics::Run(bool Holding)
       exit(-1);
   }
 
-  // Calculate aerodynamic reference point shift, if any
-  if (AeroRPShift) vDeltaRP(eX) = AeroRPShift->GetValue()*wingchord*12.0;
-
   // Calculate lift coefficient squared
-  if ( qbar > 0) {
-    clsq = vFw(eLift) / (wingarea*qbar);
+  if ( in.Qbar > 0) {
+    clsq = vFw(eLift) / (in.Wingarea*in.Qbar);
     clsq *= clsq;
   }
 
   // Calculate lift Lift over Drag
   if ( fabs(vFw(eDrag)) > 0.0) lod = fabs( vFw(eLift) / vFw(eDrag) );
 
-  vDXYZcg = FDMExec->GetMassBalance()->StructuralToBody(FDMExec->GetAircraft()->GetXYZrp() + vDeltaRP);
+  // Calculate aerodynamic reference point shift, if any. The shift
+  // takes place in the body axis. That is, if the shift is negative,
+  // it is towards the back (tail) of the vehicle. The AeroRPShift
+  // function should be non-dimensionalized by the wing chord. The
+  // calculated vDeltaRP will be in feet.
+  if (AeroRPShift) vDeltaRP(eX) = AeroRPShift->GetValue()*in.Wingchord;
+
+  vDXYZcg = in.RPBody + vDeltaRP;
 
   vMoments = vDXYZcg*vForces; // M = r X F
 
@@ -234,75 +229,6 @@ bool FGAerodynamics::Run(bool Holding)
   return false;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//
-// From Stevens and Lewis, "Aircraft Control and Simulation", 3rd Ed., the
-// transformation from body to wind axes is defined (where "a" is alpha and "B"
-// is beta):
-//
-//   cos(a)*cos(B)     sin(B)    sin(a)*cos(B)
-//  -cos(a)*sin(B)     cos(B)   -sin(a)*sin(B)
-//  -sin(a)              0       cos(a)
-//
-// The transform from wind to body axes is then,
-//
-//   cos(a)*cos(B)  -cos(a)*sin(B)  -sin(a)
-//          sin(B)          cos(B)     0
-//   sin(a)*cos(B)  -sin(a)*sin(B)   cos(a)
-
-FGMatrix33& FGAerodynamics::GetTw2b(void)
-{
-  double ca, cb, sa, sb;
-
-  double alpha = FDMExec->GetAuxiliary()->Getalpha();
-  double beta  = FDMExec->GetAuxiliary()->Getbeta();
-
-  ca = cos(alpha);
-  sa = sin(alpha);
-  cb = cos(beta);
-  sb = sin(beta);
-
-  mTw2b(1,1) =  ca*cb;
-  mTw2b(1,2) = -ca*sb;
-  mTw2b(1,3) = -sa;
-  mTw2b(2,1) =  sb;
-  mTw2b(2,2) =  cb;
-  mTw2b(2,3) =  0.0;
-  mTw2b(3,1) =  sa*cb;
-  mTw2b(3,2) = -sa*sb;
-  mTw2b(3,3) =  ca;
-
-  return mTw2b;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGMatrix33& FGAerodynamics::GetTb2w(void)
-{
-  double alpha,beta;
-  double ca, cb, sa, sb;
-
-  alpha = FDMExec->GetAuxiliary()->Getalpha();
-  beta  = FDMExec->GetAuxiliary()->Getbeta();
-
-  ca = cos(alpha);
-  sa = sin(alpha);
-  cb = cos(beta);
-  sb = sin(beta);
-
-  mTb2w(1,1) = ca*cb;
-  mTb2w(1,2) = sb;
-  mTb2w(1,3) = sa*cb;
-  mTb2w(2,1) = -ca*sb;
-  mTb2w(2,2) = cb;
-  mTb2w(2,3) = -sa*sb;
-  mTb2w(3,1) = -sa;
-  mTb2w(3,2) = 0.0;
-  mTb2w(3,3) = ca;
-
-  return mTb2w;
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 bool FGAerodynamics::Load(Element *element)
@@ -318,6 +244,7 @@ bool FGAerodynamics::Load(Element *element)
   if (!fname.empty()) {
     file = FDMExec->GetFullAircraftPath() + separator + fname;
     document = LoadXMLDocument(file);
+    if (document == 0L) return false;
   } else {
     document = element;
   }
diff --git a/src/FDM/JSBSim/models/FGAerodynamics.h b/src/FDM/JSBSim/models/FGAerodynamics.h
index 87744e86e..f4194e97d 100644
--- a/src/FDM/JSBSim/models/FGAerodynamics.h
+++ b/src/FDM/JSBSim/models/FGAerodynamics.h
@@ -52,7 +52,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.25 2011/08/04 12:46:32 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -109,7 +109,7 @@ CLASS DOCUMENTATION
     Systems may NOT be combined, or a load error will occur.
 
     @author Jon S. Berndt, Tony Peden
-    @version $Revision: 1.23 $
+    @version $Revision: 1.25 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -202,18 +202,22 @@ public:
       aero functions */
   std::string GetAeroFunctionValues(const std::string& delimeter) const;
 
-  /** Calculates and returns the wind-to-body axis transformation matrix.
-      @return a reference to the wind-to-body transformation matrix.
-      */
-  FGMatrix33& GetTw2b(void);
-
-  /** Calculates and returns the body-to-wind axis transformation matrix.
-      @return a reference to the wind-to-body transformation matrix.
-      */
-  FGMatrix33& GetTb2w(void);
-
   std::vector <FGFunction*> * GetAeroFunctions(void) const { return AeroFunctions; }
 
+  struct Inputs {
+    double Alpha;
+    double Beta;
+    double Vt;
+    double Qbar;
+    double Wingarea;
+    double Wingspan;
+    double Wingchord;
+    double Wingincidence;
+    FGColumnVector3 RPBody;
+    FGMatrix33 Tb2w;
+    FGMatrix33 Tw2b;
+  } in;
+
 private:
   enum eAxisType {atNone, atLiftDrag, atAxialNormal, atBodyXYZ} axisType;
   typedef std::map<std::string,int> AxisIndex;
@@ -227,8 +231,6 @@ private:
   FGColumnVector3 vMoments;
   FGColumnVector3 vDXYZcg;
   FGColumnVector3 vDeltaRP;
-  FGMatrix33 mTw2b;
-  FGMatrix33 mTb2w;
   double alphaclmax, alphaclmin;
   double alphahystmax, alphahystmin;
   double impending_stall, stall_hyst;
diff --git a/src/FDM/JSBSim/models/FGAircraft.cpp b/src/FDM/JSBSim/models/FGAircraft.cpp
index 7b0f3705a..a433a56fa 100644
--- a/src/FDM/JSBSim/models/FGAircraft.cpp
+++ b/src/FDM/JSBSim/models/FGAircraft.cpp
@@ -44,15 +44,7 @@ INCLUDES
 #include <cmath>
 
 #include "FGAircraft.h"
-#include "FGMassBalance.h"
-#include "FGInertial.h"
-#include "FGGroundReactions.h"
-#include "FGExternalReactions.h"
-#include "FGBuoyantForces.h"
-#include "FGAerodynamics.h"
 #include "FGFDMExec.h"
-#include "FGPropagate.h"
-#include "FGPropulsion.h"
 #include "input_output/FGPropertyManager.h"
 
 using namespace std;
@@ -67,7 +59,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.31 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.33 2011/08/21 15:06:38 bcoconni Exp $";
 static const char *IdHdr = ID_AIRCRAFT;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -78,6 +70,8 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
 {
   Name = "FGAircraft";
   WingSpan = 0.0;
+  WingArea = 0.0;
+  cbar = 0.0;
   HTailArea = VTailArea = 0.0;
   HTailArm  = VTailArm  = 0.0;
   lbarh = lbarv = 0.0;
@@ -115,32 +109,24 @@ bool FGAircraft::Run(bool Holding)
 
   vForces.InitMatrix();
   if (!HoldDown) {
-    vForces += FDMExec->GetAerodynamics()->GetForces();
-    vForces += FDMExec->GetPropulsion()->GetForces();
-    vForces += FDMExec->GetGroundReactions()->GetForces();
-    vForces += FDMExec->GetExternalReactions()->GetForces();
-    vForces += FDMExec->GetBuoyantForces()->GetForces();
+    vForces += in.AeroForce;
+    vForces += in.PropForce;
+    vForces += in.GroundForce;
+    vForces += in.ExternalForce;
+    vForces += in.BuoyantForce;
   } else {
-    const FGMatrix33& mTl2b = FDMExec->GetPropagate()->GetTl2b();
-    vForces = mTl2b * FGColumnVector3(0,0,-FDMExec->GetMassBalance()->GetWeight());
+    vForces = in.Tl2b * FGColumnVector3(0,0,-in.Weight);
   }
 
   vMoments.InitMatrix();
   if (!HoldDown) {
-    vMoments += FDMExec->GetAerodynamics()->GetMoments();
-    vMoments += FDMExec->GetPropulsion()->GetMoments();
-    vMoments += FDMExec->GetGroundReactions()->GetMoments();
-    vMoments += FDMExec->GetExternalReactions()->GetMoments();
-    vMoments += FDMExec->GetBuoyantForces()->GetMoments();
+    vMoments += in.AeroMoment;
+    vMoments += in.PropMoment;
+    vMoments += in.GroundMoment;
+    vMoments += in.ExternalMoment;
+    vMoments += in.BuoyantMoment;
   }
 
-  vBodyAccel = vForces/FDMExec->GetMassBalance()->GetMass();
-
-  vNcg = vBodyAccel/FDMExec->GetInertial()->SLgravity();
-
-  vNwcg = FDMExec->GetAerodynamics()->GetTb2w() * vNcg;
-  vNwcg(3) = 1.0 - vNwcg(3);
-
   RunPostFunctions();
 
   return false;
@@ -148,16 +134,6 @@ bool FGAircraft::Run(bool Holding)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGAircraft::GetNlf(void) const
-{
-  if (FDMExec->GetMassBalance()->GetWeight() != 0)
-    return (-FDMExec->GetAerodynamics()->GetvFw(3))/FDMExec->GetMassBalance()->GetWeight();
-  else
-    return 0.;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 bool FGAircraft::Load(Element* el)
 {
   string element_name;
@@ -240,14 +216,7 @@ void FGAircraft::bind(void)
   PropertyManager->Tie("metrics/visualrefpoint-x-in", this, eX, (PMF)&FGAircraft::GetXYZvrp);
   PropertyManager->Tie("metrics/visualrefpoint-y-in", this, eY, (PMF)&FGAircraft::GetXYZvrp);
   PropertyManager->Tie("metrics/visualrefpoint-z-in", this, eZ, (PMF)&FGAircraft::GetXYZvrp);
-  PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAircraft::GetForces);
-  PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAircraft::GetForces);
-  PropertyManager->Tie("forces/fbz-total-lbs", this, eZ, (PMF)&FGAircraft::GetForces);
-  PropertyManager->Tie("forces/load-factor", this, &FGAircraft::GetNlf);
   PropertyManager->Tie("forces/hold-down", this, &FGAircraft::GetHoldDown, &FGAircraft::SetHoldDown);
-  PropertyManager->Tie("moments/l-total-lbsft", this, eL, (PMF)&FGAircraft::GetMoments);
-  PropertyManager->Tie("moments/m-total-lbsft", this, eM, (PMF)&FGAircraft::GetMoments);
-  PropertyManager->Tie("moments/n-total-lbsft", this, eN, (PMF)&FGAircraft::GetMoments);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/FGAircraft.h b/src/FDM/JSBSim/models/FGAircraft.h
index 684f1dd2e..a7a2ba69b 100644
--- a/src/FDM/JSBSim/models/FGAircraft.h
+++ b/src/FDM/JSBSim/models/FGAircraft.h
@@ -44,12 +44,13 @@ INCLUDES
 #include "FGModel.h"
 #include "input_output/FGXMLElement.h"
 #include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.18 2011/07/10 20:18:14 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -90,7 +91,7 @@ CLASS DOCUMENTATION
 @endcode
 
     @author Jon S. Berndt
-    @version $Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $
+    @version $Id: FGAircraft.h,v 1.18 2011/07/10 20:18:14 jberndt Exp $
     @see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
 	   Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
 	   School, January 1994
@@ -159,10 +160,6 @@ public:
   double GetMoments(int idx) const { return vMoments(idx); }
   const FGColumnVector3& GetForces(void) const { return vForces; }
   double GetForces(int idx) const { return vForces(idx); }
-  FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
-  double GetBodyAccel(int idx) const { return vBodyAccel(idx); }
-  const FGColumnVector3& GetNcg(void) const { return vNcg; }
-  double GetNcg(int idx) const { return vNcg(idx); }
   const FGColumnVector3& GetXYZrp(void) const { return vXYZrp; }
   const FGColumnVector3& GetXYZvrp(void) const { return vXYZvrp; }
   const FGColumnVector3& GetXYZep(void) const { return vXYZep; }
@@ -177,13 +174,24 @@ public:
 
   void SetWingArea(double S) {WingArea = S;}
 
-  double GetNlf(void) const;
-
-  FGColumnVector3& GetNwcg(void) { return vNwcg; }
-
   void bind(void);
   void unbind(void);
 
+  struct Inputs {
+    FGColumnVector3 AeroForce;
+    FGColumnVector3 PropForce;
+    FGColumnVector3 GroundForce;
+    FGColumnVector3 ExternalForce;
+    FGColumnVector3 BuoyantForce;
+    FGColumnVector3 AeroMoment;
+    FGColumnVector3 PropMoment;
+    FGColumnVector3 GroundMoment;
+    FGColumnVector3 ExternalMoment;
+    FGColumnVector3 BuoyantMoment;
+    FGMatrix33 Tl2b;
+    double Weight;
+  } in;
+
 private:
   FGColumnVector3 vMoments;
   FGColumnVector3 vForces;
@@ -191,9 +199,6 @@ private:
   FGColumnVector3 vXYZvrp;
   FGColumnVector3 vXYZep;
   FGColumnVector3 vDXYZcg;
-  FGColumnVector3 vBodyAccel;
-  FGColumnVector3 vNcg;
-  FGColumnVector3 vNwcg;
 
   double WingArea, WingSpan, cbar, WingIncidence;
   double HTailArea, VTailArea, HTailArm, VTailArm;
diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp
index 990adb882..1387f013f 100644
--- a/src/FDM/JSBSim/models/FGAtmosphere.cpp
+++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp
@@ -1,13 +1,12 @@
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
  Module:       FGAtmosphere.cpp
- Author:       Jon Berndt
-               Implementation of 1959 Standard Atmosphere added by Tony Peden
- Date started: 11/24/98
- Purpose:      Models the atmosphere
- Called by:    FGSimExec
+ Author:       Jon Berndt, Tony Peden
+ Date started: 6/2011
+ Purpose:      Models an atmosphere interface class
+ Called by:    FGFDMExec
 
- ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -28,92 +27,43 @@
 
 FUNCTIONAL DESCRIPTION
 --------------------------------------------------------------------------------
-Models the atmosphere. The equation used below was determined by a third order
-curve fit using Excel. The data is from the ICAO atmosphere model.
+This models a base atmosphere class to serve as a common interface to any derived
+atmosphere models.
 
 HISTORY
 --------------------------------------------------------------------------------
-11/24/98   JSB   Created
-07/23/99   TP    Added implementation of 1959 Standard Atmosphere
-                 Moved calculation of Mach number to FGPropagate
-                 Later updated to '76 model
+6/18/2011 Started Jon S. Berndt
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 COMMENTS, REFERENCES,  and NOTES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-[1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
-      1989, ISBN 0-07-001641-0
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGAtmosphere.h"
-#include "FGAircraft.h"
-#include "FGPropagate.h"
-#include "FGInertial.h"
-#include "FGAuxiliary.h"
-#include "FGFDMExec.h"
-#include "input_output/FGPropertyManager.h"
 #include <iostream>
+#include <iomanip>
 #include <cstdlib>
-
-using namespace std;
+#include "FGFDMExec.h"
+#include "FGAtmosphere.h"
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.45 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.48 2011/07/10 20:18:14 jberndt Exp $";
 static const char *IdHdr = ID_ATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
+FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
+                                               PressureAltitude(0.0),      // ft
+                                               DensityAltitude(0.0),       // ft
+                                               SutherlandConstant(198.72), // deg Rankine
+                                               Beta(2.269690E-08)          // slug/(sec ft R^0.5)
 {
   Name = "FGAtmosphere";
-  lastIndex = 0;
-  h = 0.0;
-  psiw = 0.0;
-  htab[0]=0;
-  htab[1]= 36089.0;
-  htab[2]= 65617.0;
-  htab[3]=104987.0;
-  htab[4]=154199.0;
-  htab[5]=167322.0;
-  htab[6]=232940.0;
-  htab[7]=278385.0; //ft.
-
-  MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
-  SetTurbType( ttMilspec );
-  TurbGain = 1.0;
-  TurbRate = 10.0;
-  Rhythmicity = 0.1;
-  spike = target_time = strength = 0.0;
-  wind_from_clockwise = 0.0;
-  SutherlandConstant = 198.72; // deg Rankine
-  Beta = 2.269690E-08; // slug/(sec ft R^0.5)
-
-  T_dev_sl = T_dev = delta_T = 0.0;
-  StandardTempOnly = false;
-  first_pass = true;
-  vGustNED.InitMatrix();
-  vTurbulenceNED.InitMatrix();
-
-  // Milspec turbulence model
-  windspeed_at_20ft = 0.;
-  probability_of_exceedence_index = 0;
-  POE_Table = new FGTable(7,12);
-  // this is Figure 7 from p. 49 of MIL-F-8785C
-  // rows: probability of exceedance curve index, cols: altitude in ft
-  *POE_Table
-           << 500.0 << 1750.0 << 3750.0 << 7500.0 << 15000.0 << 25000.0 << 35000.0 << 45000.0 << 55000.0 << 65000.0 << 75000.0 << 80000.0
-    << 1   <<   3.2 <<    2.2 <<    1.5 <<    0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
-    << 2   <<   4.2 <<    3.6 <<    3.3 <<    1.6 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
-    << 3   <<   6.6 <<    6.9 <<    7.4 <<    6.7 <<     4.6 <<     2.7 <<     0.4 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
-    << 4   <<   8.6 <<    9.6 <<   10.6 <<   10.1 <<     8.0 <<     6.6 <<     5.0 <<     4.2 <<     2.7 <<     0.0 <<     0.0 <<     0.0
-    << 5   <<  11.8 <<   13.0 <<   16.0 <<   15.1 <<    11.6 <<     9.7 <<     8.1 <<     8.2 <<     7.9 <<     4.9 <<     3.2 <<     2.1
-    << 6   <<  15.6 <<   17.6 <<   23.0 <<   23.6 <<    22.1 <<    20.0 <<    16.0 <<    15.1 <<    12.1 <<     7.9 <<     6.2 <<     5.1
-    << 7   <<  18.7 <<   21.5 <<   28.4 <<   30.2 <<    30.7 <<    31.0 <<    25.2 <<    23.1 <<    17.5 <<    10.7 <<     8.4 <<     7.2;
 
   bind();
   Debug(0);
@@ -123,7 +73,6 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
 
 FGAtmosphere::~FGAtmosphere()
 {
-  delete(POE_Table);
   Debug(1);
 }
 
@@ -131,17 +80,16 @@ FGAtmosphere::~FGAtmosphere()
 
 bool FGAtmosphere::InitModel(void)
 {
-  UseInternal();  // this is the default
+  Calculate(0.0);
+  SLtemperature = Temperature = 518.67;
+  SLpressure = Pressure = 2116.22;
+  SLdensity = Density = Pressure/(Reng*Temperature);
+  SLsoundspeed = Soundspeed = sqrt(SHRatio*Reng*(Temperature));
 
-  Calculate(h);
-  StdSLtemperature = SLtemperature = 518.67;
-  StdSLpressure    = SLpressure = 2116.22;
-  StdSLdensity     = SLdensity = 0.00237767;
-  StdSLsoundspeed  = SLsoundspeed = sqrt(SHRatio*Reng*StdSLtemperature);
-  rSLtemperature = 1.0/StdSLtemperature;
-  rSLpressure    = 1.0/StdSLpressure;
-  rSLdensity     = 1.0/StdSLdensity;
-  rSLsoundspeed  = 1.0/StdSLsoundspeed;
+  rSLtemperature = 1/SLtemperature ;
+  rSLpressure    = 1/SLpressure    ;
+  rSLdensity     = 1/SLdensity     ;
+  rSLsoundspeed  = 1/SLsoundspeed  ;
 
   return true;
 }
@@ -155,15 +103,7 @@ bool FGAtmosphere::Run(bool Holding)
 
   RunPreFunctions();
 
-  T_dev = 0.0;
-  h = FDMExec->GetPropagate()->GetAltitudeASL();
-
-  if (!useExternal) {
-    Calculate(h);
-    CalculateDerived();
-  } else {
-    CalculateDerived();
-  }
+  Calculate(in.altitudeASL);
 
   RunPostFunctions();
 
@@ -172,537 +112,105 @@ bool FGAtmosphere::Run(bool Holding)
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//
-// See reference 1
 
 void FGAtmosphere::Calculate(double altitude)
 {
-  double slope, reftemp, refpress;
-  int i = lastIndex;
+  Temperature = GetTemperature(altitude);
+  Pressure    = GetPressure(altitude);
+  Density     = Pressure/(Reng*Temperature);
+  Soundspeed  = sqrt(SHRatio*Reng*(Temperature));
+  PressureAltitude = altitude;
+  DensityAltitude = altitude;
 
-  if (altitude < htab[lastIndex]) {
-    if (altitude <= 0) {
-      i = 0;
-      altitude=0;
-    } else {
-       i = lastIndex-1;
-       while (htab[i] > altitude) i--;
-    }
-  } else if (altitude > htab[lastIndex+1]) {
-    if (altitude >= htab[7]) {
-      i = 7;
-      altitude = htab[7];
-    } else {
-      i = lastIndex+1;
-      while (htab[i+1] < altitude) i++;
-    }
-  }
-
-  switch(i) {
-  case 0: // Sea level
-    slope     = -0.00356616; // R/ft.
-    reftemp   = 518.67;   // in degrees Rankine, 288.15 Kelvin
-    refpress  = 2116.22;    // psf
-    //refdens   = 0.00237767;  // slugs/cubic ft.
-    break;
-  case 1:     // 36089 ft. or 11 km
-    slope     = 0;
-    reftemp   = 389.97; // in degrees Rankine, 216.65 Kelvin
-    refpress  = 472.763;
-    //refdens   = 0.000706032;
-    break;
-  case 2:     // 65616 ft. or 20 km
-    slope     = 0.00054864;
-    reftemp   = 389.97; // in degrees Rankine, 216.65 Kelvin
-    refpress  = 114.636;
-    //refdens   = 0.000171306;
-    break;
-  case 3:     // 104986 ft. or 32 km
-    slope     = 0.001536192;
-    reftemp   = 411.57; // in degrees Rankine, 228.65 Kelvin
-    refpress  = 18.128;
-    //refdens   = 1.18422e-05;
-    break;
-  case 4:     // 154199 ft. 47 km
-    slope     = 0;
-    reftemp   = 487.17; // in degrees Rankine, 270.65 Kelvin
-    refpress  = 2.316;
-    //refdens   = 4.00585e-7;
-    break;
-  case 5:     // 167322 ft. or 51 km
-    slope     = -0.001536192;
-    reftemp   = 487.17; // in degrees Rankine, 270.65 Kelvin
-    refpress  = 1.398;
-    //refdens   = 8.17102e-7;
-    break;
-  case 6:     // 232940 ft. or 71 km
-    slope     = -0.00109728;
-    reftemp   = 386.368; // in degrees Rankine, 214.649 Kelvin
-    refpress  = 0.0826;
-    //refdens   = 8.77702e-9;
-    break;
-  case 7:     // 278385 ft. or 84.8520 km
-    slope     = 0;
-    reftemp   = 336.5; // in degrees Rankine, 186.94 Kelvin
-    refpress  = 0.00831;
-    //refdens   = 2.19541e-10;
-    break;
-  default:     // sea level
-    slope     = -0.00356616; // R/ft.
-    reftemp   = 518.67;   // in degrees Rankine, 288.15 Kelvin
-    refpress  = 2116.22;    // psf
-    //refdens   = 0.00237767;  // slugs/cubic ft.
-    break;
-
-  }
-
-  // If delta_T is set, then that is our temperature deviation at any altitude.
-  // If not, then we'll estimate a deviation based on the sea level deviation (if set).
-
-  if(!StandardTempOnly) {
-    T_dev = 0.0;
-    if (delta_T != 0.0) {
-      T_dev = delta_T;
-    } else {
-      if ((altitude < 36089.239) && (T_dev_sl != 0.0)) {
-        T_dev = T_dev_sl * ( 1.0 - (altitude/36089.239));
-      }
-    }
-    reftemp+=T_dev;
-  }
-
-  if (slope == 0) {
-    intTemperature = reftemp;
-    intPressure = refpress*exp(-FDMExec->GetInertial()->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
-    intDensity = intPressure/(Reng*intTemperature);
-  } else {
-    intTemperature = reftemp+slope*(altitude-htab[i]);
-    intPressure = refpress*pow(intTemperature/reftemp,-FDMExec->GetInertial()->SLgravity()/(slope*Reng));
-    intDensity = intPressure/(Reng*intTemperature);
-  }
-  
-  lastIndex=i;
+  Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
+  KinematicViscosity = Viscosity / Density;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Calculate parameters derived from T, P and rho
-// Sum gust and turbulence values in NED frame into the wind vector.
 
-void FGAtmosphere::CalculateDerived(void)
+void FGAtmosphere::SetPressureSL(double pressure, ePressure unit)
 {
-  T_dev = (*temperature) - GetTemperature(h);
+  double press = ConvertToPSF(pressure, unit);
 
-  if (T_dev == 0.0) density_altitude = h;
-  else              density_altitude = 518.67/0.00356616 * (1.0 - pow(GetDensityRatio(),0.235));
-
-  if (turbType != ttNone) Turbulence();
-
-  vTotalWindNED = vWindNED + vGustNED + vTurbulenceNED;
-
-   // psiw (Wind heading) is the direction the wind is blowing towards
-  if (vWindNED(eX) != 0.0) psiw = atan2( vWindNED(eY), vWindNED(eX) );
-  if (psiw < 0) psiw += 2*M_PI;
-
-  soundspeed = sqrt(SHRatio*Reng*(*temperature));
-
-  intViscosity = Beta * pow(intTemperature, 1.5) / (SutherlandConstant + intTemperature);
-  intKinematicViscosity = intViscosity / intDensity;
-}
-
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Get the standard atmospheric properties at a specified altitude
-
-void FGAtmosphere::GetStdAtmosphere(double altitude) {
-  StandardTempOnly = true;
-  Calculate(altitude);
-  StandardTempOnly = false;
-  atmosphere.Temperature = intTemperature;
-  atmosphere.Pressure = intPressure;
-  atmosphere.Density = intDensity;
-
-  // Reset the internal atmospheric state
-  Calculate(h);
+  SLpressure = press;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Get the standard pressure at a specified altitude
+// Get the modeled density at a specified altitude
 
-double FGAtmosphere::GetPressure(double altitude) {
-  GetStdAtmosphere(altitude);
-  return atmosphere.Pressure;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Get the standard temperature at a specified altitude
-
-double FGAtmosphere::GetTemperature(double altitude) {
-  GetStdAtmosphere(altitude);
-  return atmosphere.Temperature;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Get the standard density at a specified altitude
-
-double FGAtmosphere::GetDensity(double altitude) {
-  GetStdAtmosphere(altitude);
-  return atmosphere.Density;
-}
-
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// square a value, but preserve the original sign
-
-static inline double square_signed (double value)
+double FGAtmosphere::GetDensity(double altitude) const
 {
-    if (value < 0)
-        return value * value * -1;
-    else
-        return value * value;
+  return GetPressure(altitude)/(Reng * GetTemperature(altitude));
 }
 
-/// simply square a value
-static inline double sqr(double x) { return x*x; }
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//
-// psi is the angle that the wind is blowing *towards*
+// This function sets the sea level temperature.
+// Internally, the Rankine scale is used for calculations, so any temperature
+// supplied must be converted to that unit.
 
-void FGAtmosphere::SetWindspeed(double speed)
+void FGAtmosphere::SetTemperatureSL(double t, eTemperature unit)
 {
-  if (vWindNED.Magnitude() == 0.0) {
-    psiw = 0.0;
-    vWindNED(eNorth) = speed;
-  } else {
-    vWindNED(eNorth) = speed * cos(psiw);
-    vWindNED(eEast) = speed * sin(psiw);
-    vWindNED(eDown) = 0.0;
-  }
+  SLtemperature = ConvertToRankine(t, unit);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGAtmosphere::GetWindspeed(void) const
+double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
 {
-  return vWindNED.Magnitude();
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//
-// psi is the angle that the wind is blowing *towards*
-
-void FGAtmosphere::SetWindPsi(double dir)
-{
-  double mag = GetWindspeed();
-  psiw = dir;
-  SetWindspeed(mag);  
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAtmosphere::Turbulence(void)
-{
-  const double DeltaT = rate*FDMExec->GetDeltaT();
-  const double wingspan = FDMExec->GetAircraft()->GetWingSpan();
-  const double HOverBMAC = FDMExec->GetAuxiliary()->GetHOverBMAC();
-  const FGMatrix33& Tl2b = FDMExec->GetPropagate()->GetTl2b();
-  const double HTailArm = FDMExec->GetAircraft()->GetHTailArm();
-  const double VTailArm = FDMExec->GetAircraft()->GetVTailArm();
-
-  switch (turbType) {
-  case ttStandard: {
-    // TurbGain = TurbGain * TurbGain * 100.0; // what is this!?
-
-    vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-    vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-    vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
-
-    MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
-                                // Scale the magnitude so that it moves
-                                // away from the peaks
-    MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
-                         (1 + fabs(Magnitude)));
-    MagnitudeAccel    += MagnitudedAccelDt*TurbRate*DeltaT;
-    Magnitude         += MagnitudeAccel*DeltaT;
-    Magnitude          = fabs(Magnitude);
-
-    vDirectiondAccelDt.Normalize();
-
-                                // deemphasise non-vertical forces
-    vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX));
-    vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY));
-
-    vDirectionAccel += vDirectiondAccelDt*TurbRate*DeltaT;
-    vDirectionAccel.Normalize();
-    vDirection      += vDirectionAccel*DeltaT;
-
-    vDirection.Normalize();
-
-                                // Diminish turbulence within three wingspans
-                                // of the ground
-    vTurbulenceNED = TurbGain * Magnitude * vDirection;
-    if (HOverBMAC < 3.0)
-        vTurbulenceNED *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
-
-    // I don't believe these next two statements calculate the proper gradient over
-    // the aircraft body. One reason is because this has no relationship with the
-    // orientation or velocity of the aircraft, which it must have. What is vTurbulenceGrad
-    // supposed to represent? And the direction and magnitude of the turbulence can change,
-    // so both accelerations need to be accounted for, no?
-
-    // Need to determine the turbulence change in body axes between two time points.
-
-    vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
-    vBodyTurbGrad = Tl2b*vTurbulenceGrad;
-
-    if (wingspan > 0) {
-      vTurbPQR(eP) = vBodyTurbGrad(eY)/wingspan;
-    } else {
-      vTurbPQR(eP) = vBodyTurbGrad(eY)/30.0;
-    }
-//     if (HTailArm != 0.0)
-//       vTurbPQR(eQ) = vBodyTurbGrad(eZ)/HTailArm;
-//     else
-//       vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
-
-    if (VTailArm > 0)
-      vTurbPQR(eR) = vBodyTurbGrad(eX)/VTailArm;
-    else
-      vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
-
-                                // Clear the horizontal forces
-                                // actually felt by the plane, now
-                                // that we've used them to calculate
-                                // moments.
-                                // Why? (JSB)
-//    vTurbulenceNED(eX) = 0.0;
-//    vTurbulenceNED(eY) = 0.0;
+  double targetTemp=0; // in degrees Rankine
 
+  switch(unit) {
+  case eFahrenheit:
+    targetTemp = t + 459.67;
     break;
-  }
-
-  case ttCulp: { 
-
-    vTurbPQR(eP) = wind_from_clockwise;
-    if (TurbGain == 0.0) return;
-  
-    // keep the inputs within allowable limts for this model
-    if (TurbGain < 0.0) TurbGain = 0.0;
-    if (TurbGain > 1.0) TurbGain = 1.0;
-    if (TurbRate < 0.0) TurbRate = 0.0;
-    if (TurbRate > 30.0) TurbRate = 30.0;
-    if (Rhythmicity < 0.0) Rhythmicity = 0.0;
-    if (Rhythmicity > 1.0) Rhythmicity = 1.0;
-
-    // generate a sine wave corresponding to turbulence rate in hertz
-    double time = FDMExec->GetSimTime();
-    double sinewave = sin( time * TurbRate * 6.283185307 );
-
-    double random = 0.0;
-    if (target_time == 0.0) {
-      strength = random = 1 - 2.0*(double(rand())/double(RAND_MAX));
-      target_time = time + 0.71 + (random * 0.5);
-    }
-    if (time > target_time) {
-      spike = 1.0;
-      target_time = 0.0;
-    }    
-
-    // max vertical wind speed in fps, corresponds to TurbGain = 1.0
-    double max_vs = 40;
-
-    vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
-    double delta = strength * max_vs * TurbGain * (1-Rhythmicity) * spike;
-
-    // Vertical component of turbulence.
-    vTurbulenceNED(3) = sinewave * max_vs * TurbGain * Rhythmicity;
-    vTurbulenceNED(3)+= delta;
-    if (HOverBMAC < 3.0)
-        vTurbulenceNED(3) *= HOverBMAC * 0.3333;
- 
-    // Yaw component of turbulence.
-    vTurbulenceNED(1) = sin( delta * 3.0 );
-    vTurbulenceNED(2) = cos( delta * 3.0 );
-
-    // Roll component of turbulence. Clockwise vortex causes left roll.
-    vTurbPQR(eP) += delta * 0.04;
-
-    spike = spike * 0.9;
+  case eCelsius:
+    targetTemp = t*9.0/5.0 + 32.0 + 459.67;
     break;
+  case eRankine:
+    targetTemp = t;
+    break;
+  case eKelvin:
+    targetTemp = t*9.0/5.0;
   }
-  case ttMilspec:
-  case ttTustin: {
-    double V = FDMExec->GetAuxiliary()->GetVt(); // true airspeed in ft/s
 
-    // an index of zero means turbulence is disabled
-    // airspeed occurs as divisor in the code below
-    if (probability_of_exceedence_index == 0 || V == 0) {
-      vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
-      vTurbPQR(1) = vTurbPQR(2) = vTurbPQR(3) = 0.0;
-      return;
-    }
+  return targetTemp;
+}
 
-    // Turbulence model according to MIL-F-8785C (Flying Qualities of Piloted Aircraft)
-    double
-      h = FDMExec->GetPropagate()->GetDistanceAGL(),
-      b_w = wingspan,
-      L_u, L_w, sig_u, sig_w;
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-      if (b_w == 0.) b_w = 30.;
+double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
+{
+  double targetPressure=0; // Pressure in PSF
 
-    // clip height functions at 10 ft
-    if (h <= 10.) h = 10;
-
-    // Scale lengths L and amplitudes sigma as function of height
-    if (h <= 1000) {
-      L_u = h/pow(0.177 + 0.000823*h, 1.2); // MIL-F-8785c, Fig. 10, p. 55
-      L_w = h;
-      sig_w = 0.1*windspeed_at_20ft;
-      sig_u = sig_w/pow(0.177 + 0.000823*h, 0.4); // MIL-F-8785c, Fig. 11, p. 56
-    } else if (h <= 2000) {
-      // linear interpolation between low altitude and high altitude models
-      L_u = L_w = 1000 + (h-1000.)/1000.*750.;
-      sig_u = sig_w = 0.1*windspeed_at_20ft
-                    + (h-1000.)/1000.*(POE_Table->GetValue(probability_of_exceedence_index, h) - 0.1*windspeed_at_20ft);
-    } else {
-      L_u = L_w = 1750.; //  MIL-F-8785c, Sec. 3.7.2.1, p. 48
-      sig_u = sig_w = POE_Table->GetValue(probability_of_exceedence_index, h);
-    }
-
-    // keep values from last timesteps
-    // TODO maybe use deque?
-    static double
-      xi_u_km1 = 0, nu_u_km1 = 0,
-      xi_v_km1 = 0, xi_v_km2 = 0, nu_v_km1 = 0, nu_v_km2 = 0,
-      xi_w_km1 = 0, xi_w_km2 = 0, nu_w_km1 = 0, nu_w_km2 = 0,
-      xi_p_km1 = 0, nu_p_km1 = 0,
-      xi_q_km1 = 0, xi_r_km1 = 0;
-
-
-    double
-      T_V = DeltaT, // for compatibility of nomenclature
-      sig_p = 1.9/sqrt(L_w*b_w)*sig_w, // Yeager1998, eq. (8)
-      sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
-      sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
-      L_p = sqrt(L_w*b_w)/2.6, // eq. (10)
-      tau_u = L_u/V, // eq. (6)
-      tau_w = L_w/V, // eq. (3)
-      tau_p = L_p/V, // eq. (9)
-      tau_q = 4*b_w/M_PI/V, // eq. (13)
-      tau_r =3*b_w/M_PI/V, // eq. (17)
-      nu_u = GaussianRandomNumber(),
-      nu_v = GaussianRandomNumber(),
-      nu_w = GaussianRandomNumber(),
-      nu_p = GaussianRandomNumber(),
-      xi_u=0, xi_v=0, xi_w=0, xi_p=0, xi_q=0, xi_r=0;
-
-    // values of turbulence NED velocities
-
-    if (turbType == ttTustin) {
-      // the following is the Tustin formulation of Yeager's report
-      double
-        omega_w = V/L_w, // hidden in nomenclature p. 3
-        omega_v = V/L_u, // this is defined nowhere
-        C_BL  = 1/tau_u/tan(T_V/2/tau_u), // eq. (19)
-        C_BLp = 1/tau_p/tan(T_V/2/tau_p), // eq. (22)
-        C_BLq = 1/tau_q/tan(T_V/2/tau_q), // eq. (24)
-        C_BLr = 1/tau_r/tan(T_V/2/tau_r); // eq. (26)
-
-      // all values calculated so far are strictly positive, except for
-      // the random numbers nu_*. This means that in the code below, all
-      // divisors are strictly positive, too, and no floating point
-      // exception should occur.
-      xi_u = -(1 - C_BL*tau_u)/(1 + C_BL*tau_u)*xi_u_km1
-           + sig_u*sqrt(2*tau_u/T_V)/(1 + C_BL*tau_u)*(nu_u + nu_u_km1); // eq. (18)
-      xi_v = -2*(sqr(omega_v) - sqr(C_BL))/sqr(omega_v + C_BL)*xi_v_km1
-           - sqr(omega_v - C_BL)/sqr(omega_v + C_BL) * xi_v_km2
-           + sig_u*sqrt(3*omega_v/T_V)/sqr(omega_v + C_BL)*(
-                 (C_BL + omega_v/sqrt(3.))*nu_v
-               + 2/sqrt(3.)*omega_v*nu_v_km1
-               + (omega_v/sqrt(3.) - C_BL)*nu_v_km2); // eq. (20) for v
-      xi_w = -2*(sqr(omega_w) - sqr(C_BL))/sqr(omega_w + C_BL)*xi_w_km1
-           - sqr(omega_w - C_BL)/sqr(omega_w + C_BL) * xi_w_km2
-           + sig_w*sqrt(3*omega_w/T_V)/sqr(omega_w + C_BL)*(
-                 (C_BL + omega_w/sqrt(3.))*nu_w
-               + 2/sqrt(3.)*omega_w*nu_w_km1
-               + (omega_w/sqrt(3.) - C_BL)*nu_w_km2); // eq. (20) for w
-      xi_p = -(1 - C_BLp*tau_p)/(1 + C_BLp*tau_p)*xi_p_km1
-           + sig_p*sqrt(2*tau_p/T_V)/(1 + C_BLp*tau_p) * (nu_p + nu_p_km1); // eq. (21)
-      xi_q = -(1 - 4*b_w*C_BLq/M_PI/V)/(1 + 4*b_w*C_BLq/M_PI/V) * xi_q_km1
-           + C_BLq/V/(1 + 4*b_w*C_BLq/M_PI/V) * (xi_w - xi_w_km1); // eq. (23)
-      xi_r = - (1 - 3*b_w*C_BLr/M_PI/V)/(1 + 3*b_w*C_BLr/M_PI/V) * xi_r_km1
-           + C_BLr/V/(1 + 3*b_w*C_BLr/M_PI/V) * (xi_v - xi_v_km1); // eq. (25)
-
-    } else if (turbType == ttMilspec) {
-      // the following is the MIL-STD-1797A formulation
-      // as cited in Yeager's report
-      xi_u = (1 - T_V/tau_u)  *xi_u_km1 + sig_u*sqrt(2*T_V/tau_u)*nu_u;  // eq. (30)
-      xi_v = (1 - 2*T_V/tau_u)*xi_v_km1 + sig_u*sqrt(4*T_V/tau_u)*nu_v;  // eq. (31)
-      xi_w = (1 - 2*T_V/tau_w)*xi_w_km1 + sig_w*sqrt(4*T_V/tau_w)*nu_w;  // eq. (32)
-      xi_p = (1 - T_V/tau_p)  *xi_p_km1 + sig_p*sqrt(2*T_V/tau_p)*nu_p;  // eq. (33)
-      xi_q = (1 - T_V/tau_q)  *xi_q_km1 + M_PI/4/b_w*(xi_w - xi_w_km1);  // eq. (34)
-      xi_r = (1 - T_V/tau_r)  *xi_r_km1 + M_PI/3/b_w*(xi_v - xi_v_km1);  // eq. (35)
-    }
-
-    // rotate by wind azimuth and assign the velocities
-    double cospsi = cos(psiw), sinpsi = sin(psiw);
-    vTurbulenceNED(1) =  cospsi*xi_u + sinpsi*xi_v;
-    vTurbulenceNED(2) = -sinpsi*xi_u + cospsi*xi_v;
-    vTurbulenceNED(3) = xi_w;
-
-    vTurbPQR(1) =  cospsi*xi_p + sinpsi*xi_q;
-    vTurbPQR(2) = -sinpsi*xi_p + cospsi*xi_q;
-    vTurbPQR(3) = xi_r;
-
-    // vTurbPQR is in the body fixed frame, not NED
-    vTurbPQR = Tl2b*vTurbPQR;
-
-    // hand on the values for the next timestep
-    xi_u_km1 = xi_u; nu_u_km1 = nu_u;
-    xi_v_km2 = xi_v_km1; xi_v_km1 = xi_v; nu_v_km2 = nu_v_km1; nu_v_km1 = nu_v;
-    xi_w_km2 = xi_w_km1; xi_w_km1 = xi_w; nu_w_km2 = nu_w_km1; nu_w_km1 = nu_w;
-    xi_p_km1 = xi_p; nu_p_km1 = nu_p;
-    xi_q_km1 = xi_q;
-    xi_r_km1 = xi_r;
-
-  }
+  switch(unit) {
+  case ePSF:
+    targetPressure = p;
+    break;
+  case eMillibars:
+    targetPressure = p*2.08854342;
+    break;
+  case ePascals:
+    targetPressure = p*0.0208854342;
+    break;
+  case eInchesHg:
+    targetPressure = p*70.7180803;
+    break;
   default:
-    break;
+    throw("Undefined pressure unit given");
   }
-}
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAtmosphere::UseExternal(void)
-{
-  temperature=&exTemperature;
-  pressure=&exPressure;
-  density=&exDensity;
-  useExternal=true;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAtmosphere::UseInternal(void)
-{
-  temperature=&intTemperature;
-  pressure=&intPressure;
-  density=&intDensity;
-  useExternal=false;
+  return targetPressure;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGAtmosphere::bind(void)
 {
-  typedef double (FGAtmosphere::*PMF)(int) const;
-  typedef double (FGAtmosphere::*PMFv)(void) const;
-  typedef int (FGAtmosphere::*PMFt)(void) const;
-  typedef void   (FGAtmosphere::*PMFd)(int,double);
-  typedef void   (FGAtmosphere::*PMFi)(int);
-  PropertyManager->Tie("atmosphere/T-R", this, (PMFv)&FGAtmosphere::GetTemperature);
-  PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, (PMFv)&FGAtmosphere::GetDensity);
-  PropertyManager->Tie("atmosphere/P-psf", this, (PMFv)&FGAtmosphere::GetPressure);
+  typedef double (FGAtmosphere::*PMFi)(int) const;
+  typedef void (FGAtmosphere::*PMF)(int, double);
+  PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
+  PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
+  PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
   PropertyManager->Tie("atmosphere/a-fps", this, &FGAtmosphere::GetSoundSpeed);
   PropertyManager->Tie("atmosphere/T-sl-R", this, &FGAtmosphere::GetTemperatureSL);
   PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this, &FGAtmosphere::GetDensitySL);
@@ -712,53 +220,8 @@ void FGAtmosphere::bind(void)
   PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
   PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
   PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
-  PropertyManager->Tie("atmosphere/psiw-rad", this, &FGAtmosphere::GetWindPsi, &FGAtmosphere::SetWindPsi);
-  PropertyManager->Tie("atmosphere/delta-T", this, &FGAtmosphere::GetDeltaT, &FGAtmosphere::SetDeltaT);
-  PropertyManager->Tie("atmosphere/T-sl-dev-F", this, &FGAtmosphere::GetSLTempDev, &FGAtmosphere::SetSLTempDev);
   PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
-
-  PropertyManager->Tie("atmosphere/wind-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetWindNED,
-                                                          (PMFd)&FGAtmosphere::SetWindNED);
-  PropertyManager->Tie("atmosphere/wind-east-fps",  this, eEast, (PMF)&FGAtmosphere::GetWindNED,
-                                                          (PMFd)&FGAtmosphere::SetWindNED);
-  PropertyManager->Tie("atmosphere/wind-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetWindNED,
-                                                          (PMFd)&FGAtmosphere::SetWindNED);
-  PropertyManager->Tie("atmosphere/wind-mag-fps", this, &FGAtmosphere::GetWindspeed,
-                                                        &FGAtmosphere::SetWindspeed);
-  PropertyManager->Tie("atmosphere/total-wind-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetTotalWindNED);
-  PropertyManager->Tie("atmosphere/total-wind-east-fps",  this, eEast,  (PMF)&FGAtmosphere::GetTotalWindNED);
-  PropertyManager->Tie("atmosphere/total-wind-down-fps",  this, eDown,  (PMF)&FGAtmosphere::GetTotalWindNED);
-
-  PropertyManager->Tie("atmosphere/gust-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetGustNED,
-                                                          (PMFd)&FGAtmosphere::SetGustNED);
-  PropertyManager->Tie("atmosphere/gust-east-fps",  this, eEast, (PMF)&FGAtmosphere::GetGustNED,
-                                                          (PMFd)&FGAtmosphere::SetGustNED);
-  PropertyManager->Tie("atmosphere/gust-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetGustNED,
-                                                          (PMFd)&FGAtmosphere::SetGustNED);
-
-  PropertyManager->Tie("atmosphere/turb-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetTurbNED,
-                                                          (PMFd)&FGAtmosphere::SetTurbNED);
-  PropertyManager->Tie("atmosphere/turb-east-fps",  this, eEast, (PMF)&FGAtmosphere::GetTurbNED,
-                                                          (PMFd)&FGAtmosphere::SetTurbNED);
-  PropertyManager->Tie("atmosphere/turb-down-fps",  this, eDown, (PMF)&FGAtmosphere::GetTurbNED,
-                                                          (PMFd)&FGAtmosphere::SetTurbNED);
-
-  PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1, (PMF)&FGAtmosphere::GetTurbPQR);
-  PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2, (PMF)&FGAtmosphere::GetTurbPQR);
-  PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3, (PMF)&FGAtmosphere::GetTurbPQR);
-  PropertyManager->Tie("atmosphere/turb-type", this, (PMFt)&FGAtmosphere::GetTurbType, (PMFi)&FGAtmosphere::SetTurbType);
-  PropertyManager->Tie("atmosphere/turb-rate", this, &FGAtmosphere::GetTurbRate, &FGAtmosphere::SetTurbRate);
-  PropertyManager->Tie("atmosphere/turb-gain", this, &FGAtmosphere::GetTurbGain, &FGAtmosphere::SetTurbGain);
-  PropertyManager->Tie("atmosphere/turb-rhythmicity", this, &FGAtmosphere::GetRhythmicity,
-                                                            &FGAtmosphere::SetRhythmicity);
-
-  PropertyManager->Tie("atmosphere/turbulence/milspec/windspeed_at_20ft_AGL-fps",
-                       this, &FGAtmosphere::GetWindspeed20ft,
-                             &FGAtmosphere::SetWindspeed20ft);
-  PropertyManager->Tie("atmosphere/turbulence/milspec/severity",
-                       this, &FGAtmosphere::GetProbabilityOfExceedence,
-                             &FGAtmosphere::SetProbabilityOfExceedence);
-
+  PropertyManager->Tie("atmosphere/pressure-altitude", this, &FGAtmosphere::GetPressureAltitude);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -789,8 +252,8 @@ void FGAtmosphere::Debug(int from)
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
-    if (from == 0) cout << "Instantiated: FGAtmosphere" << endl;
-    if (from == 1) cout << "Destroyed:    FGAtmosphere" << endl;
+    if (from == 0) std::cout << "Instantiated: FGAtmosphere" << std::endl;
+    if (from == 1) std::cout << "Destroyed:    FGAtmosphere" << std::endl;
   }
   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
   }
@@ -798,23 +261,12 @@ void FGAtmosphere::Debug(int from)
   }
   if (debug_lvl & 16) { // Sanity checking
   }
-  if (debug_lvl & 128) { // Turbulence
-    if (first_pass && from == 2) {
-      first_pass = false;
-      cout << "vTurbulenceNED(X), vTurbulenceNED(Y), vTurbulenceNED(Z), "
-           << "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
-           << "vDirection(X), vDirection(Y), vDirection(Z), "
-           << "Magnitude, "
-           << "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
-    } 
-    if (from == 2) {
-      cout << vTurbulenceNED << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
-    }
+  if (debug_lvl & 128) { // 
   }
   if (debug_lvl & 64) {
     if (from == 0) { // Constructor
-      cout << IdSrc << endl;
-      cout << IdHdr << endl;
+      std::cout << IdSrc << std::endl;
+      std::cout << IdHdr << std::endl;
     }
   }
 }
diff --git a/src/FDM/JSBSim/models/FGAtmosphere.h b/src/FDM/JSBSim/models/FGAtmosphere.h
index d2c8b5dbe..157cdd9d5 100644
--- a/src/FDM/JSBSim/models/FGAtmosphere.h
+++ b/src/FDM/JSBSim/models/FGAtmosphere.h
@@ -2,10 +2,9 @@
 
  Header:       FGAtmosphere.h
  Author:       Jon Berndt
-               Implementation of 1959 Standard Atmosphere added by Tony Peden
- Date started: 11/24/98
+ Date started: 6/2011
 
- ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
 
  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free Software
@@ -26,10 +25,7 @@
 
 HISTORY
 --------------------------------------------------------------------------------
-11/24/98   JSB   Created
-07/23/99   TP    Added implementation of 1959 Standard Atmosphere
-                 Moved calculation of Mach number to FGPropagate
-                 Updated to '76 model
+5/2011   JSB   Created
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 SENTRY
@@ -42,15 +38,14 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGModel.h"
-#include "math/FGColumnVector3.h"
-#include "math/FGTable.h"
+#include <vector>
+#include "models/FGModel.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.29 2011/07/10 20:18:14 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -62,62 +57,24 @@ namespace JSBSim {
 CLASS DOCUMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-/** Models the 1976 Standard Atmosphere.
-    @author Tony Peden, Jon Berndt
-    @version $Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $
-    @see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
-         1989, ISBN 0-07-001641-0
+/** Models an empty, abstract base atmosphere class.
 
-    Additionally, various turbulence models are available. They are specified
-    via the property <tt>atmosphere/turb-type</tt>. The following models are
-    available:
-    - 0: ttNone (turbulence disabled)
-    - 1: ttStandard
-    - 2: ttBerndt
-    - 3: ttCulp
-    - 4: ttMilspec (Dryden spectrum)
-    - 5: ttTustin (Dryden spectrum)
-
-    The Milspec and Tustin models are described in the Yeager report cited below.
-    They both use a Dryden spectrum model whose parameters (scale lengths and intensities)
-    are modelled according to MIL-F-8785C. Parameters are modelled differently
-    for altitudes below 1000ft and above 2000ft, for altitudes in between they
-    are interpolated linearly.
-
-    The two models differ in the implementation of the transfer functions
-    described in the milspec.
-
-    To use one of these two models, set <tt>atmosphere/turb-type</tt> to 4 resp. 5,
-    and specify values for <tt>atmosphere/turbulence/milspec/windspeed_at_20ft_AGL-fps<tt>
-    and <tt>atmosphere/turbulence/milspec/severity<tt> (the latter corresponds to
-    the probability of exceedence curves from Fig.&nbsp;7 of the milspec, allowable
-    range is 0 (disabled) to 7). <tt>atmosphere/psiw-rad</tt> is respected as well;
-    note that you have to specify a positive wind magnitude to prevent psiw from
-    being reset to zero.
-
-    Reference values (cf. figures 7 and 9 from the milspec):
-    <table>
-      <tr><td><b>Intensity</b></td>
-          <td><b><tt>windspeed_at_20ft_AGL-fps</tt></b></td>
-          <td><b><tt>severity</tt></b></td></tr>
-      <tr><td>light</td>
-          <td>25 (15 knots)</td>
-          <td>3</td></tr>
-      <tr><td>moderate</td>
-          <td>50 (30 knots)</td>
-          <td>4</td></tr>
-      <tr><td>severe</td>
-          <td>75 (45 knots)</td>
-          <td>6</td></tr>
-    </table>
-
-    @see Yeager, Jessie C.: "Implementation and Testing of Turbulence Models for
-         the F18-HARV" (<a
-         href="http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19980028448_1998081596.pdf">
-         pdf</a>), NASA CR-1998-206937, 1998
-
-    @see MIL-F-8785C: Military Specification: Flying Qualities of Piloted Aircraft
+  <h2> Properties </h2>
+  @property atmosphere/T-R The current modeled temperature in degrees Rankine.
+  @property atmosphere/rho-slugs_ft3
+  @property atmosphere/P-psf
+  @property atmosphere/a-fps
+  @property atmosphere/T-sl-R
+  @property atmosphere/rho-sl-slugs_ft3
+  @property atmosphere/P-sl-psf
+  @property atmosphere/a-sl-fps
+  @property atmosphere/theta
+  @property atmosphere/sigma
+  @property atmosphere/delta
+  @property atmosphere/a-ratio
 
+  @author Jon Berndt
+  @version $Id: FGAtmosphere.h,v 1.29 2011/07/10 20:18:14 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -127,11 +84,19 @@ CLASS DECLARATION
 class FGAtmosphere : public FGModel {
 public:
 
+  /// Enums for specifying temperature units.
+  enum eTemperature {eNoTempUnit=0, eFahrenheit, eCelsius, eRankine, eKelvin};
+
+  /// Enums for specifying pressure units.
+  enum ePressure {eNoPressUnit=0, ePSF, eMillibars, ePascals, eInchesHg};
+
   /// Constructor
   FGAtmosphere(FGFDMExec*);
+
   /// Destructor
-  ~FGAtmosphere();
-  /** Runs the Atmosphere model; called by the Executive
+  virtual ~FGAtmosphere();
+
+  /** Runs the atmosphere forces model; called by the Executive.
       Can pass in a value indicating if the executive is directing the simulation to Hold.
       @param Holding if true, the executive has been directed to hold the sim from 
                      advancing time. Some models may ignore this flag, such as the Input
@@ -139,210 +104,137 @@ public:
                      "Resume" command to be given.
       @return false if no error */
   bool Run(bool Holding);
+
   bool InitModel(void);
-  enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType;
 
-  /// Returns the temperature in degrees Rankine.
-  virtual double GetTemperature(void) const {return *temperature;}
-  /** Returns the density in slugs/ft^3.
-      <i>This function may <b>only</b> be used if Run() is called first.</i> */
-  virtual double GetDensity(void)  const {return *density;}
+  //  *************************************************************************
+  /// @name Temperature access functions.
+  /// There are several ways to get the temperature, and several modeled temperature
+  /// values that can be retrieved.
+  // @{
+  /// Returns the actual, modeled temperature at the current altitude in degrees Rankine.
+  /// @return Modeled temperature in degrees Rankine.
+  virtual double GetTemperature() const {return Temperature;}
+
+  /// Returns the actual modeled temperature in degrees Rankine at a specified altitude.
+  /// @param altitude The altitude above sea level (ASL) in feet.
+  /// @return Modeled temperature in degrees Rankine at the specified altitude.
+  virtual double GetTemperature(double altitude) const = 0; 
+
+  /// Returns the actual, modeled sea level temperature in degrees Rankine.
+  /// @return The modeled temperature in degrees Rankine at sea level.
+  virtual double GetTemperatureSL() const { return GetTemperature(0.0); }
+
+  /// Returns the ratio of the at-current-altitude temperature as modeled
+  /// over the sea level value.
+  virtual double GetTemperatureRatio() const { return GetTemperature()*rSLtemperature; }
+
+  /// Returns the ratio of the temperature as modeled at the supplied altitude
+  /// over the sea level value.
+  virtual double GetTemperatureRatio(double h) const { return GetTemperature(h)*rSLtemperature; }
+
+  /// Sets the Sea Level temperature.
+  /// @param t the temperature value in the unit provided.
+  /// @param unit the unit of the temperature.
+  virtual void SetTemperatureSL(double t, eTemperature unit=eFahrenheit);
+
+  /// Sets the temperature at the supplied altitude.
+  /// @param t The temperature value in the unit provided.
+  /// @param h The altitude in feet above sea level.
+  /// @param unit The unit of the temperature.
+  virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit) = 0;
+  //@}
+
+  //  *************************************************************************
+  /// @name Pressure access functions.
+  //@{
   /// Returns the pressure in psf.
-  virtual double GetPressure(void)  const {return *pressure;}
-  /// Returns the standard pressure at a specified altitude
-  virtual double GetPressure(double altitude);
-  /// Returns the standard temperature at a specified altitude
-  virtual double GetTemperature(double altitude);
-  /// Returns the standard density at a specified altitude
-  virtual double GetDensity(double altitude);
-  /// Returns the speed of sound in ft/sec.
-  virtual double GetSoundSpeed(void) const {return soundspeed;}
-  /// Returns the absolute viscosity.
-  virtual double GetAbsoluteViscosity(void) const {return intViscosity;}
-  /// Returns the kinematic viscosity.
-  virtual double GetKinematicViscosity(void) const {return intKinematicViscosity;}
+  virtual double GetPressure(void)  const {return Pressure;}
+
+  /// Returns the pressure at a specified altitude in psf.
+  virtual double GetPressure(double altitude) const = 0;
 
-  /// Returns the sea level temperature in degrees Rankine.
-  virtual double GetTemperatureSL(void) const { return SLtemperature; }
-  /// Returns the sea level density in slugs/ft^3
-  virtual double GetDensitySL(void)  const { return SLdensity; }
   /// Returns the sea level pressure in psf.
   virtual double GetPressureSL(void) const { return SLpressure; }
+
+  /// Returns the ratio of at-altitude pressure over the sea level value.
+  virtual double GetPressureRatio(void) const { return Pressure*rSLpressure; }
+
+  /** Sets the sea level pressure for modeling.
+      @param pressure The pressure in the units specified (PSF by default).
+      @param unit the unit of measure that the specified pressure is
+                  supplied in.*/
+  virtual void SetPressureSL(double pressure, ePressure unit=ePSF);
+  //@}
+
+  //  *************************************************************************
+  /// @name Density access functions.
+  //@{
+  /** Returns the density in slugs/ft^3.
+      This function may only be used if Run() is called first. */
+  virtual double GetDensity(void)  const {return Density;}
+
+  /** Returns the density in slugs/ft^3 at a given altitude in ft. */
+  virtual double GetDensity(double altitude) const;
+
+  /// Returns the sea level density in slugs/ft^3
+  virtual double GetDensitySL(void)  const { return SLdensity; }
+
+  /// Returns the ratio of at-altitude density over the sea level value.
+  virtual double GetDensityRatio(void) const { return Density*rSLdensity; }
+  //@}
+
+  //  *************************************************************************
+  /// @name Speed of sound access functions.
+  //@{
+  /// Returns the speed of sound in ft/sec.
+  virtual double GetSoundSpeed(void) const {return Soundspeed;}
+
   /// Returns the sea level speed of sound in ft/sec.
   virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; }
 
-  /// Returns the ratio of at-altitude temperature over the sea level value.
-  virtual double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
-  /// Returns the ratio of at-altitude density over the sea level value.
-  virtual double GetDensityRatio(void) const { return (*density)*rSLdensity; }
-  /// Returns the ratio of at-altitude pressure over the sea level value.
-  virtual double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
   /// Returns the ratio of at-altitude sound speed over the sea level value.
-  virtual double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
+  virtual double GetSoundSpeedRatio(void) const { return Soundspeed*rSLsoundspeed; }
+  //@}
 
-  /// Tells the simulator to use an externally calculated atmosphere model.
-  virtual void UseExternal(void);
-  /// Tells the simulator to use the internal atmosphere model.
-  virtual void UseInternal(void);  //this is the default
-  /// Gets the boolean that tells if the external atmosphere model is being used.
-  virtual bool External(void) { return useExternal; }
+  //  *************************************************************************
+  /// @name Viscosity access functions.
+  //@{
+  /// Returns the absolute viscosity.
+  virtual double GetAbsoluteViscosity(void) const {return Viscosity;}
 
-  /// Provides the external atmosphere model with an interface to set the temperature.
-  virtual void SetExTemperature(double t)  { exTemperature=t; }
-  /// Provides the external atmosphere model with an interface to set the density.
-  virtual void SetExDensity(double d)      { exDensity=d; }
-  /// Provides the external atmosphere model with an interface to set the pressure.
-  virtual void SetExPressure(double p)     { exPressure=p; }
+  /// Returns the kinematic viscosity.
+  virtual double GetKinematicViscosity(void) const {return KinematicViscosity;}
+  //@}
 
-  /// Sets the temperature deviation at sea-level in degrees Fahrenheit
-  virtual void SetSLTempDev(double d)  { T_dev_sl = d; }
-  /// Gets the temperature deviation at sea-level in degrees Fahrenheit
-  virtual double GetSLTempDev(void) const { return T_dev_sl; }
-  /// Sets the current delta-T in degrees Fahrenheit
-  virtual void SetDeltaT(double d)  { delta_T = d; }
-  /// Gets the current delta-T in degrees Fahrenheit
-  virtual double GetDeltaT(void) const  { return delta_T; }
-  /// Gets the at-altitude temperature deviation in degrees Fahrenheit
-  virtual double GetTempDev(void) const { return T_dev; }
-  /// Gets the density altitude in feet
-  virtual double GetDensityAltitude(void) const { return density_altitude; }
+  virtual double GetDensityAltitude() const {return DensityAltitude;}
 
-  // TOTAL WIND access functions (wind + gust + turbulence)
+  virtual double GetPressureAltitude() const {return PressureAltitude;}
 
-  /// Retrieves the total wind components in NED frame.
-  virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; }
-
-  /// Retrieves a total wind component in NED frame.
-  virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);}
-
-  // WIND access functions
-
-  /// Sets the wind components in NED frame.
-  virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
-
-  /// Sets a wind component in NED frame.
-  virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;}
-
-  /// Retrieves the wind components in NED frame.
-  virtual FGColumnVector3& GetWindNED(void) { return vWindNED; }
-
-  /// Retrieves a wind component in NED frame.
-  virtual double GetWindNED(int idx) const {return vWindNED(idx);}
-
-  /** Retrieves the direction that the wind is coming from.
-      The direction is defined as north=0 and increases counterclockwise.
-      The wind heading is returned in radians.*/
-  virtual double GetWindPsi(void) const { return psiw; }
-
-  /** Sets the direction that the wind is coming from.
-      The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The
-      vertical component of wind is assumed to be zero - and is forcibly set to zero. This function
-      sets the vWindNED vector components based on the supplied direction. The magnitude of
-      the wind set in the vector is preserved (assuming the vertical component is non-zero).
-      @param dir wind direction in the horizontal plane, in radians.*/
-  virtual void SetWindPsi(double dir);
-
-  virtual void SetWindspeed(double speed);
-
-  virtual double GetWindspeed(void) const;
-
-  // GUST access functions
-
-  /// Sets a gust component in NED frame.
-  virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;}
-
-  /// Sets a turbulence component in NED frame.
-  virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;}
-
-  /// Sets the gust components in NED frame.
-  virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;}
-
-  /// Retrieves a gust component in NED frame.
-  virtual double GetGustNED(int idx) const {return vGustNED(idx);}
-
-  /// Retrieves a turbulence component in NED frame.
-  virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);}
-
-  /// Retrieves the gust components in NED frame.
-  virtual FGColumnVector3& GetGustNED(void) {return vGustNED;}
-
-  /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */
-  virtual void   SetTurbType(tType tt) {turbType = tt;}
-  virtual tType  GetTurbType() const {return turbType;}
-
-  virtual void   SetTurbGain(double tg) {TurbGain = tg;}
-  virtual double GetTurbGain() const {return TurbGain;}
-
-  virtual void   SetTurbRate(double tr) {TurbRate = tr;}
-  virtual double GetTurbRate() const {return TurbRate;}
-
-  virtual void   SetRhythmicity(double r) {Rhythmicity=r;}
-  virtual double GetRhythmicity() const {return Rhythmicity;}
-
-  virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
-  virtual double GetTurbMagnitude(void) const {return Magnitude;}
-  virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
-  virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
-
-  virtual void   SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
-  virtual double GetWindspeed20ft() const { return windspeed_at_20ft;}
-
-  /// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence
-  virtual void   SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;}
-  virtual int    GetProbabilityOfExceedence() const { return probability_of_exceedence_index;}
+  struct Inputs {
+    double altitudeASL;
+  } in;
 
 protected:
-  double rho;
+  double    SLtemperature,    SLdensity,    SLpressure,    SLsoundspeed; // Sea level conditions
+  double      Temperature,      Density,      Pressure,      Soundspeed; // Current actual conditions at altitude
+  double   rSLtemperature,   rSLdensity,   rSLpressure,   rSLsoundspeed; // Reciprocal of sea level conditions
 
-  struct atmType {double Temperature; double Pressure; double Density;};
-  int lastIndex;
-  double h;
-  double htab[8];
-  double StdSLtemperature,StdSLdensity,StdSLpressure,StdSLsoundspeed;
-  double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
-  double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
-  double *temperature, *density, *pressure;
-  double soundspeed;
-  bool useExternal;
-  double exTemperature,exDensity,exPressure;
-  double intTemperature, intDensity, intPressure;
-  double SutherlandConstant, Beta, intViscosity, intKinematicViscosity;
-  double T_dev_sl, T_dev, delta_T, density_altitude;
-  atmType atmosphere;
-  bool StandardTempOnly;
-  bool first_pass;
+  double PressureAltitude;
+  double DensityAltitude;
 
-  double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
-  double TurbGain;
-  double TurbRate;
-  double Rhythmicity;
-  double wind_from_clockwise;
-  double spike, target_time, strength;
-  FGColumnVector3 vDirectiondAccelDt;
-  FGColumnVector3 vDirectionAccel;
-  FGColumnVector3 vDirection;
-  FGColumnVector3 vTurbulenceGrad;
-  FGColumnVector3 vBodyTurbGrad;
-  FGColumnVector3 vTurbPQR;
+  const double SutherlandConstant, Beta;
+  double Viscosity, KinematicViscosity;
 
-  // Dryden turbulence model
-  double windspeed_at_20ft; ///< in ft/s
-  int probability_of_exceedence_index; ///< this is bound as the severity property
-  FGTable *POE_Table; ///< probability of exceedence table
-
-  double psiw;
-  FGColumnVector3 vTotalWindNED;
-  FGColumnVector3 vWindNED;
-  FGColumnVector3 vGustNED;
-  FGColumnVector3 vTurbulenceNED;
-
-  /// Calculate the atmosphere for the given altitude, including effects of temperature deviation.
+  /// Calculate the atmosphere for the given altitude.
   void Calculate(double altitude);
-  /// Calculate atmospheric properties other than the basic T, P and rho.
-  void CalculateDerived(void);
-  /// Get T, P and rho for a standard atmosphere at the given altitude.
-  void GetStdAtmosphere(double altitude);
-  void Turbulence(void);
+
+  // Converts to Rankine from one of several unit systems.
+  virtual double ConvertToRankine(double t, eTemperature unit) const;
+  
+  // Converts to PSF (pounds per square foot) from one of several unit systems.
+  virtual double ConvertToPSF(double t, ePressure unit=ePSF) const;
+
   virtual void bind(void);
   void Debug(int from);
 };
diff --git a/src/FDM/JSBSim/models/FGAuxiliary.cpp b/src/FDM/JSBSim/models/FGAuxiliary.cpp
index 0993bc757..8e29a7e39 100755
--- a/src/FDM/JSBSim/models/FGAuxiliary.cpp
+++ b/src/FDM/JSBSim/models/FGAuxiliary.cpp
@@ -40,26 +40,17 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGAuxiliary.h"
-#include "FGAerodynamics.h"
-#include "FGPropagate.h"
-#include "FGAtmosphere.h"
-#include "FGFDMExec.h"
-#include "FGAircraft.h"
-#include "FGInertial.h"
-#include "FGExternalReactions.h"
-#include "FGBuoyantForces.h"
-#include "FGGroundReactions.h"
-#include "FGPropulsion.h"
-#include "FGMassBalance.h"
-#include "input_output/FGPropertyManager.h"
 #include <iostream>
 
+#include "FGAuxiliary.h"
+#include "FGFDMExec.h"
+#include "input_output/FGPropertyManager.h"
+
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.49 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.53 2011/08/17 23:56:01 jberndt Exp $";
 static const char *IdHdr = ID_AUXILIARY;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -70,9 +61,8 @@ CLASS IMPLEMENTATION
 FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
 {
   Name = "FGAuxiliary";
-  pt = p = psl = 1.0;
-  rho = rhosl = 1.0;
-  tat = sat = 1.0;
+  pt = 1.0;
+  tat = 1.0;
   tatc = RankineToCelsius(tat);
 
   vcas = veas = 0.0;
@@ -91,13 +81,11 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
 
   vPilotAccel.InitMatrix();
   vPilotAccelN.InitMatrix();
-  vToEyePt.InitMatrix();
   vAeroUVW.InitMatrix();
   vAeroPQR.InitMatrix();
   vMachUVW.InitMatrix();
   vEuler.InitMatrix();
   vEulerRates.InitMatrix();
-  vAircraftAccel.InitMatrix();
 
   bind();
 
@@ -108,11 +96,8 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
 
 bool FGAuxiliary::InitModel(void)
 {
-  pt = p = FDMExec->GetAtmosphere()->GetPressure();
-  rho = FDMExec->GetAtmosphere()->GetDensity();
-  rhosl = FDMExec->GetAtmosphere()->GetDensitySL();
-  psl = FDMExec->GetAtmosphere()->GetPressureSL();
-  tat = sat = FDMExec->GetAtmosphere()->GetTemperature();
+  pt = in.Pressure;
+  tat = in.Temperature;
   tatc = RankineToCelsius(tat);
 
   vcas = veas = 0.0;
@@ -131,13 +116,11 @@ bool FGAuxiliary::InitModel(void)
 
   vPilotAccel.InitMatrix();
   vPilotAccelN.InitMatrix();
-  vToEyePt.InitMatrix();
   vAeroUVW.InitMatrix();
   vAeroPQR.InitMatrix();
   vMachUVW.InitMatrix();
   vEuler.InitMatrix();
   vEulerRates.InitMatrix();
-  vAircraftAccel.InitMatrix();
 
   return true;
 }
@@ -160,139 +143,118 @@ bool FGAuxiliary::Run(bool Holding)
 
   RunPreFunctions();
 
-  const double density = FDMExec->GetAtmosphere()->GetDensity();
-  const double soundspeed = FDMExec->GetAtmosphere()->GetSoundSpeed();
-  const double DistanceAGL = FDMExec->GetPropagate()->GetDistanceAGL();
-  const double wingspan = FDMExec->GetAircraft()->GetWingSpan();
-  const FGMatrix33& Tl2b = FDMExec->GetPropagate()->GetTl2b();
-  const FGMatrix33& Tb2l = FDMExec->GetPropagate()->GetTb2l();
-
-  const FGColumnVector3& vPQR = FDMExec->GetPropagate()->GetPQR();
-  const FGColumnVector3& vUVW = FDMExec->GetPropagate()->GetUVW();
-  const FGColumnVector3& vUVWdot = FDMExec->GetPropagate()->GetUVWdot();
-  const FGColumnVector3& vVel = FDMExec->GetPropagate()->GetVel();
-
-  p = FDMExec->GetAtmosphere()->GetPressure();
-  rhosl = FDMExec->GetAtmosphere()->GetDensitySL();
-  psl = FDMExec->GetAtmosphere()->GetPressureSL();
-  sat = FDMExec->GetAtmosphere()->GetTemperature();
-
 // Rotation
 
-  double cTht = FDMExec->GetPropagate()->GetCosEuler(eTht);
-  double sTht = FDMExec->GetPropagate()->GetSinEuler(eTht);
-  double cPhi = FDMExec->GetPropagate()->GetCosEuler(ePhi);
-  double sPhi = FDMExec->GetPropagate()->GetSinEuler(ePhi);
-
-  vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
-  if (cTht != 0.0) {
-    vEulerRates(ePsi) = (vPQR(eQ)*sPhi + vPQR(eR)*cPhi)/cTht;
-    vEulerRates(ePhi) = vPQR(eP) + vEulerRates(ePsi)*sTht;
+  vEulerRates(eTht) = in.vPQR(eQ)*in.CosPhi - in.vPQR(eR)*in.SinPhi;
+  if (in.CosTht != 0.0) {
+    vEulerRates(ePsi) = (in.vPQR(eQ)*in.SinPhi + in.vPQR(eR)*in.CosPhi)/in.CosTht;
+    vEulerRates(ePhi) = in.vPQR(eP) + vEulerRates(ePsi)*in.SinTht;
   }
 
 // Combine the wind speed with aircraft speed to obtain wind relative speed
-  FGColumnVector3 wind = Tl2b*FDMExec->GetAtmosphere()->GetTotalWindNED();
-  vAeroPQR = vPQR - FDMExec->GetAtmosphere()->GetTurbPQR();
-  vAeroUVW = vUVW - wind;
+  vAeroPQR = in.vPQR - in.TurbPQR;
+  vAeroUVW = in.vUVW - in.Tl2b * in.TotalWindNED;
 
   Vt = vAeroUVW.Magnitude();
-  double Vt2 = Vt*Vt;
   alpha = beta = adot = bdot = 0;
-  double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
+  double AeroU2 = vAeroUVW(eU)*vAeroUVW(eU);
+  double AeroV2 = vAeroUVW(eV)*vAeroUVW(eV);
+  double AeroW2 = vAeroUVW(eW)*vAeroUVW(eW);
+  double mUW = AeroU2 + AeroW2;
+
+  double Vt2 = Vt*Vt;
 
   if ( Vt > 1.0 ) {
     if (vAeroUVW(eW) != 0.0)
-      alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
+      alpha = AeroU2 > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
     if (vAeroUVW(eV) != 0.0)
-      beta = mUW > 0.0 ? atan2(vAeroUVW(eV), sqrt(mUW)) : 0.0;
+      beta  =    mUW > 0.0 ? atan2(vAeroUVW(eV), sqrt(mUW)) : 0.0;
 
     double signU=1;
     if (vAeroUVW(eU) < 0.0) signU=-1;
 
     if ( mUW >= 1.0 ) {
-      adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
-      bdot = (signU*mUW*vUVWdot(eV)
-             - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU) + vAeroUVW(eW)*vUVWdot(eW)))/(Vt2*sqrt(mUW));
+      adot = (vAeroUVW(eU)*in.vUVWdot(eW) - vAeroUVW(eW)*in.vUVWdot(eU))/mUW;
+      bdot = (signU*mUW*in.vUVWdot(eV)
+             - vAeroUVW(eV)*(vAeroUVW(eU)*in.vUVWdot(eU) + vAeroUVW(eW)*in.vUVWdot(eW)))/(Vt2*sqrt(mUW));
     }
   }
 
-  Re = Vt * FDMExec->GetAircraft()->Getcbar() / FDMExec->GetAtmosphere()->GetKinematicViscosity();
+  Re = Vt * in.Wingchord / in.KinematicViscosity;
 
-  qbar = 0.5*density*Vt2;
-  qbarUW = 0.5*density*(mUW);
-  qbarUV = 0.5*density*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
-  Mach = Vt / soundspeed;
-  MachU = vMachUVW(eU) = vAeroUVW(eU) / soundspeed;
-  vMachUVW(eV) = vAeroUVW(eV) / soundspeed;
-  vMachUVW(eW) = vAeroUVW(eW) / soundspeed;
+  double densityD2 = 0.5*in.Density;
+
+  qbar = densityD2 * Vt2;
+  qbarUW = densityD2 * (mUW);
+  qbarUV = densityD2 * (AeroU2 + AeroV2);
+  Mach = Vt / in.SoundSpeed;
+  MachU = vMachUVW(eU) = vAeroUVW(eU) / in.SoundSpeed;
+  vMachUVW(eV) = vAeroUVW(eV) / in.SoundSpeed;
+  vMachUVW(eW) = vAeroUVW(eW) / in.SoundSpeed;
+  double MachU2 = MachU * MachU;
 
 // Position
 
-  Vground = sqrt( vVel(eNorth)*vVel(eNorth) + vVel(eEast)*vVel(eEast) );
+  Vground = sqrt( in.vVel(eNorth)*in.vVel(eNorth) + in.vVel(eEast)*in.vVel(eEast) );
 
-  psigt = atan2(vVel(eEast), vVel(eNorth));
+  psigt = atan2(in.vVel(eEast), in.vVel(eNorth));
   if (psigt < 0.0) psigt += 2*M_PI;
-  gamma = atan2(-vVel(eDown), Vground);
+  gamma = atan2(-in.vVel(eDown), Vground);
 
-  tat = sat*(1 + 0.2*Mach*Mach); // Total Temperature, isentropic flow
+  tat = in.Temperature*(1 + 0.2*Mach*Mach); // Total Temperature, isentropic flow
   tatc = RankineToCelsius(tat);
 
   if (MachU < 1) {   // Calculate total pressure assuming isentropic flow
-    pt = p*pow((1 + 0.2*MachU*MachU),3.5);
+    pt = in.Pressure*pow((1 + 0.2*MachU2),3.5);
   } else {
     // Use Rayleigh pitot tube formula for normal shock in front of pitot tube
-    B = 5.76*MachU*MachU/(5.6*MachU*MachU - 0.8);
-    D = (2.8*MachU*MachU-0.4)*0.4167;
-    pt = p*pow(B,3.5)*D;
+    B = 5.76 * MachU2 / (5.6*MachU2 - 0.8);
+    D = (2.8 * MachU2 - 0.4) * 0.4167;
+    pt = in.Pressure*pow(B,3.5)*D;
   }
 
-  A = pow(((pt-p)/psl+1),0.28571);
+  A = pow(((pt-in.Pressure)/in.PressureSL + 1),0.28571);
   if (MachU > 0.0) {
-    vcas = sqrt(7*psl/rhosl*(A-1));
-    veas = sqrt(2*qbar/rhosl);
+    vcas = sqrt(7 * in.PressureSL / in.DensitySL * (A-1));
+    veas = sqrt(2 * qbar / in.DensitySL);
+    vtrue = 1116.43559 * MachU * sqrt(in.Temperature / 518.67);
   } else {
-    vcas = veas = 0.0;
+    vcas = veas = vtrue = 0.0;
   }
 
-  const double SLgravity = FDMExec->GetInertial()->SLgravity();
-
   vPilotAccel.InitMatrix();
+  vNcg = in.vBodyAccel/in.SLGravity;
   if ( Vt > 1.0 ) {
-     vAircraftAccel = FDMExec->GetAircraft()->GetBodyAccel();
-     // Nz is Acceleration in "g's", along normal axis (-Z body axis)
-     Nz = -vAircraftAccel(eZ)/SLgravity;
-     vToEyePt = FDMExec->GetMassBalance()->StructuralToBody(FDMExec->GetAircraft()->GetXYZep());
-     vPilotAccel = vAircraftAccel + FDMExec->GetPropagate()->GetPQRdot() * vToEyePt;
-     vPilotAccel += vPQR * (vPQR * vToEyePt);
+    // Nz is Acceleration in "g's", along normal axis (-Z body axis)
+    Nz = -vNcg(eZ);
+    vPilotAccel = in.vBodyAccel + in.vPQRdot * in.ToEyePt;
+    vPilotAccel += in.vPQR * (in.vPQR * in.ToEyePt);
   } else {
-     // The line below handles low velocity (and on-ground) cases, basically
-     // representing the opposite of the force that the landing gear would
-     // exert on the ground (which is just the total weight). This eliminates
-     // any jitter that could be introduced by the landing gear. Theoretically,
-     // this branch could be eliminated, with a penalty of having a short
-     // transient at startup (lasting only a fraction of a second).
-     vPilotAccel = Tl2b * FGColumnVector3( 0.0, 0.0, -SLgravity );
-     Nz = -vPilotAccel(eZ)/SLgravity;
+    // The line below handles low velocity (and on-ground) cases, basically
+    // representing the opposite of the force that the landing gear would
+    // exert on the ground (which is just the total weight). This eliminates
+    // any jitter that could be introduced by the landing gear. Theoretically,
+    // this branch could be eliminated, with a penalty of having a short
+    // transient at startup (lasting only a fraction of a second).
+    vPilotAccel = in.Tl2b * FGColumnVector3( 0.0, 0.0, -in.SLGravity );
+    Nz = -vPilotAccel(eZ) / in.SLGravity;
   }
 
-  vPilotAccelN = vPilotAccel/SLgravity;
+  vNwcg = mTb2w * vNcg;
+  vNwcg(eZ) = 1.0 - vNwcg(eZ);
+
+  vPilotAccelN = vPilotAccel / in.SLGravity;
 
   // VRP computation
-  const FGLocation& vLocation = FDMExec->GetPropagate()->GetLocation();
-  const FGColumnVector3& vrpStructural = FDMExec->GetAircraft()->GetXYZvrp();
-  const FGColumnVector3 vrpBody = FDMExec->GetMassBalance()->StructuralToBody( vrpStructural );
-  const FGColumnVector3 vrpLocal = Tb2l * vrpBody;
-  vLocationVRP = vLocation.LocalToLocation( vrpLocal );
+  vLocationVRP = in.vLocation.LocalToLocation( in.Tb2l * in.VRPBody );
 
   // Recompute some derived values now that we know the dependent parameters values ...
-  hoverbcg = DistanceAGL / wingspan;
+  hoverbcg = in.DistanceAGL / in.Wingspan;
 
-  FGColumnVector3 vMac = Tb2l*FDMExec->GetMassBalance()->StructuralToBody(FDMExec->GetAircraft()->GetXYZrp());
-  hoverbmac = (DistanceAGL + vMac(3)) / wingspan;
-
-  // when all model are executed, 
-  // please calculate the distance from the initial point
+  FGColumnVector3 vMac = in.Tb2l * in.RPBody;
+  hoverbmac = (in.DistanceAGL + vMac(3)) / in.Wingspan;
 
+  // When all models are executed calculate the distance from the initial point.
   CalculateRelativePosition();
 
   RunPostFunctions();
@@ -300,6 +262,68 @@ bool FGAuxiliary::Run(bool Holding)
   return false;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// From Stevens and Lewis, "Aircraft Control and Simulation", 3rd Ed., the
+// transformation from body to wind axes is defined (where "a" is alpha and "B"
+// is beta):
+//
+//   cos(a)*cos(B)     sin(B)    sin(a)*cos(B)
+//  -cos(a)*sin(B)     cos(B)   -sin(a)*sin(B)
+//  -sin(a)              0       cos(a)
+//
+// The transform from wind to body axes is then,
+//
+//   cos(a)*cos(B)  -cos(a)*sin(B)  -sin(a)
+//          sin(B)          cos(B)     0
+//   sin(a)*cos(B)  -sin(a)*sin(B)   cos(a)
+
+FGMatrix33& FGAuxiliary::GetTw2b(void)
+{
+  double ca, cb, sa, sb;
+
+  ca = cos(alpha);
+  sa = sin(alpha);
+  cb = cos(beta);
+  sb = sin(beta);
+
+  mTw2b(1,1) =  ca*cb;
+  mTw2b(1,2) = -ca*sb;
+  mTw2b(1,3) = -sa;
+  mTw2b(2,1) =  sb;
+  mTw2b(2,2) =  cb;
+  mTw2b(2,3) =  0.0;
+  mTw2b(3,1) =  sa*cb;
+  mTw2b(3,2) = -sa*sb;
+  mTw2b(3,3) =  ca;
+
+  return mTw2b;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGMatrix33& FGAuxiliary::GetTb2w(void)
+{
+  double ca, cb, sa, sb;
+
+  ca = cos(alpha);
+  sa = sin(alpha);
+  cb = cos(beta);
+  sb = sin(beta);
+
+  mTb2w(1,1) = ca*cb;
+  mTb2w(1,2) = sb;
+  mTb2w(1,3) = sa*cb;
+  mTb2w(2,1) = -ca*sb;
+  mTb2w(2,2) = cb;
+  mTb2w(2,3) = -sa*sb;
+  mTb2w(3,1) = -sa;
+  mTb2w(3,2) = 0.0;
+  mTb2w(3,3) = ca;
+
+  return mTb2w;
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //
 // A positive headwind is blowing with you, a negative headwind is blowing against you.
@@ -308,12 +332,7 @@ bool FGAuxiliary::Run(bool Holding)
 
 double FGAuxiliary::GetHeadWind(void) const
 {
-  double psiw,vw;
-
-  psiw = FDMExec->GetAtmosphere()->GetWindPsi();
-  vw = FDMExec->GetAtmosphere()->GetTotalWindNED().Magnitude();
-
-  return vw*cos(psiw - FDMExec->GetPropagate()->GetEuler(ePsi));
+  return in.Vwind * cos(in.WindPsi - in.Psi);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -324,23 +343,38 @@ double FGAuxiliary::GetHeadWind(void) const
 
 double FGAuxiliary::GetCrossWind(void) const
 {
-  double psiw,vw;
-
-  psiw = FDMExec->GetAtmosphere()->GetWindPsi();
-  vw = FDMExec->GetAtmosphere()->GetTotalWindNED().Magnitude();
-
-  return  vw*sin(psiw - FDMExec->GetPropagate()->GetEuler(ePsi));
+  return in.Vwind * sin(in.WindPsi - in.Psi);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 double FGAuxiliary::GethVRP(void) const
 {
-  return vLocationVRP.GetRadius() - FDMExec->GetPropagate()->GetSeaLevelRadius();
+  return vLocationVRP.GetRadius() - in.ReferenceRadius;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+double FGAuxiliary::GetNlf(void) const
+{
+  if (in.Mass != 0)
+    return (-in.vFw(3))/(in.Mass*slugtolb);
+  else
+    return 0.;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGAuxiliary::CalculateRelativePosition(void)  //ToDo: This belongs elsewhere - perhaps in FGPropagate or Exec
+{ 
+  const double earth_radius_mt = in.ReferenceRadius*fttom;
+  lat_relative_position=(in.Latitude  - FDMExec->GetIC()->GetLatitudeDegIC() *degtorad)*earth_radius_mt;
+  lon_relative_position=(in.Longitude - FDMExec->GetIC()->GetLongitudeDegIC()*degtorad)*earth_radius_mt;
+  relative_position = sqrt(lat_relative_position*lat_relative_position + lon_relative_position*lon_relative_position);
+};
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGAuxiliary::bind(void)
 {
   typedef double (FGAuxiliary::*PMF)(int) const;
@@ -352,6 +386,8 @@ void FGAuxiliary::bind(void)
   PropertyManager->Tie("velocities/vc-kts", this, &FGAuxiliary::GetVcalibratedKTS);
   PropertyManager->Tie("velocities/ve-fps", this, &FGAuxiliary::GetVequivalentFPS);
   PropertyManager->Tie("velocities/ve-kts", this, &FGAuxiliary::GetVequivalentKTS);
+  PropertyManager->Tie("velocities/vtrue-fps", this, &FGAuxiliary::GetVtrueFPS);
+  PropertyManager->Tie("velocities/vtrue-kts", this, &FGAuxiliary::GetVtrueKTS);
   PropertyManager->Tie("velocities/machU", this, &FGAuxiliary::GetMachU);
   PropertyManager->Tie("velocities/p-aero-rad_sec", this, eX, (PMF)&FGAuxiliary::GetAeroPQR);
   PropertyManager->Tie("velocities/q-aero-rad_sec", this, eY, (PMF)&FGAuxiliary::GetAeroPQR);
@@ -362,8 +398,8 @@ void FGAuxiliary::bind(void)
   PropertyManager->Tie("velocities/u-aero-fps", this, eU, (PMF)&FGAuxiliary::GetAeroUVW);
   PropertyManager->Tie("velocities/v-aero-fps", this, eV, (PMF)&FGAuxiliary::GetAeroUVW);
   PropertyManager->Tie("velocities/w-aero-fps", this, eW, (PMF)&FGAuxiliary::GetAeroUVW);
-  PropertyManager->Tie("velocities/vt-fps", this, &FGAuxiliary::GetVt, &FGAuxiliary::SetVt, true);
-  PropertyManager->Tie("velocities/mach", this, &FGAuxiliary::GetMach, &FGAuxiliary::SetMach, true);
+  PropertyManager->Tie("velocities/vt-fps", this, &FGAuxiliary::GetVt);
+  PropertyManager->Tie("velocities/mach", this, &FGAuxiliary::GetMach);
   PropertyManager->Tie("velocities/vg-fps", this, &FGAuxiliary::GetVground);
   PropertyManager->Tie("accelerations/a-pilot-x-ft_sec2", this, eX, (PMF)&FGAuxiliary::GetPilotAccel);
   PropertyManager->Tie("accelerations/a-pilot-y-ft_sec2", this, eY, (PMF)&FGAuxiliary::GetPilotAccel);
@@ -372,25 +408,26 @@ void FGAuxiliary::bind(void)
   PropertyManager->Tie("accelerations/n-pilot-y-norm", this, eY, (PMF)&FGAuxiliary::GetNpilot);
   PropertyManager->Tie("accelerations/n-pilot-z-norm", this, eZ, (PMF)&FGAuxiliary::GetNpilot);
   PropertyManager->Tie("accelerations/Nz", this, &FGAuxiliary::GetNz);
+  PropertyManager->Tie("forces/load-factor", this, &FGAuxiliary::GetNlf);
   /* PropertyManager->Tie("atmosphere/headwind-fps", this, &FGAuxiliary::GetHeadWind, true);
   PropertyManager->Tie("atmosphere/crosswind-fps", this, &FGAuxiliary::GetCrossWind, true); */
-  PropertyManager->Tie("aero/alpha-rad", this, (PF)&FGAuxiliary::Getalpha, &FGAuxiliary::Setalpha, true);
-  PropertyManager->Tie("aero/beta-rad", this, (PF)&FGAuxiliary::Getbeta, &FGAuxiliary::Setbeta, true);
+  PropertyManager->Tie("aero/alpha-rad", this, (PF)&FGAuxiliary::Getalpha);
+  PropertyManager->Tie("aero/beta-rad", this, (PF)&FGAuxiliary::Getbeta);
   PropertyManager->Tie("aero/mag-beta-rad", this, (PF)&FGAuxiliary::GetMagBeta);
   PropertyManager->Tie("aero/alpha-deg", this, inDegrees, (PMF)&FGAuxiliary::Getalpha);
   PropertyManager->Tie("aero/beta-deg", this, inDegrees, (PMF)&FGAuxiliary::Getbeta);
   PropertyManager->Tie("aero/mag-beta-deg", this, inDegrees, (PMF)&FGAuxiliary::GetMagBeta);
   PropertyManager->Tie("aero/Re", this, &FGAuxiliary::GetReynoldsNumber);
-  PropertyManager->Tie("aero/qbar-psf", this, &FGAuxiliary::Getqbar, &FGAuxiliary::Setqbar, true);
-  PropertyManager->Tie("aero/qbarUW-psf", this, &FGAuxiliary::GetqbarUW, &FGAuxiliary::SetqbarUW, true);
-  PropertyManager->Tie("aero/qbarUV-psf", this, &FGAuxiliary::GetqbarUV, &FGAuxiliary::SetqbarUV, true);
-  PropertyManager->Tie("aero/alphadot-rad_sec", this, (PF)&FGAuxiliary::Getadot, &FGAuxiliary::Setadot, true);
-  PropertyManager->Tie("aero/betadot-rad_sec", this, (PF)&FGAuxiliary::Getbdot, &FGAuxiliary::Setbdot, true);
+  PropertyManager->Tie("aero/qbar-psf", this, &FGAuxiliary::Getqbar);
+  PropertyManager->Tie("aero/qbarUW-psf", this, &FGAuxiliary::GetqbarUW);
+  PropertyManager->Tie("aero/qbarUV-psf", this, &FGAuxiliary::GetqbarUV);
+  PropertyManager->Tie("aero/alphadot-rad_sec", this, (PF)&FGAuxiliary::Getadot);
+  PropertyManager->Tie("aero/betadot-rad_sec", this, (PF)&FGAuxiliary::Getbdot);
   PropertyManager->Tie("aero/alphadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getadot);
   PropertyManager->Tie("aero/betadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getbdot);
   PropertyManager->Tie("aero/h_b-cg-ft", this, &FGAuxiliary::GetHOverBCG);
   PropertyManager->Tie("aero/h_b-mac-ft", this, &FGAuxiliary::GetHOverBMAC);
-  PropertyManager->Tie("flight-path/gamma-rad", this, &FGAuxiliary::GetGamma, &FGAuxiliary::SetGamma);
+  PropertyManager->Tie("flight-path/gamma-rad", this, &FGAuxiliary::GetGamma);
   PropertyManager->Tie("flight-path/psi-gt-rad", this, &FGAuxiliary::GetGroundTrack);
 
   PropertyManager->Tie("position/distance-from-start-lon-mt", this, &FGAuxiliary::GetLongitudeRelativePosition);
@@ -403,16 +440,6 @@ void FGAuxiliary::bind(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGAuxiliary::CalculateRelativePosition(void)
-{ 
-  const double earth_radius_mt = FDMExec->GetInertial()->GetRefRadius()*fttom;
-  lat_relative_position=(FDMExec->GetPropagate()->GetLatitude()  - FDMExec->GetIC()->GetLatitudeDegIC() *degtorad)*earth_radius_mt;
-  lon_relative_position=(FDMExec->GetPropagate()->GetLongitude() - FDMExec->GetIC()->GetLongitudeDegIC()*degtorad)*earth_radius_mt;
-  relative_position = sqrt(lat_relative_position*lat_relative_position + lon_relative_position*lon_relative_position);
-};
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 double FGAuxiliary::BadUnits(void) const
 {
   cerr << "Bad units" << endl; return 0.0;
diff --git a/src/FDM/JSBSim/models/FGAuxiliary.h b/src/FDM/JSBSim/models/FGAuxiliary.h
index 3061a8cd6..45a7382f5 100644
--- a/src/FDM/JSBSim/models/FGAuxiliary.h
+++ b/src/FDM/JSBSim/models/FGAuxiliary.h
@@ -41,13 +41,14 @@ INCLUDES
 
 #include "FGModel.h"
 #include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
 #include "math/FGLocation.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.23 2011/08/17 23:56:01 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -96,10 +97,9 @@ CLASS DOCUMENTATION
     by the F = ma relation. If the vForces vector is divided by the aircraft
     mass, the acceleration vector is calculated. The term wdot is equivalent
     to the JSBSim vPQRdot vector, and the w parameter is equivalent to vPQR.
-    The radius R is calculated below in the vector vToEyePt.
 
     @author Tony Peden, Jon Berndt
-    @version $Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $
+    @version $Id: FGAuxiliary.h,v 1.23 2011/08/17 23:56:01 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -137,6 +137,10 @@ public:
   double GetVequivalentFPS(void) const { return veas; }
   /** Returns equivalent airspeed in knots. */
   double GetVequivalentKTS(void) const { return veas*fpstokts; }
+  /** Returns the true airspeed in feet per second. */
+  double GetVtrueFPS() const { return vtrue; }
+  /** Returns the true airspeed in knots. */
+  double GetVtrueKTS() const { return vtrue * fpstokts; }
 
   /** Returns the total pressure.
       Total pressure is freestream total pressure for
@@ -147,9 +151,9 @@ public:
   /** Returns the total temperature.
     The total temperature ("tat", isentropic flow) is calculated:
     @code
-    tat = sat*(1 + 0.2*Mach*Mach)
+    tat = in.Temperature*(1 + 0.2*Mach*Mach)
     @endcode
-    (where "sat" is standard temperature) */
+    (where "in.Temperature" is standard temperature calculated by the atmosphere model) */
 
   double GetTotalTemperature(void) const { return tat; }
   double GetTAT_C(void) const { return tatc; }
@@ -161,6 +165,9 @@ public:
 
   const FGColumnVector3& GetPilotAccel (void) const { return vPilotAccel;  }
   const FGColumnVector3& GetNpilot     (void) const { return vPilotAccelN; }
+  const FGColumnVector3& GetNcg        (void) const { return vNcg;         }
+  double GetNcg                     (int idx) const { return vNcg(idx);    }
+  double GetNlf                        (void) const;
   const FGColumnVector3& GetAeroPQR    (void) const { return vAeroPQR;     }
   const FGColumnVector3& GetEulerRates (void) const { return vEulerRates;  }
   const FGColumnVector3& GetAeroUVW    (void) const { return vAeroUVW;     }
@@ -185,6 +192,16 @@ public:
   double GetMagBeta (int unit) const { if (unit == inDegrees) return fabs(beta)*radtodeg;
                                        else return BadUnits(); }
 
+  /** Calculates and returns the wind-to-body axis transformation matrix.
+      @return a reference to the wind-to-body transformation matrix.
+      */
+  FGMatrix33& GetTw2b(void);
+
+  /** Calculates and returns the body-to-wind axis transformation matrix.
+      @return a reference to the wind-to-body transformation matrix.
+      */
+  FGMatrix33& GetTb2w(void);
+
   double Getqbar          (void) const { return qbar;       }
   double GetqbarUW        (void) const { return qbarUW;     }
   double GetqbarUV        (void) const { return qbarUV;     }
@@ -208,6 +225,8 @@ public:
   /** The vertical acceleration in g's of the aircraft center of gravity. */
   double GetNz            (void) const { return Nz;         }
 
+  FGColumnVector3& GetNwcg(void) { return vNwcg; }
+
   double GetHOverBCG(void) const { return hoverbcg; }
   double GetHOverBMAC(void) const { return hoverbmac; }
 
@@ -217,23 +236,6 @@ public:
   double GetHeadWind(void) const;
   double GetCrossWind(void) const;
 
-// SET functions
-
-  void SetAeroUVW(FGColumnVector3 tt) { vAeroUVW = tt; }
-
-  void Setalpha  (double tt) { alpha = tt;  }
-  void Setbeta   (double tt) { beta  = tt;  }
-  void Setqbar   (double tt) { qbar = tt;   }
-  void SetqbarUW (double tt) { qbarUW = tt; }
-  void SetqbarUV (double tt) { qbarUV = tt; }
-  void SetVt     (double tt) { Vt = tt;     }
-  void SetMach   (double tt) { Mach=tt;     }
-  void Setadot   (double tt) { adot = tt;   }
-  void Setbdot   (double tt) { bdot = tt;   }
-
-  void SetAB    (double t1, double t2) { alpha=t1; beta=t2; }
-  void SetGamma (double tt)            { gamma = tt;        }
-
 // Time routines, SET and GET functions, used by FGMSIS atmosphere
 
   void SetDayOfYear    (int doy)    { day_of_year = doy;    }
@@ -248,19 +250,65 @@ public:
 
   void SetAeroPQR(FGColumnVector3 tt) { vAeroPQR = tt; }
 
+  struct Inputs {
+    double Pressure;
+    double Density;
+    double DensitySL;
+    double PressureSL;
+    double Temperature;
+    double SoundSpeed;
+    double KinematicViscosity;
+    double DistanceAGL;
+    double Wingspan;
+    double Wingchord;
+    double SLGravity;
+    double Mass;
+    FGMatrix33 Tl2b;
+    FGMatrix33 Tb2l;
+    FGMatrix33 Tb2w;
+    FGColumnVector3 vPQR;
+    FGColumnVector3 vPQRdot;
+    FGColumnVector3 vUVW;
+    FGColumnVector3 vUVWdot;
+    FGColumnVector3 vVel;
+    FGColumnVector3 vBodyAccel;
+    FGColumnVector3 ToEyePt;
+    FGColumnVector3 RPBody;
+    FGColumnVector3 VRPBody;
+    FGColumnVector3 vFw;
+    FGLocation vLocation;
+    double Latitude;
+    double Longitude;
+    double InitialLatitude;
+    double InitialLongitude;
+    double ReferenceRadius;
+    double CosTht;
+    double SinTht;
+    double CosPhi;
+    double SinPhi;
+    double Psi;
+    FGColumnVector3 TotalWindNED;
+    FGColumnVector3 TurbPQR;
+    double WindPsi;
+    double Vwind;
+  } in;
+
 private:
-  double vcas, veas;
-  double rhosl, rho, p, psl, pt, tat, sat, tatc; // Don't add a getter for pt!
+  double vcas, veas, vtrue;
+  double pt, tat, tatc; // Don't add a getter for pt!
+
+  FGMatrix33 mTw2b;
+  FGMatrix33 mTb2w;
 
   FGColumnVector3 vPilotAccel;
   FGColumnVector3 vPilotAccelN;
-  FGColumnVector3 vToEyePt;
+  FGColumnVector3 vNcg;
+  FGColumnVector3 vNwcg;
   FGColumnVector3 vAeroPQR;
   FGColumnVector3 vAeroUVW;
   FGColumnVector3 vEuler;
   FGColumnVector3 vEulerRates;
   FGColumnVector3 vMachUVW;
-  FGColumnVector3 vAircraftAccel;
   FGLocation vLocationVRP;
 
   double Vt, Vground, Mach, MachU;
diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp
index a1824e7a0..d98d543dd 100644
--- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp
+++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.19 2011/07/01 21:22:25 andgi Exp $";
+static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.20 2011/08/06 13:47:59 jberndt Exp $";
 static const char *IdHdr = ID_BUOYANTFORCES;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -131,7 +131,7 @@ bool FGBuoyantForces::Load(Element *element)
   gas_cell_element = document->FindElement("gas_cell");
   while (gas_cell_element) {
     NoneDefined = false;
-    Cells.push_back(new FGGasCell(FDMExec, gas_cell_element, Cells.size()));
+    Cells.push_back(new FGGasCell(FDMExec, gas_cell_element, Cells.size(), in));
     gas_cell_element = document->FindNextElement("gas_cell");
   }
   
diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.h b/src/FDM/JSBSim/models/FGBuoyantForces.h
index ac712e242..a844b9c3b 100644
--- a/src/FDM/JSBSim/models/FGBuoyantForces.h
+++ b/src/FDM/JSBSim/models/FGBuoyantForces.h
@@ -32,8 +32,8 @@ HISTORY
 SENTRY
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#ifndef FGBuoyanTFORCES_H
-#define FGBuoyanTFORCES_H
+#ifndef FGBUOYANTFORCES_H
+#define FGBUOYANTFORCES_H
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
@@ -51,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.13 2011/07/01 21:22:25 andgi Exp $"
+#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.15 2011/08/14 20:15:56 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -96,7 +96,7 @@ CLASS DOCUMENTATION
     See FGGasCell for the full configuration file format for gas cells.
 
     @author Anders Gidenstam, Jon S. Berndt
-    @version $Id: FGBuoyantForces.h,v 1.13 2011/07/01 21:22:25 andgi Exp $
+    @version $Id: FGBuoyantForces.h,v 1.15 2011/08/14 20:15:56 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -172,6 +172,8 @@ public:
       parameters */
   string GetBuoyancyValues(string delimeter);
 
+  FGGasCell::Inputs in;
+
 private:
   vector <FGGasCell*> Cells;
   // Buoyant forces and moments. Excluding the gas weight.
diff --git a/src/FDM/JSBSim/models/FGExternalReactions.cpp b/src/FDM/JSBSim/models/FGExternalReactions.cpp
index 54a219bc4..f9e98f9f5 100755
--- a/src/FDM/JSBSim/models/FGExternalReactions.cpp
+++ b/src/FDM/JSBSim/models/FGExternalReactions.cpp
@@ -53,7 +53,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.10 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.12 2011/07/20 12:16:34 jberndt Exp $";
 static const char *IdHdr = ID_EXTERNALREACTIONS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -63,6 +63,7 @@ CLASS IMPLEMENTATION
 FGExternalReactions::FGExternalReactions(FGFDMExec* fdmex) : FGModel(fdmex)
 {
   NoneDefined = true;
+
   Debug(0);
 }
 
@@ -70,6 +71,14 @@ FGExternalReactions::FGExternalReactions(FGFDMExec* fdmex) : FGModel(fdmex)
 
 bool FGExternalReactions::Load(Element* el)
 {
+  // check if a file attribute was specified
+  string fname = el->GetAttributeValue("file");
+  if (!fname.empty()) {
+    string file = FDMExec->GetFullAircraftPath() + "/" + fname;
+    el = LoadXMLDocument(file);
+    if (el == 0L) return false;
+  }
+
   FGModel::Load(el); // Call the base class Load() function to load interface properties.
 
   Debug(2);
@@ -87,6 +96,8 @@ bool FGExternalReactions::Load(Element* el)
 
   PostLoad(el, PropertyManager);
 
+  if (!NoneDefined) bind();
+
   return true;
 }
 
@@ -130,6 +141,20 @@ bool FGExternalReactions::Run(bool Holding)
   return false;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGExternalReactions::bind(void)
+{
+  typedef double (FGExternalReactions::*PMF)(int) const;
+  PropertyManager->Tie("moments/l-external-lbsft", this, eL, (PMF)&FGExternalReactions::GetMoments);
+  PropertyManager->Tie("moments/m-external-lbsft", this, eM, (PMF)&FGExternalReactions::GetMoments);
+  PropertyManager->Tie("moments/n-external-lbsft", this, eN, (PMF)&FGExternalReactions::GetMoments);
+  PropertyManager->Tie("forces/fbx-external-lbs", this, eX, (PMF)&FGExternalReactions::GetForces);
+  PropertyManager->Tie("forces/fby-external-lbs", this, eY, (PMF)&FGExternalReactions::GetForces);
+  PropertyManager->Tie("forces/fbz-external-lbs", this, eZ, (PMF)&FGExternalReactions::GetForces);
+}
+
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 //    The bitmasked value choices are as follows:
 //    unset: In this case (the default) JSBSim would only print
diff --git a/src/FDM/JSBSim/models/FGExternalReactions.h b/src/FDM/JSBSim/models/FGExternalReactions.h
index 36666697f..9f9164ed4 100755
--- a/src/FDM/JSBSim/models/FGExternalReactions.h
+++ b/src/FDM/JSBSim/models/FGExternalReactions.h
@@ -41,12 +41,14 @@ INCLUDES
 #include <vector>
 #include "FGModel.h"
 #include "FGExternalForce.h"
+#include "input_output/FGXMLFileRead.h"
+
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.11 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.13 2011/07/20 12:16:34 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -115,7 +117,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGExternalReactions : public FGModel
+class FGExternalReactions : public FGModel, public FGXMLFileRead
 {
 public:
   /** Constructor.
@@ -152,11 +154,13 @@ public:
       @return the total force in pounds.
   */
   FGColumnVector3 GetForces(void) const {return vTotalForces;}
+  double GetForces(int idx) const {return vTotalForces(idx);}
 
   /** Retrieves the total moment resulting from the forces defined in the external reactions.
       @return the total moment in foot-pounds.
   */
   FGColumnVector3 GetMoments(void) const {return vTotalMoments;}
+  double GetMoments(int idx) const {return vTotalMoments(idx);}
 
 private:
 
@@ -167,6 +171,7 @@ private:
 
   bool NoneDefined;
 
+  void bind(void);
   void Debug(int from);
 };
 }
diff --git a/src/FDM/JSBSim/models/FGFCS.cpp b/src/FDM/JSBSim/models/FGFCS.cpp
index 67c02d698..d781f54f1 100644
--- a/src/FDM/JSBSim/models/FGFCS.cpp
+++ b/src/FDM/JSBSim/models/FGFCS.cpp
@@ -37,13 +37,14 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <fstream>
+#include <sstream>
+#include <iomanip>
+
 #include "FGFCS.h"
 #include "FGFDMExec.h"
 #include "FGGroundReactions.h"
 #include "input_output/FGPropertyManager.h"
-#include <fstream>
-#include <sstream>
-#include <iomanip>
 
 #include "models/flight_control/FGFilter.h"
 #include "models/flight_control/FGDeadBand.h"
@@ -63,7 +64,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFCS.cpp,v 1.74 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFCS.cpp,v 1.76 2011/08/14 20:15:56 jberndt Exp $";
 static const char *IdHdr = ID_FCS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -78,7 +79,7 @@ FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
   DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
   GearCmd = GearPos = 1; // default to gear down
-  LeftBrake = RightBrake = CenterBrake = 0.0;
+  BrakePos.resize(FGLGear::bgNumBrakeGroups);
   TailhookPos = WingFoldPos = 0.0; 
 
   bind();
@@ -673,17 +674,7 @@ bool FGFCS::Load(Element* el, SystemType systype)
 
 double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
 {
-  switch (bg) {
-  case FGLGear::bgLeft:
-    return LeftBrake;
-  case FGLGear::bgRight:
-    return RightBrake;
-  case FGLGear::bgCenter:
-    return CenterBrake;
-  default:
-    cerr << "GetBrake asked to return a bogus brake value" << endl;
-  }
-  return 0.0;
+  return BrakePos[bg];
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -838,9 +829,10 @@ void FGFCS::AddThrottle(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGFCS::AddGear(void)
+void FGFCS::AddGear(unsigned int NumGear)
 {
-  SteerPosDeg.push_back(0.0);
+  SteerPosDeg.clear();
+  for (unsigned int i=0; i<NumGear; i++) SteerPosDeg.push_back(0.0);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/FGFCS.h b/src/FDM/JSBSim/models/FGFCS.h
index 9e6736eed..c48cc4cc1 100644
--- a/src/FDM/JSBSim/models/FGFCS.h
+++ b/src/FDM/JSBSim/models/FGFCS.h
@@ -51,7 +51,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_FCS "$Id: FGFCS.h,v 1.36 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_FCS "$Id: FGFCS.h,v 1.39 2011/08/14 20:15:56 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -168,7 +168,7 @@ CLASS DOCUMENTATION
     @property gear/tailhook-pos-norm
 
     @author Jon S. Berndt
-    @version $Revision: 1.36 $
+    @version $Revision: 1.39 $
     @see FGActuator
     @see FGDeadBand
     @see FGFCSFunction
@@ -243,11 +243,15 @@ public:
       @return throttle command in range from 0 - 1.0 for the given engine */
   double GetThrottleCmd(int engine) const;
 
+  vector <double> GetThrottleCmd() const {return ThrottleCmd;}
+
   /** Gets the mixture command.
       @param engine engine ID number
       @return mixture command in range from 0 - 1.0 for the given engine */
   double GetMixtureCmd(int engine) const { return MixtureCmd[engine]; }
 
+  vector <double> GetMixtureCmd() const {return MixtureCmd;}
+
   /** Gets the prop pitch command.
       @param engine engine ID number
       @return pitch command in range from 0.0 - 1.0 for the given engine */
@@ -318,15 +322,21 @@ public:
       @return throttle position for the given engine in range from 0 - 1.0 */
   double GetThrottlePos(int engine) const;
 
+  vector <double> GetThrottlePos() const {return ThrottlePos;}
+
   /** Gets the mixture position.
       @param engine engine ID number
       @return mixture position for the given engine in range from 0 - 1.0 */
   double GetMixturePos(int engine) const { return MixturePos[engine]; }
 
+  vector <double> GetMixturePos() const {return MixturePos;}
+
   /** Gets the steering position.
       @return steering position in degrees */
   double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
 
+  vector <double> GetSteerPosDeg() const {return SteerPosDeg;}
+
   /** Gets the gear position (0 up, 1 down), defaults to down
       @return gear position (0 up, 1 down) */
   double GetGearPos(void) const { return GearPos; }
@@ -344,10 +354,14 @@ public:
       @return prop pitch position for the given engine in range from 0 - 1.0 */
   double GetPropAdvance(int engine) const { return PropAdvance[engine]; }
 
+  vector <double> GetPropAdvance() const { return PropAdvance; }
+
   /** Gets the prop feather position.
       @param engine engine ID number
       @return prop fether for the given engine (on / off)*/
   bool GetPropFeather(int engine) const { return PropFeather[engine]; }
+
+  vector <bool> GetPropFeather() const { return PropFeather; }
   //@}
 
   /** Retrieves all component names for inclusion in output stream
@@ -499,32 +513,34 @@ public:
   //@{
   /** Sets the left brake group
       @param cmd brake setting in percent (0.0 - 1.0) */
-  void SetLBrake(double cmd) {LeftBrake = cmd;}
+  void SetLBrake(double cmd) {BrakePos[FGLGear::bgLeft] = cmd;}
 
   /** Sets the right brake group
       @param cmd brake setting in percent (0.0 - 1.0) */
-  void SetRBrake(double cmd) {RightBrake = cmd;}
+  void SetRBrake(double cmd) {BrakePos[FGLGear::bgRight] = cmd;}
 
   /** Sets the center brake group
       @param cmd brake setting in percent (0.0 - 1.0) */
-  void SetCBrake(double cmd) {CenterBrake = cmd;}
+  void SetCBrake(double cmd) {BrakePos[FGLGear::bgCenter] = cmd;}
 
   /** Gets the brake for a specified group.
       @param bg which brakegroup to retrieve the command for
       @return the brake setting for the supplied brake group argument */
   double GetBrake(FGLGear::BrakeGroup bg);
 
+  vector <double> GetBrakePos() const {return BrakePos;}
+
   /** Gets the left brake.
       @return the left brake setting. */
-  double GetLBrake(void) const {return LeftBrake;}
+  double GetLBrake(void) const {return BrakePos[FGLGear::bgLeft];}
 
   /** Gets the right brake.
       @return the right brake setting. */
-  double GetRBrake(void) const {return RightBrake;}
+  double GetRBrake(void) const {return BrakePos[FGLGear::bgRight];}
 
   /** Gets the center brake.
       @return the center brake setting. */
-  double GetCBrake(void) const {return CenterBrake;}
+  double GetCBrake(void) const {return BrakePos[FGLGear::bgCenter];}
   //@}
 
   enum SystemType { stFCS, stSystem, stAutoPilot }; 
@@ -540,13 +556,17 @@ public:
   std::string FindSystemFullPathname(const std::string& system_filename);
 
   void AddThrottle(void);
-  void AddGear(void);
+  void AddGear(unsigned int NumGear);
   double GetDt(void);
 
   FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
 
   bool GetTrimStatus(void) const { return FDMExec->GetTrimStatus(); }
 
+  struct Inputs {
+    unsigned int NumGear;
+  } in;
+
 private:
   double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
   double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
@@ -562,6 +582,7 @@ private:
   std::vector <bool> PropFeather;
   std::vector <double> SteerPosDeg;
   double LeftBrake, RightBrake, CenterBrake; // Brake settings
+  vector <double> BrakePos; // left, center, right - defined by FGLGear:: enum
   double GearCmd,GearPos;
   double TailhookPos, WingFoldPos;
 
diff --git a/src/FDM/JSBSim/models/FGGasCell.cpp b/src/FDM/JSBSim/models/FGGasCell.cpp
index 742288cd6..de92cc1fa 100644
--- a/src/FDM/JSBSim/models/FGGasCell.cpp
+++ b/src/FDM/JSBSim/models/FGGasCell.cpp
@@ -36,9 +36,6 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFDMExec.h"
-#include "models/FGAuxiliary.h"
-#include "models/FGAtmosphere.h"
-#include "models/FGInertial.h"
 #include "models/FGMassBalance.h"
 #include "FGGasCell.h"
 #include "input_output/FGXMLElement.h"
@@ -53,7 +50,7 @@ using std::max;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.14 2011/07/01 21:22:25 andgi Exp $";
+static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.15 2011/08/06 13:47:59 jberndt Exp $";
 static const char *IdHdr = ID_GASCELL;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,15 +62,13 @@ const double FGGasCell::M_air = 0.0019186;       // [slug/mol]
 const double FGGasCell::M_hydrogen = 0.00013841; // [slug/mol]
 const double FGGasCell::M_helium = 0.00027409;   // [slug/mol]
 
-FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num) : FGForce(exec)
+FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num, const struct Inputs& input)
+  : FGForce(exec), in(input)
 {
   string token;
   Element* element;
 
-  Auxiliary = exec->GetAuxiliary();
-  Atmosphere = exec->GetAtmosphere();
   PropertyManager = exec->GetPropertyManager();
-  Inertial = exec->GetInertial();
   MassBalance = exec->GetMassBalance();
 
   gasCellJ = FGMatrix33();
@@ -175,10 +170,10 @@ FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num) : FGForce(exec)
   SetLocation(vXYZ);
 
   if (Temperature == 0.0) {
-    Temperature = Atmosphere->GetTemperature();
+    Temperature = in.Temperature;
   }
   if (Pressure == 0.0) {
-    Pressure = Atmosphere->GetPressure();
+    Pressure = in.Pressure;
   }
   if (Volume != 0.0) {
     // Calculate initial gas content.
@@ -239,7 +234,7 @@ FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num) : FGForce(exec)
       Ballonet.push_back(new FGBallonet(exec,
                                         ballonet_element,
                                         Ballonet.size(),
-                                        this));
+                                        this, in));
       ballonet_element = el->FindNextElement("ballonet");
     }
   }
@@ -265,10 +260,10 @@ FGGasCell::~FGGasCell()
 
 void FGGasCell::Calculate(double dt)
 {
-  const double AirTemperature = Atmosphere->GetTemperature();  // [Rankine]
-  const double AirPressure    = Atmosphere->GetPressure();     // [lbs/ft�]
-  const double AirDensity     = Atmosphere->GetDensity();      // [slug/ft�]
-  const double g = Inertial->gravity();                        // [lbs/slug]
+  const double AirTemperature = in.Temperature;  // [Rankine]
+  const double AirPressure    = in.Pressure;     // [lbs/ft�]
+  const double AirDensity     = in.Density;      // [slug/ft�]
+  const double g = in.gravity;                   // [lbs/slug]
 
   const double OldTemperature = Temperature;
   const double OldPressure    = Pressure;
@@ -509,15 +504,13 @@ const double FGBallonet::R = 3.4071;              // [lbs ft/(mol Rankine)]
 const double FGBallonet::M_air = 0.0019186;       // [slug/mol]
 const double FGBallonet::Cv_air = 5.0/2.0;        // [??]
 
-FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent)
+FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent, const struct FGGasCell::Inputs& input)
+  : in(input)
 {
   string token;
   Element* element;
 
-  Auxiliary = exec->GetAuxiliary();
-  Atmosphere = exec->GetAtmosphere();
   PropertyManager = exec->GetPropertyManager();
-  Inertial = exec->GetInertial();
   MassBalance = exec->GetMassBalance();
 
   ballonetJ = FGMatrix33();
@@ -696,8 +689,8 @@ FGBallonet::~FGBallonet()
 
 void FGBallonet::Calculate(double dt)
 {
-  const double ParentPressure = Parent->GetPressure();         // [lbs/ft�]
-  const double AirPressure    = Atmosphere->GetPressure();     // [lbs/ft�]
+  const double ParentPressure = Parent->GetPressure(); // [lbs/ft�]
+  const double AirPressure    = Pressure;              // [lbs/ft�]
 
   const double OldTemperature = Temperature;
   const double OldPressure    = Pressure;
diff --git a/src/FDM/JSBSim/models/FGGasCell.h b/src/FDM/JSBSim/models/FGGasCell.h
index abe73ac5b..ff3613c17 100644
--- a/src/FDM/JSBSim/models/FGGasCell.h
+++ b/src/FDM/JSBSim/models/FGGasCell.h
@@ -32,8 +32,8 @@ This class simulates a generic gas cell for static buoyancy.
 SENTRY
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#ifndef FGGasCell_H
-#define FGGasCell_H
+#ifndef FGGASCELL_H
+#define FGGASCELL_H
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
@@ -50,7 +50,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_GASCELL "$Id: FGGasCell.h,v 1.11 2011/07/01 21:22:25 andgi Exp $"
+#define ID_GASCELL "$Id: FGGasCell.h,v 1.12 2011/08/06 13:47:59 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -172,11 +172,18 @@ CLASS DECLARATION
 class FGGasCell : public FGForce
 {
 public:
+  struct Inputs {
+    double Pressure;
+    double Temperature;
+    double Density;
+    double gravity;
+  };
+
   /** Constructor
       @param exec Executive a pointer to the parent executive object
       @param el   Pointer to configuration file XML node
       @param num  Gas cell index number. */
-  FGGasCell(FGFDMExec* exec, Element* el, int num);
+  FGGasCell(FGFDMExec* exec, Element* el, int num, const struct Inputs& input);
   ~FGGasCell();
 
   /** Runs the gas cell model; called by BuoyantForces
@@ -221,6 +228,8 @@ public:
       @return gas pressure in lbs / ft<sup>2</sup>. */
   double GetPressure(void) const {return Pressure;}
 
+  const struct Inputs& in;
+
 private:
 
   enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
@@ -252,10 +261,7 @@ private:
   FGMatrix33 gasCellJ;      // [slug foot^2]
   FGColumnVector3 gasCellM; // [lbs in]
 
-  FGAuxiliary* Auxiliary;
-  FGAtmosphere* Atmosphere;
   FGPropertyManager* PropertyManager;
-  FGInertial* Inertial;
   FGMassBalance* MassBalance;
   void Debug(int from);
 
@@ -302,7 +308,7 @@ private:
 class FGBallonet : public FGJSBBase
 {
 public:
-  FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent);
+  FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent, const struct FGGasCell::Inputs& input);
   ~FGBallonet();
 
   /** Runs the ballonet model; called by FGGasCell
@@ -333,6 +339,8 @@ public:
       @return heat flow in lbs ft / sec. */
   double GetHeatFlow(void) const {return dU;}       // [lbs ft / sec]
 
+  const struct FGGasCell::Inputs& in;
+
 private:
   int CellNum;
   // Structural constants
@@ -356,10 +364,7 @@ private:
   double ValveOpen;        // 0 <= ValveOpen <= 1 (or higher).
   FGMatrix33 ballonetJ;     // [slug foot^2]
 
-  FGAuxiliary* Auxiliary;
-  FGAtmosphere* Atmosphere;
   FGPropertyManager* PropertyManager;
-  FGInertial* Inertial;
   FGMassBalance* MassBalance;
   void Debug(int from);
 
diff --git a/src/FDM/JSBSim/models/FGGroundReactions.cpp b/src/FDM/JSBSim/models/FGGroundReactions.cpp
index 7f92cec41..e38878102 100644
--- a/src/FDM/JSBSim/models/FGGroundReactions.cpp
+++ b/src/FDM/JSBSim/models/FGGroundReactions.cpp
@@ -39,56 +39,16 @@ INCLUDES
 #include <iomanip>
 
 #include "FGGroundReactions.h"
-#include "FGFCS.h"
+#include "FGLGear.h"
 #include "input_output/FGPropertyManager.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.32 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.36 2011/08/21 15:13:22 bcoconni Exp $";
 static const char *IdHdr = ID_GROUNDREACTIONS;
 
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS IMPLEMENTATION for MultiplierIterator (See below for FGGroundReactions)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-MultiplierIterator::MultiplierIterator(FGGroundReactions* GndReactions)
-: GroundReactions(GndReactions),
-  multiplier(NULL),
-  gearNum(0),
-  entry(0)
-{
-  for (int i=0; i < GroundReactions->GetNumGearUnits(); i++) {
-		FGLGear* gear = GroundReactions->GetGearUnit(i);
-
-		if (!gear->GetWOW()) continue;
-
-    gearNum = i;
-    multiplier = gear->GetMultiplierEntry(0);
-    break;
-  }
-}
-
-MultiplierIterator& MultiplierIterator::operator++()
-{
-  for (int i=gearNum; i < GroundReactions->GetNumGearUnits(); i++) {
-		FGLGear* gear = GroundReactions->GetGearUnit(i);
-
-    if (!gear->GetWOW()) continue;
-
-    multiplier = gear->GetMultiplierEntry(++entry);
-    if (multiplier) {
-      gearNum = i;
-      break;
-    }
-    else
-      entry = -1;
-  }
-
-  return *this;
-}
-
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -131,6 +91,8 @@ bool FGGroundReactions::Run(bool Holding)
   vForces.InitMatrix();
   vMoments.InitMatrix();
 
+  multipliers.clear();
+
   // Sum forces and moments for all gear, here.
   // Some optimizations may be made here - or rather in the gear code itself.
   // The gear ::Run() method is called several times - once for each gear.
@@ -160,20 +122,6 @@ bool FGGroundReactions::GetWOW(void) const
   return result;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This function must be called after friction forces are resolved in order to
-// include them in the ground reactions total force and moment.
-void FGGroundReactions::UpdateForcesAndMoments(void)
-{
-  vForces.InitMatrix();
-  vMoments.InitMatrix();
-
-  for (unsigned int i=0; i<lGear.size(); i++) {
-    vForces  += lGear[i]->UpdateForces();
-    vMoments += lGear[i]->GetMoments();
-  }
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 bool FGGroundReactions::Load(Element* el)
@@ -182,15 +130,18 @@ bool FGGroundReactions::Load(Element* el)
 
   Debug(2);
 
+  unsigned int numContacts = el->GetNumElements("contact");
+  lGear.resize(numContacts);
   Element* contact_element = el->FindElement("contact");
-  while (contact_element) {
-    lGear.push_back(new FGLGear(contact_element, FDMExec, num++));
-    FDMExec->GetFCS()->AddGear(); // make the FCS aware of the landing gear
+  for (unsigned int idx=0; idx<numContacts; idx++) {
+    lGear[idx] = new FGLGear(contact_element, FDMExec, num++, in);
     contact_element = el->FindNextElement("contact");
   }
-  
+
   FGModel::Load(el); // Perform base class Load
 
+  in.vWhlBodyVec.resize(lGear.size());
+
   for (unsigned int i=0; i<lGear.size();i++) lGear[i]->bind();
 
   PostLoad(el, PropertyManager);
@@ -275,12 +226,6 @@ void FGGroundReactions::bind(void)
   typedef double (FGGroundReactions::*PMF)(int) const;
   PropertyManager->Tie("gear/num-units", this, &FGGroundReactions::GetNumGearUnits);
   PropertyManager->Tie("gear/wow", this, &FGGroundReactions::GetWOW);
-  PropertyManager->Tie("moments/l-gear-lbsft", this, eL, (PMF)&FGGroundReactions::GetMoments);
-  PropertyManager->Tie("moments/m-gear-lbsft", this, eM, (PMF)&FGGroundReactions::GetMoments);
-  PropertyManager->Tie("moments/n-gear-lbsft", this, eN, (PMF)&FGGroundReactions::GetMoments);
-  PropertyManager->Tie("forces/fbx-gear-lbs", this, eX, (PMF)&FGGroundReactions::GetForces);
-  PropertyManager->Tie("forces/fby-gear-lbs", this, eY, (PMF)&FGGroundReactions::GetForces);
-  PropertyManager->Tie("forces/fbz-gear-lbs", this, eZ, (PMF)&FGGroundReactions::GetForces);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/FGGroundReactions.h b/src/FDM/JSBSim/models/FGGroundReactions.h
index 64bfafa1b..5774918ad 100644
--- a/src/FDM/JSBSim/models/FGGroundReactions.h
+++ b/src/FDM/JSBSim/models/FGGroundReactions.h
@@ -45,7 +45,7 @@ INCLUDES
 #include "math/FGColumnVector3.h"
 #include "input_output/FGXMLElement.h"
 
-#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.24 2011/08/21 15:13:22 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -78,19 +78,6 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class MultiplierIterator
-{
-public:
-  MultiplierIterator(FGGroundReactions* GndReactions);
-  MultiplierIterator& operator++();
-  FGPropagate::LagrangeMultiplier* operator*() { return multiplier; }
-private:
-  FGGroundReactions* GroundReactions;
-  FGPropagate::LagrangeMultiplier* multiplier;
-  int gearNum;
-  int entry;
-};
-
 class FGGroundReactions : public FGModel
 {
 public:
@@ -114,7 +101,6 @@ public:
   string GetGroundReactionStrings(string delimeter) const;
   string GetGroundReactionValues(string delimeter) const;
   bool GetWOW(void) const;
-  void UpdateForcesAndMoments(void);
 
   int GetNumGearUnits(void) const { return (int)lGear.size(); }
 
@@ -123,10 +109,16 @@ public:
       @return a pointer to the FGLGear instance of the gear unit requested */
   FGLGear* GetGearUnit(int gear) const { return lGear[gear]; }
 
+  void RegisterLagrangeMultiplier(LagrangeMultiplier* lmult) { multipliers.push_back(lmult); }
+  vector <LagrangeMultiplier*>* GetMultipliersList(void) { return &multipliers; }
+
+  FGLGear::Inputs in;
+
 private:
   vector <FGLGear*> lGear;
   FGColumnVector3 vForces;
   FGColumnVector3 vMoments;
+  vector <LagrangeMultiplier*> multipliers;
 
   void bind(void);
   void Debug(int from);
diff --git a/src/FDM/JSBSim/models/FGInertial.cpp b/src/FDM/JSBSim/models/FGInertial.cpp
index 93874c120..b241f78ed 100644
--- a/src/FDM/JSBSim/models/FGInertial.cpp
+++ b/src/FDM/JSBSim/models/FGInertial.cpp
@@ -37,15 +37,13 @@ INCLUDES
 
 #include "FGInertial.h"
 #include "FGFDMExec.h"
-#include "FGPropagate.h"
-#include "FGMassBalance.h"
 #include <iostream>
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGInertial.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGInertial.cpp,v 1.24 2011/08/04 12:46:32 jberndt Exp $";
 static const char *IdHdr = ID_INERTIAL;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,7 +63,6 @@ FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
   J2              = 1.0826266836E-03;   // WGS84 value for J2
   a               = 20925646.3255;      // WGS84 semimajor axis length in feet 
   b               = 20855486.5951;      // WGS84 semiminor axis length in feet
-  earthPosAngle   = 0.0;
 
   // Lunar defaults
   /*
@@ -76,9 +73,9 @@ FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
   J2              = 2.033542482111609E-4; // value for J2
   a               = 5702559.05;           // semimajor axis length in feet 
   b               = 5695439.63;           // semiminor axis length in feet
-  earthPosAngle   = 0.0;
   */
 
+  vOmegaPlanet = FGColumnVector3( 0.0, 0.0, RotationRate );
   gAccelReference = GM/(RadiusReference*RadiusReference);
   gAccel          = GM/(RadiusReference*RadiusReference);
 
@@ -98,8 +95,6 @@ FGInertial::~FGInertial(void)
 
 bool FGInertial::InitModel(void)
 {
-  earthPosAngle   = 0.0;
-
   return true;
 }
 
@@ -114,9 +109,7 @@ bool FGInertial::Run(bool Holding)
   RunPreFunctions();
 
   // Gravitation accel
-  double r = FDMExec->GetPropagate()->GetRadius();
-  gAccel = GetGAccel(r);
-  earthPosAngle += FDMExec->GetDeltaT()*RotationRate;
+  gAccel = GetGAccel(in.Radius);
 
   RunPostFunctions();
 
@@ -143,8 +136,7 @@ FGColumnVector3 FGInertial::GetGravityJ2(FGColumnVector3 position) const
 
   // Gravitation accel
   double r = position.Magnitude();
-  double lat = FDMExec->GetPropagate()->GetLatitude();
-  double sinLat = sin(lat);
+  double sinLat = sin(in.Latitude);
 
   double adivr = a/r;
   double preCommon = 1.5*J2*adivr*adivr;
@@ -163,7 +155,7 @@ FGColumnVector3 FGInertial::GetGravityJ2(FGColumnVector3 position) const
 
 void FGInertial::bind(void)
 {
-  PropertyManager->Tie("position/epa-rad", this, &FGInertial::GetEarthPositionAngle);
+  PropertyManager->Tie("inertial/sea-level-radius_ft", this, &FGInertial::GetRefRadius);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/FGInertial.h b/src/FDM/JSBSim/models/FGInertial.h
index 5394d81b8..0e08abe29 100644
--- a/src/FDM/JSBSim/models/FGInertial.h
+++ b/src/FDM/JSBSim/models/FGInertial.h
@@ -47,7 +47,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_INERTIAL "$Id: FGInertial.h,v 1.16 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_INERTIAL "$Id: FGInertial.h,v 1.19 2011/08/04 12:46:32 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -86,17 +86,20 @@ public:
   double SLgravity(void) const {return gAccelReference;}
   double gravity(void) const {return gAccel;}
   double omega(void) const {return RotationRate;}
-  double GetEarthPositionAngle(void) const { return earthPosAngle; }
-  double GetEarthPositionAngleDeg(void) const { return earthPosAngle*radtodeg;}
+  FGColumnVector3 GetOmegaPlanet() const {return vOmegaPlanet;}
   double GetGAccel(double r) const;
   FGColumnVector3 GetGravityJ2(FGColumnVector3 position) const;
   double GetRefRadius(void) const {return RadiusReference;}
   double GetSemimajor(void) const {return a;}
   double GetSemiminor(void) const {return b;}
 
-  void SetEarthPositionAngle(double epa) {earthPosAngle = epa;}
+  struct Inputs {
+    double Radius;
+    double Latitude;
+  } in;
 
 private:
+  FGColumnVector3 vOmegaPlanet;
   double gAccel;
   double gAccelReference;
   double RadiusReference;
diff --git a/src/FDM/JSBSim/models/FGLGear.cpp b/src/FDM/JSBSim/models/FGLGear.cpp
index 4a4c9946f..f3fd05df7 100644
--- a/src/FDM/JSBSim/models/FGLGear.cpp
+++ b/src/FDM/JSBSim/models/FGLGear.cpp
@@ -40,16 +40,14 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGLGear.h"
-#include "FGGroundReactions.h"
-#include "FGFCS.h"
-#include "FGAuxiliary.h"
-#include "FGAtmosphere.h"
-#include "FGMassBalance.h"
-#include "math/FGTable.h"
 #include <cstdlib>
 #include <cstring>
 
+#include "FGLGear.h"
+#include "input_output/FGPropertyManager.h"
+#include "models/FGGroundReactions.h"
+#include "math/FGTable.h"
+
 using namespace std;
 
 namespace JSBSim {
@@ -62,7 +60,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-static const char *IdSrc = "$Id: FGLGear.cpp,v 1.80 2011/01/24 13:01:56 jberndt Exp $";
+static const char *IdSrc = "$Id: FGLGear.cpp,v 1.88 2011/08/30 21:05:56 bcoconni Exp $";
 static const char *IdHdr = ID_LGEAR;
 
 // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@@ -73,12 +71,13 @@ const FGMatrix33 FGLGear::Tb2s(-1./inchtoft, 0., 0., 0., 1./inchtoft, 0., 0., 0.
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
+FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs& inputs) :
   FGForce(fdmex),
   GearNumber(number),
   SteerAngle(0.0),
   Castered(false),
-  StaticFriction(false)
+  StaticFriction(false),
+  in(inputs)
 {
   Element *force_table=0;
   Element *dampCoeff=0;
@@ -102,6 +101,15 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
     eContactType = ctSTRUCTURE;
   }
 
+  // Default values for structural contact points 
+  if (eContactType == ctSTRUCTURE) {
+    kSpring = in.EmptyWeight;
+    bDamp = kSpring;
+    bDampRebound = kSpring * 10;
+    staticFCoeff = 1.0;
+    dynamicFCoeff = 1.0;
+  }
+
   if (el->FindElement("spring_coeff"))
     kSpring = el->FindElementValueAsNumberConvertTo("spring_coeff", "LBS/FT");
   if (el->FindElement("damping_coeff")) {
@@ -138,12 +146,15 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   if (el->FindElement("retractable"))
     isRetractable = ((unsigned int)el->FindElementValueAsNumber("retractable"))>0.0?true:false;
 
+  GroundReactions = fdmex->GetGroundReactions();
+  PropertyManager = fdmex->GetPropertyManager();
+
   ForceY_Table = 0;
   force_table = el->FindElement("table");
   while (force_table) {
     force_type = force_table->GetAttributeValue("type");
     if (force_type == "CORNERING_COEFF") {
-      ForceY_Table = new FGTable(fdmex->GetPropertyManager(), force_table);
+      ForceY_Table = new FGTable(PropertyManager, force_table);
     } else {
       cerr << "Undefined force table for " << name << " contact point" << endl;
     }
@@ -212,12 +223,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
          << sSteerType << " is undefined." << endl;
   }
 
-  Auxiliary       = fdmex->GetAuxiliary();
-  Propagate       = fdmex->GetPropagate();
-  FCS             = fdmex->GetFCS();
-  MassBalance     = fdmex->GetMassBalance();
-  GroundReactions = fdmex->GetGroundReactions();
-
   GearUp = false;
   GearDown = true;
   GearPos  = 1.0;
@@ -236,8 +241,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   MaximumStrutForce = MaximumStrutTravel = 0.0;
   SinkRate = GroundSpeed = 0.0;
 
-  vWhlBodyVec = MassBalance->StructuralToBody(vXYZn);
-  vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
   vWhlVelVec.InitMatrix();
 
   compressLength  = 0.0;
@@ -274,29 +277,27 @@ FGLGear::~FGLGear()
 FGColumnVector3& FGLGear::GetBodyForces(void)
 {
   double t = fdmex->GetSimTime();
-  dT = fdmex->GetDeltaT()*GroundReactions->GetRate();
 
   vFn.InitMatrix();
 
   if (isRetractable) ComputeRetractionState();
 
   if (GearDown) {
-    FGColumnVector3 angularVel;
+    FGColumnVector3 terrainVel, dummy;
 
-    vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame
-    vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
+    vLocalGear = in.Tb2l * in.vWhlBodyVec[GearNumber]; // Get local frame wheel location
 
-    gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
+    gearLoc = in.Location.LocalToLocation(vLocalGear);
     // Compute the height of the theoretical location of the wheel (if strut is
     // not compressed) with respect to the ground level
-    double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel, angularVel);
-    vGroundNormal = Propagate->GetTec2b() * normal;
+    double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, terrainVel, dummy);
+    vGroundNormal = in.Tec2b * normal;
 
     // The height returned above is the AGL and is expressed in the Z direction
     // of the ECEF coordinate frame. We now need to transform this height in
     // actual compression of the strut (BOGEY) of in the normal direction to the
     // ground (STRUCTURE)
-    double normalZ = (Propagate->GetTec2l()*normal)(eZ);
+    double normalZ = (in.Tec2l*normal)(eZ);
     double LGearProj = -(mTGear.Transposed() * vGroundNormal)(eZ);
 
     switch (eContactType) {
@@ -309,7 +310,6 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
     }
 
     if (compressLength > 0.00) {
-
       WOW = true;
 
       // The following equations use the vector to the tire contact patch
@@ -325,10 +325,10 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
         break;
       }
 
-      FGColumnVector3 vWhlContactVec = vWhlBodyVec + vWhlDisplVec;
+      FGColumnVector3 vWhlContactVec = in.vWhlBodyVec[GearNumber] + vWhlDisplVec;
       vActingXYZn = vXYZn + Tb2s * vWhlDisplVec;
-      FGColumnVector3 vBodyWhlVel = Propagate->GetPQR() * vWhlContactVec;
-      vBodyWhlVel += Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
+      FGColumnVector3 vBodyWhlVel = in.PQR * vWhlContactVec;
+      vBodyWhlVel += in.UVW - in.Tec2b * terrainVel;
 
       vWhlVelVec = mTGear.Transposed() * vBodyWhlVel;
 
@@ -338,9 +338,13 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
 
       vLocalWhlVel = Transform().Transposed() * vBodyWhlVel;
 
-      compressSpeed = -vLocalWhlVel(eX);
-      if (eContactType == ctBOGEY)
-        compressSpeed /= LGearProj;
+      if (fdmex->GetTrimStatus())
+	compressSpeed = 0.0; // Steady state is sought during trimming
+      else {
+	compressSpeed = -vLocalWhlVel(eX);
+	if (eContactType == ctBOGEY)
+	  compressSpeed /= LGearProj;
+      }
 
       ComputeVerticalStrutForce();
 
@@ -364,7 +368,7 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
       StrutForce = 0.0;
 
       // Let wheel spin down slowly
-      vWhlVelVec(eX) -= 13.0*dT;
+      vWhlVelVec(eX) -= 13.0 * in.TotalDeltaT;
       if (vWhlVelVec(eX) < 0.0) vWhlVelVec(eX) = 0.0;
 
       // Return to neutral position between 1.0 and 0.8 gear pos.
@@ -463,14 +467,14 @@ void FGLGear::ComputeSteeringAngle(void)
 {
   switch (eSteerType) {
   case stSteer:
-    SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
+    SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
     break;
   case stFixed:
     SteerAngle = 0.0;
     break;
   case stCaster:
     if (!Castered)
-      SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
+      SteerAngle = degtorad * in.SteerPosDeg[GearNumber];
     else {
       // Check that the speed is non-null otherwise use the current angle
       if (vWhlVelVec.Magnitude(eX,eY) > 0.1)
@@ -488,7 +492,7 @@ void FGLGear::ComputeSteeringAngle(void)
 
 void FGLGear::ResetReporting(void)
 {
-  if (Propagate->GetDistanceAGL() > 200.0) {
+  if (in.DistanceAGL > 200.0) {
     FirstContact = false;
     StartedGroundRun = false;
     LandingReported = false;
@@ -508,16 +512,16 @@ void FGLGear::InitializeReporting(void)
   if (!FirstContact) {
     FirstContact  = true;
     SinkRate      =  compressSpeed;
-    GroundSpeed   =  Propagate->GetVel().Magnitude();
+    GroundSpeed   =  in.Vground;
     TakeoffReported = false;
   }
 
   // If the takeoff run is starting, initialize.
 
-  if ((Propagate->GetVel().Magnitude() > 0.1) &&
-      (FCS->GetBrake(bgLeft) == 0) &&
-      (FCS->GetBrake(bgRight) == 0) &&
-      (FCS->GetThrottlePos(0) > 0.90) && !StartedGroundRun)
+  if ((in.Vground > 0.1) &&
+      (in.BrakePos[bgLeft] == 0) &&
+      (in.BrakePos[bgRight] == 0) &&
+      (in.TakeoffThrottle && !StartedGroundRun))
   {
     TakeoffDistanceTraveled = 0;
     TakeoffDistanceTraveled50ft = 0;
@@ -531,25 +535,25 @@ void FGLGear::InitializeReporting(void)
 void FGLGear::ReportTakeoffOrLanding(void)
 {
   if (FirstContact)
-    LandingDistanceTraveled += Auxiliary->GetVground()*dT;
+    LandingDistanceTraveled += in.Vground * in.TotalDeltaT;
 
   if (StartedGroundRun) {
-    TakeoffDistanceTraveled50ft += Auxiliary->GetVground()*dT;
-    if (WOW) TakeoffDistanceTraveled += Auxiliary->GetVground()*dT;
+    TakeoffDistanceTraveled50ft += in.Vground * in.TotalDeltaT;
+    if (WOW) TakeoffDistanceTraveled += in.Vground * in.TotalDeltaT;
   }
 
   if ( ReportEnable
-       && Auxiliary->GetVground() <= 0.05
+       && in.Vground <= 0.05
        && !LandingReported
-       && GroundReactions->GetWOW())
+       && in.WOW)
   {
     if (debug_lvl > 0) Report(erLand);
   }
 
   if ( ReportEnable
        && !TakeoffReported
-       && (Propagate->GetDistanceAGL() - vLocalGear(eZ)) > 50.0
-       && !GroundReactions->GetWOW())
+       && (in.DistanceAGL - vLocalGear(eZ)) > 50.0
+       && !in.WOW)
   {
     if (debug_lvl > 0) Report(erTakeoff);
   }
@@ -584,24 +588,24 @@ void FGLGear::ComputeBrakeForceCoefficient(void)
 {
   switch (eBrakeGrp) {
   case bgLeft:
-    BrakeFCoeff =  ( rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
-                     staticFCoeff*FCS->GetBrake(bgLeft) );
+    BrakeFCoeff =  ( rollingFCoeff * (1.0 - in.BrakePos[bgLeft]) +
+                     staticFCoeff * in.BrakePos[bgLeft] );
     break;
   case bgRight:
-    BrakeFCoeff =  ( rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
-                     staticFCoeff*FCS->GetBrake(bgRight) );
+    BrakeFCoeff =  ( rollingFCoeff * (1.0 - in.BrakePos[bgRight]) +
+                     staticFCoeff * in.BrakePos[bgRight] );
     break;
   case bgCenter:
-    BrakeFCoeff =  ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
-                     staticFCoeff*FCS->GetBrake(bgCenter) );
+    BrakeFCoeff =  ( rollingFCoeff * (1.0 - in.BrakePos[bgCenter]) +
+                     staticFCoeff * in.BrakePos[bgCenter] );
     break;
   case bgNose:
-    BrakeFCoeff =  ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
-                     staticFCoeff*FCS->GetBrake(bgCenter) );
+    BrakeFCoeff =  ( rollingFCoeff * (1.0 - in.BrakePos[bgCenter]) +
+                     staticFCoeff * in.BrakePos[bgCenter] );
     break;
   case bgTail:
-    BrakeFCoeff =  ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
-                     staticFCoeff*FCS->GetBrake(bgCenter) );
+    BrakeFCoeff =  ( rollingFCoeff * (1.0 - in.BrakePos[bgCenter]) +
+                     staticFCoeff * in.BrakePos[bgCenter] );
     break;
   case bgNone:
     BrakeFCoeff =  rollingFCoeff;
@@ -683,9 +687,9 @@ void FGLGear::ComputeVerticalStrutForce(void)
 double FGLGear::GetGearUnitPos(void)
 {
   // hack to provide backward compatibility to gear/gear-pos-norm property
-  if( useFCSGearPos || FCS->GetGearPos() != 1.0 ) {
+  if( useFCSGearPos || in.FCSGearPos != 1.0 ) {
     useFCSGearPos = true;
-    return FCS->GetGearPos();
+    return in.FCSGearPos;
   }
   return GearPos;
 }
@@ -711,7 +715,14 @@ void FGLGear::ComputeJacobian(const FGColumnVector3& vWhlContactVec)
     LMultiplier[ftDynamic].MomentJacobian = vWhlContactVec * LMultiplier[ftDynamic].ForceJacobian;
     LMultiplier[ftDynamic].Max = 0.;
     LMultiplier[ftDynamic].Min = -fabs(dynamicFCoeff * vFn(eX));
+
+    // The Lagrange multiplier value obtained from the previous iteration is kept
+    // This is supposed to accelerate the convergence of the projected Gauss-Seidel
+    // algorithm. The code just below is to make sure that the initial value
+    // is consistent with the current friction coefficient and normal reaction.
     LMultiplier[ftDynamic].value = Constrain(LMultiplier[ftDynamic].Min, LMultiplier[ftDynamic].value, LMultiplier[ftDynamic].Max);
+
+    GroundReactions->RegisterLagrangeMultiplier(&LMultiplier[ftDynamic]);
   }
   else {
     // Static friction is used for ctSTRUCTURE when the contact point is not moving.
@@ -738,39 +749,24 @@ void FGLGear::ComputeJacobian(const FGColumnVector3& vWhlContactVec)
 
     LMultiplier[ftRoll].Min = -LMultiplier[ftRoll].Max;
     LMultiplier[ftSide].Min = -LMultiplier[ftSide].Max;
+
+    // The Lagrange multiplier value obtained from the previous iteration is kept
+    // This is supposed to accelerate the convergence of the projected Gauss-Seidel
+    // algorithm. The code just below is to make sure that the initial value
+    // is consistent with the current friction coefficient and normal reaction.
     LMultiplier[ftRoll].value = Constrain(LMultiplier[ftRoll].Min, LMultiplier[ftRoll].value, LMultiplier[ftRoll].Max);
     LMultiplier[ftSide].value = Constrain(LMultiplier[ftSide].Min, LMultiplier[ftSide].value, LMultiplier[ftSide].Max);
+
+    GroundReactions->RegisterLagrangeMultiplier(&LMultiplier[ftRoll]);
+    GroundReactions->RegisterLagrangeMultiplier(&LMultiplier[ftSide]);
   }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This function is used by the MultiplierIterator class to enumerate the
-// Lagrange multipliers of a landing gear. This allows to encapsulate the storage
-// of the multipliers in FGLGear without exposing it. From an outside point of
-// view, each FGLGear instance has a number of Lagrange multipliers which can be
-// accessed through this routine without knowing the exact constraint which they
-// model.
-
-FGPropagate::LagrangeMultiplier* FGLGear::GetMultiplierEntry(int entry)
-{
-  switch(entry) {
-  case 0:
-    if (StaticFriction)
-      return &LMultiplier[ftRoll];
-    else
-      return &LMultiplier[ftDynamic];
-  case 1:
-    if (StaticFriction)
-      return &LMultiplier[ftSide];
-  default:
-    return NULL;
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This routine is called after the Lagrange multiplier has been computed. The
-// friction forces of the landing gear are then updated accordingly.
-FGColumnVector3& FGLGear::UpdateForces(void)
+// This routine is called after the Lagrange multiplier has been computed in
+// the FGAccelerations class. The friction forces of the landing gear are then
+// updated accordingly.
+void FGLGear::UpdateForces(void)
 {
   if (StaticFriction) {
     vFn(eY) = LMultiplier[ftRoll].value;
@@ -778,9 +774,6 @@ FGColumnVector3& FGLGear::UpdateForces(void)
   }
   else
     vFn += LMultiplier[ftDynamic].value * (Transform ().Transposed() * LMultiplier[ftDynamic].ForceJacobian);
-
-  // Return the updated force in the body frame
-  return FGForce::GetBodyForces();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -789,41 +782,52 @@ void FGLGear::bind(void)
 {
   string property_name;
   string base_property_name;
-  base_property_name = CreateIndexedPropertyName("gear/unit", GearNumber);
+
+  switch(eContactType) {
+  case ctBOGEY:
+    base_property_name = CreateIndexedPropertyName("gear/unit", GearNumber);
+    break;
+  case ctSTRUCTURE:
+    base_property_name = CreateIndexedPropertyName("contact/unit", GearNumber);
+    break;
+  default:
+    return;
+  }
+
+  property_name = base_property_name + "/WOW";
+  PropertyManager->Tie( property_name.c_str(), &WOW );
+  property_name = base_property_name + "/z-position";
+  PropertyManager->Tie( property_name.c_str(), (FGForce*)this,
+                          &FGForce::GetLocationZ, &FGForce::SetLocationZ);
+  property_name = base_property_name + "/compression-ft";
+  PropertyManager->Tie( property_name.c_str(), &compressLength );
+  property_name = base_property_name + "/static_friction_coeff";
+  PropertyManager->Tie( property_name.c_str(), &staticFCoeff );
+  property_name = base_property_name + "/dynamic_friction_coeff";
+  PropertyManager->Tie( property_name.c_str(), &dynamicFCoeff );
+
   if (eContactType == ctBOGEY) {
     property_name = base_property_name + "/slip-angle-deg";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &WheelSlip );
-    property_name = base_property_name + "/WOW";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &WOW );
+    PropertyManager->Tie( property_name.c_str(), &WheelSlip );
     property_name = base_property_name + "/wheel-speed-fps";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
+    PropertyManager->Tie( property_name.c_str(), (FGLGear*)this,
                           &FGLGear::GetWheelRollVel);
-    property_name = base_property_name + "/z-position";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), (FGForce*)this,
-                          &FGForce::GetLocationZ, &FGForce::SetLocationZ);
-    property_name = base_property_name + "/compression-ft";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &compressLength );
     property_name = base_property_name + "/side_friction_coeff";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &FCoeff );
-
-    property_name = base_property_name + "/static_friction_coeff";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &staticFCoeff );
+    PropertyManager->Tie( property_name.c_str(), &FCoeff );
     property_name = base_property_name + "/rolling_friction_coeff";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &rollingFCoeff );
-    property_name = base_property_name + "/dynamic_friction_coeff";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &dynamicFCoeff );
+    PropertyManager->Tie( property_name.c_str(), &rollingFCoeff );
 
     if (eSteerType == stCaster) {
       property_name = base_property_name + "/steering-angle-deg";
-      fdmex->GetPropertyManager()->Tie( property_name.c_str(), this, &FGLGear::GetSteerAngleDeg );
+      PropertyManager->Tie( property_name.c_str(), this, &FGLGear::GetSteerAngleDeg );
       property_name = base_property_name + "/castered";
-      fdmex->GetPropertyManager()->Tie( property_name.c_str(), &Castered);
+      PropertyManager->Tie( property_name.c_str(), &Castered);
     }
   }
 
   if( isRetractable ) {
     property_name = base_property_name + "/pos-norm";
-    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &GearPos );
+    PropertyManager->Tie( property_name.c_str(), &GearPos );
   }
 }
 
@@ -856,11 +860,11 @@ void FGLGear::Report(ReportType repType)
          << " ft,     " << TakeoffDistanceTraveled*0.3048  << " meters"  << endl;
     cout << "  Distance traveled (over 50'):     " << TakeoffDistanceTraveled50ft
          << " ft,     " << TakeoffDistanceTraveled50ft*0.3048 << " meters" << endl;
-    cout << "  [Altitude (ASL): " << Propagate->GetAltitudeASL() << " ft. / "
-         << Propagate->GetAltitudeASLmeters() << " m  | Temperature: "
-         << fdmex->GetAtmosphere()->GetTemperature() - 459.67 << " F / "
-         << RankineToCelsius(fdmex->GetAtmosphere()->GetTemperature()) << " C]" << endl;
-    cout << "  [Velocity (KCAS): " << Auxiliary->GetVcalibratedKTS() << "]" << endl;
+    cout << "  [Altitude (ASL): " << in.DistanceASL << " ft. / "
+         << in.DistanceASL*FGJSBBase::fttom << " m  | Temperature: "
+         << in.Temperature - 459.67 << " F / "
+         << RankineToCelsius(in.Temperature) << " C]" << endl;
+    cout << "  [Velocity (KCAS): " << in.VcalibratedKts << "]" << endl;
     TakeoffReported = true;
     break;
   case erNone:
diff --git a/src/FDM/JSBSim/models/FGLGear.h b/src/FDM/JSBSim/models/FGLGear.h
index f1828f8cf..ba44029fe 100644
--- a/src/FDM/JSBSim/models/FGLGear.h
+++ b/src/FDM/JSBSim/models/FGLGear.h
@@ -38,16 +38,18 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "models/propulsion/FGForce.h"
-#include "models/FGPropagate.h"
-#include "math/FGColumnVector3.h"
 #include <string>
 
+#include "models/propulsion/FGForce.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
+#include "math/LagrangeMultiplier.h"
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_LGEAR "$Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $"
+#define ID_LGEAR "$Id: FGLGear.h,v 1.47 2011/08/30 21:05:56 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -55,13 +57,9 @@ FORWARD DECLARATIONS
 
 namespace JSBSim {
 
-class FGAircraft;
-class FGPropagate;
-class FGFCS;
-class FGMassBalance;
-class FGAuxiliary;
 class FGTable;
 class Element;
+class FGPropertyManager;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
@@ -180,7 +178,7 @@ CLASS DOCUMENTATION
         </contact>
 @endcode
     @author Jon S. Berndt
-    @version $Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $
+    @version $Id: FGLGear.h,v 1.47 2011/08/30 21:05:56 bcoconni Exp $
     @see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
      NASA-Ames", NASA CR-2497, January 1975
     @see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
@@ -196,8 +194,30 @@ CLASS DECLARATION
 class FGLGear : public FGForce
 {
 public:
+  struct Inputs {
+    double Vground;
+    double VcalibratedKts;
+    double Temperature;
+    double DistanceAGL;
+    double DistanceASL;
+    double TotalDeltaT;
+    bool TakeoffThrottle;
+    bool WOW;
+    FGMatrix33 Tb2l;
+    FGMatrix33 Tec2l;
+    FGMatrix33 Tec2b;
+    FGColumnVector3 PQR;
+    FGColumnVector3 UVW;
+    FGLocation Location;
+    std::vector <double> SteerPosDeg;
+    std::vector <double> BrakePos;
+    std::vector <FGColumnVector3> vWhlBodyVec;
+    double FCSGearPos;
+    double EmptyWeight;
+  };
+
   /// Brake grouping enumerators
-  enum BrakeGroup {bgNone=0, bgLeft, bgRight, bgCenter, bgNose, bgTail };
+  enum BrakeGroup {bgNone=0, bgLeft, bgRight, bgCenter, bgNose, bgTail, bgNumBrakeGroups };
   /// Steering group membership enumerators
   enum SteerType {stSteer, stFixed, stCaster};
   /// Contact point type
@@ -213,7 +233,7 @@ public:
       @param Executive a pointer to the parent executive object
       @param number integer identifier for this instance of FGLGear
   */
-  FGLGear(Element* el, FGFDMExec* Executive, int number);
+  FGLGear(Element* el, FGFDMExec* Executive, int number, const struct Inputs& input);
   /// Destructor
   ~FGLGear();
 
@@ -221,8 +241,8 @@ public:
   FGColumnVector3& GetBodyForces(void);
 
   /// Gets the location of the gear in Body axes
-  FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
-  double GetBodyLocation(int idx) const { return vWhlBodyVec(idx); }
+  FGColumnVector3 GetBodyLocation(void) const { return in.vWhlBodyVec[GearNumber]; }
+  double GetBodyLocation(int idx) const { return in.vWhlBodyVec[GearNumber](idx); }
 
   FGColumnVector3& GetLocalGear(void) { return vLocalGear; }
   double GetLocalGear(int idx) const { return vLocalGear(idx); }
@@ -268,9 +288,11 @@ public:
   bool GetGearUnitUp(void) const       { return GearUp;          }
   bool GetGearUnitDown(void) const     { return GearDown;        }
   double GetWheelRollForce(void) {
+    UpdateForces();
     FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
     return vForce(eX)*cos(SteerAngle) + vForce(eY)*sin(SteerAngle); }
   double GetWheelSideForce(void) {
+    UpdateForces();
     FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
     return vForce(eY)*cos(SteerAngle) - vForce(eX)*sin(SteerAngle); }
   double GetWheelRollVel(void) const   { return vWhlVelVec(eX)*cos(SteerAngle)
@@ -282,9 +304,8 @@ public:
   bool IsBogey(void) const             { return (eContactType == ctBOGEY);}
   double GetGearUnitPos(void);
   double GetSteerAngleDeg(void) const { return radtodeg*SteerAngle; }
-  FGPropagate::LagrangeMultiplier* GetMultiplierEntry(int entry);
-  void SetLagrangeMultiplier(double lambda, int entry);
-  FGColumnVector3& UpdateForces(void);
+
+  const struct Inputs& in;
 
   void bind(void);
 
@@ -293,13 +314,11 @@ private:
   static const FGMatrix33 Tb2s;
   FGMatrix33 mTGear;
   FGColumnVector3 vGearOrient;
-  FGColumnVector3 vWhlBodyVec;
   FGColumnVector3 vLocalGear;
   FGColumnVector3 vWhlVelVec, vLocalWhlVel;     // Velocity of this wheel
-  FGColumnVector3 normal, cvel, vGroundNormal;
+  FGColumnVector3 normal, vGroundNormal;
   FGLocation contact, gearLoc;
   FGTable *ForceY_Table;
-  double dT;
   double SteerAngle;
   double kSpring;
   double bDamp;
@@ -348,13 +367,10 @@ private:
   DampType    eDampTypeRebound;
   double  maxSteerAngle;
 
-  FGPropagate::LagrangeMultiplier LMultiplier[3];
+  LagrangeMultiplier LMultiplier[3];
 
-  FGAuxiliary*       Auxiliary;
-  FGPropagate*       Propagate;
-  FGFCS*             FCS;
-  FGMassBalance*     MassBalance;
   FGGroundReactions* GroundReactions;
+  FGPropertyManager* PropertyManager;
 
   void ComputeRetractionState(void);
   void ComputeBrakeForceCoefficient(void);
@@ -364,6 +380,7 @@ private:
   void ComputeVerticalStrutForce(void);
   void ComputeGroundCoordSys(void);
   void ComputeJacobian(const FGColumnVector3& vWhlContactVec);
+  void UpdateForces(void);
   void CrashDetect(void);
   void InitializeReporting(void);
   void ResetReporting(void);
diff --git a/src/FDM/JSBSim/models/FGMassBalance.cpp b/src/FDM/JSBSim/models/FGMassBalance.cpp
index aee3cc3bb..9cb32f885 100644
--- a/src/FDM/JSBSim/models/FGMassBalance.cpp
+++ b/src/FDM/JSBSim/models/FGMassBalance.cpp
@@ -38,20 +38,18 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGMassBalance.h"
-#include "FGPropulsion.h"
-#include "propulsion/FGTank.h"
-#include "FGBuoyantForces.h"
-#include "input_output/FGPropertyManager.h"
 #include <iostream>
 #include <iomanip>
 #include <cstdlib>
+#include "FGMassBalance.h"
+#include "FGFDMExec.h"
+#include "input_output/FGPropertyManager.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.35 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.37 2011/07/12 01:52:49 jberndt Exp $";
 static const char *IdHdr = ID_MASSBALANCE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -149,8 +147,8 @@ bool FGMassBalance::Load(Element* el)
     if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
   }
 
-  Weight = EmptyWeight + FDMExec->GetPropulsion()->GetTanksWeight() + GetTotalPointMassWeight()
-    + FDMExec->GetBuoyantForces()->GetGasMass()*slugtolb + ChildFDMWeight;
+  Weight = EmptyWeight + in.TanksWeight + GetTotalPointMassWeight()
+    + in.GasMass*slugtolb + ChildFDMWeight;
 
   Mass = lbtoslug*Weight;
 
@@ -177,16 +175,17 @@ bool FGMassBalance::Run(bool Holding)
     if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
   }
 
-  Weight = EmptyWeight + FDMExec->GetPropulsion()->GetTanksWeight() + GetTotalPointMassWeight()
-    + FDMExec->GetBuoyantForces()->GetGasMass()*slugtolb + ChildFDMWeight;
+  Weight = EmptyWeight + in.TanksWeight + GetTotalPointMassWeight()
+    + in.GasMass*slugtolb + ChildFDMWeight;
 
   Mass = lbtoslug*Weight;
 
 // Calculate new CG
 
-  vXYZcg = (FDMExec->GetPropulsion()->GetTanksMoment() + EmptyWeight*vbaseXYZcg
+  vXYZcg = (EmptyWeight*vbaseXYZcg
             + GetPointMassMoment()
-            + FDMExec->GetBuoyantForces()->GetGasMassMoment()) / Weight;
+            + in.TanksMoment
+            + in.GasMoment) / Weight;
 
   // Track frame-by-frame delta CG, and move the EOM-tracked location
   // by this amount.
@@ -204,8 +203,8 @@ bool FGMassBalance::Run(bool Holding)
   mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
   // Then add the contributions from the additional pointmasses.
   mJ += CalculatePMInertias();
-  mJ += FDMExec->GetPropulsion()->CalculateTankInertias();
-  mJ += FDMExec->GetBuoyantForces()->GetGasMassInertia();
+  mJ += in.TankInertia;
+  mJ += in.GasInertia;
 
   Ixx = mJ(1,1);
   Iyy = mJ(2,2);
@@ -430,24 +429,7 @@ void FGMassBalance::GetMassPropertiesReport(void) const
          << setw(12) << pm->GetPointMassMoI(3,3) << endl;
   }
 
-  for (unsigned int i=0;i<FDMExec->GetPropulsion()->GetNumTanks() ;i++) {
-    FGTank* tank = FDMExec->GetPropulsion()->GetTank(i);
-    string tankname="";
-    if (tank->GetType() == FGTank::ttFUEL && tank->GetGrainType() != FGTank::gtUNKNOWN) {
-      tankname = "Solid Fuel";
-    } else if (tank->GetType() == FGTank::ttFUEL) {
-      tankname = "Fuel";
-    } else if (tank->GetType() == FGTank::ttOXIDIZER) {
-      tankname = "Oxidizer";
-    } else {
-      tankname = "(Unknown tank type)";
-    }
-    cout << highint << left << setw(4) << i << setw(30) << tankname << normint
-      << right << setw(10) << tank->GetContents() << setw(8) << tank->GetXYZ(eX)
-         << setw(8) << tank->GetXYZ(eY) << setw(8) << tank->GetXYZ(eZ)
-         << setw(12) << "*" << setw(12) << "*"
-         << setw(12) << "*" << endl;
-  }
+  cout << FDMExec->GetPropulsionTankReport();
 
   cout << underon << setw(104) << " " << underoff << endl;
   cout << highint << left << setw(30) << "    Total: " << right << setw(14) << Weight 
diff --git a/src/FDM/JSBSim/models/FGMassBalance.h b/src/FDM/JSBSim/models/FGMassBalance.h
index 53279d39c..981eef6de 100644
--- a/src/FDM/JSBSim/models/FGMassBalance.h
+++ b/src/FDM/JSBSim/models/FGMassBalance.h
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.25 2011/07/28 12:48:19 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONSS
@@ -138,13 +138,13 @@ public:
       slugs at the given vector r in the structural frame. The units
       should be for the mass in slug and the vector in the structural
       frame as usual in inches.
-      @param slugs the mass of this single pointmass given in slugs
+      @param mass_sl the mass of this single pointmass given in slugs
       @param r the location of this single pointmass in the structural frame
    */
-  FGMatrix33 GetPointmassInertia(double slugs, const FGColumnVector3& r) const
+  FGMatrix33 GetPointmassInertia(double mass_sl, const FGColumnVector3& r) const
   {
     FGColumnVector3 v = StructuralToBody( r );
-    FGColumnVector3 sv = slugs*v;
+    FGColumnVector3 sv = mass_sl*v;
     double xx = sv(1)*v(1);
     double yy = sv(2)*v(2);
     double zz = sv(3)*v(3);
@@ -179,6 +179,15 @@ public:
   void SetAircraftBaseInertias(FGMatrix33 BaseJ) {baseJ = BaseJ;}
   void GetMassPropertiesReport(void) const;
   
+  struct Inputs {
+    double GasMass;
+    double TanksWeight;
+    FGColumnVector3 GasMoment;
+    FGMatrix33 GasInertia;
+    FGColumnVector3 TanksMoment;
+    FGMatrix33 TankInertia;
+  } in;
+
 private:
   double Weight;
   double EmptyWeight;
diff --git a/src/FDM/JSBSim/models/FGModel.h b/src/FDM/JSBSim/models/FGModel.h
index eae604668..7483dface 100644
--- a/src/FDM/JSBSim/models/FGModel.h
+++ b/src/FDM/JSBSim/models/FGModel.h
@@ -48,7 +48,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_MODEL "$Id: FGModel.h,v 1.19 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_MODEL "$Id: FGModel.h,v 1.20 2011/06/21 04:41:54 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -79,7 +79,7 @@ public:
   /// Constructor
   FGModel(FGFDMExec*);
   /// Destructor
-  ~FGModel();
+  virtual ~FGModel();
 
   std::string Name;
 
diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp
index 3131cd6c0..36dc45ed3 100644
--- a/src/FDM/JSBSim/models/FGOutput.cpp
+++ b/src/FDM/JSBSim/models/FGOutput.cpp
@@ -39,9 +39,16 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <sstream>
+#include <iomanip>
+#include <cstring>
+#include <cstdlib>
+
 #include "FGOutput.h"
 #include "FGFDMExec.h"
 #include "FGAtmosphere.h"
+#include "FGAccelerations.h"
+#include "atmosphere/FGWinds.h"
 #include "FGFCS.h"
 #include "FGAerodynamics.h"
 #include "FGGroundReactions.h"
@@ -56,10 +63,6 @@ INCLUDES
 #include "models/propulsion/FGEngine.h"
 #include "models/propulsion/FGTank.h"
 #include "models/propulsion/FGPiston.h"
-#include <sstream>
-#include <iomanip>
-#include <cstring>
-#include <cstdlib>
 
 #if defined(WIN32) && !defined(__CYGWIN__)
 #  include <windows.h>
@@ -74,7 +77,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGOutput.cpp,v 1.55 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGOutput.cpp,v 1.59 2011/08/14 20:15:56 jberndt Exp $";
 static const char *IdHdr = ID_OUTPUT;
 
 // (stolen from FGFS native_fdm.cxx)
@@ -246,9 +249,11 @@ void FGOutput::DelimitedOutput(const string& fname)
   const FGAuxiliary* Auxiliary = FDMExec->GetAuxiliary();
   const FGAircraft* Aircraft = FDMExec->GetAircraft();
   const FGAtmosphere* Atmosphere = FDMExec->GetAtmosphere();
+  const FGWinds* Winds = FDMExec->GetWinds();
   const FGPropulsion* Propulsion = FDMExec->GetPropulsion();
   const FGMassBalance* MassBalance = FDMExec->GetMassBalance();
   const FGPropagate* Propagate = FDMExec->GetPropagate();
+  const FGAccelerations* Accelerations = FDMExec->GetAccelerations();
   const FGFCS* FCS = FDMExec->GetFCS();
   const FGInertial* Inertial = FDMExec->GetInertial();
   const FGGroundReactions* GroundReactions = FDMExec->GetGroundReactions();
@@ -409,7 +414,7 @@ void FGOutput::DelimitedOutput(const string& fname)
   if (SubSystems & ssRates) {
     outstream << delimeter;
     outstream << (radtodeg*Propagate->GetPQR()).Dump(delimeter) << delimeter;
-    outstream << (radtodeg*Propagate->GetPQRdot()).Dump(delimeter) << delimeter;
+    outstream << (radtodeg*Accelerations->GetPQRdot()).Dump(delimeter) << delimeter;
     outstream << (radtodeg*Propagate->GetPQRi()).Dump(delimeter);
   }
   if (SubSystems & ssVelocities) {
@@ -453,9 +458,9 @@ void FGOutput::DelimitedOutput(const string& fname)
     outstream << Atmosphere->GetTemperature() << delimeter;
     outstream << Atmosphere->GetPressureSL() << delimeter;
     outstream << Atmosphere->GetPressure() << delimeter;
-    outstream << Atmosphere->GetTurbMagnitude() << delimeter;
-    outstream << Atmosphere->GetTurbDirection().Dump(delimeter) << delimeter;
-    outstream << Atmosphere->GetTotalWindNED().Dump(delimeter);
+    outstream << Winds->GetTurbMagnitude() << delimeter;
+    outstream << Winds->GetTurbDirection().Dump(delimeter) << delimeter;
+    outstream << Winds->GetTotalWindNED().Dump(delimeter);
   }
   if (SubSystems & ssMassProps) {
     outstream << delimeter;
@@ -477,7 +482,7 @@ void FGOutput::DelimitedOutput(const string& fname)
     outstream << ((FGColumnVector3)Propagate->GetInertialPosition()).Dump(delimeter) << delimeter;
     outstream << ((FGColumnVector3)Propagate->GetLocation()).Dump(delimeter) << delimeter;
     outstream.precision(14);
-    outstream << Inertial->GetEarthPositionAngleDeg() << delimeter;
+    outstream << Propagate->GetEarthPositionAngleDeg() << delimeter;
     outstream << Propagate->GetDistanceAGL() << delimeter;
     outstream << Propagate->GetTerrainElevation();
     outstream.precision(10);
@@ -733,8 +738,10 @@ void FGOutput::SocketOutput(void)
   const FGPropulsion* Propulsion = FDMExec->GetPropulsion();
   const FGMassBalance* MassBalance = FDMExec->GetMassBalance();
   const FGPropagate* Propagate = FDMExec->GetPropagate();
+  const FGAccelerations* Accelerations = FDMExec->GetAccelerations();
   const FGFCS* FCS = FDMExec->GetFCS();
   const FGAtmosphere* Atmosphere = FDMExec->GetAtmosphere();
+  const FGWinds* Winds = FDMExec->GetWinds();
   const FGAircraft* Aircraft = FDMExec->GetAircraft();
   const FGGroundReactions* GroundReactions = FDMExec->GetGroundReactions();
 
@@ -875,9 +882,9 @@ void FGOutput::SocketOutput(void)
     socket->Append(radtodeg*Propagate->GetPQR(eP));
     socket->Append(radtodeg*Propagate->GetPQR(eQ));
     socket->Append(radtodeg*Propagate->GetPQR(eR));
-    socket->Append(radtodeg*Propagate->GetPQRdot(eP));
-    socket->Append(radtodeg*Propagate->GetPQRdot(eQ));
-    socket->Append(radtodeg*Propagate->GetPQRdot(eR));
+    socket->Append(radtodeg*Accelerations->GetPQRdot(eP));
+    socket->Append(radtodeg*Accelerations->GetPQRdot(eQ));
+    socket->Append(radtodeg*Accelerations->GetPQRdot(eR));
   }
   if (SubSystems & ssVelocities) {
     socket->Append(Auxiliary->Getqbar());
@@ -910,9 +917,9 @@ void FGOutput::SocketOutput(void)
     socket->Append(Atmosphere->GetDensity());
     socket->Append(Atmosphere->GetPressureSL());
     socket->Append(Atmosphere->GetPressure());
-    socket->Append(Atmosphere->GetTurbMagnitude());
-    socket->Append(Atmosphere->GetTurbDirection().Dump(","));
-    socket->Append(Atmosphere->GetTotalWindNED().Dump(","));
+    socket->Append(Winds->GetTurbMagnitude());
+    socket->Append(Winds->GetTurbDirection().Dump(","));
+    socket->Append(Winds->GetTotalWindNED().Dump(","));
   }
   if (SubSystems & ssMassProps) {
     socket->Append(MassBalance->GetJ()(1,1));
diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp
index 51bc472d2..96545104d 100644
--- a/src/FDM/JSBSim/models/FGPropagate.cpp
+++ b/src/FDM/JSBSim/models/FGPropagate.cpp
@@ -62,16 +62,13 @@ INCLUDES
 #include "FGPropagate.h"
 #include "FGGroundReactions.h"
 #include "FGFDMExec.h"
-#include "FGAircraft.h"
-#include "FGMassBalance.h"
-#include "FGInertial.h"
 #include "input_output/FGPropertyManager.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.88 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.95 2011/08/21 16:11:25 bcoconni Exp $";
 static const char *IdHdr = ID_PROPAGATE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -86,11 +83,7 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex)
 {
   Debug(0);
   Name = "FGPropagate";
-  gravType = gtWGS84;
  
-  vPQRidot.InitMatrix();
-  vQtrndot = FGQuaternion(0,0,0);
-  vUVWidot.InitMatrix();
   vInertialVelocity.InitMatrix();
 
   /// These define the indices use to select the various integrators.
@@ -122,15 +115,12 @@ FGPropagate::~FGPropagate(void)
 bool FGPropagate::InitModel(void)
 {
   // For initialization ONLY:
-  SeaLevelRadius = LocalTerrainRadius = FDMExec->GetInertial()->GetRefRadius();
+  SeaLevelRadius = LocalTerrainRadius = in.RefRadius;
+  FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(LocalTerrainRadius);
 
   VState.vLocation.SetRadius( LocalTerrainRadius + 4.0 );
-  VState.vLocation.SetEllipse(FDMExec->GetInertial()->GetSemimajor(), FDMExec->GetInertial()->GetSemiminor());
-  vOmegaEarth = FGColumnVector3( 0.0, 0.0, FDMExec->GetInertial()->omega() ); // Earth rotation vector
+  VState.vLocation.SetEllipse(in.SemiMajor, in.SemiMinor);
 
-  vPQRidot.InitMatrix();
-  vQtrndot = FGQuaternion(0,0,0);
-  vUVWidot.InitMatrix();
   vInertialVelocity.InitMatrix();
 
   VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
@@ -150,7 +140,6 @@ bool FGPropagate::InitModel(void)
 
 void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
 {
-  SetSeaLevelRadius(FGIC->GetSeaLevelRadiusFtIC());
   SetTerrainElevation(FGIC->GetTerrainElevationFtIC());
 
   // Initialize the State Vector elements and the transformation matrices
@@ -158,9 +147,9 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
   // Set the position lat/lon/radius
   VState.vLocation.SetPosition( FGIC->GetLongitudeRadIC(),
                                 FGIC->GetLatitudeRadIC(),
-                                FGIC->GetAltitudeASLFtIC() + FGIC->GetSeaLevelRadiusFtIC() );
+                                FGIC->GetAltitudeASLFtIC() + SeaLevelRadius);
 
-  VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
+  VState.vLocation.SetEarthPositionAngle(0.0);
 
   Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
   Tec2i = Ti2ec.Transposed();          // ECEF to ECI frame transform
@@ -198,10 +187,22 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
                                  FGIC->GetQRadpsIC(),
                                  FGIC->GetRRadpsIC() );
 
-  VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
+  VState.vPQRi = VState.vPQR + Ti2b * in.vOmegaPlanet;
 
-  // Make an initial run and set past values
-  InitializeDerivatives();
+  CalculateInertialVelocity(); // Translational position derivative
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// Initialize the past value deques
+
+void FGPropagate::InitializeDerivatives()
+{
+  for (int i=0; i<4; i++) {
+    VState.dqPQRidot[i] = in.vPQRidot;
+    VState.dqUVWidot[i] = in.vUVWidot;
+    VState.dqInertialVelocity[i] = VState.vInertialVelocity;
+    VState.dqQtrndot[i] = in.vQtrndot;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -229,28 +230,22 @@ bool FGPropagate::Run(bool Holding)
   if (FGModel::Run(Holding)) return true;  // Fast return if we have nothing to do ...
   if (Holding) return false;
 
-  double dt = FDMExec->GetDeltaT()*rate;  // The 'stepsize'
+  double dt = in.DeltaT * rate;  // The 'stepsize'
 
   RunPreFunctions();
 
-  // Calculate state derivatives
-  CalculatePQRdot();           // Angular rate derivative
-  CalculateUVWdot();           // Translational rate derivative
-  ResolveFrictionForces(dt);   // Update rate derivatives with friction forces
-  CalculateQuatdot();          // Angular orientation derivative
-
   // Propagate rotational / translational velocity, angular /translational position, respectively.
 
-  Integrate(VState.vPQRi,             vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate);
-  Integrate(VState.qAttitudeECI,      vQtrndot,          VState.dqQtrndot,          dt, integrator_rotational_position);
+  Integrate(VState.vPQRi,             in.vPQRidot,          VState.dqPQRidot,          dt, integrator_rotational_rate);
+  Integrate(VState.qAttitudeECI,      in.vQtrndot,          VState.dqQtrndot,          dt, integrator_rotational_position);
   Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
-  Integrate(VState.vInertialVelocity, vUVWidot,          VState.dqUVWidot,          dt, integrator_translational_rate);
+  Integrate(VState.vInertialVelocity, in.vUVWidot,          VState.dqUVWidot,          dt, integrator_translational_rate);
 
   // CAUTION : the order of the operations below is very important to get transformation
   // matrices that are consistent with the new state of the vehicle
 
   // 1. Update the Earth position angle (EPA)
-  VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
+  VState.vLocation.IncrementEarthPositionAngle(in.vOmegaPlanet(eZ)*(in.DeltaT*rate));
 
   // 2. Update the Ti2ec and Tec2i transforms from the updated EPA
   Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
@@ -278,7 +273,7 @@ bool FGPropagate::Run(bool Holding)
 
   VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet
 
-  VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
+  VState.vPQR = VState.vPQRi - Ti2b * in.vOmegaPlanet;
 
   VState.qAttitudeLocal = Tl2b.GetQuaternion();
 
@@ -291,88 +286,6 @@ bool FGPropagate::Run(bool Holding)
   return false;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Compute body frame rotational accelerations based on the current body moments
-//
-// vPQRdot is the derivative of the absolute angular velocity of the vehicle 
-// (body rate with respect to the inertial frame), expressed in the body frame,
-// where the derivative is taken in the body frame.
-// J is the inertia matrix
-// Jinv is the inverse inertia matrix
-// vMoments is the moment vector in the body frame
-// VState.vPQRi is the total inertial angular velocity of the vehicle
-// expressed in the body frame.
-// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
-//            Second edition (2004), eqn 1.5-16e (page 50)
-
-void FGPropagate::CalculatePQRdot(void)
-{
-  const FGColumnVector3& vMoments = FDMExec->GetAircraft()->GetMoments(); // current moments
-  const FGMatrix33& J = FDMExec->GetMassBalance()->GetJ();                // inertia matrix
-  const FGMatrix33& Jinv = FDMExec->GetMassBalance()->GetJinv();          // inertia matrix inverse
-
-  // Compute body frame rotational accelerations based on the current body
-  // moments and the total inertial angular velocity expressed in the body
-  // frame.
-
-  vPQRidot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
-  vPQRdot = vPQRidot - VState.vPQRi * (Ti2b * vOmegaEarth);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Compute the quaternion orientation derivative
-//
-// vQtrndot is the quaternion derivative.
-// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
-//            Second edition (2004), eqn 1.5-16b (page 50)
-
-void FGPropagate::CalculateQuatdot(void)
-{
-  // Compute quaternion orientation derivative on current body rates
-  vQtrndot = VState.qAttitudeECI.GetQDot( VState.vPQRi);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This set of calculations results in the body and inertial frame accelerations
-// being computed.
-// Compute body and inertial frames accelerations based on the current body
-// forces including centripetal and coriolis accelerations for the former.
-// vOmegaEarth is the Earth angular rate - expressed in the inertial frame -
-//   so it has to be transformed to the body frame. More completely,
-//   vOmegaEarth is the rate of the ECEF frame relative to the Inertial
-//   frame (ECI), expressed in the Inertial frame.
-// vForces is the total force on the vehicle in the body frame.
-// VState.vPQR is the vehicle body rate relative to the ECEF frame, expressed
-//   in the body frame.
-// VState.vUVW is the vehicle velocity relative to the ECEF frame, expressed
-//   in the body frame.
-// Reference: See Stevens and Lewis, "Aircraft Control and Simulation", 
-//            Second edition (2004), eqns 1.5-13 (pg 48) and 1.5-16d (page 50)
-
-void FGPropagate::CalculateUVWdot(void)
-{
-  double mass = FDMExec->GetMassBalance()->GetMass();                      // mass
-  const FGColumnVector3& vForces = FDMExec->GetAircraft()->GetForces();    // current forces
-
-  vUVWdot = vForces/mass - (VState.vPQR + 2.0*(Ti2b *vOmegaEarth)) * VState.vUVW;
-
-  // Include Centripetal acceleration.
-  vUVWdot -= Ti2b * (vOmegaEarth*(vOmegaEarth*VState.vInertialPosition));
-
-  // Include Gravitation accel
-  switch (gravType) {
-    case gtStandard:
-      vGravAccel = Tl2b * FGColumnVector3( 0.0, 0.0, FDMExec->GetInertial()->GetGAccel(VehicleRadius) );
-      break;
-    case gtWGS84:
-      vGravAccel = Tec2b * FDMExec->GetInertial()->GetGravityJ2(VState.vLocation);
-      break;
-  }
-
-  vUVWdot += vGravAccel;
-  vUVWidot = Tb2i * (vForces/mass + vGravAccel);
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   // Transform the velocity vector of the body relative to the origin (Earth
   // center) to be expressed in the inertial frame, and add the vehicle velocity
@@ -382,7 +295,7 @@ void FGPropagate::CalculateUVWdot(void)
 
 void FGPropagate::CalculateInertialVelocity(void)
 {
-  VState.vInertialVelocity = Tb2i * VState.vUVW + (vOmegaEarth * VState.vInertialPosition);
+  VState.vInertialVelocity = Tb2i * VState.vUVW + (in.vOmegaPlanet * VState.vInertialPosition);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -392,7 +305,7 @@ void FGPropagate::CalculateInertialVelocity(void)
 
 void FGPropagate::CalculateUVW(void)
 {
-  VState.vUVW = Ti2b * (VState.vInertialVelocity - (vOmegaEarth * VState.vInertialPosition));
+  VState.vUVW = Ti2b * (VState.vInertialVelocity - (in.vOmegaPlanet * VState.vInertialPosition));
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -449,167 +362,6 @@ void FGPropagate::Integrate( FGQuaternion& Integrand,
   }
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Evaluates the rates (translation or rotation) that the friction forces have
-// to resist to. This includes the external forces and moments as well as the
-// relative movement between the aircraft and the ground.
-// Erin Catto's paper (see ref [6]) only supports Euler integration scheme and
-// this algorithm has been adapted to handle the multistep algorithms that
-// JSBSim supports (i.e. Trapezoidal, Adams-Bashforth 2, 3 and 4). The capacity
-// to handle the multistep integration schemes adds some complexity but it
-// significantly helps stabilizing the friction forces.
-
-void FGPropagate::EvaluateRateToResistTo(FGColumnVector3& vdot,
-                                         const FGColumnVector3& Val,
-                                         const FGColumnVector3& ValDot,
-                                         const FGColumnVector3& LocalTerrainVal,
-                                         deque <FGColumnVector3>& dqValDot,
-                                         const double dt,
-                                         const eIntegrateType integration_type)
-{
-  switch(integration_type) {
-  case eAdamsBashforth4:
-    vdot = ValDot + Ti2b * (-59.*dqValDot[0]+37.*dqValDot[1]-9.*dqValDot[2])/55.;
-    if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
-      vdot += 24.*(Val - Tec2b * LocalTerrainVal) / (55.*dt);
-    break;
-  case eAdamsBashforth3:
-    vdot = ValDot + Ti2b * (-16.*dqValDot[0]+5.*dqValDot[1])/23.;
-    if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
-      vdot += 12.*(Val - Tec2b * LocalTerrainVal) / (23.*dt);
-    break;
-  case eAdamsBashforth2:
-    vdot = ValDot - Ti2b * dqValDot[0]/3.;
-    if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
-      vdot += 2.*(Val - Tec2b * LocalTerrainVal) / (3.*dt);
-    break;
-  case eTrapezoidal:
-    vdot = ValDot + Ti2b * dqValDot[0];
-    if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
-      vdot += 2.*(Val - Tec2b * LocalTerrainVal) / dt;
-    break;
-  case eRectEuler:
-    vdot = ValDot;
-    if (dt > 0.) // Zeroes out the relative movement between aircraft and ground
-      vdot += (Val - Tec2b * LocalTerrainVal) / dt;
-    break;
-  case eNone:
-    break;
-  }
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Resolves the contact forces just before integrating the EOM.
-// This routine is using Lagrange multipliers and the projected Gauss-Seidel
-// (PGS) method.
-// Reference: See Erin Catto, "Iterative Dynamics with Temporal Coherence", 
-//            February 22, 2005
-// In JSBSim there is only one rigid body (the aircraft) and there can be
-// multiple points of contact between the aircraft and the ground. As a
-// consequence our matrix J*M^-1*J^T is not sparse and the algorithm described
-// in Catto's paper has been adapted accordingly.
-// The friction forces are resolved in the body frame relative to the origin
-// (Earth center).
-
-void FGPropagate::ResolveFrictionForces(double dt)
-{
-  const double invMass = 1.0 / FDMExec->GetMassBalance()->GetMass();
-  const FGMatrix33& Jinv = FDMExec->GetMassBalance()->GetJinv();
-  vector <FGColumnVector3> JacF, JacM;
-  vector<double> lambda, lambdaMin, lambdaMax;
-  FGColumnVector3 vdot, wdot;
-  FGColumnVector3 Fc, Mc;
-  int n = 0;
-
-  // Compiles data from the ground reactions to build up the jacobian matrix
-  for (MultiplierIterator it=MultiplierIterator(FDMExec->GetGroundReactions()); *it; ++it, n++) {
-    JacF.push_back((*it)->ForceJacobian);
-    JacM.push_back((*it)->MomentJacobian);
-    lambda.push_back((*it)->value);
-    lambdaMax.push_back((*it)->Max);
-    lambdaMin.push_back((*it)->Min);
-  }
-
-  // If no gears are in contact with the ground then return
-  if (!n) return;
-
-  vector<double> a(n*n); // Will contain J*M^-1*J^T
-  vector<double> rhs(n);
-
-  // Assemble the linear system of equations
-  for (int i=0; i < n; i++) {
-    for (int j=0; j < i; j++)
-      a[i*n+j] = a[j*n+i]; // Takes advantage of the symmetry of J^T*M^-1*J
-    for (int j=i; j < n; j++)
-      a[i*n+j] = DotProduct(JacF[i],invMass*JacF[j])+DotProduct(JacM[i],Jinv*JacM[j]);
-  }
-
-  // Assemble the RHS member
-
-  // Translation
-  EvaluateRateToResistTo(vdot, VState.vUVW, vUVWdot, LocalTerrainVelocity,
-                         VState.dqUVWidot, dt, integrator_translational_rate);
-
-  // Rotation
-  EvaluateRateToResistTo(wdot, VState.vPQR, vPQRdot, LocalTerrainAngularVelocity,
-                         VState.dqPQRidot, dt, integrator_rotational_rate);
-
-  // Prepare the linear system for the Gauss-Seidel algorithm :
-  // 1. Compute the right hand side member 'rhs'
-  // 2. Divide every line of 'a' and 'rhs' by a[i,i]. This is in order to save
-  //    a division computation at each iteration of Gauss-Seidel.
-  for (int i=0; i < n; i++) {
-    double d = 1.0 / a[i*n+i];
-
-    rhs[i] = -(DotProduct(JacF[i],vdot)+DotProduct(JacM[i],wdot))*d;
-    for (int j=0; j < n; j++)
-      a[i*n+j] *= d;
-  }
-
-  // Resolve the Lagrange multipliers with the projected Gauss-Seidel method
-  for (int iter=0; iter < 50; iter++) {
-    double norm = 0.;
-
-    for (int i=0; i < n; i++) {
-      double lambda0 = lambda[i];
-      double dlambda = rhs[i];
-      
-      for (int j=0; j < n; j++)
-        dlambda -= a[i*n+j]*lambda[j];
-
-      lambda[i] = Constrain(lambdaMin[i], lambda0+dlambda, lambdaMax[i]);
-      dlambda = lambda[i] - lambda0;
-
-      norm += fabs(dlambda);
-    }
-
-    if (norm < 1E-5) break;
-  }
-
-  // Calculate the total friction forces and moments
-
-  Fc.InitMatrix();
-  Mc.InitMatrix();
-
-  for (int i=0; i< n; i++) {
-    Fc += lambda[i]*JacF[i];
-    Mc += lambda[i]*JacM[i];
-  }
-
-  vUVWdot += invMass * Fc;
-  vUVWidot += invMass * Tb2i * Fc;
-  vPQRdot += Jinv * Mc;
-  vPQRidot += Jinv * Mc;
-
-  // Save the value of the Lagrange multipliers to accelerate the convergence
-  // of the Gauss-Seidel algorithm at next iteration.
-  int i = 0;
-  for (MultiplierIterator it=MultiplierIterator(FDMExec->GetGroundReactions()); *it; ++it)
-    (*it)->value = lambda[i++];
-
-  FDMExec->GetGroundReactions()->UpdateForcesAndMoments();
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPropagate::UpdateLocationMatrices(void)
@@ -653,31 +405,7 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
 
 void FGPropagate::SetInertialRates(FGColumnVector3 vRates) {
   VState.vPQRi = Ti2b * vRates;
-  VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGPropagate::InitializeDerivatives(void)
-{
-  // Make an initial run and set past values
-  CalculatePQRdot();           // Angular rate derivative
-  CalculateUVWdot();           // Translational rate derivative
-  ResolveFrictionForces(0.);   // Update rate derivatives with friction forces
-  CalculateQuatdot();          // Angular orientation derivative
-  CalculateInertialVelocity(); // Translational position derivative
-
-  // Initialize past values deques
-  VState.dqPQRidot.clear();
-  VState.dqUVWidot.clear();
-  VState.dqInertialVelocity.clear();
-  VState.dqQtrndot.clear();
-  for (int i=0; i<4; i++) {
-    VState.dqPQRidot.push_front(vPQRidot);
-    VState.dqUVWidot.push_front(vUVWidot);
-    VState.dqInertialVelocity.push_front(VState.vInertialVelocity);
-    VState.dqQtrndot.push_front(vQtrndot);
-  }
+  VState.vPQR = VState.vPQRi - Ti2b * in.vOmegaPlanet;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -685,13 +413,14 @@ void FGPropagate::InitializeDerivatives(void)
 void FGPropagate::RecomputeLocalTerrainRadius(void)
 {
   FGLocation contactloc;
-  FGColumnVector3 dv;
+  FGColumnVector3 dummy;
   double t = FDMExec->GetSimTime();
 
   // Get the LocalTerrain radius.
-  FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv,
-                                           LocalTerrainVelocity, LocalTerrainAngularVelocity);
-  LocalTerrainRadius = contactloc.GetRadius(); 
+  FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc,
+                      dummy, LocalTerrainVelocity, LocalTerrainAngularVelocity);
+  LocalTerrainRadius = contactloc.GetRadius();
+  FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(LocalTerrainRadius);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -720,8 +449,9 @@ double FGPropagate::GetDistanceAGL(void) const
 
 void FGPropagate::SetVState(const VehicleState& vstate)
 {
+  //ToDo: Shouldn't all of these be set from the vstate vector passed in?
   VState.vLocation = vstate.vLocation;
-  VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
+  VState.vLocation.SetEarthPositionAngle(vstate.vLocation.GetEPA());
   Ti2ec = VState.vLocation.GetTi2ec(); // useless ?
   Tec2i = Ti2ec.Transposed();
   UpdateLocationMatrices();
@@ -731,10 +461,8 @@ void FGPropagate::SetVState(const VehicleState& vstate)
   VState.vUVW = vstate.vUVW;
   vVel = Tb2l * VState.vUVW;
   VState.vPQR = vstate.vPQR;
-  VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
+  VState.vPQRi = VState.vPQR + Ti2b * in.vOmegaPlanet;
   VState.vInertialPosition = vstate.vInertialPosition;
-
-  InitializeDerivatives();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -755,7 +483,7 @@ void FGPropagate::UpdateVehicleState(void)
 void FGPropagate::SetLocation(const FGLocation& l)
 {
   VState.vLocation = l;
-  VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
+  VState.vLocation.SetEarthPositionAngle(l.GetEPA());
   Ti2ec = VState.vLocation.GetTi2ec(); // useless ?
   Tec2i = Ti2ec.Transposed();
   UpdateVehicleState();
@@ -822,14 +550,6 @@ void FGPropagate::bind(void)
 
   PropertyManager->Tie("velocities/eci-velocity-mag-fps", this, &FGPropagate::GetInertialVelocityMagnitude);
 
-  PropertyManager->Tie("accelerations/pdot-rad_sec2", this, eP, (PMF)&FGPropagate::GetPQRdot);
-  PropertyManager->Tie("accelerations/qdot-rad_sec2", this, eQ, (PMF)&FGPropagate::GetPQRdot);
-  PropertyManager->Tie("accelerations/rdot-rad_sec2", this, eR, (PMF)&FGPropagate::GetPQRdot);
-
-  PropertyManager->Tie("accelerations/udot-ft_sec2", this, eU, (PMF)&FGPropagate::GetUVWdot);
-  PropertyManager->Tie("accelerations/vdot-ft_sec2", this, eV, (PMF)&FGPropagate::GetUVWdot);
-  PropertyManager->Tie("accelerations/wdot-ft_sec2", this, eW, (PMF)&FGPropagate::GetUVWdot);
-
   PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::GetAltitudeASL, &FGPropagate::SetAltitudeASL, true);
   PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::GetAltitudeASLmeters, &FGPropagate::SetAltitudeASLmeters, true);
   PropertyManager->Tie("position/lat-gc-rad", this, &FGPropagate::GetLatitude, &FGPropagate::SetLatitude);
@@ -845,6 +565,7 @@ void FGPropagate::bind(void)
                           &FGPropagate::GetTerrainElevation,
                           &FGPropagate::SetTerrainElevation, false);
 
+  PropertyManager->Tie("position/epa-rad", this, &FGPropagate::GetEarthPositionAngle);
   PropertyManager->Tie("metrics/terrain-radius", this, &FGPropagate::GetLocalTerrainRadius);
 
   PropertyManager->Tie("attitude/phi-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
@@ -859,7 +580,6 @@ void FGPropagate::bind(void)
   PropertyManager->Tie("simulation/integrator/rate/translational", (int*)&integrator_translational_rate);
   PropertyManager->Tie("simulation/integrator/position/rotational", (int*)&integrator_rotational_position);
   PropertyManager->Tie("simulation/integrator/position/translational", (int*)&integrator_translational_position);
-  PropertyManager->Tie("simulation/gravity-model", &gravType);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -902,7 +622,7 @@ void FGPropagate::Debug(int from)
          << reset << endl;
     cout << endl;
     cout << highint << "  Earth Position Angle (deg): " << setw(8) << setprecision(3) << reset
-                    << FDMExec->GetInertial()->GetEarthPositionAngleDeg() << endl;
+         << GetEarthPositionAngleDeg() << endl;
     cout << endl;
     cout << highint << "  Body velocity (ft/sec): " << setw(8) << setprecision(3) << reset << VState.vUVW << endl;
     cout << highint << "  Local velocity (ft/sec): " << setw(8) << setprecision(3) << reset << vVel << endl;
@@ -911,7 +631,7 @@ void FGPropagate::Debug(int from)
     cout << highint << "  Latitude (deg): " << setw(8) << setprecision(3) << reset << VState.vLocation.GetLatitudeDeg() << endl;
     cout << highint << "  Longitude (deg): " << setw(8) << setprecision(3) << reset << VState.vLocation.GetLongitudeDeg() << endl;
     cout << highint << "  Altitude ASL (ft): " << setw(8) << setprecision(3) << reset << GetAltitudeASL() << endl;
-    cout << highint << "  Acceleration (NED, ft/sec^2): " << setw(8) << setprecision(3) << reset << Tb2l*GetUVWdot() << endl;
+//    cout << highint << "  Acceleration (NED, ft/sec^2): " << setw(8) << setprecision(3) << reset << Tb2l*GetUVWdot() << endl;
     cout << endl;
     cout << highint << "  Matrix ECEF to Body (Orientation of Body with respect to ECEF): "
                     << reset << endl << Tec2b.Dump("\t", "    ") << endl;
diff --git a/src/FDM/JSBSim/models/FGPropagate.h b/src/FDM/JSBSim/models/FGPropagate.h
index 1afe7f641..f262d1fb1 100644
--- a/src/FDM/JSBSim/models/FGPropagate.h
+++ b/src/FDM/JSBSim/models/FGPropagate.h
@@ -49,7 +49,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.63 2011/08/21 15:35:39 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -69,15 +69,6 @@ CLASS DOCUMENTATION
     state of the vehicle given the forces and moments that act on it. The
     integration accounts for a rotating Earth.
 
-    The general execution of this model follows this process:
-
-    -Calculate the angular accelerations
-    -Calculate the translational accelerations
-    -Calculate the angular rate
-    -Calculate the translational velocity
-
-    -Integrate accelerations and rates
-
     Integration of rotational and translation position and rate can be 
     customized as needed or frozen by the selection of no integrator. The
     selection of which integrator to use is done through the setting of 
@@ -101,8 +92,8 @@ CLASS DOCUMENTATION
     5: Adams Bashforth 4
     @endcode
 
-    @author Jon S. Berndt, Mathias Froehlich
-    @version $Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $
+    @author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
+    @version $Id: FGPropagate.h,v 1.63 2011/08/21 15:35:39 bcoconni Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -169,14 +160,13 @@ public:
   /// These define the indices use to select the various integrators.
   enum eIntegrateType {eNone = 0, eRectEuler, eTrapezoidal, eAdamsBashforth2, eAdamsBashforth3, eAdamsBashforth4};
 
-  /// These define the indices use to select the gravitation models.
-  enum eGravType {gtStandard, gtWGS84}; 
-
   /** Initializes the FGPropagate class after instantiation and prior to first execution.
       The base class FGModel::InitModel is called first, initializing pointers to the 
       other FGModel objects (and others).  */
   bool InitModel(void);
 
+  void InitializeDerivatives();
+
   /** Runs the state propagation model; called by the Executive
       Can pass in a value indicating if the executive is directing the simulation to Hold.
       @param Holding if true, the executive has been directed to hold the sim from 
@@ -186,8 +176,6 @@ public:
       @return false if no error */
   bool Run(bool Holding);
 
-  const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;}
-
   /** Retrieves the velocity vector.
       The vector returned is represented by an FGColumnVector reference. The vector
       for the velocity in Local frame is organized (Vnorth, Veast, Vdown). The vector
@@ -213,20 +201,6 @@ public:
   */
   const FGColumnVector3& GetUVW(void) const { return VState.vUVW; }
   
-  /** Retrieves the body axis acceleration.
-      Retrieves the computed body axis accelerations based on the
-      applied forces and accounting for a rotating body frame.
-      The vector returned is represented by an FGColumnVector reference. The vector
-      for the acceleration in Body frame is organized (Ax, Ay, Az). The vector
-      is 1-based, so that the first element can be retrieved using the "()" operator.
-      In other words, vUVWdot(1) is Ax. Various convenience enumerators are defined
-      in FGJSBBase. The relevant enumerators for the vector returned by this call are,
-      eX=1, eY=2, eZ=3.
-      units ft/sec^2
-      @return Body axis translational acceleration in ft/sec^2.
-  */
-  const FGColumnVector3& GetUVWdot(void) const { return vUVWdot; }
-  
   /** Retrieves the body angular rates vector, relative to the ECEF frame.
       Retrieves the body angular rates (p, q, r), which are calculated by integration
       of the angular acceleration.
@@ -255,21 +229,6 @@ public:
   */
   const FGColumnVector3& GetPQRi(void) const {return VState.vPQRi;}
 
-  /** Retrieves the body axis angular acceleration vector.
-      Retrieves the body axis angular acceleration vector in rad/sec^2. The
-      angular acceleration vector is determined from the applied forces and
-      accounts for a rotating frame.
-      The vector returned is represented by an FGColumnVector reference. The vector
-      for the angular acceleration in Body frame is organized (Pdot, Qdot, Rdot). The vector
-      is 1-based, so that the first element can be retrieved using the "()" operator.
-      In other words, vPQRdot(1) is Pdot. Various convenience enumerators are defined
-      in FGJSBBase. The relevant enumerators for the vector returned by this call are,
-      eP=1, eQ=2, eR=3.
-      units rad/sec^2
-      @return The angular acceleration vector.
-  */
-  const FGColumnVector3& GetPQRdot(void) const {return vPQRdot;}
-  
   /** Retrieves the Euler angles that define the vehicle orientation.
       Extracts the Euler angles from the quaternion that stores the orientation
       in the Local frame. The order of rotation used is Yaw-Pitch-Roll. The
@@ -300,19 +259,6 @@ public:
   */
   double GetUVW   (int idx) const { return VState.vUVW(idx); }
 
-  /** Retrieves a body frame acceleration component.
-      Retrieves a body frame acceleration component. The acceleration returned
-      is extracted from the vUVWdot vector (an FGColumnVector). The vector for
-      the acceleration in Body frame is organized (Ax, Ay, Az). The vector is
-      1-based. In other words, GetUVWdot(1) returns Ax. Various convenience
-      enumerators are defined in FGJSBBase. The relevant enumerators for the
-      acceleration returned by this call are, eX=1, eY=2, eZ=3.
-      units ft/sec^2
-      @param idx the index of the acceleration component desired (1-based).
-      @return The body frame acceleration component.
-  */
-  double GetUVWdot(int idx) const { return vUVWdot(idx); }
-
   /** Retrieves a Local frame velocity component.
       Retrieves a Local frame velocity component. The velocity returned is
       extracted from the vVel vector (an FGColumnVector). The vector for the
@@ -382,20 +328,6 @@ public:
   */
   double GetPQRi(int axis) const {return VState.vPQRi(axis);}
 
-  /** Retrieves a body frame angular acceleration component.
-      Retrieves a body frame angular acceleration component. The angular
-      acceleration returned is extracted from the vPQRdot vector (an
-      FGColumnVector). The vector for the angular acceleration in Body frame
-      is organized (Pdot, Qdot, Rdot). The vector is 1-based. In other words,
-      GetPQRdot(1) returns Pdot (roll acceleration). Various convenience
-      enumerators are defined in FGJSBBase. The relevant enumerators for the
-      angular acceleration returned by this call are, eP=1, eQ=2, eR=3.
-      units rad/sec^2
-      @param axis the index of the angular acceleration component desired (1-based).
-      @return The body frame angular acceleration component.
-  */
-  double GetPQRdot(int axis) const {return vPQRdot(axis);}
-
   /** Retrieves a vehicle Euler angle component.
       Retrieves an Euler angle (Phi, Theta, or Psi) from the quaternion that
       stores the vehicle orientation relative to the Local frame. The order of
@@ -447,7 +379,12 @@ public:
       */
   double GetLocalTerrainRadius(void) const { return LocalTerrainRadius; }
 
-  double GetSeaLevelRadius(void) const { return SeaLevelRadius; }
+  double GetEarthPositionAngle(void) const { return VState.vLocation.GetEPA(); }
+
+  double GetEarthPositionAngleDeg(void) const { return GetEarthPositionAngle()*radtodeg;}
+
+  const FGColumnVector3& GetTerrainVelocity(void) const { return LocalTerrainVelocity; }
+  const FGColumnVector3& GetTerrainAngularVelocity(void) const { return LocalTerrainAngularVelocity; }
   double GetTerrainElevation(void) const;
   double GetDistanceAGL(void)  const;
   double GetRadius(void) const {
@@ -526,13 +463,14 @@ public:
 
   void SetVState(const VehicleState& vstate);
 
-  void InitializeDerivatives(void);
+  void SetEarthPositionAngle(double epa) {VState.vLocation.SetEarthPositionAngle(epa);}
 
   void SetInertialOrientation(FGQuaternion Qi);
   void SetInertialVelocity(FGColumnVector3 Vi);
   void SetInertialRates(FGColumnVector3 vRates);
 
   const FGQuaternion GetQuaternion(void) const { return VState.qAttitudeLocal; }
+  const FGQuaternion GetQuaternionECI(void) const { return VState.qAttitudeECI; }
 
   void SetPQR(unsigned int i, double val) {
       if ((i>=1) && (i<=3) )
@@ -589,16 +527,19 @@ public:
     VState.vLocation -= Tb2ec*deltaLoc;
   }
 
-  struct LagrangeMultiplier {
-    FGColumnVector3 ForceJacobian;
-    FGColumnVector3 MomentJacobian;
-    double Min;
-    double Max;
-    double value;
-  };
-
   void DumpState(void);
 
+  struct Inputs {
+    FGColumnVector3 vPQRidot;
+    FGQuaternion vQtrndot;
+    FGColumnVector3 vUVWidot;
+    FGColumnVector3 vOmegaPlanet;
+    double RefRadius;
+    double SemiMajor;
+    double SemiMinor;
+    double DeltaT;
+  } in;
+
 private:
 
 // state vector
@@ -606,14 +547,9 @@ private:
   struct VehicleState VState;
 
   FGColumnVector3 vVel;
-  FGColumnVector3 vPQRdot, vPQRidot;
-  FGColumnVector3 vUVWdot, vUVWidot;
   FGColumnVector3 vInertialVelocity;
   FGColumnVector3 vLocation;
   FGColumnVector3 vDeltaXYZEC;
-  FGColumnVector3 vGravAccel;
-  FGColumnVector3 vOmegaEarth;  // The Earth angular velocity vector
-  FGQuaternion vQtrndot;
   FGMatrix33 Tec2b;
   FGMatrix33 Tb2ec;
   FGMatrix33 Tl2b;   // local to body frame matrix copy for immediate local use
@@ -633,13 +569,9 @@ private:
   eIntegrateType integrator_translational_rate;
   eIntegrateType integrator_rotational_position;
   eIntegrateType integrator_translational_position;
-  int gravType;
 
-  void CalculatePQRdot(void);
-  void CalculateQuatdot(void);
   void CalculateInertialVelocity(void);
   void CalculateUVW(void);
-  void CalculateUVWdot(void);
 
   void Integrate( FGColumnVector3& Integrand,
                   FGColumnVector3& Val,
@@ -653,16 +585,6 @@ private:
                   double dt,
                   eIntegrateType integration_type);
 
-  void EvaluateRateToResistTo(FGColumnVector3& vdot,
-                              const FGColumnVector3& Val,
-                              const FGColumnVector3& ValDot,
-                              const FGColumnVector3& LocalTerrainVal,
-                              deque <FGColumnVector3>& dqValDot,
-                              const double dt,
-                              const eIntegrateType integration_type);
-
-  void ResolveFrictionForces(double dt);
-
   void UpdateLocationMatrices(void);
   void UpdateBodyMatrices(void);
   void UpdateVehicleState(void);
diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp
index bb260f09b..6c5942e8d 100644
--- a/src/FDM/JSBSim/models/FGPropulsion.cpp
+++ b/src/FDM/JSBSim/models/FGPropulsion.cpp
@@ -44,10 +44,14 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <iomanip>
+
+#include "FGFDMExec.h"
 #include "FGPropulsion.h"
-#include "models/FGFCS.h"
 #include "models/FGMassBalance.h"
-#include "models/propulsion/FGThruster.h"
 #include "models/propulsion/FGRocket.h"
 #include "models/propulsion/FGTurbine.h"
 #include "models/propulsion/FGPiston.h"
@@ -57,15 +61,12 @@ INCLUDES
 #include "input_output/FGPropertyManager.h"
 #include "input_output/FGXMLParse.h"
 #include "math/FGColumnVector3.h"
-#include <iostream>
-#include <sstream>
-#include <cstdlib>
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.46 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.50 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_PROPULSION;
 
 extern short debug_lvl;
@@ -87,7 +88,7 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
   tankJ.InitMatrix();
   refuel = dump = false;
   DumpRate = 0.0;
-  fuel_freeze = false;
+  FuelFreeze = false;
   TotalFuelQuantity = 0.0;
   IsBound =
   HavePistonEngine =
@@ -158,33 +159,132 @@ bool FGPropulsion::Run(bool Holding)
 
   RunPreFunctions();
 
-  double dt = FDMExec->GetDeltaT();
-
   vForces.InitMatrix();
   vMoments.InitMatrix();
 
   for (i=0; i<numEngines; i++) {
     Engines[i]->Calculate();
+    ConsumeFuel(Engines[i]);
     vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
     vMoments += Engines[i]->GetMoments();     // sum body frame moments
   }
 
   TotalFuelQuantity = 0.0;
   for (i=0; i<numTanks; i++) {
-    Tanks[i]->Calculate( dt * rate );
+    Tanks[i]->Calculate( in.TotalDeltaT, in.TAT_c);
     if (Tanks[i]->GetType() == FGTank::ttFUEL) {
       TotalFuelQuantity += Tanks[i]->GetContents();
     }
   }
 
-  if (refuel) DoRefuel( dt * rate );
-  if (dump) DumpFuel( dt * rate );
+  if (refuel) DoRefuel( in.TotalDeltaT );
+  if (dump) DumpFuel( in.TotalDeltaT );
 
   RunPostFunctions();
 
   return false;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// The engine can tell us how much fuel it needs, but it is up to the propulsion
+// subsystem manager class FGPropulsion to manage fuel flow amongst tanks. Engines
+// May burn fuel from more than one tank at a time, and may burn from one tank
+// before another - that is, may burn from one tank until the tank is depleted,
+// then burn from the next highest priority tank. This can be accompished
+// by defining a fuel management system, but this way of specifying priorities
+// is more automatic from a user perspective.
+
+void FGPropulsion::ConsumeFuel(FGEngine* engine)
+{
+  if (FuelFreeze) return;
+  if (FDMExec->GetTrimStatus()) return;
+
+  unsigned int TanksWithFuel=0, CurrentFuelTankPriority=1;
+  unsigned int TanksWithOxidizer=0, CurrentOxidizerTankPriority=1;
+  vector <int> FeedListFuel, FeedListOxi;
+  bool Starved = true; // Initially set Starved to true. Set to false in code below.
+//  bool hasOxTanks = false;
+
+  // For this engine,
+  // 1) Count how many fuel tanks with the current priority level have fuel
+  // 2) If there none, then try next lower priority (higher number) - that is,
+  //    increment CurrentPriority.
+  // 3) Build the feed list.
+  // 4) Do the same for oxidizer tanks, if needed.
+
+  // Process fuel tanks, if any
+  while ((TanksWithFuel == 0) && (CurrentFuelTankPriority <= numTanks)) {
+    for (unsigned int i=0; i<engine->GetNumSourceTanks(); i++) {
+      unsigned int TankId = engine->GetSourceTank(i);
+      FGTank* Tank = Tanks[TankId];
+      unsigned int TankPriority = Tank->GetPriority();
+      if (TankPriority != 0) {
+        switch(Tank->GetType()) {
+        case FGTank::ttFUEL:
+          if ((Tank->GetContents() > 0.0) && Tank->GetSelected() && (TankPriority == CurrentFuelTankPriority)) {
+            TanksWithFuel++;
+            Starved = false;
+            FeedListFuel.push_back(TankId);
+          } 
+          break;
+        case FGTank::ttOXIDIZER:
+          // Skip this here (done below)
+          break;
+        }
+      }
+    }
+    if (TanksWithFuel == 0) CurrentFuelTankPriority++; // No tanks at this priority, try next priority
+  }
+
+  // Process Oxidizer tanks, if any
+  if (engine->GetType() == FGEngine::etRocket) {
+    while ((TanksWithOxidizer == 0) && (CurrentOxidizerTankPriority <= numTanks)) {
+      for (unsigned int i=0; i<engine->GetNumSourceTanks(); i++) {
+        unsigned int TankId = engine->GetSourceTank(i);
+        FGTank* Tank = Tanks[TankId];
+        unsigned int TankPriority = Tank->GetPriority();
+        if (TankPriority != 0) {
+          switch(Tank->GetType()) {
+          case FGTank::ttFUEL:
+            // Skip this here (done above)
+            break;
+          case FGTank::ttOXIDIZER:
+//            hasOxTanks = true;
+            if (Tank->GetContents() > 0.0 && Tank->GetSelected() && TankPriority == CurrentOxidizerTankPriority) {
+              TanksWithOxidizer++;
+              if (TanksWithFuel > 0) Starved = false;
+              FeedListOxi.push_back(TankId);
+            }
+            break;
+          }
+        }
+      }
+      if (TanksWithOxidizer == 0) CurrentOxidizerTankPriority++; // No tanks at this priority, try next priority
+    }
+  }
+
+  engine->SetStarved(Starved); // Tanks can be refilled, so be sure to reset engine Starved flag here.
+
+  // No fuel or fuel/oxidizer found at any priority!
+  if (Starved) return;
+
+  double FuelToBurn = engine->CalcFuelNeed();            // How much fuel does this engine need?
+  double FuelNeededPerTank = FuelToBurn / TanksWithFuel; // Determine fuel needed per tank.  
+  for (unsigned int i=0; i<FeedListFuel.size(); i++) {
+    Tanks[FeedListFuel[i]]->Drain(FuelNeededPerTank); 
+  }
+
+  if (engine->GetType() == FGEngine::etRocket) {
+    double OxidizerToBurn = engine->CalcOxidizerNeed();                // How much fuel does this engine need?
+    double OxidizerNeededPerTank = OxidizerToBurn / TanksWithOxidizer; // Determine fuel needed per tank.  
+    for (unsigned int i=0; i<FeedListOxi.size(); i++) {
+      Tanks[FeedListOxi[i]]->Drain(OxidizerNeededPerTank); 
+    }
+  }
+
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 bool FGPropulsion::GetSteadyState(void)
@@ -201,28 +301,23 @@ bool FGPropulsion::GetSteadyState(void)
     FDMExec->SetTrimStatus(true);
 
     for (unsigned int i=0; i<numEngines; i++) {
-//      cout << "  Finding steady state for engine " << i << endl;
       steady=false;
       steady_count=0;
       j=0;
       while (!steady && j < 6000) {
         Engines[i]->Calculate();
         lastThrust = currentThrust;
-        currentThrust = Engines[i]->GetThruster()->GetThrust();
+        currentThrust = Engines[i]->GetThrust();
         if (fabs(lastThrust-currentThrust) < 0.0001) {
           steady_count++;
           if (steady_count > 120) {
             steady=true;
-//            cout << "    Steady state found at thrust: " << currentThrust << " lbs." << endl;
           }
         } else {
           steady_count=0;
         }
         j++;
       }
-//      if (j >= 6000) {
-//        cout << "    Could not find a steady state for this engine." << endl;
-//      }
       vForces  += Engines[i]->GetBodyForces();  // sum body frame forces
       vMoments += Engines[i]->GetMoments();     // sum body frame moments
     }
@@ -244,8 +339,10 @@ void FGPropulsion::InitRunning(int n)
     if (n >= (int)GetNumEngines() ) {
       throw(string("Tried to initialize a non-existent engine!"));
     }
-    FDMExec->GetFCS()->SetThrottleCmd(n,1);
-    FDMExec->GetFCS()->SetMixtureCmd(n,1);
+
+    in.ThrottleCmd[n] = in.ThrottlePos[n] = 1; // Set the throttle command and position
+    in.MixtureCmd[n] = in.MixturePos[n] = 1;   // Set the mixture command and position
+
     GetEngine(n)->InitRunning();
     GetSteadyState();
 
@@ -255,14 +352,14 @@ void FGPropulsion::InitRunning(int n)
   } else if (n < 0) { // -1 refers to "All Engines"
 
     for (unsigned int i=0; i<GetNumEngines(); i++) {
-      FDMExec->GetFCS()->SetThrottleCmd(i,1);
-      FDMExec->GetFCS()->SetMixtureCmd(i,1);
+      in.ThrottleCmd[i] = in.ThrottlePos[i] = 1; // Set the throttle command and position
+      in.MixtureCmd[i] = in.MixturePos[i] = 1;   // Set the mixture command and position
       GetEngine(i)->InitRunning();
     }
+
     GetSteadyState();
     InitializedEngines = -1;
     HasInitializedEngines = true;
-
   }
 }
 
@@ -301,6 +398,11 @@ bool FGPropulsion::Load(Element* el)
     }
 
     engine_filename = FindEngineFullPathname(engine_filename);
+    if (engine_filename.empty()) {
+      // error message already printed by FindEngineFullPathname()
+      return false;
+    }
+
     document = LoadXMLDocument(engine_filename);
     document->SetParent(engine_element);
 
@@ -309,23 +411,23 @@ bool FGPropulsion::Load(Element* el)
       if (type == "piston_engine") {
         HavePistonEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGPiston(FDMExec, document, numEngines));
+        Engines.push_back(new FGPiston(FDMExec, document, numEngines, in));
       } else if (type == "turbine_engine") {
         HaveTurbineEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
+        Engines.push_back(new FGTurbine(FDMExec, document, numEngines, in));
       } else if (type == "turboprop_engine") {
         HaveTurboPropEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
+        Engines.push_back(new FGTurboProp(FDMExec, document, numEngines, in));
       } else if (type == "rocket_engine") {
         HaveRocketEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGRocket(FDMExec, document, numEngines));
+        Engines.push_back(new FGRocket(FDMExec, document, numEngines, in));
       } else if (type == "electric_engine") {
         HaveElectricEngine = true;
         if (!IsBound) bind();
-        Engines.push_back(new FGElectric(FDMExec, document, numEngines));
+        Engines.push_back(new FGElectric(FDMExec, document, numEngines, in));
       } else {
         cerr << "Unknown engine type: " << type << endl;
         exit(-5);
@@ -335,9 +437,6 @@ bool FGPropulsion::Load(Element* el)
       return false;
     }
 
-    FDMExec->GetFCS()->AddThrottle();
-    ThrottleAdded = true;
-
     numEngines++;
 
     engine_element = el->FindNextElement("engine");
@@ -345,7 +444,6 @@ bool FGPropulsion::Load(Element* el)
   }
 
   CalculateTankInertias();
-  if (!ThrottleAdded) FDMExec->GetFCS()->AddThrottle(); // need to have at least one throttle
 
   // Process fuel dump rate
   if (el->FindElement("dump-rate"))
@@ -459,6 +557,34 @@ string FGPropulsion::GetPropulsionValues(const string& delimiter) const
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+string FGPropulsion::GetPropulsionTankReport()
+{
+  string out="";
+  stringstream outstream;
+  for (unsigned int i=0; i<numTanks; i++)
+  {
+    FGTank* tank = Tanks[i];
+    string tankname="";
+    if (tank->GetType() == FGTank::ttFUEL && tank->GetGrainType() != FGTank::gtUNKNOWN) {
+      tankname = "Solid Fuel";
+    } else if (tank->GetType() == FGTank::ttFUEL) {
+      tankname = "Fuel";
+    } else if (tank->GetType() == FGTank::ttOXIDIZER) {
+      tankname = "Oxidizer";
+    } else {
+      tankname = "(Unknown tank type)";
+    }
+    outstream << highint << left << setw(4) << i << setw(30) << tankname << normint
+      << right << setw(10) << tank->GetContents() << setw(8) << tank->GetXYZ(eX)
+         << setw(8) << tank->GetXYZ(eY) << setw(8) << tank->GetXYZ(eZ)
+         << setw(12) << "*" << setw(12) << "*"
+         << setw(12) << "*" << endl;
+  }
+  return outstream.str();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 FGColumnVector3& FGPropulsion::GetTanksMoment(void)
 {
   vXYZtank_arm.InitMatrix();
@@ -633,7 +759,7 @@ void FGPropulsion::DumpFuel(double time_slice)
 
 void FGPropulsion::SetFuelFreeze(bool f)
 {
-  fuel_freeze = f;
+  FuelFreeze = f;
   for (unsigned int i=0; i<numEngines; i++) {
     Engines[i]->SetFuelFreeze(f);
   }
diff --git a/src/FDM/JSBSim/models/FGPropulsion.h b/src/FDM/JSBSim/models/FGPropulsion.h
index 3dacfc4fd..b16b17382 100644
--- a/src/FDM/JSBSim/models/FGPropulsion.h
+++ b/src/FDM/JSBSim/models/FGPropulsion.h
@@ -42,6 +42,7 @@ INCLUDES
 #include <iosfwd>
 
 #include "FGModel.h"
+#include "propulsion/FGEngine.h"
 #include "math/FGMatrix33.h"
 #include "input_output/FGXMLFileRead.h"
 
@@ -49,7 +50,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $"
+#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.30 2011/08/03 03:21:06 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -91,7 +92,7 @@ CLASS DOCUMENTATION
   @endcode
 
     @author Jon S. Berndt
-    @version $Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $
+    @version $Id: FGPropulsion.h,v 1.30 2011/08/03 03:21:06 jberndt Exp $
     @see
     FGEngine
     FGTank
@@ -164,6 +165,7 @@ public:
 
   std::string GetPropulsionStrings(const std::string& delimiter) const;
   std::string GetPropulsionValues(const std::string& delimiter) const;
+  std::string GetPropulsionTankReport();
 
   const FGColumnVector3& GetForces(void) const {return vForces; }
   double GetForces(int n) const { return vForces(n);}
@@ -184,7 +186,7 @@ public:
   std::ifstream* FindEngineFile(const std::string& filename);
   std::string FindEngineFullPathname(const std::string& engine_filename);
   inline int GetActiveEngine(void) const {return ActiveEngine;}
-  inline bool GetFuelFreeze(void) {return fuel_freeze;}
+  inline bool GetFuelFreeze(void) {return FuelFreeze;}
   double GetTotalFuelQuantity(void) const {return TotalFuelQuantity;}
 
   void SetMagnetos(int setting);
@@ -194,6 +196,8 @@ public:
   void SetFuelFreeze(bool f);
   FGMatrix33& CalculateTankInertias(void);
 
+  struct FGEngine::Inputs in;
+
 private:
   std::vector <FGEngine*>   Engines;
   std::vector <FGTank*>     Tanks;
@@ -211,7 +215,7 @@ private:
   FGMatrix33 tankJ;
   bool refuel;
   bool dump;
-  bool fuel_freeze;
+  bool FuelFreeze;
   double TotalFuelQuantity;
   double DumpRate;
   bool IsBound;
@@ -220,6 +224,7 @@ private:
   bool HaveTurboPropEngine;
   bool HaveRocketEngine;
   bool HaveElectricEngine;
+  void ConsumeFuel(FGEngine* engine);
 
   int InitializedEngines;
   bool HasInitializedEngines;
diff --git a/src/FDM/JSBSim/models/Makefile.am b/src/FDM/JSBSim/models/Makefile.am
index 6a7a7e932..ade54931b 100644
--- a/src/FDM/JSBSim/models/Makefile.am
+++ b/src/FDM/JSBSim/models/Makefile.am
@@ -7,12 +7,12 @@ libModels_a_SOURCES = FGAerodynamics.cpp FGAircraft.cpp FGAtmosphere.cpp \
                       FGInertial.cpp FGBuoyantForces.cpp FGExternalForce.cpp \
                       FGLGear.cpp FGMassBalance.cpp FGModel.cpp FGOutput.cpp \
                       FGPropagate.cpp FGPropulsion.cpp FGInput.cpp \
-                      FGExternalReactions.cpp FGGasCell.cpp
+                      FGExternalReactions.cpp FGGasCell.cpp FGAccelerations.cpp
 
 noinst_HEADERS = FGAerodynamics.h FGAircraft.h FGAtmosphere.h FGAuxiliary.h \
                  FGFCS.h FGGroundReactions.h FGInertial.h FGLGear.h \
                  FGMassBalance.h FGBuoyantForces.h FGExternalForce.h \
                  FGModel.h FGOutput.h FGPropagate.h FGPropulsion.h FGInput.h \
-                 FGExternalReactions.h FGGasCell.h
+                 FGExternalReactions.h FGGasCell.h FGAccelerations.h
 
 INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp b/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
index 23f185f12..429a5cbb3 100755
--- a/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
@@ -66,7 +66,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.18 2011/06/21 13:54:40 jberndt Exp $";
 static const char *IdHdr = ID_MSIS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -140,16 +140,16 @@ bool MSIS::InitModel(void)
   input.f107 = 150.0;
   input.ap = 4.0;
 
-  UseInternal();
+//  UseInternal();
 
-  SLtemperature = intTemperature = 518.0;
-  SLpressure    = intPressure = 2116.7;
-  SLdensity     = intDensity = 0.002378;
-  SLsoundspeed  = sqrt(2403.0832 * SLtemperature);
-  rSLtemperature = 1.0/intTemperature;
-  rSLpressure    = 1.0/intPressure;
-  rSLdensity     = 1.0/intDensity;
-  rSLsoundspeed  = 1.0/SLsoundspeed;
+//  SLtemperature = intTemperature = 518.0;
+//  SLpressure    = intPressure = 2116.7;
+//  SLdensity     = intDensity = 0.002378;
+//  SLsoundspeed  = sqrt(2403.0832 * SLtemperature);
+//  rSLtemperature = 1.0/intTemperature;
+//  rSLpressure    = 1.0/intPressure;
+//  rSLdensity     = 1.0/intDensity;
+//  rSLsoundspeed  = 1.0/SLsoundspeed;
 
   return true;
 }
@@ -163,10 +163,10 @@ bool MSIS::Run(bool Holding)
 
   RunPreFunctions();
 
-  h = FDMExec->GetPropagate()->GetAltitudeASL();
+  double h = FDMExec->GetPropagate()->GetAltitudeASL();
 
   //do temp, pressure, and density first
-  if (!useExternal) {
+//  if (!useExternal) {
     // get sea-level values
     Calculate(FDMExec->GetAuxiliary()->GetDayOfYear(),
               FDMExec->GetAuxiliary()->GetSecondsInDay(),
@@ -188,14 +188,12 @@ bool MSIS::Run(bool Holding)
               h,
               FDMExec->GetPropagate()->GetLocation().GetLatitudeDeg(),
               FDMExec->GetPropagate()->GetLocation().GetLongitudeDeg());
-    intTemperature = output.t[1] * 1.8;
-    intDensity     = output.d[5] * 1.940321;
-    intPressure    = 1716.488 * intDensity * intTemperature;
+//    intTemperature = output.t[1] * 1.8;
+//    intDensity     = output.d[5] * 1.940321;
+//    intPressure    = 1716.488 * intDensity * intTemperature;
     //cout << "T=" << intTemperature << " D=" << intDensity << " P=";
     //cout << intPressure << " a=" << soundspeed << endl;
-  }
-
-  CalculateDerived();
+//  }
 
   RunPostFunctions();
 
@@ -1660,16 +1658,6 @@ void MSIS::Debug(int from)
   if (debug_lvl & 16) { // Sanity checking
   }
   if (debug_lvl & 32) { // Turbulence
-    if (first_pass && from == 2) {
-      cout << "vTurbulenceNED(X), vTurbulenceNED(Y), vTurbulenceNED(Z), "
-           << "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
-           << "vDirection(X), vDirection(Y), vDirection(Z), "
-           << "Magnitude, "
-           << "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
-    }
-    if (from == 2) {
-      cout << vTurbulenceNED << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
-    }
   }
   if (debug_lvl & 64) {
     if (from == 0) { // Constructor
diff --git a/src/FDM/JSBSim/models/atmosphere/FGMars.cpp b/src/FDM/JSBSim/models/atmosphere/FGMars.cpp
old mode 100644
new mode 100755
index 93c388f5f..28673d3c8
--- a/src/FDM/JSBSim/models/atmosphere/FGMars.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGMars.cpp
@@ -48,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGMars.cpp,v 1.10 2010/02/25 05:21:36 jberndt Exp $";
+static const char *IdSrc = "$Id: FGMars.cpp,v 1.11 2011/06/21 13:54:40 jberndt Exp $";
 static const char *IdHdr = ID_MARS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -74,12 +74,12 @@ void FGMars::Calculate(double altitude)
   // LIMIT the temperatures so they do not descend below absolute zero.
 
   if (altitude < 22960.0) {
-    intTemperature = -25.68 - 0.000548*altitude; // Deg Fahrenheit
+    Temperature = -25.68 - 0.000548*altitude; // Deg Fahrenheit
   } else {
-    intTemperature = -10.34 - 0.001217*altitude; // Deg Fahrenheit
+    Temperature = -10.34 - 0.001217*altitude; // Deg Fahrenheit
   }
-  intPressure = 14.62*exp(-0.00003*altitude); // psf - 14.62 psf =~ 7 millibars
-  intDensity = intPressure/(Reng*intTemperature); // slugs/ft^3 (needs deg R. as input
+  Pressure = 14.62*exp(-0.00003*altitude); // psf - 14.62 psf =~ 7 millibars
+  Density = Pressure/(Reng*Temperature); // slugs/ft^3 (needs deg R. as input
 
   //cout << "Atmosphere:  h=" << altitude << " rho= " << intDensity << endl;
 }
@@ -122,15 +122,6 @@ void FGMars::Debug(int from)
   if (debug_lvl & 16) { // Sanity checking
   }
   if (debug_lvl & 32) { // Turbulence
-    if (first_pass && from == 2) {
-      cout << "vTurbulenceNED(X), vTurbulenceNED(Y), vTurbulenceNED(Z), "
-           << "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
-           << "vDirection(X), vDirection(Y), vDirection(Z), "
-           << "Magnitude, "
-           << "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
-    } else if (from == 2) {
-      cout << vTurbulenceNED << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
-    }
   }
   if (debug_lvl & 64) {
     if (from == 0) { // Constructor
diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
index ab0011c7f..5c8d93c87 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
@@ -50,20 +50,16 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.9 2011/06/13 12:06:29 jberndt Exp $";
+static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.18 2011/08/17 23:56:01 jberndt Exp $";
 static const char *IdHdr = ID_STANDARDATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
+FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGAtmosphere(fdmex),
                                                                TemperatureDeltaGradient(0.0),
-                                                               TemperatureBias(0.0),
-                                                               PressureAltitude(0.0),      // ft
-                                                               DensityAltitude(0.0),       // ft
-                                                               SutherlandConstant(198.72), // deg Rankine
-                                                               Beta(2.269690E-08)          // slug/(sec ft R^0.5)
+                                                               TemperatureBias(0.0)
 {
   Name = "FGStandardAtmosphere";
 
@@ -102,6 +98,7 @@ FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
 
 FGStandardAtmosphere::~FGStandardAtmosphere()
 {
+  delete StdAtmosTemperatureTable;
   LapseRateVector.clear();
   Debug(1);
 }
@@ -131,38 +128,6 @@ bool FGStandardAtmosphere::InitModel(void)
   return true;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-bool FGStandardAtmosphere::Run(bool Holding)
-{
-  if (FGModel::Run(Holding)) return true;
-  if (Holding) return false;
-
-  RunPreFunctions();
-
-  double altitude = FDMExec->GetPropagate()->GetAltitudeASL();
-
-  Calculate(altitude);
-
-  RunPostFunctions();
-
-  Debug(2);
-  return false;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGStandardAtmosphere::Calculate(double altitude)
-{
-  Temperature = GetTemperature(altitude);
-  Pressure = GetPressure(altitude);
-  Density     = Pressure/(Reng*Temperature);
-  Soundspeed  = sqrt(SHRatio*Reng*(Temperature));
-
-  Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
-  KinematicViscosity = Viscosity / Density;
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Get the actual pressure as modeled at a specified altitude
 // These calculations are from equations 33a and 33b in the U.S. Standard Atmosphere
@@ -173,6 +138,7 @@ double FGStandardAtmosphere::GetPressure(double altitude) const
   unsigned int b=0;
   double pressure = 0.0;
   double Lmb, Exp, Tmb, deltaH, factor;
+  double numRows = StdAtmosTemperatureTable->GetNumRows();
 
   // Iterate through the altitudes to find the current Base Altitude
   // in the table. That is, if the current altitude (the argument passed in)
@@ -180,9 +146,8 @@ double FGStandardAtmosphere::GetPressure(double altitude) const
   // passed-in altitude is 40000 ft, the base altitude is 36151.6 ft (and
   // the index "b" is 2 - the second entry in the table).
   double testAlt = (*StdAtmosTemperatureTable)(b+1,0);
-  while (altitude >= testAlt) {
+  while ((altitude >= testAlt) && (b <= numRows-2)) {
     b++;
-    if (b+1 > StdAtmosTemperatureTable->GetNumRows()) break;
     testAlt = (*StdAtmosTemperatureTable)(b+1,0);
   }
   if (b>0) b--;
@@ -205,7 +170,7 @@ double FGStandardAtmosphere::GetPressure(double altitude) const
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGStandardAtmosphere::SetSeaLevelPressure(double pressure, ePressure unit)
+void FGStandardAtmosphere::SetPressureSL(double pressure, ePressure unit)
 {
   double press = ConvertToPSF(pressure, unit);
 
@@ -285,30 +250,21 @@ double FGStandardAtmosphere::GetStdPressure100K(double altitude) const
   // Limit this equation to input altitudes of 100000 ft.
   if (altitude > 100000.0) altitude = 100000.0;
 
-  double alt[6];
-  double coef[6] = { 2116.22,
-                    -7.583514352598E-02,
-                     1.045494405501E-06,
-                    -5.881341527124E-12,
-                     3.482031690718E-18,
-                     5.683922549284E-23 };
+  double alt[5];
+  const double coef[5] = {  2116.217,
+                          -7.648932746E-2,
+                           1.0925498604E-6,
+                          -7.1135726027E-12,
+                           1.7470331356E-17 };
 
   alt[0] = 1;
-  for (int pwr=1; pwr<=5; pwr++) alt[pwr] = alt[pwr-1]*altitude;
+  for (int pwr=1; pwr<=4; pwr++) alt[pwr] = alt[pwr-1]*altitude;
 
   double press = 0.0;
-  for (int ctr=0; ctr<=5; ctr++) press += coef[ctr]*alt[ctr];
+  for (int ctr=0; ctr<=4; ctr++) press += coef[ctr]*alt[ctr];
   return press;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// Get the modeled density at a specified altitude
-
-double FGStandardAtmosphere::GetDensity(double altitude) const
-{
-  return GetPressure(altitude)/(Reng * GetTemperature(altitude));
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Get the standard density at a specified altitude
 
@@ -319,9 +275,23 @@ double FGStandardAtmosphere::GetStdDensity(double altitude) const
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGStandardAtmosphere::SetTemperatureBias(double t, eTemperature unit)
+void FGStandardAtmosphere::SetTemperature(double t, double h, eTemperature unit)
 {
-  TemperatureBias = ConvertToRankine(t, unit);
+  double targetSLtemp = ConvertToRankine(t, unit);
+
+  TemperatureBias = 0.0;
+  TemperatureBias = targetSLtemp - GetTemperature(h);
+  CalculatePressureBreakpoints();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGStandardAtmosphere::SetTemperatureBias(eTemperature unit, double t)
+{
+  if (unit == eCelsius || unit == eKelvin)
+    t *= 1.80; // If temp delta "t" is given in metric, scale up to English
+
+  TemperatureBias = t;
   CalculatePressureBreakpoints();
 }
 
@@ -331,18 +301,15 @@ void FGStandardAtmosphere::SetTemperatureBias(double t, eTemperature unit)
 // Internally, the Rankine scale is used for calculations, so any temperature
 // supplied must be converted to that unit.
 
-void FGStandardAtmosphere::SetSLTemperature(double t, eTemperature unit)
+void FGStandardAtmosphere::SetTemperatureSL(double t, eTemperature unit)
 {
-  double targetSLtemp = ConvertToRankine(t, unit);
-
-  TemperatureBias = targetSLtemp - GetStdTemperatureSL();
-  CalculatePressureBreakpoints();
+  SetTemperature(t, 0.0, unit);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Sets a Sea Level temperature delta that is ramped out by 86 km (282,152 ft).
 
-void FGStandardAtmosphere::SetSLTemperatureGradedDelta(double deltemp, eTemperature unit)
+void FGStandardAtmosphere::SetSLTemperatureGradedDelta(eTemperature unit, double deltemp)
 {
   SetTemperatureGradedDelta(deltemp, 0.0, unit);
 }
@@ -356,12 +323,9 @@ void FGStandardAtmosphere::SetSLTemperatureGradedDelta(double deltemp, eTemperat
 
 void FGStandardAtmosphere::SetTemperatureGradedDelta(double deltemp, double h, eTemperature unit)
 {
-  switch(unit) {
-  case eCelsius:
-  case eKelvin:
-    deltemp *= 9.0/5.0; // If temp delta is given in metric, scale up to English
-    break;
-  }
+  if (unit == eCelsius || unit == eKelvin)
+    deltemp *= 1.80; // If temp delta "t" is given in metric, scale up to English
+
   TemperatureDeltaGradient = deltemp/(GradientFadeoutAltitude - h);
   CalculateLapseRates();
   CalculatePressureBreakpoints();
@@ -376,7 +340,7 @@ void FGStandardAtmosphere::SetTemperatureGradedDelta(double deltemp, double h, e
   for (int i=0; i<280000; i+=1000) {
     Calculate(i);
     std::cout  << std::setw(12) << std::setprecision(2) << i
-       << "  " << std::setw(9)  << std::setprecision(2) << Temperature-459.67
+       << "  " << std::setw(9)  << std::setprecision(2) << Temperature - 459.67
        << "  " << std::setw(13) << std::setprecision(4) << Pressure
        << "  " << std::setw(18) << std::setprecision(8) << Density
        << std::endl;
@@ -447,75 +411,16 @@ void FGStandardAtmosphere::ResetSLPressure()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGStandardAtmosphere::ConvertToRankine(double t, eTemperature unit) const
-{
-  double targetTemp=0; // in degrees Rankine
-
-  switch(unit) {
-  case eFahrenheit:
-    targetTemp = t + 459.67;
-    break;
-  case eCelsius:
-    targetTemp = t*9.0/5.0 + 32.0 + 459.67;
-    break;
-  case eRankine:
-    targetTemp = t;
-    break;
-  case eKelvin:
-    targetTemp = t*9.0/5.0;
-  }
-
-  return targetTemp;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-double FGStandardAtmosphere::ConvertToPSF(double p, ePressure unit) const
-{
-  double targetPressure=0; // Pressure in PSF
-
-  switch(unit) {
-  case ePSF:
-    targetPressure = p;
-    break;
-  case eMillibars:
-    targetPressure = p*2.08854342;
-    break;
-  case ePascals:
-    targetPressure = p*0.0208854342;
-    break;
-  case eInchesHg:
-    targetPressure = p*70.7180803;
-    break;
-  default:
-    throw("Undefined pressure unit given");
-  }
-
-  return targetPressure;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGStandardAtmosphere::bind(void)
 {
   typedef double (FGStandardAtmosphere::*PMFi)(int) const;
   typedef void (FGStandardAtmosphere::*PMF)(int, double);
-  PropertyManager->Tie("stdatmosphere/T-R", this, &FGStandardAtmosphere::GetTemperature);
-  PropertyManager->Tie("stdatmosphere/rho-slugs_ft3", this, &FGStandardAtmosphere::GetDensity);
-  PropertyManager->Tie("stdatmosphere/P-psf", this, &FGStandardAtmosphere::GetPressure);
-  PropertyManager->Tie("stdatmosphere/a-fps", this, &FGStandardAtmosphere::GetSoundSpeed);
-  PropertyManager->Tie("stdatmosphere/T-sl-R", this, &FGStandardAtmosphere::GetTemperatureSL);
-  PropertyManager->Tie("stdatmosphere/rho-sl-slugs_ft3", this, &FGStandardAtmosphere::GetDensitySL);
-  PropertyManager->Tie("stdatmosphere/P-sl-psf", this, &FGStandardAtmosphere::GetPressureSL);
-  PropertyManager->Tie("stdatmosphere/a-sl-fps", this, &FGStandardAtmosphere::GetSoundSpeedSL);
-  PropertyManager->Tie("stdatmosphere/theta", this, &FGStandardAtmosphere::GetTemperatureRatio);
-  PropertyManager->Tie("stdatmosphere/sigma", this, &FGStandardAtmosphere::GetDensityRatio);
-  PropertyManager->Tie("stdatmosphere/delta", this, &FGStandardAtmosphere::GetPressureRatio);
-  PropertyManager->Tie("stdatmosphere/a-ratio", this, &FGStandardAtmosphere::GetSoundSpeedRatio);
-  PropertyManager->Tie("stdatmosphere/delta-T", this, eRankine,
+  PropertyManager->Tie("atmosphere/delta-T", this, eRankine,
                                     (PMFi)&FGStandardAtmosphere::GetTemperatureBias,
                                     (PMF)&FGStandardAtmosphere::SetTemperatureBias);
-//  PropertyManager->Tie("atmosphere/density-altitude", this, &FGStandardAtmosphere::GetDensityAltitude);
+  PropertyManager->Tie("atmosphere/SL-graded-delta-T", this, eRankine,
+                                    (PMFi)&FGStandardAtmosphere::GetTemperatureDeltaGradient,
+									(PMF)&FGStandardAtmosphere::SetSLTemperatureGradedDelta);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
index 07978941e..380550ade 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
+++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
@@ -39,14 +39,14 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include <vector>
-#include "models/FGModel.h"
 #include "math/FGTable.h"
+#include "models/FGAtmosphere.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $"
+#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.15 2011/08/17 23:56:01 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -88,51 +88,26 @@ and/or the sea level standard pressure, so that the entire profile will be
 consistently and accurately calculated.
 
   <h2> Properties </h2>
-  @property atmosphere/T-R The current modeled temperature in degrees Rankine.
-  @property atmosphere/rho-slugs_ft3
-  @property atmosphere/P-psf
-  @property atmosphere/a-fps
-  @property atmosphere/T-sl-R
-  @property atmosphere/rho-sl-slugs_ft3
-  @property atmosphere/P-sl-psf
-  @property atmosphere/a-sl-fps
-  @property atmosphere/theta
-  @property atmosphere/sigma
-  @property atmosphere/delta
-  @property atmosphere/a-ratio
   @property atmosphere/delta-T
   @property atmosphere/T-sl-dev-F
 
   @author Jon Berndt
   @see "U.S. Standard Atmosphere, 1976", NASA TM-X-74335
-  @version $Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $
+  @version $Id: FGStandardAtmosphere.h,v 1.15 2011/08/17 23:56:01 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGStandardAtmosphere : public FGModel {
+class FGStandardAtmosphere : public FGAtmosphere {
 public:
-
-  /// Enums for specifying temperature units.
-  enum eTemperature {eNoTempUnit=0, eFahrenheit, eCelsius, eRankine, eKelvin};
-
-  /// Enums for specifying pressure units.
-  enum ePressure {eNoPressUnit=0, ePSF, eMillibars, ePascals, eInchesHg};
-
   /// Constructor
   FGStandardAtmosphere(FGFDMExec*);
+
   /// Destructor
-  ~FGStandardAtmosphere();
-  /** Runs the standard atmosphere forces model; called by the Executive.
-      Can pass in a value indicating if the executive is directing the simulation to Hold.
-      @param Holding if true, the executive has been directed to hold the sim from 
-                     advancing time. Some models may ignore this flag, such as the Input
-                     model, which may need to be active to listen on a socket for the
-                     "Resume" command to be given.
-      @return false if no error */
-  bool Run(bool Holding);
+  virtual ~FGStandardAtmosphere();
+
   bool InitModel(void);
 
   //  *************************************************************************
@@ -145,19 +120,11 @@ public:
   /// at sea level can also be retrieved. These two temperatures DO include the
   /// effects of an optionally user-supplied bias or delta gradient.
   // @{
-  /// Returns the actual, modeled temperature at the current altitude in degrees Rankine.
-  /// @return Modeled temperature in degrees Rankine.
-  virtual double GetTemperature() const {return Temperature;}
-
   /// Returns the actual modeled temperature in degrees Rankine at a specified altitude.
   /// @param altitude The altitude above sea level (ASL) in feet.
   /// @return Modeled temperature in degrees Rankine at the specified altitude.
   virtual double GetTemperature(double altitude) const;
 
-  /// Returns the actual, modeled sea level temperature in degrees Rankine.
-  /// @return The modeled temperature in degrees Rankine at sea level.
-  virtual double GetTemperatureSL() const { return GetTemperature(0.0); }
-
   /// Returns the standard temperature in degrees Rankine at a specified altitude.
   /// @param altitude The altitude in feet above sea level (ASL) to get the temperature at.
   /// @return The STANDARD temperature in degrees Rankine at the specified altitude.
@@ -167,14 +134,6 @@ public:
   /// @return The STANDARD temperature at sea level in degrees Rankine.
   virtual double GetStdTemperatureSL() const { return GetStdTemperature(0.0); }
 
-  /// Returns the ratio of the at-current-altitude temperature as modeled
-  /// over the standard sea level value.
-  virtual double GetTemperatureRatio() const { return GetTemperature()*rSLtemperature; }
-
-  /// Returns the ratio of the temperature as modeled at the supplied altitude
-  /// over the standard sea level value.
-  virtual double GetTemperatureRatio(double h) const { return GetTemperature(h)*rSLtemperature; }
-
   /// Returns the ratio of the standard temperature at the supplied altitude 
   /// over the standard sea level temperature.
   virtual double GetStdTemperatureRatio(double h) const { return GetStdTemperature(h)*rSLtemperature; }
@@ -194,17 +153,20 @@ public:
   /// this function.
   /// @param t the temperature value in the unit provided.
   /// @param unit the unit of the temperature.
-  virtual void SetSLTemperature(double t, eTemperature unit=eFahrenheit);
+  virtual void SetTemperatureSL(double t, eTemperature unit=eFahrenheit);
 
   /// Sets the temperature at the supplied altitude, if it is to be different
   /// than the standard temperature.
   /// This function will calculate a bias - a difference - from the standard
   /// atmosphere temperature at the supplied altitude and will apply that
-  /// calculated bias to the entire temperature profile.
+  /// calculated bias to the entire temperature profile. If a graded delta is
+  /// present, that will be included in the calculation - that is, regardless
+  /// of any graded delta present, a temperature bias will be determined so that
+  /// the temperature requested in this function call will be reached.
   /// @param t The temperature value in the unit provided.
   /// @param h The altitude in feet above sea level.
   /// @param unit The unit of the temperature.
-  virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit) {};
+  virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit);
 
   /// Sets the temperature bias to be added to the standard temperature at all altitudes.
   /// This function sets the bias - the difference - from the standard
@@ -214,7 +176,7 @@ public:
   /// this function with a calculated bias.
   /// @param t the temperature value in the unit provided.
   /// @param unit the unit of the temperature.
-  virtual void SetTemperatureBias(double t, eTemperature unit=eFahrenheit);
+  virtual void SetTemperatureBias(eTemperature unit, double t);
 
   /// Sets a Sea Level temperature delta that is ramped out by 86 km.
   /// The value of the delta is used to calculate a delta gradient that is
@@ -229,7 +191,7 @@ public:
   /// temperature profile as desired.
   /// @param t the sea level temperature delta value in the unit provided.
   /// @param unit the unit of the temperature.
-  virtual void SetSLTemperatureGradedDelta(double t, eTemperature unit=eFahrenheit);
+  virtual void SetSLTemperatureGradedDelta(eTemperature unit, double t);
 
   /// Sets the temperature delta value at the supplied altitude/elevation above
   /// sea level, to be added to the standard temperature and ramped out by
@@ -250,9 +212,6 @@ public:
   //  *************************************************************************
   /// @name Pressure access functions.
   //@{
-  /// Returns the pressure in psf.
-  virtual double GetPressure(void)  const {return Pressure;}
-
   /// Returns the pressure at a specified altitude in psf.
   virtual double GetPressure(double altitude) const;
 
@@ -262,19 +221,13 @@ public:
   /// Returns the standard pressure at the specified altitude.
   virtual double GetStdPressure(double altitude) const;
 
-  /// Returns the sea level pressure in psf.
-  virtual double GetPressureSL(void) const { return SLpressure; }
-
-  /// Returns the ratio of at-altitude pressure over the sea level value.
-  virtual double GetPressureRatio(void) const { return Pressure*rSLpressure; }
-
   /** Sets the sea level pressure for modeling an off-standard pressure
       profile. This could be useful in the case where the pressure at an
       airfield is known or set for a particular simulation run.
       @param pressure The pressure in the units specified (PSF by default).
       @param unit the unit of measure that the specified pressure is
                        supplied in.*/
-  virtual void SetSeaLevelPressure(double pressure, ePressure unit=ePSF);
+  virtual void SetPressureSL(double pressure, ePressure unit=ePSF);
 
   /** Resets the sea level to the Standard sea level pressure, and recalculates
       dependent parameters so that the pressure calculations are standard. */
@@ -284,60 +237,15 @@ public:
   //  *************************************************************************
   /// @name Density access functions.
   //@{
-  /** Returns the density in slugs/ft^3.
-      This function may only be used if Run() is called first. */
-  virtual double GetDensity(void)  const {return Density;}
-
-  /** Returns the density in slugs/ft^3 at a given altitude in ft. */
-  virtual double GetDensity(double altitude) const;
-
   /// Returns the standard density at a specified altitude
   virtual double GetStdDensity(double altitude) const;
-
-  /// Returns the sea level density in slugs/ft^3
-  virtual double GetDensitySL(void)  const { return SLdensity; }
-
-  /// Returns the ratio of at-altitude density over the sea level value.
-  virtual double GetDensityRatio(void) const { return Density*rSLdensity; }
   //@}
 
-  //  *************************************************************************
-  /// @name Speed of sound access functions.
-  //@{
-  /// Returns the speed of sound in ft/sec.
-  virtual double GetSoundSpeed(void) const {return Soundspeed;}
-
-  /// Returns the sea level speed of sound in ft/sec.
-  virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; }
-
-  /// Returns the ratio of at-altitude sound speed over the sea level value.
-  virtual double GetSoundSpeedRatio(void) const { return Soundspeed*rSLsoundspeed; }
-  //@}
-
-  //  *************************************************************************
-  /// @name Viscosity access functions.
-  //@{
-  /// Returns the absolute viscosity.
-  virtual double GetAbsoluteViscosity(void) const {return Viscosity;}
-
-  /// Returns the kinematic viscosity.
-  virtual double GetKinematicViscosity(void) const {return KinematicViscosity;}
-  //@}
-
-  /* /// Gets the density altitude in feet */
-//  virtual double GetDensityAltitude(void) const { return density_altitude; }
-
   /// Prints the U.S. Standard Atmosphere table.
   virtual void PrintStandardAtmosphereTable();
 
 protected:
   double StdSLtemperature, StdSLdensity, StdSLpressure, StdSLsoundspeed; // Standard sea level conditions
-  double    SLtemperature,    SLdensity,    SLpressure,    SLsoundspeed; // Sea level conditions
-  double      Temperature,      Density,      Pressure,      Soundspeed; // Current actual conditions at altitude
-  double   rSLtemperature,   rSLdensity,   rSLpressure,   rSLsoundspeed; // Reciprocal of sea level conditions
-
-  double PressureAltitude;
-  double DensityAltitude;
 
   double TemperatureBias;
   double TemperatureDeltaGradient;
@@ -347,12 +255,6 @@ protected:
   std::vector<double> LapseRateVector;
   std::vector<double> PressureBreakpointVector;
 
-  const double SutherlandConstant, Beta;
-  double Viscosity, KinematicViscosity;
-
-  /// Calculate the atmosphere for the given altitude, including effects of temperature deviation.
-  void Calculate(double altitude);
-
   /// Recalculate the lapse rate vectors when the temperature profile is altered
   /// in a way that would change the lapse rates, such as when a gradient is applied.
   /// This function is also called to initialize the lapse rate vector.
@@ -362,12 +264,6 @@ protected:
   /// altitudes in the standard temperature table.
   void CalculatePressureBreakpoints();
 
-  // Converts to Rankine from one of several unit systems.
-  virtual double ConvertToRankine(double t, eTemperature unit) const;
-  
-  // Converts to PSF (pounds per square foot) from one of several unit systems.
-  virtual double ConvertToPSF(double t, ePressure unit=ePSF) const;
-
   virtual void bind(void);
   void Debug(int from);
 };
diff --git a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
new file mode 100644
index 000000000..d6c55afde
--- /dev/null
+++ b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
@@ -0,0 +1,553 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Module:       FGWinds.cpp
+ Author:       Jon Berndt, Tony Peden, Andreas Gaeb
+ Date started: Extracted from FGAtmosphere, which originated in 1998
+               5/2011
+ Purpose:      Models winds, gusts, turbulence, and other atmospheric disturbances
+ Called by:    FGFDMExec
+
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser 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 Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+HISTORY
+--------------------------------------------------------------------------------
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES,  and NOTES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+[1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
+      1989, ISBN 0-07-001641-0
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <iostream>
+#include <cstdlib>
+#include "FGWinds.h"
+#include "FGFDMExec.h"
+
+using namespace std;
+
+namespace JSBSim {
+
+static const char *IdSrc = "$Id: FGWinds.cpp,v 1.4 2011/09/07 02:37:04 jberndt Exp $";
+static const char *IdHdr = ID_WINDS;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS IMPLEMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// square a value, but preserve the original sign
+
+static inline double square_signed (double value)
+{
+    if (value < 0)
+        return value * value * -1;
+    else
+        return value * value;
+}
+
+/// simply square a value
+static inline double sqr(double x) { return x*x; }
+
+FGWinds::FGWinds(FGFDMExec* fdmex) : FGModel(fdmex)
+{
+  Name = "FGWinds";
+
+  MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
+  SetTurbType( ttMilspec );
+  TurbGain = 1.0;
+  TurbRate = 10.0;
+  Rhythmicity = 0.1;
+  spike = target_time = strength = 0.0;
+  wind_from_clockwise = 0.0;
+  psiw = 0.0;
+
+  vGustNED.InitMatrix();
+  vTurbulenceNED.InitMatrix();
+
+  // Milspec turbulence model
+  windspeed_at_20ft = 0.;
+  probability_of_exceedence_index = 0;
+  POE_Table = new FGTable(7,12);
+  // this is Figure 7 from p. 49 of MIL-F-8785C
+  // rows: probability of exceedance curve index, cols: altitude in ft
+  *POE_Table
+           << 500.0 << 1750.0 << 3750.0 << 7500.0 << 15000.0 << 25000.0 << 35000.0 << 45000.0 << 55000.0 << 65000.0 << 75000.0 << 80000.0
+    << 1   <<   3.2 <<    2.2 <<    1.5 <<    0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
+    << 2   <<   4.2 <<    3.6 <<    3.3 <<    1.6 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
+    << 3   <<   6.6 <<    6.9 <<    7.4 <<    6.7 <<     4.6 <<     2.7 <<     0.4 <<     0.0 <<     0.0 <<     0.0 <<     0.0 <<     0.0
+    << 4   <<   8.6 <<    9.6 <<   10.6 <<   10.1 <<     8.0 <<     6.6 <<     5.0 <<     4.2 <<     2.7 <<     0.0 <<     0.0 <<     0.0
+    << 5   <<  11.8 <<   13.0 <<   16.0 <<   15.1 <<    11.6 <<     9.7 <<     8.1 <<     8.2 <<     7.9 <<     4.9 <<     3.2 <<     2.1
+    << 6   <<  15.6 <<   17.6 <<   23.0 <<   23.6 <<    22.1 <<    20.0 <<    16.0 <<    15.1 <<    12.1 <<     7.9 <<     6.2 <<     5.1
+    << 7   <<  18.7 <<   21.5 <<   28.4 <<   30.2 <<    30.7 <<    31.0 <<    25.2 <<    23.1 <<    17.5 <<    10.7 <<     8.4 <<     7.2;
+
+  bind();
+  Debug(0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGWinds::~FGWinds()
+{
+  delete(POE_Table);
+  Debug(1);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGWinds::InitModel(void)
+{
+  return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGWinds::Run(bool Holding)
+{
+  if (FGModel::Run(Holding)) return true;
+  if (Holding) return false;
+
+  RunPreFunctions();
+
+  if (turbType != ttNone) Turbulence(in.AltitudeASL);
+  if (oneMinusCosineGust.gustProfile.Running) CosineGust();
+
+  vTotalWindNED = vWindNED + vGustNED + vCosineGust + vTurbulenceNED;
+
+   // psiw (Wind heading) is the direction the wind is blowing towards
+  if (vWindNED(eX) != 0.0) psiw = atan2( vWindNED(eY), vWindNED(eX) );
+  if (psiw < 0) psiw += 2*M_PI;
+
+  RunPostFunctions();
+
+  Debug(2);
+  return false;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// psi is the angle that the wind is blowing *towards*
+
+void FGWinds::SetWindspeed(double speed)
+{
+  if (vWindNED.Magnitude() == 0.0) {
+    psiw = 0.0;
+    vWindNED(eNorth) = speed;
+  } else {
+    vWindNED(eNorth) = speed * cos(psiw);
+    vWindNED(eEast) = speed * sin(psiw);
+    vWindNED(eDown) = 0.0;
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGWinds::GetWindspeed(void) const
+{
+  return vWindNED.Magnitude();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// psi is the angle that the wind is blowing *towards*
+
+void FGWinds::SetWindPsi(double dir)
+{
+  double mag = GetWindspeed();
+  psiw = dir;
+  SetWindspeed(mag);  
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGWinds::Turbulence(double h)
+{
+  switch (turbType) {
+
+  case ttCulp: { 
+
+    vTurbPQR(eP) = wind_from_clockwise;
+    if (TurbGain == 0.0) return;
+  
+    // keep the inputs within allowable limts for this model
+    if (TurbGain < 0.0) TurbGain = 0.0;
+    if (TurbGain > 1.0) TurbGain = 1.0;
+    if (TurbRate < 0.0) TurbRate = 0.0;
+    if (TurbRate > 30.0) TurbRate = 30.0;
+    if (Rhythmicity < 0.0) Rhythmicity = 0.0;
+    if (Rhythmicity > 1.0) Rhythmicity = 1.0;
+
+    // generate a sine wave corresponding to turbulence rate in hertz
+    double time = FDMExec->GetSimTime();
+    double sinewave = sin( time * TurbRate * 6.283185307 );
+
+    double random = 0.0;
+    if (target_time == 0.0) {
+      strength = random = 1 - 2.0*(double(rand())/double(RAND_MAX));
+      target_time = time + 0.71 + (random * 0.5);
+    }
+    if (time > target_time) {
+      spike = 1.0;
+      target_time = 0.0;
+    }    
+
+    // max vertical wind speed in fps, corresponds to TurbGain = 1.0
+    double max_vs = 40;
+
+    vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
+    double delta = strength * max_vs * TurbGain * (1-Rhythmicity) * spike;
+
+    // Vertical component of turbulence.
+    vTurbulenceNED(3) = sinewave * max_vs * TurbGain * Rhythmicity;
+    vTurbulenceNED(3)+= delta;
+    if (in.DistanceAGL/in.wingspan < 3.0)
+        vTurbulenceNED(3) *= in.DistanceAGL/in.wingspan * 0.3333;
+ 
+    // Yaw component of turbulence.
+    vTurbulenceNED(1) = sin( delta * 3.0 );
+    vTurbulenceNED(2) = cos( delta * 3.0 );
+
+    // Roll component of turbulence. Clockwise vortex causes left roll.
+    vTurbPQR(eP) += delta * 0.04;
+
+    spike = spike * 0.9;
+    break;
+  }
+  case ttMilspec:
+  case ttTustin: {
+
+    // an index of zero means turbulence is disabled
+    // airspeed occurs as divisor in the code below
+    if (probability_of_exceedence_index == 0 || in.V == 0) {
+      vTurbulenceNED(1) = vTurbulenceNED(2) = vTurbulenceNED(3) = 0.0;
+      vTurbPQR(1) = vTurbPQR(2) = vTurbPQR(3) = 0.0;
+      return;
+    }
+
+    // Turbulence model according to MIL-F-8785C (Flying Qualities of Piloted Aircraft)
+    double b_w = in.wingspan, L_u, L_w, sig_u, sig_w;
+
+      if (b_w == 0.) b_w = 30.;
+
+    // clip height functions at 10 ft
+    if (h <= 10.) h = 10;
+
+    // Scale lengths L and amplitudes sigma as function of height
+    if (h <= 1000) {
+      L_u = h/pow(0.177 + 0.000823*h, 1.2); // MIL-F-8785c, Fig. 10, p. 55
+      L_w = h;
+      sig_w = 0.1*windspeed_at_20ft;
+      sig_u = sig_w/pow(0.177 + 0.000823*h, 0.4); // MIL-F-8785c, Fig. 11, p. 56
+    } else if (h <= 2000) {
+      // linear interpolation between low altitude and high altitude models
+      L_u = L_w = 1000 + (h-1000.)/1000.*750.;
+      sig_u = sig_w = 0.1*windspeed_at_20ft
+                    + (h-1000.)/1000.*(POE_Table->GetValue(probability_of_exceedence_index, h) - 0.1*windspeed_at_20ft);
+    } else {
+      L_u = L_w = 1750.; //  MIL-F-8785c, Sec. 3.7.2.1, p. 48
+      sig_u = sig_w = POE_Table->GetValue(probability_of_exceedence_index, h);
+    }
+
+    // keep values from last timesteps
+    // TODO maybe use deque?
+    static double
+      xi_u_km1 = 0, nu_u_km1 = 0,
+      xi_v_km1 = 0, xi_v_km2 = 0, nu_v_km1 = 0, nu_v_km2 = 0,
+      xi_w_km1 = 0, xi_w_km2 = 0, nu_w_km1 = 0, nu_w_km2 = 0,
+      xi_p_km1 = 0, nu_p_km1 = 0,
+      xi_q_km1 = 0, xi_r_km1 = 0;
+
+
+    double
+      T_V = in.totalDeltaT, // for compatibility of nomenclature
+      sig_p = 1.9/sqrt(L_w*b_w)*sig_w, // Yeager1998, eq. (8)
+      sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
+      sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
+      L_p = sqrt(L_w*b_w)/2.6, // eq. (10)
+      tau_u = L_u/in.V, // eq. (6)
+      tau_w = L_w/in.V, // eq. (3)
+      tau_p = L_p/in.V, // eq. (9)
+      tau_q = 4*b_w/M_PI/in.V, // eq. (13)
+      tau_r =3*b_w/M_PI/in.V, // eq. (17)
+      nu_u = GaussianRandomNumber(),
+      nu_v = GaussianRandomNumber(),
+      nu_w = GaussianRandomNumber(),
+      nu_p = GaussianRandomNumber(),
+      xi_u=0, xi_v=0, xi_w=0, xi_p=0, xi_q=0, xi_r=0;
+
+    // values of turbulence NED velocities
+
+    if (turbType == ttTustin) {
+      // the following is the Tustin formulation of Yeager's report
+      double
+        omega_w = in.V/L_w, // hidden in nomenclature p. 3
+        omega_v = in.V/L_u, // this is defined nowhere
+        C_BL  = 1/tau_u/tan(T_V/2/tau_u), // eq. (19)
+        C_BLp = 1/tau_p/tan(T_V/2/tau_p), // eq. (22)
+        C_BLq = 1/tau_q/tan(T_V/2/tau_q), // eq. (24)
+        C_BLr = 1/tau_r/tan(T_V/2/tau_r); // eq. (26)
+
+      // all values calculated so far are strictly positive, except for
+      // the random numbers nu_*. This means that in the code below, all
+      // divisors are strictly positive, too, and no floating point
+      // exception should occur.
+      xi_u = -(1 - C_BL*tau_u)/(1 + C_BL*tau_u)*xi_u_km1
+           + sig_u*sqrt(2*tau_u/T_V)/(1 + C_BL*tau_u)*(nu_u + nu_u_km1); // eq. (18)
+      xi_v = -2*(sqr(omega_v) - sqr(C_BL))/sqr(omega_v + C_BL)*xi_v_km1
+           - sqr(omega_v - C_BL)/sqr(omega_v + C_BL) * xi_v_km2
+           + sig_u*sqrt(3*omega_v/T_V)/sqr(omega_v + C_BL)*(
+                 (C_BL + omega_v/sqrt(3.))*nu_v
+               + 2/sqrt(3.)*omega_v*nu_v_km1
+               + (omega_v/sqrt(3.) - C_BL)*nu_v_km2); // eq. (20) for v
+      xi_w = -2*(sqr(omega_w) - sqr(C_BL))/sqr(omega_w + C_BL)*xi_w_km1
+           - sqr(omega_w - C_BL)/sqr(omega_w + C_BL) * xi_w_km2
+           + sig_w*sqrt(3*omega_w/T_V)/sqr(omega_w + C_BL)*(
+                 (C_BL + omega_w/sqrt(3.))*nu_w
+               + 2/sqrt(3.)*omega_w*nu_w_km1
+               + (omega_w/sqrt(3.) - C_BL)*nu_w_km2); // eq. (20) for w
+      xi_p = -(1 - C_BLp*tau_p)/(1 + C_BLp*tau_p)*xi_p_km1
+           + sig_p*sqrt(2*tau_p/T_V)/(1 + C_BLp*tau_p) * (nu_p + nu_p_km1); // eq. (21)
+      xi_q = -(1 - 4*b_w*C_BLq/M_PI/in.V)/(1 + 4*b_w*C_BLq/M_PI/in.V) * xi_q_km1
+           + C_BLq/in.V/(1 + 4*b_w*C_BLq/M_PI/in.V) * (xi_w - xi_w_km1); // eq. (23)
+      xi_r = - (1 - 3*b_w*C_BLr/M_PI/in.V)/(1 + 3*b_w*C_BLr/M_PI/in.V) * xi_r_km1
+           + C_BLr/in.V/(1 + 3*b_w*C_BLr/M_PI/in.V) * (xi_v - xi_v_km1); // eq. (25)
+
+    } else if (turbType == ttMilspec) {
+      // the following is the MIL-STD-1797A formulation
+      // as cited in Yeager's report
+      xi_u = (1 - T_V/tau_u)  *xi_u_km1 + sig_u*sqrt(2*T_V/tau_u)*nu_u;  // eq. (30)
+      xi_v = (1 - 2*T_V/tau_u)*xi_v_km1 + sig_u*sqrt(4*T_V/tau_u)*nu_v;  // eq. (31)
+      xi_w = (1 - 2*T_V/tau_w)*xi_w_km1 + sig_w*sqrt(4*T_V/tau_w)*nu_w;  // eq. (32)
+      xi_p = (1 - T_V/tau_p)  *xi_p_km1 + sig_p*sqrt(2*T_V/tau_p)*nu_p;  // eq. (33)
+      xi_q = (1 - T_V/tau_q)  *xi_q_km1 + M_PI/4/b_w*(xi_w - xi_w_km1);  // eq. (34)
+      xi_r = (1 - T_V/tau_r)  *xi_r_km1 + M_PI/3/b_w*(xi_v - xi_v_km1);  // eq. (35)
+    }
+
+    // rotate by wind azimuth and assign the velocities
+    double cospsi = cos(psiw), sinpsi = sin(psiw);
+    vTurbulenceNED(1) =  cospsi*xi_u + sinpsi*xi_v;
+    vTurbulenceNED(2) = -sinpsi*xi_u + cospsi*xi_v;
+    vTurbulenceNED(3) = xi_w;
+
+    vTurbPQR(1) =  cospsi*xi_p + sinpsi*xi_q;
+    vTurbPQR(2) = -sinpsi*xi_p + cospsi*xi_q;
+    vTurbPQR(3) = xi_r;
+
+    // vTurbPQR is in the body fixed frame, not NED
+    vTurbPQR = in.Tl2b*vTurbPQR;
+
+    // hand on the values for the next timestep
+    xi_u_km1 = xi_u; nu_u_km1 = nu_u;
+    xi_v_km2 = xi_v_km1; xi_v_km1 = xi_v; nu_v_km2 = nu_v_km1; nu_v_km1 = nu_v;
+    xi_w_km2 = xi_w_km1; xi_w_km1 = xi_w; nu_w_km2 = nu_w_km1; nu_w_km1 = nu_w;
+    xi_p_km1 = xi_p; nu_p_km1 = nu_p;
+    xi_q_km1 = xi_q;
+    xi_r_km1 = xi_r;
+
+  }
+  default:
+    break;
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+double FGWinds::CosineGustProfile(double startDuration, double steadyDuration, double endDuration, double elapsedTime)
+{
+  double factor = 0.0;
+  if (elapsedTime >= 0 && elapsedTime <= startDuration) {
+    factor = (1.0 - cos(M_PI*elapsedTime/startDuration))/2.0;
+  } else if (elapsedTime > startDuration && (elapsedTime <= (startDuration + steadyDuration))) {
+    factor = 1.0;
+  } else if (elapsedTime > (startDuration + steadyDuration) && elapsedTime <= (startDuration + steadyDuration + endDuration)) {
+    factor = (1-cos(M_PI*(1-(elapsedTime-(startDuration + steadyDuration))/endDuration)))/2.0;
+  } else {
+    factor = 0.0;
+  }
+
+  return factor;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGWinds::CosineGust()
+{
+  struct OneMinusCosineProfile& profile = oneMinusCosineGust.gustProfile;
+
+  double factor = CosineGustProfile( profile.startupDuration,
+                                     profile.steadyDuration,
+                                     profile.endDuration,
+                                     profile.elapsedTime);
+  // Normalize the gust wind vector
+  oneMinusCosineGust.vWind.Normalize();
+
+  if (oneMinusCosineGust.vWindTransformed.Magnitude() == 0.0) {
+    switch (oneMinusCosineGust.gustFrame) {
+    case gfBody:
+      oneMinusCosineGust.vWindTransformed = in.Tl2b.Inverse() * oneMinusCosineGust.vWind;
+      break;
+    case gfWind:
+      oneMinusCosineGust.vWindTransformed = in.Tl2b.Inverse() * in.Tw2b * oneMinusCosineGust.vWind;
+      break;
+    case gfLocal:
+      // this is the native frame - and the default.
+      oneMinusCosineGust.vWindTransformed = oneMinusCosineGust.vWind;
+      break;
+    }
+  }
+
+  vCosineGust = factor * oneMinusCosineGust.vWindTransformed * oneMinusCosineGust.magnitude;
+
+  profile.elapsedTime += in.totalDeltaT;
+
+  if (profile.elapsedTime > (profile.startupDuration + profile.steadyDuration + profile.endDuration)) {
+    profile.Running = false;
+    profile.elapsedTime = 0.0;
+    oneMinusCosineGust.vWindTransformed.InitMatrix(0.0);
+    vCosineGust.InitMatrix(0);
+  }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGWinds::bind(void)
+{
+  typedef double (FGWinds::*PMF)(int) const;
+  typedef int (FGWinds::*PMFt)(void) const;
+  typedef void   (FGWinds::*PMFd)(int,double);
+  typedef void   (FGWinds::*PMFi)(int);
+  typedef double (FGWinds::*Ptr)(void) const;
+
+  // User-specified steady, constant, wind properties (local navigational/geographic frame: N-E-D)
+  PropertyManager->Tie("atmosphere/psiw-rad", this, &FGWinds::GetWindPsi, &FGWinds::SetWindPsi);
+  PropertyManager->Tie("atmosphere/wind-north-fps", this, eNorth, (PMF)&FGWinds::GetWindNED,
+                                                          (PMFd)&FGWinds::SetWindNED);
+  PropertyManager->Tie("atmosphere/wind-east-fps",  this, eEast, (PMF)&FGWinds::GetWindNED,
+                                                          (PMFd)&FGWinds::SetWindNED);
+  PropertyManager->Tie("atmosphere/wind-down-fps",  this, eDown, (PMF)&FGWinds::GetWindNED,
+                                                          (PMFd)&FGWinds::SetWindNED);
+  PropertyManager->Tie("atmosphere/wind-mag-fps", this, &FGWinds::GetWindspeed,
+                                                        &FGWinds::SetWindspeed);
+
+  // User-specifieded gust (local navigational/geographic frame: N-E-D)
+  PropertyManager->Tie("atmosphere/gust-north-fps", this, eNorth, (PMF)&FGWinds::GetGustNED,
+                                                          (PMFd)&FGWinds::SetGustNED);
+  PropertyManager->Tie("atmosphere/gust-east-fps",  this, eEast, (PMF)&FGWinds::GetGustNED,
+                                                          (PMFd)&FGWinds::SetGustNED);
+  PropertyManager->Tie("atmosphere/gust-down-fps",  this, eDown, (PMF)&FGWinds::GetGustNED,
+                                                          (PMFd)&FGWinds::SetGustNED);
+  
+  // User-specified 1 - cosine gust parameters (in specified frame)
+  PropertyManager->Tie("atmosphere/cosine-gust/startup-duration-sec", this, (Ptr)0L, &FGWinds::StartupGustDuration);
+  PropertyManager->Tie("atmosphere/cosine-gust/steady-duration-sec", this, (Ptr)0L, &FGWinds::SteadyGustDuration);
+  PropertyManager->Tie("atmosphere/cosine-gust/end-duration-sec", this, (Ptr)0L, &FGWinds::EndGustDuration);
+  PropertyManager->Tie("atmosphere/cosine-gust/magnitude-ft_sec", this, (Ptr)0L, &FGWinds::GustMagnitude);
+  PropertyManager->Tie("atmosphere/cosine-gust/frame", this, (PMFt)0L, (PMFi)&FGWinds::GustFrame);
+  PropertyManager->Tie("atmosphere/cosine-gust/X-velocity-ft_sec", this, (Ptr)0L, &FGWinds::GustXComponent);
+  PropertyManager->Tie("atmosphere/cosine-gust/Y-velocity-ft_sec", this, (Ptr)0L, &FGWinds::GustYComponent);
+  PropertyManager->Tie("atmosphere/cosine-gust/Z-velocity-ft_sec", this, (Ptr)0L, &FGWinds::GustZComponent);
+  PropertyManager->Tie("atmosphere/cosine-gust/start", this, (PMFt)0L, (PMFi)&FGWinds::StartGust);
+
+  // User-specified turbulence (local navigational/geographic frame: N-E-D)
+  PropertyManager->Tie("atmosphere/turb-north-fps", this, eNorth, (PMF)&FGWinds::GetTurbNED,
+                                                          (PMFd)&FGWinds::SetTurbNED);
+  PropertyManager->Tie("atmosphere/turb-east-fps",  this, eEast, (PMF)&FGWinds::GetTurbNED,
+                                                          (PMFd)&FGWinds::SetTurbNED);
+  PropertyManager->Tie("atmosphere/turb-down-fps",  this, eDown, (PMF)&FGWinds::GetTurbNED,
+                                                          (PMFd)&FGWinds::SetTurbNED);
+  // Experimental turbulence parameters
+  PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1, (PMF)&FGWinds::GetTurbPQR);
+  PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2, (PMF)&FGWinds::GetTurbPQR);
+  PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3, (PMF)&FGWinds::GetTurbPQR);
+  PropertyManager->Tie("atmosphere/turb-type", this, (PMFt)&FGWinds::GetTurbType, (PMFi)&FGWinds::SetTurbType);
+  PropertyManager->Tie("atmosphere/turb-rate", this, &FGWinds::GetTurbRate, &FGWinds::SetTurbRate);
+  PropertyManager->Tie("atmosphere/turb-gain", this, &FGWinds::GetTurbGain, &FGWinds::SetTurbGain);
+  PropertyManager->Tie("atmosphere/turb-rhythmicity", this, &FGWinds::GetRhythmicity,
+                                                            &FGWinds::SetRhythmicity);
+
+  // Parameters for milspec turbulence
+  PropertyManager->Tie("atmosphere/turbulence/milspec/windspeed_at_20ft_AGL-fps",
+                       this, &FGWinds::GetWindspeed20ft,
+                             &FGWinds::SetWindspeed20ft);
+  PropertyManager->Tie("atmosphere/turbulence/milspec/severity",
+                       this, &FGWinds::GetProbabilityOfExceedence,
+                             &FGWinds::SetProbabilityOfExceedence);
+
+  // Total, calculated winds (local navigational/geographic frame: N-E-D). Read only.
+  PropertyManager->Tie("atmosphere/total-wind-north-fps", this, eNorth, (PMF)&FGWinds::GetTotalWindNED);
+  PropertyManager->Tie("atmosphere/total-wind-east-fps",  this, eEast,  (PMF)&FGWinds::GetTotalWindNED);
+  PropertyManager->Tie("atmosphere/total-wind-down-fps",  this, eDown,  (PMF)&FGWinds::GetTotalWindNED);
+
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//    The bitmasked value choices are as follows:
+//    unset: In this case (the default) JSBSim would only print
+//       out the normally expected messages, essentially echoing
+//       the config files as they are read. If the environment
+//       variable is not set, debug_lvl is set to 1 internally
+//    0: This requests JSBSim not to output any messages
+//       whatsoever.
+//    1: This value explicity requests the normal JSBSim
+//       startup messages
+//    2: This value asks for a message to be printed out when
+//       a class is instantiated
+//    4: When this value is set, a message is displayed when a
+//       FGModel object executes its Run() method
+//    8: When this value is set, various runtime state variables
+//       are printed out periodically
+//    16: When set various parameters are sanity checked and
+//       a message is printed out when they go out of bounds
+
+void FGWinds::Debug(int from)
+{
+  if (debug_lvl <= 0) return;
+
+  if (debug_lvl & 1) { // Standard console startup message output
+    if (from == 0) { // Constructor
+    }
+  }
+  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+    if (from == 0) cout << "Instantiated: FGWinds" << endl;
+    if (from == 1) cout << "Destroyed:    FGWinds" << endl;
+  }
+  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+  }
+  if (debug_lvl & 8 ) { // Runtime state variables
+  }
+  if (debug_lvl & 16) { // Sanity checking
+  }
+  if (debug_lvl & 128) { // 
+  }
+  if (debug_lvl & 64) {
+    if (from == 0) { // Constructor
+      cout << IdSrc << endl;
+      cout << IdHdr << endl;
+    }
+  }
+}
+
+} // namespace JSBSim
diff --git a/src/FDM/JSBSim/models/atmosphere/FGWinds.h b/src/FDM/JSBSim/models/atmosphere/FGWinds.h
new file mode 100644
index 000000000..6ea065af6
--- /dev/null
+++ b/src/FDM/JSBSim/models/atmosphere/FGWinds.h
@@ -0,0 +1,349 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       FGWinds.h
+ Author:       Jon Berndt, Andreas Gaeb, David Culp
+ Date started: 5/2011
+
+ ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
+
+ This program is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser 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 Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ Further information about the GNU Lesser General Public License can also be found on
+ the world wide web at http://www.gnu.org.
+
+HISTORY
+--------------------------------------------------------------------------------
+5/2011   JSB   Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef FGWINDS_H
+#define FGWINDS_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include "models/FGModel.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
+#include "math/FGTable.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_WINDS "$Id: FGWinds.h,v 1.5 2011/09/07 12:21:45 jberndt Exp $"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Models atmospheric disturbances: winds, gusts, turbulence, downbursts, etc.
+
+    Various turbulence models are available. They are specified
+    via the property <tt>atmosphere/turb-type</tt>. The following models are
+    available:
+    - 0: ttNone (turbulence disabled)
+    - 1: ttStandard
+    - 2: ttCulp
+    - 3: ttMilspec (Dryden spectrum)
+    - 4: ttTustin (Dryden spectrum)
+
+    The Milspec and Tustin models are described in the Yeager report cited below.
+    They both use a Dryden spectrum model whose parameters (scale lengths and intensities)
+    are modelled according to MIL-F-8785C. Parameters are modelled differently
+    for altitudes below 1000ft and above 2000ft, for altitudes in between they
+    are interpolated linearly.
+
+    The two models differ in the implementation of the transfer functions
+    described in the milspec.
+
+    To use one of these two models, set <tt>atmosphere/turb-type</tt> to 4 resp. 5,
+    and specify values for <tt>atmosphere/turbulence/milspec/windspeed_at_20ft_AGL-fps<tt>
+    and <tt>atmosphere/turbulence/milspec/severity<tt> (the latter corresponds to
+    the probability of exceedence curves from Fig.&nbsp;7 of the milspec, allowable
+    range is 0 (disabled) to 7). <tt>atmosphere/psiw-rad</tt> is respected as well;
+    note that you have to specify a positive wind magnitude to prevent psiw from
+    being reset to zero.
+
+    Reference values (cf. figures 7 and 9 from the milspec):
+    <table>
+      <tr><td><b>Intensity</b></td>
+          <td><b><tt>windspeed_at_20ft_AGL-fps</tt></b></td>
+          <td><b><tt>severity</tt></b></td></tr>
+      <tr><td>light</td>
+          <td>25 (15 knots)</td>
+          <td>3</td></tr>
+      <tr><td>moderate</td>
+          <td>50 (30 knots)</td>
+          <td>4</td></tr>
+      <tr><td>severe</td>
+          <td>75 (45 knots)</td>
+          <td>6</td></tr>
+    </table>
+
+    @see Yeager, Jessie C.: "Implementation and Testing of Turbulence Models for
+         the F18-HARV" (<a
+         href="http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19980028448_1998081596.pdf">
+         pdf</a>), NASA CR-1998-206937, 1998
+
+    @see MIL-F-8785C: Military Specification: Flying Qualities of Piloted Aircraft
+
+*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGWinds : public FGModel {
+public:
+
+  /// Constructor
+  FGWinds(FGFDMExec*);
+  /// Destructor
+  ~FGWinds();
+  /** Runs the winds model; called by the Executive
+      Can pass in a value indicating if the executive is directing the simulation to Hold.
+      @param Holding if true, the executive has been directed to hold the sim from 
+                     advancing time. Some models may ignore this flag, such as the Input
+                     model, which may need to be active to listen on a socket for the
+                     "Resume" command to be given.
+      @return false if no error */
+  bool Run(bool Holding);
+  bool InitModel(void);
+  enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType;
+
+  // TOTAL WIND access functions (wind + gust + turbulence)
+
+  /// Retrieves the total wind components in NED frame.
+  virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; }
+
+  /// Retrieves a total wind component in NED frame.
+  virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);}
+
+  // WIND access functions
+
+  /// Sets the wind components in NED frame.
+  virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
+
+  /// Sets a wind component in NED frame.
+  virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;}
+
+  /// Retrieves the wind components in NED frame.
+  virtual FGColumnVector3& GetWindNED(void) { return vWindNED; }
+
+  /// Retrieves a wind component in NED frame.
+  virtual double GetWindNED(int idx) const {return vWindNED(idx);}
+
+  /** Retrieves the direction that the wind is coming from.
+      The direction is defined as north=0 and increases counterclockwise.
+      The wind heading is returned in radians.*/
+  virtual double GetWindPsi(void) const { return psiw; }
+
+  /** Sets the direction that the wind is coming from.
+      The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The
+      vertical component of wind is assumed to be zero - and is forcibly set to zero. This function
+      sets the vWindNED vector components based on the supplied direction. The magnitude of
+      the wind set in the vector is preserved (assuming the vertical component is non-zero).
+      @param dir wind direction in the horizontal plane, in radians.*/
+  virtual void SetWindPsi(double dir);
+
+  virtual void SetWindspeed(double speed);
+
+  virtual double GetWindspeed(void) const;
+
+  // GUST access functions
+
+  /// Sets a gust component in NED frame.
+  virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;}
+
+  /// Sets a turbulence component in NED frame.
+  virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;}
+
+  /// Sets the gust components in NED frame.
+  virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;}
+
+  /// Retrieves a gust component in NED frame.
+  virtual double GetGustNED(int idx) const {return vGustNED(idx);}
+
+  /// Retrieves a turbulence component in NED frame.
+  virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);}
+
+  /// Retrieves the gust components in NED frame.
+  virtual FGColumnVector3& GetGustNED(void) {return vGustNED;}
+
+  /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */
+  virtual void   SetTurbType(tType tt) {turbType = tt;}
+  virtual tType  GetTurbType() const {return turbType;}
+
+  virtual void   SetTurbGain(double tg) {TurbGain = tg;}
+  virtual double GetTurbGain() const {return TurbGain;}
+
+  virtual void   SetTurbRate(double tr) {TurbRate = tr;}
+  virtual double GetTurbRate() const {return TurbRate;}
+
+  virtual void   SetRhythmicity(double r) {Rhythmicity=r;}
+  virtual double GetRhythmicity() const {return Rhythmicity;}
+
+  virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
+  virtual double GetTurbMagnitude(void) const {return Magnitude;}
+  virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;}
+  virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;}
+
+  virtual void   SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;}
+  virtual double GetWindspeed20ft() const { return windspeed_at_20ft;}
+
+  /// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence
+  virtual void   SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;}
+  virtual int    GetProbabilityOfExceedence() const { return probability_of_exceedence_index;}
+
+  // Stores data defining a 1 - cosine gust profile that builds up, holds steady
+  // and fades out over specified durations.
+  struct OneMinusCosineProfile {
+    bool Running;           ///<- This flag is set true through FGWinds::StartGust().
+    double elapsedTime;     ///<- Stores the elapsed time for the ongoing gust.
+    double startupDuration; ///<- Specifies the time it takes for the gust startup transient.
+    double steadyDuration;  ///<- Specifies the duration of the steady gust.
+    double endDuration;     ///<- Specifies the time it takes for the gust to subsude.
+    OneMinusCosineProfile() ///<- The constructor.
+    {
+      elapsedTime = 0.0;
+      Running = false;
+      startupDuration = 2;
+      steadyDuration = 4;
+      endDuration = 2;
+    }
+  };
+
+  enum eGustFrame {gfNone=0, gfBody, gfWind, gfLocal};
+
+  /// Stores the information about a single one minus cosine gust instance.
+  struct OneMinusCosineGust {
+    FGColumnVector3 vWind;                    ///<- The input normalized wind vector.
+    FGColumnVector3 vWindTransformed;         ///<- The transformed normal vector at the time the gust is started.
+    double magnitude;                         ///<- The magnitude of the wind vector.
+    eGustFrame gustFrame;                     ///<- The frame that the wind vector is specified in.
+    struct OneMinusCosineProfile gustProfile; ///<- The gust shape (profile) data for this gust.
+    OneMinusCosineGust()                      ///<- Constructor.
+    {
+      vWind.InitMatrix(0.0);
+      gustFrame = gfLocal;
+      magnitude = 1.0;
+    };
+  };
+
+  /// Stores information about a specified Up- or Down-burst.
+  struct UpDownBurst {
+    double ringLatitude;                           ///<- The latitude of the downburst run (radians)
+    double ringLongitude;                          ///<- The longitude of the downburst run (radians)
+    double ringAltitude;                           ///<- The altitude of the ring (feet).
+    double ringRadius;                             ///<- The radius of the ring (feet).
+    double ringCoreRadius;                         ///<- The cross-section "core" radius of the ring (feet).
+    double circulation;                            ///<- The circulation (gamma) (feet-squared per second).
+    struct OneMinusCosineProfile oneMCosineProfile;
+  };
+
+  // 1 - Cosine gust setters
+  /// Initiates the execution of the gust.
+  virtual void StartGust(bool running) {oneMinusCosineGust.gustProfile.Running = running;}
+  ///Specifies the duration of the startup portion of the gust.
+  virtual void StartupGustDuration(double dur) {oneMinusCosineGust.gustProfile.startupDuration = dur;}
+  ///Specifies the length of time that the gust is at a steady, full strength.
+  virtual void SteadyGustDuration(double dur) {oneMinusCosineGust.gustProfile.steadyDuration = dur;}
+  /// Specifies the length of time it takes for the gust to return to zero velocity.
+  virtual void EndGustDuration(double dur) {oneMinusCosineGust.gustProfile.endDuration = dur;}
+  /// Specifies the magnitude of the gust in feet/second.
+  virtual void GustMagnitude(double mag) {oneMinusCosineGust.magnitude = mag;}
+  /** Specifies the frame that the gust direction vector components are specified in. The 
+      body frame is defined with the X direction forward, and the Y direction positive out
+      the right wing. The wind frame is defined with the X axis pointing into the velocity
+      vector, the Z axis perpendicular to the X axis, in the aircraft XZ plane, and the Y
+      axis completing the system. The local axis is a navigational frame with X pointing north,
+      Y pointing east, and Z pointing down. This is a locally vertical, locally horizontal
+      frame, with the XY plane tangent to the geocentric surface. */
+  virtual void GustFrame(eGustFrame gFrame) {oneMinusCosineGust.gustFrame = gFrame;}
+  /// Specifies the X component of velocity in the specified gust frame (ft/sec).
+  virtual void GustXComponent(double x) {oneMinusCosineGust.vWind(eX) = x;}
+  /// Specifies the Y component of velocity in the specified gust frame (ft/sec).
+  virtual void GustYComponent(double y) {oneMinusCosineGust.vWind(eY) = y;}
+  /// Specifies the Z component of velocity in the specified gust frame (ft/sec).
+  virtual void GustZComponent(double z) {oneMinusCosineGust.vWind(eZ) = z;}
+
+  struct Inputs {
+    double V;
+    double wingspan;
+    double DistanceAGL;
+    double AltitudeASL;
+    FGMatrix33 Tl2b;
+    FGMatrix33 Tw2b;
+    double totalDeltaT;
+  } in;
+
+private:
+
+  double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
+  double h;
+  double TurbGain;
+  double TurbRate;
+  double Rhythmicity;
+  double wind_from_clockwise;
+  double spike, target_time, strength;
+  FGColumnVector3 vDirectiondAccelDt;
+  FGColumnVector3 vDirectionAccel;
+  FGColumnVector3 vDirection;
+  FGColumnVector3 vTurbulenceGrad;
+  FGColumnVector3 vBodyTurbGrad;
+  FGColumnVector3 vTurbPQR;
+
+  struct OneMinusCosineGust oneMinusCosineGust;
+
+  // Dryden turbulence model
+  double windspeed_at_20ft; ///< in ft/s
+  int probability_of_exceedence_index; ///< this is bound as the severity property
+  FGTable *POE_Table; ///< probability of exceedence table
+
+  double psiw;
+  FGColumnVector3 vTotalWindNED;
+  FGColumnVector3 vWindNED;
+  FGColumnVector3 vGustNED;
+  FGColumnVector3 vCosineGust;
+  FGColumnVector3 vBurstGust;
+  FGColumnVector3 vTurbulenceNED;
+
+  /// Get T, P and rho for a standard atmosphere at the given altitude.
+  void Turbulence(double h);
+
+  void CosineGust();
+  double CosineGustProfile( double startDuration, double steadyDuration,
+                            double endDuration, double elapsedTime);
+
+  virtual void bind(void);
+  void Debug(int from);
+};
+
+} // namespace JSBSim
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+#endif
+
diff --git a/src/FDM/JSBSim/models/atmosphere/Makefile.am b/src/FDM/JSBSim/models/atmosphere/Makefile.am
index c4fc9d844..1cbe13238 100644
--- a/src/FDM/JSBSim/models/atmosphere/Makefile.am
+++ b/src/FDM/JSBSim/models/atmosphere/Makefile.am
@@ -1,7 +1,7 @@
 noinst_LIBRARIES = libAtmosphere.a
 
-libAtmosphere_a_SOURCES = FGMSIS.cpp FGMSISData.cpp FGMars.cpp
+libAtmosphere_a_SOURCES = FGMSIS.cpp FGMSISData.cpp FGMars.cpp FGStandardAtmosphere.cpp FGWinds.cpp
 
-noinst_HEADERS = FGMSIS.h FGMars.h
+noinst_HEADERS = FGMSIS.h FGMars.h FGStandardAtmosphere.h FGWinds.h
 
 INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
diff --git a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
old mode 100644
new mode 100755
index 30c2f2244..028509deb
--- a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
+++ b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
@@ -41,11 +41,16 @@ INCLUDES
 #include <iostream>
 #include <cstdlib>
 
+#include "models/FGPropagate.h"
+#include "models/FGAccelerations.h"
+#include "models/FGMassBalance.h"
+#include "models/FGInertial.h"
+
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAccelerometer.cpp,v 1.8 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAccelerometer.cpp,v 1.9 2011/07/17 13:51:23 jberndt Exp $";
 static const char *IdHdr = ID_ACCELEROMETER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57,6 +62,7 @@ FGAccelerometer::FGAccelerometer(FGFCS* fcs, Element* element)
     FGSensorOrientation(element)
 {
   Propagate = fcs->GetExec()->GetPropagate();
+  Accelerations = fcs->GetExec()->GetAccelerations();
   MassBalance = fcs->GetExec()->GetMassBalance();
   Inertial = fcs->GetExec()->GetInertial();
   
@@ -88,8 +94,8 @@ bool FGAccelerometer::Run(void )
   vAccel = Propagate->GetTl2b() * FGColumnVector3(0, 0, Inertial->gravity());
 
   //aircraft forces
-  vAccel += (Propagate->GetUVWdot()
-              + Propagate->GetPQRdot() * vRadius
+  vAccel += (Accelerations->GetUVWdot()
+              + Accelerations->GetPQRdot() * vRadius
               + Propagate->GetPQR() * (Propagate->GetPQR() * vRadius));
 
   // transform to the specified orientation
diff --git a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
old mode 100644
new mode 100755
index 5616ed55b..5f966b8a3
--- a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
+++ b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
@@ -39,9 +39,6 @@ INCLUDES
 
 #include "FGSensor.h"
 #include "input_output/FGXMLElement.h"
-#include "models/FGPropagate.h"
-#include "models/FGMassBalance.h"
-#include "models/FGInertial.h"
 #include "math/FGColumnVector3.h"
 #include "math/FGMatrix33.h"
 #include "FGSensorOrientation.h"
@@ -50,7 +47,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ACCELEROMETER "$Id: FGAccelerometer.h,v 1.4 2009/10/02 10:30:09 jberndt Exp $"
+#define ID_ACCELEROMETER "$Id: FGAccelerometer.h,v 1.5 2011/07/17 13:51:23 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -59,6 +56,10 @@ FORWARD DECLARATIONS
 namespace JSBSim {
 
 class FGFCS;
+class FGPropagate;
+class FGAccelerations;
+class FGInertial;
+class FGMassBalance;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
@@ -110,7 +111,7 @@ even varying all the way from 0.95 to 1.05 in adjacent frames - whatever the del
 time.
 
 @author Jon S. Berndt
-@version $Revision: 1.4 $
+@version $Revision: 1.5 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -127,6 +128,7 @@ public:
 
 private:
   FGPropagate* Propagate;
+  FGAccelerations* Accelerations;
   FGMassBalance* MassBalance;
   FGInertial* Inertial;
   FGColumnVector3 vLocation;
diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp
index 9571d33f7..3baa82a9a 100644
--- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp
+++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp
@@ -43,7 +43,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGActuator.cpp,v 1.21 2011/06/30 03:16:10 jentron Exp $";
+static const char *IdSrc = "$Id: FGActuator.cpp,v 1.22 2011/07/12 21:40:32 jentron Exp $";
 static const char *IdHdr = ID_ACTUATOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,6 +65,7 @@ FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme
   rate_limit = 0.0; // no limit
   fail_zero = fail_hardover = fail_stuck = false;
   ca = cb = 0.0;
+  initialized = 0;
 
   if ( element->FindElement("deadband_width") ) {
     deadband_width = element->FindElementValueAsNumber("deadband_width");
@@ -104,6 +105,8 @@ bool FGActuator::Run(void )
 {
   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
 
+  if( fcs->GetTrimStatus() ) initialized = 0;
+
   if (fail_zero) Input = 0;
   if (fail_hardover) Input =  clipmax*sign(Input);
 
@@ -125,6 +128,8 @@ bool FGActuator::Run(void )
   }
 
   PreviousOutput = Output; // previous value needed for "stuck" malfunction
+  
+  initialized = 1;
 
   Clip();
   if (IsOutput) SetOutput();
@@ -147,7 +152,7 @@ void FGActuator::Lag(void)
   // for this Lag filter
   double input = Output;
 
-  if (!fcs->GetTrimStatus())
+  if ( initialized )
     Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb;
 
   PreviousLagInput = input;
@@ -163,7 +168,7 @@ void FGActuator::Hysteresis(void)
   // method.
   double input = Output;
   
-  if (!fcs->GetTrimStatus()) {
+  if ( initialized ) {
     if (input > PreviousHystOutput)
       Output = max(PreviousHystOutput, input-0.5*hysteresis_width);
     else if (input < PreviousHystOutput)
@@ -181,7 +186,7 @@ void FGActuator::RateLimit(void)
   // is - for the purposes of this RateLimit method - really the input to the
   // method.
   double input = Output;
-  if (!fcs->GetTrimStatus()) {
+  if ( initialized ) {
     double delta = input - PreviousRateLimOutput;
     if (fabs(delta) > dt * rate_limit) {
       double signed_rate_limit = delta > 0.0 ? rate_limit : -rate_limit;
diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.h b/src/FDM/JSBSim/models/flight_control/FGActuator.h
index 7a7866e6d..9259430d0 100644
--- a/src/FDM/JSBSim/models/flight_control/FGActuator.h
+++ b/src/FDM/JSBSim/models/flight_control/FGActuator.h
@@ -44,7 +44,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ACTUATOR "$Id: FGActuator.h,v 1.11 2009/10/02 10:30:09 jberndt Exp $"
+#define ID_ACTUATOR "$Id: FGActuator.h,v 1.12 2011/07/12 21:40:32 jentron Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -81,7 +81,7 @@ Syntax:
 <actuator name="name">
   <input> {[-]property} </input>
   <lag> number </lag>
-  <rate_limit> number <rate_limit>
+  <rate_limit> number </rate_limit>
   <bias> number </bias>
   <deadband_width> number </deadband_width>
   <hysteresis_width> number </hysteresis_width>
@@ -96,14 +96,14 @@ Syntax:
 Example:
 
 @code
-<actuator name="fcs/gimbal_pitch_position">
+<actuator name="fcs/gimbal_pitch_position_radians">
   <input> fcs/gimbal_pitch_command </input>
   <lag> 60 </lag>
-  <rate_limit> 0.085 <rate_limit> <!-- 5 degrees/sec -->
+  <rate_limit> 0.085 </rate_limit> <!-- 0.085 radians/sec -->
   <bias> 0.002 </bias>
   <deadband_width> 0.002 </deadband_width>
   <hysteresis_width> 0.05 </hysteresis_width>
-  <clipto> <!-- +/- 10 degrees -->
+  <clipto> <!-- +/- 0.17 radians -->
     <min> -0.17 </min>
     <max>  0.17 </max>
    </clipto>
@@ -111,7 +111,7 @@ Example:
 @endcode
 
 @author Jon S. Berndt
-@version $Revision: 1.11 $
+@version $Revision: 1.12 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -160,6 +160,7 @@ private:
   bool fail_zero;
   bool fail_hardover;
   bool fail_stuck;
+  bool initialized;
 
   void Hysteresis(void);
   void Lag(void);
diff --git a/src/FDM/JSBSim/models/flight_control/FGGyro.cpp b/src/FDM/JSBSim/models/flight_control/FGGyro.cpp
old mode 100644
new mode 100755
index dffb3c9da..7ee6abe44
--- a/src/FDM/JSBSim/models/flight_control/FGGyro.cpp
+++ b/src/FDM/JSBSim/models/flight_control/FGGyro.cpp
@@ -40,11 +40,13 @@ INCLUDES
 #include "FGGyro.h"
 #include <iostream>
 
+#include "models/FGAccelerations.h"
+
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGGyro.cpp,v 1.5 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGGyro.cpp,v 1.6 2011/07/17 13:51:23 jberndt Exp $";
 static const char *IdHdr = ID_GYRO;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -54,7 +56,7 @@ CLASS IMPLEMENTATION
 FGGyro::FGGyro(FGFCS* fcs, Element* element) : FGSensor(fcs, element),
                                                FGSensorOrientation(element)
 {
-  Propagate = fcs->GetExec()->GetPropagate();
+  Accelerations = fcs->GetExec()->GetAccelerations();
   
   Debug(0);
 }
@@ -73,7 +75,7 @@ bool FGGyro::Run(void )
   // There is no input assumed. This is a dedicated angular acceleration sensor.
   
   //aircraft rates
-  vAccel = mT * Propagate->GetPQRdot();
+  vAccel = mT * Accelerations->GetPQRdot();
 
   Input = vAccel(axis);
 
diff --git a/src/FDM/JSBSim/models/flight_control/FGGyro.h b/src/FDM/JSBSim/models/flight_control/FGGyro.h
old mode 100644
new mode 100755
index 2dcc9fb21..39db505bb
--- a/src/FDM/JSBSim/models/flight_control/FGGyro.h
+++ b/src/FDM/JSBSim/models/flight_control/FGGyro.h
@@ -39,9 +39,6 @@ INCLUDES
 
 #include "FGSensor.h"
 #include "input_output/FGXMLElement.h"
-#include "models/FGPropagate.h"
-#include "models/FGMassBalance.h"
-#include "models/FGInertial.h"
 #include "math/FGColumnVector3.h"
 #include "math/FGMatrix33.h"
 #include "FGSensorOrientation.h"
@@ -50,7 +47,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_GYRO "$Id: FGGyro.h,v 1.5 2009/12/11 06:03:06 jberndt Exp $"
+#define ID_GYRO "$Id: FGGyro.h,v 1.6 2011/07/17 13:51:23 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -59,6 +56,7 @@ FORWARD DECLARATIONS
 namespace JSBSim {
 
 class FGFCS;
+class FGAccelerations;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS DOCUMENTATION
@@ -106,7 +104,7 @@ even varying all the way from 0.95 to 1.05 in adjacent frames - whatever the del
 time.
 
 @author Jon S. Berndt
-@version $Revision: 1.5 $
+@version $Revision: 1.6 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -122,7 +120,7 @@ public:
   bool Run (void);
 
 private:
-  FGPropagate* Propagate;
+  FGAccelerations* Accelerations;
   FGColumnVector3 vAccel;
   void CalculateTransformMatrix(void);
   
diff --git a/src/FDM/JSBSim/models/flight_control/FGSensor.cpp b/src/FDM/JSBSim/models/flight_control/FGSensor.cpp
old mode 100644
new mode 100755
index 60b5f955a..bccf5187e
--- a/src/FDM/JSBSim/models/flight_control/FGSensor.cpp
+++ b/src/FDM/JSBSim/models/flight_control/FGSensor.cpp
@@ -46,7 +46,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGSensor.cpp,v 1.20 2009/10/24 22:59:30 jberndt Exp $";
+static const char *IdSrc = "$Id: FGSensor.cpp,v 1.23 2011/08/18 12:42:17 jberndt Exp $";
 static const char *IdHdr = ID_SENSOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -181,7 +181,7 @@ void FGSensor::Noise(void)
   double random_value=0.0;
 
   if (DistributionType == eUniform) {
-    random_value = ((double)rand()/(double)RAND_MAX) - 0.5;
+    random_value = 2.0*(((double)rand()/(double)RAND_MAX) - 0.5);
   } else {
     random_value = GaussianRandomNumber();
   }
diff --git a/src/FDM/JSBSim/models/flight_control/FGSensor.h b/src/FDM/JSBSim/models/flight_control/FGSensor.h
old mode 100644
new mode 100755
index bcc18dbe5..4a34ac7cb
--- a/src/FDM/JSBSim/models/flight_control/FGSensor.h
+++ b/src/FDM/JSBSim/models/flight_control/FGSensor.h
@@ -44,7 +44,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_SENSOR "$Id: FGSensor.h,v 1.19 2009/10/24 22:59:30 jberndt Exp $"
+#define ID_SENSOR "$Id: FGSensor.h,v 1.20 2011/08/18 12:42:17 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -67,7 +67,7 @@ Syntax:
 <sensor name="name">
   <input> property </input>
   <lag> number </lag>
-  <noise variation="PERCENT|ABSOLUTE"> number </noise>
+  <noise [variation="PERCENT|ABSOLUTE"] [distribution="UNIFORM|GAUSSIAN"]> number </noise>
   <quantization name="name">
     <bits> number </bits>
     <min> number </min>
@@ -98,16 +98,32 @@ Example:
 The only required element in the sensor definition is the input element. In that
 case, no degradation would be modeled, and the output would simply be the input.
 
-For noise, if the type is PERCENT, then the value supplied is understood to be a
-percentage variance. That is, if the number given is 0.05, the the variance is
-understood to be +/-0.05 percent maximum variance. So, the actual value for the sensor
-will be *anywhere* from 0.95 to 1.05 of the actual "perfect" value at any time -
-even varying all the way from 0.95 to 1.05 in adjacent frames - whatever the delta
-time. The delay element can specify a frame delay. The integer number provided is
+Noise can be Gaussian or uniform, and the noise can be applied as a factor (PERCENT)
+or additively (ABSOLUTE). The noise that can be applied at each frame of the
+simulation execution is calculated as a random factor times a noise value that
+is specified in the config file. When the noise distribution type is Gaussian,
+the random number can be between roughly -3 and +3 for a span of six sigma. When
+the distribution type is UNIFORM, the random value can be between -1.0 and +1.0.
+This random value is multiplied against the specified noise to arrive at a random
+noise value for the frame. If the noise type is PERCENT, then random noise value
+is added to one, and that sum is then multiplied against the input signal for the
+sensor. In this case, the specified noise value in the config file would be
+expected to actually be a percent value, such as 0.05 (for a 5% variance). If the
+noise type is ABSOLUTE, then the random noise value specified in the config file
+is understood to be an absolute value of noise to be added to the input signal
+instead of being added to 1.0 and having that sum be multiplied against the input
+signal as in the PERCENT type. For the ABSOLUTE noise case, the noise number
+specified in the config file could be any number.
+
+If the type is ABSOLUTE, then the noise number times the random number is
+added to the input signal instead of being multiplied against it as with the
+PERCENT type of noise.
+
+The delay element can specify a frame delay. The integer number provided is
 the number of frames to delay the output signal.
 
 @author Jon S. Berndt
-@version $Revision: 1.19 $
+@version $Revision: 1.20 $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/flight_control/Makefile.am b/src/FDM/JSBSim/models/flight_control/Makefile.am
index 2d7a1aa67..63487bcb8 100644
--- a/src/FDM/JSBSim/models/flight_control/Makefile.am
+++ b/src/FDM/JSBSim/models/flight_control/Makefile.am
@@ -2,13 +2,13 @@ noinst_LIBRARIES = libFlightControl.a
 
 libFlightControl_a_SOURCES = \
 	FGPID.cpp FGDeadBand.cpp FGFCSComponent.cpp \
-	FGFilter.cpp FGGain.cpp FGGradient.cpp FGKinemat.cpp \
+	FGFilter.cpp FGGain.cpp FGKinemat.cpp \
 	FGSummer.cpp FGSwitch.cpp FGFCSFunction.cpp FGSensor.cpp \
 	FGActuator.cpp FGAccelerometer.cpp FGGyro.cpp FGMagnetometer.cpp
 
 noinst_HEADERS = \
 	FGPID.h FGDeadBand.h FGFCSComponent.h FGFilter.h \
-	FGGain.h FGGradient.h FGKinemat.h FGSummer.h FGSwitch.h FGFCSFunction.h\
+	FGGain.h FGKinemat.h FGSummer.h FGSwitch.h FGFCSFunction.h\
 	FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h FGMagnetometer.h \
 	FGSensorOrientation.h
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp
index 341c02a39..c591ceb63 100644
--- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp
@@ -39,27 +39,25 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include "FGElectric.h"
-#include "models/FGPropulsion.h"
-#include "models/propulsion/FGThruster.h"
-#include "FGPropeller.h"
-
 #include <iostream>
 #include <sstream>
 
+#include "FGElectric.h"
+#include "FGPropeller.h"
+
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGElectric.cpp,v 1.11 2011/06/06 22:35:08 jentron Exp $";
+static const char *IdSrc = "$Id: FGElectric.cpp,v 1.13 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_ELECTRIC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number)
-  : FGEngine(exec, el, engine_number)
+FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number, struct FGEngine::Inputs& input)
+  : FGEngine(exec, el, engine_number, input)
 {
   string token;
 
@@ -67,8 +65,6 @@ FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number)
   PowerWatts = 745.7;
   hptowatts = 745.7;
 
-  dt = FDMExec->GetDeltaT();
-
   if (el->FindElement("power"))
     PowerWatts = el->FindElementValueAsNumberConvertTo("power","WATTS");
 
@@ -93,17 +89,16 @@ void FGElectric::Calculate(void)
 {
   RunPreFunctions();
 
-  Throttle = FCS->GetThrottlePos(EngineNumber);
-
   if (Thruster->GetType() == FGThruster::ttPropeller) {
-      ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
-      ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
+    ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
+    ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
   } 
 
   RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
 
-  HP = PowerWatts * Throttle / hptowatts;
+  HP = PowerWatts * in.ThrottlePos[EngineNumber] / hptowatts;
   
+  LoadThrusterInputs();
   Thruster->Calculate(HP * hptoftlbssec);
 
   RunPostFunctions();
diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.h b/src/FDM/JSBSim/models/propulsion/FGElectric.h
index 28c703dee..f35be2186 100644
--- a/src/FDM/JSBSim/models/propulsion/FGElectric.h
+++ b/src/FDM/JSBSim/models/propulsion/FGElectric.h
@@ -45,7 +45,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ELECTRIC "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $";
+#define ID_ELECTRIC "$Id: FGElectric.h,v 1.11 2011/07/28 12:48:19 jberndt Exp $";
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -65,7 +65,7 @@ CLASS DOCUMENTATION
     there is no battery model available, so this motor does not consume any
     energy.  There is no internal friction.
     @author David Culp
-    @version "$Id: FGElectric.h,v 1.10 2011/03/10 01:35:25 dpculp Exp $"
+    @version "$Id: FGElectric.h,v 1.11 2011/07/28 12:48:19 jberndt Exp $"
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -76,7 +76,7 @@ class FGElectric : public FGEngine
 {
 public:
   /// Constructor
-  FGElectric(FGFDMExec* exec, Element *el, int engine_number);
+  FGElectric(FGFDMExec* exec, Element *el, int engine_number, FGEngine::Inputs& input);
   /// Destructor
   ~FGElectric();
 
@@ -92,9 +92,6 @@ private:
 
   double BrakeHorsePower;
 
-  // timestep
-  double dt;
-
   // constants
   double hptowatts;
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
index 707d425e4..4d8c2dc41 100644
--- a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
@@ -37,32 +37,31 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+
 #include "FGEngine.h"
 #include "FGTank.h"
 #include "FGPropeller.h"
 #include "FGNozzle.h"
 #include "FGRotor.h"
-#include "models/FGPropulsion.h"
 #include "input_output/FGXMLParse.h"
 #include "math/FGColumnVector3.h"
 
-#include <iostream>
-#include <fstream>
-#include <cstdlib>
-
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGEngine.cpp,v 1.42 2011/03/03 12:16:26 jberndt Exp $";
+static const char *IdSrc = "$Id: FGEngine.cpp,v 1.46 2011/08/17 23:56:01 jberndt Exp $";
 static const char *IdHdr = ID_ENGINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
-                      : EngineNumber(engine_number)
+FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number, struct Inputs& input)
+                      : EngineNumber(engine_number), in(input)
 {
   Element* local_element;
   FGColumnVector3 location, orientation;
@@ -72,20 +71,13 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
   X = Y = Z = 0.0;
   EnginePitch = EngineYaw = 0.0;
   SLFuelFlowMax = 0.0;
+  FuelExpended = 0.0;
   MaxThrottle = 1.0;
   MinThrottle = 0.0;
-  FuelDensity = 6.0;
-  unsigned int i;
 
   ResetToIC(); // initialize dynamic terms
 
   FDMExec = exec;
-  Atmosphere = FDMExec->GetAtmosphere();
-  FCS = FDMExec->GetFCS();
-  Propulsion = FDMExec->GetPropulsion();
-  Aircraft = FDMExec->GetAircraft();
-  Propagate = FDMExec->GetPropagate();
-  Auxiliary = FDMExec->GetAuxiliary();
 
   PropertyManager = FDMExec->GetPropertyManager();
 
@@ -118,28 +110,12 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
     cerr << "No thruster definition supplied with engine definition." << endl;
   }
 
-  // Build and initialize the feed tank vector.
-  for (i=0; i<(Propulsion->GetNumTanks()); i++) {
-    SourceTanks.push_back(0);
-  }
-
   // Load feed tank[s] references
   local_element = engine_element->GetParent()->FindElement("feed");
-  if (local_element) {
-    while (local_element) {
-      int tankID = (int)local_element->GetDataAsNumber();
-      FGTank* tank = Propulsion->GetTank(tankID); 
-      if (tank) {
-        AddFeedTank(tankID, tank->GetPriority());
-        FuelDensity = tank->GetDensity();
-      } else {
-        cerr << "Feed tank " << tankID <<
-          " specified in engine definition does not exist." << endl;
-      }
-      local_element = engine_element->GetParent()->FindNextElement("feed");
-    }
-  } else {
-    cerr << "No feed tank specified in engine definition." << endl;
+  while (local_element) {
+    int tankID = (int)local_element->GetDataAsNumber();
+    SourceTanks.push_back(tankID);
+    local_element = engine_element->GetParent()->FindNextElement("feed");
   }
 
   string property_name, base_property_name;
@@ -151,13 +127,13 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
   PropertyManager->Tie( property_name.c_str(), Thruster, &FGThruster::GetThrust);
   property_name = base_property_name + "/fuel-flow-rate-pps";
   PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRate);
+  property_name = base_property_name + "/fuel-flow-rate-gph";
+  PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelFlowRateGPH);
   property_name = base_property_name + "/fuel-used-lbs";
   PropertyManager->Tie( property_name.c_str(), this, &FGEngine::GetFuelUsedLbs);
 
   PostLoad(engine_element, PropertyManager, to_string(EngineNumber));
 
-  //cout << "Engine[" << EngineNumber << "] using fuel density: " << FuelDensity << endl;
-
   Debug(0);
 }
 
@@ -173,8 +149,6 @@ FGEngine::~FGEngine()
 
 void FGEngine::ResetToIC(void)
 {
-  Throttle = 0.0;
-  Mixture = 1.0;
   Starter = false;
   FuelExpended = 0.0;
   Starved = Running = Cranking = false;
@@ -187,73 +161,24 @@ void FGEngine::ResetToIC(void)
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This base class function should be called from within the
-// derived class' Calculate() function before any other calculations are done.
-// This base class method removes fuel from the fuel tanks as appropriate,
-// and sets the starved flag if necessary.
-// This version of the fuel consumption code should never see an oxidizer tank.
 
-void FGEngine::ConsumeFuel(void)
+double FGEngine::CalcFuelNeed(void)
 {
-  if (FuelFreeze) return;
-  if (FDMExec->GetTrimStatus()) return;
-
-  unsigned int i;
-  double Fshortage, FuelNeeded;
-  FGTank* Tank;
-  unsigned int TanksWithFuel = 0;
-  Fshortage = FuelNeeded = 0.0;
-  double FuelToBurn;
-  unsigned int CurrentPriority = 1;
-  vector <int> FeedList;
-  Starved = false;
-
-  FuelToBurn = CalcFuelNeed();
-  if (FuelToBurn == 0.0) return;
-
-  // Count how many fuel tanks with the current priority level have fuel.
-  // If none, then try next lower priority.  Build the feed list.
-  while ((TanksWithFuel == 0) && (CurrentPriority <= Propulsion->GetNumTanks())) {
-    for (i=0; i<Propulsion->GetNumTanks(); i++) {
-      if (SourceTanks[i] != 0) {
-        Tank = Propulsion->GetTank(i);
-        if (Tank->GetType() == FGTank::ttFUEL) {
-          if ((Tank->GetContents() > 0.0) && ((unsigned int)Tank->GetPriority() == CurrentPriority)) {
-             ++TanksWithFuel;
-             FeedList.push_back(i);
-           } 
-        } else {
-           cerr << "No oxidizer tanks should be used for this engine type." << endl;
-        }
-      }
-    }
-    if (TanksWithFuel == 0) CurrentPriority++;
-  }
-
-  // No fuel found at any priority!
-  if (TanksWithFuel == 0) {
-    Starved = true;
-    return;
-  }
-
-  // Remove equal amount of fuel from each feed tank.  
-  FuelNeeded = FuelToBurn/TanksWithFuel;
-  for (i=0; i<FeedList.size(); i++) {
-    Tank = Propulsion->GetTank(FeedList[i]);
-    Tank->Drain(FuelNeeded); 
-  }
-  FuelUsedLbs += FuelToBurn;
-
+  FuelFlowRate = SLFuelFlowMax*PctPower;
+  FuelExpended = FuelFlowRate*in.TotalDeltaT;
+  if (!Starved) FuelUsedLbs += FuelExpended;
+  return FuelExpended;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGEngine::CalcFuelNeed(void)
+unsigned int FGEngine::GetSourceTank(unsigned int i) const
 {
-  double dT = FDMExec->GetDeltaT()*Propulsion->GetRate();
-  FuelFlowRate = SLFuelFlowMax*PctPower;
-  FuelExpended = FuelFlowRate*dT;
-  return FuelExpended;
+  if (i >= 0 && i < SourceTanks.size()) {
+    return SourceTanks[i];
+  } else {
+    throw("No such source tank is available for this engine");
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -269,14 +194,14 @@ void FGEngine::SetPlacement(FGColumnVector3& location, FGColumnVector3& orientat
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGEngine::AddFeedTank(int tkID, int priority)
+double FGEngine::GetThrust(void) const 
 {
-  SourceTanks[tkID] = priority;
+  return Thruster->GetThrust();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector3& FGEngine::GetBodyForces(void)
+  FGColumnVector3& FGEngine::GetBodyForces(void)
 {
   return Thruster->GetBodyForces();
 }
@@ -290,6 +215,23 @@ FGColumnVector3& FGEngine::GetMoments(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGEngine::LoadThrusterInputs()
+{
+  Thruster->in.TotalDeltaT     = in.TotalDeltaT;
+  Thruster->in.H_agl           = in.H_agl;
+  Thruster->in.PQR             = in.PQR;
+  Thruster->in.AeroPQR         = in.AeroPQR;
+  Thruster->in.AeroUVW         = in.AeroUVW;
+  Thruster->in.Density         = in.Density;
+  Thruster->in.Pressure        = in.Pressure;
+  Thruster->in.Soundspeed      = in.Soundspeed;
+  Thruster->in.Alpha           = in.alpha;
+  Thruster->in.Beta            = in.beta;
+  Thruster->in.Vt              = in.Vt;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGEngine::LoadThruster(Element *thruster_element)
 {
   string token, fullpath, localpath;
@@ -339,7 +281,7 @@ bool FGEngine::LoadThruster(Element *thruster_element)
     Thruster = new FGThruster( FDMExec, document, EngineNumber);
   }
 
-  Thruster->SetdeltaT(FDMExec->GetDeltaT() * Propulsion->GetRate());
+  Thruster->SetdeltaT(in.TotalDeltaT);
 
   Debug(2);
   return true;
diff --git a/src/FDM/JSBSim/models/propulsion/FGEngine.h b/src/FDM/JSBSim/models/propulsion/FGEngine.h
index 03b774d94..33db9998e 100644
--- a/src/FDM/JSBSim/models/propulsion/FGEngine.h
+++ b/src/FDM/JSBSim/models/propulsion/FGEngine.h
@@ -43,19 +43,19 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <vector>
+#include <string>
+
 #include "math/FGModelFunctions.h"
 #include "input_output/FGXMLFileRead.h"
 #include "input_output/FGXMLElement.h"
-#include "models/FGFCS.h"
 #include "math/FGColumnVector3.h"
-#include <vector>
-#include <string>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ENGINE "$Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $"
+#define ID_ENGINE "$Id: FGEngine.h,v 1.27 2011/08/17 23:56:01 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -64,11 +64,6 @@ FORWARD DECLARATIONS
 namespace JSBSim {
 
 class FGFDMExec;
-class FGAtmosphere;
-class FGAircraft;
-class FGPropagate;
-class FGPropulsion;
-class FGAuxiliary;
 class FGThruster;
 class Element;
 class FGPropertyManager;
@@ -118,7 +113,7 @@ CLASS DOCUMENTATION
 	documentation for engine and thruster classes.
 </pre>     
     @author Jon S. Berndt
-    @version $Id: FGEngine.h,v 1.23 2011/03/03 12:16:26 jberndt Exp $
+    @version $Id: FGEngine.h,v 1.27 2011/08/17 23:56:01 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -128,7 +123,36 @@ CLASS DECLARATION
 class FGEngine : public FGModelFunctions, public FGXMLFileRead
 {
 public:
-  FGEngine(FGFDMExec* exec, Element* el, int engine_number);
+  struct Inputs {
+    double SLPressure;
+    double Pressure;
+    double PressureRatio;
+    double Temperature;
+    double Density;
+    double DensityRatio;
+    double Soundspeed;
+    double TotalPressure;
+    double TotalTempearture;
+    double TAT_c;
+    double Vt;
+    double Vc;
+    double qbar;
+    double alpha;
+    double beta;
+    double H_agl;
+    FGColumnVector3 AeroUVW;
+    FGColumnVector3 AeroPQR;
+    FGColumnVector3 PQR;
+    vector <double> ThrottleCmd;
+    vector <double> MixtureCmd;
+    vector <double> ThrottlePos;
+    vector <double> MixturePos;
+    vector <double> PropAdvance;
+    vector <bool> PropFeather;
+    double TotalDeltaT;
+  };
+
+  FGEngine(FGFDMExec* exec, Element* el, int engine_number, struct Inputs& input);
   virtual ~FGEngine();
 
   enum EngineType {etUnknown, etRocket, etPiston, etTurbine, etTurboprop, etElectric};
@@ -139,13 +163,12 @@ public:
   // Engine controls
   virtual double  GetThrottleMin(void) { return MinThrottle; }
   virtual double  GetThrottleMax(void) { return MaxThrottle; }
-  virtual double  GetThrottle(void) { return Throttle; }
-  virtual double  GetMixture(void) { return Mixture; }
   virtual bool    GetStarter(void) { return Starter; }
 
   virtual double getFuelFlow_gph () const {return FuelFlow_gph;}
   virtual double getFuelFlow_pph () const {return FuelFlow_pph;}
   virtual double GetFuelFlowRate(void) const {return FuelFlowRate;}
+  virtual double GetFuelFlowRateGPH(void) const {return FuelFlowRate*3600/6.02;}
   virtual double GetFuelUsedLbs(void) const {return FuelUsedLbs;}
   virtual bool   GetStarved(void) { return Starved; }
   virtual bool   GetRunning(void) const { return Running; }
@@ -156,7 +179,6 @@ public:
 
   virtual void SetRunning(bool bb) { Running=bb; }
   virtual void SetName(string name) { Name = name; }
-  virtual void AddFeedTank(int tkID, int priority);
   virtual void SetFuelFreeze(bool f) { FuelFreeze = f; }
 
   virtual void SetStarter(bool s) { Starter = s; }
@@ -169,9 +191,19 @@ public:
   /** Calculates the thrust of the engine, and other engine functions. */
   virtual void Calculate(void) = 0;
 
+  virtual double GetThrust(void) const;
+    
   /// Sets engine placement information
   virtual void SetPlacement(FGColumnVector3& location, FGColumnVector3& orientation);
 
+  /** The fuel need is calculated based on power levels and flow rate for that
+      power level. It is also turned from a rate into an actual amount (pounds)
+      by multiplying it by the delta T and the rate.
+      @return Total fuel requirement for this engine in pounds. */
+  virtual double CalcFuelNeed(void);
+
+  virtual double CalcOxidizerNeed(void) {return 0.0;}
+
   virtual double GetPowerAvailable(void) {return 0.0;};
 
   virtual FGColumnVector3& GetBodyForces(void);
@@ -180,22 +212,22 @@ public:
   bool LoadThruster(Element *el);
   FGThruster* GetThruster(void) {return Thruster;}
 
+  unsigned int GetSourceTank(unsigned int i) const;
+  unsigned int GetNumSourceTanks() const {return SourceTanks.size();}
+
   virtual std::string GetEngineLabels(const std::string& delimiter) = 0;
   virtual std::string GetEngineValues(const std::string& delimiter) = 0;
 
+  struct Inputs& in;
+  void LoadThrusterInputs();
+
 protected:
   /** Reduces the fuel in the active tanks by the amount required.
       This function should be called from within the
       derived class' Calculate() function before any other calculations are
       done. This base class method removes fuel from the fuel tanks as
-      appropriate, and sets the starved flag if necessary. */
-  virtual void ConsumeFuel(void);
-
-  /** The fuel need is calculated based on power levels and flow rate for that
-      power level. It is also turned from a rate into an actual amount (pounds)
-      by multiplying it by the delta T and the rate.
-      @return Total fuel requirement for this engine in pounds. */
-  virtual double CalcFuelNeed(void);
+      appropriate, and sets the starved flag if necessary. * /
+  virtual void ConsumeFuel(void); */
 
   FGPropertyManager* PropertyManager;
   std::string Name;
@@ -208,8 +240,6 @@ protected:
   double MaxThrottle;
   double MinThrottle;
 
-  double Throttle;
-  double Mixture;
   double FuelExpended;
   double FuelFlowRate;
   double PctPower;
@@ -221,16 +251,9 @@ protected:
 
   double FuelFlow_gph;
   double FuelFlow_pph;
-  double FuelDensity;
   double FuelUsedLbs;
 
   FGFDMExec*      FDMExec;
-  FGAtmosphere*   Atmosphere;
-  FGFCS*          FCS;
-  FGPropulsion*   Propulsion;
-  FGAircraft*     Aircraft;
-  FGPropagate*    Propagate;
-  FGAuxiliary*    Auxiliary;
   FGThruster*     Thruster;
 
   std::vector <int> SourceTanks;
diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.cpp b/src/FDM/JSBSim/models/propulsion/FGForce.cpp
index 0bebb1772..bd5872b95 100644
--- a/src/FDM/JSBSim/models/propulsion/FGForce.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGForce.cpp
@@ -40,20 +40,20 @@ and the cg.
 
 */
 
-#include "FGForce.h"
-#include "FGFDMExec.h"
-#include "models/FGAircraft.h"
-#include "models/FGPropagate.h"
-#include "models/FGMassBalance.h"
-#include "models/FGAerodynamics.h"
 #include <iostream>
 #include <cstdlib>
 
+#include "FGForce.h"
+#include "FGFDMExec.h"
+#include "models/FGPropagate.h"
+#include "models/FGMassBalance.h"
+#include "models/FGAuxiliary.h"
+
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGForce.cpp,v 1.15 2011/02/17 00:20:52 jberndt Exp $";
+static const char *IdSrc = "$Id: FGForce.cpp,v 1.16 2011/08/04 12:46:32 jberndt Exp $";
 static const char *IdHdr = ID_FORCE;
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -110,7 +110,7 @@ FGMatrix33 FGForce::Transform(void)
 {
   switch(ttype) {
   case tWindBody:
-    return fdmex->GetAerodynamics()->GetTw2b();
+    return fdmex->GetAuxiliary()->GetTw2b();
   case tLocalBody:
     return fdmex->GetPropagate()->GetTl2b();
   case tCustom:
diff --git a/src/FDM/JSBSim/models/propulsion/FGNozzle.cpp b/src/FDM/JSBSim/models/propulsion/FGNozzle.cpp
index f1d0fb12e..65cbf9ec1 100644
--- a/src/FDM/JSBSim/models/propulsion/FGNozzle.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGNozzle.cpp
@@ -40,14 +40,13 @@ INCLUDES
 #include <cstdlib>
 
 #include "FGNozzle.h"
-#include "models/FGAtmosphere.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGNozzle.cpp,v 1.13 2009/10/26 03:49:58 jberndt Exp $";
+static const char *IdSrc = "$Id: FGNozzle.cpp,v 1.14 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_NOZZLE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -64,14 +63,7 @@ FGNozzle::FGNozzle(FGFDMExec* FDMExec, Element* nozzle_element, int num)
     cerr << "Fatal Error: Nozzle exit area must be given in nozzle config file." << endl;
     exit(-1);
   }
-/*
-  if (nozzle_element->FindElement("pe"))
-    PE = nozzle_element->FindElementValueAsNumberConvertTo("pe", "PSF");
-  else {
-    cerr << "Fatal Error: Nozzle exit pressure must be given in nozzle config file." << endl;
-    exit(-1);
-  }
-*/
+
   Thrust = 0;
   Type = ttNozzle;
   
@@ -89,8 +81,7 @@ FGNozzle::~FGNozzle()
 
 double FGNozzle::Calculate(double vacThrust)
 {
-  double pAtm = fdmex->GetAtmosphere()->GetPressure();
-  Thrust = max((double)0.0, vacThrust - pAtm*Area);
+  Thrust = max((double)0.0, vacThrust - in.Pressure*Area);
 
   vFn(1) = Thrust * cos(ReverserAngle);
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGNozzle.h b/src/FDM/JSBSim/models/propulsion/FGNozzle.h
index d2945ba7b..d210b2f50 100644
--- a/src/FDM/JSBSim/models/propulsion/FGNozzle.h
+++ b/src/FDM/JSBSim/models/propulsion/FGNozzle.h
@@ -44,7 +44,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_NOZZLE "$Id: FGNozzle.h,v 1.8 2009/10/26 03:49:58 jberndt Exp $";
+#define ID_NOZZLE "$Id: FGNozzle.h,v 1.9 2011/08/03 03:21:06 jberndt Exp $";
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -75,7 +75,7 @@ CLASS DOCUMENTATION
 
     All parameters MUST be specified.  
     @author Jon S. Berndt
-    @version $Id: FGNozzle.h,v 1.8 2009/10/26 03:49:58 jberndt Exp $
+    @version $Id: FGNozzle.h,v 1.9 2011/08/03 03:21:06 jberndt Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -83,7 +83,6 @@ CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 class FGNozzle : public FGThruster {
-
 public:
   /// Constructor
   FGNozzle(FGFDMExec* exec, Element* el, int num = 0);
diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
index c687b31e8..2220cacd1 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
@@ -40,28 +40,25 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
+#include <iostream>
 #include <sstream>
 
 #include "FGPiston.h"
-#include "models/FGAtmosphere.h"
-#include "models/FGAuxiliary.h"
-#include "models/FGPropulsion.h"
 #include "FGPropeller.h"
-#include <iostream>
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPiston.cpp,v 1.58 2011/06/13 15:23:09 jentron Exp $";
+static const char *IdSrc = "$Id: FGPiston.cpp,v 1.64 2011/08/04 13:45:42 jberndt Exp $";
 static const char *IdHdr = ID_PISTON;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
-  : FGEngine(exec, el, engine_number),
+FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Inputs& input)
+  : FGEngine(exec, el, engine_number, input),
   R_air(287.3),                  // Gas constant for air J/Kg/K
   rho_fuel(800),                 // estimate
   calorific_value_fuel(47.3e6),  // J/Kg
@@ -69,12 +66,13 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   Cp_fuel(1700),
   standard_pressure(101320.73)
 {
+  Element *table_element;
   string token;
+  string name="";
 
   // Defaults and initializations
 
   Type = etPiston;
-  dt = FDMExec->GetDeltaT();
 
   // These items are read from the configuration file
   // Defaults are from a Lycoming O-360, more or less
@@ -104,6 +102,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
 
   // These are internal program variables
 
+  Lookup_Combustion_Efficiency = 0;
+  Mixture_Efficiency_Correlation = 0;
   crank_counter = 0;
   Magnetos = 0;
   minMAP = 21950;
@@ -135,39 +135,6 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
     BoostSwitchPressure[i] = 0.0;
   }
 
-  // First column is thi, second is neta (combustion efficiency)
-  Lookup_Combustion_Efficiency = new FGTable(12);
-  *Lookup_Combustion_Efficiency << 0.00 << 0.980;
-  *Lookup_Combustion_Efficiency << 0.90 << 0.980;
-  *Lookup_Combustion_Efficiency << 1.00 << 0.970;
-  *Lookup_Combustion_Efficiency << 1.05 << 0.950;
-  *Lookup_Combustion_Efficiency << 1.10 << 0.900;
-  *Lookup_Combustion_Efficiency << 1.15 << 0.850;
-  *Lookup_Combustion_Efficiency << 1.20 << 0.790;
-  *Lookup_Combustion_Efficiency << 1.30 << 0.700;
-  *Lookup_Combustion_Efficiency << 1.40 << 0.630;
-  *Lookup_Combustion_Efficiency << 1.50 << 0.570;
-  *Lookup_Combustion_Efficiency << 1.60 << 0.525;
-  *Lookup_Combustion_Efficiency << 2.00 << 0.345;
-
-  Mixture_Efficiency_Correlation = new FGTable(15);
-  *Mixture_Efficiency_Correlation << 0.05000 << 0.00000;
-  *Mixture_Efficiency_Correlation << 0.05137 << 0.00862;
-  *Mixture_Efficiency_Correlation << 0.05179 << 0.21552;
-  *Mixture_Efficiency_Correlation << 0.05430 << 0.48276;
-  *Mixture_Efficiency_Correlation << 0.05842 << 0.70690;
-  *Mixture_Efficiency_Correlation << 0.06312 << 0.83621;
-  *Mixture_Efficiency_Correlation << 0.06942 << 0.93103;
-  *Mixture_Efficiency_Correlation << 0.07786 << 1.00000;
-  *Mixture_Efficiency_Correlation << 0.08845 << 1.00000;
-  *Mixture_Efficiency_Correlation << 0.09270 << 0.98276;
-  *Mixture_Efficiency_Correlation << 0.10120 << 0.93103;
-  *Mixture_Efficiency_Correlation << 0.11455 << 0.72414;
-  *Mixture_Efficiency_Correlation << 0.12158 << 0.45690;
-  *Mixture_Efficiency_Correlation << 0.12435 << 0.23276;
-  *Mixture_Efficiency_Correlation << 0.12500 << 0.00000;
-
-
   // Read inputs from engine data file where present.
 
   if (el->FindElement("minmp")) // Should have ELSE statement telling default value used?
@@ -252,6 +219,21 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
       RatedAltitude[2] = el->FindElementValueAsNumberConvertTo("ratedaltitude3", "FT");
   }
 
+  while(table_element = el->FindNextElement("table")) {
+    name = table_element->GetAttributeValue("name");
+    try {
+      if (name == "COMBUSTION") {
+        Lookup_Combustion_Efficiency = new FGTable(PropertyManager, table_element);
+      } else if (name == "MIXTURE") {
+        Mixture_Efficiency_Correlation = new FGTable(PropertyManager, table_element);
+      } else {
+        cerr << "Unknown table type: " << name << " in piston engine definition." << endl;
+      }
+    } catch (std::string str) {
+      throw("Error loading piston engine table:" + name + ". " + str);
+    }
+  }
+
   StarterHP = sqrt(MaxHP) * 0.4;
   displacement_SI = Displacement * in3tom3;
   RatedMeanPistonSpeed_fps =  ( MaxRPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS
@@ -286,7 +268,6 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
  *
  *
  */
-
   if(Z_airbox < 0.0){
     double Ze=PeakMeanPistonSpeed_fps/RatedMeanPistonSpeed_fps; // engine impedence
     Z_airbox = (standard_pressure *Ze / maxMAP) - Ze; // impedence of airbox
@@ -295,6 +276,44 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   Z_throttle=(PeakMeanPistonSpeed_fps/((IdleRPM * Stroke) / 360))*(standard_pressure/minMAP - 1) - Z_airbox; 
   //  Z_throttle=(MaxRPM/IdleRPM )*(standard_pressure/minMAP+2); // Constant for Throttle impedence
 
+// Default tables if not provided in the configuration file
+  if(Lookup_Combustion_Efficiency == 0) {
+    // First column is thi, second is neta (combustion efficiency)
+    Lookup_Combustion_Efficiency = new FGTable(12);
+    *Lookup_Combustion_Efficiency << 0.00 << 0.980;
+    *Lookup_Combustion_Efficiency << 0.90 << 0.980;
+    *Lookup_Combustion_Efficiency << 1.00 << 0.970;
+    *Lookup_Combustion_Efficiency << 1.05 << 0.950;
+    *Lookup_Combustion_Efficiency << 1.10 << 0.900;
+    *Lookup_Combustion_Efficiency << 1.15 << 0.850;
+    *Lookup_Combustion_Efficiency << 1.20 << 0.790;
+    *Lookup_Combustion_Efficiency << 1.30 << 0.700;
+    *Lookup_Combustion_Efficiency << 1.40 << 0.630;
+    *Lookup_Combustion_Efficiency << 1.50 << 0.570;
+    *Lookup_Combustion_Efficiency << 1.60 << 0.525;
+    *Lookup_Combustion_Efficiency << 2.00 << 0.345;
+  }
+
+    // First column is Fuel/Air Ratio, second is neta (mixture efficiency)
+  if( Mixture_Efficiency_Correlation == 0) {
+    Mixture_Efficiency_Correlation = new FGTable(15);
+    *Mixture_Efficiency_Correlation << 0.05000 << 0.00000;
+    *Mixture_Efficiency_Correlation << 0.05137 << 0.00862;
+    *Mixture_Efficiency_Correlation << 0.05179 << 0.21552;
+    *Mixture_Efficiency_Correlation << 0.05430 << 0.48276;
+    *Mixture_Efficiency_Correlation << 0.05842 << 0.70690;
+    *Mixture_Efficiency_Correlation << 0.06312 << 0.83621;
+    *Mixture_Efficiency_Correlation << 0.06942 << 0.93103;
+    *Mixture_Efficiency_Correlation << 0.07786 << 1.00000;
+    *Mixture_Efficiency_Correlation << 0.08845 << 1.00000;
+    *Mixture_Efficiency_Correlation << 0.09270 << 0.98276;
+    *Mixture_Efficiency_Correlation << 0.10120 << 0.93103;
+    *Mixture_Efficiency_Correlation << 0.11455 << 0.72414;
+    *Mixture_Efficiency_Correlation << 0.12158 << 0.45690;
+    *Mixture_Efficiency_Correlation << 0.12435 << 0.23276;
+    *Mixture_Efficiency_Correlation << 0.12500 << 0.00000;
+  }
+
   string property_name, base_property_name;
   base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
   property_name = base_property_name + "/power-hp";
@@ -347,13 +366,13 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
         // But we can also make a reasonable estimate, as below.
         BoostSwitchAltitude[i] = RatedAltitude[i] + 1000;
       }
-      BoostSwitchPressure[i] = Atmosphere->GetPressure(BoostSwitchAltitude[i]) * psftopa;
+      BoostSwitchPressure[i] = GetStdPressure100K(BoostSwitchAltitude[i]) * psftopa;
       //cout << "BoostSwitchAlt = " << BoostSwitchAltitude[i] << ", pressure = " << BoostSwitchPressure[i] << '\n';
       // Assume there is some hysteresis on the supercharger gear switch, and guess the value for now
       BoostSwitchHysteresis = 1000;
     }
     // Now work out the supercharger pressure multiplier of this speed from the rated boost and altitude.
-    RatedMAP[i] = Atmosphere->GetPressureSL() * psftopa + RatedBoost[i] * 6895;  // psi*6895 = Pa.
+    RatedMAP[i] = standard_pressure + RatedBoost[i] * 6895;  // psi*6895 = Pa.
     // Sometimes a separate BCV setting for takeoff or extra power is fitted.
     if (TakeoffBoost > RatedBoost[0]) {
       // Assume that the effect on the BCV is the same whichever speed is in use.
@@ -363,7 +382,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
       TakeoffMAP[i] = RatedMAP[i];
       bTakeoffBoost = false;
     }
-    BoostMul[i] = RatedMAP[i] / (Atmosphere->GetPressure(RatedAltitude[i]) * psftopa);
+    BoostMul[i] = RatedMAP[i] / (GetStdPressure100K(RatedAltitude[i]) * psftopa);
 
   }
 
@@ -391,10 +410,10 @@ void FGPiston::ResetToIC(void)
 {
   FGEngine::ResetToIC();
 
-  ManifoldPressure_inHg = Atmosphere->GetPressure() * psftoinhg; // psf to in Hg
-  MAP = Atmosphere->GetPressure() * psftopa;
+  ManifoldPressure_inHg = in.Pressure * psftoinhg; // psf to in Hg
+  MAP = in.Pressure * psftopa;
   TMAP = MAP;
-  double airTemperature_degK = RankineToKelvin(Atmosphere->GetTemperature());
+  double airTemperature_degK = RankineToKelvin(in.Temperature);
   OilTemp_degK = airTemperature_degK;
   CylinderHeadTemp_degK = airTemperature_degK;
   ExhaustGasTemp_degK = airTemperature_degK;
@@ -405,26 +424,22 @@ void FGPiston::ResetToIC(void)
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGPiston::Calculate(void)
 {
-  RunPreFunctions();
-
-  if (FuelFlow_gph > 0.0) ConsumeFuel();
-
-  Throttle = FCS->GetThrottlePos(EngineNumber);
-  Mixture = FCS->GetMixturePos(EngineNumber);
-
   // Input values.
 
-  p_amb = Atmosphere->GetPressure() * psftopa;
-  double p = Auxiliary->GetTotalPressure() * psftopa;
+  p_amb = in.Pressure * psftopa;
+  double p = in.TotalPressure * psftopa;
   p_ram = (p - p_amb) * Ram_Air_Factor + p_amb;
-  T_amb = RankineToKelvin(Atmosphere->GetTemperature());
+  T_amb = RankineToKelvin(in.Temperature);
+
+  RunPreFunctions();
 
   RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
   MeanPistonSpeed_fps =  ( RPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS
 
-  IAS = Auxiliary->GetVcalibratedKTS();
+  IAS = in.Vc;
 
   doEngineStartup();
   if (Boosted) doBoostControl();
@@ -449,10 +464,11 @@ void FGPiston::Calculate(void)
   doOilPressure();
 
   if (Thruster->GetType() == FGThruster::ttPropeller) {
-    ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
-    ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
+    ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
+    ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
   }
 
+  LoadThrusterInputs();
   Thruster->Calculate(HP * hptoftlbssec);
 
   RunPostFunctions();
@@ -462,22 +478,19 @@ void FGPiston::Calculate(void)
 
 double FGPiston::CalcFuelNeed(void)
 {
-  double dT = FDMExec->GetDeltaT() * Propulsion->GetRate();
-  FuelExpended = FuelFlowRate * dT;
+  FuelExpended = FuelFlowRate * in.TotalDeltaT;
   return FuelExpended;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-int FGPiston::InitRunning(void) {
+int FGPiston::InitRunning(void)
+{
   Magnetos=3;
-  p_amb = Atmosphere->GetPressure() * psftopa;
-  double mix= p_amb / (101325.0*1.3);
-  FCS->SetMixturePos(EngineNumber, mix);
-  Thruster->SetRPM( 2.*IdleRPM/Thruster->GetGearRatio() );
-  //Thruster->SetRPM( 1000 );
-  Running=true;
-// cout <<"Set Running in FGPiston. RPM:" << Thruster->GetRPM()*Thruster->GetGearRatio() <<" Pressure:"<<p_amb<<" Mixture:"<< mix <<endl;
+  in.MixtureCmd[EngineNumber] = in.PressureRatio/1.3;
+  in.MixturePos[EngineNumber] = in.PressureRatio/1.3;
+  Thruster->SetRPM( 2.0*IdleRPM/Thruster->GetGearRatio() );
+  Running = true;
   return 1;
 }
 
@@ -597,13 +610,18 @@ void FGPiston::doBoostControl(void)
 
 void FGPiston::doMAP(void)
 {
-  double Zt = (1-Throttle)*(1-Throttle)*Z_throttle; // throttle impedence
+  double Zt = (1 - in.ThrottlePos[EngineNumber])*(1 - in.ThrottlePos[EngineNumber])*Z_throttle; // throttle impedence
   double Ze= MeanPistonSpeed_fps > 0 ? PeakMeanPistonSpeed_fps/MeanPistonSpeed_fps : 999999; // engine impedence
 
   double map_coefficient = Ze/(Ze+Z_airbox+Zt);
 
   // Add a one second lag to manifold pressure changes
-  double dMAP = (TMAP - p_ram * map_coefficient) * dt;
+  double dMAP=0;
+  if (in.TotalDeltaT > 0.0) 
+    dMAP = (TMAP - p_ram * map_coefficient) * in.TotalDeltaT;
+  else 
+    dMAP = (TMAP - p_ram * map_coefficient) / 120;
+
   TMAP -=dMAP;
 
   // Find the mean effective pressure required to achieve this manifold pressure
@@ -620,7 +638,7 @@ void FGPiston::doMAP(void)
 
     bool bTakeoffPos = false;
     if (bTakeoffBoost) {
-      if (Throttle > 0.98) {
+      if (in.ThrottlePos[EngineNumber] > 0.98) {
         bTakeoffPos = true;
       }
     }
@@ -661,7 +679,7 @@ void FGPiston::doAirFlow(void)
 // loss of volumentric efficiency due to difference between MAP and exhaust pressure
 // Eq 6-10 from The Internal Combustion Engine - Charles Taylor Vol 1
   double ve =((gamma-1)/gamma) +( CompressionRatio -(p_amb/MAP))/(gamma*( CompressionRatio - 1));
-// FGAtmosphere::GetDensity() * FGJSBBase::m3toft3 / FGJSBBase::kgtoslug;
+
   rho_air = p_amb / (R_air * T_amb);
   double swept_volume = (displacement_SI * (RPM/60)) / 2;
   double v_dot_air = swept_volume * volumetric_efficiency *ve;
@@ -682,12 +700,18 @@ void FGPiston::doAirFlow(void)
 
 void FGPiston::doFuelFlow(void)
 {
-  double thi_sea_level = 1.3 * Mixture; // Allows an AFR of infinity:1 to 11.3075:1
+  double thi_sea_level = 1.3 * in.MixturePos[EngineNumber]; // Allows an AFR of infinity:1 to 11.3075:1
   equivalence_ratio = thi_sea_level * 101325.0 / p_amb;
-//  double AFR = 10+(12*(1-Mixture));// mixture 10:1 to 22:1
+//  double AFR = 10+(12*(1-in.Mixture[EngineNumber]));// mixture 10:1 to 22:1
 //  m_dot_fuel = m_dot_air / AFR;
   m_dot_fuel = (m_dot_air * equivalence_ratio) / 14.7;
   FuelFlowRate =  m_dot_fuel * 2.2046;  // kg to lb
+  if(Starved) // There is no fuel, so zero out the flows we've calculated so far
+  {
+    equivalence_ratio = 0.0;
+    FuelFlowRate = 0.0;
+    m_dot_fuel = 0.0;
+  }
   FuelFlow_pph = FuelFlowRate  * 3600;  // seconds to hours
   FuelFlow_gph = FuelFlow_pph / 6.0;    // Assumes 6 lbs / gallon
 }
@@ -773,8 +797,12 @@ void FGPiston::doEGT(void)
     ExhaustGasTemp_degK = T_amb + delta_T_exhaust;
   } else {  // Drop towards ambient - guess an appropriate time constant for now
     combustion_efficiency = 0;
-    dEGTdt = (RankineToKelvin(Atmosphere->GetTemperature()) - ExhaustGasTemp_degK) / 100.0;
-    delta_T_exhaust = dEGTdt * dt;
+    dEGTdt = (RankineToKelvin(in.Temperature) - ExhaustGasTemp_degK) / 100.0;
+    if (in.TotalDeltaT > 0.0)
+      delta_T_exhaust = dEGTdt * in.TotalDeltaT;
+    else
+      delta_T_exhaust = dEGTdt / 120;
+
     ExhaustGasTemp_degK += delta_T_exhaust;
   }
 }
@@ -812,8 +840,12 @@ void FGPiston::doCHT(void)
 
   double HeatCapacityCylinderHead = CpCylinderHead * MassCylinderHead;
 
-  CylinderHeadTemp_degK +=
-    (dqdt_cylinder_head / HeatCapacityCylinderHead) * dt;
+  if (in.TotalDeltaT > 0.0)
+    CylinderHeadTemp_degK +=
+      (dqdt_cylinder_head / HeatCapacityCylinderHead) * in.TotalDeltaT;
+  else 
+    CylinderHeadTemp_degK +=
+      (dqdt_cylinder_head / HeatCapacityCylinderHead) / 120.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -847,7 +879,10 @@ void FGPiston::doOilTemperature(void)
 
   double dOilTempdt = (target_oil_temp - OilTemp_degK) / time_constant;
 
-  OilTemp_degK += (dOilTempdt * dt);
+  if (in.TotalDeltaT > 0.0)
+    OilTemp_degK += (dOilTempdt * in.TotalDeltaT);
+  else 
+    OilTemp_degK += (dOilTempdt / 120.0);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -875,6 +910,30 @@ void FGPiston::doOilPressure(void)
   OilPressure_psi += (Design_Oil_Temp - OilTemp_degK) * Oil_Viscosity_Index * OilPressure_psi / Oil_Press_Relief_Valve;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+//
+// This is a local copy of the same function in FGStandardAtmosphere.
+
+double FGPiston::GetStdPressure100K(double altitude) const
+{
+  // Limit this equation to input altitudes of 100000 ft.
+  if (altitude > 100000.0) altitude = 100000.0;
+
+  double alt[5];
+  const double coef[5] = {  2116.217,
+                          -7.648932746E-2,
+                           1.0925498604E-6,
+                          -7.1135726027E-12,
+                           1.7470331356E-17 };
+
+  alt[0] = 1;
+  for (int pwr=1; pwr<=4; pwr++) alt[pwr] = alt[pwr-1]*altitude;
+
+  double press = 0.0;
+  for (int ctr=0; ctr<=4; ctr++) press += coef[ctr]*alt[ctr];
+  return press;
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 string FGPiston::GetEngineLabels(const string& delimiter)
diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.h b/src/FDM/JSBSim/models/propulsion/FGPiston.h
index 4a536b5d0..2174b806a 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPiston.h
+++ b/src/FDM/JSBSim/models/propulsion/FGPiston.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PISTON "$Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $";
+#define ID_PISTON "$Id: FGPiston.h,v 1.31 2011/08/04 13:45:42 jberndt Exp $";
 #define FG_MAX_BOOST_SPEEDS 3
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -198,7 +198,7 @@ boostspeed they refer to:
     @author David Megginson (initial porting and additional code)
     @author Ron Jensen (additional engine code)
     @see Taylor, Charles Fayette, "The Internal Combustion Engine in Theory and Practice"
-    @version $Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $
+    @version $Id: FGPiston.h,v 1.31 2011/08/04 13:45:42 jberndt Exp $
   */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -209,7 +209,7 @@ class FGPiston : public FGEngine
 {
 public:
   /// Constructor
-  FGPiston(FGFDMExec* exec, Element* el, int engine_number);
+  FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Inputs& input);
   /// Destructor
   ~FGPiston();
 
@@ -244,9 +244,6 @@ private:
   double FMEPDynamic;
   double FMEPStatic;
 
-  // timestep
-  double dt;
-
   void doEngineStartup(void);
   void doBoostControl(void);
   void doMAP(void);
@@ -257,6 +254,7 @@ private:
   void doCHT(void);
   void doOilPressure(void);
   void doOilTemperature(void);
+  double GetStdPressure100K(double altitude) const;
 
   int InitRunning(void);
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
index 64ae65574..6d86d134d 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
@@ -39,16 +39,13 @@ INCLUDES
 #include <sstream>
 
 #include "FGPropeller.h"
-#include "models/FGPropagate.h"
-#include "models/FGAtmosphere.h"
-#include "models/FGAuxiliary.h"
 #include "input_output/FGXMLElement.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.34 2011/06/16 14:54:06 jentron Exp $";
+static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.36 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_PROPELLER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -195,19 +192,18 @@ FGPropeller::~FGPropeller()
 
 double FGPropeller::Calculate(double EnginePower)
 {
-  double omega, alpha, beta, PowerAvailable;
+  double omega, PowerAvailable;
 
-  double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
-  double rho = fdmex->GetAtmosphere()->GetDensity();
+  double Vel = in.AeroUVW(eU);
+  double rho = in.Density;
   double RPS = RPM/60.0;
 
-  PowerAvailable = EnginePower - GetPowerRequired();
-
   // Calculate helical tip Mach
   double Area = 0.25*Diameter*Diameter*M_PI;
   double Vtip = RPS * Diameter * M_PI;
-  HelicalTipMach = sqrt(Vtip*Vtip + Vel*Vel) / 
-                   fdmex->GetAtmosphere()->GetSoundSpeed(); 
+  HelicalTipMach = sqrt(Vtip*Vtip + Vel*Vel) / in.Soundspeed; 
+
+  PowerAvailable = EnginePower - GetPowerRequired();
 
   if (RPS > 0.0) J = Vel / (Diameter * RPS); // Calculate J normally
   else           J = Vel / Diameter;      
@@ -225,10 +221,8 @@ double FGPropeller::Calculate(double EnginePower)
   if (CtMach) ThrustCoeff *= CtMach->GetValue(HelicalTipMach);
 
   if (P_Factor > 0.0001) {
-    alpha = fdmex->GetAuxiliary()->Getalpha();
-    beta  = fdmex->GetAuxiliary()->Getbeta();
-    SetActingLocationY( GetLocationY() + P_Factor*alpha*Sense);
-    SetActingLocationZ( GetLocationZ() + P_Factor*beta*Sense);
+    SetActingLocationY( GetLocationY() + P_Factor*in.Alpha*Sense);
+    SetActingLocationZ( GetLocationZ() + P_Factor*in.Beta*Sense);
   }
 
   Thrust = ThrustCoeff*RPS*RPS*D4*rho;
@@ -258,7 +252,7 @@ double FGPropeller::Calculate(double EnginePower)
 
   // Transform Torque and momentum first, as PQR is used in this
   // equation and cannot be transformed itself.
-  vMn = fdmex->GetPropagate()->GetPQR()*(Transform()*vH) + Transform()*vTorque;
+  vMn = in.PQR*(Transform()*vH) + Transform()*vTorque;
 
   return Thrust; // return thrust in pounds
 }
@@ -268,8 +262,8 @@ double FGPropeller::Calculate(double EnginePower)
 double FGPropeller::GetPowerRequired(void)
 {
   double cPReq, J;
-  double rho = fdmex->GetAtmosphere()->GetDensity();
-  double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
+  double rho = in.Density;
+  double Vel = in.AeroUVW(eU);
   double RPS = RPM / 60.0;
 
   if (RPS != 0.0) J = Vel / (Diameter * RPS);
diff --git a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp
index f8fb091cb..143c71402 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp
@@ -41,23 +41,21 @@ INCLUDES
 #include <iostream>
 #include <sstream>
 #include "FGRocket.h"
-#include "models/FGPropulsion.h"
 #include "FGThruster.h"
-#include "FGTank.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRocket.cpp,v 1.23 2011/01/24 13:01:56 jberndt Exp $";
+static const char *IdSrc = "$Id: FGRocket.cpp,v 1.26 2011/08/04 13:45:42 jberndt Exp $";
 static const char *IdHdr = ID_ROCKET;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGRocket::FGRocket(FGFDMExec* exec, Element *el, int engine_number)
-  : FGEngine(exec, el, engine_number)
+FGRocket::FGRocket(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
+  : FGEngine(exec, el, engine_number, input)
 {
   Type = etRocket;
   Element* thrust_table_element = 0;
@@ -66,6 +64,7 @@ FGRocket::FGRocket(FGFDMExec* exec, Element *el, int engine_number)
   previousFuelNeedPerTank = 0.0;
   previousOxiNeedPerTank = 0.0;
   PropellantFlowRate = 0.0;
+  TotalPropellantExpended = 0.0;
   FuelFlowRate = FuelExpended = 0.0;
   OxidizerFlowRate = OxidizerExpended = 0.0;
   SLOxiFlowMax = SLFuelFlowMax = 0.0;
@@ -126,14 +125,10 @@ void FGRocket::Calculate(void)
 {
   if (FDMExec->IntegrationSuspended()) return;
 
-  double dT = FDMExec->GetDeltaT()*Propulsion->GetRate();
-
   RunPreFunctions();
 
-  if (!Flameout && !Starved) ConsumeFuel();
-
-  PropellantFlowRate = (FuelExpended + OxidizerExpended)/dT;
-  Throttle = FCS->GetThrottlePos(EngineNumber);
+  PropellantFlowRate = (FuelExpended + OxidizerExpended)/in.TotalDeltaT;
+  TotalPropellantExpended += FuelExpended + OxidizerExpended;
 
   // If there is a thrust table, it is a function of propellant burned. The
   // engine is started when the throttle is advanced to 1.0. After that, it
@@ -141,30 +136,23 @@ void FGRocket::Calculate(void)
 
   if (ThrustTable != 0L) { // Thrust table given -> Solid fuel used
 
-    if ((Throttle == 1 || BurnTime > 0.0 ) && !Starved) {
-      double TotalEngineFuelBurned=0.0;
-      for (int i=0; i<(int)SourceTanks.size(); i++) {
-        FGTank* tank = Propulsion->GetTank(i);
-        if (SourceTanks[i] == 1) {
-          TotalEngineFuelBurned += tank->GetCapacity() - tank->GetContents();
-        }
-      }
+    if ((in.ThrottlePos[EngineNumber] == 1 || BurnTime > 0.0 ) && !Starved) {
 
-      VacThrust = ThrustTable->GetValue(TotalEngineFuelBurned)
+      VacThrust = ThrustTable->GetValue(TotalPropellantExpended)
                 * (ThrustVariation + 1)
                 * (TotalIspVariation + 1);
       if (BurnTime <= BuildupTime && BuildupTime > 0.0) {
         VacThrust *= sin((BurnTime/BuildupTime)*M_PI/2.0);
         // VacThrust *= (1-cos((BurnTime/BuildupTime)*M_PI))/2.0; // 1 - cos approach
       }
-      BurnTime += FDMExec->GetDeltaT(); // Increment burn time
+      BurnTime += in.TotalDeltaT; // Increment burn time
     } else {
       VacThrust = 0.0;
     }
 
   } else { // liquid fueled rocket assumed
 
-    if (Throttle < MinThrottle || Starved) { // Combustion not supported
+    if (in.ThrottlePos[EngineNumber] < MinThrottle || Starved) { // Combustion not supported
 
       PctPower = 0.0; // desired thrust
       Flameout = true;
@@ -172,12 +160,9 @@ void FGRocket::Calculate(void)
 
     } else { // Calculate thrust
 
-      // This is nonsensical. Max throttle should be assumed to be 1.0. One might
-      // conceivably have a throttle setting > 1.0 for some rocket engines. But, 1.0
-      // should always be the default.
       // PctPower = Throttle / MaxThrottle; // Min and MaxThrottle range from 0.0 to 1.0, normally.
       
-      PctPower = Throttle;
+      PctPower = in.ThrottlePos[EngineNumber];
       Flameout = false;
       VacThrust = Isp * PropellantFlowRate;
 
@@ -185,79 +170,12 @@ void FGRocket::Calculate(void)
 
   } // End thrust calculations
 
-  It += Thruster->Calculate(VacThrust) * dT;
+  LoadThrusterInputs();
+  It += Thruster->Calculate(VacThrust) * in.TotalDeltaT;
 
   RunPostFunctions();
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-// This overrides the base class ConsumeFuel() function, for special rocket
-// engine processing.
-
-void FGRocket::ConsumeFuel(void)
-{
-  unsigned int i;
-  FGTank* Tank;
-  bool haveOxTanks = false;
-  double Fshortage=0, Oshortage=0, TanksWithFuel=0, TanksWithOxidizer=0;
-
-  if (FuelFreeze) return;
-  if (FDMExec->GetTrimStatus()) return;
-
-  // Count how many assigned tanks have fuel for this engine at this time.
-  // If there is/are fuel tanks but no oxidizer tanks, this indicates
-  // a solid rocket is being modeled.
-
-  for (i=0; i<SourceTanks.size(); i++) {
-    Tank = Propulsion->GetTank(i);
-    switch(Tank->GetType()) {
-      case FGTank::ttFUEL:
-        if (Tank->GetContents() > 0.0 && Tank->GetSelected() && SourceTanks[i] > 0) ++TanksWithFuel;
-        break;
-      case FGTank::ttOXIDIZER:
-        if (Tank->GetSelected() && SourceTanks[i] > 0) {
-          haveOxTanks = true;
-          if (Tank->GetContents() > 0.0) ++TanksWithOxidizer;
-        }
-        break;
-    }
-  }
-
-  // If this engine has burned out, it is starved.
-
-  if (TanksWithFuel==0 || (haveOxTanks && TanksWithOxidizer==0)) {
-    Starved = true;
-    return;
-  }
-
-  // Expend fuel from the engine's tanks if the tank is selected as a source
-  // for this engine.
-
-  double fuelNeedPerTank = 0;
-  double oxiNeedPerTank = 0;
-
-  if (TanksWithFuel > 0) fuelNeedPerTank = CalcFuelNeed()/TanksWithFuel;
-  if (TanksWithOxidizer > 0) oxiNeedPerTank = CalcOxidizerNeed()/TanksWithOxidizer;
-
-  for (i=0; i<SourceTanks.size(); i++) {
-    Tank = Propulsion->GetTank(i);
-    if ( ! Tank->GetSelected() || SourceTanks[i] == 0) continue; // If this tank is not selected as a source, skip it.
-    switch(Tank->GetType()) {
-      case FGTank::ttFUEL:
-        Fshortage += Tank->Drain(2.0*fuelNeedPerTank - previousFuelNeedPerTank);
-        previousFuelNeedPerTank = fuelNeedPerTank;
-        break;
-      case FGTank::ttOXIDIZER:
-        Oshortage += Tank->Drain(2.0*oxiNeedPerTank - previousOxiNeedPerTank);
-        previousOxiNeedPerTank = oxiNeedPerTank;
-        break;
-    }
-  }
-
-  if (Fshortage < 0.00 || (haveOxTanks && Oshortage < 0.00)) Starved = true;
-  else Starved = false;
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // 
 // The FuelFlowRate can be affected by the TotalIspVariation value (settable
@@ -267,8 +185,6 @@ void FGRocket::ConsumeFuel(void)
 
 double FGRocket::CalcFuelNeed(void)
 {
-  double dT = FDMExec->GetDeltaT()*Propulsion->GetRate();
-
   if (ThrustTable != 0L) {          // Thrust table given - infers solid fuel
     FuelFlowRate = VacThrust/Isp;   // This calculates wdot (weight flow rate in lbs/sec)
     FuelFlowRate /= (1 + TotalIspVariation);
@@ -276,7 +192,7 @@ double FGRocket::CalcFuelNeed(void)
     FuelFlowRate = SLFuelFlowMax*PctPower;
   }
 
-  FuelExpended = FuelFlowRate*dT; // For this time step ...
+  FuelExpended = FuelFlowRate * in.TotalDeltaT; // For this time step ...
   return FuelExpended;
 }
 
@@ -284,9 +200,8 @@ double FGRocket::CalcFuelNeed(void)
 
 double FGRocket::CalcOxidizerNeed(void)
 {
-  double dT = FDMExec->GetDeltaT()*Propulsion->GetRate();
-  OxidizerFlowRate = SLOxiFlowMax*PctPower;
-  OxidizerExpended = OxidizerFlowRate*dT;
+  OxidizerFlowRate = SLOxiFlowMax * PctPower;
+  OxidizerExpended = OxidizerFlowRate * in.TotalDeltaT;
   return OxidizerExpended;
 }
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGRocket.h b/src/FDM/JSBSim/models/propulsion/FGRocket.h
index 38e367510..b375c47d6 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRocket.h
+++ b/src/FDM/JSBSim/models/propulsion/FGRocket.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ROCKET "$Id: FGRocket.h,v 1.14 2010/08/21 18:08:25 jberndt Exp $"
+#define ID_ROCKET "$Id: FGRocket.h,v 1.17 2011/08/04 13:45:42 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -118,13 +118,11 @@ for the rocket engine to be throttle up to 1. At that time, the solid rocket
 fuel begins burning and thrust is provided.
 
     @author Jon S. Berndt
-    $Id: FGRocket.h,v 1.14 2010/08/21 18:08:25 jberndt Exp $
+    $Id: FGRocket.h,v 1.17 2011/08/04 13:45:42 jberndt Exp $
     @see FGNozzle,
     FGThruster,
     FGForce,
     FGEngine,
-    FGPropulsion,
-    FGTank
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -138,7 +136,7 @@ public:
       @param exec pointer to JSBSim parent object, the FDM Executive.
       @param el a pointer to the XML Element instance representing the engine.
       @param engine_number engine number */
-  FGRocket(FGFDMExec* exec, Element *el, int engine_number);
+  FGRocket(FGFDMExec* exec, Element *el, int engine_number, struct FGEngine::Inputs& input);
 
   /** Destructor */
   ~FGRocket(void);
@@ -146,6 +144,18 @@ public:
   /** Determines the thrust.*/
   void Calculate(void);
 
+  /** The fuel need is calculated based on power levels and flow rate for that
+      power level. It is also turned from a rate into an actual amount (pounds)
+      by multiplying it by the delta T and the rate.
+      @return Total fuel requirement for this engine in pounds. */
+  double CalcFuelNeed(void);
+
+  /** The oxidizer need is calculated based on power levels and flow rate for that
+      power level. It is also turned from a rate into an actual amount (pounds)
+      by multiplying it by the delta T and the rate.
+      @return Total oxidizer requirement for this engine in pounds. */
+  double CalcOxidizerNeed(void);
+
   /** Gets the total impulse of the rocket.
       @return The cumulative total impulse of the rocket up to this time.*/
   double GetTotalImpulse(void) const {return It;}
@@ -188,25 +198,6 @@ public:
   double GetTotalIspVariation(void) const {return TotalIspVariation;}
 
 private:
-  /** Reduces the fuel in the active tanks by the amount required.
-      This function should be called from within the
-      derived class' Calculate() function before any other calculations are
-      done. This base class method removes fuel from the fuel tanks as
-      appropriate, and sets the starved flag if necessary. */
-  void ConsumeFuel(void);
-
-  /** The fuel need is calculated based on power levels and flow rate for that
-      power level. It is also turned from a rate into an actual amount (pounds)
-      by multiplying it by the delta T and the rate.
-      @return Total fuel requirement for this engine in pounds. */
-  double CalcFuelNeed(void);
-
-  /** The oxidizer need is calculated based on power levels and flow rate for that
-      power level. It is also turned from a rate into an actual amount (pounds)
-      by multiplying it by the delta T and the rate.
-      @return Total oxidizer requirement for this engine in pounds. */
-  double CalcOxidizerNeed(void);
-
   /** Returns the vacuum thrust.
       @return The vacuum thrust in lbs. */
   double GetVacThrust(void) const {return VacThrust;}
@@ -223,6 +214,7 @@ private:
   double previousFuelNeedPerTank;
   double previousOxiNeedPerTank;
   double OxidizerExpended;
+  double TotalPropellantExpended;
   double SLOxiFlowMax;
   double OxidizerFlowRate;
   double PropellantFlowRate;
diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
index 1ac58405a..401d6a0b9 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
@@ -45,20 +45,17 @@ INCLUDES
 #include <sstream>
 
 #include "FGRotor.h"
-
-#include "models/FGPropagate.h"
-#include "models/FGAtmosphere.h"
-#include "models/FGAuxiliary.h"
+#include "input_output/FGXMLElement.h"
 #include "models/FGMassBalance.h"
 
-#include "input_output/FGXMLElement.h"
-
-
-using namespace std;
+using std::cerr;
+using std::endl;
+using std::ostringstream;
+using std::cout;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRotor.cpp,v 1.12 2011/03/10 01:35:25 dpculp Exp $";
+static const char *IdSrc = "$Id: FGRotor.cpp,v 1.13 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_ROTOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -77,46 +74,28 @@ CLASS IMPLEMENTATION
 // Constructor
 
 FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
-                    : FGThruster(exec, rotor_element, num),
-                    
-
-  // environment
-  dt(0.0), rho(0.002356),
-
-  // configuration parameters
-  Radius(0.0), BladeNum(0),
-
-  Sense(1.0), NominalRPM(0.0), ExternalRPM(0), RPMdefinition(0), ExtRPMsource(NULL),
-
-  BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0),
-  BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0),
-  InflowLag(0.0),
-  TipLossB(0.0),
-
-  GroundEffectExp(0.0), GroundEffectShift(0.0),
-
-  // derived parameters
-  LockNumberByRho(0.0), Solidity(0.0), 
-
-  // dynamic values
-  RPM(0.0), Omega(0.0),
-
-  beta_orient(0.0),
-  a0(0.0), a_1(0.0), b_1(0.0), a_dw(0.0), a1s(0.0), b1s(0.0),
-
-  H_drag(0.0), J_side(0.0), Torque(0.0), C_T(0.0),
-
-  lambda(-0.001), mu(0.0), nu(0.001), v_induced(0.0),
-  theta_downwash(0.0), phi_downwash(0.0),
-
-  // control
-  ControlMap(eMainCtrl),
-  CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
-  BrakeCtrlNorm(0.0), MaxBrakePower(0.0),
-
-  // free-wheeling-unit (FWU)
-  FreeWheelPresent(0), FreeWheelThresh(0.0), FreeWheelTransmission(0.0)
-
+  : FGThruster(exec, rotor_element, num),
+    rho(0.002356),                                  // environment
+    Radius(0.0), BladeNum(0),                       // configuration parameters
+    Sense(1.0), NominalRPM(0.0), ExternalRPM(0),
+    RPMdefinition(0), ExtRPMsource(NULL),
+    BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0),
+    BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0),
+    InflowLag(0.0), TipLossB(0.0),
+    GroundEffectExp(0.0), GroundEffectShift(0.0),
+    LockNumberByRho(0.0), Solidity(0.0),            // derived parameters
+    RPM(0.0), Omega(0.0),                           // dynamic values
+    beta_orient(0.0),
+    a0(0.0), a_1(0.0), b_1(0.0), a_dw(0.0),
+    a1s(0.0), b1s(0.0),
+    H_drag(0.0), J_side(0.0), Torque(0.0), C_T(0.0),
+    lambda(-0.001), mu(0.0), nu(0.001), v_induced(0.0),
+    theta_downwash(0.0), phi_downwash(0.0),
+    ControlMap(eMainCtrl),                          // control
+    CollectiveCtrl(0.0), LateralCtrl(0.0), LongitudinalCtrl(0.0),
+    BrakeCtrlNorm(0.0), MaxBrakePower(0.0),
+    FreeWheelPresent(0), FreeWheelThresh(0.0),      // free-wheeling-unit (FWU)
+    FreeWheelTransmission(0.0)
 {
   FGColumnVector3 location(0.0, 0.0, 0.0), orientation(0.0, 0.0, 0.0);
   Element *thruster_element;
@@ -194,7 +173,7 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
 
   // smooth out jumps in hagl reported, otherwise the ground effect
   // calculation would cause jumps too. 1Hz seems sufficient.
-  damp_hagl = Filter(1.0,dt);
+  damp_hagl = Filter(1.0, dt);
 
   // avoid too abrupt changes in power transmission
   FreeWheelLag = Filter(200.0,dt);
@@ -583,21 +562,14 @@ void FGRotor::CalcStatePart1(void)
   double B_IC;       // longitudinal (pitch) control in radians
   double theta_col;  // rotor collective pitch in radians
 
-  double Vt ;
-
-  FGColumnVector3 UVW_h, PQR_h;
   FGColumnVector3 vHub_ca, avFus_ca;
 
-  double h_agl_ft, filtered_hagl = 0.0;
+  double filtered_hagl = 0.0;
   double ge_factor = 1.0;
 
   // fetch needed values from environment
-  Vt = fdmex->GetAuxiliary()->GetVt(); // total vehicle velocity including wind
-  dt = fdmex->GetDeltaT();
-  rho = fdmex->GetAtmosphere()->GetDensity(); // slugs/ft^3.
-  UVW_h = fdmex->GetAuxiliary()->GetAeroUVW();
-  PQR_h = fdmex->GetAuxiliary()->GetAeroPQR();
-  h_agl_ft = fdmex->GetPropagate()->GetDistanceAGL();
+  rho = in.Density; // slugs/ft^3.
+  double h_agl_ft = in.H_agl;
   // update InvTransform, the rotor orientation could have been altered
   InvTransform = Transform().Transposed();
 
@@ -628,9 +600,9 @@ void FGRotor::CalcStatePart1(void)
 
   // all set, start calculations
 
-  vHub_ca  = hub_vel_body2ca(UVW_h, PQR_h, A_IC, B_IC);
+  vHub_ca  = hub_vel_body2ca(in.AeroUVW, in.AeroPQR, A_IC, B_IC);
 
-  avFus_ca = fus_angvel_body2ca(PQR_h);
+  avFus_ca = fus_angvel_body2ca(in.AeroPQR);
 
   calc_flow_and_thrust(theta_col, vHub_ca(eU), vHub_ca(eW), ge_factor);
 
@@ -643,8 +615,8 @@ void FGRotor::CalcStatePart1(void)
   calc_torque(theta_col);
 
   // Fixme: only valid for a 'decent' rotor
-  theta_downwash = atan2( - UVW_h(eU), v_induced - UVW_h(eW));
-  phi_downwash   = atan2(   UVW_h(eV), v_induced - UVW_h(eW));
+  theta_downwash = atan2( -in.AeroUVW(eU), v_induced - in.AeroUVW(eW));
+  phi_downwash   = atan2(  in.AeroUVW(eV), v_induced - in.AeroUVW(eW));
 
   vFn = body_forces(A_IC, B_IC);
   vMn = Transform() * body_moments(A_IC, B_IC); 
@@ -658,7 +630,7 @@ void FGRotor::CalcStatePart2(double PowerAvailable)
   if (! ExternalRPM) {
     // calculate new RPM
     double ExcessTorque = PowerAvailable / Omega;
-    double deltaOmega   = ExcessTorque / PolarMoment * dt;
+    double deltaOmega   = ExcessTorque / PolarMoment * in.TotalDeltaT;
     RPM += deltaOmega/(2.0*M_PI) * 60.0;
     if (RPM < 0.0) RPM = 0.0; // Engine won't turn backwards
   }
diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.cpp b/src/FDM/JSBSim/models/propulsion/FGTank.cpp
index a39fbcec3..a0417d540 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTank.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTank.cpp
@@ -38,7 +38,6 @@ INCLUDES
 
 #include "FGTank.h"
 #include "FGFDMExec.h"
-#include "models/FGAuxiliary.h"
 #include "input_output/FGXMLElement.h"
 #include "input_output/FGPropertyManager.h"
 #include <iostream>
@@ -48,7 +47,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTank.cpp,v 1.30 2011/06/21 04:41:54 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTank.cpp,v 1.31 2011/08/03 03:21:06 jberndt Exp $";
 static const char *IdHdr = ID_TANK;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -66,6 +65,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
   InitialTemperature = Temperature = -9999.0;
   Ixx = Iyy = Izz = 0.0;
   Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
+  PreviousUsed = 0.0;
   ExternalFlow = 0.0;
   InitialStandpipe = 0.0;
   Capacity = 0.00001;
@@ -192,6 +192,7 @@ void FGTank::ResetToIC(void)
   SetContents ( InitialContents );
   PctFull = 100.0*Contents/Capacity;
   SetPriority( InitialPriority );
+  PreviousUsed = 0.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -212,6 +213,7 @@ const double FGTank::GetXYZ(int idx)
 
 double FGTank::Drain(double used)
 {
+//  double AmountToDrain = 2.0*used - PreviousUsed;
   double remaining = Contents - used;
 
   if (remaining >= 0) { // Reduce contents by amount used.
@@ -224,7 +226,7 @@ double FGTank::Drain(double used)
     Contents = 0.0;
     PctFull = 0.0;
   }
-
+//  PreviousUsed = AmountToDrain;
   if (grainType != gtUNKNOWN) CalculateInertias();
 
   return remaining;
@@ -271,7 +273,7 @@ void FGTank::SetContentsGallons(double gallons)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-double FGTank::Calculate(double dt)
+double FGTank::Calculate(double dt, double TAT_C)
 {
   if(ExternalFlow < 0.) Drain( -ExternalFlow *dt);
   else Fill(ExternalFlow * dt);
@@ -279,8 +281,7 @@ double FGTank::Calculate(double dt)
   if (Temperature == -9999.0) return 0.0;
   double HeatCapacity = 900.0;        // Joules/lbm/C
   double TempFlowFactor = 1.115;      // Watts/sqft/C
-  double TAT = Exec->GetAuxiliary()->GetTAT_C();
-  double Tdiff = TAT - Temperature;
+  double Tdiff = TAT_C - Temperature;
   double dTemp = 0.0;                 // Temp change due to one surface
   if (fabs(Tdiff) > 0.1) {
     dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity);
diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.h b/src/FDM/JSBSim/models/propulsion/FGTank.h
index 4bf420a38..dc929beb5 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTank.h
+++ b/src/FDM/JSBSim/models/propulsion/FGTank.h
@@ -52,7 +52,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_TANK "$Id: FGTank.h,v 1.23 2011/06/13 15:23:09 jentron Exp $"
+#define ID_TANK "$Id: FGTank.h,v 1.24 2011/08/03 03:21:06 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -218,9 +218,10 @@ public:
   /** Performs local, tanks-specific calculations, such as fuel temperature.
       This function calculates the temperature of the fuel in the tank.
       @param dt the time step for this model.
+      @param TempC the Total Air Temperature in degrees Celsius.
       @return the current temperature in degrees Celsius.
   */
-  double Calculate(double dt);
+  double Calculate(double dt, double TempC);
 
   /** Retrieves the type of tank: Fuel or Oxidizer.
       @return the tank type, 0 for undefined, 1 for fuel, and 2 for oxidizer.
@@ -318,6 +319,7 @@ private:
   double Izz;
   double PctFull;
   double Contents, InitialContents;
+  double PreviousUsed;
   double Area;
   double Temperature, InitialTemperature;
   double Standpipe, InitialStandpipe;
@@ -326,6 +328,7 @@ private:
   int Priority, InitialPriority;
   FGFDMExec* Exec;
   FGPropertyManager* PropertyManager;
+
   void CalculateInertias(void);
   void Debug(int from);
 };
diff --git a/src/FDM/JSBSim/models/propulsion/FGThruster.h b/src/FDM/JSBSim/models/propulsion/FGThruster.h
index 4ef760e98..04313d797 100644
--- a/src/FDM/JSBSim/models/propulsion/FGThruster.h
+++ b/src/FDM/JSBSim/models/propulsion/FGThruster.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_THRUSTER "$Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $"
+#define ID_THRUSTER "$Id: FGThruster.h,v 1.17 2011/08/03 03:21:06 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -74,7 +74,7 @@ CLASS DOCUMENTATION
     1.57 (pi/2) results in no thrust at all.
  
     @author Jon Berndt
-    @version $Id: FGThruster.h,v 1.16 2011/03/10 01:35:25 dpculp Exp $
+    @version $Id: FGThruster.h,v 1.17 2011/08/03 03:21:06 jberndt Exp $
     */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -112,6 +112,20 @@ public:
   virtual string GetThrusterLabels(int id, string delimeter);
   virtual string GetThrusterValues(int id, string delimeter);
 
+  struct Inputs {
+    double TotalDeltaT;
+    double H_agl;
+    FGColumnVector3 PQR;
+    FGColumnVector3 AeroPQR;
+    FGColumnVector3 AeroUVW;
+    double Density;
+    double Pressure;
+    double Soundspeed;
+    double Alpha;
+    double Beta;
+    double Vt;
+  } in;
+
 protected:
   eType Type;
   string Name;
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
index c4cfc3033..5b676ed8f 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
@@ -41,17 +41,15 @@ INCLUDES
 
 #include <iostream>
 #include <sstream>
+
 #include "FGTurbine.h"
 #include "FGThruster.h"
-#include "models/FGPropulsion.h"
-#include "models/FGAuxiliary.h"
-#include "models/FGAtmosphere.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.32 2011/06/07 00:28:03 jentron Exp $";
+static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.35 2011/08/04 13:45:42 jberndt Exp $";
 static const char *IdHdr = ID_TURBINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -59,8 +57,8 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number)
-  : FGEngine(exec, el, engine_number)
+FGTurbine::FGTurbine(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
+  : FGEngine(exec, el, engine_number, input)
 {
   Type = etTurbine;
 
@@ -103,12 +101,12 @@ void FGTurbine::ResetToIC(void)
   N1 = N2 = 0.0;
   N2norm = 0.0;
   correctedTSFC = TSFC;
-  ThrottlePos = AugmentCmd = 0.0;
+  AugmentCmd = 0.0;
   InletPosition = NozzlePosition = 1.0;
   Stalled = Seized = Overtemp = Fire = Augmentation = Injection = Reversed = false;
   Cutoff = true;
   phase = tpOff;
-  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+  TAT = (in.TotalTempearture - 491.69) * 0.5555556;
   EGT_degC = TAT;
   OilTemp_degK = TAT + 273.0;
 }
@@ -123,10 +121,9 @@ void FGTurbine::Calculate(void)
 
   RunPreFunctions();
 
-  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
-  double qbar = Auxiliary->Getqbar();
-  dt = FDMExec->GetDeltaT() * Propulsion->GetRate();
-  ThrottlePos = FCS->GetThrottlePos(EngineNumber);
+  ThrottlePos = in.ThrottlePos[EngineNumber];
+
+  TAT = (in.TotalTempearture - 491.69) * 0.5555556;
   if (ThrottlePos > 1.0) {
     AugmentCmd = ThrottlePos - 1.0;
     ThrottlePos -= AugmentCmd;
@@ -135,7 +132,7 @@ void FGTurbine::Calculate(void)
   }
 
   // When trimming is finished check if user wants engine OFF or RUNNING
-  if ((phase == tpTrim) && (dt > 0)) {
+  if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
     if (Running && !Starved) {
       phase = tpRun;
       N2 = IdleN2 + ThrottlePos * N2_factor;
@@ -155,12 +152,12 @@ void FGTurbine::Calculate(void)
   }
 
   // start
-  if ((Starter == true) || (qbar > 30.0)) {
+  if ((Starter == true) || (in.qbar > 30.0)) {
     if (!Running && !Cutoff && (N2 > 15.0)) phase = tpStart;
   }
 
   if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
-  if (dt == 0) phase = tpTrim;
+  if (in.TotalDeltaT == 0) phase = tpTrim;
   if (Starved) phase = tpOff;
   if (Stalled) phase = tpStall;
   if (Seized) phase = tpSeize;
@@ -185,18 +182,16 @@ void FGTurbine::Calculate(void)
 
 double FGTurbine::Off(void)
 {
-  double qbar = Auxiliary->Getqbar();
   Running = false;
   FuelFlow_pph = Seek(&FuelFlow_pph, 0, 1000.0, 10000.0);
-  N1 = Seek(&N1, qbar/10.0, N1/2.0, N1/2.0);
-  N2 = Seek(&N2, qbar/15.0, N2/2.0, N2/2.0);
+  N1 = Seek(&N1, in.qbar/10.0, N1/2.0, N1/2.0);
+  N2 = Seek(&N2, in.qbar/15.0, N2/2.0, N2/2.0);
   EGT_degC = Seek(&EGT_degC, TAT, 11.7, 7.3);
   OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0.2, 0.2);
   OilPressure_psi = N2 * 0.62;
   NozzlePosition = Seek(&NozzlePosition, 1.0, 0.8, 0.8);
   EPR = Seek(&EPR, 1.0, 0.2, 0.2);
   Augmentation = false;
-  ConsumeFuel();  
   return 0.0;
 }
 
@@ -206,8 +201,8 @@ double FGTurbine::Run()
 {
   double idlethrust, milthrust, thrust;
   double spoolup;                        // acceleration in pct/sec
-  double sigma = Atmosphere->GetDensityRatio();
-  double T = Atmosphere->GetTemperature();
+  double sigma = in.DensityRatio;
+  double T = in.Temperature;
 
   idlethrust = MilThrust * IdleThrustLookup->GetValue();
   milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue();
@@ -261,7 +256,7 @@ double FGTurbine::Run()
   }
 
   if ((Injected == 1) && Injection) {
-    InjectionTimer += dt;
+    InjectionTimer += in.TotalDeltaT;
     if (InjectionTimer < InjectionTime) {
        thrust = thrust * InjectionLookup->GetValue();
     } else {
@@ -269,7 +264,6 @@ double FGTurbine::Run()
     }
   }
 
-  ConsumeFuel();
   if (Cutoff) phase = tpOff;
   if (Starved) phase = tpOff;
 
@@ -297,7 +291,6 @@ double FGTurbine::SpinUp(void)
 
 double FGTurbine::Start(void)
 {
-  double qbar = Auxiliary->Getqbar();
   if ((N2 > 15.0) && !Starved) {       // minimum 15% N2 needed for start
     Cranking = true;                   // provided for sound effects signal
     if (N2 < IdleN2) {
@@ -306,8 +299,7 @@ double FGTurbine::Start(void)
       EGT_degC = Seek(&EGT_degC, TAT + 363.1, 21.3, 7.3);
       FuelFlow_pph = IdleFF * N2 / IdleN2;
       OilPressure_psi = N2 * 0.62;
-      ConsumeFuel();
-      if ((Starter == false) && (qbar < 30.0)) phase = tpOff; // aborted start
+      if ((Starter == false) && (in.qbar < 30.0)) phase = tpOff; // aborted start
       }
     else {
       phase = tpRun;
@@ -328,12 +320,10 @@ double FGTurbine::Start(void)
 
 double FGTurbine::Stall(void)
 {
-  double qbar = Auxiliary->Getqbar();
   EGT_degC = TAT + 903.14;
   FuelFlow_pph = IdleFF;
-  N1 = Seek(&N1, qbar/10.0, 0, N1/10.0);
-  N2 = Seek(&N2, qbar/15.0, 0, N2/10.0);
-  ConsumeFuel();
+  N1 = Seek(&N1, in.qbar/10.0, 0, N1/10.0);
+  N2 = Seek(&N2, in.qbar/15.0, 0, N2/10.0);
   if (ThrottlePos < 0.01) {
     phase = tpRun;               // clear the stall with throttle to idle
     Stalled = false;
@@ -345,11 +335,9 @@ double FGTurbine::Stall(void)
 
 double FGTurbine::Seize(void)
 {
-    double qbar = Auxiliary->Getqbar();
     N2 = 0.0;
-    N1 = Seek(&N1, qbar/20.0, 0, N1/15.0);
+    N1 = Seek(&N1, in.qbar/20.0, 0, N1/15.0);
     FuelFlow_pph = Cutoff ? 0.0 : IdleFF;
-    ConsumeFuel();
     OilPressure_psi = 0.0;
     OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0, 0.2);
     Running = false;
@@ -395,9 +383,8 @@ double FGTurbine::Trim()
 
 double FGTurbine::CalcFuelNeed(void)
 {
-  double dT = FDMExec->GetDeltaT() * Propulsion->GetRate();
   FuelFlowRate = FuelFlow_pph / 3600.0; // Calculates flow in lbs/sec from lbs/hr
-  FuelExpended = FuelFlowRate * dT;     // Calculates fuel expended in this time step
+  FuelExpended = FuelFlowRate * in.TotalDeltaT;     // Calculates fuel expended in this time step
   return FuelExpended;
 }
 
@@ -415,10 +402,10 @@ double FGTurbine::GetPowerAvailable(void) {
 double FGTurbine::Seek(double *var, double target, double accel, double decel) {
   double v = *var;
   if (v > target) {
-    v -= dt * decel;
+    v -= in.TotalDeltaT * decel;
     if (v < target) v = target;
   } else if (v < target) {
-    v += dt * accel;
+    v += in.TotalDeltaT * accel;
     if (v > target) v = target;
   }
   return v;
@@ -488,7 +475,7 @@ bool FGTurbine::Load(FGFDMExec* exec, Element *el)
   delay = 90.0 / (BypassRatio + 3.0);
   N1_factor = MaxN1 - IdleN1;
   N2_factor = MaxN2 - IdleN2;
-  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+  OilTemp_degK = (in.TotalTempearture - 491.69) * 0.5555556 + 273.0;
   IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate
 
   bindmodel();
@@ -544,7 +531,8 @@ void FGTurbine::bindmodel()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-int FGTurbine::InitRunning(void) {
+int FGTurbine::InitRunning(void)
+{
   FDMExec->SuspendIntegration();
   Cutoff=false;
   Running=true;  
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.h b/src/FDM/JSBSim/models/propulsion/FGTurbine.h
index 907d08dd2..67816c191 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTurbine.h
+++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.h
@@ -42,7 +42,7 @@ INCLUDES
 
 #include "FGEngine.h"
 
-#define ID_TURBINE "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $"
+#define ID_TURBINE "$Id: FGTurbine.h,v 1.22 2011/08/04 13:45:42 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -150,7 +150,7 @@ CLASS DOCUMENTATION
     /engine/direct.xml
 </pre>
     @author David P. Culp
-    @version "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $"
+    @version "$Id: FGTurbine.h,v 1.22 2011/08/04 13:45:42 jberndt Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -164,7 +164,7 @@ public:
       @param Executive pointer to executive structure
       @param el pointer to the XML element representing the turbine engine
       @param engine_number engine number  */
-  FGTurbine(FGFDMExec* Executive, Element *el, int engine_number);
+  FGTurbine(FGFDMExec* Executive, Element *el, int engine_number, struct Inputs& input);
   /// Destructor
   ~FGTurbine();
 
@@ -233,10 +233,9 @@ private:
   double MaxN2;            ///< N2 at 100% throttle
   double IdleFF;           ///< Idle Fuel Flow (lbm/hr)
   double delay;            ///< Inverse spool-up time from idle to 100% (seconds)
-  double dt;               ///< Simulator time slice
   double N1_factor;        ///< factor to tie N1 and throttle
   double N2_factor;        ///< factor to tie N2 and throttle
-  double ThrottlePos;      ///< FCS-supplied throttle position
+  double ThrottlePos;      ///< FCS-supplied throttle position - modified for local use!
   double AugmentCmd;       ///< modulated afterburner command (0.0 to 1.0)
   double TAT;              ///< total air temperature (deg C)
   double N1_spinup;        ///< N1 spin up rate from starter (per second)
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
old mode 100644
new mode 100755
index acc35cca2..58188112a
--- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
@@ -44,25 +44,24 @@ INCLUDES
 
 #include <iostream>
 #include <sstream>
+
 #include "FGTurboProp.h"
 #include "FGPropeller.h"
 #include "FGRotor.h"
-#include "models/FGPropulsion.h"
-#include "models/FGAuxiliary.h"
 
 using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.19 2011/03/10 01:35:25 dpculp Exp $";
+static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.22 2011/08/04 13:45:42 jberndt Exp $";
 static const char *IdHdr = ID_TURBOPROP;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number)
-  : FGEngine(exec, el, engine_number),
+FGTurboProp::FGTurboProp(FGFDMExec* exec, Element *el, int engine_number, struct Inputs& input)
+  : FGEngine(exec, el, engine_number, input),
     ITT_N1(NULL), EnginePowerRPM_N1(NULL), EnginePowerVC(NULL)
 {
   SetDefaults();
@@ -151,7 +150,7 @@ bool FGTurboProp::Load(FGFDMExec* exec, Element *el)
   delay=1;
   N1_factor = MaxN1 - IdleN1;
   N2_factor = MaxN2 - IdleN2;
-  OilTemp_degK = Auxiliary->GetTAT_C() + 273.0;
+  OilTemp_degK = in.TAT_c + 273.0;
   if (IdleFF==-1) IdleFF = pow(MilThrust, 0.2) * 107.0;  // just an estimate
 
   // cout << "ENG POWER:" << EnginePowerRPM_N1->GetValue(1200,90) << endl;
@@ -167,34 +166,33 @@ void FGTurboProp::Calculate(void)
 {
   RunPreFunctions();
 
-  TAT = Auxiliary->GetTAT_C();
-  dt = FDMExec->GetDeltaT() * Propulsion->GetRate();
+  TAT = in.TAT_c;
 
-  Throttle = FCS->GetThrottlePos(EngineNumber);
+  ThrottlePos = in.ThrottlePos[EngineNumber];
 
   RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
   if (thrusterType == FGThruster::ttPropeller) {
-    ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber));
-    ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber));
+    ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
+    ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
     ((FGPropeller*)Thruster)->SetReverse(Reversed);
     if (Reversed) {
-      ((FGPropeller*)Thruster)->SetReverseCoef(Throttle);
+      ((FGPropeller*)Thruster)->SetReverseCoef(ThrottlePos);
     } else {
       ((FGPropeller*)Thruster)->SetReverseCoef(0.0);
     }
 
     if (Reversed) {
-      if (Throttle < BetaRangeThrottleEnd) {
-          Throttle = 0.0;  // idle when in Beta-range
+      if (ThrottlePos < BetaRangeThrottleEnd) {
+          ThrottlePos = 0.0;  // idle when in Beta-range
       } else {
         // when reversed:
-        Throttle = (Throttle-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
+        ThrottlePos = (ThrottlePos-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower;
       }
     }
   }
 
   // When trimming is finished check if user wants engine OFF or RUNNING
-  if ((phase == tpTrim) && (dt > 0)) {
+  if ((phase == tpTrim) && (in.TotalDeltaT > 0)) {
     if (Running && !Starved) {
       phase = tpRun;
       N2 = IdleN2;
@@ -221,7 +219,7 @@ void FGTurboProp::Calculate(void)
     StartTime = -1;
   }
   if (Cutoff && (phase != tpSpinUp)) phase = tpOff;
-  if (dt == 0) phase = tpTrim;
+  if (in.TotalDeltaT == 0) phase = tpTrim;
   if (Starved) phase = tpOff;
   if (Condition >= 10) {
     phase = tpOff;
@@ -239,11 +237,11 @@ void FGTurboProp::Calculate(void)
     }
 
     if (Condition < 1) {
-      if ( abs(torque) > Ielu_max_torque && Throttle >= OldThrottle ) {
-        Throttle = OldThrottle - 0.1 * dt; //IELU down
+      if ( abs(torque) > Ielu_max_torque && ThrottlePos >= OldThrottle ) {
+        ThrottlePos = OldThrottle - 0.1 * in.TotalDeltaT; //IELU down
         Ielu_intervent = true;
-      } else if ( Ielu_intervent && Throttle >= OldThrottle) {
-        Throttle = OldThrottle + 0.05 * dt; //IELU up
+      } else if ( Ielu_intervent && ThrottlePos >= OldThrottle) {
+        ThrottlePos = OldThrottle + 0.05 * in.TotalDeltaT; //IELU up
         Ielu_intervent = true;
       } else {
         Ielu_intervent = false;
@@ -251,7 +249,7 @@ void FGTurboProp::Calculate(void)
     } else {
       Ielu_intervent = false;
     }
-    OldThrottle = Throttle;
+    OldThrottle = ThrottlePos;
   }
 
   switch (phase) {
@@ -262,6 +260,7 @@ void FGTurboProp::Calculate(void)
     default: HP = 0;
   }
  
+  LoadThrusterInputs();
   Thruster->Calculate(HP * hptoftlbssec);
 
   RunPostFunctions();
@@ -271,13 +270,12 @@ void FGTurboProp::Calculate(void)
 
 double FGTurboProp::Off(void)
 {
-  double qbar = Auxiliary->Getqbar();
   Running = false; EngStarting = false;
 
   FuelFlow_pph = Seek(&FuelFlow_pph, 0, 800.0, 800.0);
 
   //allow the air turn with generator
-  N1 = ExpSeek(&N1, qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
+  N1 = ExpSeek(&N1, in.qbar/15.0, Idle_Max_Delay*2.5, Idle_Max_Delay * 5);
 
   OilTemp_degK = ExpSeek(&OilTemp_degK,273.15 + TAT, 400 , 400);
 
@@ -287,9 +285,6 @@ double FGTurboProp::Off(void)
 
   OilPressure_psi = (N1/100.0*0.25+(0.1-(OilTemp_degK-273.15)*0.1/80.0)*N1/100.0) / 7692.0e-6; //from MPa to psi
 
-  ConsumeFuel(); // for possible setting Starved = false when fuel tank
-                 // is refilled (fuel crossfeed etc.)
-
   if (RPM>5) return -0.012; // friction in engine when propeller spining (estimate)
   return 0.0;
 }
@@ -303,7 +298,7 @@ double FGTurboProp::Run(void)
 
 //---
   double old_N1 = N1;
-  N1 = ExpSeek(&N1, IdleN1 + Throttle * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
+  N1 = ExpSeek(&N1, IdleN1 + ThrottlePos * N1_factor, Idle_Max_Delay, Idle_Max_Delay * 2.4);
 
   EngPower_HP = EnginePowerRPM_N1->GetValue(RPM,N1);
   EngPower_HP *= EnginePowerVC->GetValue();
@@ -322,8 +317,6 @@ double FGTurboProp::Run(void)
 
   OilTemp_degK = Seek(&OilTemp_degK, 353.15, 0.4-N1*0.001, 0.04);
 
-  ConsumeFuel();
-
   if (Cutoff) phase = tpOff;
   if (Starved) phase = tpOff;
 
@@ -360,15 +353,12 @@ double FGTurboProp::SpinUp(void)
   EngPower_HP *= EnginePowerVC->GetValue();
   if (EngPower_HP > MaxPower) EngPower_HP = MaxPower;
 
-  if (StartTime>=0) StartTime+=dt;
+  if (StartTime>=0) StartTime+=in.TotalDeltaT;
   if (StartTime > MaxStartingTime && MaxStartingTime > 0) { //start failed due timeout
     phase = tpOff;
     StartTime = -1;
   }
 
-  ConsumeFuel(); // for possible setting Starved = false when fuel tank
-                 // is refilled (fuel crossfeed etc.)
-
   return EngPower_HP;
 }
 
@@ -409,8 +399,6 @@ double FGTurboProp::Start(void)
     Starter = false;
   }
 
-  ConsumeFuel();
-
   return EngPower_HP;
 }
 
@@ -419,9 +407,8 @@ double FGTurboProp::Start(void)
 
 double FGTurboProp::CalcFuelNeed(void)
 {
-  double dT = FDMExec->GetDeltaT() * Propulsion->GetRate();
   FuelFlowRate = FuelFlow_pph / 3600.0;
-  FuelExpended = FuelFlowRate * dT;
+  FuelExpended = FuelFlowRate * in.TotalDeltaT;
   return FuelExpended;
 }
 
@@ -431,10 +418,10 @@ double FGTurboProp::Seek(double *var, double target, double accel, double decel)
 {
   double v = *var;
   if (v > target) {
-    v -= dt * decel;
+    v -= in.TotalDeltaT * decel;
     if (v < target) v = target;
   } else if (v < target) {
-    v += dt * accel;
+    v += in.TotalDeltaT * accel;
     if (v > target) v = target;
   }
   return v;
@@ -447,9 +434,9 @@ double FGTurboProp::ExpSeek(double *var, double target, double accel_tau, double
 // exponential delay instead of the linear delay used in Seek
   double v = *var;
   if (v > target) {
-    v = (v - target) * exp ( -dt / decel_tau) + target;
+    v = (v - target) * exp ( -in.TotalDeltaT / decel_tau) + target;
   } else if (v < target) {
-    v = (target - v) * (1 - exp ( -dt / accel_tau)) + v;
+    v = (target - v) * (1 - exp ( -in.TotalDeltaT / accel_tau)) + v;
   }
   return v;
 }
@@ -467,7 +454,6 @@ void FGTurboProp::SetDefaults(void)
   IdleN2 = 60.0;
   MaxN1 = 100.0;
   MaxN2 = 100.0;
-  Throttle = 0.0;
   InletPosition = 1.0;
   NozzlePosition = 1.0;
   Reversed = false;
@@ -485,7 +471,7 @@ void FGTurboProp::SetDefaults(void)
 
   Idle_Max_Delay = 1.0;
 
-  Throttle = OldThrottle = 0.0;
+  ThrottlePos = OldThrottle = 0.0;
   ITT_Delay = 0.05;
   ReverseMaxPower = 0.0;
   BetaRangeThrottleEnd = 0.0;
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.h b/src/FDM/JSBSim/models/propulsion/FGTurboProp.h
old mode 100644
new mode 100755
index 1c5f48ae9..330a7267a
--- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.h
+++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.h
@@ -47,7 +47,7 @@ INCLUDES
 #include "input_output/FGXMLElement.h"
 #include "math/FGTable.h"
 
-#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.14 2011/03/10 01:35:25 dpculp Exp $"
+#define ID_TURBOPROP "$Id: FGTurboProp.h,v 1.16 2011/08/04 13:45:42 jberndt Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -99,7 +99,7 @@ public:
       @param Executive pointer to executive structure
       @param el pointer to the XML element representing the turbine engine
       @param engine_number engine number*/
-  FGTurboProp(FGFDMExec* Executive, Element *el, int engine_number);
+  FGTurboProp(FGFDMExec* Executive, Element *el, int engine_number, struct Inputs& input);
   /// Destructor
   ~FGTurboProp();
 
@@ -110,7 +110,7 @@ public:
 
   double GetPowerAvailable(void) const { return (HP * hptoftlbssec); }
   double GetRPM(void) const { return (RPM); }
-  double GetIeluThrottle(void) const { return (Throttle); }
+  double GetIeluThrottle(void) const { return (ThrottlePos); }
   bool GetIeluIntervent(void) const { return Ielu_intervent; }
 
   double Seek(double* var, double target, double accel, double decel);
@@ -162,10 +162,9 @@ private:
   double MaxN2;            ///< N2 at 100% throttle
   double IdleFF;           ///< Idle Fuel Flow (lbm/hr)
   double delay;            ///< Inverse spool-up time from idle to 100% (seconds)
-  double dt;               ///< Simulator time slice
   double N1_factor;        ///< factor to tie N1 and throttle
   double N2_factor;        ///< factor to tie N2 and throttle
-  double Throttle;         ///< FCS-supplied throttle position
+  double ThrottlePos;      ///< FCS-supplied throttle position, modified locally
   double TAT;              ///< total air temperature (deg C)
   bool Stalled;            ///< true if engine is compressor-stalled
   bool Seized;             ///< true if inner spool is seized
diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am
index f6dab96a7..fc617ad0f 100644
--- a/src/Main/Makefile.am
+++ b/src/Main/Makefile.am
@@ -35,9 +35,9 @@ GFX_CODE = fg_os_osgviewer.cxx fg_os_common.cxx fg_os.hxx
 JSBSIM_LIBS = \
 	$(top_builddir)/src/FDM/JSBSim/libJSBSim.a \
         $(top_builddir)/src/FDM/JSBSim/initialization/libInit.a \
+        $(top_builddir)/src/FDM/JSBSim/models/atmosphere/libAtmosphere.a \
         $(top_builddir)/src/FDM/JSBSim/models/libModels.a \
         $(top_builddir)/src/FDM/JSBSim/models/flight_control/libFlightControl.a\
-        $(top_builddir)/src/FDM/JSBSim/models/atmosphere/libAtmosphere.a \
         $(top_builddir)/src/FDM/JSBSim/models/propulsion/libPropulsion.a \
         $(top_builddir)/src/FDM/JSBSim/input_output/libInputOutput.a \
         $(top_builddir)/src/FDM/JSBSim/math/libMath.a

From b09a2347a8fd699d222e63c2df525d1d10753d6b Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Sun, 11 Sep 2011 11:44:19 +0200
Subject: [PATCH 11/85] remove unused files

---
 .../models/flight_control/FGGradient.cpp      | 121 ------------------
 .../JSBSim/models/flight_control/FGGradient.h |  80 ------------
 2 files changed, 201 deletions(-)
 delete mode 100644 src/FDM/JSBSim/models/flight_control/FGGradient.cpp
 delete mode 100644 src/FDM/JSBSim/models/flight_control/FGGradient.h

diff --git a/src/FDM/JSBSim/models/flight_control/FGGradient.cpp b/src/FDM/JSBSim/models/flight_control/FGGradient.cpp
deleted file mode 100644
index 9046e4975..000000000
--- a/src/FDM/JSBSim/models/flight_control/FGGradient.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Module:       FGGradient.cpp
- Author:
- Date started:
-
- ------------- Copyright (C) 2000 -------------
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser 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 Lesser General Public License for more
- details.
-
- You should have received a copy of the GNU Lesser General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place - Suite 330, Boston, MA  02111-1307, USA.
-
- Further information about the GNU Lesser General Public License can also be found on
- the world wide web at http://www.gnu.org.
-
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-
-HISTORY
---------------------------------------------------------------------------------
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-COMMENTS, REFERENCES,  and NOTES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#include "FGGradient.h"
-#include <iostream>
-
-using namespace std;
-
-namespace JSBSim {
-
-static const char *IdSrc = "$Id: FGGradient.cpp,v 1.4 2009/10/24 22:59:30 jberndt Exp $";
-static const char *IdHdr = ID_GRADIENT;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS IMPLEMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-FGGradient::FGGradient(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
-{
-  FGFCSComponent::bind();
-
-  Debug(0);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGGradient::~FGGradient()
-{
-  Debug(1);
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-bool FGGradient::Run(void )
-{
-  return true;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//    The bitmasked value choices are as follows:
-//    unset: In this case (the default) JSBSim would only print
-//       out the normally expected messages, essentially echoing
-//       the config files as they are read. If the environment
-//       variable is not set, debug_lvl is set to 1 internally
-//    0: This requests JSBSim not to output any messages
-//       whatsoever.
-//    1: This value explicity requests the normal JSBSim
-//       startup messages
-//    2: This value asks for a message to be printed out when
-//       a class is instantiated
-//    4: When this value is set, a message is displayed when a
-//       FGModel object executes its Run() method
-//    8: When this value is set, various runtime state variables
-//       are printed out periodically
-//    16: When set various parameters are sanity checked and
-//       a message is printed out when they go out of bounds
-
-void FGGradient::Debug(int from)
-{
-  if (debug_lvl <= 0) return;
-
-  if (debug_lvl & 1) { // Standard console startup message output
-    if (from == 0) { // Constructor
-
-    }
-  }
-  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
-    if (from == 0) cout << "Instantiated: FGGradient" << endl;
-    if (from == 1) cout << "Destroyed:    FGGradient" << endl;
-  }
-  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
-  }
-  if (debug_lvl & 8 ) { // Runtime state variables
-  }
-  if (debug_lvl & 16) { // Sanity checking
-  }
-  if (debug_lvl & 64) {
-    if (from == 0) { // Constructor
-      cout << IdSrc << endl;
-      cout << IdHdr << endl;
-    }
-  }
-}
-}
diff --git a/src/FDM/JSBSim/models/flight_control/FGGradient.h b/src/FDM/JSBSim/models/flight_control/FGGradient.h
deleted file mode 100644
index 06d3e843f..000000000
--- a/src/FDM/JSBSim/models/flight_control/FGGradient.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Header:       FGGradient.h
- Author:       
- Date started: 
-
- ------------- Copyright (C)  -------------
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser 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 Lesser General Public License for more
- details.
-
- You should have received a copy of the GNU Lesser General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- Place - Suite 330, Boston, MA  02111-1307, USA.
-
- Further information about the GNU Lesser General Public License can also be found on
- the world wide web at http://www.gnu.org.
-
-HISTORY
---------------------------------------------------------------------------------
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-SENTRY
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifndef FGGRADIENT_H
-#define FGGRADIENT_H
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#include "FGFCSComponent.h"
-#include "input_output/FGXMLElement.h"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-DEFINITIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#define ID_GRADIENT "$Id: FGGradient.h,v 1.5 2009/10/02 10:30:09 jberndt Exp $"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-FORWARD DECLARATIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-namespace JSBSim {
-
-class FGFCS;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DOCUMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/** Encapsulates a gradient component for the flight control system.
-  */
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DECLARATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-class FGGradient  : public FGFCSComponent
-{
-public:
-  FGGradient(FGFCS* fcs, Element* element);
-  ~FGGradient();
-
-  bool Run (void);
-
-private:
-  void Debug(int from);
-};
-}
-#endif

From f4b45eca7e0e03ff0354ebb9a544c4cc65a3c407 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sun, 11 Sep 2011 12:13:55 +0200
Subject: [PATCH 12/85] cmake: Use ws2_32.lib instead of the WINSOCK_LIBRARY
 variable.

Fixup for commit 549c5eccb9e18b6db2f469ca9d38e35dda4e33f1.
Do not refer to the no longer existing WINSOCK_LIBRARY variable.
Instead, at this single place where it is used, just use ws2_32.lib.
---
 CMakeModules/FindSimGear.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake
index 7481fadb4..cd966f0d6 100644
--- a/CMakeModules/FindSimGear.cmake
+++ b/CMakeModules/FindSimGear.cmake
@@ -159,7 +159,7 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
         ${ZLIB_LIBRARY})
 
     if(WIN32)
-        list(APPEND SIMGEAR_CORE_LIBRARY_DEPENDENCIES ${WINSOCK_LIBRARY})
+        list(APPEND SIMGEAR_CORE_LIBRARY_DEPENDENCIES ws2_32.lib)
     endif(WIN32)
 
     if(NOT MSVC)

From c5b22d248ea0616444af2ad51364da40137fdae5 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sun, 11 Sep 2011 12:42:59 +0200
Subject: [PATCH 13/85] cmake: Quote argument in FindSvnClient.cmake.

---
 CMakeModules/FindSvnClient.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 0823a5322..7b175d4f0 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -16,7 +16,7 @@ if(HAVE_APR_CONFIG)
         OUTPUT_STRIP_TRAILING_WHITESPACE)
     
 # clean up some vars, or other CMake pieces complain
-	string(STRIP ${RAW_APR_LIBS} APR_LIBS)
+	string(STRIP "${RAW_APR_LIBS}" APR_LIBS)
 
 else(HAVE_APR_CONFIG)
     message(STATUS "apr-1-config not found, implement manual search for APR")

From 7e91e7e98b9ba6a3b74883527602ad8886e352b8 Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Sun, 11 Sep 2011 13:19:51 +0200
Subject: [PATCH 14/85] change file mode to 644

---
 src/FDM/JSBSim/input_output/FGPropertyManager.cpp        | 0
 src/FDM/JSBSim/input_output/FGScript.cpp                 | 0
 src/FDM/JSBSim/input_output/FGXMLElement.cpp             | 0
 src/FDM/JSBSim/math/FGFunction.cpp                       | 0
 src/FDM/JSBSim/math/FGFunction.h                         | 0
 src/FDM/JSBSim/math/FGModelFunctions.h                   | 0
 src/FDM/JSBSim/math/FGParameter.h                        | 0
 src/FDM/JSBSim/math/FGPropertyValue.cpp                  | 0
 src/FDM/JSBSim/math/FGPropertyValue.h                    | 0
 src/FDM/JSBSim/math/LagrangeMultiplier.h                 | 0
 src/FDM/JSBSim/models/FGAuxiliary.cpp                    | 0
 src/FDM/JSBSim/models/FGExternalReactions.cpp            | 0
 src/FDM/JSBSim/models/FGExternalReactions.h              | 0
 src/FDM/JSBSim/models/FGInput.cpp                        | 0
 src/FDM/JSBSim/models/FGInput.h                          | 0
 src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp              | 0
 src/FDM/JSBSim/models/atmosphere/FGMSIS.h                | 0
 src/FDM/JSBSim/models/atmosphere/FGMars.cpp              | 0
 src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp | 0
 src/FDM/JSBSim/models/flight_control/FGAccelerometer.h   | 0
 src/FDM/JSBSim/models/flight_control/FGGyro.cpp          | 0
 src/FDM/JSBSim/models/flight_control/FGGyro.h            | 0
 src/FDM/JSBSim/models/flight_control/FGPID.cpp           | 0
 src/FDM/JSBSim/models/flight_control/FGSensor.cpp        | 0
 src/FDM/JSBSim/models/flight_control/FGSensor.h          | 0
 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp         | 0
 src/FDM/JSBSim/models/propulsion/FGTurboProp.h           | 0
 27 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 src/FDM/JSBSim/input_output/FGPropertyManager.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/input_output/FGScript.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/input_output/FGXMLElement.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGFunction.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGFunction.h
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGModelFunctions.h
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGParameter.h
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGPropertyValue.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/math/FGPropertyValue.h
 mode change 100755 => 100644 src/FDM/JSBSim/math/LagrangeMultiplier.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/FGAuxiliary.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/FGExternalReactions.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/FGExternalReactions.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/FGInput.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/FGInput.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/atmosphere/FGMSIS.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/atmosphere/FGMars.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGGyro.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGGyro.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGPID.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGSensor.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/flight_control/FGSensor.h
 mode change 100755 => 100644 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
 mode change 100755 => 100644 src/FDM/JSBSim/models/propulsion/FGTurboProp.h

diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/input_output/FGScript.cpp b/src/FDM/JSBSim/input_output/FGScript.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/input_output/FGXMLElement.cpp b/src/FDM/JSBSim/input_output/FGXMLElement.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGFunction.cpp b/src/FDM/JSBSim/math/FGFunction.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGFunction.h b/src/FDM/JSBSim/math/FGFunction.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGModelFunctions.h b/src/FDM/JSBSim/math/FGModelFunctions.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGParameter.h b/src/FDM/JSBSim/math/FGParameter.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGPropertyValue.cpp b/src/FDM/JSBSim/math/FGPropertyValue.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/FGPropertyValue.h b/src/FDM/JSBSim/math/FGPropertyValue.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/math/LagrangeMultiplier.h b/src/FDM/JSBSim/math/LagrangeMultiplier.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/FGAuxiliary.cpp b/src/FDM/JSBSim/models/FGAuxiliary.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/FGExternalReactions.cpp b/src/FDM/JSBSim/models/FGExternalReactions.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/FGExternalReactions.h b/src/FDM/JSBSim/models/FGExternalReactions.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/FGInput.cpp b/src/FDM/JSBSim/models/FGInput.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/FGInput.h b/src/FDM/JSBSim/models/FGInput.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp b/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.h b/src/FDM/JSBSim/models/atmosphere/FGMSIS.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/atmosphere/FGMars.cpp b/src/FDM/JSBSim/models/atmosphere/FGMars.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h b/src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGGyro.cpp b/src/FDM/JSBSim/models/flight_control/FGGyro.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGGyro.h b/src/FDM/JSBSim/models/flight_control/FGGyro.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGPID.cpp b/src/FDM/JSBSim/models/flight_control/FGPID.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGSensor.cpp b/src/FDM/JSBSim/models/flight_control/FGSensor.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/flight_control/FGSensor.h b/src/FDM/JSBSim/models/flight_control/FGSensor.h
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
old mode 100755
new mode 100644
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.h b/src/FDM/JSBSim/models/propulsion/FGTurboProp.h
old mode 100755
new mode 100644

From 865a5c4f14d2bcce513a65c3770633a9c1ca8150 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 16:05:58 +0200
Subject: [PATCH 15/85] Fix VS2008 build after JSBSim update

---
 projects/VC90/FlightGear/FlightGear.vcproj | 40 +++++++++++++---------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index c2e799c8d..e06fc4514 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -836,6 +836,14 @@
 			<Filter
 				Name="models"
 				>
+				<File
+					RelativePath="..\..\..\src\FDM\JSBSim\models\FGAccelerations.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\..\src\FDM\JSBSim\models\FGAccelerations.h"
+					>
+				</File>
 				<File
 					RelativePath="..\..\..\src\Fdm\JSBSim\models\FGAerodynamics.cpp"
 					>
@@ -1023,6 +1031,14 @@
 						RelativePath="..\..\..\src\Fdm\JSBSim\models\atmosphere\FGMSISData.cpp"
 						>
 					</File>
+					<File
+						RelativePath="..\..\..\src\FDM\JSBSim\models\atmosphere\FGWinds.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\src\FDM\JSBSim\models\atmosphere\FGWinds.h"
+						>
+					</File>
 				</Filter>
 				<Filter
 					Name="flight_control"
@@ -1083,14 +1099,6 @@
 						RelativePath="..\..\..\src\Fdm\JSBSim\models\flight_control\FGGain.h"
 						>
 					</File>
-					<File
-						RelativePath="..\..\..\src\Fdm\JSBSim\models\flight_control\FGGradient.cpp"
-						>
-					</File>
-					<File
-						RelativePath="..\..\..\src\Fdm\JSBSim\models\flight_control\FGGradient.h"
-						>
-					</File>
 					<File
 						RelativePath="..\..\..\src\Fdm\JSBSim\models\flight_control\FGKinemat.cpp"
 						>
@@ -4309,14 +4317,6 @@
 		<Filter
 			Name="Lib_ATC"
 			>
-			<File
-				RelativePath="..\..\..\src\ATC\atcdialog.cxx"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\ATC\atcdialog.hxx"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\ATC\atc_mgr.cxx"
 				>
@@ -4325,6 +4325,14 @@
 				RelativePath="..\..\..\src\ATC\atc_mgr.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\ATC\atcdialog.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\ATC\atcdialog.hxx"
+				>
+			</File>
 			<File
 				RelativePath="..\..\..\src\ATC\CommStation.cxx"
 				>

From 073511492fabb1c4e92b2d2cb0504993118a8497 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 16:09:26 +0200
Subject: [PATCH 16/85] Fix VS2008 build after JSBSim update - 2nd try

---
 projects/VC90/FlightGear/FlightGear.vcproj | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index e06fc4514..c9f3558c8 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -1031,6 +1031,14 @@
 						RelativePath="..\..\..\src\Fdm\JSBSim\models\atmosphere\FGMSISData.cpp"
 						>
 					</File>
+					<File
+						RelativePath="..\..\..\src\FDM\JSBSim\models\atmosphere\FGStandardAtmosphere.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\..\src\FDM\JSBSim\models\atmosphere\FGStandardAtmosphere.h"
+						>
+					</File>
 					<File
 						RelativePath="..\..\..\src\FDM\JSBSim\models\atmosphere\FGWinds.cpp"
 						>

From 45f08ceb6d39b6e47fb493ae874882539cf61da6 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 16:18:36 +0200
Subject: [PATCH 17/85] Update version in Win32 dev packaging

---
 package/Win32-Inno/FlightGear-devel.iss | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package/Win32-Inno/FlightGear-devel.iss b/package/Win32-Inno/FlightGear-devel.iss
index d10ebf453..43d0874d5 100644
--- a/package/Win32-Inno/FlightGear-devel.iss
+++ b/package/Win32-Inno/FlightGear-devel.iss
@@ -36,7 +36,7 @@ DefaultGroupName=FlightGear {#FGVER}
 LicenseFile=X:\data\COPYING
 Uninstallable=yes
 SetupIconFile=x:\flightgear.ico
-VersionInfoVersion=2.0.0.0
+VersionInfoVersion=2.5.0.0
 WizardImageFile=X:\setupimg.bmp
 WizardImageStretch=No
 WizardSmallImageFile=X:\setupsmall.bmp

From 759149427411901b95c7969a4275e8ab7b6f590a Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 16:30:56 +0200
Subject: [PATCH 18/85] First stab at creating a nightly build for programs
 created with vs2010 and Cmake

---
 .../Win-NSIS/flightgear-nightly-vs2010.nsi    | 153 ++++++++++++++++++
 1 file changed, 153 insertions(+)
 create mode 100644 package/Win-NSIS/flightgear-nightly-vs2010.nsi

diff --git a/package/Win-NSIS/flightgear-nightly-vs2010.nsi b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
new file mode 100644
index 000000000..545302e24
--- /dev/null
+++ b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
@@ -0,0 +1,153 @@
+!include "MUI.nsh"
+
+!system 'osgversion --so-number > %TEMP%\osg-so-number.txt'
+!system 'osgversion --version-number > %TEMP%\osg-version.txt'
+
+!define /file OSGSoNumber $%TEMP%\osg-so-number.txt
+!define /file OSGVersion $%TEMP%\osg-version.txt
+!define /file FGVersion flightgear\version
+
+!echo "osg-so is ${OSGSoNumber}"
+
+Name "FlightGear Nightly vs2010"
+OutFile fgfs_win32_vs2010_nightly_${FGVersion}.exe
+
+; use LZMA for best compression
+SetCompressor /FINAL /SOLID lzma
+SetCompressorDictSize 64
+
+InstallDir $PROGRAMFILES\FlightGear-nightly-2010
+
+; Request admin privileges for Windows Vista
+RequestExecutionLevel highest
+
+; don't hang around
+AutoCloseWindow true
+		
+!define UninstallKey "Software\Microsoft\Windows\CurrentVersion\Uninstall\FlightGear-nightly-2010"
+!define FGBinDir "install\msvc100\FlightGear\bin"
+!define FGRunDir "install\msvc100\fgrun"
+!define OSGInstallDir "install\msvc100\OpenSceneGraph"
+!define OSGPluginsDir "${OSGInstallDir}\bin\osgPlugins-${OSGVersion}"
+
+!define ThirdPartyBinDir "3rdParty\bin"
+
+!define MUI_ICON "flightgear\projects\VC90\flightgear.ico"
+!define MUI_UNICON "flightgear\projects\VC90\flightgear.ico"
+
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_RIGHT
+!define MUI_HEADERIMAGE_BITMAP "flightgear\package\Win-NSIS\fg-install-header.bmp" ; optional
+
+
+
+;!define MUI_WELCOMEFINISHPAGE_BITMAP "welcome.bmp"
+;!define MUI_UNWELCOMEFINISHPAGE_BITMAP "welcome.bmp"
+
+!insertmacro MUI_PAGE_WELCOME
+; include GPL license page
+!insertmacro MUI_PAGE_LICENSE "flightgear\Copying"
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+
+!define MUI_FINISHPAGE_RUN $INSTDIR\fgrun.exe
+!define MUI_FINISHPAGE_RUN_TEXT "Run FlightGear now"
+!insertmacro MUI_PAGE_FINISH
+
+
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+
+!insertmacro MUI_LANGUAGE "English"
+
+; The stuff to install
+Section "" ;No components page, name is not important  
+        
+  SetShellVarContext all
+  ; Set output path to the installation directory.
+  SetOutPath $INSTDIR
+  
+  File ${FGBinDir}\fgfs.exe
+  File ${FGBinDir}\fgjs.exe
+  File ${FGBinDir}\terrasync.exe
+  File ${FGRunDir}\bin\fgrun.exe
+  
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osg.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgDB.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgGA.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgParticle.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgText.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgUtil.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgViewer.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgSim.dll
+  File ${OSGInstallDir}\bin\osg${OSGSoNumber}-osgFX.dll
+  
+  File ${OSGInstallDir}\bin\ot12-OpenThreads.dll
+  
+  File ${ThirdPartyBinDir}\*.dll
+  
+  ; VC runtime redistributables
+  File "$%VCINSTALLDIR%\redist\x86\Microsoft.VC100.CRT\*.dll"
+  
+  File /r ${FGRunDir}\share
+  
+  SetOutPath $INSTDIR\osgPlugins-${OSGVersion}
+  File ${OSGPluginsDir}\osgdb_ac.dll
+  File ${OSGPluginsDir}\osgdb_osg.dll
+  File ${OSGPluginsDir}\osgdb_osga.dll
+  File ${OSGPluginsDir}\osgdb_3ds.dll
+  File ${OSGPluginsDir}\osgdb_mdl.dll
+  File ${OSGPluginsDir}\osgdb_jpeg.dll
+  File ${OSGPluginsDir}\osgdb_rgb.dll  
+  File ${OSGPluginsDir}\osgdb_png.dll
+  File ${OSGPluginsDir}\osgdb_dds.dll
+  File ${OSGPluginsDir}\osgdb_txf.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osg.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osganimation.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgfx.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgmanipulator.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgparticle.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgshadow.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgsim.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgterrain.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgtext.dll
+  File ${OSGPluginsDir}\osgdb_serializers_osgvolume.dll
+  File ${OSGPluginsDir}\osgdb_deprecated_osg.dll
+  File ${OSGPluginsDir}\osgdb_deprecated_osgparticle.dll
+  
+  
+  Exec '"$INSTDIR\fgrun.exe"  --silent --fg-exe="$INSTDIR\fgfs.exe" --ts-exe="$INSTDIR\terrasync.exe" '
+  
+  CreateDirectory "$SMPROGRAMS\FlightGear"
+  CreateShortCut "$SMPROGRAMS\FlightGear\FlightGear-nightly-2010.lnk" "$INSTDIR\fgrun.exe" 
+  
+  
+  WriteUninstaller "$INSTDIR\FlightGear_Uninstall.exe"
+  
+  WriteRegStr HKLM ${UninstallKey} "DisplayName" "FlightGear Nightly"
+  WriteRegStr HKLM ${UninstallKey} "DisplayVersion" "${FGVersion}"
+  WriteRegStr HKLM ${UninstallKey} "UninstallString" "$INSTDIR\FlightGear_Uninstall.exe"
+  WriteRegStr HKLM ${UninstallKey} "UninstallPath" "$INSTDIR\FlightGear_Uninstall.exe"
+  WriteRegDWORD HKLM ${UninstallKey} "NoModify" 1
+  WriteRegDWORD HKLM ${UninstallKey} "NoRepair" 1
+  WriteRegStr HKLM ${UninstallKey} "URLInfoAbout" "http://www.flightgear.org/"
+ 
+SectionEnd
+
+
+
+Section "Uninstall"
+   
+  SetShellVarContext all
+  
+  
+  Delete "$SMPROGRAMS\FlightGear\FlightGear-nightly-2010.lnk"
+  ; only delete the FlightGear group if it's empty
+  RMDir "$SMPROGRAMS\FlightGear"
+  
+  RMDir /r "$INSTDIR"
+  
+  DeleteRegKey HKLM ${UninstallKey}
+
+SectionEnd
+ 

From ce8488c276b60d2af0b05b8e073ece7fd0598e0a Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 19:50:20 +0200
Subject: [PATCH 19/85] Change display name

---
 package/Win-NSIS/flightgear-nightly-vs2010.nsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package/Win-NSIS/flightgear-nightly-vs2010.nsi b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
index 545302e24..dc387466a 100644
--- a/package/Win-NSIS/flightgear-nightly-vs2010.nsi
+++ b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
@@ -124,7 +124,7 @@ Section "" ;No components page, name is not important
   
   WriteUninstaller "$INSTDIR\FlightGear_Uninstall.exe"
   
-  WriteRegStr HKLM ${UninstallKey} "DisplayName" "FlightGear Nightly"
+  WriteRegStr HKLM ${UninstallKey} "DisplayName" "FlightGear Nightly vs2010"
   WriteRegStr HKLM ${UninstallKey} "DisplayVersion" "${FGVersion}"
   WriteRegStr HKLM ${UninstallKey} "UninstallString" "$INSTDIR\FlightGear_Uninstall.exe"
   WriteRegStr HKLM ${UninstallKey} "UninstallPath" "$INSTDIR\FlightGear_Uninstall.exe"

From 6b3088346b0535d20b7541ad97e6cb6fef5bdb70 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 20:12:27 +0200
Subject: [PATCH 20/85] Less confusing display name

---
 package/Win-NSIS/flightgear-nightly-vs2010.nsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package/Win-NSIS/flightgear-nightly-vs2010.nsi b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
index dc387466a..95f5ad90e 100644
--- a/package/Win-NSIS/flightgear-nightly-vs2010.nsi
+++ b/package/Win-NSIS/flightgear-nightly-vs2010.nsi
@@ -124,7 +124,7 @@ Section "" ;No components page, name is not important
   
   WriteUninstaller "$INSTDIR\FlightGear_Uninstall.exe"
   
-  WriteRegStr HKLM ${UninstallKey} "DisplayName" "FlightGear Nightly vs2010"
+  WriteRegStr HKLM ${UninstallKey} "DisplayName" "FlightGear Nightly (vs2010 build)"
   WriteRegStr HKLM ${UninstallKey} "DisplayVersion" "${FGVersion}"
   WriteRegStr HKLM ${UninstallKey} "UninstallString" "$INSTDIR\FlightGear_Uninstall.exe"
   WriteRegStr HKLM ${UninstallKey} "UninstallPath" "$INSTDIR\FlightGear_Uninstall.exe"

From 57754b4ac80d0fec828aadc68feb6f145d72254d Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 20:50:37 +0200
Subject: [PATCH 21/85] Enforce the use of Cmake 2.8

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0d702a18..34711fc17 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 2.8)
 
 include (CheckFunctionExists)
 include (CheckCSourceCompiles)

From 1e4b17595a0b1d45d86b3ddf893f3c3495cbaa23 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durk@linux-gj5p.site>
Date: Sun, 11 Sep 2011 21:42:29 +0200
Subject: [PATCH 22/85] -Prevent crashing the sim when starting at a gate that
 is not connected to the ground network. For now, just silently shut down the
 ATC system.

---
 src/AIModel/AIFlightPlanCreatePushBack.cxx | 281 +++++++++++----------
 src/ATC/atc_mgr.cxx                        |   9 +-
 src/ATC/atc_mgr.hxx                        |   1 +
 3 files changed, 150 insertions(+), 141 deletions(-)

diff --git a/src/AIModel/AIFlightPlanCreatePushBack.cxx b/src/AIModel/AIFlightPlanCreatePushBack.cxx
index c5cdaca0d..83d5793b9 100644
--- a/src/AIModel/AIFlightPlanCreatePushBack.cxx
+++ b/src/AIModel/AIFlightPlanCreatePushBack.cxx
@@ -1,22 +1,22 @@
 /****************************************************************************
- * AIFlightPlanCreatePushBack.cxx
- * Written by Durk Talsma, started August 1, 2007.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- **************************************************************************/
+* AIFlightPlanCreatePushBack.cxx
+* Written by Durk Talsma, started August 1, 2007.
+*
+* 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, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*
+**************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
@@ -38,13 +38,13 @@
 
 // TODO: Use James Turner's createOnGround functions.
 bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
-                                    bool firstFlight, FGAirport *dep, 
- 				    double latitude,
- 				    double longitude,
- 				    double radius,
- 				    const string& fltType,
- 				    const string& aircraftType,
- 				    const string& airline)
+				    bool firstFlight, FGAirport *dep, 
+				    double latitude,
+				    double longitude,
+				    double radius,
+				    const string& fltType,
+				    const string& aircraftType,
+				    const string& airline)
 {
     double lat, lon, heading;
     double vTaxi = ac->getPerformance()->vTaxi();
@@ -57,72 +57,72 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
 
     if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
 	//cerr << "Push Back fallback" << endl;
-        createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
-                               radius, fltType, aircraftType, airline);
+	createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
+			      radius, fltType, aircraftType, airline);
     } else {
-        if (firstFlight) {
-             
-             if (!(dep->getDynamics()->getAvailableParking(&lat, &lon, 
-                                                           &heading, &gateId, 
-                                                           radius, fltType, 
-                                                           aircraftType, airline))) {
- 	            SG_LOG(SG_INPUT, SG_WARN, "Warning: Could not find parking for a " << 
-                                              aircraftType <<
-                                              " of flight type " << fltType << 
-                                              " of airline     " << airline <<
-                                              " at airport     " << dep->getId());
-                    return false;
-                    char buffer[10];
-                    snprintf (buffer, 10, "%d", gateId);
-                    SGGeod coord = coord.fromDeg(lon, lat);
-                    //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
-                    FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
-                   wpt->setRouteIndex(-1);
-                   waypoints.push_back(wpt);
-            }
-           //cerr << "Success : GateId = " << gateId << endl;
-           SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " << 
-                                              aircraftType <<
-                                              " of flight type " << fltType << 
-                                              " of airline     " << airline <<
-                                              " at airport     " << dep->getId());
-        } else {
+	if (firstFlight) {
+	    
+	    if (!(dep->getDynamics()->getAvailableParking(&lat, &lon, 
+							  &heading, &gateId, 
+							  radius, fltType, 
+							  aircraftType, airline))) {
+		    SG_LOG(SG_INPUT, SG_WARN, "Warning: Could not find parking for a " << 
+					      aircraftType <<
+					      " of flight type " << fltType << 
+					      " of airline     " << airline <<
+					      " at airport     " << dep->getId());
+		    return false;
+		    char buffer[10];
+		    snprintf (buffer, 10, "%d", gateId);
+		    SGGeod coord = coord.fromDeg(lon, lat);
+		    //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
+		    FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
+		  wpt->setRouteIndex(-1);
+		  waypoints.push_back(wpt);
+	    }
+	  //cerr << "Success : GateId = " << gateId << endl;
+	  SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " << 
+					      aircraftType <<
+					      " of flight type " << fltType << 
+					      " of airline     " << airline <<
+					      " at airport     " << dep->getId());
+	} else {
 	    //cerr << "Push Back follow-up Flight" << endl;
-            dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
-        }
-        if (gateId < 0) {
-             createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
-                                    radius, fltType, aircraftType, airline);
-             return true;
+	    dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
+	}
+	if (gateId < 0) {
+	    createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
+				    radius, fltType, aircraftType, airline);
+	    return true;
 
-        }
+	}
 	//cerr << "getting parking " << gateId;
-        //cerr << " for a " << 
-        //                                      aircraftType <<
-        //                                      " of flight type " << fltType << 
-        //                                      " of airline     " << airline <<
-        //                                      " at airport     " << dep->getId() << endl;
+	//cerr << " for a " << 
+	//                                      aircraftType <<
+	//                                      " of flight type " << fltType << 
+	//                                      " of airline     " << airline <<
+	//                                      " at airport     " << dep->getId() << endl;
 	FGParking *parking = dep->getDynamics()->getParking(gateId);
-        int pushBackNode = parking->getPushBackPoint();
+	int pushBackNode = parking->getPushBackPoint();
 
 
-        pushBackRoute = parking->getPushBackRoute();
-        if ((pushBackNode > 0) && (pushBackRoute == 0)) {  // Load the already established route for this gate
-            int node, rte;
-            FGTaxiRoute route;
-            //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
-            route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
-            parking->setPushBackRoute(new FGTaxiRoute(route));
-            
+	pushBackRoute = parking->getPushBackRoute();
+	if ((pushBackNode > 0) && (pushBackRoute == 0)) {  // Load the already established route for this gate
+	    int node, rte;
+	    FGTaxiRoute route;
+	    //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
+	    route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
+	    parking->setPushBackRoute(new FGTaxiRoute(route));
+	    
 
-            pushBackRoute = parking->getPushBackRoute();
-            int size = pushBackRoute->size();
-            if (size < 2) {
+	    pushBackRoute = parking->getPushBackRoute();
+	    int size = pushBackRoute->size();
+	    if (size < 2) {
 		SG_LOG(SG_GENERAL, SG_WARN, "Push back route from gate " << gateId << " has only " << size << " nodes.");
-                SG_LOG(SG_GENERAL, SG_WARN, "Using  " << pushBackNode);
-            }
-            pushBackRoute->first();
- 	    while(pushBackRoute->next(&node, &rte))
+		SG_LOG(SG_GENERAL, SG_WARN, "Using  " << pushBackNode);
+	    }
+	    pushBackRoute->first();
+	    while(pushBackRoute->next(&node, &rte))
 	      {
 		//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
 		char buffer[10];
@@ -130,70 +130,73 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
 		FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
 		//ids.pop_back();  
 		//wpt = new waypoint;
-                SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
-                FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
+		SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
+		FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
 
 		wpt->setRouteIndex(rte);
 		waypoints.push_back(wpt);
 	      }
-              // some special considerations for the last point:
-              waypoints.back()->setName(string("PushBackPoint"));
-              waypoints.back()->setSpeed(vTaxi);
-              ac->setTaxiClearanceRequest(true);
-        } else {  // In case of a push forward departure...
-           ac->setTaxiClearanceRequest(false);
-           double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
+	      // some special considerations for the last point:
+	      waypoints.back()->setName(string("PushBackPoint"));
+	      waypoints.back()->setSpeed(vTaxi);
+	      ac->setTaxiClearanceRequest(true);
+	} else {  // In case of a push forward departure...
+	  ac->setTaxiClearanceRequest(false);
+	  double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
 
-           //cerr << "Creating final push forward point for gate " << gateId << endl;
-	   FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
-	   FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
-	   FGTaxiSegmentVectorIterator te = tn->getEndRoute();
-	   if (ts == te) {
-               SG_LOG(SG_GENERAL, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
-               //exit(1);
-	   }
-           tn = (*ts)->getEnd();
-           lastNodeVisited = tn->getIndex();
-	   if (tn == NULL) {
-               SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
-               exit(1);
-           }
-           double distance = (*ts)->getLength();
-           //cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
-           lat2 =  tn->getLatitude();
-           lon2 =  tn->getLongitude();
+	  //cerr << "Creating final push forward point for gate " << gateId << endl;
+	  FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
+	  FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
+	  FGTaxiSegmentVectorIterator te = tn->getEndRoute();
+	  // if the starting node equals the ending node, then there aren't any routes for this parking.
+          // in cases like these we should flag the gate as being inoperative and return false
+	  if (ts == te) {
+	      SG_LOG(SG_GENERAL, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
+              parking->setAvailable(false);
+              return false;
+	  }
+	  tn = (*ts)->getEnd();
+	  lastNodeVisited = tn->getIndex();
+	  if (tn == NULL) {
+	      SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
+	      exit(1);
+	  }
+	  double distance = (*ts)->getLength();
+	  //cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
+	  lat2 =  tn->getLatitude();
+	  lon2 =  tn->getLongitude();
 
-           for (int i = 1; i < 10; i++) {
-                geo_direct_wgs_84 ( 0, lat, lon, heading, 
-                                   ((i / 10.0) * distance), &lat2, &lon2, &az2 );
-                char buffer[16];
-                snprintf(buffer, 16, "pushback-%02d", i);
-                SGGeod coord = coord.fromDeg(lon2, lat2);
-                //cerr << i << endl;
-                FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
+	  for (int i = 1; i < 10; i++) {
+		geo_direct_wgs_84 ( 0, lat, lon, heading, 
+				  ((i / 10.0) * distance), &lat2, &lon2, &az2 );
+		char buffer[16];
+		snprintf(buffer, 16, "pushback-%02d", i);
+		SGGeod coord = coord.fromDeg(lon2, lat2);
+		//cerr << i << endl;
+		FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
 
-                wpt->setRouteIndex((*ts)->getIndex());
-                waypoints.push_back(wpt); 
-           }
-           // cerr << "Done " << endl;
-           waypoints.back()->setName(string("PushBackPoint"));
-           // cerr << "Done assinging new name" << endl;
-        }
+		wpt->setRouteIndex((*ts)->getIndex());
+		waypoints.push_back(wpt); 
+	  }
+	  // cerr << "Done " << endl;
+	  waypoints.back()->setName(string("PushBackPoint"));
+	  // cerr << "Done assinging new name" << endl;
+	}
     }
     return true;
 }
 /*******************************************************************
- * createPushBackFallBack
- * This is the backup function for airports that don't have a 
- * network yet. 
- ******************************************************************/
+* createPushBackFallBack
+* This is the backup function for airports that don't have a 
+* network yet. 
+******************************************************************/
 void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, 
- 				    double latitude,
- 				    double longitude,
- 				    double radius,
- 				    const string& fltType,
- 				    const string& aircraftType,
- 				    const string& airline)
+				    double latitude,
+				    double longitude,
+				    double radius,
+				    const string& fltType,
+				    const string& aircraftType,
+				    const string& airline)
 {
   double heading;
   double lat;
@@ -212,7 +215,7 @@ void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight,
 
   heading += 180.0;
   if (heading > 360)
-        heading -= 360;
+	heading -= 360;
 
   SGGeod coord = coord.fromDeg(lon, lat);
   FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
@@ -220,16 +223,16 @@ void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight,
   waypoints.push_back(wpt); 
 
   geo_direct_wgs_84 ( 0, lat, lon, heading, 
- 		      10, 
- 		      &lat2, &lon2, &az2 );
+		      10, 
+		      &lat2, &lon2, &az2 );
   coord = coord.fromDeg(lon2, lat2); 
   wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
 
   waypoints.push_back(wpt); 
 
   geo_direct_wgs_84 ( 0, lat, lon, heading, 
- 		      2.2*radius,           
- 		      &lat2, &lon2, &az2 );
+		      2.2*radius,           
+		      &lat2, &lon2, &az2 );
   coord = coord.fromDeg(lon2, lat2); 
   wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
   waypoints.push_back(wpt);
diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index 41743e6e7..73130fe63 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -37,6 +37,7 @@ FGATCManager::FGATCManager() {
     controller = 0;
     prevController = 0;
     networkVisible = false;
+    initSucceeded  = false;
 }
 
 FGATCManager::~FGATCManager() {
@@ -136,7 +137,7 @@ void FGATCManager::init() {
             string aircraftType; // Unused.
             string airline;      // Currently used for gate selection, but a fallback mechanism will apply when not specified.
             fp->setGate(park_index);
-            fp->createPushBack(&ai_ac,
+            if (!(fp->createPushBack(&ai_ac,
                                false, 
                                apt, 
                                latitude,
@@ -144,7 +145,10 @@ void FGATCManager::init() {
                                aircraftRadius,
                                fltType,
                                aircraftType,
-                               airline);
+                               airline))) {
+                controller = 0;
+                return;
+            }
 
         }
         fp->getLastWaypoint()->setName( fp->getLastWaypoint()->getName() + string("legend")); 
@@ -170,6 +174,7 @@ void FGATCManager::init() {
    //cerr << "Adding groundnetWork to the scenegraph::init" << endl;
    //globals->get_scenery()->get_scene_graph()->addChild(node);
    }
+   initSucceeded = true;
 }
 
 void FGATCManager::addController(FGATCController *controller) {
diff --git a/src/ATC/atc_mgr.hxx b/src/ATC/atc_mgr.hxx
index 277ad4d9b..38a2def72 100644
--- a/src/ATC/atc_mgr.hxx
+++ b/src/ATC/atc_mgr.hxx
@@ -52,6 +52,7 @@ private:
   FGATCController *controller, *prevController; // The ATC controller that is responsible for the user's aircraft. 
   //FGATCDialogNew dialog;  // note that this variable should really replace the ugly global "currentATCDialog();
   bool networkVisible;
+  bool initSucceeded;
 
 public:
   FGATCManager();

From 7a83db28c6f64fa005904500a9623a37fe2d94c2 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 11 Sep 2011 21:44:43 +0200
Subject: [PATCH 23/85] Lower the requirements on Cmake version (at least until
 Jenkins is updated)

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34711fc17..e6d449217 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.8)
+cmake_minimum_required (VERSION 2.6.4)
 
 include (CheckFunctionExists)
 include (CheckCSourceCompiles)

From 81b125069b5ff93c42b59c28c24f6f18547a8bb4 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Mon, 12 Sep 2011 08:10:48 +0200
Subject: [PATCH 24/85] cmake: Use a default build type that builds fast
 executables.

---
 CMakeLists.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e6d449217..8dd8107df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,13 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
 # autoconf compatibility
 set(PKGLIBDIR "foo")
 
+# Change the default build type to something fast
+if(NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Release CACHE STRING
+      "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
+      FORCE)
+endif(NOT CMAKE_BUILD_TYPE)
+
 if($ENV{BUILD_ID})
 	set(HUDSON_BUILD_ID $ENV{BUILD_ID})
 	set(HUDSON_BUILD_NUMBER $ENV{BUILD_NUMBER})

From 14fb839c4453d6be8fe32e8acabe6f43573e17ae Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Mon, 12 Sep 2011 11:07:31 +0200
Subject: [PATCH 25/85] Auto detect 3rd Party root for Windows

---
 CMakeLists.txt | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8dd8107df..4a6d8232f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,7 +72,21 @@ option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient
 option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
 option(WITH_FGPANEL "Set to ON to build the fgpanel application" ON)
 
-set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
+if (MSVC)
+  GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
+  if (CMAKE_CL_64)
+    SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
+  else (CMAKE_CL_64)
+    SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty")
+  endif (CMAKE_CL_64)
+  if (EXISTS ${TEST_3RDPARTY_DIR})
+    set(MSVC_3RDPARTY_ROOT ${PARENT_DIR} CACHE PATH "Location where the third-party dependencies are extracted")
+  else (EXISTS ${TEST_3RDPARTY_DIR})
+    set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
+  endif (EXISTS ${TEST_3RDPARTY_DIR})
+else (MSVC)
+  set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
+endif (MSVC)
 
 if(LOGGING)
 	# nothing

From 918202a1ae1a7f6e56263228a8fe86d0f31bef74 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Mon, 12 Sep 2011 11:08:02 +0200
Subject: [PATCH 26/85] Fix SVN detection for Windows

---
 CMakeModules/FindSvnClient.cmake | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 7b175d4f0..566c700cc 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -3,6 +3,7 @@
 
 include (CheckFunctionExists)
 include (CheckIncludeFile)
+include (CheckLibraryExists)
 
 find_program(HAVE_APR_CONFIG apr-1-config)
 if(HAVE_APR_CONFIG) 
@@ -22,7 +23,7 @@ else(HAVE_APR_CONFIG)
     message(STATUS "apr-1-config not found, implement manual search for APR")
 endif(HAVE_APR_CONFIG)
 
-if(HAVE_APR_CONFIG)
+if(HAVE_APR_CONFIG OR MSVC)
 	find_path(LIBSVN_INCLUDE_DIR svn_client.h
 	  HINTS
 	  $ENV{LIBSVN_DIR}
@@ -33,9 +34,15 @@ if(HAVE_APR_CONFIG)
 	  /opt
 	)
 
-	check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
-	check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
-	check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
+	if (MSVC)
+		check_library_exists(libsvn_client-1 svn_client_checkout "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNCLIENT)
+		check_library_exists(libsvn_subr-1 svn_cmdline_init "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNSUBR)
+		check_library_exists(libsvn_ra-1 svn_ra_initialize "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNRA)
+	else (MSVC)
+		check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
+		check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
+		check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
+	endif (MSVC)
 
 	include(FindPackageHandleStandardArgs)
 	FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG 
@@ -47,4 +54,4 @@ if(HAVE_APR_CONFIG)
 	if(LIBSVN_FOUND)
 		set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
 	endif(LIBSVN_FOUND)
-endif(HAVE_APR_CONFIG)
+endif(HAVE_APR_CONFIG OR MSVC)

From d3d358bdbdf0b7a20c13e9b3ce024da912e3e0bc Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Mon, 12 Sep 2011 11:08:32 +0200
Subject: [PATCH 27/85] Don't try to find winmm

---
 CMakeModules/FindPLIB.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeModules/FindPLIB.cmake b/CMakeModules/FindPLIB.cmake
index 987943eb1..685c54d63 100644
--- a/CMakeModules/FindPLIB.cmake
+++ b/CMakeModules/FindPLIB.cmake
@@ -161,7 +161,7 @@ if(${haveJs} GREATER -1)
         find_library(CF_LIBRARY CoreFoundation)
         set(JS_LIBS ${IOKIT_LIBRARY} ${CF_LIBRARY})
     elseif(WIN32)
-        find_library(WINMM_LIBRARY winmm)
+        set(WINMM_LIBRARY winmm)
         set(JS_LIBS ${WINMM_LIBRARY})
     elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
         # anything needed here?

From 8a63b26c426fde995d17dfd9f86d620555cbb122 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Mon, 12 Sep 2011 12:14:08 +0200
Subject: [PATCH 28/85] Attempt to make FindSvnClient.cmake portable

---
 CMakeModules/FindSvnClient.cmake | 48 +++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 566c700cc..f5b567741 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -5,6 +5,30 @@ include (CheckFunctionExists)
 include (CheckIncludeFile)
 include (CheckLibraryExists)
 
+macro(find_static_component comp libs)
+    # account for alternative Windows svn distribution naming
+    if(MSVC)
+      set(compLib "lib${comp}")
+    else(MSVC)
+      set(compLib "${comp}")
+    endif(MSVC)
+    
+    string(TOUPPER "${comp}" compLibBase)
+    set( compLibName ${compLibBase}_LIBRARY )
+
+    FIND_LIBRARY(${compLibName}
+      NAMES ${compLib}
+      HINTS $ENV{PLIBDIR}
+      PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
+      PATHS
+      /usr/local
+      /usr
+      /opt
+    )
+
+	list(APPEND ${libs} ${${compLibName}})
+endmacro()
+
 find_program(HAVE_APR_CONFIG apr-1-config)
 if(HAVE_APR_CONFIG) 
         
@@ -33,25 +57,17 @@ if(HAVE_APR_CONFIG OR MSVC)
 	  /usr
 	  /opt
 	)
-
+	
+	set(LIBSVN_LIBRARIES "")
 	if (MSVC)
-		check_library_exists(libsvn_client-1 svn_client_checkout "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNCLIENT)
-		check_library_exists(libsvn_subr-1 svn_cmdline_init "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNSUBR)
-		check_library_exists(libsvn_ra-1 svn_ra_initialize "${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib" HAVE_LIB_SVNRA)
+		find_static_component("apr-1" LIBSVN_LIBRARIES)
 	else (MSVC)
-		check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
-		check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
-		check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
+		list(APPEND LIBSVN_LIBRARIES APR_LIBS)
 	endif (MSVC)
+	find_static_component("svn_client-1" LIBSVN_LIBRARIES)
+	find_static_component("svn_subr-1" LIBSVN_LIBRARIES)
+	find_static_component("svn_ra-1" LIBSVN_LIBRARIES)
 
 	include(FindPackageHandleStandardArgs)
-	FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG 
-		HAVE_LIB_SVNSUBR 
-		HAVE_LIB_SVNCLIENT
-		HAVE_LIB_SVNRA 
-		LIBSVN_INCLUDE_DIR)
-
-	if(LIBSVN_FOUND)
-		set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
-	endif(LIBSVN_FOUND)
+	FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG LIBSVN_LIBRARIES LIBSVN_INCLUDE_DIR)
 endif(HAVE_APR_CONFIG OR MSVC)

From 587895bf2b0982f9dfc588094126520845e64bba Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Mon, 12 Sep 2011 12:20:22 +0200
Subject: [PATCH 29/85] Typo

---
 CMakeModules/FindSvnClient.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index f5b567741..22ae0999c 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -62,7 +62,7 @@ if(HAVE_APR_CONFIG OR MSVC)
 	if (MSVC)
 		find_static_component("apr-1" LIBSVN_LIBRARIES)
 	else (MSVC)
-		list(APPEND LIBSVN_LIBRARIES APR_LIBS)
+		list(APPEND LIBSVN_LIBRARIES ${APR_LIBS})
 	endif (MSVC)
 	find_static_component("svn_client-1" LIBSVN_LIBRARIES)
 	find_static_component("svn_subr-1" LIBSVN_LIBRARIES)

From 9cef27f5ca7486230d1158748f994cba0ceea673 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Tue, 13 Sep 2011 20:06:31 +0200
Subject: [PATCH 30/85] Refactor morse and beacon as singleton

---
 projects/VC90/FlightGear/FlightGear.vcproj |  8 +++
 src/Instrumentation/adf.cxx                |  6 +-
 src/Instrumentation/adf.hxx                |  2 -
 src/Instrumentation/kr_87.cxx              |  4 +-
 src/Instrumentation/kr_87.hxx              |  3 -
 src/Instrumentation/marker_beacon.cxx      |  9 ++-
 src/Instrumentation/marker_beacon.hxx      |  6 --
 src/Instrumentation/navradio.cxx           |  7 +--
 src/Instrumentation/navradio.hxx           |  3 -
 src/Sound/CMakeLists.txt                   |  4 +-
 src/Sound/Makefile.am                      |  1 +
 src/Sound/beacon.cxx                       | 13 ++++-
 src/Sound/beacon.hxx                       | 43 ++++++--------
 src/Sound/morse.cxx                        | 50 ++++------------
 src/Sound/morse.hxx                        | 29 +++-------
 src/Sound/soundgenerator.cxx               | 64 +++++++++++++++++++++
 src/Sound/soundgenerator.hxx               | 67 ++++++++++++++++++++++
 17 files changed, 202 insertions(+), 117 deletions(-)
 create mode 100644 src/Sound/soundgenerator.cxx
 create mode 100644 src/Sound/soundgenerator.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index c9f3558c8..77d845292 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3229,6 +3229,14 @@
 				RelativePath="..\..\..\src\Sound\sample_queue.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\Sound\soundgenerator.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Sound\soundgenerator.hxx"
+				>
+			</File>
 			<File
 				RelativePath="..\..\..\src\Sound\voice.cxx"
 				>
diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx
index 41ee7700e..e3fbac053 100644
--- a/src/Instrumentation/adf.cxx
+++ b/src/Instrumentation/adf.cxx
@@ -17,6 +17,8 @@
 #include <Navaids/navlist.hxx>
 
 #include "adf.hxx"
+#include <Sound/morse.hxx>
+
 
 #include <iostream>
 #include <string>
@@ -110,8 +112,6 @@ ADF::init ()
     _sgr = smgr->find("avionics", true);
     _sgr->tie_to_listener();
 
-    morse.init();
-
     std::ostringstream temp;
     temp << _name << _num;
     _adf_ident = temp.str();
@@ -252,7 +252,7 @@ ADF::search (double frequency_khz, double longitude_rad,
         }
 
         SGSoundSample *sound;
-        sound = morse.make_ident( ident, LO_FREQUENCY );
+        sound = FGMorse::instance()->make_ident( ident, LO_FREQUENCY );
         sound->set_volume(_last_volume = 0);
         _sgr->add( sound, _adf_ident );
 
diff --git a/src/Instrumentation/adf.hxx b/src/Instrumentation/adf.hxx
index 88817a8ee..5b1b1667d 100644
--- a/src/Instrumentation/adf.hxx
+++ b/src/Instrumentation/adf.hxx
@@ -16,7 +16,6 @@
 #include <simgear/props/props.hxx>
 
 #include <simgear/structure/subsystem_mgr.hxx>
-#include <Sound/morse.hxx>
 
 using std::string;
 
@@ -93,7 +92,6 @@ private:
     SGVec3d _transmitter_cart;
     double _transmitter_range_nm;
 
-    FGMorse morse;
     int _ident_count;
     time_t _last_ident_time;
     float _last_volume;
diff --git a/src/Instrumentation/kr_87.cxx b/src/Instrumentation/kr_87.cxx
index 30c0cbe66..9b91babea 100644
--- a/src/Instrumentation/kr_87.cxx
+++ b/src/Instrumentation/kr_87.cxx
@@ -36,6 +36,7 @@
 
 #include "kr_87.hxx"
 
+#include <Sound/morse.hxx>
 #include <string>
 using std::string;
 
@@ -119,7 +120,6 @@ void FGKR_87::init () {
     SGSoundMgr *smgr = globals->get_soundmgr();
     _sgr = smgr->find("avionics", true);
     _sgr->tie_to_listener();
-    morse.init();
 }
 
 
@@ -534,7 +534,7 @@ void FGKR_87::search() {
 		_sgr->remove( "adf-ident" );
 	    }
 	    SGSoundSample *sound;
-	    sound = morse.make_ident( trans_ident, LO_FREQUENCY );
+        sound = FGMorse::instance()->make_ident( trans_ident, LO_FREQUENCY );
 	    sound->set_volume( 0.3 );
 	    _sgr->add( sound, "adf-ident" );
 
diff --git a/src/Instrumentation/kr_87.hxx b/src/Instrumentation/kr_87.hxx
index e59beba7b..14accba9f 100644
--- a/src/Instrumentation/kr_87.hxx
+++ b/src/Instrumentation/kr_87.hxx
@@ -32,14 +32,11 @@
 #include <simgear/timing/timestamp.hxx>
 
 #include <Navaids/navlist.hxx>
-#include <Sound/morse.hxx>
 
 class SGSampleGroup;
 
 class FGKR_87 : public SGSubsystem
 {
-    FGMorse morse;
-
     SGPropertyNode_ptr lon_node;
     SGPropertyNode_ptr lat_node;
     SGPropertyNode_ptr alt_node;
diff --git a/src/Instrumentation/marker_beacon.cxx b/src/Instrumentation/marker_beacon.cxx
index f7945722d..5fa56fade 100644
--- a/src/Instrumentation/marker_beacon.cxx
+++ b/src/Instrumentation/marker_beacon.cxx
@@ -34,6 +34,7 @@
 #include <Navaids/navlist.hxx>
 
 #include "marker_beacon.hxx"
+#include <Sound/beacon.hxx>
 
 #include <string>
 using std::string;
@@ -120,8 +121,6 @@ FGMarkerBeacon::init ()
     _sgr = smgr->find("avionics", true);
     _sgr->tie_to_listener();
 
-    morse.init();
-    beacon.init();
     blink.stamp();
 
     outer_marker = middle_marker = inner_marker = false;
@@ -317,7 +316,7 @@ void FGMarkerBeacon::search()
             // cout << "OUTER MARKER" << endl;
             if ( last_beacon != OUTER ) {
                 if ( ! _sgr->exists( current_sound_name ) ) {
-                    SGSoundSample *sound = beacon.get_outer();
+                    SGSoundSample *sound = FGBeacon::instance()->get_outer();
                     if ( sound ) {
                         _sgr->add( sound, current_sound_name );
                     }
@@ -336,7 +335,7 @@ void FGMarkerBeacon::search()
             // cout << "MIDDLE MARKER" << endl;
             if ( last_beacon != MIDDLE ) {
                 if ( ! _sgr->exists( current_sound_name ) ) {
-                    SGSoundSample *sound = beacon.get_middle();
+                    SGSoundSample *sound = FGBeacon::instance()->get_middle();
                     if ( sound ) {
                         _sgr->add( sound, current_sound_name );
                     }
@@ -355,7 +354,7 @@ void FGMarkerBeacon::search()
             // cout << "INNER MARKER" << endl;
             if ( last_beacon != INNER ) {
                 if ( ! _sgr->exists( current_sound_name ) ) {
-                    SGSoundSample *sound = beacon.get_inner();
+                    SGSoundSample *sound = FGBeacon::instance()->get_inner();
                     if ( sound ) {
                         _sgr->add( sound, current_sound_name );
                     }
diff --git a/src/Instrumentation/marker_beacon.hxx b/src/Instrumentation/marker_beacon.hxx
index 25e435fea..52259b6a2 100644
--- a/src/Instrumentation/marker_beacon.hxx
+++ b/src/Instrumentation/marker_beacon.hxx
@@ -32,16 +32,10 @@
 #include <simgear/math/interpolater.hxx>
 #include <simgear/timing/timestamp.hxx>
 
-#include <Sound/beacon.hxx>
-#include <Sound/morse.hxx>
-
 class SGSampleGroup;
 
 class FGMarkerBeacon : public SGSubsystem
 {
-    FGBeacon beacon;
-    FGMorse morse;
-
     SGInterpTable *term_tbl;
     SGInterpTable *low_tbl;
     SGInterpTable *high_tbl;
diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx
index 780094c42..886ad1f37 100644
--- a/src/Instrumentation/navradio.cxx
+++ b/src/Instrumentation/navradio.cxx
@@ -44,6 +44,7 @@
 #include <Airports/runways.hxx>
 #include <Navaids/navlist.hxx>
 #include <Main/util.hxx>
+#include <Sound/morse.hxx>
 
 
 using std::string;
@@ -175,8 +176,6 @@ FGNavRadio::init ()
     _sgr = smgr->find("avionics", true);
     _sgr->tie_to_listener();
 
-    morse.init();
-
     SGPropertyNode* node = _radio_node.get();
     bus_power_node = 
 	fgGetNode(("/systems/electrical/outputs/" + _name).c_str(), true);
@@ -1014,7 +1013,7 @@ void FGNavRadio::audioNavidChanged()
   
   try {
     string trans_ident(_navaid->get_trans_ident());
-    SGSoundSample* sound = morse.make_ident(trans_ident, LO_FREQUENCY);
+    SGSoundSample* sound = FGMorse::instance()->make_ident(trans_ident, LO_FREQUENCY);
     sound->set_volume( 0.3 );
     if (!_sgr->add( sound, nav_fx_name )) {
       SG_LOG(SG_COCKPIT, SG_WARN, "Failed to add v1-vor-ident sound");
@@ -1024,7 +1023,7 @@ void FGNavRadio::audioNavidChanged()
       _sgr->remove( dme_fx_name );
     }
      
-    sound = morse.make_ident( trans_ident, HI_FREQUENCY );
+    sound = FGMorse::instance()->make_ident( trans_ident, HI_FREQUENCY );
     sound->set_volume( 0.3 );
     _sgr->add( sound, dme_fx_name );
 
diff --git a/src/Instrumentation/navradio.hxx b/src/Instrumentation/navradio.hxx
index 96621b6d0..4b2e16918 100644
--- a/src/Instrumentation/navradio.hxx
+++ b/src/Instrumentation/navradio.hxx
@@ -26,7 +26,6 @@
 
 
 #include <Main/fg_props.hxx>
-#include "Sound/morse.hxx"
 
 #include <simgear/compiler.h>
 #include <simgear/structure/subsystem_mgr.hxx>
@@ -41,8 +40,6 @@ typedef SGSharedPtr<FGNavRecord> FGNavRecordPtr;
 
 class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
 {
-    FGMorse morse;
-
     SGInterpTable *term_tbl;
     SGInterpTable *low_tbl;
     SGInterpTable *high_tbl;
diff --git a/src/Sound/CMakeLists.txt b/src/Sound/CMakeLists.txt
index 29a1d4854..28cc5bf8c 100644
--- a/src/Sound/CMakeLists.txt
+++ b/src/Sound/CMakeLists.txt
@@ -1,6 +1,7 @@
 include(FlightGearComponent)
 
 set(SOURCES
+	soundgenerator.cxx
 	beacon.cxx
 	fg_fx.cxx
 	morse.cxx
@@ -10,6 +11,7 @@ set(SOURCES
 	)
 
 set(HEADERS
+	soundgenerator.hxx
 	beacon.hxx
 	fg_fx.hxx
 	morse.hxx
@@ -18,4 +20,4 @@ set(HEADERS
 	voiceplayer.hxx
 	)
     		
-flightgear_component(Sound "${SOURCES}" "${HEADERS}")
\ No newline at end of file
+flightgear_component(Sound "${SOURCES}" "${HEADERS}")
diff --git a/src/Sound/Makefile.am b/src/Sound/Makefile.am
index e6799c233..893b776d2 100644
--- a/src/Sound/Makefile.am
+++ b/src/Sound/Makefile.am
@@ -1,6 +1,7 @@
 noinst_LIBRARIES = libSound.a
 
 libSound_a_SOURCES = \
+	soundgenerator.cxx soundgenerator.hxx \
 	beacon.cxx beacon.hxx \
 	fg_fx.cxx fg_fx.hxx \
 	morse.cxx morse.hxx \
diff --git a/src/Sound/beacon.cxx b/src/Sound/beacon.cxx
index de9a98915..9d7a1a184 100644
--- a/src/Sound/beacon.cxx
+++ b/src/Sound/beacon.cxx
@@ -18,8 +18,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
-
 
 #include <stdlib.h>
 #include <cstring>
@@ -104,3 +102,14 @@ bool FGBeacon::init() {
 
     return true;
 }
+
+FGBeacon * FGBeacon::_instance = NULL;
+
+FGBeacon * FGBeacon::instance()
+{
+    if( _instance == NULL ) {
+        _instance = new FGBeacon();
+        _instance->init();
+    }
+    return _instance;
+}
diff --git a/src/Sound/beacon.hxx b/src/Sound/beacon.hxx
index d0c37d697..c60f48225 100644
--- a/src/Sound/beacon.hxx
+++ b/src/Sound/beacon.hxx
@@ -20,24 +20,17 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
-
 
 #ifndef _BEACON_HXX
 #define _BEACON_HXX
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
+#include "soundgenerator.hxx"
 
 #include <simgear/compiler.h>
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/structure/SGReferenced.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 
-#include "morse.hxx"
-
-
 // Quoting from http://www.smartregs.com/data/sa326.htm
 // Smart REGS Glossary - marker beacon
 // 
@@ -77,35 +70,35 @@
 // (See instrument landing system) (Refer to AIM.)
 
 
-static const int INNER_FREQ = 3000;
-static const int MIDDLE_FREQ = 1300;
-static const int OUTER_FREQ = 400;
-
-static const int INNER_SIZE = BYTES_PER_SECOND;
-static const int MIDDLE_SIZE = (int)(BYTES_PER_SECOND * 60 / 95 );
-static const int OUTER_SIZE = BYTES_PER_SECOND;
-
-static const int INNER_DIT_LEN = (int)(BYTES_PER_SECOND / 6.0);
-static const int MIDDLE_DIT_LEN = (int)(MIDDLE_SIZE / 3.0);
-static const int MIDDLE_DAH_LEN = (int)(MIDDLE_SIZE * 2 / 3.0);
-static const int OUTER_DAH_LEN = (int)(BYTES_PER_SECOND / 2.0);
-
 // manages everything we need to know for an individual sound sample
-class FGBeacon {
+class FGBeacon : public FGSoundGenerator {
 
 private:
+    static const int INNER_FREQ = 3000;
+    static const int MIDDLE_FREQ = 1300;
+    static const int OUTER_FREQ = 400;
+
+    static const int INNER_SIZE = BYTES_PER_SECOND;
+    static const int MIDDLE_SIZE = (int)(BYTES_PER_SECOND * 60 / 95 );
+    static const int OUTER_SIZE = BYTES_PER_SECOND;
+
+    static const int INNER_DIT_LEN = (int)(BYTES_PER_SECOND / 6.0);
+    static const int MIDDLE_DIT_LEN = (int)(MIDDLE_SIZE / 3.0);
+    static const int MIDDLE_DAH_LEN = (int)(MIDDLE_SIZE * 2 / 3.0);
+    static const int OUTER_DAH_LEN = (int)(BYTES_PER_SECOND / 2.0);
 
     SGSharedPtr<SGSoundSample> inner;
     SGSharedPtr<SGSoundSample> middle;
     SGSharedPtr<SGSoundSample> outer;
 
+    // allocate and initialize sound samples
+    bool init();
+    static FGBeacon * _instance;
 public:
 
     FGBeacon();
     ~FGBeacon();
-
-    // allocate and initialize sound samples
-    bool init();
+    static FGBeacon * instance();
 
     SGSoundSample *get_inner() { return inner; }
     SGSoundSample *get_middle() { return middle; }
diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx
index 7ae7cac98..9ff603322 100644
--- a/src/Sound/morse.cxx
+++ b/src/Sound/morse.cxx
@@ -18,7 +18,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
 
 
 #include <simgear/constants.h>
@@ -79,44 +78,6 @@ FGMorse::~FGMorse() {
 }
 
 
-// Make a tone of specified freq and total_len with trans_len ramp in
-// and out and only the first len bytes with sound, the rest with
-// silence
-void make_tone( unsigned char *buf, int freq, 
-		int len, int total_len, int trans_len )
-{
-    int i, j;
-
-    for ( i = 0; i < trans_len; ++i ) {
-	float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
-	    * ((double)i / trans_len) / 2.0 + 0.5;
-
-	/* Convert to unsigned byte */
-	buf[ i ] = (unsigned char) ( level * 255.0 ) ;
-    }
-
-    for ( i = trans_len; i < len - trans_len; ++i ) {
-	float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
-	    / 2.0 + 0.5;
-
-	/* Convert to unsigned byte */
-	buf[ i ] = (unsigned char) ( level * 255.0 ) ;
-    }
-    j = trans_len;
-    for ( i = len - trans_len; i < len; ++i ) {
-	float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
-	    * ((double)j / trans_len) / 2.0 + 0.5;
-	--j;
-
-	/* Convert to unsigned byte */
-	buf[ i ] = (unsigned char) ( level * 255.0 ) ;
-    }
-    for ( i = len; i < total_len; ++i ) {
-	buf[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
-    }
-}
-
-
 // allocate and initialize sound samples
 bool FGMorse::init() {
     // Make Low DIT
@@ -270,3 +231,14 @@ SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) {
 
     return sample;
 }
+
+FGMorse * FGMorse::_instance = NULL;
+
+FGMorse * FGMorse::instance()
+{
+    if( _instance == NULL ) {
+        _instance = new FGMorse();
+        _instance->init();
+    }
+    return _instance;
+}
diff --git a/src/Sound/morse.hxx b/src/Sound/morse.hxx
index c6ed5a43b..3d8b9dfbb 100644
--- a/src/Sound/morse.hxx
+++ b/src/Sound/morse.hxx
@@ -18,16 +18,12 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
 
 
 #ifndef _MORSE_HXX
 #define _MORSE_HXX
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
+#include "soundgenerator.hxx"
 #include <simgear/compiler.h>
 #include <simgear/sound/soundmgr_openal.hxx>
 
@@ -97,7 +93,7 @@ static const int LO_FREQUENCY = 1020;	 // AIM 1-1-7 (f) specified in Hz
 static const int HI_FREQUENCY = 1350;	 // AIM 1-1-7 (f) specified in Hz
 
 // manages everything we need to know for an individual sound sample
-class FGMorse {
+class FGMorse : public FGSoundGenerator {
 
 private:
 
@@ -110,15 +106,18 @@ private:
     unsigned char cust_dit[ DIT_SIZE ] ;
     unsigned char cust_dah[ DAH_SIZE ] ;
 
+    static FGMorse * _instance;
+
     bool cust_init( const int freq );
+    // allocate and initialize sound samples
+    bool init();
 
 public:
 
     FGMorse();
     ~FGMorse();
 
-    // allocate and initialize sound samples
-    bool init();
+    static FGMorse * instance();
 
     // make a SimpleSound morse code transmission for the specified string
     SGSoundSample *make_ident( const string& id,
@@ -126,20 +125,6 @@ public:
 };
 
 
-/**
- * \relates FGMorse
- * Make a tone of specified freq and total_len with trans_len ramp in
- * and out and only the first len bytes with sound, the rest with
- * silence.
- * @param buf unsigned char pointer to sound buffer
- * @param freq desired frequency of tone
- * @param len length of tone within sound
- * @param total_len total length of sound (anything more than len is padded
- *        with silence.
- * @param trans_len length of ramp up and ramp down to avoid audio "pop"
- */
-void make_tone( unsigned char *buf, int freq, 
-		int len, int total_len, int trans_len );
 
 #endif // _MORSE_HXX
 
diff --git a/src/Sound/soundgenerator.cxx b/src/Sound/soundgenerator.cxx
new file mode 100644
index 000000000..0f5743ee2
--- /dev/null
+++ b/src/Sound/soundgenerator.cxx
@@ -0,0 +1,64 @@
+// soundgenerator.cxx -- simple sound generation 
+//
+// Written by Curtis Olson, started March 2001.
+//
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#include "soundgenerator.hxx"
+#include <simgear/constants.h>
+
+FGSoundGenerator::~FGSoundGenerator()
+{
+}
+
+// Make a tone of specified freq and total_len with trans_len ramp in
+// and out and only the first len bytes with sound, the rest with
+// silence
+void FGSoundGenerator::make_tone( unsigned char *buf, int freq, 
+		int len, int total_len, int trans_len )
+{
+    int i, j;
+
+    for ( i = 0; i < trans_len; ++i ) {
+        float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
+            * ((double)i / trans_len) / 2.0 + 0.5;
+
+        /* Convert to unsigned byte */
+        buf[ i ] = (unsigned char) ( level * 255.0 ) ;
+    }
+
+    for ( i = trans_len; i < len - trans_len; ++i ) {
+        float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
+            / 2.0 + 0.5;
+
+        /* Convert to unsigned byte */
+        buf[ i ] = (unsigned char) ( level * 255.0 ) ;
+    }
+    j = trans_len;
+    for ( i = len - trans_len; i < len; ++i ) {
+        float level = ( sin( (double) i * SGD_2PI / (BYTES_PER_SECOND / freq) ) )
+            * ((double)j / trans_len) / 2.0 + 0.5;
+        --j;
+
+        /* Convert to unsigned byte */
+        buf[ i ] = (unsigned char) ( level * 255.0 ) ;
+    }
+    for ( i = len; i < total_len; ++i ) {
+        buf[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
+    }
+}
diff --git a/src/Sound/soundgenerator.hxx b/src/Sound/soundgenerator.hxx
new file mode 100644
index 000000000..fa600f347
--- /dev/null
+++ b/src/Sound/soundgenerator.hxx
@@ -0,0 +1,67 @@
+// soundgenerator.hxx -- simple sound generation 
+//
+// Written by Curtis Olson, started March 2001.
+//
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+
+#ifndef _FGSOUNDGENERATOR_HXX
+#define _FGSOUNDGENERATOR_HXX
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+class FGSoundGenerator {
+
+public:
+    static const int BYTES_PER_SECOND = 22050;
+    // static const int BEAT_LENGTH = 240; // milleseconds (5 wpm)
+    static const int BEAT_LENGTH = 92;  // milleseconds (13 wpm)
+    static const int TRANSITION_BYTES = (int)(0.005 * BYTES_PER_SECOND);
+    static const int COUNT_SIZE = BYTES_PER_SECOND * BEAT_LENGTH / 1000;
+    static const int DIT_SIZE = 2 * COUNT_SIZE;   // 2 counts
+    static const int DAH_SIZE = 4 * COUNT_SIZE;   // 4 counts
+    static const int SPACE_SIZE = 3 * COUNT_SIZE; // 3 counts
+    static const int LO_FREQUENCY = 1020;	 // AIM 1-1-7 (f) specified in Hz
+    static const int HI_FREQUENCY = 1350;	 // AIM 1-1-7 (f) specified in Hz
+
+protected:
+    /**
+    * \relates FGMorse
+    * Make a tone of specified freq and total_len with trans_len ramp in
+    * and out and only the first len bytes with sound, the rest with
+    * silence.
+    * @param buf unsigned char pointer to sound buffer
+    * @param freq desired frequency of tone
+    * @param len length of tone within sound
+    * @param total_len total length of sound (anything more than len is padded
+    *        with silence.
+    * @param trans_len length of ramp up and ramp down to avoid audio "pop"
+    */
+    static void make_tone( unsigned char *buf, int freq, 
+        int len, int total_len, int trans_len );
+
+public:
+
+    virtual ~FGSoundGenerator();
+};
+
+
+
+#endif // _FGSOUNDGENERATOR_HXX

From 633b07dedc28cd6ff482e9c94d42ae2968b31e15 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Wed, 14 Sep 2011 09:57:57 +0200
Subject: [PATCH 31/85] cmake: clear the svn libraries variable if not found.

---
 CMakeModules/FindSvnClient.cmake | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 22ae0999c..15f6ba27a 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -70,4 +70,7 @@ if(HAVE_APR_CONFIG OR MSVC)
 
 	include(FindPackageHandleStandardArgs)
 	FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG LIBSVN_LIBRARIES LIBSVN_INCLUDE_DIR)
+        if(NOT LIBSVN_FOUND)
+		set(LIBSVN_LIBRARIES "")
+        endif(NOT LIBSVN_FOUND)
 endif(HAVE_APR_CONFIG OR MSVC)

From 2de3872d664cbe14f50b68bd39364effdd054167 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Thu, 15 Sep 2011 09:54:00 +0100
Subject: [PATCH 32/85] In joystick configurations, fall back to <unix> if no
 <mac> entry was provided, since the number is frequently identical.

---
 src/Input/CMakeLists.txt      | 13 ++++++++++++-
 src/Input/FGJoystickInput.cxx | 13 +++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index eb9916107..4c5939d4a 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -18,6 +18,17 @@ set(SOURCES
 	input.cxx	
 	)
 	
+set(HEADERS
+	FGButton.hxx
+    FGCommonInput.hxx
+    FGDeviceConfigurationMap.hxx
+    FGEventInput.hxx
+    FGJoystickInput.hxx
+    FGKeyboardInput.hxx
+    FGMouseInput.hxx
+    input.hxx
+	)
+    	
 if(EVENT_INPUT)
 	list(APPEND SOURCES ${EVENT_INPUT_SOURCES})
 	include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
@@ -43,6 +54,6 @@ target_link_libraries(js_demo
 	${PLIB_LIBRARIES}
 	${SIMGEAR_CORE_LIBRARY_DEPENDENCIES})
 
-flightgear_component(Input "${SOURCES}")
+flightgear_component(Input "${SOURCES}" "${HEADERS}")
 
 install(TARGETS fgjs js_demo RUNTIME DESTINATION bin)
diff --git a/src/Input/FGJoystickInput.cxx b/src/Input/FGJoystickInput.cxx
index 456747647..516679f25 100644
--- a/src/Input/FGJoystickInput.cxx
+++ b/src/Input/FGJoystickInput.cxx
@@ -217,10 +217,19 @@ void FGJoystickInput::postinit()
       if (num_node != 0) {
           n_axis = num_node->getIntValue(TGT_PLATFORM, -1);
 
+        #ifdef SG_MAC
+          // Mac falls back to Unix by default - avoids specifying many
+          // duplicate <mac> entries in joystick config files
+          if (n_axis < 0) {
+              n_axis = num_node->getIntValue("unix", -1);
+          }
+        #endif
+          
           // Silently ignore platforms that are not specified within the
           // <number></number> section
-          if (n_axis < 0)
-             continue;
+          if (n_axis < 0) {
+              continue;
+          }
       }
 
       if (n_axis >= naxes) {

From 43109feb0c6a2ab35d5f1ee9318daadff811cc88 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Thu, 15 Sep 2011 21:28:30 +0200
Subject: [PATCH 33/85] Some more refactoring of the radios

- wrap the ident-generating code into a class
- move dme-in-range property into dme.cxx
- move dme-ident generation into dme.cxx
- support ident-button and volume for dme idents
- use globals.get_aircraft_position instead of properties
- some minor cleanup
---
 projects/VC90/FlightGear/FlightGear.vcproj |   8 +
 src/Instrumentation/adf.cxx                |   2 +-
 src/Instrumentation/dme.cxx                |  99 ++++++------
 src/Instrumentation/dme.hxx                |  16 +-
 src/Instrumentation/kr_87.cxx              |  13 +-
 src/Instrumentation/kr_87.hxx              |   3 -
 src/Instrumentation/navradio.cxx           | 171 ++++-----------------
 src/Instrumentation/navradio.hxx           |  30 +---
 src/Sound/CMakeLists.txt                   |   2 +
 src/Sound/Makefile.am                      |   1 +
 src/Sound/audioident.cxx                   | 141 +++++++++++++++++
 src/Sound/audioident.hxx                   |  65 ++++++++
 src/Sound/morse.cxx                        |   6 +
 src/Sound/morse.hxx                        |  28 ++--
 14 files changed, 323 insertions(+), 262 deletions(-)
 create mode 100644 src/Sound/audioident.cxx
 create mode 100644 src/Sound/audioident.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index 77d845292..1ae6559ab 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3197,6 +3197,14 @@
 		<Filter
 			Name="Lib_Sound"
 			>
+			<File
+				RelativePath="..\..\..\src\Sound\audioident.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Sound\audioident.hxx"
+				>
+			</File>
 			<File
 				RelativePath="..\..\..\src\Sound\beacon.cxx"
 				>
diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx
index e3fbac053..805be1040 100644
--- a/src/Instrumentation/adf.cxx
+++ b/src/Instrumentation/adf.cxx
@@ -252,7 +252,7 @@ ADF::search (double frequency_khz, double longitude_rad,
         }
 
         SGSoundSample *sound;
-        sound = FGMorse::instance()->make_ident( ident, LO_FREQUENCY );
+        sound = FGMorse::instance()->make_ident( ident, FGMorse::LO_FREQUENCY );
         sound->set_volume(_last_volume = 0);
         _sgr->add( sound, _adf_ident );
 
diff --git a/src/Instrumentation/dme.cxx b/src/Instrumentation/dme.cxx
index 925681e0a..d8d14a5a2 100644
--- a/src/Instrumentation/dme.cxx
+++ b/src/Instrumentation/dme.cxx
@@ -8,15 +8,16 @@
 #endif
 
 #include <simgear/compiler.h>
+#include <simgear/sg_inlines.h>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/math/sg_random.h>
 
 #include <Main/fg_props.hxx>
 #include <Navaids/navlist.hxx>
+#include <Sound/audioident.hxx>
 
 #include "dme.hxx"
 
-
 /**
  * Adjust the range.
  *
@@ -44,17 +45,16 @@ DME::DME ( SGPropertyNode *node )
     : _last_distance_nm(0),
       _last_frequency_mhz(-1),
       _time_before_search_sec(0),
-      _transmitter_valid(false),
-      _transmitter_elevation_ft(0),
-      _transmitter_range_nm(0),
-      _transmitter_bias(0.0),
+      _navrecord(NULL),
       _name(node->getStringValue("name", "dme")),
-      _num(node->getIntValue("number", 0))
+      _num(node->getIntValue("number", 0)),
+      _audioIdent(NULL)
 {
 }
 
 DME::~DME ()
 {
+    delete _audioIdent;
 }
 
 void
@@ -65,9 +65,6 @@ DME::init ()
 
     SGPropertyNode *node = fgGetNode(branch.c_str(), _num, true );
 
-    _longitude_node = fgGetNode("/position/longitude-deg", true);
-    _latitude_node = fgGetNode("/position/latitude-deg", true);
-    _altitude_node = fgGetNode("/position/altitude-ft", true);
     _serviceable_node = node->getChild("serviceable", 0, true);
     _electrical_node = fgGetNode("/systems/electrical/outputs/dme", true);
     SGPropertyNode *fnode = node->getChild("frequencies", 0, true);
@@ -77,11 +74,28 @@ DME::init ()
     _distance_node = node->getChild("indicated-distance-nm", 0, true);
     _speed_node = node->getChild("indicated-ground-speed-kt", 0, true);
     _time_node = node->getChild("indicated-time-min", 0, true);
+
+    double d = node->getDoubleValue( "volume", 1.0 );
+    _volume_node = node->getChild("volume", 0, true);
+    _volume_node->setDoubleValue( d );
+
+    bool b = node->getBoolValue( "ident", false );
+    _ident_btn_node = node->getChild("ident", 0, true);
+    _ident_btn_node->setBoolValue( b );
+
+    std::ostringstream temp;
+    temp << _name << "-ident-" << _num;
+    if( NULL == _audioIdent ) 
+        _audioIdent = new DMEAudioIdent( temp.str() );
+    _audioIdent->init();
 }
 
 void
 DME::update (double delta_time_sec)
 {
+    if( delta_time_sec < SGLimitsd::min() )
+        return;  //paused
+
                                 // Figure out the source
     const char * source = _source_node->getStringValue();
     if (source[0] == '\0') {
@@ -100,48 +114,50 @@ DME::update (double delta_time_sec)
     _frequency_node->setDoubleValue(frequency_mhz);
 
                                 // Get the aircraft position
-    double longitude_rad =
-        _longitude_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double latitude_rad =
-        _latitude_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
-    double altitude_m =
-        _altitude_node->getDoubleValue() * SG_FEET_TO_METER;
-
-                                // On timeout, scan again
+    // On timeout, scan again
     _time_before_search_sec -= delta_time_sec;
-    if (_time_before_search_sec < 0)
-        search(frequency_mhz, longitude_rad,
-               latitude_rad, altitude_m);
+    if (_time_before_search_sec < 0) {
+        _time_before_search_sec = 1.0;
 
-                                // If it's off, don't bother.
+        _navrecord = globals->get_dmelist()->findByFreq( frequency_mhz,
+            globals->get_aircraft_position());
+    }
+
+    // If it's off, don't bother.
     if (!_serviceable_node->getBoolValue() ||
         !_electrical_node->getBoolValue() ||
-        !_transmitter_valid) {
+        NULL == _navrecord ) {
         _last_distance_nm = 0;
         _in_range_node->setBoolValue(false);
         _distance_node->setDoubleValue(0);
         _speed_node->setDoubleValue(0);
         _time_node->setDoubleValue(0);
+        _audioIdent->setIdent("", 0.0 );
         return;
     }
 
-                                // Calculate the distance to the transmitter
-    SGGeod geod = SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m);
-    SGVec3d location = SGVec3d::fromGeod(geod);
+    // Calculate the distance to the transmitter
+    SGVec3d location = SGVec3d::fromGeod(globals->get_aircraft_position());
     
-    double distance_nm = dist(_transmitter, location) * SG_METER_TO_NM;
+    double distance_nm = dist(_navrecord->cart(), location) * SG_METER_TO_NM;
 
-    double range_nm = adjust_range(_transmitter_elevation_ft,
-                                   altitude_m * SG_METER_TO_FEET,
-                                   _transmitter_range_nm);
+    double range_nm = adjust_range(_navrecord->get_elev_ft(),
+                                   globals->get_aircraft_position().getElevationFt(),
+                                   _navrecord->get_range());
 
     if (distance_nm <= range_nm) {
+        double volume = _volume_node->getDoubleValue();
+        if( false == _ident_btn_node->getBoolValue() )
+            volume = 0.0;
+
+        _audioIdent->setIdent(_navrecord->ident(), volume );
+
         double speed_kt = (fabs(distance_nm - _last_distance_nm) *
                            ((1 / delta_time_sec) * 3600.0));
         _last_distance_nm = distance_nm;
 
         _in_range_node->setBoolValue(true);
-        double tmp_dist = distance_nm - _transmitter_bias;
+        double tmp_dist = distance_nm - _navrecord->get_multiuse();
         if ( tmp_dist < 0.0 ) {
             tmp_dist = 0.0;
         }
@@ -156,29 +172,10 @@ DME::update (double delta_time_sec)
         _distance_node->setDoubleValue(0);
         _speed_node->setDoubleValue(0);
         _time_node->setDoubleValue(0);
+        _audioIdent->setIdent("", 0.0 );
     }
-}
-
-void
-DME::search (double frequency_mhz, double longitude_rad,
-             double latitude_rad, double altitude_m)
-{
-    // reset search time
-    _time_before_search_sec = 1.0;
-
-    // try the ILS list first
     
-    FGNavRecord *dme = globals->get_dmelist()->findByFreq( frequency_mhz,
-      SGGeod::fromRadM(longitude_rad, latitude_rad, altitude_m));
-
-    _transmitter_valid = (dme != NULL);
-
-    if ( _transmitter_valid ) {
-        _transmitter = dme->cart();
-        _transmitter_elevation_ft = dme->get_elev_ft();
-        _transmitter_range_nm = dme->get_range();
-        _transmitter_bias = dme->get_multiuse();
-    }
+    _audioIdent->update( delta_time_sec );
 }
 
 // end of dme.cxx
diff --git a/src/Instrumentation/dme.hxx b/src/Instrumentation/dme.hxx
index 5d9963b10..6ec6edc63 100644
--- a/src/Instrumentation/dme.hxx
+++ b/src/Instrumentation/dme.hxx
@@ -10,7 +10,6 @@
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 
-
 /**
  * Model a DME radio.
  *
@@ -44,12 +43,6 @@ public:
 
 private:
 
-    void search (double frequency, double longitude_rad,
-                 double latitude_rad, double altitude_m);
-
-    SGPropertyNode_ptr _longitude_node;
-    SGPropertyNode_ptr _latitude_node;
-    SGPropertyNode_ptr _altitude_node;
     SGPropertyNode_ptr _serviceable_node;
     SGPropertyNode_ptr _electrical_node;
     SGPropertyNode_ptr _source_node;
@@ -59,20 +52,19 @@ private:
     SGPropertyNode_ptr _distance_node;
     SGPropertyNode_ptr _speed_node;
     SGPropertyNode_ptr _time_node;
+    SGPropertyNode_ptr _ident_btn_node;
+    SGPropertyNode_ptr _volume_node;
 
     double _last_distance_nm;
     double _last_frequency_mhz;
     double _time_before_search_sec;
 
-    bool _transmitter_valid;
-    SGVec3d _transmitter;
-    double _transmitter_elevation_ft;
-    double _transmitter_range_nm;
-    double _transmitter_bias;
+    FGNavRecord * _navrecord;
 
     string _name;
     int _num;
 
+    class AudioIdent * _audioIdent;
 };
 
 
diff --git a/src/Instrumentation/kr_87.cxx b/src/Instrumentation/kr_87.cxx
index 9b91babea..0fa58012e 100644
--- a/src/Instrumentation/kr_87.cxx
+++ b/src/Instrumentation/kr_87.cxx
@@ -18,7 +18,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
 
 
 #ifdef HAVE_CONFIG_H
@@ -71,9 +70,6 @@ static double kludgeRange ( double stationElev, double aircraftElev,
 
 // Constructor
 FGKR_87::FGKR_87( SGPropertyNode *node ) :
-    lon_node(fgGetNode("/position/longitude-deg", true)),
-    lat_node(fgGetNode("/position/latitude-deg", true)),
-    alt_node(fgGetNode("/position/altitude-ft", true)),
     bus_power(fgGetNode("/systems/electrical/outputs/adf", true)),
     serviceable(fgGetNode("/instrumentation/adf/serviceable", true)),
     need_update(true),
@@ -249,9 +245,7 @@ void FGKR_87::unbind () {
 
 // Update the various nav values based on position and valid tuned in navs
 void FGKR_87::update( double dt_sec ) {
-    SGGeod acft = SGGeod::fromDegFt(lon_node->getDoubleValue(),
-                                    lat_node->getDoubleValue(),
-                                    alt_node->getDoubleValue());
+    SGGeod acft = globals->get_aircraft_position();
 
     need_update = false;
 
@@ -497,8 +491,7 @@ void FGKR_87::update( double dt_sec ) {
 
 // Update current nav/adf radio stations based on current postition
 void FGKR_87::search() {
-  SGGeod pos = SGGeod::fromDegFt(lon_node->getDoubleValue(), 
-    lat_node->getDoubleValue(), alt_node->getDoubleValue());
+  SGGeod pos = globals->get_aircraft_position();
   
 				// FIXME: the panel should handle this
     static string last_ident = "";
@@ -534,7 +527,7 @@ void FGKR_87::search() {
 		_sgr->remove( "adf-ident" );
 	    }
 	    SGSoundSample *sound;
-        sound = FGMorse::instance()->make_ident( trans_ident, LO_FREQUENCY );
+        sound = FGMorse::instance()->make_ident( trans_ident, FGMorse::LO_FREQUENCY );
 	    sound->set_volume( 0.3 );
 	    _sgr->add( sound, "adf-ident" );
 
diff --git a/src/Instrumentation/kr_87.hxx b/src/Instrumentation/kr_87.hxx
index 14accba9f..83b8f6bcf 100644
--- a/src/Instrumentation/kr_87.hxx
+++ b/src/Instrumentation/kr_87.hxx
@@ -37,9 +37,6 @@ class SGSampleGroup;
 
 class FGKR_87 : public SGSubsystem
 {
-    SGPropertyNode_ptr lon_node;
-    SGPropertyNode_ptr lat_node;
-    SGPropertyNode_ptr alt_node;
     SGPropertyNode_ptr bus_power;
     SGPropertyNode_ptr serviceable;
 
diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx
index 886ad1f37..2103bb364 100644
--- a/src/Instrumentation/navradio.cxx
+++ b/src/Instrumentation/navradio.cxx
@@ -18,8 +18,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// $Id$
-
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
@@ -40,12 +38,10 @@
 #include <simgear/misc/strutils.hxx>
 
 #include <Navaids/navrecord.hxx>
-
+#include <Sound/audioident.hxx>
 #include <Airports/runways.hxx>
 #include <Navaids/navlist.hxx>
 #include <Main/util.hxx>
-#include <Sound/morse.hxx>
-
 
 using std::string;
 
@@ -105,9 +101,6 @@ FGNavRadio::FGNavRadio(SGPropertyNode *node) :
     term_tbl(NULL),
     low_tbl(NULL),
     high_tbl(NULL),
-    lon_node(fgGetNode("/position/longitude-deg", true)),
-    lat_node(fgGetNode("/position/latitude-deg", true)),
-    alt_node(fgGetNode("/position/altitude-ft", true)),
     _operable(false),
     play_count(0),
     last_time(0),
@@ -126,14 +119,13 @@ FGNavRadio::FGNavRadio(SGPropertyNode *node) :
     _gsCart(SGVec3d::zeros()),
     _gsAxis(SGVec3d::zeros()),
     _gsVertical(SGVec3d::zeros()),
-    _dmeInRange(false),
     _toFlag(false),
     _fromFlag(false),
     _cdiDeflection(0.0),
     _cdiCrossTrackErrorM(0.0),
     _gsNeedleDeflection(0.0),
     _gsNeedleDeflectionNorm(0.0),
-    _sgr(NULL)
+    _audioIdent(NULL)
 {
     SGPath path( globals->get_fg_root() );
     SGPath term = path;
@@ -166,16 +158,14 @@ FGNavRadio::~FGNavRadio()
     delete term_tbl;
     delete low_tbl;
     delete high_tbl;
+
+    delete _audioIdent;
 }
 
 
 void
 FGNavRadio::init ()
 {
-    SGSoundMgr *smgr = globals->get_soundmgr();
-    _sgr = smgr->find("avionics", true);
-    _sgr->tie_to_listener();
-
     SGPropertyNode* node = _radio_node.get();
     bus_power_node = 
 	fgGetNode(("/systems/electrical/outputs/" + _name).c_str(), true);
@@ -196,7 +186,6 @@ FGNavRadio::init ()
     cdi_serviceable_node = createServiceableProp(node, "cdi");
     gs_serviceable_node = createServiceableProp(node, "gs");
     tofrom_serviceable_node = createServiceableProp(node, "to-from");
-    dme_serviceable_node = createServiceableProp(node, "dme");
     
     falseCoursesEnabledNode = 
       fgGetNode("/sim/realism/false-radio-courses-enabled");
@@ -266,27 +255,28 @@ FGNavRadio::init ()
     _magvarNode = fgGetNode("/environment/magnetic-variation-deg", true);
     
     std::ostringstream temp;
-    temp << _name << "nav-ident" << _num;
-    nav_fx_name = temp.str();
-    temp << _name << "dme-ident" << _num;
-    dme_fx_name = temp.str();
+    temp << _name << "-ident-" << _num;
+    if( NULL == _audioIdent ) 
+        _audioIdent = new VORAudioIdent( temp.str() );
+    _audioIdent->init();
+
+    // dme-in-range is deprecated,
+    // temporarily create dme-in-range alias for instrumentation/dme[0]/in-range
+    // remove after flightgear 2.6.0
+    node->getNode( "dme-in-range", true )->alias( fgGetNode("/instrumentation/dme[0]/in-range", true ) );
 }
 
 void
 FGNavRadio::bind ()
 {
-  tie("dme-in-range", SGRawValuePointer<bool>(&_dmeInRange));
-  tie("operable", SGRawValueMethods<FGNavRadio, bool>(*this, &FGNavRadio::isOperable, NULL));
+    _radio_node->tie( "operable", SGRawValueMethods<FGNavRadio,bool>( *this, &FGNavRadio::isOperable ) );
 }
 
 
 void
 FGNavRadio::unbind ()
 {
-  for (unsigned int t=0; t<_tiedNodes.size(); ++t) {
-    _tiedNodes[t]->untie();
-  }
-  _tiedNodes.clear();
+    _radio_node->untie("operable");
 }
 
 
@@ -386,7 +376,7 @@ FGNavRadio::update(double dt)
     clearOutputs();
   }
   
-  updateAudio();
+  updateAudio( dt );
 }
 
 void FGNavRadio::clearOutputs()
@@ -412,17 +402,13 @@ void FGNavRadio::clearOutputs()
   is_valid_node->setBoolValue(false);
   nav_id_node->setStringValue("");
   
-  _dmeInRange = false;
   _operable = false;
   _navaid = NULL;
 }
 
 void FGNavRadio::updateReceiver(double dt)
 {
-  SGGeod pos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
-                               lat_node->getDoubleValue(),
-                               alt_node->getDoubleValue());
-  SGVec3d aircraft = SGVec3d::fromGeod(pos);
+  SGVec3d aircraft = SGVec3d::fromGeod(globals->get_aircraft_position());
   double loc_dist = 0;
 
   // Do a nav station search only once a second to reduce
@@ -438,11 +424,10 @@ void FGNavRadio::updateReceiver(double dt)
       loc_dist = dist(aircraft, _navaid->cart());
       loc_dist_node->setDoubleValue( loc_dist );
   }
-  updateDME(aircraft);
 
   if (nav_slaved_to_gps_node->getBoolValue()) {
     // when slaved to GPS: only allow stuff above: tune NAV station
-    // upate DME. All other data driven by GPS only.
+    // All other data driven by GPS only.
     updateGPSSlaved();
     return;
   }
@@ -468,7 +453,7 @@ void FGNavRadio::updateReceiver(double dt)
 	// compute forward and reverse wgs84 headings to localizer
   //////////////////////////////////////////////////////////
   double hdg;
-  SGGeodesy::inverse(pos, _navaid->geod(), hdg, az2, s);
+  SGGeodesy::inverse(globals->get_aircraft_position(), _navaid->geod(), hdg, az2, s);
   heading_node->setDoubleValue(hdg);
   double radial = az2 - twist;
   double recip = radial + 180.0;
@@ -497,11 +482,11 @@ void FGNavRadio::updateReceiver(double dt)
 	    double offset = radial - target_radial;
       SG_NORMALIZE_RANGE(offset, -180.0, 180.0);
 	    effective_range
-                = adjustILSRange( nav_elev, pos.getElevationM(), offset,
+                = adjustILSRange( nav_elev, globals->get_aircraft_position().getElevationM(), offset,
                                   loc_dist * SG_METER_TO_NM );
 	} else {
 	    effective_range
-                = adjustNavRange( nav_elev, pos.getElevationM(), _navaid->get_range() );
+                = adjustNavRange( nav_elev, globals->get_aircraft_position().getElevationM(), _navaid->get_range() );
 	}
   
   double effective_range_m = effective_range * SG_NM_TO_METER;
@@ -679,17 +664,6 @@ void FGNavRadio::updateGlideSlope(double dt, const SGVec3d& aircraft, double sig
       ->setDoubleValue( gs_rate_of_climb_node->getDoubleValue() * 60 );
 }
 
-void FGNavRadio::updateDME(const SGVec3d& aircraft)
-{
-  if (!_dme || !dme_serviceable_node->getBoolValue()) {
-    _dmeInRange = false;
-    return;
-  }
-  
-  double dme_distance = dist(aircraft, _dme->cart()); 
-  _dmeInRange =  (dme_distance < _dme->get_range() * SG_NM_TO_METER);
-}
-
 void FGNavRadio::valueChanged (SGPropertyNode* prop)
 {
   if (prop == gps_course_node) {
@@ -849,9 +823,10 @@ void FGNavRadio::updateCDI(double dt)
   last_xtrack_error = _cdiCrossTrackErrorM;
 }
 
-void FGNavRadio::updateAudio()
+void FGNavRadio::updateAudio( double dt )
 {
   if (!_navaid || !inrange_node->getBoolValue() || !nav_serviceable_node->getBoolValue()) {
+    _audioIdent->setIdent("", 0.0 );
     return;
   }
   
@@ -861,57 +836,13 @@ void FGNavRadio::updateAudio()
       || !(bus_power_node->getDoubleValue() > 1.0)
       || !ident_btn_node->getBoolValue()
       || !audio_btn_node->getBoolValue() ) {
-    _sgr->stop( nav_fx_name );
-    _sgr->stop( dme_fx_name );
+    _audioIdent->setIdent("", 0.0 );
     return;
   }
 
-  SGSoundSample *sound = _sgr->find( nav_fx_name );
-  double vol = vol_btn_node->getFloatValue();
-  SG_CLAMP_RANGE(vol, 0.0, 1.0);
-  
-  if ( sound != NULL ) {
-    sound->set_volume( vol );
-  } else {
-    SG_LOG( SG_COCKPIT, SG_ALERT, "Can't find nav-vor-ident sound" );
-  }
-  
-  sound = _sgr->find( dme_fx_name );
-  if ( sound != NULL ) {
-    sound->set_volume( vol );
-  } else {
-    SG_LOG( SG_COCKPIT, SG_ALERT, "Can't find nav-dme-ident sound" );
-  }
-  
-  const int NUM_IDENT_SLOTS = 5;
-  const time_t SLOT_LENGTH = 5; // seconds
+  _audioIdent->setIdent( _navaid->get_trans_ident(), vol_btn_node->getFloatValue() );
 
-  // There are N slots numbered 0 through (NUM_IDENT_SLOTS-1) inclusive.
-  // Each slot is 5 seconds long.
-  // Slots 0 is for DME
-  // the rest are for azimuth.
-  time_t now = globals->get_time_params()->get_cur_time();
-  if ((now >= last_time) && (now < last_time + SLOT_LENGTH)) {
-    return; // wait longer
-  }
-  
-  last_time = now;
-  play_count++;
-  play_count %= NUM_IDENT_SLOTS;
-    
-  // Previous ident is out of time;  if still playing, cut it off:
-  _sgr->stop( nav_fx_name );
-  _sgr->stop( dme_fx_name );
-  if (play_count == 0) { // the DME slot
-    if (_dmeInRange && dme_serviceable_node->getBoolValue()) {
-      // play DME ident
-      if (vol > 0.05) _sgr->play_once( dme_fx_name );
-    }
-  } else { // NAV slot
-    if (inrange_node->getBoolValue() && nav_serviceable_node->getBoolValue()) {
-      if (vol > 0.05) _sgr->play_once(nav_fx_name);
-    }
-  }
+  _audioIdent->update( dt );
 }
 
 FGNavRecord* FGNavRadio::findPrimaryNavaid(const SGGeod& aPos, double aFreqMHz)
@@ -928,11 +859,9 @@ FGNavRecord* FGNavRadio::findPrimaryNavaid(const SGGeod& aPos, double aFreqMHz)
 void FGNavRadio::search() 
 {
   _time_before_search_sec = 1.0;
-  SGGeod pos = SGGeod::fromDegFt(lon_node->getDoubleValue(),
-    lat_node->getDoubleValue(), alt_node->getDoubleValue());
   double freq = freq_node->getDoubleValue();
   
-  FGNavRecord* nav = findPrimaryNavaid(pos, freq);
+  FGNavRecord* nav = findPrimaryNavaid(globals->get_aircraft_position(), freq);
   if (nav == _navaid) {
     return; // found the same as last search, we're done
   }
@@ -940,16 +869,10 @@ void FGNavRadio::search()
   _navaid = nav;
   string identBuffer(4, ' ');
   if (nav) {
-    // use ILS signals as DME, otherwise search by frequency
-    if (nav->type()==FGPositioned::ILS)
-        _dme = nav;
-    else
-        _dme = globals->get_dmelist()->findByFreq(freq, pos);
-    
     nav_id_node->setStringValue(nav->get_ident());
     identBuffer =  simgear::strutils::rpad( nav->ident(), 4, ' ' );
     
-    effective_range = adjustNavRange(nav->get_elev_ft(), pos.getElevationM(), nav->get_range());
+    effective_range = adjustNavRange(nav->get_elev_ft(), globals->get_aircraft_position().getElevationM(), nav->get_range());
     loc_node->setBoolValue(nav->type() != FGPositioned::VOR);
     twist = nav->get_multiuse();
 
@@ -958,7 +881,7 @@ void FGNavRadio::search()
       _gs = NULL;
       has_gs_node->setBoolValue(false);
     } else { // ILS or LOC
-      _gs = globals->get_gslist()->findByFreq(freq, pos);
+      _gs = globals->get_gslist()->findByFreq(freq, globals->get_aircraft_position());
       has_gs_node->setBoolValue(_gs != NULL);
       _localizerWidth = nav->localizerWidth();
       twist = 0.0;
@@ -986,16 +909,12 @@ void FGNavRadio::search()
       } // of have glideslope
     } // of found LOC or ILS
     
-    audioNavidChanged();
   } else { // found nothing
     _gs = NULL;
-    _dme = NULL;
     nav_id_node->setStringValue("");
     loc_node->setBoolValue(false);
     has_gs_node->setBoolValue(false);
-    
-    _sgr->remove( nav_fx_name );
-    _sgr->remove( dme_fx_name );
+    _audioIdent->setIdent("", 0.0 );
   }
 
   is_valid_node->setBoolValue(nav != NULL);
@@ -1004,33 +923,3 @@ void FGNavRadio::search()
   id_c3_node->setIntValue( (int)identBuffer[2] );
   id_c4_node->setIntValue( (int)identBuffer[3] );
 }
-
-void FGNavRadio::audioNavidChanged()
-{
-  if (_sgr->exists(nav_fx_name)) {
-		_sgr->remove(nav_fx_name);
-  }
-  
-  try {
-    string trans_ident(_navaid->get_trans_ident());
-    SGSoundSample* sound = FGMorse::instance()->make_ident(trans_ident, LO_FREQUENCY);
-    sound->set_volume( 0.3 );
-    if (!_sgr->add( sound, nav_fx_name )) {
-      SG_LOG(SG_COCKPIT, SG_WARN, "Failed to add v1-vor-ident sound");
-    }
-
-	  if ( _sgr->exists( dme_fx_name ) ) {
-      _sgr->remove( dme_fx_name );
-    }
-     
-    sound = FGMorse::instance()->make_ident( trans_ident, HI_FREQUENCY );
-    sound->set_volume( 0.3 );
-    _sgr->add( sound, dme_fx_name );
-
-	  int offset = (int)(sg_random() * 30.0);
-	  play_count = offset / 4;
-    last_time = globals->get_time_params()->get_cur_time() - offset;
-  } catch (sg_io_exception& e) {
-    SG_LOG(SG_GENERAL, SG_ALERT, e.getFormattedMessage());
-  }
-}
diff --git a/src/Instrumentation/navradio.hxx b/src/Instrumentation/navradio.hxx
index 4b2e16918..518772845 100644
--- a/src/Instrumentation/navradio.hxx
+++ b/src/Instrumentation/navradio.hxx
@@ -45,9 +45,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     SGInterpTable *high_tbl;
 
     SGPropertyNode_ptr _radio_node;
-    SGPropertyNode_ptr lon_node;
-    SGPropertyNode_ptr lat_node;
-    SGPropertyNode_ptr alt_node;
     SGPropertyNode_ptr bus_power_node;
 
     // property inputs
@@ -65,7 +62,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     SGPropertyNode_ptr cdi_serviceable_node;
     SGPropertyNode_ptr gs_serviceable_node;
     SGPropertyNode_ptr tofrom_serviceable_node;
-    SGPropertyNode_ptr dme_serviceable_node;
     
     // property outputs
     SGPropertyNode_ptr fmt_freq_node;     // formated frequency
@@ -131,9 +127,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     FGNavRecordPtr _navaid;
     FGNavRecordPtr _gs;
     
-    string nav_fx_name;
-    string dme_fx_name;
-
     double target_radial;
     double effective_range;
     double target_gs;
@@ -152,9 +145,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
 
     SGVec3d _gsCart, _gsAxis, _gsVertical, _gsBaseline;
 
-    FGNavRecordPtr _dme;
-    bool _dmeInRange;
-    
     // CDI properties
     bool _toFlag, _fromFlag;
     double _cdiDeflection;
@@ -162,9 +152,8 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     double _gsNeedleDeflection;
     double _gsNeedleDeflectionNorm;
     double _gsDirect;
-    
-    SGSharedPtr<SGSampleGroup> _sgr;
-    std::vector<SGPropertyNode_ptr> _tiedNodes;
+
+    class AudioIdent * _audioIdent;
     
     bool updateWithPower(double aDt);
 
@@ -176,11 +165,9 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     double adjustILSRange( double stationElev, double aircraftElev,
 			   double offsetDegrees, double distance );
 
-    void updateAudio();
-    void audioNavidChanged();
+    void updateAudio( double dt );
 
     void updateReceiver(double dt);
-    void updateDME(const SGVec3d& aircraft);
     void updateGlideSlope(double dt, const SGVec3d& aircraft, double signal_quality_norm);
     void updateGPSSlaved();
     void updateCDI(double dt);
@@ -193,17 +180,6 @@ class FGNavRadio : public SGSubsystem, public SGPropertyChangeListener
     bool isOperable() const
       { return _operable; }
       
-    /**
-     * Tied-properties helper, record nodes which are tied for easy un-tie-ing
-     */
-    template <typename T>
-    void tie(const char* aRelPath, const SGRawValue<T>& aRawValue)
-    {
-      SGPropertyNode_ptr nd = _radio_node->getNode(aRelPath, true);
-      _tiedNodes.push_back(nd);
-      nd->tie(aRawValue);
-    }
-    
   // implement SGPropertyChangeListener
     virtual void valueChanged (SGPropertyNode * prop);
 public:
diff --git a/src/Sound/CMakeLists.txt b/src/Sound/CMakeLists.txt
index 28cc5bf8c..470e684c1 100644
--- a/src/Sound/CMakeLists.txt
+++ b/src/Sound/CMakeLists.txt
@@ -1,6 +1,7 @@
 include(FlightGearComponent)
 
 set(SOURCES
+	audioident.cxx
 	soundgenerator.cxx
 	beacon.cxx
 	fg_fx.cxx
@@ -11,6 +12,7 @@ set(SOURCES
 	)
 
 set(HEADERS
+	audioident.hxx
 	soundgenerator.hxx
 	beacon.hxx
 	fg_fx.hxx
diff --git a/src/Sound/Makefile.am b/src/Sound/Makefile.am
index 893b776d2..871001743 100644
--- a/src/Sound/Makefile.am
+++ b/src/Sound/Makefile.am
@@ -1,6 +1,7 @@
 noinst_LIBRARIES = libSound.a
 
 libSound_a_SOURCES = \
+	audioident.cxx audioident.hxx \
 	soundgenerator.cxx soundgenerator.hxx \
 	beacon.cxx beacon.hxx \
 	fg_fx.cxx fg_fx.hxx \
diff --git a/src/Sound/audioident.cxx b/src/Sound/audioident.cxx
new file mode 100644
index 000000000..74674522c
--- /dev/null
+++ b/src/Sound/audioident.cxx
@@ -0,0 +1,141 @@
+// audioident.cxx -- audible station identifiers
+//
+// Written by Torsten Dreyer, September 2011
+//
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#include "audioident.hxx"
+#include <simgear/sg_inlines.h>
+
+#include <Main/globals.hxx>
+#include <Sound/Morse.hxx>
+
+AudioIdent::AudioIdent( const std::string & fx_name, const double interval_secs, const int frequency_hz ) :
+  _fx_name(fx_name),
+  _frequency(frequency_hz),
+  _timer(0.0),
+  _interval(interval_secs),
+  _running(false)
+{
+}
+
+void AudioIdent::init()
+{
+    _timer = 0.0;
+    _ident = "";
+    _running = false;
+    _sgr = globals->get_soundmgr()->find("avionics", true);
+    _sgr->tie_to_listener();
+}
+
+void AudioIdent::stop()
+{
+    if( _sgr->exists( _fx_name ) )
+        _sgr->stop( _fx_name );
+    _running = false;
+}
+
+void AudioIdent::start()
+{
+    _timer = _interval;
+    _sgr->play_once(_fx_name);
+    _running = true;
+}
+
+void AudioIdent::setVolumeNorm( double volumeNorm )
+{
+    SG_CLAMP_RANGE(volumeNorm, 0.0, 1.0);
+
+    SGSoundSample *sound = _sgr->find( _fx_name );
+
+    if ( sound != NULL ) {
+        sound->set_volume( volumeNorm );
+    }
+}
+
+void AudioIdent::setIdent( const std::string & ident, double volumeNorm )
+{
+    if( _ident == ident ) {
+        if( false == _ident.empty() )
+            setVolumeNorm( volumeNorm );
+        return;
+    }
+
+    try {
+        stop();
+
+        if ( _sgr->exists( _fx_name ) )
+            _sgr->remove( _fx_name );
+
+        if( false == ident.empty() ) {
+
+            SGSoundSample* sound = FGMorse::instance()->make_ident(ident, _frequency );
+            sound->set_volume( volumeNorm );
+            if (!_sgr->add( sound, _fx_name )) {
+                SG_LOG(SG_SOUND, SG_WARN, "Failed to add sound '" << _fx_name << "' for ident '" << ident << "'" );
+                return;
+            }
+
+            start();
+        }
+        _ident = ident;
+
+    } catch (sg_io_exception& e) {
+        SG_LOG(SG_SOUND, SG_ALERT, e.getFormattedMessage());
+    }
+
+}
+
+void AudioIdent::update( double dt )
+{
+    // single-shot
+    if( false == _running || _interval < SGLimitsd::min() ) 
+        return;
+
+    _timer -= dt;
+
+    if( _timer < SGLimitsd::min() ) {
+        _timer = _interval;
+        stop();
+        start();
+    }
+}
+
+// FIXME: shall transmit at least 6 wpm (ICAO Annex 10 - 3.5.3.6.3)
+DMEAudioIdent::DMEAudioIdent( const std::string & fx_name )
+: AudioIdent( fx_name, 40, FGMorse::HI_FREQUENCY )
+{
+}
+
+
+//FIXME: for co-located VOR/DME or ILS/DME, assign four time-slots
+// 3xVOR/ILS ident, 1xDME ident
+
+// FIXME: shall transmit at approx. 7 wpm (ICAO Annex 10 - 3.3.6.5.1)
+VORAudioIdent::VORAudioIdent( const std::string & fx_name )
+: AudioIdent( fx_name, 10, FGMorse::LO_FREQUENCY )
+{
+}
+
+//FIXME: LOCAudioIdent at approx 7wpm (ICAO Annex 10 - 3.1.3.9.4)
+// not less than six times per minute at approx equal intervals
+// frequency 1020+/-50Hz (3.1.3.9.2)
+
+// FIXME: NDBAudioIdent at approx 7 wpm (ICAO ANNEX 10 - 3.4.5.1)
+// at least once every 10s (3.4.5.2.1)
+// frequency 1020+/-50Hz or 400+/-25Hz (3.4.5.4)
\ No newline at end of file
diff --git a/src/Sound/audioident.hxx b/src/Sound/audioident.hxx
new file mode 100644
index 000000000..723ddd70d
--- /dev/null
+++ b/src/Sound/audioident.hxx
@@ -0,0 +1,65 @@
+// audioident.hxx -- audible station identifiers
+//
+// Written by Torsten Dreyer, September 2011
+//
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+
+#ifndef _FGAUDIOIDENT_HXX
+#define _FGAUDIOIDENT_HXX
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string>
+#include <simgear/sound/soundmgr_openal.hxx>
+
+class AudioIdent {
+public:
+    AudioIdent( const std::string & fx_name, const double interval_secs, const int frequency );
+    void init();
+    void setVolumeNorm( double volumeNorm );
+    void setIdent( const std::string & ident, double volumeNorm );
+
+    void update( double dt );
+
+private:
+    void stop();
+    void start();
+
+    SGSharedPtr<SGSampleGroup> _sgr;
+    std::string _fx_name;
+    const int _frequency;
+    std::string _ident;
+    double _timer;
+    double _interval;
+    bool _running;
+};
+
+class DMEAudioIdent : public AudioIdent {
+public:
+    DMEAudioIdent( const std::string & fx_name );
+};
+
+class VORAudioIdent : public AudioIdent {
+public:
+    VORAudioIdent( const std::string & fx_name );
+};
+
+#endif // _FGAUDIOIDENT_HXX
diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx
index 9ff603322..379c15748 100644
--- a/src/Sound/morse.cxx
+++ b/src/Sound/morse.cxx
@@ -26,6 +26,12 @@
 
 #include <cstring>
 
+static const char DI = '1';
+static const char DIT = '1';
+static const char DA = '2';
+static const char DAH = '2';
+static const char END = '0';
+
 static const char alphabet[26][4] = {
     { DI, DAH, END, END },	/* A */ 
     { DA, DI, DI, DIT },	/* B */ 
diff --git a/src/Sound/morse.hxx b/src/Sound/morse.hxx
index 3d8b9dfbb..c79b4782e 100644
--- a/src/Sound/morse.hxx
+++ b/src/Sound/morse.hxx
@@ -75,23 +75,6 @@
 // Hz for the VOR ident.
 
 
-static const char DI = '1';
-static const char DIT = '1';
-static const char DA = '2';
-static const char DAH = '2';
-static const char END = '0';
-
-static const int BYTES_PER_SECOND = 22050;
-// static const int BEAT_LENGTH = 240; // milleseconds (5 wpm)
-static const int BEAT_LENGTH = 92;  // milleseconds (13 wpm)
-static const int TRANSITION_BYTES = (int)(0.005 * BYTES_PER_SECOND);
-static const int COUNT_SIZE = BYTES_PER_SECOND * BEAT_LENGTH / 1000;
-static const int DIT_SIZE = 2 * COUNT_SIZE;   // 2 counts
-static const int DAH_SIZE = 4 * COUNT_SIZE;   // 4 counts
-static const int SPACE_SIZE = 3 * COUNT_SIZE; // 3 counts
-static const int LO_FREQUENCY = 1020;	 // AIM 1-1-7 (f) specified in Hz
-static const int HI_FREQUENCY = 1350;	 // AIM 1-1-7 (f) specified in Hz
-
 // manages everything we need to know for an individual sound sample
 class FGMorse : public FGSoundGenerator {
 
@@ -113,6 +96,17 @@ private:
     bool init();
 
 public:
+    static const int BYTES_PER_SECOND = 22050;
+    // static const int BEAT_LENGTH = 240; // milleseconds (5 wpm)
+    static const int BEAT_LENGTH = 92;  // milleseconds (13 wpm)
+    static const int TRANSITION_BYTES = (int)(0.005 * BYTES_PER_SECOND);
+    static const int COUNT_SIZE = BYTES_PER_SECOND * BEAT_LENGTH / 1000;
+    static const int DIT_SIZE = 2 * COUNT_SIZE;   // 2 counts
+    static const int DAH_SIZE = 4 * COUNT_SIZE;   // 4 counts
+    static const int SPACE_SIZE = 3 * COUNT_SIZE; // 3 counts
+    static const int LO_FREQUENCY = 1020;	 // AIM 1-1-7 (f) specified in Hz
+    static const int HI_FREQUENCY = 1350;	 // AIM 1-1-7 (f) specified in Hz
+
 
     FGMorse();
     ~FGMorse();

From 0fa556d36a70671af37405da285e32a79faae0b5 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Thu, 15 Sep 2011 22:39:47 +0200
Subject: [PATCH 34/85] fix upper/lowercase typo

Just don't develop with windows. Never.
---
 src/Sound/audioident.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Sound/audioident.cxx b/src/Sound/audioident.cxx
index 74674522c..a09b68d80 100644
--- a/src/Sound/audioident.cxx
+++ b/src/Sound/audioident.cxx
@@ -23,7 +23,7 @@
 #include <simgear/sg_inlines.h>
 
 #include <Main/globals.hxx>
-#include <Sound/Morse.hxx>
+#include <Sound/morse.hxx>
 
 AudioIdent::AudioIdent( const std::string & fx_name, const double interval_secs, const int frequency_hz ) :
   _fx_name(fx_name),

From 67c604a722345ea459ad0f9f46544e2b1c208959 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durk@linux-gj5p.site>
Date: Fri, 16 Sep 2011 20:04:13 +0200
Subject: [PATCH 35/85] Some tweaks to the AI traffic scheduling algorithm.
 Remove the requirement for a home port, but keep planning until we are back
 at the original port of departure.

---
 src/Traffic/Schedule.cxx | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx
index 288d5eb10..2e2ef33d9 100644
--- a/src/Traffic/Schedule.cxx
+++ b/src/Traffic/Schedule.cxx
@@ -321,7 +321,7 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots
   mp_ai.append(modelPath);
 
   if (!mp.exists() && !mp_ai.exists()) {
-    SG_LOG(SG_INPUT, SG_WARN, "TrafficManager: Could not load model " << mp.str());
+    SG_LOG(SG_GENERAL, SG_WARN, "TrafficManager: Could not load model " << mp.str());
     return true;
   }
 
@@ -371,9 +371,11 @@ void FGAISchedule::setHeading()
 
 void FGAISchedule::scheduleFlights()
 {
+  string startingPort;
   if (!flights.empty()) {
     return;
   }
+  // change back to bulk
   SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " <<  registration << " " << homePort);
   FGScheduledFlight *flight = NULL;
   do {
@@ -381,7 +383,11 @@ void FGAISchedule::scheduleFlights()
     if (!flight) {
       break;
     }
-    
+    if (startingPort.empty()) {
+        startingPort = flight->getDepartureAirport()->getId();
+    }
+
+   
     currentDestination = flight->getArrivalAirport()->getId();
     if (!initialized) {
         string departurePort = flight->getDepartureAirport()->getId();
@@ -409,7 +415,7 @@ void FGAISchedule::scheduleFlights()
                              << "  "        << arrT << ":");
   
     flights.push_back(flight);
-  } while (1); //while (currentDestination != homePort);
+  } while (currentDestination != startingPort);
   SG_LOG(SG_GENERAL, SG_BULK, " Done ");
 }
 
@@ -492,7 +498,7 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
           }
           if (flights.size()) {
             time_t arrival = flights.back()->getArrivalTime();
-            if ((*i)->getDepartureTime() < arrival)
+            if ((*i)->getDepartureTime() < (arrival+(20*60)))
                 continue;
           }
 

From db816deb90961b82e085f3d7afc64b4977728f49 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durk@linux-gj5p.site>
Date: Sat, 17 Sep 2011 16:51:00 +0200
Subject: [PATCH 36/85] Added a new startup option. By giving the command line
 option --parkpos=AVAILABLE you can -in principle- let FlightGear decide what
 the most optimal parking location is. This option does require a few
 properties to be set that are also needed for future ATC use. Hence, they are
 listed under /sim/ATC, but could move to a different location if desired.
 /sim/ATC/radius should be a nummeric estimate of the size of your aircraft. A
 small aircraft fits into a large parking, but a large aircraft does not fit
 into a small parking space. Because the AI part of radius is also used for
 slightly different purposes (prioritizing gate assignmments, the given valuem
 may deviate slightly from the real aircraft size. See
 http:/wiki.flightgear.org/Aircraft.radii for an overview of currently used
 values for the redius property. /sim/ATC/flight-type can be any one of "ga",
 "cargo", "gate", "mil-fighter", "mil-cargo", or "vtol". See
 http://wiki.flightgear.org/Interactive_traffic#A_technical_perspective for
 more information. optionally, the property /sim/ATC/airline can be set set to
 a three letter icao airline code. By way of illustration, I will commit a
 number of startup preset files setting these properties shortly.

Also did some more finetuning to the traffic mananger routing algorithm can be any one of "ga", "cargo", "gate", "mil-fighter", "mil-cargo", or "vtol". See http://wiki.flightgear.org/Interactive_traffic#A_technical_perspective for more information.
optionally, the property /sim/ATC/airline can be set set to a three letter icao airline code. By way of illustration, I will commit a number of startup preset files setting these properties shortly.

Also did some more finetuning to the traffic mananger routing algorithm.
---
 src/ATC/atc_mgr.cxx      |  2 +-
 src/Main/fg_init.cxx     | 36 ++++++++++++++++++++++++++++--------
 src/Traffic/Schedule.cxx | 28 +++++++++++++++++++++-------
 src/Traffic/Schedule.hxx |  4 ++--
 4 files changed, 52 insertions(+), 18 deletions(-)

diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index 73130fe63..ef17774c2 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -111,7 +111,7 @@ void FGATCManager::init() {
             if (park_index < 0) {
                   SG_LOG( SG_GENERAL, SG_ALERT,
                         "Failed to find parking position " << parking <<
-                        " at airport " << airport );
+                        " at airport " << airport << "at " << SG_ORIGIN);
             }
         if (parking.empty() || (park_index < 0)) {
             controller = apt->getDynamics()->getTowerController();
diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index 25fe5a6f7..7f9bc87c2 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -901,18 +901,38 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
     FGAirportDynamics* dcs = apt->getDynamics();
     if (!dcs) {
         SG_LOG( SG_GENERAL, SG_ALERT,
-                "Failed to find parking position " << parkpos <<
-                " at airport " << id );
+                "Airport " << id << "does not appear to have parking information available");
         return false;
     }
     
     int park_index = dcs->getNrOfParkings() - 1;
-    while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--;
-    if (park_index < 0) {
-        SG_LOG( SG_GENERAL, SG_ALERT,
-                "Failed to find parking position " << parkpos <<
-                " at airport " << id );
-        return false;
+    bool succes;
+    double radius = fgGetDouble("/sim/atc/acradius");
+    //cerr << "Using radius " << radius << endl;
+    //cerr << "Checking parkpos comparison " << (bool) (parkpos == string("AVAILABLE")) << endl;
+    if ((parkpos == string("AVAILABLE")) && (radius > 0)) {
+        double lat, lon, heading;
+        string fltType = fgGetString("/sim/atc/flight-type");
+        string airline = fgGetString("/sim/atc/airline" );
+        string acType; // Currently not used by findAvailable parking, so safe to leave empty. 
+        succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, airline);
+        if (succes) {
+            fgGetString("/sim/presets/parkpos");
+            fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName());
+        } else {
+            SG_LOG( SG_GENERAL, SG_ALERT,
+                    "Failed to find a suitable parking at airport " << id );
+            return false;
+        }
+    } else {
+        //cerr << "We shouldn't get here when AVAILABLE" << endl;
+        while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--;
+        if (park_index < 0) {
+            SG_LOG( SG_GENERAL, SG_ALERT,
+                    "Failed to find parking position " << parkpos <<
+                    " at airport " << id );
+            return false;
+        }
     }
     FGParking* parking = dcs->getParking(park_index);
     parking->setAvailable(false);
diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx
index 2e2ef33d9..a4a18ca17 100644
--- a/src/Traffic/Schedule.cxx
+++ b/src/Traffic/Schedule.cxx
@@ -201,7 +201,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
   if (!valid) {
     return false;
   }
-  scheduleFlights();
+  scheduleFlights(now);
   if (flights.empty()) { // No flights available for this aircraft
       valid = false;
       return false;
@@ -369,17 +369,24 @@ void FGAISchedule::setHeading()
     courseToDest = SGGeodesy::courseDeg((*flights.begin())->getDepartureAirport()->geod(), (*flights.begin())->getArrivalAirport()->geod());
 }
 
-void FGAISchedule::scheduleFlights()
+void FGAISchedule::scheduleFlights(time_t now)
 {
-  string startingPort;
   if (!flights.empty()) {
     return;
   }
-  // change back to bulk
+  string startingPort;
+  string userPort = fgGetString("/sim/presets/airport-id");
   SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " <<  registration << " " << homePort);
   FGScheduledFlight *flight = NULL;
   do {
-    flight = findAvailableFlight(currentDestination, flightIdentifier);
+    if (currentDestination.empty()) {
+        flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400));
+        if (!flight)
+            flight = findAvailableFlight(currentDestination, flightIdentifier);
+    } else {
+        flight = findAvailableFlight(currentDestination, flightIdentifier);
+    }
+    
     if (!flight) {
       break;
     }
@@ -389,11 +396,12 @@ void FGAISchedule::scheduleFlights()
 
    
     currentDestination = flight->getArrivalAirport()->getId();
+    //cerr << "Current destination " <<  currentDestination << endl;
     if (!initialized) {
         string departurePort = flight->getDepartureAirport()->getId();
        //cerr << "Scheduled " << registration <<  " " << score << " for Flight " 
        //     << flight-> getCallSign() << " from " << departurePort << " to " << currentDestination << endl;
-        if (fgGetString("/sim/presets/airport-id") == departurePort) {
+        if (userPort == departurePort) {
             hits++;
         }
         //runCount++;
@@ -452,7 +460,8 @@ bool FGAISchedule::next()
 }
 
 FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDestination,
-                                                      const string &req)
+                                                      const string &req,
+                                                     time_t min, time_t max)
 {
     time_t now = time(NULL) + fgGetLong("/sim/time/warp");
 
@@ -501,6 +510,11 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
             if ((*i)->getDepartureTime() < (arrival+(20*60)))
                 continue;
           }
+          if (min != 0) {
+              time_t dep = (*i)->getDepartureTime();
+              if ((dep < min) || (dep > max))
+                  continue;
+          }
 
           // So, if we actually get here, we have a winner
           //cerr << "found flight: " << req << " : " << currentDestination << " : " <<       
diff --git a/src/Traffic/Schedule.hxx b/src/Traffic/Schedule.hxx
index 7c7816120..27385ed0d 100644
--- a/src/Traffic/Schedule.hxx
+++ b/src/Traffic/Schedule.hxx
@@ -62,7 +62,7 @@ class FGAISchedule
   bool initialized;
   bool valid;
 
-  void scheduleFlights();
+  void scheduleFlights(time_t now);
   
   /**
    * Transition this schedule from distant mode to AI mode;
@@ -122,7 +122,7 @@ class FGAISchedule
   void         setHeading (); 
   void         assign         (FGScheduledFlight *ref) { flights.push_back(ref); };
   void         setFlightType  (string val            ) { flightType = val; };
-  FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req);
+  FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req, time_t min=0, time_t max=0);
   // used to sort in decending order of score: I've probably found a better way to
   // decending order sorting, but still need to test that.
   bool operator< (const FGAISchedule &other) const;

From f2f78e364666fcd11221a7f271de584708c025b7 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durk@linux-gj5p.site>
Date: Sat, 17 Sep 2011 17:08:14 +0200
Subject: [PATCH 37/85] ignore kdevelop developer projects.

---
 .gitignore | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index ac9d148d5..30b70a920 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,4 +22,5 @@ CPackConfig.cmake
 CPackSourceConfig.cmake
 cmake_uninstall.cmake
 CTestTestfile.cmake
-
+.kdev4
+*.kdev4

From e1d5a52a3a535007d4249aeba84fc645158997a7 Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Sun, 18 Sep 2011 11:06:54 +0200
Subject: [PATCH 38/85] resync JSBSim

---
 src/FDM/JSBSim/FGFDMExec.cpp                  |  6 ++--
 src/FDM/JSBSim/JSBSim.cxx                     | 30 +++++++++----------
 src/FDM/JSBSim/JSBSim.hxx                     |  1 -
 src/FDM/JSBSim/models/FGAtmosphere.cpp        |  5 +++-
 src/FDM/JSBSim/models/FGLGear.cpp             |  6 ++--
 src/FDM/JSBSim/models/FGOutput.cpp            |  5 +---
 src/FDM/JSBSim/models/FGPropagate.cpp         | 10 +++----
 src/FDM/JSBSim/models/FGPropulsion.cpp        |  3 +-
 .../atmosphere/FGStandardAtmosphere.cpp       |  6 ++--
 src/FDM/JSBSim/models/atmosphere/FGWinds.cpp  |  8 +++--
 .../models/flight_control/FGFCSComponent.cpp  |  4 +--
 src/FDM/JSBSim/models/propulsion/FGEngine.cpp |  4 +--
 src/FDM/JSBSim/models/propulsion/FGPiston.cpp |  4 +--
 .../JSBSim/models/propulsion/FGPropeller.cpp  |  4 +--
 src/FDM/JSBSim/models/propulsion/FGRotor.cpp  | 23 +++++++++-----
 src/FDM/JSBSim/models/propulsion/FGRotor.h    | 12 ++++++--
 16 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp
index 624f10354..8d29a688f 100644
--- a/src/FDM/JSBSim/FGFDMExec.cpp
+++ b/src/FDM/JSBSim/FGFDMExec.cpp
@@ -70,7 +70,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.113 2011/09/07 02:37:04 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.114 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_FDMEXEC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -441,7 +441,7 @@ void FGFDMExec::LoadInputs(unsigned int idx)
     GroundReactions->in.TotalDeltaT     = dT * GroundReactions->GetRate();
     GroundReactions->in.WOW             = GroundReactions->GetWOW();
     GroundReactions->in.Location        = Propagate->GetLocation();
-    for (unsigned int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
+    for (int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
       GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation());
     }
     break;
@@ -530,7 +530,7 @@ void FGFDMExec::LoadModelConstants(void)
   Aerodynamics->in.Wingspan      = Aircraft->GetWingSpan();
   Auxiliary->in.Wingspan         = Aircraft->GetWingSpan();
   Auxiliary->in.Wingchord        = Aircraft->Getcbar();
-  for (unsigned int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
+  for (int i=0; i<GroundReactions->GetNumGearUnits(); i++) {
     GroundReactions->in.vWhlBodyVec[i] = MassBalance->StructuralToBody(GroundReactions->GetGearUnit(i)->GetLocation());
   }
 
diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index eed3c6873..77b006f09 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -311,7 +311,6 @@ FGJSBsim::FGJSBsim( double dt )
     temperature = fgGetNode("/environment/temperature-degc",true);
     pressure = fgGetNode("/environment/pressure-inhg",true);
     pressureSL = fgGetNode("/environment/pressure-sea-level-inhg",true);
-    density = fgGetNode("/environment/density-slugft3",true);
     ground_wind = fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt",true);
     turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
     turbulence_rate = fgGetNode("/environment/turbulence/rate-hz",true);
@@ -368,7 +367,6 @@ void FGJSBsim::init()
       Winds->SetProbabilityOfExceedence(0.0);
     }
 
-    fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
     fgic->SetWindNEDFpsIC( -wind_from_north->getDoubleValue(),
                            -wind_from_east->getDoubleValue(),
                            -wind_from_down->getDoubleValue() );
@@ -376,9 +374,9 @@ void FGJSBsim::init()
     //Atmosphere->SetExTemperature(get_Static_temperature());
     //Atmosphere->SetExPressure(get_Static_pressure());
     //Atmosphere->SetExDensity(get_Density());
-    SG_LOG(SG_FLIGHT,SG_INFO,"T,p,rho: " << fdmex->GetAtmosphere()->GetTemperature()
-     << ", " << fdmex->GetAtmosphere()->GetPressure()
-     << ", " << fdmex->GetAtmosphere()->GetDensity() );
+    SG_LOG(SG_FLIGHT,SG_INFO,"T,p,rho: " << Atmosphere->GetTemperature()
+     << ", " << Atmosphere->GetPressure()
+     << ", " << Atmosphere->GetDensity() );
 
 // deprecate egt_degf for egt-degf to have consistent naming
 // TODO: remove this for 2.6.0
@@ -394,7 +392,9 @@ void FGJSBsim::init()
 
     FCS->SetDfPos( ofNorm, globals->get_controls()->get_flaps() );
 
+    needTrim = startup_trim->getBoolValue();
     common_init();
+    fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
 
     copy_to_JSBsim();
     fdmex->RunIC();     //loop JSBSim once w/o integrating
@@ -407,7 +407,7 @@ void FGJSBsim::init()
       }
     }
 
-    if ( startup_trim->getBoolValue() ) {
+    if ( needTrim ) {
       FGLocation cart(fgic->GetLongitudeRadIC(), fgic->GetLatitudeRadIC(),
                       get_Sea_level_radius() + fgic->GetAltitudeASLFtIC());
       double cart_pos[3], contact[3], d[3], vel[3], agl;
@@ -785,8 +785,8 @@ bool FGJSBsim::copy_from_JSBsim()
 
     // Positions of Visual Reference Point
     FGLocation l = Auxiliary->GetLocationVRP();
-    _updateGeocentricPosition( l.GetLatitude(), l.GetLongitude(),
-                               l.GetRadius() - get_Sea_level_radius() );
+    _updatePosition(SGGeoc::fromRadFt( l.GetLongitude(), l.GetLatitude(),
+                                       l.GetRadius() ));
 
     _set_Altitude_AGL( Propagate->GetDistanceAGL() );
     {
@@ -1006,26 +1006,26 @@ bool FGJSBsim::ToggleDataLogging(bool state)
 void FGJSBsim::set_Latitude(double lat)
 {
   static SGConstPropertyNode_ptr altitude = fgGetNode("/position/altitude-ft");
-  double alt;
+  double alt = altitude->getDoubleValue();
   double sea_level_radius_meters, lat_geoc;
 
-  if ( altitude->getDoubleValue() > -9990 )
-    alt = altitude->getDoubleValue();
-  else
-    alt = 0.0;
+  if ( alt < -9990 ) alt = 0.0;
 
   SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat );
   SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) =  " << alt );
 
   sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
                     &sea_level_radius_meters, &lat_geoc );
-  _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
+
+  double sea_level_radius_ft = sea_level_radius_meters * SG_METER_TO_FEET;
+  _set_Sea_level_radius( sea_level_radius_ft );
 
   if (needTrim) {
-    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET  );
+    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_ft );
     fgic->SetLatitudeRadIC( lat_geoc );
   }
   else {
+    Propagate->SetSeaLevelRadius( sea_level_radius_ft );
     Propagate->SetLatitude(lat_geoc);
     FGInterface::set_Latitude(lat);
   }
diff --git a/src/FDM/JSBSim/JSBSim.hxx b/src/FDM/JSBSim/JSBSim.hxx
index a0294d5b5..1e6e09355 100644
--- a/src/FDM/JSBSim/JSBSim.hxx
+++ b/src/FDM/JSBSim/JSBSim.hxx
@@ -274,7 +274,6 @@ private:
     SGPropertyNode_ptr temperature;
     SGPropertyNode_ptr pressure;
     SGPropertyNode_ptr pressureSL;
-    SGPropertyNode_ptr density;
     SGPropertyNode_ptr ground_wind;
     SGPropertyNode_ptr turbulence_gain;
     SGPropertyNode_ptr turbulence_rate;
diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp
index 1387f013f..38622f037 100644
--- a/src/FDM/JSBSim/models/FGAtmosphere.cpp
+++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp
@@ -50,7 +50,7 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.48 2011/07/10 20:18:14 jberndt Exp $";
+static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.49 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_ATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -171,6 +171,9 @@ double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
     break;
   case eKelvin:
     targetTemp = t*9.0/5.0;
+    break;
+  default:
+    break;
   }
 
   return targetTemp;
diff --git a/src/FDM/JSBSim/models/FGLGear.cpp b/src/FDM/JSBSim/models/FGLGear.cpp
index f3fd05df7..cb3d8f521 100644
--- a/src/FDM/JSBSim/models/FGLGear.cpp
+++ b/src/FDM/JSBSim/models/FGLGear.cpp
@@ -60,7 +60,7 @@ DEFINITIONS
 GLOBAL DATA
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-static const char *IdSrc = "$Id: FGLGear.cpp,v 1.88 2011/08/30 21:05:56 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGLGear.cpp,v 1.89 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_LGEAR;
 
 // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@@ -73,11 +73,11 @@ CLASS IMPLEMENTATION
 
 FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs& inputs) :
   FGForce(fdmex),
+  in(inputs),
   GearNumber(number),
   SteerAngle(0.0),
   Castered(false),
-  StaticFriction(false),
-  in(inputs)
+  StaticFriction(false)
 {
   Element *force_table=0;
   Element *dampCoeff=0;
diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp
index 36dc45ed3..aa30ad07a 100644
--- a/src/FDM/JSBSim/models/FGOutput.cpp
+++ b/src/FDM/JSBSim/models/FGOutput.cpp
@@ -77,7 +77,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGOutput.cpp,v 1.59 2011/08/14 20:15:56 jberndt Exp $";
+static const char *IdSrc = "$Id: FGOutput.cpp,v 1.60 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_OUTPUT;
 
 // (stolen from FGFS native_fdm.cxx)
@@ -255,7 +255,6 @@ void FGOutput::DelimitedOutput(const string& fname)
   const FGPropagate* Propagate = FDMExec->GetPropagate();
   const FGAccelerations* Accelerations = FDMExec->GetAccelerations();
   const FGFCS* FCS = FDMExec->GetFCS();
-  const FGInertial* Inertial = FDMExec->GetInertial();
   const FGGroundReactions* GroundReactions = FDMExec->GetGroundReactions();
   const FGExternalReactions* ExternalReactions = FDMExec->GetExternalReactions();
   const FGBuoyantForces* BuoyantForces = FDMExec->GetBuoyantForces();
@@ -518,10 +517,8 @@ void FGOutput::DelimitedOutput(const string& fname)
 
 void FGOutput::SocketDataFill(FGNetFDM* net)
 {
-  const FGAerodynamics* Aerodynamics = FDMExec->GetAerodynamics();
   const FGAuxiliary* Auxiliary = FDMExec->GetAuxiliary();
   const FGPropulsion* Propulsion = FDMExec->GetPropulsion();
-  const FGMassBalance* MassBalance = FDMExec->GetMassBalance();
   const FGPropagate* Propagate = FDMExec->GetPropagate();
   const FGFCS* FCS = FDMExec->GetFCS();
   const FGGroundReactions* GroundReactions = FDMExec->GetGroundReactions();
diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp
index 96545104d..0668ac682 100644
--- a/src/FDM/JSBSim/models/FGPropagate.cpp
+++ b/src/FDM/JSBSim/models/FGPropagate.cpp
@@ -68,7 +68,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.95 2011/08/21 16:11:25 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.96 2011/09/17 15:36:35 bcoconni Exp $";
 static const char *IdHdr = ID_PROPAGATE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -552,10 +552,10 @@ void FGPropagate::bind(void)
 
   PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::GetAltitudeASL, &FGPropagate::SetAltitudeASL, true);
   PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::GetAltitudeASLmeters, &FGPropagate::SetAltitudeASLmeters, true);
-  PropertyManager->Tie("position/lat-gc-rad", this, &FGPropagate::GetLatitude, &FGPropagate::SetLatitude);
-  PropertyManager->Tie("position/long-gc-rad", this, &FGPropagate::GetLongitude, &FGPropagate::SetLongitude);
-  PropertyManager->Tie("position/lat-gc-deg", this, &FGPropagate::GetLatitudeDeg, &FGPropagate::SetLatitudeDeg);
-  PropertyManager->Tie("position/long-gc-deg", this, &FGPropagate::GetLongitudeDeg, &FGPropagate::SetLongitudeDeg);
+  PropertyManager->Tie("position/lat-gc-rad", this, &FGPropagate::GetLatitude, &FGPropagate::SetLatitude, false);
+  PropertyManager->Tie("position/long-gc-rad", this, &FGPropagate::GetLongitude, &FGPropagate::SetLongitude, false);
+  PropertyManager->Tie("position/lat-gc-deg", this, &FGPropagate::GetLatitudeDeg, &FGPropagate::SetLatitudeDeg, false);
+  PropertyManager->Tie("position/long-gc-deg", this, &FGPropagate::GetLongitudeDeg, &FGPropagate::SetLongitudeDeg, false);
   PropertyManager->Tie("position/lat-geod-rad", this, &FGPropagate::GetGeodLatitudeRad);
   PropertyManager->Tie("position/lat-geod-deg", this, &FGPropagate::GetGeodLatitudeDeg);
   PropertyManager->Tie("position/geod-alt-ft", this, &FGPropagate::GetGeodeticAltitude);
diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp
index 6c5942e8d..2021c822e 100644
--- a/src/FDM/JSBSim/models/FGPropulsion.cpp
+++ b/src/FDM/JSBSim/models/FGPropulsion.cpp
@@ -66,7 +66,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.50 2011/08/03 03:21:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.51 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_PROPULSION;
 
 extern short debug_lvl;
@@ -368,7 +368,6 @@ void FGPropulsion::InitRunning(int n)
 bool FGPropulsion::Load(Element* el)
 {
   string type, engine_filename;
-  bool ThrottleAdded = false;
 
   Debug(2);
 
diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
index 5c8d93c87..e25a7138b 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
@@ -50,7 +50,7 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.18 2011/08/17 23:56:01 jberndt Exp $";
+static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.19 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_STANDARDATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -58,8 +58,8 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGAtmosphere(fdmex),
-                                                               TemperatureDeltaGradient(0.0),
-                                                               TemperatureBias(0.0)
+                                                               TemperatureBias(0.0),
+                                                               TemperatureDeltaGradient(0.0)
 {
   Name = "FGStandardAtmosphere";
 
diff --git a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
index d6c55afde..c24648e3a 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
@@ -51,7 +51,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGWinds.cpp,v 1.4 2011/09/07 02:37:04 jberndt Exp $";
+static const char *IdSrc = "$Id: FGWinds.cpp,v 1.5 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_WINDS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -284,8 +284,8 @@ void FGWinds::Turbulence(double h)
     double
       T_V = in.totalDeltaT, // for compatibility of nomenclature
       sig_p = 1.9/sqrt(L_w*b_w)*sig_w, // Yeager1998, eq. (8)
-      sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
-      sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
+      //sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
+      //sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
       L_p = sqrt(L_w*b_w)/2.6, // eq. (10)
       tau_u = L_u/in.V, // eq. (6)
       tau_w = L_w/in.V, // eq. (3)
@@ -416,6 +416,8 @@ void FGWinds::CosineGust()
       // this is the native frame - and the default.
       oneMinusCosineGust.vWindTransformed = oneMinusCosineGust.vWind;
       break;
+    default:
+      break;
     }
   }
 
diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
index 68e699adf..dfa2e46b1 100644
--- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
+++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
@@ -48,7 +48,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.33 2011/06/21 04:41:54 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.34 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_FCSCOMPONENT;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -223,7 +223,7 @@ bool FGFCSComponent::Run(void)
 void FGFCSComponent::Delay(void)
 {
   output_array[index] = Output;
-  if (index == delay-1) index = 0;
+  if ((unsigned int)index == delay-1) index = 0;
   else index++;
   Output = output_array[index];
 }
diff --git a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
index 4d8c2dc41..e0c056b37 100644
--- a/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGEngine.cpp
@@ -53,7 +53,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGEngine.cpp,v 1.46 2011/08/17 23:56:01 jberndt Exp $";
+static const char *IdSrc = "$Id: FGEngine.cpp,v 1.47 2011/09/11 11:36:04 bcoconni Exp $";
 static const char *IdHdr = ID_ENGINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -61,7 +61,7 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number, struct Inputs& input)
-                      : EngineNumber(engine_number), in(input)
+                      : in(input), EngineNumber(engine_number)
 {
   Element* local_element;
   FGColumnVector3 location, orientation;
diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
index 2220cacd1..c3cb90800 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
@@ -50,7 +50,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPiston.cpp,v 1.64 2011/08/04 13:45:42 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPiston.cpp,v 1.65 2011/09/11 12:06:54 bcoconni Exp $";
 static const char *IdHdr = ID_PISTON;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -219,7 +219,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input
       RatedAltitude[2] = el->FindElementValueAsNumberConvertTo("ratedaltitude3", "FT");
   }
 
-  while(table_element = el->FindNextElement("table")) {
+  while((table_element = el->FindNextElement("table")) != 0) {
     name = table_element->GetAttributeValue("name");
     try {
       if (name == "COMBUSTION") {
diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
index 6d86d134d..411f12a65 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.36 2011/08/03 03:21:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.37 2011/09/11 12:06:54 bcoconni Exp $";
 static const char *IdHdr = ID_PROPELLER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -99,7 +99,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
     ConstantSpeed = (int)prop_element->FindElementValueAsNumber("constspeed");
   if (prop_element->FindElement("reversepitch"))
     ReversePitch = prop_element->FindElementValueAsNumber("reversepitch");
-  while(table_element = prop_element->FindNextElement("table")) {
+  while((table_element = prop_element->FindNextElement("table")) != 0) {
     name = table_element->GetAttributeValue("name");
     try {
       if (name == "C_THRUST") {
diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
index 401d6a0b9..55a711cee 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
@@ -55,7 +55,7 @@ using std::cout;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRotor.cpp,v 1.13 2011/08/03 03:21:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGRotor.cpp,v 1.16 2011/09/17 16:39:19 bcoconni Exp $";
 static const char *IdHdr = ID_ROTOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -77,8 +77,8 @@ FGRotor::FGRotor(FGFDMExec *exec, Element* rotor_element, int num)
   : FGThruster(exec, rotor_element, num),
     rho(0.002356),                                  // environment
     Radius(0.0), BladeNum(0),                       // configuration parameters
-    Sense(1.0), NominalRPM(0.0), ExternalRPM(0),
-    RPMdefinition(0), ExtRPMsource(NULL),
+    Sense(1.0), NominalRPM(0.0), MinimalRPM(0.0), MaximalRPM(0.0), 
+    ExternalRPM(0), RPMdefinition(0), ExtRPMsource(NULL),
     BladeChord(0.0), LiftCurveSlope(0.0), BladeTwist(0.0), HingeOffset(0.0),
     BladeFlappingMoment(0.0), BladeMassMoment(0.0), PolarMoment(0.0),
     InflowLag(0.0), TipLossB(0.0),
@@ -255,6 +255,13 @@ void FGRotor::Configure(Element* rotor_element)
   // make sure that v_tip (omega*r) is below 0.7mach ~ 750ft/s
   estimate = (750.0/Radius)/(2.0*M_PI) * 60.0;  // 7160/Radius
   NominalRPM = ConfigValue(rotor_element, "nominalrpm", estimate, yell);
+  NominalRPM = Constrain(2.0, NominalRPM, 1e9);
+
+  MinimalRPM = ConfigValue(rotor_element, "minrpm", 1.0);
+  MinimalRPM = Constrain(1.0, MinimalRPM, NominalRPM - 1.0);
+
+  MaximalRPM = ConfigValue(rotor_element, "maxrpm", 2.0*NominalRPM);
+  MaximalRPM = Constrain(NominalRPM, MaximalRPM, 1e9);
 
   estimate = Constrain(0.07, 2.0/Radius , 0.14); // guess solidity
   estimate = estimate * M_PI*Radius/BladeNum;
@@ -393,6 +400,7 @@ void FGRotor::calc_flow_and_thrust( double theta_0, double Uw, double Ww,
   double mu2;
 
   mu = Uw/(Omega*Radius); // /SH79/ eqn(24)
+  if (mu > 0.7) mu = 0.7;
   mu2 = sqr(mu);
   
   ct_t0 = (1.0/3.0*B[3] + 1.0/2.0 * TipLossB*mu2 - 4.0/(9.0*M_PI) * mu*mu2 ) * theta_0;
@@ -578,9 +586,8 @@ void FGRotor::CalcStatePart1(void)
     RPM = ExtRPMsource->getDoubleValue() / GearRatio;
   }
 
-  if (RPM < 1.0) { // kludge, otherwise calculations go bananas 
-    RPM = 1.0;
-  }
+  // MinimalRPM is always >= 1. MaximalRPM is always >= NominalRPM
+  RPM = Constrain(MinimalRPM, RPM, MaximalRPM);
 
   Omega = (RPM/60.0)*2.0*M_PI;
 
@@ -632,8 +639,8 @@ void FGRotor::CalcStatePart2(double PowerAvailable)
     double ExcessTorque = PowerAvailable / Omega;
     double deltaOmega   = ExcessTorque / PolarMoment * in.TotalDeltaT;
     RPM += deltaOmega/(2.0*M_PI) * 60.0;
-    if (RPM < 0.0) RPM = 0.0; // Engine won't turn backwards
   }
+  RPM = Constrain(MinimalRPM, RPM, MaximalRPM); // trim again
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -846,6 +853,8 @@ void FGRotor::Debug(int from)
       cout << "      Gear Ratio = " << GearRatio << endl;
       cout << "      Sense = " << Sense << endl;
       cout << "      Nominal RPM = " << NominalRPM << endl;
+      cout << "      Minimal RPM = " << MinimalRPM << endl;
+      cout << "      Maximal RPM = " << MaximalRPM << endl;
 
       if (ExternalRPM) {
         if (RPMdefinition == -1) {
diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.h b/src/FDM/JSBSim/models/propulsion/FGRotor.h
index 02fbf9295..85d1b3e6e 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRotor.h
+++ b/src/FDM/JSBSim/models/propulsion/FGRotor.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ROTOR "$Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $"
+#define ID_ROTOR "$Id: FGRotor.h,v 1.10 2011/09/17 16:39:19 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -68,6 +68,8 @@ CLASS DOCUMENTATION
   <numblades> {number} </numblades>
   <gearratio> {number} </gearratio>
   <nominalrpm> {number} </nominalrpm>
+  <minrpm> {number} </minrpm>
+  <maxrpm> {number} </maxrpm>
   <chord unit="{LENGTH}"> {number} </chord>
   <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
   <twist unit="{ANGLE}"> {number} </twist>
@@ -102,7 +104,9 @@ CLASS DOCUMENTATION
     \<diameter>           - Rotor disk diameter (2x R).
     \<numblades>          - Number of blades (b).
     \<gearratio>          - Ratio of (engine rpm) / (rotor rpm), usually > 1.
-    \<nominalrpm>         - RPM at which the rotor usally operates. 
+    \<nominalrpm>         - RPM at which the rotor usally operates.
+    \<minrpm>             - Lowest RPM used in the model, optional and defaults to 1.
+    \<maxrpm>             - Largest RPM used in the model, optional and defaults to 2 x nominalrpm.
     \<chord>              - Blade chord, (c).
     \<liftcurveslope>     - Slope of curve of section lift against section angle of attack,
                              per rad (a).
@@ -201,7 +205,7 @@ CLASS DOCUMENTATION
     </dl>
 
     @author Thomas Kreitler
-    @version $Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $
+    @version $Id: FGRotor.h,v 1.10 2011/09/17 16:39:19 bcoconni Exp $
   */
 
 
@@ -339,6 +343,8 @@ private:
 
   double Sense;
   double NominalRPM;
+  double MinimalRPM;
+  double MaximalRPM;
   int    ExternalRPM;
   int    RPMdefinition;
   FGPropertyManager* ExtRPMsource;

From 66a3a7f164baf75ffd26b4539c45d09923f22d8f Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 18 Sep 2011 12:53:40 +0100
Subject: [PATCH 39/85] Make map widget zoom a real property, so it persists
 between opening and closing the dialog.

---
 src/GUI/MapWidget.cxx | 38 ++++++++++++++++++++++++--------------
 src/GUI/MapWidget.hxx |  4 +++-
 src/GUI/dialog.cxx    |  2 +-
 3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx
index b6f344497..47ec864c0 100644
--- a/src/GUI/MapWidget.cxx
+++ b/src/GUI/MapWidget.cxx
@@ -8,6 +8,7 @@
 #include <algorithm> // for std::sort
 #include <plib/puAux.h>
 
+#include <simgear/sg_inlines.h>
 #include <simgear/route/waypoint.hxx>
 #include <simgear/sg_inlines.h>
 #include <simgear/misc/strutils.hxx>
@@ -383,7 +384,6 @@ MapWidget::MapWidget(int x, int y, int maxX, int maxY) :
   _route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
   _gps = fgGetNode("/instrumentation/gps");
 
-  _zoom = 6;
   _width = maxX - x;
   _height = maxY - y;
   _hasPanned = false;
@@ -402,6 +402,11 @@ MapWidget::~MapWidget()
 void MapWidget::setProperty(SGPropertyNode_ptr prop)
 {
   _root = prop;
+  int zoom = _root->getBoolValue("zoom", -1);
+  if (zoom < 0) {
+    _root->setIntValue("zoom", 6); // default zoom
+  }
+  
   _root->setBoolValue("centre-on-aircraft", true);
   _root->setBoolValue("draw-data", false);
   _root->setBoolValue("magnetic-headings", true);
@@ -501,24 +506,29 @@ void MapWidget::pan(const SGVec2d& delta)
   _projectionCenter = unproject(-delta);
 }
 
+int MapWidget::zoom() const
+{
+  int z = _root->getIntValue("zoom");
+  SG_CLAMP_RANGE(z, 0, MAX_ZOOM);
+  return z;
+}
+
 void MapWidget::zoomIn()
 {
-  if (_zoom <= 0) {
+  if (zoom() <= 0) {
     return;
   }
 
-  --_zoom;
-  SG_LOG(SG_GENERAL, SG_INFO, "zoom is now:" << _zoom);
+  _root->setIntValue("zoom", zoom() - 1);
 }
 
 void MapWidget::zoomOut()
 {
-  if (_zoom >= MAX_ZOOM) {
+  if (zoom() >= MAX_ZOOM) {
     return;
   }
 
-  ++_zoom;
-  SG_LOG(SG_GENERAL, SG_INFO, "zoom is now:" << _zoom);
+  _root->setIntValue("zoom", zoom() + 1);
 }
 
 void MapWidget::draw(int dx, int dy)
@@ -532,8 +542,7 @@ void MapWidget::draw(int dx, int dy)
       _root->setBoolValue("centre-on-aircraft", false);
       _hasPanned = false;
   }
-  else
-  if (_root->getBoolValue("centre-on-aircraft")) {
+  else if (_root->getBoolValue("centre-on-aircraft")) {
     _projectionCenter = _aircraft;
   }
 
@@ -547,6 +556,7 @@ void MapWidget::draw(int dx, int dy)
     _upHeading = 0.0;
   }
 
+  _cachedZoom = zoom();
   SGGeod topLeft = unproject(SGVec2d(_width/2, _height/2));
   // compute draw range, including a fudge factor for ILSs and other 'long'
   // symbols
@@ -1028,7 +1038,7 @@ void MapWidget::drawFix(FGFix* fix)
   glColor3f(0.0, 0.0, 0.0);
   circleAt(pos, 3, 6);
 
-  if (_zoom > SHOW_DETAIL_ZOOM) {
+  if (_cachedZoom > SHOW_DETAIL_ZOOM) {
     return; // hide fix labels beyond a certain zoom level
   }
 
@@ -1126,7 +1136,7 @@ void MapWidget::drawAirport(FGAirport* apt)
 	// draw tower location
 	SGVec2d towerPos = project(apt->getTowerLocation());
 
-  if (_zoom <= SHOW_DETAIL_ZOOM) {
+  if (_cachedZoom <= SHOW_DETAIL_ZOOM) {
     glColor3f(1.0, 1.0, 1.0);
     glLineWidth(1.0);
 
@@ -1152,7 +1162,7 @@ void MapWidget::drawAirport(FGAirport* apt)
     d->setAnchor(towerPos);
   }
 
-  if (_zoom > SHOW_DETAIL_ZOOM) {
+  if (_cachedZoom > SHOW_DETAIL_ZOOM) {
     return;
   }
 
@@ -1318,7 +1328,7 @@ void MapWidget::drawTraffic()
     return;
   }
 
-  if (_zoom > SHOW_DETAIL_ZOOM) {
+  if (_cachedZoom > SHOW_DETAIL_ZOOM) {
     return;
   }
 
@@ -1477,7 +1487,7 @@ SGGeod MapWidget::unproject(const SGVec2d& p) const
 
 double MapWidget::currentScale() const
 {
-  return 1.0 / pow(2.0, _zoom);
+  return 1.0 / pow(2.0, _cachedZoom);
 }
 
 void MapWidget::circleAt(const SGVec2d& center, int nSides, double r)
diff --git a/src/GUI/MapWidget.hxx b/src/GUI/MapWidget.hxx
index 934198603..8c3ae0b5b 100644
--- a/src/GUI/MapWidget.hxx
+++ b/src/GUI/MapWidget.hxx
@@ -32,6 +32,8 @@ public:
     
   void setProperty(SGPropertyNode_ptr prop);
 private:
+  int zoom() const;
+  
   void handlePan(int x, int y);
   
   void pan(const SGVec2d& delta);
@@ -82,7 +84,7 @@ private:
   void drawLegendBox(const SGVec2d& pos, const std::string& t);
   
   int _width, _height;
-  int _zoom;
+  int _cachedZoom;
   double _drawRangeNm;
   double _upHeading; // true heading corresponding to +ve y-axis
   bool _magneticHeadings;
diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx
index 364cf5d13..4af5b8a68 100644
--- a/src/GUI/dialog.cxx
+++ b/src/GUI/dialog.cxx
@@ -961,7 +961,7 @@ FGDialog::setupObject (puObject *object, SGPropertyNode *props)
         SGPropertyNode_ptr node = fgGetNode(propname, true);
         if (type == "map") {
           // mapWidget binds to a sub-tree of properties, and
-          // ignroes the puValue mechanism, so special case things here
+          // ignores the puValue mechanism, so special case things here
           MapWidget* mw = static_cast<MapWidget*>(object);
           mw->setProperty(node);
         } else {

From 28c8e6fe1cdf19b517c6d572244b451f93581cf2 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 4 Jun 2011 18:41:25 +0100
Subject: [PATCH 40/85] Initial hacking on nav-display instrument, derived from
 the wxradar code

---
 src/Instrumentation/CMakeLists.txt     |   1 +
 src/Instrumentation/Makefile.am        |   3 +-
 src/Instrumentation/NavDisplay.cxx     | 648 +++++++++++++++++++++++++
 src/Instrumentation/NavDisplay.hxx     | 150 ++++++
 src/Instrumentation/instrument_mgr.cxx |   6 +-
 5 files changed, 806 insertions(+), 2 deletions(-)
 create mode 100644 src/Instrumentation/NavDisplay.cxx
 create mode 100644 src/Instrumentation/NavDisplay.hxx

diff --git a/src/Instrumentation/CMakeLists.txt b/src/Instrumentation/CMakeLists.txt
index 60d9457d3..96c11b519 100644
--- a/src/Instrumentation/CMakeLists.txt
+++ b/src/Instrumentation/CMakeLists.txt
@@ -36,6 +36,7 @@ set(SOURCES
 	turn_indicator.cxx
 	vertical_speed_indicator.cxx
 	wxradar.cxx
+	NavDisplay.cxx
     HUD/HUD.cxx
     HUD/HUD_dial.cxx
     HUD/HUD_gauge.cxx
diff --git a/src/Instrumentation/Makefile.am b/src/Instrumentation/Makefile.am
index 0edb85433..7930fdbfb 100644
--- a/src/Instrumentation/Makefile.am
+++ b/src/Instrumentation/Makefile.am
@@ -34,6 +34,7 @@ libInstrumentation_a_SOURCES = \
 	groundradar.cxx groundradar.hxx \
 	agradar.cxx agradar.hxx rad_alt.cxx rad_alt.hxx \
 	rnav_waypt_controller.cxx rnav_waypt_controller.hxx \
-	tcas.cxx tcas.hxx
+	tcas.cxx tcas.hxx \
+	NavDisplay.cxx NavDisplay.hxx
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_builddir)/src
diff --git a/src/Instrumentation/NavDisplay.cxx b/src/Instrumentation/NavDisplay.cxx
new file mode 100644
index 000000000..3d0e401b7
--- /dev/null
+++ b/src/Instrumentation/NavDisplay.cxx
@@ -0,0 +1,648 @@
+// navigation display texture
+//
+// Written by James Turner, forked from wxradar code
+//
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "NavDisplay.hxx"
+
+#include <osg/Array>
+#include <osg/Geometry>
+#include <osg/Matrixf>
+#include <osg/PrimitiveSet>
+#include <osg/StateSet>
+#include <osg/LineWidth>
+
+#include <osg/Version>
+#include <osgDB/ReaderWriter>
+#include <osgDB/WriteFile>
+
+#include <simgear/constants.h>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/scene/model/model.hxx>
+#include <simgear/structure/exception.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+
+#include <sstream>
+#include <iomanip>
+#include <iostream>             // for cout, endl
+
+using std::stringstream;
+using std::endl;
+using std::setprecision;
+using std::fixed;
+using std::setw;
+using std::setfill;
+using std::cout;
+using std::endl;
+
+#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <Cockpit/panel.hxx>
+#include <Navaids/routePath.hxx>
+#include <Autopilot/route_mgr.hxx>
+#include <Navaids/navrecord.hxx>
+#include <Navaids/navlist.hxx>
+#include <Navaids/fix.hxx>
+#include <Airports/simple.hxx>
+#include <Airports/runways.hxx>
+
+#include "instrument_mgr.hxx"
+#include "od_gauge.hxx"
+
+static const float UNIT = 1.0f / 8.0f;  // 8 symbols in a row/column in the texture
+static const char *DEFAULT_FONT = "typewriter.txf";
+
+NavDisplay::NavDisplay(SGPropertyNode *node) :
+    _name(node->getStringValue("name", "nd")),
+    _num(node->getIntValue("number", 0)),
+    _time(0.0),
+    _interval(node->getDoubleValue("update-interval-sec", 1.0)),
+    _elapsed_time(0),
+    _persistance(0),
+    _sim_init_done(false),
+    _odg(0),
+    _scale(0),
+    _angle_offset(0),
+    _view_heading(0),
+    _x_offset(0),
+    _y_offset(0),
+    _radar_ref_rng(0),
+    _lat(0),
+    _lon(0),
+    _resultTexture(0),
+    _font_size(0),
+    _font_spacing(0),
+    _rangeNm(0)
+{
+    _Instrument = fgGetNode(string("/instrumentation/" + _name).c_str(), _num, true);
+    _font_node = _Instrument->getNode("font", true);
+
+#define INITFONT(p, val, type) if (!_font_node->hasValue(p)) _font_node->set##type##Value(p, val)
+    INITFONT("name", DEFAULT_FONT, String);
+    INITFONT("size", 8, Float);
+    INITFONT("line-spacing", 0.25, Float);
+    INITFONT("color/red", 0, Float);
+    INITFONT("color/green", 0.8, Float);
+    INITFONT("color/blue", 0, Float);
+    INITFONT("color/alpha", 1, Float);
+#undef INITFONT
+
+}
+
+
+NavDisplay::~NavDisplay()
+{
+}
+
+
+void
+NavDisplay::init ()
+{
+    _serviceable_node = _Instrument->getNode("serviceable", true);
+
+    // texture name to use in 2D and 3D instruments
+    _texture_path = _Instrument->getStringValue("radar-texture-path",
+        "Aircraft/Instruments/Textures/od_wxradar.rgb");
+    _resultTexture = FGTextureManager::createTexture(_texture_path.c_str(), false);
+
+    string path = _Instrument->getStringValue("symbol-texture-path",
+        "Aircraft/Instruments/Textures/nd-symbols.png");
+    SGPath tpath = globals->resolve_aircraft_path(path);
+
+    // no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
+    _symbols = SGLoadTexture2D(tpath, NULL, false, false);
+
+    FGInstrumentMgr *imgr = (FGInstrumentMgr *)globals->get_subsystem("instrumentation");
+    _odg = (FGODGauge *)imgr->get_subsystem("od_gauge");
+    _odg->setSize(_Instrument->getIntValue("texture-size", 512));
+
+
+    _user_lat_node = fgGetNode("/position/latitude-deg", true);
+    _user_lon_node = fgGetNode("/position/longitude-deg", true);
+    _user_alt_node = fgGetNode("/position/altitude-ft", true);
+
+    SGPropertyNode *n = _Instrument->getNode("display-controls", true);
+    _radar_weather_node     = n->getNode("WX", true);
+    _radar_position_node    = n->getNode("pos", true);
+    _radar_data_node        = n->getNode("data", true);
+    _radar_symbol_node      = n->getNode("symbol", true);
+    _radar_centre_node      = n->getNode("centre", true);
+    _radar_tcas_node        = n->getNode("tcas", true);
+    _radar_absalt_node      = n->getNode("abs-altitude", true);
+  
+    _ai_enabled_node = fgGetNode("/sim/ai/enabled", true);
+    _route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
+    
+// OSG geometry setup
+    _radarGeode = new osg::Geode;
+    osg::StateSet *stateSet = _radarGeode->getOrCreateStateSet();
+    stateSet->setTextureAttributeAndModes(0, _symbols.get());
+    
+    osg::LineWidth *lw = new osg::LineWidth();
+    lw->setWidth(2.0);
+    stateSet->setAttribute(lw);
+    
+    _geom = new osg::Geometry;
+    _geom->setUseDisplayList(false);
+    // Initially allocate space for 128 quads
+    _vertices = new osg::Vec2Array;
+    _vertices->setDataVariance(osg::Object::DYNAMIC);
+    _vertices->reserve(128 * 4);
+    _geom->setVertexArray(_vertices);
+    _texCoords = new osg::Vec2Array;
+    _texCoords->setDataVariance(osg::Object::DYNAMIC);
+    _texCoords->reserve(128 * 4);
+    _geom->setTexCoordArray(0, _texCoords);
+    
+    osg::Vec3Array *colors = new osg::Vec3Array;
+    colors->push_back(osg::Vec3(1.0f, 1.0f, 1.0f)); // color of echos
+    _geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
+    _geom->setColorArray(colors);
+    
+    _symbolPrimSet = new osg::DrawArrays(osg::PrimitiveSet::QUADS);
+    _symbolPrimSet->setDataVariance(osg::Object::DYNAMIC);
+    _geom->addPrimitiveSet(_symbolPrimSet);
+    
+    _geom->setInitialBound(osg::BoundingBox(osg::Vec3f(-256.0f, -256.0f, 0.0f),
+        osg::Vec3f(256.0f, 256.0f, 0.0f)));
+    _radarGeode->addDrawable(_geom);
+    _odg->allocRT();
+    // Texture in the 2D panel system
+    FGTextureManager::addTexture(_texture_path.c_str(), _odg->getTexture());
+
+    _lineGeometry = new osg::Geometry;
+    _lineGeometry->setUseDisplayList(false);
+    
+    _lineVertices = new osg::Vec2Array;
+    _lineVertices->setDataVariance(osg::Object::DYNAMIC);
+    _lineVertices->reserve(128 * 4);
+    _lineGeometry->setVertexArray(_vertices);
+    
+                  
+    _lineColors = new osg::Vec3Array;
+    _lineColors->setDataVariance(osg::Object::DYNAMIC);
+    _lineGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+    _lineGeometry->setColorArray(colors);
+    
+    _linePrimSet = new osg::DrawArrays(osg::PrimitiveSet::LINES);
+    _linePrimSet->setDataVariance(osg::Object::DYNAMIC);
+    _lineGeometry->addPrimitiveSet(_linePrimSet);
+    
+    _lineGeometry->setInitialBound(osg::BoundingBox(osg::Vec3f(-256.0f, -256.0f, 0.0f),
+                                            osg::Vec3f(256.0f, 256.0f, 0.0f)));
+
+    _radarGeode->addDrawable(_lineGeometry);              
+                  
+    _textGeode = new osg::Geode;
+
+    osg::Camera *camera = _odg->getCamera();
+    camera->addChild(_radarGeode.get());
+    camera->addChild(_textGeode.get());
+
+    updateFont();
+}
+
+
+// Local coordinates for each echo
+const osg::Vec3f symbolCoords[4] = {
+    osg::Vec3f(-.7f, -.7f, 0.0f), osg::Vec3f(.7f, -.7f, 0.0f),
+    osg::Vec3f(.7f, .7f, 0.0f), osg::Vec3f(-.7f, .7f, 0.0f)
+};
+
+
+const osg::Vec2f symbolTexCoords[4] = {
+    osg::Vec2f(0.0f, 0.0f), osg::Vec2f(UNIT, 0.0f),
+    osg::Vec2f(UNIT, UNIT), osg::Vec2f(0.0f, UNIT)
+};
+
+
+// helper
+static void
+addQuad(osg::Vec2Array *vertices, osg::Vec2Array *texCoords,
+        const osg::Matrixf& transform, const osg::Vec2f& texBase)
+{
+    for (int i = 0; i < 4; i++) {
+        const osg::Vec3f coords = transform.preMult(symbolCoords[i]);
+        texCoords->push_back(texBase + symbolTexCoords[i]);
+        vertices->push_back(osg::Vec2f(coords.x(), coords.y()));
+    }
+}
+
+
+// Rotate by a heading value
+static inline
+osg::Matrixf wxRotate(float angle)
+{
+    return osg::Matrixf::rotate(angle, 0.0f, 0.0f, -1.0f);
+}
+
+
+void
+NavDisplay::update (double delta_time_sec)
+{
+  if (!fgGetBool("sim/sceneryloaded", false)) {
+    return;
+  }
+
+  if (!_odg || !_serviceable_node->getBoolValue()) {
+    _Instrument->setStringValue("status", "");
+    return;
+  }
+  
+  _time += delta_time_sec;
+  if (_time < _interval){
+    return;
+  }
+  _time -= _interval;
+
+  string mode = _Instrument->getStringValue("display-mode", "arc");
+  _rangeNm = _Instrument->getFloatValue("range", 40.0);
+  _view_heading = fgGetDouble("/orientation/heading-deg") * SG_DEGREES_TO_RADIANS;
+  _scale = 200.0;
+    
+  bool centre = _radar_centre_node->getBoolValue();
+    if (centre) {
+        _centerTrans = osg::Matrixf::identity();
+    } else {
+        _centerTrans = osg::Matrixf::identity();
+    }
+    
+    _drawData = _radar_data_node->getBoolValue();
+    _pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
+                                      _user_lat_node->getDoubleValue(),
+                                      _user_alt_node->getDoubleValue());
+    
+  _vertices->clear();
+  _lineVertices->clear();
+  _lineColors->clear();
+  _texCoords->clear();
+  _textGeode->removeDrawables(0, _textGeode->getNumDrawables());
+  
+  update_aircraft();
+  update_route();
+  
+  
+  _symbolPrimSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
+  _symbolPrimSet->dirty();
+  _linePrimSet->set(osg::PrimitiveSet::LINES, 0, _lineVertices->size());
+  _linePrimSet->dirty();
+}
+
+osg::Matrixf NavDisplay::project(const SGGeod& geod) const
+{
+    double rangeM, bearing, az2;
+    SGGeodesy::inverse(_pos, geod, bearing, az2, rangeM);
+    
+    double radius = ((rangeM * SG_METER_TO_NM) / _rangeNm) * _scale;
+    bearing *= SG_DEGREES_TO_RADIANS;
+    
+    return osg::Matrixf(wxRotate(_view_heading - bearing)
+                          * osg::Matrixf::translate(0.0f, radius, 0.0f)
+                          * wxRotate(bearing) * _centerTrans);
+
+}
+
+void
+NavDisplay::addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data)
+{
+    int symbolRow = symbolIndex >> 4;
+    int symbolColumn = symbolIndex & 0x0f;
+    
+    const osg::Vec2f texBase(UNIT * symbolColumn, UNIT * symbolRow);
+    float size = 600 * UNIT;
+    
+    osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
+                   * project(pos));
+    addQuad(_vertices, _texCoords, m, texBase);
+    
+    if (!_drawData) {
+        return;
+    }
+
+// add data drawable
+    osgText::Text* text = new osgText::Text;
+    text->setFont(_font.get());
+    text->setFontResolution(12, 12);
+    text->setCharacterSize(_font_size);
+
+    osg::Vec3 dataPos = m.preMult(osg::Vec3(16, 16, 0));
+    text->setLineSpacing(_font_spacing);
+    
+    text->setAlignment(osgText::Text::LEFT_CENTER);
+    text->setText(data);
+    text->setPosition(osg::Vec3((int) dataPos.x(), (int)dataPos.y(), 0));
+    _textGeode->addDrawable(text);
+}
+
+void
+NavDisplay::update_route()
+{
+    if (_route->numWaypts() < 2) {
+        return;
+    }
+    
+    RoutePath path(_route->waypts());
+    for (int w=0; w<_route->numWaypts(); ++w) {
+        bool isPast = w < _route->currentIndex();
+        SGGeodVec gv(path.pathForIndex(w));
+        if (!gv.empty()) {
+            osg::Vec3 color(1.0, 0.0, 1.0);
+            if (isPast) {
+                color = osg::Vec3(0.5, 0.5, 0.5);
+            }
+            
+            osg::Vec3 pr = project(gv[0]).preMult(osg::Vec3(0.0, 0.0, 0.0));
+            for (unsigned int i=1; i<gv.size(); ++i) {
+                _lineVertices->push_back(osg::Vec2(pr.x(), pr.y()));
+                pr = project(gv[i]).preMult(osg::Vec3(0.0, 0.0, 0.0));
+               _lineVertices->push_back(osg::Vec2(pr.x(), pr.y()));
+                
+               _lineColors->push_back(color);
+               _lineColors->push_back(color);
+            }
+        } // of line drawing
+        
+        flightgear::WayptRef wpt(_route->wayptAtIndex(w));
+        SGGeod g = path.positionForIndex(w);
+        int symbolIndex = isPast ? 1 : 0;
+        if (!(g == SGGeod())) {
+            std::string data = wpt->ident();
+            addSymbol(g, symbolIndex, data);
+        }
+    } // of waypoints iteration
+}
+
+void
+NavDisplay::update_aircraft()
+{
+    if (!_ai_enabled_node->getBoolValue()) {
+        return;
+    }
+
+    bool draw_tcas     = _radar_tcas_node->getBoolValue();
+    bool draw_absolute = _radar_absalt_node->getBoolValue();
+    bool draw_echoes   = _radar_position_node->getBoolValue();
+    bool draw_symbols  = _radar_symbol_node->getBoolValue();
+    bool draw_data     = _radar_data_node->getBoolValue();
+    if (!draw_echoes && !draw_symbols && !draw_data)
+        return;
+    
+    const SGPropertyNode *ai = fgGetNode("/ai/models", true);
+    for (int i = ai->nChildren() - 1; i >= 0; i--) {
+        const SGPropertyNode *model = ai->getChild(i);
+        if (!model->nChildren()) {
+            continue;
+        }
+
+        double echo_radius, sigma;
+        const string name = model->getName();
+
+        if (name == "aircraft" || name == "tanker")
+            echo_radius = 1, sigma = 1;
+        else if (name == "multiplayer" || name == "wingman" || name == "static")
+            echo_radius = 1.5, sigma = 1;
+        else if (name == "ship" || name == "carrier" || name == "escort" ||name == "storm")
+            echo_radius = 1.5, sigma = 100;
+        else if (name == "thermal")
+            echo_radius = 2, sigma = 100;
+        else if (name == "rocket")
+            echo_radius = 0.1, sigma = 0.1;
+        else if (name == "ballistic")
+            echo_radius = 0.001, sigma = 0.001;
+        else
+            continue;
+      
+        SGGeod aiModelPos = SGGeod::fromDegFt(model->getDoubleValue("position/longitude-deg"), 
+                                            model->getDoubleValue("position/latitude-deg"), 
+                                            model->getDoubleValue("position/altitude-ft"));
+      
+        double heading = model->getDoubleValue("orientation/true-heading-deg");
+        double rangeM, bearing, az2;
+        SGGeodesy::inverse(_pos, aiModelPos, bearing, az2, rangeM);
+
+     //   if (!inRadarRange(sigma, rangeM))
+     //       continue;
+
+        bearing *= SG_DEGREES_TO_RADIANS;
+        heading *= SG_DEGREES_TO_RADIANS;
+
+        float radius = rangeM * _scale;
+     //   float angle = relativeBearing(bearing, _view_heading);
+
+        bool is_tcas_contact = false;
+        if (draw_tcas)
+        {
+            is_tcas_contact = update_tcas(model,rangeM, 
+                                          _pos.getElevationFt(),
+                                          aiModelPos.getElevationFt(),
+                                          bearing,radius,draw_absolute);
+        }
+
+        // data mode
+        if (draw_symbols && (!draw_tcas)) {
+            const osg::Vec2f texBase(0, 3 * UNIT);
+            float size = 600 * UNIT;
+            osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
+                * wxRotate(heading - bearing)
+                * osg::Matrixf::translate(0.0f, radius, 0.0f)
+                * wxRotate(bearing) * _centerTrans);
+            addQuad(_vertices, _texCoords, m, texBase);
+        }
+
+        if (draw_data || is_tcas_contact) {
+            update_data(model, aiModelPos.getElevationFt(), heading, radius, bearing, false);
+        }
+    } // of ai models iteration
+}
+
+/** Update TCAS display.
+ * Return true when processed as TCAS contact, false otherwise. */
+bool
+NavDisplay::update_tcas(const SGPropertyNode *model,double range,double user_alt,double alt,
+                       double bearing,double radius,bool absMode)
+{
+    int threatLevel=0;
+    {
+        // update TCAS symbol
+        osg::Vec2f texBase;
+        threatLevel = model->getIntValue("tcas/threat-level",-1);
+        if (threatLevel == -1)
+        {
+            // no TCAS information (i.e. no transponder) => not visible to TCAS
+            return false;
+        }
+        int row = 7 - threatLevel;
+        int col = 4;
+        double vspeed = model->getDoubleValue("velocities/vertical-speed-fps");
+        if (vspeed < -3.0) // descending
+            col+=1;
+        else
+        if (vspeed > 3.0) // climbing
+            col+=2;
+        texBase = osg::Vec2f(col*UNIT,row * UNIT);
+        float size = 200 * UNIT;
+            osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
+                * wxRotate(-bearing)
+                * osg::Matrixf::translate(0.0f, radius, 0.0f)
+                * wxRotate(bearing) * _centerTrans);
+            addQuad(_vertices, _texCoords, m, texBase);
+    }
+
+    {
+        // update TCAS data
+        osgText::Text *altStr = new osgText::Text;
+        altStr->setFont(_font.get());
+        altStr->setFontResolution(12, 12);
+        altStr->setCharacterSize(_font_size);
+        altStr->setColor(_tcas_colors[threatLevel]);
+        osg::Matrixf m(wxRotate(-bearing)
+            * osg::Matrixf::translate(0.0f, radius, 0.0f)
+            * wxRotate(bearing) * _centerTrans);
+    
+        osg::Vec3 pos = m.preMult(osg::Vec3(16, 16, 0));
+        // cast to int's, otherwise text comes out ugly
+        altStr->setLineSpacing(_font_spacing);
+    
+        stringstream text;
+        altStr->setAlignment(osgText::Text::LEFT_CENTER);
+        int altDif = (alt-user_alt+50)/100;
+        char sign = 0;
+        int dy=0;
+        if (altDif>=0)
+        {
+            sign='+';
+            dy=2;
+        }
+        else
+        if (altDif<0)
+        {
+            sign='-';
+            altDif = -altDif;
+            dy=-30;
+        }
+        altStr->setPosition(osg::Vec3((int)pos.x()-30, (int)pos.y()+dy, 0));
+        if (absMode)
+        {
+            // absolute altitude display
+            text << setprecision(0) << fixed
+                 << setw(3) << setfill('0') << alt/100 << endl;
+        }
+        else // relative altitude display
+        if (sign)
+        {
+            text << sign
+                 << setprecision(0) << fixed
+                 << setw(2) << setfill('0') << altDif << endl;
+        }
+    
+        altStr->setText(text.str());
+        _textGeode->addDrawable(altStr);
+    }
+
+    return true;
+}
+
+void NavDisplay::update_data(const SGPropertyNode *ac, double altitude, double heading,
+                       double radius, double bearing, bool selected)
+{
+  osgText::Text *callsign = new osgText::Text;
+  callsign->setFont(_font.get());
+  callsign->setFontResolution(12, 12);
+  callsign->setCharacterSize(_font_size);
+  callsign->setColor(selected ? osg::Vec4(1, 1, 1, 1) : _font_color);
+  osg::Matrixf m(wxRotate(-bearing)
+                 * osg::Matrixf::translate(0.0f, radius, 0.0f)
+                 * wxRotate(bearing) * _centerTrans);
+  
+  osg::Vec3 pos = m.preMult(osg::Vec3(16, 16, 0));
+  // cast to int's, otherwise text comes out ugly
+  callsign->setPosition(osg::Vec3((int)pos.x(), (int)pos.y(), 0));
+  callsign->setAlignment(osgText::Text::LEFT_BOTTOM_BASE_LINE);
+  callsign->setLineSpacing(_font_spacing);
+  
+  const char *identity = ac->getStringValue("transponder-id");
+  if (!identity[0])
+    identity = ac->getStringValue("callsign");
+  
+  stringstream text;
+  text << identity << endl
+  << setprecision(0) << fixed
+  << setw(3) << setfill('0') << heading * SG_RADIANS_TO_DEGREES << "\xB0 "
+  << setw(0) << altitude << "ft" << endl
+  << ac->getDoubleValue("velocities/true-airspeed-kt") << "kts";
+  
+  callsign->setText(text.str());
+  _textGeode->addDrawable(callsign);
+}
+
+void
+NavDisplay::updateFont()
+{
+    float red = _font_node->getFloatValue("color/red");
+    float green = _font_node->getFloatValue("color/green");
+    float blue = _font_node->getFloatValue("color/blue");
+    float alpha = _font_node->getFloatValue("color/alpha");
+    _font_color.set(red, green, blue, alpha);
+
+    _font_size = _font_node->getFloatValue("size");
+    _font_spacing = _font_size * _font_node->getFloatValue("line-spacing");
+    string path = _font_node->getStringValue("name", DEFAULT_FONT);
+
+    SGPath tpath;
+    if (path[0] != '/') {
+        tpath = globals->get_fg_root();
+        tpath.append("Fonts");
+        tpath.append(path);
+    } else {
+        tpath = path;
+    }
+
+#if (FG_OSG_VERSION >= 21000)
+    osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome");
+    osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str(), fontOptions.get());
+#else
+    osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str());
+#endif
+
+    if (font != 0) {
+        _font = font;
+        _font->setMinFilterHint(osg::Texture::NEAREST);
+        _font->setMagFilterHint(osg::Texture::NEAREST);
+        _font->setGlyphImageMargin(0);
+        _font->setGlyphImageMarginRatio(0);
+    }
+
+    for (int i=0;i<4;i++)
+    {
+        const float defaultColors[4][3] = {{0,1,1},{0,1,1},{1,0.5,0},{1,0,0}};
+        SGPropertyNode_ptr color_node = _font_node->getNode("tcas/color",i,true);
+        float red   = color_node->getFloatValue("red",defaultColors[i][0]);
+        float green = color_node->getFloatValue("green",defaultColors[i][1]);
+        float blue  = color_node->getFloatValue("blue",defaultColors[i][2]);
+        float alpha = color_node->getFloatValue("alpha",1);
+        _tcas_colors[i]=osg::Vec4(red, green, blue, alpha);
+    }
+}
+
+
diff --git a/src/Instrumentation/NavDisplay.hxx b/src/Instrumentation/NavDisplay.hxx
new file mode 100644
index 000000000..bedaf6fb0
--- /dev/null
+++ b/src/Instrumentation/NavDisplay.hxx
@@ -0,0 +1,150 @@
+// Wx Radar background texture
+//
+// Written by Harald JOHNSEN, started May 2005.
+// With major amendments by Vivian MEAZZA May 2007
+// Ported to OSG by Tim MOORE Jun 2007
+//
+// Copyright (C) 2005  Harald JOHNSEN - hjohnsen@evc.net
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifndef _INST_ND_HXX
+#define _INST_ND_HXX
+
+#include <osg/ref_ptr>
+#include <osg/Geode>
+#include <osg/Texture2D>
+#include <osgText/Text>
+
+#include <simgear/props/props.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+
+#include <vector>
+#include <string>
+
+class FGODGauge;
+class FGRouteMgr;
+
+class NavDisplay : public SGSubsystem
+{
+public:
+
+    NavDisplay(SGPropertyNode *node);
+    virtual ~NavDisplay();
+
+    virtual void init();
+    virtual void update(double dt);
+
+protected:
+    string _name;
+    int _num;
+    double _time;
+    double _interval;
+    double _elapsed_time;
+    double _persistance;
+    bool _sim_init_done;
+
+    SGPropertyNode_ptr _serviceable_node;
+    SGPropertyNode_ptr _Instrument;
+    SGPropertyNode_ptr _radar_mode_control_node;
+
+    SGPropertyNode_ptr _user_lat_node;
+    SGPropertyNode_ptr _user_lon_node;
+    SGPropertyNode_ptr _user_heading_node;
+    SGPropertyNode_ptr _user_alt_node;
+
+    FGODGauge *_odg;
+
+    // Convenience function for creating a property node with a
+    // default value
+    template<typename DefaultType>
+    SGPropertyNode *getInstrumentNode(const char *name, DefaultType value);
+
+private:
+    string _texture_path;
+
+    typedef enum { ARC, MAP, PLAN, ROSE, BSCAN} DisplayMode;
+    DisplayMode _display_mode;
+
+    float _scale;   // factor to convert nm to display units
+    float _angle_offset;
+    float _view_heading;
+    float _x_offset, _y_offset;
+
+    double _radar_ref_rng;
+    double _lat, _lon;
+
+    bool _drawData;
+    
+    SGPropertyNode_ptr _Radar_controls;
+
+    SGPropertyNode_ptr _radar_weather_node;
+    SGPropertyNode_ptr _radar_position_node;
+    SGPropertyNode_ptr _radar_data_node;
+    SGPropertyNode_ptr _radar_symbol_node;
+
+    SGPropertyNode_ptr _radar_centre_node;
+    SGPropertyNode_ptr _radar_coverage_node;
+    SGPropertyNode_ptr _radar_ref_rng_node;
+    SGPropertyNode_ptr _radar_hdg_marker_node;
+    SGPropertyNode_ptr _radar_rotate_node;
+    SGPropertyNode_ptr _radar_tcas_node;
+    SGPropertyNode_ptr _radar_absalt_node;
+
+    SGPropertyNode_ptr _font_node;
+    SGPropertyNode_ptr _ai_enabled_node;
+
+    osg::ref_ptr<osg::Texture2D> _resultTexture;
+    osg::ref_ptr<osg::Texture2D> _symbols;
+    osg::ref_ptr<osg::Geode> _radarGeode;
+    osg::ref_ptr<osg::Geode> _textGeode;
+  
+    osg::Geometry *_geom;
+  
+    osg::DrawArrays* _symbolPrimSet;
+    osg::Vec2Array *_vertices;
+    osg::Vec2Array *_texCoords;
+  
+    osg::Geometry* _lineGeometry;
+    osg::DrawArrays* _linePrimSet;
+    osg::Vec2Array* _lineVertices;
+    osg::Vec3Array* _lineColors;
+  
+  
+    osg::Matrixf _centerTrans;
+    osg::ref_ptr<osgText::Font> _font;
+    osg::Vec4 _font_color;
+    osg::Vec4 _tcas_colors[4];
+    float _font_size;
+    float _font_spacing;
+
+    FGRouteMgr* _route;
+    SGGeod _pos;
+    double _rangeNm;
+    
+    void update_route();
+    void update_aircraft();
+    bool update_tcas(const SGPropertyNode *model,double range,double user_alt,double alt,
+                     double bearing,double radius, bool absMode);
+    void update_data(const SGPropertyNode *ac, double altitude, double heading,
+                               double radius, double bearing, bool selected);
+    void updateFont();
+    
+    osg::Matrixf project(const SGGeod& geod) const;
+    void addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data);
+};
+
+#endif // _INST_ND_HXX
diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx
index 67dfd7623..4ebda4fa1 100644
--- a/src/Instrumentation/instrument_mgr.cxx
+++ b/src/Instrumentation/instrument_mgr.cxx
@@ -52,6 +52,7 @@
 #include "agradar.hxx"
 #include "rad_alt.hxx"
 #include "tcas.hxx"
+#include "NavDisplay.hxx"
 
 FGInstrumentMgr::FGInstrumentMgr () :
   _explicitGps(false)
@@ -227,7 +228,10 @@ bool FGInstrumentMgr::build (SGPropertyNode* config_props)
 
         } else if ( name == "tcas" ) {
             set_subsystem( id, new TCAS( node ) );
-
+        
+        } else if ( name == "navigation-display" ) {
+            set_subsystem( id, new NavDisplay( node ) );
+            
         } else {
             SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: "
                     << name );

From af6ed2ff3a0e8b04b42e1992e5d79c3156b7b358 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Mon, 13 Jun 2011 22:34:00 +0100
Subject: [PATCH 41/85] Expose departure+arrival airport + runway on
 route-manager.

---
 src/Autopilot/route_mgr.cxx        |  39 +++
 src/Autopilot/route_mgr.hxx        |   8 +
 src/Instrumentation/NavDisplay.cxx | 493 +++++++++++++++++++----------
 src/Instrumentation/NavDisplay.hxx |  48 ++-
 src/Instrumentation/od_gauge.hxx   |   4 +-
 5 files changed, 401 insertions(+), 191 deletions(-)

diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx
index 94ec9980e..f9bd77091 100644
--- a/src/Autopilot/route_mgr.cxx
+++ b/src/Autopilot/route_mgr.cxx
@@ -1556,3 +1556,42 @@ void FGRouteMgr::setDestinationICAO(const char* aIdent)
   
   arrivalChanged();
 }
+
+FGAirportRef FGRouteMgr::departureAirport() const
+{
+    return _departure;
+}
+
+FGAirportRef FGRouteMgr::destinationAirport() const
+{
+    return _destination;
+}
+
+FGRunway* FGRouteMgr::departureRunway() const
+{
+    if (!_departure) {
+        return NULL;
+    }
+    
+    string runwayId(departure->getStringValue("runway"));
+    if (!_departure->hasRunwayWithIdent(runwayId)) {
+        return NULL;
+    }
+    
+    return _departure->getRunwayByIdent(runwayId);
+}
+
+FGRunway* FGRouteMgr::destinationRunway() const
+{
+    if (!_destination) {
+        return NULL;
+    }
+    
+    string runwayId(destination->getStringValue("runway"));
+    if (!_destination->hasRunwayWithIdent(runwayId)) {
+        return NULL;
+    }
+    
+    return _destination->getRunwayByIdent(runwayId);
+}
+
diff --git a/src/Autopilot/route_mgr.hxx b/src/Autopilot/route_mgr.hxx
index 31336f96a..a309bb364 100644
--- a/src/Autopilot/route_mgr.hxx
+++ b/src/Autopilot/route_mgr.hxx
@@ -35,6 +35,8 @@ class SGPath;
 class PropertyWatcher;
 
 class FGAirport;
+class FGRunway;
+
 typedef SGSharedPtr<FGAirport> FGAirportRef;
 
 /**
@@ -134,6 +136,12 @@ public:
      *  - navaid/radial-deg/offset-nm
      */
     flightgear::WayptRef waypointFromString(const std::string& target);
+    
+    FGAirportRef departureAirport() const;
+    FGAirportRef destinationAirport() const;
+    
+    FGRunway* departureRunway() const;
+    FGRunway* destinationRunway() const;
 private:
   flightgear::WayptVec _route;
   int _currentIndex;
diff --git a/src/Instrumentation/NavDisplay.cxx b/src/Instrumentation/NavDisplay.cxx
index 3d0e401b7..c5d573f08 100644
--- a/src/Instrumentation/NavDisplay.cxx
+++ b/src/Instrumentation/NavDisplay.cxx
@@ -31,10 +31,7 @@
 #include <osg/PrimitiveSet>
 #include <osg/StateSet>
 #include <osg/LineWidth>
-
 #include <osg/Version>
-#include <osgDB/ReaderWriter>
-#include <osgDB/WriteFile>
 
 #include <simgear/constants.h>
 #include <simgear/misc/sg_path.hxx>
@@ -70,26 +67,18 @@ using std::endl;
 #include "instrument_mgr.hxx"
 #include "od_gauge.hxx"
 
-static const float UNIT = 1.0f / 8.0f;  // 8 symbols in a row/column in the texture
+static const int SYMBOL_TEX_DIM = 8;
+static const float UNIT = 1.0 / SYMBOL_TEX_DIM;
 static const char *DEFAULT_FONT = "typewriter.txf";
 
 NavDisplay::NavDisplay(SGPropertyNode *node) :
     _name(node->getStringValue("name", "nd")),
     _num(node->getIntValue("number", 0)),
     _time(0.0),
-    _interval(node->getDoubleValue("update-interval-sec", 1.0)),
-    _elapsed_time(0),
-    _persistance(0),
-    _sim_init_done(false),
+    _updateInterval(node->getDoubleValue("update-interval-sec", 0.1)),
     _odg(0),
     _scale(0),
-    _angle_offset(0),
     _view_heading(0),
-    _x_offset(0),
-    _y_offset(0),
-    _radar_ref_rng(0),
-    _lat(0),
-    _lon(0),
     _resultTexture(0),
     _font_size(0),
     _font_spacing(0),
@@ -150,21 +139,28 @@ NavDisplay::init ()
     _radar_centre_node      = n->getNode("centre", true);
     _radar_tcas_node        = n->getNode("tcas", true);
     _radar_absalt_node      = n->getNode("abs-altitude", true);
-  
+    _radar_arpt_node        = n->getNode("airport", true);
+    _radar_station_node     = n->getNode("station", true);
+    _draw_track_node        = n->getNode("ground-track", true);
+    _draw_heading_node      = n->getNode("heading", true);
+    _draw_north_node        = n->getNode("north", true);
+    _draw_fix_node          = n->getNode("fixes", true);
+    
     _ai_enabled_node = fgGetNode("/sim/ai/enabled", true);
     _route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
     
+    _navRadio1Node = fgGetNode("/instrumentation/nav[0]", true);
+    _navRadio2Node = fgGetNode("/instrumentation/nav[1]", true);
+    
 // OSG geometry setup
     _radarGeode = new osg::Geode;
-    osg::StateSet *stateSet = _radarGeode->getOrCreateStateSet();
-    stateSet->setTextureAttributeAndModes(0, _symbols.get());
-    
-    osg::LineWidth *lw = new osg::LineWidth();
-    lw->setWidth(2.0);
-    stateSet->setAttribute(lw);
-    
+
     _geom = new osg::Geometry;
     _geom->setUseDisplayList(false);
+    
+    osg::StateSet *stateSet = _geom->getOrCreateStateSet();
+    stateSet->setTextureAttributeAndModes(0, _symbols.get());
+    
     // Initially allocate space for 128 quads
     _vertices = new osg::Vec2Array;
     _vertices->setDataVariance(osg::Object::DYNAMIC);
@@ -175,10 +171,9 @@ NavDisplay::init ()
     _texCoords->reserve(128 * 4);
     _geom->setTexCoordArray(0, _texCoords);
     
-    osg::Vec3Array *colors = new osg::Vec3Array;
-    colors->push_back(osg::Vec3(1.0f, 1.0f, 1.0f)); // color of echos
-    _geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
-    _geom->setColorArray(colors);
+    _quadColors = new osg::Vec3Array;
+    _geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+    _geom->setColorArray(_quadColors);
     
     _symbolPrimSet = new osg::DrawArrays(osg::PrimitiveSet::QUADS);
     _symbolPrimSet->setDataVariance(osg::Object::DYNAMIC);
@@ -193,17 +188,21 @@ NavDisplay::init ()
 
     _lineGeometry = new osg::Geometry;
     _lineGeometry->setUseDisplayList(false);
+    stateSet = _lineGeometry->getOrCreateStateSet();    
+    osg::LineWidth *lw = new osg::LineWidth();
+    lw->setWidth(2.0);
+    stateSet->setAttribute(lw);
     
     _lineVertices = new osg::Vec2Array;
     _lineVertices->setDataVariance(osg::Object::DYNAMIC);
     _lineVertices->reserve(128 * 4);
-    _lineGeometry->setVertexArray(_vertices);
+    _lineGeometry->setVertexArray(_lineVertices);
     
                   
     _lineColors = new osg::Vec3Array;
     _lineColors->setDataVariance(osg::Object::DYNAMIC);
     _lineGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
-    _lineGeometry->setColorArray(colors);
+    _lineGeometry->setColorArray(_lineColors);
     
     _linePrimSet = new osg::DrawArrays(osg::PrimitiveSet::LINES);
     _linePrimSet->setDataVariance(osg::Object::DYNAMIC);
@@ -219,7 +218,10 @@ NavDisplay::init ()
     osg::Camera *camera = _odg->getCamera();
     camera->addChild(_radarGeode.get());
     camera->addChild(_textGeode.get());
-
+    osg::Texture2D* tex = _odg->getTexture();
+    camera->setProjectionMatrixAsOrtho2D(0, tex->getTextureWidth(), 
+        0, tex->getTextureHeight());
+    
     updateFont();
 }
 
@@ -237,19 +239,6 @@ const osg::Vec2f symbolTexCoords[4] = {
 };
 
 
-// helper
-static void
-addQuad(osg::Vec2Array *vertices, osg::Vec2Array *texCoords,
-        const osg::Matrixf& transform, const osg::Vec2f& texBase)
-{
-    for (int i = 0; i < 4; i++) {
-        const osg::Vec3f coords = transform.preMult(symbolCoords[i]);
-        texCoords->push_back(texBase + symbolTexCoords[i]);
-        vertices->push_back(osg::Vec2f(coords.x(), coords.y()));
-    }
-}
-
-
 // Rotate by a heading value
 static inline
 osg::Matrixf wxRotate(float angle)
@@ -271,24 +260,33 @@ NavDisplay::update (double delta_time_sec)
   }
   
   _time += delta_time_sec;
-  if (_time < _interval){
+  if (_time < _updateInterval){
     return;
   }
-  _time -= _interval;
+  _time -= _updateInterval;
 
   string mode = _Instrument->getStringValue("display-mode", "arc");
   _rangeNm = _Instrument->getFloatValue("range", 40.0);
-  _view_heading = fgGetDouble("/orientation/heading-deg") * SG_DEGREES_TO_RADIANS;
-  _scale = 200.0;
-    
-  bool centre = _radar_centre_node->getBoolValue();
-    if (centre) {
-        _centerTrans = osg::Matrixf::identity();
-    } else {
-        _centerTrans = osg::Matrixf::identity();
-    }
-    
-    _drawData = _radar_data_node->getBoolValue();
+  if (_Instrument->getBoolValue("aircraft-heading-up", true)) {
+    _view_heading = fgGetDouble("/orientation/heading-deg");
+  } else {
+    _view_heading = _Instrument->getFloatValue("heading-up-deg", 0.0);
+  }
+  _view_heading *= SG_DEGREES_TO_RADIANS;
+  
+  _scale = _odg->size() / _rangeNm;
+  _drawData = _radar_data_node->getBoolValue();
+  
+  double xCenterFrac = _Instrument->getDoubleValue("x-center", 0.5);
+  double yCenterFrac = _Instrument->getDoubleValue("y-center", 0.5);
+  _centerTrans = osg::Matrixf::translate(xCenterFrac * _odg->size(), 
+      yCenterFrac * _odg->size(), 0.0);
+
+// scale from nm to display units, rotate so aircraft heading is up
+// (as opposed to north), and compensate for centering
+  _projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) * 
+      wxRotate(-_view_heading) * _centerTrans;
+  
     _pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
                                       _user_lat_node->getDoubleValue(),
                                       _user_alt_node->getDoubleValue());
@@ -300,8 +298,24 @@ NavDisplay::update (double delta_time_sec)
   _textGeode->removeDrawables(0, _textGeode->getNumDrawables());
   
   update_aircraft();
+  update_stations();
+  update_airports();
+  update_waypoints();
   update_route();
+    
+  osg::Vec2 origin = projectGeod(_pos);
+  if (_draw_heading_node->getBoolValue()) {
+    addLine(origin, projectBearingRange(fgGetDouble("/orientation/heading-deg"), _rangeNm), osg::Vec3(1, 1, 1));
+  }
   
+  if (_draw_track_node->getBoolValue()) {
+    double groundTrackDeg = fgGetDouble("/instrumentation/gps/indicated-track-true-deg");
+    addLine(origin, projectBearingRange(groundTrackDeg, _rangeNm), osg::Vec3(1, 1, 1));
+  }
+  
+  if (_draw_north_node->getBoolValue()) {
+    addLine(origin, projectBearingRange(0, _rangeNm), osg::Vec3(0, 1, 1));
+  }
   
   _symbolPrimSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
   _symbolPrimSet->dirty();
@@ -309,6 +323,22 @@ NavDisplay::update (double delta_time_sec)
   _linePrimSet->dirty();
 }
 
+void NavDisplay::addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec3& color)
+{    
+    _lineVertices->push_back(a);
+    _lineVertices->push_back(b);
+    _lineColors->push_back(color);
+    _lineColors->push_back(color);
+}
+
+osg::Vec2 NavDisplay::projectBearingRange(double bearingDeg, double rangeNm) const
+{
+    osg::Vec3 p(0, rangeNm, 0.0);
+    p = wxRotate(bearingDeg * SG_DEGREES_TO_RADIANS).preMult(p);
+    p = _projectMat.preMult(p);
+    return osg::Vec2(p.x(), p.y());
+}
+
 osg::Matrixf NavDisplay::project(const SGGeod& geod) const
 {
     double rangeM, bearing, az2;
@@ -323,35 +353,42 @@ osg::Matrixf NavDisplay::project(const SGGeod& geod) const
 
 }
 
-void
-NavDisplay::addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data)
+osg::Vec2 NavDisplay::projectGeod(const SGGeod& geod) const
 {
-    int symbolRow = symbolIndex >> 4;
-    int symbolColumn = symbolIndex & 0x0f;
-    
-    const osg::Vec2f texBase(UNIT * symbolColumn, UNIT * symbolRow);
-    float size = 600 * UNIT;
-    
-    osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
-                   * project(pos));
-    addQuad(_vertices, _texCoords, m, texBase);
-    
-    if (!_drawData) {
-        return;
-    }
+    double rangeM, bearing, az2;
+    SGGeodesy::inverse(_pos, geod, bearing, az2, rangeM);
+    return projectBearingRange(bearing, rangeM * SG_METER_TO_NM);
+}
 
+void
+NavDisplay::addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data, const osg::Vec3& color)
+{
+    osg::Vec2 xy = projectGeod(pos);
+    double scale = 20.0;    
+    int symbolRow = (SYMBOL_TEX_DIM - 1) - (symbolIndex >> 4);
+    int symbolColumn = symbolIndex & 0x0f;
+    const osg::Vec2f texBase(UNIT * symbolColumn, UNIT * symbolRow);
+    
+    for (int i = 0; i < 4; i++) {
+        _texCoords->push_back(texBase + symbolTexCoords[i]);
+        osg::Vec2 coord(symbolCoords[i].x() * scale, symbolCoords[i].y() * scale);
+        _vertices->push_back(xy + coord);
+        _quadColors->push_back(color);
+    }
+    
 // add data drawable
     osgText::Text* text = new osgText::Text;
     text->setFont(_font.get());
     text->setFontResolution(12, 12);
     text->setCharacterSize(_font_size);
-
-    osg::Vec3 dataPos = m.preMult(osg::Vec3(16, 16, 0));
     text->setLineSpacing(_font_spacing);
-    
+
     text->setAlignment(osgText::Text::LEFT_CENTER);
     text->setText(data);
-    text->setPosition(osg::Vec3((int) dataPos.x(), (int)dataPos.y(), 0));
+    
+    osg::Vec4 textColor(color.x(), color.y(), color.z(), 1);
+    text->setColor(textColor);
+    text->setPosition( osg::Vec3(xy.x() + 16, xy.y(), 0));
     _textGeode->addDrawable(text);
 }
 
@@ -364,35 +401,199 @@ NavDisplay::update_route()
     
     RoutePath path(_route->waypts());
     for (int w=0; w<_route->numWaypts(); ++w) {
-        bool isPast = w < _route->currentIndex();
+        osg::Vec3 color(1.0, 0.0, 1.0);
         SGGeodVec gv(path.pathForIndex(w));
         if (!gv.empty()) {
-            osg::Vec3 color(1.0, 0.0, 1.0);
-            if (isPast) {
-                color = osg::Vec3(0.5, 0.5, 0.5);
-            }
-            
-            osg::Vec3 pr = project(gv[0]).preMult(osg::Vec3(0.0, 0.0, 0.0));
+            osg::Vec2 pr = projectGeod(gv[0]);
             for (unsigned int i=1; i<gv.size(); ++i) {
-                _lineVertices->push_back(osg::Vec2(pr.x(), pr.y()));
-                pr = project(gv[i]).preMult(osg::Vec3(0.0, 0.0, 0.0));
-               _lineVertices->push_back(osg::Vec2(pr.x(), pr.y()));
-                
-               _lineColors->push_back(color);
-               _lineColors->push_back(color);
+                osg::Vec2 p = projectGeod(gv[i]);
+                addLine(pr, p, color);
+                pr = p;
             }
         } // of line drawing
         
         flightgear::WayptRef wpt(_route->wayptAtIndex(w));
         SGGeod g = path.positionForIndex(w);
-        int symbolIndex = isPast ? 1 : 0;
         if (!(g == SGGeod())) {
-            std::string data = wpt->ident();
-            addSymbol(g, symbolIndex, data);
+            int symbolIndex = (6 << 4);
+            osg::Vec3 color(1.0, 1.0, 1.0);
+        // active waypoint is magenta, not white
+            if (w ==  _route->currentIndex()) {
+                color = osg::Vec3(1.0, 0.0, 1.0);
+            }
+            
+            addSymbol(g, symbolIndex, wpt->ident(), color);
         }
     } // of waypoints iteration
 }
 
+void
+NavDisplay::update_stations()
+{
+    FGNavRecord* nav1 = drawTunedNavaid(_navRadio1Node);
+    FGNavRecord* nav2 = drawTunedNavaid(_navRadio2Node);
+    
+    if (_radar_station_node->getBoolValue()) {
+        osg::Vec3 cyanColor(0, 1, 1);
+        FGPositioned::TypeFilter filt(FGPositioned::VOR);
+        FGPositioned::List stations = 
+            FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
+
+        FGPositioned::List::const_iterator it;
+        for (it = stations.begin(); it != stations.end(); ++it) {
+            FGPositioned* sta = *it;
+            if ((sta == nav1) || (sta == nav2)) {
+                continue;
+            }
+            
+            int symbolIndex = (6 << 4) + 2;
+            addSymbol(sta->geod(), symbolIndex, sta->ident(), cyanColor);
+        }
+    } // of stations beiong drawn
+}
+
+class FixFilter : public FGPositioned::Filter
+{
+public:
+  virtual bool pass(FGPositioned* aPos) const
+  {
+    // ignore fixes which end in digits
+      if (isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
+        return false;
+      }
+
+    return true;
+  }
+
+  virtual FGPositioned::Type minType() const {
+    return FGPositioned::FIX;
+  }
+
+  virtual FGPositioned::Type maxType() const {
+    return FGPositioned::FIX;
+  }
+
+private:
+  bool _fixes, _navaids;
+};
+
+void
+NavDisplay::update_waypoints()
+{
+    if (!_draw_fix_node->getBoolValue()) {
+        return;
+    }
+    
+    std::set<FGPositioned*> routeWaypts;
+    for (int w=0; w<_route->numWaypts(); ++w) {
+        flightgear::WayptRef wpt(_route->wayptAtIndex(w));
+        routeWaypts.insert(wpt->source());
+    }
+    
+    osg::Vec3 cyanColor(0, 1, 1);
+    FixFilter filt;
+    FGPositioned::List fixes = 
+        FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
+
+    FGPositioned::List::const_iterator it;
+    for (it = fixes.begin(); it != fixes.end(); ++it) {
+        FGPositioned* fix = *it;
+        if (routeWaypts.count(fix)) {
+            continue; // part of active route, don't draw here
+        }
+        
+        int symbolIndex = (6 << 4) + 0;
+        addSymbol(fix->geod(), symbolIndex, fix->ident(), cyanColor);
+    } // of draw fixes iteration
+}
+
+FGNavRecord*
+NavDisplay::drawTunedNavaid(const SGPropertyNode_ptr& radio )
+{
+    double mhz = radio->getDoubleValue("frequencies/selected-mhz", 0.0);
+    FGNavRecord* nav = globals->get_navlist()->findByFreq(mhz, _pos);
+    if (!nav || (nav->ident() != radio->getStringValue("nav-id"))) {
+        // station was not found
+        return NULL;
+    }
+
+    osg::Vec3 greenColor(0, 1, 0);
+    int symbolIndex = (6 << 4) + 2;
+    addSymbol(nav->geod(), symbolIndex, nav->ident(), greenColor);
+    
+// Boeing: only show radial + reciprocal if manually tuned ... hmmmm
+    osg::Vec2 stationXY = projectGeod(nav->geod());
+    SGGeod radialEnd;
+    double az2;
+    double trueRadial = radio->getDoubleValue("radials/target-radial-deg");
+    SGGeodesy::direct(nav->geod(), trueRadial, 
+        nav->get_range() * SG_NM_TO_METER, radialEnd, az2);
+    osg::Vec2 radialXY = projectGeod(radialEnd);
+    
+    osg::Vec2 d = radialXY - stationXY;
+    addLine(stationXY - d, radialXY, greenColor);
+    
+// Boeing: if POS is selected, show radial to station
+    osg::Vec2 posXY = projectGeod(_pos);
+    addLine(posXY, stationXY, greenColor);
+    
+    osgText::Text* text = new osgText::Text;
+    text->setFont(_font.get());
+    text->setFontResolution(12, 12);
+    text->setCharacterSize(_font_size);
+    text->setLineSpacing(_font_spacing);
+    text->setAlignment(osgText::Text::CENTER_BOTTOM);
+    text->setColor(osg::Vec4(0, 1, 0, 1));
+    
+    stringstream s;
+    s << "R-" << setw(3) << setfill('0') << static_cast<int>(trueRadial);
+    text->setText(s.str());
+    osg::Vec2 mid = (posXY + stationXY) * 0.5; // radial mid-point
+    text->setPosition( osg::Vec3(mid.x(), mid.y(), 0));
+    _textGeode->addDrawable(text);
+    
+    return nav;
+}
+
+void
+NavDisplay::update_airports()
+{
+    FGAirport* dep = _route->departureAirport(), 
+        *arr = _route->destinationAirport();
+    
+    if (_radar_arpt_node->getBoolValue()) {
+        osg::Vec3 cyanColor(0, 1, 1);
+        int symbolIndex = (6 << 4) + 3;
+        double minRunway = _Instrument->getDoubleValue("display-controls/min-runway-len-ft", 0.0);
+        FGAirport::HardSurfaceFilter filt(minRunway);
+        FGPositioned::List apts = 
+            FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
+            
+        FGPositioned::List::const_iterator it;
+        for (it = apts.begin(); it != apts.end(); ++it) {
+            FGPositioned* apt = *it;
+            if ((apt == dep) || (apt == arr)) {
+            // added seperately
+                continue;
+            }
+        
+            addSymbol(apt->geod(), symbolIndex, apt->ident(), cyanColor);
+        } // of airports iteration
+    }
+    
+    int symbolIndex = (7 << 4) + 1;
+    osg::Vec3 whiteColor(1, 1, 1);
+    FGRunway* rwy = _route->departureRunway();
+    if (rwy) {
+        addSymbol(dep->geod(), symbolIndex, dep->ident() + "\n" + rwy->ident(), whiteColor);
+    }
+    
+    rwy = _route->destinationRunway();
+    if (rwy) {
+        addSymbol(arr->geod(), symbolIndex, arr->ident() + "\n" + rwy->ident(), whiteColor);
+    }
+}
+
 void
 NavDisplay::update_aircraft()
 {
@@ -401,12 +602,11 @@ NavDisplay::update_aircraft()
     }
 
     bool draw_tcas     = _radar_tcas_node->getBoolValue();
-    bool draw_absolute = _radar_absalt_node->getBoolValue();
-    bool draw_echoes   = _radar_position_node->getBoolValue();
-    bool draw_symbols  = _radar_symbol_node->getBoolValue();
-    bool draw_data     = _radar_data_node->getBoolValue();
-    if (!draw_echoes && !draw_symbols && !draw_data)
+    if (!draw_tcas) {
         return;
+    }
+    
+    bool draw_absolute = _radar_absalt_node->getBoolValue();
     
     const SGPropertyNode *ai = fgGetNode("/ai/models", true);
     for (int i = ai->nChildren() - 1; i >= 0; i--) {
@@ -422,14 +622,6 @@ NavDisplay::update_aircraft()
             echo_radius = 1, sigma = 1;
         else if (name == "multiplayer" || name == "wingman" || name == "static")
             echo_radius = 1.5, sigma = 1;
-        else if (name == "ship" || name == "carrier" || name == "escort" ||name == "storm")
-            echo_radius = 1.5, sigma = 100;
-        else if (name == "thermal")
-            echo_radius = 2, sigma = 100;
-        else if (name == "rocket")
-            echo_radius = 0.1, sigma = 0.1;
-        else if (name == "ballistic")
-            echo_radius = 0.001, sigma = 0.001;
         else
             continue;
       
@@ -441,91 +633,45 @@ NavDisplay::update_aircraft()
         double rangeM, bearing, az2;
         SGGeodesy::inverse(_pos, aiModelPos, bearing, az2, rangeM);
 
-     //   if (!inRadarRange(sigma, rangeM))
-     //       continue;
-
         bearing *= SG_DEGREES_TO_RADIANS;
         heading *= SG_DEGREES_TO_RADIANS;
 
         float radius = rangeM * _scale;
-     //   float angle = relativeBearing(bearing, _view_heading);
 
-        bool is_tcas_contact = false;
-        if (draw_tcas)
-        {
-            is_tcas_contact = update_tcas(model,rangeM, 
+        bool is_tcas_contact = update_tcas(model,aiModelPos, 
                                           _pos.getElevationFt(),
                                           aiModelPos.getElevationFt(),
-                                          bearing,radius,draw_absolute);
-        }
+                                          draw_absolute);
 
-        // data mode
-        if (draw_symbols && (!draw_tcas)) {
-            const osg::Vec2f texBase(0, 3 * UNIT);
-            float size = 600 * UNIT;
-            osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
-                * wxRotate(heading - bearing)
-                * osg::Matrixf::translate(0.0f, radius, 0.0f)
-                * wxRotate(bearing) * _centerTrans);
-            addQuad(_vertices, _texCoords, m, texBase);
-        }
-
-        if (draw_data || is_tcas_contact) {
-            update_data(model, aiModelPos.getElevationFt(), heading, radius, bearing, false);
-        }
+        update_data(model, aiModelPos.getElevationFt(), heading, radius, bearing, false);
     } // of ai models iteration
 }
 
 /** Update TCAS display.
  * Return true when processed as TCAS contact, false otherwise. */
 bool
-NavDisplay::update_tcas(const SGPropertyNode *model,double range,double user_alt,double alt,
-                       double bearing,double radius,bool absMode)
+NavDisplay::update_tcas(const SGPropertyNode *model, const SGGeod& modelPos, 
+                        double user_alt,double alt, bool absMode)
 {
-    int threatLevel=0;
-    {
-        // update TCAS symbol
-        osg::Vec2f texBase;
-        threatLevel = model->getIntValue("tcas/threat-level",-1);
-        if (threatLevel == -1)
-        {
-            // no TCAS information (i.e. no transponder) => not visible to TCAS
-            return false;
-        }
-        int row = 7 - threatLevel;
-        int col = 4;
-        double vspeed = model->getDoubleValue("velocities/vertical-speed-fps");
-        if (vspeed < -3.0) // descending
-            col+=1;
-        else
-        if (vspeed > 3.0) // climbing
-            col+=2;
-        texBase = osg::Vec2f(col*UNIT,row * UNIT);
-        float size = 200 * UNIT;
-            osg::Matrixf m(osg::Matrixf::scale(size, size, 1.0f)
-                * wxRotate(-bearing)
-                * osg::Matrixf::translate(0.0f, radius, 0.0f)
-                * wxRotate(bearing) * _centerTrans);
-            addQuad(_vertices, _texCoords, m, texBase);
+    int threatLevel = model->getIntValue("tcas/threat-level",-1);
+    if (threatLevel == -1) {
+        // no TCAS information (i.e. no transponder) => not visible to TCAS
+        return false;
     }
-
-    {
-        // update TCAS data
-        osgText::Text *altStr = new osgText::Text;
-        altStr->setFont(_font.get());
-        altStr->setFontResolution(12, 12);
-        altStr->setCharacterSize(_font_size);
-        altStr->setColor(_tcas_colors[threatLevel]);
-        osg::Matrixf m(wxRotate(-bearing)
-            * osg::Matrixf::translate(0.0f, radius, 0.0f)
-            * wxRotate(bearing) * _centerTrans);
     
-        osg::Vec3 pos = m.preMult(osg::Vec3(16, 16, 0));
-        // cast to int's, otherwise text comes out ugly
-        altStr->setLineSpacing(_font_spacing);
+    int row = 4;
+    int col = threatLevel;
+    double vspeed = model->getDoubleValue("velocities/vertical-speed-fps");
+    if (vspeed < -3.0) // descending
+        row+=1;
+  //  else
+//    if (vspeed > 3.0) // climbing
+  //      col+=2;
+        
+    osg::Vec4 color = _tcas_colors[threatLevel];
     
         stringstream text;
-        altStr->setAlignment(osgText::Text::LEFT_CENTER);
+       // altStr->setAlignment(osgText::Text::LEFT_CENTER);
         int altDif = (alt-user_alt+50)/100;
         char sign = 0;
         int dy=0;
@@ -541,7 +687,7 @@ NavDisplay::update_tcas(const SGPropertyNode *model,double range,double user_alt
             altDif = -altDif;
             dy=-30;
         }
-        altStr->setPosition(osg::Vec3((int)pos.x()-30, (int)pos.y()+dy, 0));
+      //  altStr->setPosition(osg::Vec3((int)pos.x()-30, (int)pos.y()+dy, 0));
         if (absMode)
         {
             // absolute altitude display
@@ -555,11 +701,10 @@ NavDisplay::update_tcas(const SGPropertyNode *model,double range,double user_alt
                  << setprecision(0) << fixed
                  << setw(2) << setfill('0') << altDif << endl;
         }
-    
-        altStr->setText(text.str());
-        _textGeode->addDrawable(altStr);
-    }
 
+    addSymbol(modelPos, (col << 4) | row, text.str(), 
+        osg::Vec3(color.r(), color.g(), color.b()));
+            
     return true;
 }
 
diff --git a/src/Instrumentation/NavDisplay.hxx b/src/Instrumentation/NavDisplay.hxx
index bedaf6fb0..8d72bb80a 100644
--- a/src/Instrumentation/NavDisplay.hxx
+++ b/src/Instrumentation/NavDisplay.hxx
@@ -37,6 +37,7 @@
 
 class FGODGauge;
 class FGRouteMgr;
+class FGNavRecord;
 
 class NavDisplay : public SGSubsystem
 {
@@ -52,10 +53,7 @@ protected:
     string _name;
     int _num;
     double _time;
-    double _interval;
-    double _elapsed_time;
-    double _persistance;
-    bool _sim_init_done;
+    double _updateInterval;
 
     SGPropertyNode_ptr _serviceable_node;
     SGPropertyNode_ptr _Instrument;
@@ -80,13 +78,7 @@ private:
     DisplayMode _display_mode;
 
     float _scale;   // factor to convert nm to display units
-    float _angle_offset;
     float _view_heading;
-    float _x_offset, _y_offset;
-
-    double _radar_ref_rng;
-    double _lat, _lon;
-
     bool _drawData;
     
     SGPropertyNode_ptr _Radar_controls;
@@ -95,7 +87,9 @@ private:
     SGPropertyNode_ptr _radar_position_node;
     SGPropertyNode_ptr _radar_data_node;
     SGPropertyNode_ptr _radar_symbol_node;
-
+    SGPropertyNode_ptr _radar_arpt_node;
+    SGPropertyNode_ptr _radar_station_node;
+    
     SGPropertyNode_ptr _radar_centre_node;
     SGPropertyNode_ptr _radar_coverage_node;
     SGPropertyNode_ptr _radar_ref_rng_node;
@@ -104,9 +98,16 @@ private:
     SGPropertyNode_ptr _radar_tcas_node;
     SGPropertyNode_ptr _radar_absalt_node;
 
+    SGPropertyNode_ptr _draw_track_node;
+    SGPropertyNode_ptr _draw_heading_node;
+    SGPropertyNode_ptr _draw_north_node;
+    SGPropertyNode_ptr _draw_fix_node;
+    
     SGPropertyNode_ptr _font_node;
     SGPropertyNode_ptr _ai_enabled_node;
-
+    SGPropertyNode_ptr _navRadio1Node;
+    SGPropertyNode_ptr _navRadio2Node;
+    
     osg::ref_ptr<osg::Texture2D> _resultTexture;
     osg::ref_ptr<osg::Texture2D> _symbols;
     osg::ref_ptr<osg::Geode> _radarGeode;
@@ -117,7 +118,8 @@ private:
     osg::DrawArrays* _symbolPrimSet;
     osg::Vec2Array *_vertices;
     osg::Vec2Array *_texCoords;
-  
+    osg::Vec3Array* _quadColors;
+    
     osg::Geometry* _lineGeometry;
     osg::DrawArrays* _linePrimSet;
     osg::Vec2Array* _lineVertices;
@@ -125,6 +127,8 @@ private:
   
   
     osg::Matrixf _centerTrans;
+    osg::Matrixf _projectMat;
+    
     osg::ref_ptr<osgText::Font> _font;
     osg::Vec4 _font_color;
     osg::Vec4 _tcas_colors[4];
@@ -137,14 +141,26 @@ private:
     
     void update_route();
     void update_aircraft();
-    bool update_tcas(const SGPropertyNode *model,double range,double user_alt,double alt,
-                     double bearing,double radius, bool absMode);
+    void update_stations();
+    void update_airports();
+    void update_waypoints();
+    
+    bool update_tcas(const SGPropertyNode *model, const SGGeod& modelPos, 
+                            double user_alt,double alt, bool absMode);
     void update_data(const SGPropertyNode *ac, double altitude, double heading,
                                double radius, double bearing, bool selected);
     void updateFont();
     
     osg::Matrixf project(const SGGeod& geod) const;
-    void addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data);
+    osg::Vec2 projectBearingRange(double bearingDeg, double rangeNm) const;
+    osg::Vec2 projectGeod(const SGGeod& geod) const;
+    
+    void addSymbol(const SGGeod& pos, int symbolIndex, 
+        const std::string& data, const osg::Vec3& color);
+  
+    void addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec3& color);
+    
+    FGNavRecord* drawTunedNavaid(const SGPropertyNode_ptr& radio );    
 };
 
 #endif // _INST_ND_HXX
diff --git a/src/Instrumentation/od_gauge.hxx b/src/Instrumentation/od_gauge.hxx
index 3b3217d5b..932b4847d 100644
--- a/src/Instrumentation/od_gauge.hxx
+++ b/src/Instrumentation/od_gauge.hxx
@@ -43,7 +43,9 @@ public:
     virtual void update (double dt);
 
     void setSize(int viewSize);
-
+    int size() const
+        { return textureWH; }
+    
     /**
      * Say if we can render to a texture.
      * @return true if rtt is available

From 563614f36c9e530279eb13ddf2311763987b153a Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 3 Jul 2011 17:56:01 +0100
Subject: [PATCH 42/85] Expose route-manager WP mirror nodes on the API

---
 src/Autopilot/route_mgr.cxx        |   11 +-
 src/Autopilot/route_mgr.hxx        |    2 +
 src/Instrumentation/NavDisplay.cxx | 1267 +++++++++++++++++-----------
 src/Instrumentation/NavDisplay.hxx |   96 +--
 4 files changed, 837 insertions(+), 539 deletions(-)

diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx
index f9bd77091..178b7cfa2 100644
--- a/src/Autopilot/route_mgr.cxx
+++ b/src/Autopilot/route_mgr.cxx
@@ -978,7 +978,6 @@ void FGRouteMgr::update_mirror()
 
     const SGGeod& pos(wp->position());
     prop->setStringValue("id", wp->ident().c_str());
-    //prop->setStringValue("name", wp.get_name().c_str());
     prop->setDoubleValue("longitude-deg", pos.getLongitudeDeg());
     prop->setDoubleValue("latitude-deg",pos.getLatitudeDeg());
    
@@ -995,6 +994,7 @@ void FGRouteMgr::update_mirror()
       double ft = wp->altitudeFt();
       prop->setDoubleValue("altitude-m", ft * SG_FEET_TO_METER);
       prop->setDoubleValue("altitude-ft", ft);
+      prop->setIntValue("flight-level", static_cast<int>(ft / 1000) * 10);
     } else {
       prop->setDoubleValue("altitude-m", -9999.9);
       prop->setDoubleValue("altitude-ft", -9999.9);
@@ -1273,6 +1273,15 @@ Waypt* FGRouteMgr::wayptAtIndex(int index) const
   return _route[index];
 }
 
+SGPropertyNode_ptr FGRouteMgr::wayptNodeAtIndex(int index) const
+{
+    if ((index < 0) || (index >= numWaypts())) {
+        throw sg_range_exception("waypt index out of range", "FGRouteMgr::wayptAtIndex");
+    }
+    
+    return mirror->getChild("wp", index);
+}
+
 bool FGRouteMgr::saveRoute(const SGPath& path)
 {
   SG_LOG(SG_IO, SG_INFO, "Saving route to " << path.str());
diff --git a/src/Autopilot/route_mgr.hxx b/src/Autopilot/route_mgr.hxx
index a309bb364..2b3409b13 100644
--- a/src/Autopilot/route_mgr.hxx
+++ b/src/Autopilot/route_mgr.hxx
@@ -94,6 +94,8 @@ public:
     
   flightgear::Waypt* wayptAtIndex(int index) const;
              
+  SGPropertyNode_ptr wayptNodeAtIndex(int index) const;
+             
   /**
    * Find a waypoint in the route, by position, and return its index, or
    * -1 if no matching waypoint was found in the route.
diff --git a/src/Instrumentation/NavDisplay.cxx b/src/Instrumentation/NavDisplay.cxx
index c5d573f08..164fb40fd 100644
--- a/src/Instrumentation/NavDisplay.cxx
+++ b/src/Instrumentation/NavDisplay.cxx
@@ -25,6 +25,10 @@
 
 #include "NavDisplay.hxx"
 
+#include <cassert>
+#include <boost/foreach.hpp>
+#include <algorithm>
+
 #include <osg/Array>
 #include <osg/Geometry>
 #include <osg/Matrixf>
@@ -67,10 +71,252 @@ using std::endl;
 #include "instrument_mgr.hxx"
 #include "od_gauge.hxx"
 
-static const int SYMBOL_TEX_DIM = 8;
-static const float UNIT = 1.0 / SYMBOL_TEX_DIM;
 static const char *DEFAULT_FONT = "typewriter.txf";
 
+static
+osg::Matrixf degRotation(float angle)
+{
+    return osg::Matrixf::rotate(angle * SG_DEGREES_TO_RADIANS, 0.0f, 0.0f, -1.0f);
+}
+
+static osg::Vec4 readColor(SGPropertyNode* colorNode, const osg::Vec4& c)
+{
+    osg::Vec4 result;
+    result.r() = colorNode->getDoubleValue("red",   c.r());
+    result.g() = colorNode->getDoubleValue("green", c.g());
+    result.b() = colorNode->getDoubleValue("blue",  c.b());
+    result.a() = colorNode->getDoubleValue("alpha", c.a());
+    return result;
+}
+
+static osgText::Text::AlignmentType readAlignment(const std::string& t)
+{
+    if (t == "left-top") {
+        return osgText::Text::LEFT_TOP;
+    } else if (t == "left-center") {
+        return osgText::Text::LEFT_CENTER;
+    } else if (t == "left-bottom") {
+        return osgText::Text::LEFT_BOTTOM;
+    } else if (t == "center-top") {
+        return osgText::Text::CENTER_TOP;
+    } else if (t == "center-center") {
+        return osgText::Text::CENTER_CENTER;
+    } else if (t == "center-bottom") {
+        return osgText::Text::CENTER_BOTTOM;
+    } else if (t == "right-top") {
+        return osgText::Text::RIGHT_TOP;
+    } else if (t == "right-center") {
+        return osgText::Text::RIGHT_CENTER;
+    } else if (t == "right-bottom") {
+        return osgText::Text::RIGHT_BOTTOM;
+    } else if (t == "left-baseline") {
+        return osgText::Text::LEFT_BASE_LINE;
+    } else if (t == "center-baseline") {
+        return osgText::Text::CENTER_BASE_LINE;
+    } else if (t == "right-baseline") {
+        return osgText::Text::RIGHT_BASE_LINE;
+    }
+    
+    return osgText::Text::BASE_LINE;
+}
+
+static string formatPropertyValue(SGPropertyNode* nd, const string& format)
+{
+    assert(nd);
+    static char buf[512];
+    if (format.find('d') >= 0) {
+        ::snprintf(buf, 512, format.c_str(), nd->getIntValue());
+        return buf;
+    }
+    
+    if (format.find('s') >= 0) {
+        ::snprintf(buf, 512, format.c_str(), nd->getStringValue());
+        return buf;
+    }
+    
+// assume it's a double/float
+    ::snprintf(buf, 512, format.c_str(), nd->getDoubleValue());
+    return buf;
+}
+
+static osg::Vec2 mult(const osg::Vec2& v, const osg::Matrixf& m)
+{
+    osg::Vec3 r = m.preMult(osg::Vec3(v.x(), v.y(), 0.0));
+    return osg::Vec2(r.x(), r.y());
+}
+
+///////////////////////////////////////////////////////////////////
+
+class SymbolDef
+{
+public:
+    void initFromNode(SGPropertyNode* node)
+    {
+        type = node->getStringValue("type");
+        enable = sgReadCondition(fgGetNode("/"), node->getChild("enable"));
+        int n=0;
+        while (node->hasChild("state", n)) {
+            string m = node->getChild("state", n++)->getStringValue();
+            if (m[0] == '!') {
+                excluded_states.insert(m.substr(1));
+            } else {
+                required_states.insert(m);
+            }
+        } // of matches parsing
+        
+        xy0.x()  = node->getFloatValue("x0", -5);
+        xy0.y()  = node->getFloatValue("y0", -5);
+        xy1.x()  = node->getFloatValue("x1", 5);
+        xy1.y()  = node->getFloatValue("y1", 5);
+        
+        double texSize = node->getFloatValue("texture-size", 1.0);
+        
+        uv0.x()  = node->getFloatValue("u0", 0) / texSize;
+        uv0.y()  = node->getFloatValue("v0", 0) / texSize;
+        uv1.x()  = node->getFloatValue("u1", 1) / texSize;
+        uv1.y()  = node->getFloatValue("v1", 1) / texSize;
+        
+        color = readColor(node->getChild("color"), osg::Vec4(1, 1, 1, 1));
+        priority = node->getIntValue("priority", 0);
+        zOrder = node->getIntValue("zOrder", 0);
+        rotateToHeading = node->getBoolValue("rotate-to-heading", false);
+        roundPos = node->getBoolValue("round-position", true);
+        hasText = false;
+        if (node->hasChild("text")) {
+            hasText = true;
+            alignment = readAlignment(node->getStringValue("text-align"));
+            textTemplate = node->getStringValue("text");
+            textOffset.x() = node->getFloatValue("text-offset-x", 0);
+            textOffset.y() = node->getFloatValue("text-offset-y", 0);
+            textColor = readColor(node->getChild("text-color"), color);
+        }
+        
+        drawLine = node->getBoolValue("draw-line", false);
+        lineColor = readColor(node->getChild("line-color"), color);
+        drawRouteLeg = node->getBoolValue("draw-line", false);
+        
+        stretchSymbol = node->getBoolValue("stretch-symbol", false);
+        if (stretchSymbol) {
+            stretchY2 = node->getFloatValue("y2");
+            stretchY3 = node->getFloatValue("y3");
+            stretchV2 = node->getFloatValue("v2");
+            stretchV3 = node->getFloatValue("v3");
+        }
+    }
+    
+    SGCondition* enable;
+    bool enabled; // cached enabled state
+    
+    std::string type;
+    string_set required_states;
+    string_set excluded_states;
+    
+    osg::Vec2 xy0, xy1;
+    osg::Vec2 uv0, uv1;
+    osg::Vec4 color;
+    
+    int priority;
+    int zOrder;
+    bool rotateToHeading;
+    bool roundPos; ///< should position be rounded to integer values
+    bool hasText;
+    osg::Vec4 textColor;
+    osg::Vec2 textOffset;
+    osgText::Text::AlignmentType alignment;
+    string textTemplate;
+    
+    bool drawLine;
+    osg::Vec4 lineColor;
+    
+// symbol stretching creates three quads (instead of one) - a start,
+// middle and end quad, positioned along the line of the symbol.
+// X (and U) axis values determined by the values above, so we only need
+// to define the Y (and V) values to build the other quads.
+    bool stretchSymbol;
+    double stretchY2, stretchY3;
+    double stretchV2, stretchV3;
+    
+    bool drawRouteLeg;
+    
+    bool matches(const string_set& states) const
+    {
+        string_set::const_iterator it = states.begin(),
+            end = states.end();
+        for (; it != end; ++it) {
+            if (required_states.count(*it) == 0) {
+            // required state not matched
+                return false;
+            }
+            
+            if (excluded_states.count(*it) > 0) {
+            // excluded state matched
+                return false;
+            }
+        } // of applicable states iteration
+    
+        return true; // matches!
+    }
+};
+
+class SymbolInstance
+{
+public:
+    SymbolInstance(const osg::Vec2& p, double h, SymbolDef* def, SGPropertyNode* vars) :
+        pos(p),
+        headingDeg(h),
+        definition(def),
+        props(vars)
+    { }
+    
+    osg::Vec2 pos; // projected position
+    osg::Vec2 endPos;
+    double headingDeg;
+    SymbolDef* definition;
+    SGPropertyNode_ptr props;
+    
+    string text() const
+    {
+        assert(definition->hasText);
+        string r;
+        
+        int pos = 0;
+        int lastPos = 0;
+        
+        for (; pos < (int) definition->textTemplate.size();) {
+            pos = definition->textTemplate.find('{', pos);
+            if (pos == -1) { // no more replacements
+                r.append(definition->textTemplate.substr(lastPos));
+                break;
+            }
+            
+            r.append(definition->textTemplate.substr(lastPos, pos - lastPos));
+            
+            int endReplacement = definition->textTemplate.find('}', pos+1);
+            if (endReplacement <= pos) {
+                return "bad replacement";
+            }
+
+            string spec = definition->textTemplate.substr(pos + 1, endReplacement - (pos + 1));
+        // look for formatter in spec
+            int colonPos = spec.find(':');
+            if (colonPos < 0) {
+            // simple replacement
+                r.append(props->getStringValue(spec));
+            } else {
+                string format = spec.substr(colonPos + 1);
+                string prop = spec.substr(0, colonPos);
+                r.append(formatPropertyValue(props->getNode(prop), format));
+            }
+            
+            lastPos = endReplacement + 1;
+        }
+        
+        return r;
+    }
+};
+
+//////////////////////////////////////////////////////////////////
+
 NavDisplay::NavDisplay(SGPropertyNode *node) :
     _name(node->getStringValue("name", "nd")),
     _num(node->getIntValue("number", 0)),
@@ -120,7 +366,7 @@ NavDisplay::init ()
     SGPath tpath = globals->resolve_aircraft_path(path);
 
     // no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
-    _symbols = SGLoadTexture2D(tpath, NULL, false, false);
+    _symbolTexture = SGLoadTexture2D(tpath, NULL, false, false);
 
     FGInstrumentMgr *imgr = (FGInstrumentMgr *)globals->get_subsystem("instrumentation");
     _odg = (FGODGauge *)imgr->get_subsystem("od_gauge");
@@ -131,22 +377,6 @@ NavDisplay::init ()
     _user_lon_node = fgGetNode("/position/longitude-deg", true);
     _user_alt_node = fgGetNode("/position/altitude-ft", true);
 
-    SGPropertyNode *n = _Instrument->getNode("display-controls", true);
-    _radar_weather_node     = n->getNode("WX", true);
-    _radar_position_node    = n->getNode("pos", true);
-    _radar_data_node        = n->getNode("data", true);
-    _radar_symbol_node      = n->getNode("symbol", true);
-    _radar_centre_node      = n->getNode("centre", true);
-    _radar_tcas_node        = n->getNode("tcas", true);
-    _radar_absalt_node      = n->getNode("abs-altitude", true);
-    _radar_arpt_node        = n->getNode("airport", true);
-    _radar_station_node     = n->getNode("station", true);
-    _draw_track_node        = n->getNode("ground-track", true);
-    _draw_heading_node      = n->getNode("heading", true);
-    _draw_north_node        = n->getNode("north", true);
-    _draw_fix_node          = n->getNode("fixes", true);
-    
-    _ai_enabled_node = fgGetNode("/sim/ai/enabled", true);
     _route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
     
     _navRadio1Node = fgGetNode("/instrumentation/nav[0]", true);
@@ -159,7 +389,7 @@ NavDisplay::init ()
     _geom->setUseDisplayList(false);
     
     osg::StateSet *stateSet = _geom->getOrCreateStateSet();
-    stateSet->setTextureAttributeAndModes(0, _symbols.get());
+    stateSet->setTextureAttributeAndModes(0, _symbolTexture.get());
     
     // Initially allocate space for 128 quads
     _vertices = new osg::Vec2Array;
@@ -171,7 +401,7 @@ NavDisplay::init ()
     _texCoords->reserve(128 * 4);
     _geom->setTexCoordArray(0, _texCoords);
     
-    _quadColors = new osg::Vec3Array;
+    _quadColors = new osg::Vec4Array;
     _geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
     _geom->setColorArray(_quadColors);
     
@@ -199,7 +429,7 @@ NavDisplay::init ()
     _lineGeometry->setVertexArray(_lineVertices);
     
                   
-    _lineColors = new osg::Vec3Array;
+    _lineColors = new osg::Vec4Array;
     _lineColors->setDataVariance(osg::Object::DYNAMIC);
     _lineGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
     _lineGeometry->setColorArray(_lineColors);
@@ -225,28 +455,6 @@ NavDisplay::init ()
     updateFont();
 }
 
-
-// Local coordinates for each echo
-const osg::Vec3f symbolCoords[4] = {
-    osg::Vec3f(-.7f, -.7f, 0.0f), osg::Vec3f(.7f, -.7f, 0.0f),
-    osg::Vec3f(.7f, .7f, 0.0f), osg::Vec3f(-.7f, .7f, 0.0f)
-};
-
-
-const osg::Vec2f symbolTexCoords[4] = {
-    osg::Vec2f(0.0f, 0.0f), osg::Vec2f(UNIT, 0.0f),
-    osg::Vec2f(UNIT, UNIT), osg::Vec2f(0.0f, UNIT)
-};
-
-
-// Rotate by a heading value
-static inline
-osg::Matrixf wxRotate(float angle)
-{
-    return osg::Matrixf::rotate(angle, 0.0f, 0.0f, -1.0f);
-}
-
-
 void
 NavDisplay::update (double delta_time_sec)
 {
@@ -265,17 +473,14 @@ NavDisplay::update (double delta_time_sec)
   }
   _time -= _updateInterval;
 
-  string mode = _Instrument->getStringValue("display-mode", "arc");
   _rangeNm = _Instrument->getFloatValue("range", 40.0);
   if (_Instrument->getBoolValue("aircraft-heading-up", true)) {
     _view_heading = fgGetDouble("/orientation/heading-deg");
   } else {
     _view_heading = _Instrument->getFloatValue("heading-up-deg", 0.0);
   }
-  _view_heading *= SG_DEGREES_TO_RADIANS;
   
   _scale = _odg->size() / _rangeNm;
-  _drawData = _radar_data_node->getBoolValue();
   
   double xCenterFrac = _Instrument->getDoubleValue("x-center", 0.5);
   double yCenterFrac = _Instrument->getDoubleValue("y-center", 0.5);
@@ -285,7 +490,7 @@ NavDisplay::update (double delta_time_sec)
 // scale from nm to display units, rotate so aircraft heading is up
 // (as opposed to north), and compensate for centering
   _projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) * 
-      wxRotate(-_view_heading) * _centerTrans;
+      degRotation(-_view_heading) * _centerTrans;
   
     _pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
                                       _user_lat_node->getDoubleValue(),
@@ -297,25 +502,16 @@ NavDisplay::update (double delta_time_sec)
   _texCoords->clear();
   _textGeode->removeDrawables(0, _textGeode->getNumDrawables());
   
-  update_aircraft();
-  update_stations();
-  update_airports();
-  update_waypoints();
-  update_route();
-    
-  osg::Vec2 origin = projectGeod(_pos);
-  if (_draw_heading_node->getBoolValue()) {
-    addLine(origin, projectBearingRange(fgGetDouble("/orientation/heading-deg"), _rangeNm), osg::Vec3(1, 1, 1));
+  BOOST_FOREACH(SymbolDef* def, _rules) {
+      def->enabled = def->enable->test();
   }
   
-  if (_draw_track_node->getBoolValue()) {
-    double groundTrackDeg = fgGetDouble("/instrumentation/gps/indicated-track-true-deg");
-    addLine(origin, projectBearingRange(groundTrackDeg, _rangeNm), osg::Vec3(1, 1, 1));
-  }
-  
-  if (_draw_north_node->getBoolValue()) {
-    addLine(origin, projectBearingRange(0, _rangeNm), osg::Vec3(0, 1, 1));
-  }
+  processRoute();
+  processNavRadios();
+  processAI();
+  findItems();
+  limitDisplayedSymbols();
+  addSymbolsToScene();
   
   _symbolPrimSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
   _symbolPrimSet->dirty();
@@ -323,423 +519,6 @@ NavDisplay::update (double delta_time_sec)
   _linePrimSet->dirty();
 }
 
-void NavDisplay::addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec3& color)
-{    
-    _lineVertices->push_back(a);
-    _lineVertices->push_back(b);
-    _lineColors->push_back(color);
-    _lineColors->push_back(color);
-}
-
-osg::Vec2 NavDisplay::projectBearingRange(double bearingDeg, double rangeNm) const
-{
-    osg::Vec3 p(0, rangeNm, 0.0);
-    p = wxRotate(bearingDeg * SG_DEGREES_TO_RADIANS).preMult(p);
-    p = _projectMat.preMult(p);
-    return osg::Vec2(p.x(), p.y());
-}
-
-osg::Matrixf NavDisplay::project(const SGGeod& geod) const
-{
-    double rangeM, bearing, az2;
-    SGGeodesy::inverse(_pos, geod, bearing, az2, rangeM);
-    
-    double radius = ((rangeM * SG_METER_TO_NM) / _rangeNm) * _scale;
-    bearing *= SG_DEGREES_TO_RADIANS;
-    
-    return osg::Matrixf(wxRotate(_view_heading - bearing)
-                          * osg::Matrixf::translate(0.0f, radius, 0.0f)
-                          * wxRotate(bearing) * _centerTrans);
-
-}
-
-osg::Vec2 NavDisplay::projectGeod(const SGGeod& geod) const
-{
-    double rangeM, bearing, az2;
-    SGGeodesy::inverse(_pos, geod, bearing, az2, rangeM);
-    return projectBearingRange(bearing, rangeM * SG_METER_TO_NM);
-}
-
-void
-NavDisplay::addSymbol(const SGGeod& pos, int symbolIndex, const std::string& data, const osg::Vec3& color)
-{
-    osg::Vec2 xy = projectGeod(pos);
-    double scale = 20.0;    
-    int symbolRow = (SYMBOL_TEX_DIM - 1) - (symbolIndex >> 4);
-    int symbolColumn = symbolIndex & 0x0f;
-    const osg::Vec2f texBase(UNIT * symbolColumn, UNIT * symbolRow);
-    
-    for (int i = 0; i < 4; i++) {
-        _texCoords->push_back(texBase + symbolTexCoords[i]);
-        osg::Vec2 coord(symbolCoords[i].x() * scale, symbolCoords[i].y() * scale);
-        _vertices->push_back(xy + coord);
-        _quadColors->push_back(color);
-    }
-    
-// add data drawable
-    osgText::Text* text = new osgText::Text;
-    text->setFont(_font.get());
-    text->setFontResolution(12, 12);
-    text->setCharacterSize(_font_size);
-    text->setLineSpacing(_font_spacing);
-
-    text->setAlignment(osgText::Text::LEFT_CENTER);
-    text->setText(data);
-    
-    osg::Vec4 textColor(color.x(), color.y(), color.z(), 1);
-    text->setColor(textColor);
-    text->setPosition( osg::Vec3(xy.x() + 16, xy.y(), 0));
-    _textGeode->addDrawable(text);
-}
-
-void
-NavDisplay::update_route()
-{
-    if (_route->numWaypts() < 2) {
-        return;
-    }
-    
-    RoutePath path(_route->waypts());
-    for (int w=0; w<_route->numWaypts(); ++w) {
-        osg::Vec3 color(1.0, 0.0, 1.0);
-        SGGeodVec gv(path.pathForIndex(w));
-        if (!gv.empty()) {
-            osg::Vec2 pr = projectGeod(gv[0]);
-            for (unsigned int i=1; i<gv.size(); ++i) {
-                osg::Vec2 p = projectGeod(gv[i]);
-                addLine(pr, p, color);
-                pr = p;
-            }
-        } // of line drawing
-        
-        flightgear::WayptRef wpt(_route->wayptAtIndex(w));
-        SGGeod g = path.positionForIndex(w);
-        if (!(g == SGGeod())) {
-            int symbolIndex = (6 << 4);
-            osg::Vec3 color(1.0, 1.0, 1.0);
-        // active waypoint is magenta, not white
-            if (w ==  _route->currentIndex()) {
-                color = osg::Vec3(1.0, 0.0, 1.0);
-            }
-            
-            addSymbol(g, symbolIndex, wpt->ident(), color);
-        }
-    } // of waypoints iteration
-}
-
-void
-NavDisplay::update_stations()
-{
-    FGNavRecord* nav1 = drawTunedNavaid(_navRadio1Node);
-    FGNavRecord* nav2 = drawTunedNavaid(_navRadio2Node);
-    
-    if (_radar_station_node->getBoolValue()) {
-        osg::Vec3 cyanColor(0, 1, 1);
-        FGPositioned::TypeFilter filt(FGPositioned::VOR);
-        FGPositioned::List stations = 
-            FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
-
-        FGPositioned::List::const_iterator it;
-        for (it = stations.begin(); it != stations.end(); ++it) {
-            FGPositioned* sta = *it;
-            if ((sta == nav1) || (sta == nav2)) {
-                continue;
-            }
-            
-            int symbolIndex = (6 << 4) + 2;
-            addSymbol(sta->geod(), symbolIndex, sta->ident(), cyanColor);
-        }
-    } // of stations beiong drawn
-}
-
-class FixFilter : public FGPositioned::Filter
-{
-public:
-  virtual bool pass(FGPositioned* aPos) const
-  {
-    // ignore fixes which end in digits
-      if (isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
-        return false;
-      }
-
-    return true;
-  }
-
-  virtual FGPositioned::Type minType() const {
-    return FGPositioned::FIX;
-  }
-
-  virtual FGPositioned::Type maxType() const {
-    return FGPositioned::FIX;
-  }
-
-private:
-  bool _fixes, _navaids;
-};
-
-void
-NavDisplay::update_waypoints()
-{
-    if (!_draw_fix_node->getBoolValue()) {
-        return;
-    }
-    
-    std::set<FGPositioned*> routeWaypts;
-    for (int w=0; w<_route->numWaypts(); ++w) {
-        flightgear::WayptRef wpt(_route->wayptAtIndex(w));
-        routeWaypts.insert(wpt->source());
-    }
-    
-    osg::Vec3 cyanColor(0, 1, 1);
-    FixFilter filt;
-    FGPositioned::List fixes = 
-        FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
-
-    FGPositioned::List::const_iterator it;
-    for (it = fixes.begin(); it != fixes.end(); ++it) {
-        FGPositioned* fix = *it;
-        if (routeWaypts.count(fix)) {
-            continue; // part of active route, don't draw here
-        }
-        
-        int symbolIndex = (6 << 4) + 0;
-        addSymbol(fix->geod(), symbolIndex, fix->ident(), cyanColor);
-    } // of draw fixes iteration
-}
-
-FGNavRecord*
-NavDisplay::drawTunedNavaid(const SGPropertyNode_ptr& radio )
-{
-    double mhz = radio->getDoubleValue("frequencies/selected-mhz", 0.0);
-    FGNavRecord* nav = globals->get_navlist()->findByFreq(mhz, _pos);
-    if (!nav || (nav->ident() != radio->getStringValue("nav-id"))) {
-        // station was not found
-        return NULL;
-    }
-
-    osg::Vec3 greenColor(0, 1, 0);
-    int symbolIndex = (6 << 4) + 2;
-    addSymbol(nav->geod(), symbolIndex, nav->ident(), greenColor);
-    
-// Boeing: only show radial + reciprocal if manually tuned ... hmmmm
-    osg::Vec2 stationXY = projectGeod(nav->geod());
-    SGGeod radialEnd;
-    double az2;
-    double trueRadial = radio->getDoubleValue("radials/target-radial-deg");
-    SGGeodesy::direct(nav->geod(), trueRadial, 
-        nav->get_range() * SG_NM_TO_METER, radialEnd, az2);
-    osg::Vec2 radialXY = projectGeod(radialEnd);
-    
-    osg::Vec2 d = radialXY - stationXY;
-    addLine(stationXY - d, radialXY, greenColor);
-    
-// Boeing: if POS is selected, show radial to station
-    osg::Vec2 posXY = projectGeod(_pos);
-    addLine(posXY, stationXY, greenColor);
-    
-    osgText::Text* text = new osgText::Text;
-    text->setFont(_font.get());
-    text->setFontResolution(12, 12);
-    text->setCharacterSize(_font_size);
-    text->setLineSpacing(_font_spacing);
-    text->setAlignment(osgText::Text::CENTER_BOTTOM);
-    text->setColor(osg::Vec4(0, 1, 0, 1));
-    
-    stringstream s;
-    s << "R-" << setw(3) << setfill('0') << static_cast<int>(trueRadial);
-    text->setText(s.str());
-    osg::Vec2 mid = (posXY + stationXY) * 0.5; // radial mid-point
-    text->setPosition( osg::Vec3(mid.x(), mid.y(), 0));
-    _textGeode->addDrawable(text);
-    
-    return nav;
-}
-
-void
-NavDisplay::update_airports()
-{
-    FGAirport* dep = _route->departureAirport(), 
-        *arr = _route->destinationAirport();
-    
-    if (_radar_arpt_node->getBoolValue()) {
-        osg::Vec3 cyanColor(0, 1, 1);
-        int symbolIndex = (6 << 4) + 3;
-        double minRunway = _Instrument->getDoubleValue("display-controls/min-runway-len-ft", 0.0);
-        FGAirport::HardSurfaceFilter filt(minRunway);
-        FGPositioned::List apts = 
-            FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
-            
-        FGPositioned::List::const_iterator it;
-        for (it = apts.begin(); it != apts.end(); ++it) {
-            FGPositioned* apt = *it;
-            if ((apt == dep) || (apt == arr)) {
-            // added seperately
-                continue;
-            }
-        
-            addSymbol(apt->geod(), symbolIndex, apt->ident(), cyanColor);
-        } // of airports iteration
-    }
-    
-    int symbolIndex = (7 << 4) + 1;
-    osg::Vec3 whiteColor(1, 1, 1);
-    FGRunway* rwy = _route->departureRunway();
-    if (rwy) {
-        addSymbol(dep->geod(), symbolIndex, dep->ident() + "\n" + rwy->ident(), whiteColor);
-    }
-    
-    rwy = _route->destinationRunway();
-    if (rwy) {
-        addSymbol(arr->geod(), symbolIndex, arr->ident() + "\n" + rwy->ident(), whiteColor);
-    }
-}
-
-void
-NavDisplay::update_aircraft()
-{
-    if (!_ai_enabled_node->getBoolValue()) {
-        return;
-    }
-
-    bool draw_tcas     = _radar_tcas_node->getBoolValue();
-    if (!draw_tcas) {
-        return;
-    }
-    
-    bool draw_absolute = _radar_absalt_node->getBoolValue();
-    
-    const SGPropertyNode *ai = fgGetNode("/ai/models", true);
-    for (int i = ai->nChildren() - 1; i >= 0; i--) {
-        const SGPropertyNode *model = ai->getChild(i);
-        if (!model->nChildren()) {
-            continue;
-        }
-
-        double echo_radius, sigma;
-        const string name = model->getName();
-
-        if (name == "aircraft" || name == "tanker")
-            echo_radius = 1, sigma = 1;
-        else if (name == "multiplayer" || name == "wingman" || name == "static")
-            echo_radius = 1.5, sigma = 1;
-        else
-            continue;
-      
-        SGGeod aiModelPos = SGGeod::fromDegFt(model->getDoubleValue("position/longitude-deg"), 
-                                            model->getDoubleValue("position/latitude-deg"), 
-                                            model->getDoubleValue("position/altitude-ft"));
-      
-        double heading = model->getDoubleValue("orientation/true-heading-deg");
-        double rangeM, bearing, az2;
-        SGGeodesy::inverse(_pos, aiModelPos, bearing, az2, rangeM);
-
-        bearing *= SG_DEGREES_TO_RADIANS;
-        heading *= SG_DEGREES_TO_RADIANS;
-
-        float radius = rangeM * _scale;
-
-        bool is_tcas_contact = update_tcas(model,aiModelPos, 
-                                          _pos.getElevationFt(),
-                                          aiModelPos.getElevationFt(),
-                                          draw_absolute);
-
-        update_data(model, aiModelPos.getElevationFt(), heading, radius, bearing, false);
-    } // of ai models iteration
-}
-
-/** Update TCAS display.
- * Return true when processed as TCAS contact, false otherwise. */
-bool
-NavDisplay::update_tcas(const SGPropertyNode *model, const SGGeod& modelPos, 
-                        double user_alt,double alt, bool absMode)
-{
-    int threatLevel = model->getIntValue("tcas/threat-level",-1);
-    if (threatLevel == -1) {
-        // no TCAS information (i.e. no transponder) => not visible to TCAS
-        return false;
-    }
-    
-    int row = 4;
-    int col = threatLevel;
-    double vspeed = model->getDoubleValue("velocities/vertical-speed-fps");
-    if (vspeed < -3.0) // descending
-        row+=1;
-  //  else
-//    if (vspeed > 3.0) // climbing
-  //      col+=2;
-        
-    osg::Vec4 color = _tcas_colors[threatLevel];
-    
-        stringstream text;
-       // altStr->setAlignment(osgText::Text::LEFT_CENTER);
-        int altDif = (alt-user_alt+50)/100;
-        char sign = 0;
-        int dy=0;
-        if (altDif>=0)
-        {
-            sign='+';
-            dy=2;
-        }
-        else
-        if (altDif<0)
-        {
-            sign='-';
-            altDif = -altDif;
-            dy=-30;
-        }
-      //  altStr->setPosition(osg::Vec3((int)pos.x()-30, (int)pos.y()+dy, 0));
-        if (absMode)
-        {
-            // absolute altitude display
-            text << setprecision(0) << fixed
-                 << setw(3) << setfill('0') << alt/100 << endl;
-        }
-        else // relative altitude display
-        if (sign)
-        {
-            text << sign
-                 << setprecision(0) << fixed
-                 << setw(2) << setfill('0') << altDif << endl;
-        }
-
-    addSymbol(modelPos, (col << 4) | row, text.str(), 
-        osg::Vec3(color.r(), color.g(), color.b()));
-            
-    return true;
-}
-
-void NavDisplay::update_data(const SGPropertyNode *ac, double altitude, double heading,
-                       double radius, double bearing, bool selected)
-{
-  osgText::Text *callsign = new osgText::Text;
-  callsign->setFont(_font.get());
-  callsign->setFontResolution(12, 12);
-  callsign->setCharacterSize(_font_size);
-  callsign->setColor(selected ? osg::Vec4(1, 1, 1, 1) : _font_color);
-  osg::Matrixf m(wxRotate(-bearing)
-                 * osg::Matrixf::translate(0.0f, radius, 0.0f)
-                 * wxRotate(bearing) * _centerTrans);
-  
-  osg::Vec3 pos = m.preMult(osg::Vec3(16, 16, 0));
-  // cast to int's, otherwise text comes out ugly
-  callsign->setPosition(osg::Vec3((int)pos.x(), (int)pos.y(), 0));
-  callsign->setAlignment(osgText::Text::LEFT_BOTTOM_BASE_LINE);
-  callsign->setLineSpacing(_font_spacing);
-  
-  const char *identity = ac->getStringValue("transponder-id");
-  if (!identity[0])
-    identity = ac->getStringValue("callsign");
-  
-  stringstream text;
-  text << identity << endl
-  << setprecision(0) << fixed
-  << setw(3) << setfill('0') << heading * SG_RADIANS_TO_DEGREES << "\xB0 "
-  << setw(0) << altitude << "ft" << endl
-  << ac->getDoubleValue("velocities/true-airspeed-kt") << "kts";
-  
-  callsign->setText(text.str());
-  _textGeode->addDrawable(callsign);
-}
 
 void
 NavDisplay::updateFont()
@@ -777,17 +556,525 @@ NavDisplay::updateFont()
         _font->setGlyphImageMargin(0);
         _font->setGlyphImageMarginRatio(0);
     }
+}
 
-    for (int i=0;i<4;i++)
+void NavDisplay::addSymbolToScene(SymbolInstance* sym)
+{
+    SymbolDef* def = sym->definition;
+    
+    osg::Vec2 verts[4];
+    verts[0] = def->xy0;
+    verts[1] = osg::Vec2(def->xy1.x(), def->xy0.y());
+    verts[2] = def->xy1;
+    verts[3] = osg::Vec2(def->xy0.x(), def->xy1.y());
+    
+    if (def->rotateToHeading) {
+        osg::Matrixf m(degRotation(sym->headingDeg));
+        for (int i=0; i<4; ++i) {
+            verts[i] = mult(verts[i], m);
+        }
+    }
+    
+    osg::Vec2 pos = sym->pos;
+    if (def->roundPos) {
+        pos = osg::Vec2((int) pos.x(), (int) pos.y());
+    }
+    
+    _texCoords->push_back(def->uv0);
+    _texCoords->push_back(osg::Vec2(def->uv1.x(), def->uv0.y()));
+    _texCoords->push_back(def->uv1);
+    _texCoords->push_back(osg::Vec2(def->uv0.x(), def->uv1.y()));
+    
+    for (int i=0; i<4; ++i) {
+        _vertices->push_back(verts[i] + pos);
+        _quadColors->push_back(def->color);
+    }
+    
+    if (def->stretchSymbol) {
+        osg::Vec2 stretchVerts[4];
+        stretchVerts[0] = osg::Vec2(def->xy0.x(), def->stretchY2);
+        stretchVerts[1] = osg::Vec2(def->xy1.x(), def->stretchY2);
+        stretchVerts[2] = osg::Vec2(def->xy1.x(), def->stretchY3);
+        stretchVerts[3] = osg::Vec2(def->xy0.x(), def->stretchY3);
+        
+        osg::Matrixf m(degRotation(sym->headingDeg));
+        for (int i=0; i<4; ++i) {
+            stretchVerts[i] = mult(stretchVerts[i], m);
+        }
+        
+    // stretched quad
+        _vertices->push_back(verts[2] + pos);
+        _vertices->push_back(stretchVerts[1] + sym->endPos);
+        _vertices->push_back(stretchVerts[0] + sym->endPos);
+        _vertices->push_back(verts[3] + pos);
+        
+        _texCoords->push_back(def->uv1);
+        _texCoords->push_back(osg::Vec2(def->uv1.x(), def->stretchV2));
+        _texCoords->push_back(osg::Vec2(def->uv0.x(), def->stretchV2));
+        _texCoords->push_back(osg::Vec2(def->uv0.x(), def->uv1.y()));
+        
+        for (int i=0; i<4; ++i) {
+            _quadColors->push_back(def->color);
+        }
+        
+    // quad three, for the end portion
+        for (int i=0; i<4; ++i) {
+            _vertices->push_back(stretchVerts[i] + sym->endPos);
+            _quadColors->push_back(def->color);
+        }
+        
+        _texCoords->push_back(osg::Vec2(def->uv0.x(), def->stretchV2));
+        _texCoords->push_back(osg::Vec2(def->uv1.x(), def->stretchV2));
+        _texCoords->push_back(osg::Vec2(def->uv1.x(), def->stretchV3));
+        _texCoords->push_back(osg::Vec2(def->uv0.x(), def->stretchV3));
+    }
+    
+    if (def->drawLine) {
+        addLine(sym->pos, sym->endPos, def->lineColor);
+    }
+    
+    if (!def->hasText) {
+        return;
+    }
+    
+    osgText::Text* t = new osgText::Text;
+    t->setFont(_font.get());
+    t->setFontResolution(12, 12);
+    t->setCharacterSize(_font_size);
+    t->setLineSpacing(_font_spacing);
+    t->setColor(def->textColor);
+    t->setAlignment(def->alignment);
+    t->setText(sym->text());
+
+
+    osg::Vec2 textPos = def->textOffset + pos;
+// ensure we use ints here, or text visual quality goes bad
+    t->setPosition(osg::Vec3((int)textPos.x(), (int)textPos.y(), 0));
+    _textGeode->addDrawable(t);
+}
+
+class OrderByPriority
+{
+public:
+    bool operator()(SymbolInstance* a, SymbolInstance* b)
     {
-        const float defaultColors[4][3] = {{0,1,1},{0,1,1},{1,0.5,0},{1,0,0}};
-        SGPropertyNode_ptr color_node = _font_node->getNode("tcas/color",i,true);
-        float red   = color_node->getFloatValue("red",defaultColors[i][0]);
-        float green = color_node->getFloatValue("green",defaultColors[i][1]);
-        float blue  = color_node->getFloatValue("blue",defaultColors[i][2]);
-        float alpha = color_node->getFloatValue("alpha",1);
-        _tcas_colors[i]=osg::Vec4(red, green, blue, alpha);
+        return a->definition->priority > b->definition->priority;
+    }    
+};
+
+void NavDisplay::limitDisplayedSymbols()
+{
+    unsigned int maxSymbols = _Instrument->getIntValue("max-symbols");
+    if (_symbols.size() <= maxSymbols) {
+        _excessDataNode->setBoolValue(false);
+        return;
+    }
+    
+    std::sort(_symbols.begin(), _symbols.end(), OrderByPriority());
+    _symbols.resize(maxSymbols);
+    _excessDataNode->setBoolValue(true);
+}
+
+class OrderByZ
+{
+public:
+    bool operator()(SymbolInstance* a, SymbolInstance* b)
+    {
+        return a->definition->zOrder > b->definition->zOrder;
+    }
+};
+
+void NavDisplay::addSymbolsToScene()
+{
+    std::sort(_symbols.begin(), _symbols.end(), OrderByZ());
+    BOOST_FOREACH(SymbolInstance* sym, _symbols) {
+        addSymbolToScene(sym);
     }
 }
 
+void NavDisplay::addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec4& color)
+{    
+    _lineVertices->push_back(a);
+    _lineVertices->push_back(b);
+    _lineColors->push_back(color);
+    _lineColors->push_back(color);
+}
+
+osg::Vec2 NavDisplay::projectBearingRange(double bearingDeg, double rangeNm) const
+{
+    osg::Vec3 p(0, rangeNm, 0.0);
+    p = degRotation(bearingDeg).preMult(p);
+    p = _projectMat.preMult(p);
+    return osg::Vec2(p.x(), p.y());
+}
+
+osg::Vec2 NavDisplay::projectGeod(const SGGeod& geod) const
+{
+    double rangeM, bearing, az2;
+    SGGeodesy::inverse(_pos, geod, bearing, az2, rangeM);
+    return projectBearingRange(bearing, rangeM * SG_METER_TO_NM);
+}
+
+class Filter : public FGPositioned::Filter
+{
+public:
+    virtual bool pass(FGPositioned* aPos) const
+    {
+        if (aPos->type() == FGPositioned::FIX) {
+            string ident(aPos->ident());
+            // ignore fixes which end in digits
+            if ((ident.size() > 4) && isdigit(ident[3]) && isdigit(ident[4])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    virtual FGPositioned::Type minType() const {
+        return FGPositioned::AIRPORT;
+    }
+
+    virtual FGPositioned::Type maxType() const {
+        return FGPositioned::OBSTACLE;
+    }
+};
+
+void NavDisplay::findItems()
+{
+    Filter filt;
+    FGPositioned::List items = 
+        FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
+
+    FGPositioned::List::const_iterator it;
+    for (it = items.begin(); it != items.end(); ++it) {
+        foundPositionedItem(*it);
+    }
+}
+
+void NavDisplay::processRoute()
+{
+    _routeSources.clear();
+    RoutePath path(_route->waypts());
+    int current = _route->currentIndex();
+    
+    for (int w=0; w<_route->numWaypts(); ++w) {
+        flightgear::WayptRef wpt(_route->wayptAtIndex(w));
+        _routeSources.insert(wpt->source());
+        
+        string_set state;
+        state.insert("on-active-route");
+        
+        if (w < current) {
+            state.insert("passed");
+        }
+        
+        if (w == current) {
+            state.insert("current-wp");
+        }
+        
+        if (w > current) {
+            state.insert("future");
+        }
+        
+        if (w == (current + 1)) {
+            state.insert("next-wp");
+        }
+        
+        SymbolDefVector rules;
+        findRules(wpt->type() , state, rules);
+        if (rules.empty()) {
+            return; // no rules matched, we can skip this item
+        }
+
+        SGGeod g = path.positionForIndex(w);
+        SGPropertyNode* vars = _route->wayptNodeAtIndex(w);
+        double heading;
+        computeWayptPropsAndHeading(wpt, g, vars, heading);
+
+        osg::Vec2 projected = projectGeod(g);
+        BOOST_FOREACH(SymbolDef* r, rules) {
+            addSymbolInstance(projected, heading, r, vars);
+            
+            if (r->drawRouteLeg) {
+                SGGeodVec gv(path.pathForIndex(w));
+                if (!gv.empty()) {
+                    osg::Vec2 pr = projectGeod(gv[0]);
+                    for (unsigned int i=1; i<gv.size(); ++i) {
+                        osg::Vec2 p = projectGeod(gv[i]);
+                        addLine(pr, p, r->lineColor);
+                        pr = p;
+                    }
+                }
+            } // of leg drawing enabled
+        } // of matching rules iteration
+    } // of waypoints iteration
+}
+
+void NavDisplay::computeWayptPropsAndHeading(flightgear::Waypt* wpt, const SGGeod& pos, SGPropertyNode* nd, double& heading)
+{
+    double rangeM, az2;
+    SGGeodesy::inverse(_pos, pos, heading, az2, rangeM);
+    nd->setIntValue("radial", heading);
+    nd->setDoubleValue("distance-nm", rangeM * SG_METER_TO_NM);
+    
+    heading = nd->getDoubleValue("leg-bearing-true-deg");
+}
+
+void NavDisplay::processNavRadios()
+{
+    _nav1Station = processNavRadio(_navRadio1Node);
+    _nav2Station = processNavRadio(_navRadio2Node);
+    
+    foundPositionedItem(_nav1Station);
+    foundPositionedItem(_nav2Station);
+}
+
+FGNavRecord* NavDisplay::processNavRadio(const SGPropertyNode_ptr& radio)
+{
+    double mhz = radio->getDoubleValue("frequencies/selected-mhz", 0.0);
+    FGNavRecord* nav = globals->get_navlist()->findByFreq(mhz, _pos);
+    if (!nav || (nav->ident() != radio->getStringValue("nav-id"))) {
+        // station was not found
+        return NULL;
+    }
+    
+    
+    return nav;
+}
+
+bool NavDisplay::anyRuleForType(const string& type) const
+{
+    BOOST_FOREACH(SymbolDef* r, _rules) {
+        if (!r->enabled) {
+            continue;
+        }
+    
+        if (r->type == type) {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool NavDisplay::anyRuleMatches(const string& type, const string_set& states) const
+{
+    BOOST_FOREACH(SymbolDef* r, _rules) {
+        if (!r->enabled || (r->type != type)) {
+            continue;
+        }
+
+        if (r->matches(states)) {
+            return true;
+        }
+    } // of rules iteration
+    
+    return false;
+}
+
+void NavDisplay::findRules(const string& type, const string_set& states, SymbolDefVector& rules)
+{
+    BOOST_FOREACH(SymbolDef* candidate, _rules) {
+        if (!candidate->enabled) {
+            continue;
+        }
+        
+        if (candidate->matches(states)) {
+            rules.push_back(candidate);
+        }
+    }
+}
+
+void NavDisplay::foundPositionedItem(FGPositioned* pos)
+{
+    if (!pos) {
+        return;
+    }
+    
+    string type = FGPositioned::nameForType(pos->type());
+    if (!anyRuleForType(type)) {
+        return; // not diplayed at all, we're done
+    }
+    
+    string_set states;
+    computePositionedState(pos, states);
+    
+    SymbolDefVector rules;
+    findRules(type, states, rules);
+    if (rules.empty()) {
+        return; // no rules matched, we can skip this item
+    }
+    
+    SGPropertyNode_ptr vars(new SGPropertyNode);
+    double heading;
+    computePositionedPropsAndHeading(pos, vars, heading);
+    
+    osg::Vec2 projected = projectGeod(pos->geod());
+    BOOST_FOREACH(SymbolDef* r, rules) {
+        addSymbolInstance(projected, heading, r, vars);
+    }
+}
+
+void NavDisplay::computePositionedPropsAndHeading(FGPositioned* pos, SGPropertyNode* nd, double& heading)
+{
+    nd->setStringValue("id", pos->ident());
+    nd->setStringValue("name", pos->name());
+    nd->setDoubleValue("elevation-ft", pos->elevation());
+    nd->setIntValue("heading-deg", 0);
+    
+    switch (pos->type()) {
+    case FGPositioned::VOR:
+    case FGPositioned::LOC: {
+        FGNavRecord* nav = static_cast<FGNavRecord*>(pos);
+        nd->setDoubleValue("frequency-mhz", nav->get_freq());
+        
+        if (pos == _nav1Station) {
+            nd->setIntValue("heading-deg", _navRadio1Node->getDoubleValue("radials/target-radial-deg"));
+        } else if (pos == _nav2Station) {
+            nd->setIntValue("heading-deg", _navRadio2Node->getDoubleValue("radials/target-radial-deg"));
+        }
+        
+        break;
+    }
+
+    case FGPositioned::AIRPORT:
+    case FGPositioned::SEAPORT:
+    case FGPositioned::HELIPORT:
+        
+        break;
+        
+    case FGPositioned::RUNWAY: {
+        FGRunway* rwy = static_cast<FGRunway*>(pos);
+        nd->setDoubleValue("heading-deg", rwy->headingDeg());
+        nd->setIntValue("length-ft", rwy->lengthFt());
+        nd->setStringValue("airport", rwy->airport()->ident());
+        break;
+    }
+
+    default:
+        break; 
+    }
+}
+
+void NavDisplay::computePositionedState(FGPositioned* pos, string_set& states)
+{
+    if (_routeSources.count(pos) != 0) {
+        states.insert("on-active-route");
+    }
+    
+    switch (pos->type()) {
+    case FGPositioned::VOR:
+    case FGPositioned::LOC:
+        if (pos == _nav1Station) {
+            states.insert("tuned");
+            states.insert("nav1");
+        }
+        
+        if (pos == _nav2Station) {
+            states.insert("tuned");
+            states.insert("nav2");
+        }
+        break;
+    
+    case FGPositioned::AIRPORT:
+    case FGPositioned::SEAPORT:
+    case FGPositioned::HELIPORT:
+        // mark alternates!
+        // once the FMS system has some way to tell us about them, of course
+        
+        if (pos == _route->departureAirport()) {
+            states.insert("departure");
+        }
+        
+        if (pos == _route->destinationAirport()) {
+            states.insert("destination");
+        }
+        break;
+    
+    case FGPositioned::RUNWAY:
+        if (pos == _route->departureRunway()) {
+            states.insert("departure");
+        }
+        
+        if (pos == _route->destinationRunway()) {
+            states.insert("destination");
+        }
+        break;
+    
+    case FGPositioned::OBSTACLE:
+    #if 0    
+        FGObstacle* obs = (FGObstacle*) pos;
+        if (obj->isLit()) {
+            states.insert("lit");
+        }
+        
+        if (obj->getHeightAGLFt() >= 1000) {
+            states.insert("greater-1000-ft");
+        }
+    #endif
+        break;
+    
+    default:
+        break;
+    } // FGPositioned::Type switch
+}
+
+void NavDisplay::processAI()
+{
+    SGPropertyNode *ai = fgGetNode("/ai/models", true);
+    for (int i = ai->nChildren() - 1; i >= 0; i--) {
+        SGPropertyNode *model = ai->getChild(i);
+        if (!model->nChildren()) {
+            continue;
+        }
+        
+    // prefix types with 'ai-', to avoid any chance of namespace collisions
+    // with fg-positioned.
+        string_set ss;
+        computeAIStates(model, ss);        
+        SymbolDefVector rules;
+        findRules(string("ai-") + model->getName(), ss, rules);
+        if (rules.empty()) {
+            return; // no rules matched, we can skip this item
+        }
+
+        double heading = model->getDoubleValue("orientation/true-heading-deg");
+        SGGeod aiModelPos = SGGeod::fromDegFt(model->getDoubleValue("position/longitude-deg"), 
+                                            model->getDoubleValue("position/latitude-deg"), 
+                                            model->getDoubleValue("position/altitude-ft"));
+    // compute some additional props
+        int fl = (aiModelPos.getElevationFt() / 1000);
+        model->setIntValue("flight-level", fl * 10);
+                                            
+        osg::Vec2 projected = projectGeod(aiModelPos);
+        BOOST_FOREACH(SymbolDef* r, rules) {
+            addSymbolInstance(projected, heading, r, (SGPropertyNode*) model);
+        }
+    } // of ai models iteration
+}
+
+void NavDisplay::computeAIStates(const SGPropertyNode* ai, string_set& states)
+{
+    int threatLevel = ai->getIntValue("tcas/threat-level",-1);
+    if (threatLevel >= 0) {
+        states.insert("tcas");
+    //    states.insert("tcas-threat-level-" + itoa(threatLevel));
+    }
+    
+    double vspeed = ai->getDoubleValue("velocities/vertical-speed-fps");
+    if (vspeed < -3.0) {
+        states.insert("descending");
+    } else if (vspeed > 3.0) {
+        states.insert("climbing");
+    }
+}
+
+void NavDisplay::addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars)
+{
+    SymbolInstance* sym = new SymbolInstance(proj, heading, def, vars);
+    _symbols.push_back(sym);
+}
+
+
 
diff --git a/src/Instrumentation/NavDisplay.hxx b/src/Instrumentation/NavDisplay.hxx
index 8d72bb80a..1c8a73885 100644
--- a/src/Instrumentation/NavDisplay.hxx
+++ b/src/Instrumentation/NavDisplay.hxx
@@ -38,6 +38,18 @@
 class FGODGauge;
 class FGRouteMgr;
 class FGNavRecord;
+class FGPositioned;
+
+class SymbolInstance;
+class SymbolDef;
+
+namespace flightgear
+{
+    class Waypt;
+}
+
+typedef std::set<std::string> string_set;
+typedef std::vector<SymbolDef*> SymbolDefVector;
 
 class NavDisplay : public SGSubsystem
 {
@@ -72,36 +84,41 @@ protected:
     SGPropertyNode *getInstrumentNode(const char *name, DefaultType value);
 
 private:
+    void addSymbolsToScene();
+    void addSymbolToScene(SymbolInstance* sym);
+    void limitDisplayedSymbols();
+    
+    void findItems();
+    void foundPositionedItem(FGPositioned* pos);
+    void computePositionedPropsAndHeading(FGPositioned* pos, SGPropertyNode* nd, double& heading);
+    void computePositionedState(FGPositioned* pos, string_set& states);
+    void processRoute();
+    void computeWayptPropsAndHeading(flightgear::Waypt* wpt, const SGGeod& pos, SGPropertyNode* nd, double& heading);
+    void processNavRadios();
+    FGNavRecord* processNavRadio(const SGPropertyNode_ptr& radio);
+    void processAI();
+    void computeAIStates(const SGPropertyNode* ai, string_set& states);
+    
+    bool anyRuleForType(const std::string& type) const;
+    bool anyRuleMatches(const std::string& type, const string_set& states) const;
+    void findRules(const std::string& type, const string_set& states, SymbolDefVector& rules);
+    
+    void addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars);
+    void addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec4& color);
+    osg::Vec2 projectBearingRange(double bearingDeg, double rangeNm) const;
+    osg::Vec2 projectGeod(const SGGeod& geod) const;
+    
+    void updateFont();
+    
     string _texture_path;
 
-    typedef enum { ARC, MAP, PLAN, ROSE, BSCAN} DisplayMode;
-    DisplayMode _display_mode;
 
     float _scale;   // factor to convert nm to display units
     float _view_heading;
-    bool _drawData;
     
     SGPropertyNode_ptr _Radar_controls;
 
-    SGPropertyNode_ptr _radar_weather_node;
-    SGPropertyNode_ptr _radar_position_node;
-    SGPropertyNode_ptr _radar_data_node;
-    SGPropertyNode_ptr _radar_symbol_node;
-    SGPropertyNode_ptr _radar_arpt_node;
-    SGPropertyNode_ptr _radar_station_node;
-    
-    SGPropertyNode_ptr _radar_centre_node;
-    SGPropertyNode_ptr _radar_coverage_node;
-    SGPropertyNode_ptr _radar_ref_rng_node;
-    SGPropertyNode_ptr _radar_hdg_marker_node;
-    SGPropertyNode_ptr _radar_rotate_node;
-    SGPropertyNode_ptr _radar_tcas_node;
-    SGPropertyNode_ptr _radar_absalt_node;
 
-    SGPropertyNode_ptr _draw_track_node;
-    SGPropertyNode_ptr _draw_heading_node;
-    SGPropertyNode_ptr _draw_north_node;
-    SGPropertyNode_ptr _draw_fix_node;
     
     SGPropertyNode_ptr _font_node;
     SGPropertyNode_ptr _ai_enabled_node;
@@ -109,7 +126,7 @@ private:
     SGPropertyNode_ptr _navRadio2Node;
     
     osg::ref_ptr<osg::Texture2D> _resultTexture;
-    osg::ref_ptr<osg::Texture2D> _symbols;
+    osg::ref_ptr<osg::Texture2D> _symbolTexture;
     osg::ref_ptr<osg::Geode> _radarGeode;
     osg::ref_ptr<osg::Geode> _textGeode;
   
@@ -118,12 +135,12 @@ private:
     osg::DrawArrays* _symbolPrimSet;
     osg::Vec2Array *_vertices;
     osg::Vec2Array *_texCoords;
-    osg::Vec3Array* _quadColors;
+    osg::Vec4Array* _quadColors;
     
     osg::Geometry* _lineGeometry;
     osg::DrawArrays* _linePrimSet;
     osg::Vec2Array* _lineVertices;
-    osg::Vec3Array* _lineColors;
+    osg::Vec4Array* _lineColors;
   
   
     osg::Matrixf _centerTrans;
@@ -131,36 +148,19 @@ private:
     
     osg::ref_ptr<osgText::Font> _font;
     osg::Vec4 _font_color;
-    osg::Vec4 _tcas_colors[4];
     float _font_size;
     float _font_spacing;
 
     FGRouteMgr* _route;
     SGGeod _pos;
     double _rangeNm;
-    
-    void update_route();
-    void update_aircraft();
-    void update_stations();
-    void update_airports();
-    void update_waypoints();
-    
-    bool update_tcas(const SGPropertyNode *model, const SGGeod& modelPos, 
-                            double user_alt,double alt, bool absMode);
-    void update_data(const SGPropertyNode *ac, double altitude, double heading,
-                               double radius, double bearing, bool selected);
-    void updateFont();
-    
-    osg::Matrixf project(const SGGeod& geod) const;
-    osg::Vec2 projectBearingRange(double bearingDeg, double rangeNm) const;
-    osg::Vec2 projectGeod(const SGGeod& geod) const;
-    
-    void addSymbol(const SGGeod& pos, int symbolIndex, 
-        const std::string& data, const osg::Vec3& color);
-  
-    void addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec3& color);
-    
-    FGNavRecord* drawTunedNavaid(const SGPropertyNode_ptr& radio );    
+
+    SymbolDefVector _rules;
+    FGNavRecord* _nav1Station;
+    FGNavRecord* _nav2Station;
+    std::vector<SymbolInstance*> _symbols;
+    std::set<FGPositioned*> _routeSources;
+    SGPropertyNode_ptr _excessDataNode;
 };
 
 #endif // _INST_ND_HXX

From 05eebae3615ff71a43993e0797d2ffe864a2d727 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Mon, 19 Sep 2011 17:19:57 +0100
Subject: [PATCH 43/85] MSVC2008 project files update.

---
 projects/VC90/FlightGear/FlightGear.vcproj | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index 1ae6559ab..a4c24e46a 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3761,6 +3761,14 @@
 				RelativePath="..\..\..\src\Instrumentation\od_gauge.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\Instrumentation\NavDisplay.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Instrumentation\NavDisplay.hxx"
+				>
+			</File>
 			<File
 				RelativePath="..\..\..\src\Instrumentation\rad_alt.cxx"
 				>

From f9d35d3bf5b0fd182cab20c784c7dedb824b2bb4 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Tue, 20 Sep 2011 16:03:32 +0200
Subject: [PATCH 44/85] Add -lsgthreads to fgpanel's automake

---
 utils/fgpanel/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/fgpanel/Makefile.am b/utils/fgpanel/Makefile.am
index fedae0567..df6b6dde0 100644
--- a/utils/fgpanel/Makefile.am
+++ b/utils/fgpanel/Makefile.am
@@ -17,6 +17,6 @@ fgpanel_SOURCES = main.cxx \
 
 fgpanel_LDADD = \
 	-lGLU -lglut -lsgmath -lsgprops -lsgio -lsgdebug -lsgmisc -lsgstructure -lsgxml -lsgtiming \
-	-lplibpu -lplibfnt -lplibul \
+	-lplibpu -lplibfnt -lplibul -lsgthreads \
 	-lrt -lpng
 endif

From 25707ce82e6246522755032a6a558ff6dfe36837 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Sat, 17 Sep 2011 19:26:23 +0200
Subject: [PATCH 45/85] Add debug messages for real-weather runway selection

---
 src/Main/main.cxx | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/Main/main.cxx b/src/Main/main.cxx
index 6fa94dc9b..0fa2e7f94 100644
--- a/src/Main/main.cxx
+++ b/src/Main/main.cxx
@@ -510,6 +510,8 @@ static void fgIdleFunction ( void ) {
         // runway selection as for AI traffic. However, this code belongs to
         // somewhere(?) else - if I only new where...
         if( true == fgGetBool( "/environment/metar/valid" ) ) {
+            SG_LOG(SG_ENVIRONMENT, SG_INFO,
+                "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
             // the realwx_ctrl fetches metar in the foreground on init,
             // If it was able to fetch a metar or one was given on the commandline,
             // the valid flag is set here, otherwise it is false
@@ -525,6 +527,9 @@ static void fgIdleFunction ( void ) {
                 extern bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg );
                 fgSetPosFromAirportIDandHdg( apt, hdg );
             }
+        } else {
+            SG_LOG(SG_ENVIRONMENT, SG_INFO,
+                "No METAR available to pick active runway" );
         }
 
         fgSplashProgress("initializing graphics engine");

From 7dd8f00c4259160ba7ffcb3cfad36ebecf412a13 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 21 Sep 2011 17:13:13 +0100
Subject: [PATCH 46/85] Enable event-input for joysticks by default on Mac +
 Linux, in Cmake.

---
 CMakeLists.txt           | 35 ++++++++++++++++++++---------------
 src/Input/CMakeLists.txt |  5 +++++
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4a6d8232f..eb74dd462 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,6 +49,12 @@ else()
 	set(HUDSON_BUILD_ID "none")
 endif()
 
+IF(APPLE)
+    set(EVENT_INPUT_DEFAULT 1)
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+    set(EVENT_INPUT_DEFAULT 1)
+endif()
+
 find_package(Git)
 if (GIT_FOUND)
 	execute_process(COMMAND git --git-dir ${PROJECT_SOURCE_DIR}/.git rev-parse  HEAD
@@ -67,7 +73,7 @@ option(ENABLE_LARCSIM "Set to ON to build FlightGear with LaRCsim FDM" ON)
 option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON)
 option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
 option(ENABLE_FGADMIN "Set to ON to build FlightGear with FGADMIN" ON)
-option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
+option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" ${EVENT_INPUT_DEFAULT})
 option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient support" ON)
 option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
 option(WITH_FGPANEL "Set to ON to build the fgpanel application" ON)
@@ -98,20 +104,6 @@ if(SP_FDMS)
 	set(ENABLE_SP_FDM 1)
 endif()
 
-if(EVENT_INPUT)
-	message(STATUS "checking event-based Input")
-	find_package(DBus)
-	IF(APPLE)
-
-	elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
-
-	else()
-		message(WARNING "event input is not supported on this platform yet")
-	endif()
-else(EVENT_INPUT)
-	set(ENABLE_PLIB_JOYSTICK 1)
-endif(EVENT_INPUT)
-
 if (MSVC AND MSVC_3RDPARTY_ROOT)
   message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
   set( OSG_MSVC "msvc" )
@@ -135,6 +127,19 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
   set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
 endif (MSVC AND MSVC_3RDPARTY_ROOT)
 
+if(EVENT_INPUT)
+	message(STATUS "checking event-based Input")
+	
+	IF(APPLE)
+
+	elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+        find_package(DBus)
+	else()
+		message(WARNING "event input is not supported on this platform yet")
+	endif()
+else(EVENT_INPUT)
+	set(ENABLE_PLIB_JOYSTICK 1)
+endif(EVENT_INPUT)
 
 # check required dependencies
 find_package(Boost REQUIRED)
diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index 4c5939d4a..7fb713507 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -2,8 +2,12 @@ include(FlightGearComponent)
 
 IF(APPLE)
 	set(EVENT_INPUT_SOURCES FGMacOSXEventInput.cxx)
+	set(EVENT_INPUT_HEADERS FGMacOSXEventInput.hxx)
+else(MSVC)
+    message(STATUS "EventInput not implemented for Windows yet")
 else()
 	set(EVENT_INPUT_SOURCES FGLinuxEventInput.cxx)
+	set(EVENT_INPUT_HEADERS FGLinuxEventInput.hxx)
 endif()
 
 
@@ -31,6 +35,7 @@ set(HEADERS
     	
 if(EVENT_INPUT)
 	list(APPEND SOURCES ${EVENT_INPUT_SOURCES})
+	list(APPEND SOURCES ${EVENT_INPUT_HEADERS})
 	include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
 endif()
 	

From 227b3e469c5d062458b3fe1b0c429a54d25089e2 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 18 Sep 2011 15:05:05 +0100
Subject: [PATCH 47/85] Remove indirection on viewer draw/resize code-paths.

---
 src/Main/FGEventHandler.cxx  |  7 +++----
 src/Main/FGEventHandler.hxx  | 22 ----------------------
 src/Main/fg_os_common.cxx    | 10 ----------
 src/Main/fg_os_osgviewer.cxx |  4 +---
 src/Main/main.cxx            |  7 -------
 src/Main/renderer.cxx        |  6 ------
 src/Main/renderer.hxx        |  3 +--
 7 files changed, 5 insertions(+), 54 deletions(-)

diff --git a/src/Main/FGEventHandler.cxx b/src/Main/FGEventHandler.cxx
index e43f4b8ab..f6fc75c76 100644
--- a/src/Main/FGEventHandler.cxx
+++ b/src/Main/FGEventHandler.cxx
@@ -12,6 +12,7 @@
 #include "CameraGroup.hxx"
 #include "FGEventHandler.hxx"
 #include "WindowSystemAdapter.hxx"
+#include "renderer.hxx"
 
 #if !defined(X_DISPLAY_MISSING)
 #define X_DOUBLE_SCROLL_BUG 1
@@ -29,8 +30,6 @@ const int printStatsKey = 2;
 
 FGEventHandler::FGEventHandler() :
     idleHandler(0),
-    drawHandler(0),
-    windowResizeHandler(0),
     keyHandler(0),
     mouseClickHandler(0),
     mouseMotionHandler(0),
@@ -233,8 +232,8 @@ bool FGEventHandler::handle(const osgGA::GUIEventAdapter& ea,
         return true;
     case osgGA::GUIEventAdapter::RESIZE:
         CameraGroup::getDefault()->resized();
-        if (resizable && windowResizeHandler)
-            (*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
+        if (resizable)
+          globals->get_renderer()->resize(ea.getWindowWidth(), ea.getWindowHeight());
         return true;
      case osgGA::GUIEventAdapter::CLOSE_WINDOW:
     case osgGA::GUIEventAdapter::QUIT_APPLICATION:
diff --git a/src/Main/FGEventHandler.hxx b/src/Main/FGEventHandler.hxx
index 652b2b74d..4be0caf21 100644
--- a/src/Main/FGEventHandler.hxx
+++ b/src/Main/FGEventHandler.hxx
@@ -34,26 +34,6 @@ public:
 	    return idleHandler;
 	}
 
-    void setDrawHandler(fgDrawHandler drawHandler)
-	{
-	    this->drawHandler = drawHandler;
-	}
-
-    fgDrawHandler getDrawHandler() const
-	{
-	    return drawHandler;
-	}
-
-    void setWindowResizeHandler(fgWindowResizeHandler windowResizeHandler)
-	{
-	    this->windowResizeHandler = windowResizeHandler;
-	}
-    
-    fgWindowResizeHandler getWindowResizeHandler() const
-	{
-	    return windowResizeHandler;
-	}
-
     void setKeyHandler(fgKeyHandler keyHandler)
 	{
 	    this->keyHandler = keyHandler;
@@ -103,8 +83,6 @@ public:
 protected:
     osg::ref_ptr<osg::Node> _node;
     fgIdleHandler idleHandler;
-    fgDrawHandler drawHandler;
-    fgWindowResizeHandler windowResizeHandler;
     fgKeyHandler keyHandler;
     fgMouseClickHandler mouseClickHandler;
     fgMouseMotionHandler mouseMotionHandler;
diff --git a/src/Main/fg_os_common.cxx b/src/Main/fg_os_common.cxx
index 1df935139..cba760bb9 100644
--- a/src/Main/fg_os_common.cxx
+++ b/src/Main/fg_os_common.cxx
@@ -39,16 +39,6 @@ void fgRegisterIdleHandler(fgIdleHandler func)
     globals->get_renderer()->getEventHandler()->setIdleHandler(func);
 }
 
-void fgRegisterDrawHandler(fgDrawHandler func)
-{
-    globals->get_renderer()->getEventHandler()->setDrawHandler(func);
-}
-
-void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
-{
-    globals->get_renderer()->getEventHandler()->setWindowResizeHandler(func);
-}
-
 void fgRegisterKeyHandler(fgKeyHandler func)
 {
     globals->get_renderer()->getEventHandler()->setKeyHandler(func);
diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx
index 357661be7..764f90735 100644
--- a/src/Main/fg_os_osgviewer.cxx
+++ b/src/Main/fg_os_osgviewer.cxx
@@ -279,11 +279,9 @@ int fgOSMainLoop()
         viewer->realize();
     while (!viewer->done()) {
         fgIdleHandler idleFunc = manipulator->getIdleHandler();
-        fgDrawHandler drawFunc = manipulator->getDrawHandler();
         if (idleFunc)
             (*idleFunc)();
-        if (drawFunc)
-            (*drawFunc)();
+        globals->get_renderer()->update(true);
         viewer->frame();
     }
     
diff --git a/src/Main/main.cxx b/src/Main/main.cxx
index 6fa94dc9b..9a40613a3 100644
--- a/src/Main/main.cxx
+++ b/src/Main/main.cxx
@@ -551,11 +551,6 @@ static void fgIdleFunction ( void ) {
     }
 }
 
-static void fgWinResizeFunction(int width, int height)
-{
-    globals->get_renderer()->resize(width, height);
-}
-
 static void upper_case_property(const char *name)
 {
     using namespace simgear;
@@ -646,9 +641,7 @@ int fgMainInit( int argc, char **argv ) {
     fgOSInit(&argc, argv);
     _bootstrap_OSInit++;
 
-    fgRegisterWindowResizeHandler( &fgWinResizeFunction );
     fgRegisterIdleHandler( &fgIdleFunction );
-    fgRegisterDrawHandler( &FGRenderer::update );
 
     // Initialize sockets (WinSock needs this)
     simgear::Socket::initSockets();
diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx
index 3d40cf4c1..6aa796d69 100644
--- a/src/Main/renderer.cxx
+++ b/src/Main/renderer.cxx
@@ -595,12 +595,6 @@ FGRenderer::setupView( void )
     stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
 }
 
-void
-FGRenderer::update()
-{
-    globals->get_renderer()->update(true);
-}
-
 // Update all Visuals (redraws anything graphics related)
 void
 FGRenderer::update( bool refresh_camera_settings ) {
diff --git a/src/Main/renderer.hxx b/src/Main/renderer.hxx
index 3f045fe0c..67b9ff926 100644
--- a/src/Main/renderer.hxx
+++ b/src/Main/renderer.hxx
@@ -55,8 +55,7 @@ public:
     // touch window or camera settings.  This is useful for the tiled
     // renderer which needs to set the view frustum itself.
     void update( bool refresh_camera_settings);
-    static void update();
-
+  
     /** Just pick into the scene and return the pick callbacks on the way ...
      */
     bool pick( std::vector<SGSceneryPick>& pickList,

From 5a17ccf9eb7f76ef830fc364ee242c6fec3bda40 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Mon, 19 Sep 2011 09:00:23 +0100
Subject: [PATCH 48/85] Push aspect-ratio handling into CameraGroup, so
 renderer doesn't need to resize viewports each update.

---
 src/GUI/gui_funcs.cxx        |  2 +-
 src/Main/CameraGroup.cxx     | 16 +++++++++++++++
 src/Main/CameraGroup.hxx     |  5 +++++
 src/Main/fg_os_osgviewer.cxx |  2 +-
 src/Main/renderer.cxx        | 38 ++++--------------------------------
 src/Main/renderer.hxx        |  5 +----
 src/Main/viewer.cxx          | 20 ++++++++++++-------
 src/Main/viewer.hxx          | 10 +---------
 8 files changed, 42 insertions(+), 56 deletions(-)

diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx
index 9713b45c6..538eb755d 100644
--- a/src/GUI/gui_funcs.cxx
+++ b/src/GUI/gui_funcs.cxx
@@ -322,7 +322,7 @@ void fgHiResDump()
         int curColumn = trGet(tr, TR_CURRENT_COLUMN);
         // int curRow =  trGet(tr, TR_CURRENT_ROW);
 
-        renderer->update( false );
+        renderer->update();
         // OSGFIXME
 //         if ( do_hud )
 //             fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx
index 78a27891b..3e70e9fe1 100644
--- a/src/Main/CameraGroup.cxx
+++ b/src/Main/CameraGroup.cxx
@@ -263,6 +263,22 @@ void CameraGroup::setCameraParameters(float vfov, float aspectRatio)
                                                1.0f / aspectRatio,
                                                _zNear, _zFar);
 }
+    
+double CameraGroup::getMasterAspectRatio() const
+{
+    if (_cameras.empty())
+        return 0.0;
+    
+    const CameraInfo* info = _cameras.front();
+    
+    const osg::Viewport* viewport = info->camera->getViewport();
+    if (!viewport) {
+        return 0.0;
+    }
+    
+    return static_cast<double>(viewport->height()) / viewport->width();
+}
+    
 }
 
 namespace
diff --git a/src/Main/CameraGroup.hxx b/src/Main/CameraGroup.hxx
index 1e18e28e1..e0808ce47 100644
--- a/src/Main/CameraGroup.hxx
+++ b/src/Main/CameraGroup.hxx
@@ -183,6 +183,11 @@ public:
 
     void buildDistortionCamera(const SGPropertyNode* psNode,
                                osg::Camera* camera);
+  
+    /**
+     * get aspect ratio of master camera's viewport
+     */
+    double getMasterAspectRatio() const;
 protected:
     CameraList _cameras;
     osg::ref_ptr<osgViewer::Viewer> _viewer;
diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx
index 764f90735..6952195f5 100644
--- a/src/Main/fg_os_osgviewer.cxx
+++ b/src/Main/fg_os_osgviewer.cxx
@@ -281,7 +281,7 @@ int fgOSMainLoop()
         fgIdleHandler idleFunc = manipulator->getIdleHandler();
         if (idleFunc)
             (*idleFunc)();
-        globals->get_renderer()->update(true);
+        globals->get_renderer()->update();
         viewer->frame();
     }
     
diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx
index 6aa796d69..57980c785 100644
--- a/src/Main/renderer.cxx
+++ b/src/Main/renderer.cxx
@@ -597,7 +597,7 @@ FGRenderer::setupView( void )
 
 // Update all Visuals (redraws anything graphics related)
 void
-FGRenderer::update( bool refresh_camera_settings ) {
+FGRenderer::update( ) {
     if (!(_scenery_loaded->getBoolValue() || 
            _scenery_override->getBoolValue()))
     {
@@ -649,12 +649,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
     FGViewer *current__view = globals->get_current_view();
     // Force update of center dependent values ...
     current__view->set_dirty();
-
-    if ( refresh_camera_settings ) {
-        // update view port
-        resize( _xsize->getIntValue(),
-                _ysize->getIntValue() );
-    }
+  
     osg::Camera *camera = viewer->getCamera();
 
     bool skyblend = _skyblend->getBoolValue();
@@ -771,22 +766,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
     CameraGroup::getDefault()->setCameraCullMasks(cullMask);
 }
 
-
-
-// options.cxx needs to see this for toggle_panel()
-// Handle new window size or exposure
 void
-FGRenderer::resize( int width, int height ) {
-
-// the following breaks aspect-ratio of the main 3D scenery window when 2D panels are moved
-// in y direction - causing issues for aircraft with 2D panels (/sim/virtual_cockpit=false).
-// Disabling for now. Seems this useful for the pre-OSG time only.
-//    if ( (!_virtual_cockpit->getBoolValue())
-//         && fgPanelVisible() && idle_state == 1000 ) {
-//        view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
-//                             globals->get_current_panel()->getYOffset()) / 768.0);
-//    }
-
+FGRenderer::resize( int width, int height )
+{
     int curWidth = _xsize->getIntValue(),
         curHeight = _ysize->getIntValue();
     if ((curHeight != height) || (curWidth != width)) {
@@ -794,18 +776,6 @@ FGRenderer::resize( int width, int height ) {
         _xsize->setIntValue(width);
         _ysize->setIntValue(height);
     }
-    
-    // must set view aspect ratio each frame, or initial values are wrong.
-    // should probably be fixed 'smarter' during view setup.
-    double aspect = height / (double) width;
-
-    // for all views
-    FGViewMgr *viewmgr = globals->get_viewmgr();
-    if (viewmgr) {
-        for ( int i = 0; i < viewmgr->size(); ++i ) {
-            viewmgr->get_view(i)->set_aspect_ratio(aspect);
-        }
-    }
 }
 
 bool
diff --git a/src/Main/renderer.hxx b/src/Main/renderer.hxx
index 67b9ff926..84b03d87e 100644
--- a/src/Main/renderer.hxx
+++ b/src/Main/renderer.hxx
@@ -51,10 +51,7 @@ public:
 
     void resize(int width, int height );
 
-    // calling update( refresh_camera_settings = false ) will not
-    // touch window or camera settings.  This is useful for the tiled
-    // renderer which needs to set the view frustum itself.
-    void update( bool refresh_camera_settings);
+    void update();
   
     /** Just pick into the scene and return the pick callbacks on the way ...
      */
diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx
index 57e60f481..49d77cf5b 100644
--- a/src/Main/viewer.cxx
+++ b/src/Main/viewer.cxx
@@ -65,7 +65,6 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
     _pitch_deg(0),
     _heading_deg(0),
     _scaling_type(FG_SCALING_MAX),
-    _aspect_ratio(0),
     _cameraGroup(CameraGroup::getDefault())
 {
     _absolute_view_pos = SGVec3d(0, 0, 0);
@@ -102,7 +101,7 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
     } else {
       _fov_deg = 55;
     }
-    _aspect_ratio = 1;
+
     _aspect_ratio_multiplier = aspect_ratio_multiplier;
     _target_offset_m.x() = target_x_offset_m;
     _target_offset_m.y() = target_y_offset_m;
@@ -539,18 +538,19 @@ FGViewer::updateDampOutput(double dt)
 double
 FGViewer::get_h_fov()
 {
+    double aspectRatio = _cameraGroup->getMasterAspectRatio();
     switch (_scaling_type) {
     case FG_SCALING_WIDTH:  // h_fov == fov
 	return _fov_deg;
     case FG_SCALING_MAX:
-	if (_aspect_ratio < 1.0) {
+	if (aspectRatio < 1.0) {
 	    // h_fov == fov
 	    return _fov_deg;
 	} else {
 	    // v_fov == fov
 	    return
                 atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                     / (_aspect_ratio*_aspect_ratio_multiplier))
+                     / (aspectRatio*_aspect_ratio_multiplier))
                 * SG_RADIANS_TO_DEGREES * 2;
 	}
     default:
@@ -564,18 +564,19 @@ FGViewer::get_h_fov()
 double
 FGViewer::get_v_fov()
 {
+    double aspectRatio = _cameraGroup->getMasterAspectRatio();
     switch (_scaling_type) {
     case FG_SCALING_WIDTH:  // h_fov == fov
 	return 
             atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                 * (_aspect_ratio*_aspect_ratio_multiplier))
+                 * (aspectRatio*_aspect_ratio_multiplier))
             * SG_RADIANS_TO_DEGREES * 2;
     case FG_SCALING_MAX:
-	if (_aspect_ratio < 1.0) {
+	if (aspectRatio < 1.0) {
 	    // h_fov == fov
 	    return
                 atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                     * (_aspect_ratio*_aspect_ratio_multiplier))
+                     * (aspectRatio*_aspect_ratio_multiplier))
                 * SG_RADIANS_TO_DEGREES * 2;
 	} else {
 	    // v_fov == fov
@@ -671,3 +672,8 @@ FGViewer::update (double dt)
     _cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio());
   }
 }
+
+double FGViewer::get_aspect_ratio() const
+{
+    return _cameraGroup->getMasterAspectRatio();
+}
diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx
index 7cd58adae..ef5df5049 100644
--- a/src/Main/viewer.hxx
+++ b/src/Main/viewer.hxx
@@ -215,10 +215,7 @@ public:
     virtual double get_h_fov();    // Get horizontal fov, in degrees.
     virtual double get_v_fov();    // Get vertical fov, in degrees.
 
-    virtual void set_aspect_ratio( double r ) {
-	_aspect_ratio = r;
-    }
-    virtual double get_aspect_ratio() const { return _aspect_ratio; }
+    virtual double get_aspect_ratio() const;
 
     virtual void set_aspect_ratio_multiplier( double m ) {
 	_aspect_ratio_multiplier = m;
@@ -305,11 +302,6 @@ private:
     // the nominal field of view (angle, in degrees)
     double _fov_deg;
 
-    // Ratio of window width and height; height = width *
-    // aspect_ratio.  This value is automatically calculated based on
-    // window dimentions.
-    double _aspect_ratio;
-
     // default = 1.0, this value is user configurable and is
     // multiplied into the aspect_ratio to get the actual vertical fov
     double _aspect_ratio_multiplier;

From 3a757324884d1d6f89aa2c6f106fc22b99570df4 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 21 Sep 2011 18:00:57 +0100
Subject: [PATCH 49/85] If DBus is not found, disable event-input on Linux.

---
 CMakeLists.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index eb74dd462..e1a6dcc7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -134,6 +134,11 @@ if(EVENT_INPUT)
 
 	elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
         find_package(DBus)
+        if(NOT DBUS_FOUND)
+            message(WARNING "DBus not found, event input will be disabled")
+            set(EVENT_INPUT 0)
+        endif()
+        
 	else()
 		message(WARNING "event input is not supported on this platform yet")
 	endif()

From fcf03717774e32450c74b2d735eca9cb581f7e8f Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Wed, 21 Sep 2011 19:22:32 +0200
Subject: [PATCH 50/85] fix cmake conditional for event-input

---
 src/Input/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index 7fb713507..b38ffc8cb 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -3,7 +3,7 @@ include(FlightGearComponent)
 IF(APPLE)
 	set(EVENT_INPUT_SOURCES FGMacOSXEventInput.cxx)
 	set(EVENT_INPUT_HEADERS FGMacOSXEventInput.hxx)
-else(MSVC)
+elseif(MSVC)
     message(STATUS "EventInput not implemented for Windows yet")
 else()
 	set(EVENT_INPUT_SOURCES FGLinuxEventInput.cxx)

From 54aca561b63a406e6046c0438038cd00d9c9255a Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 21 Sep 2011 19:22:13 +0100
Subject: [PATCH 51/85] Fix JPEG-server builds.

---
 src/Main/renderer.cxx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx
index 57980c785..f4d6e0ad4 100644
--- a/src/Main/renderer.cxx
+++ b/src/Main/renderer.cxx
@@ -384,10 +384,17 @@ static osg::ref_ptr<osg::Group> mRealRoot = new osg::Group;
 
 static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
 
+#ifdef FG_JPEG_SERVER
+static void updateRenderer()
+{
+    globals->get_renderer()->update();
+}
+#endif
+
 FGRenderer::FGRenderer()
 {
 #ifdef FG_JPEG_SERVER
-   jpgRenderFrame = FGRenderer::update;
+   jpgRenderFrame = updateRenderer;
 #endif
    eventHandler = new FGEventHandler;
 }

From 5ae207c2fc90fc77307c31edd59104091f183965 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Thu, 22 Sep 2011 19:06:26 +0200
Subject: [PATCH 52/85] Prefetch a previously saved aircraft settings
 configuration file to retrieve aircraft usage and livery information.
 Fallback to default settings in aircraft-set.xml file if not found.

---
 src/Main/fg_init.cxx | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index 7f9bc87c2..6634b710d 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -907,15 +907,42 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
     
     int park_index = dcs->getNrOfParkings() - 1;
     bool succes;
-    double radius = fgGetDouble("/sim/atc/acradius");
-    //cerr << "Using radius " << radius << endl;
-    //cerr << "Checking parkpos comparison " << (bool) (parkpos == string("AVAILABLE")) << endl;
+    double radius = fgGetDouble("/sim/dimensions/radius-m");
     if ((parkpos == string("AVAILABLE")) && (radius > 0)) {
         double lat, lon, heading;
-        string fltType = fgGetString("/sim/atc/flight-type");
-        string airline = fgGetString("/sim/atc/airline" );
+        string fltType;
+        string acOperator;
+        SGPath acData;
+        try {
+            acData = fgGetString("/sim/fg-home");
+            acData.append("aircraft-data");
+            string acfile = fgGetString("/sim/aircraft") + string(".xml");
+            acData.append(acfile);
+            SGPropertyNode root;
+            readProperties(acData.str(), &root);
+            SGPropertyNode * node = root.getNode("sim");
+            fltType    = node->getStringValue("aircraft-class", "NONE"     );
+            acOperator = node->getStringValue("aircraft-operator", "NONE"     );
+        } catch (const sg_exception &) {
+            SG_LOG(SG_GENERAL, SG_INFO,
+                "Could not load aircraft aircrat type and operator information from: " << acData.str() << ". Using defaults");
+
+       // cout << path.str() << endl;
+        }
+        if (fltType.empty() || fltType == "NONE") {
+            SG_LOG(SG_GENERAL, SG_INFO,
+                "Aircraft type information not found in: " << acData.str() << ". Using default value");
+                fltType = fgGetString("/sim/aircraft-class"   );
+        }
+        if (acOperator.empty() || fltType == "NONE") {
+            SG_LOG(SG_GENERAL, SG_INFO,
+                "Aircraft type information not found in: " << acData.str() << ". Using default value");
+                acOperator = fgGetString("/sim/aircraft-class"   );
+        }
+
+        cerr << "Running aircraft " << fltType << " of livery " << acOperator << endl;
         string acType; // Currently not used by findAvailable parking, so safe to leave empty. 
-        succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, airline);
+        succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, acOperator);
         if (succes) {
             fgGetString("/sim/presets/parkpos");
             fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName());

From 152fec1cb638a18c8b3852e9992ca8987bb54052 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Thu, 22 Sep 2011 20:52:05 +0200
Subject: [PATCH 53/85] Patch by Torsten Dryer: Remove the Ugly global dialog
 variable and remove rwy as a member variable from the AIFlightPlan class.

---
 src/AIModel/AIFlightPlan.cxx             |  1 -
 src/AIModel/AIFlightPlan.hxx             |  1 -
 src/AIModel/AIFlightPlanCreate.cxx       | 20 ++++++++++++--------
 src/AIModel/AIFlightPlanCreateCruise.cxx |  3 ++-
 src/ATC/atc_mgr.cxx                      |  4 +---
 src/ATC/atc_mgr.hxx                      |  2 --
 src/ATC/atcdialog.cxx                    |  7 ++++---
 src/ATC/atcdialog.hxx                    | 16 ++++++++++++++--
 src/ATC/trafficcontrol.cxx               |  7 ++-----
 src/Airports/groundnetwork.cxx           |  2 +-
 10 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/src/AIModel/AIFlightPlan.cxx b/src/AIModel/AIFlightPlan.cxx
index e87d11530..5458b2ce4 100644
--- a/src/AIModel/AIFlightPlan.cxx
+++ b/src/AIModel/AIFlightPlan.cxx
@@ -71,7 +71,6 @@ bool FGAIWaypoint::contains(string target) {
 
 FGAIFlightPlan::FGAIFlightPlan() 
 {
-    rwy = 0;
     sid = 0;
     repeat = false;
     distance_to_go = 0;
diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx
index 624ea16a8..1b95cad47 100644
--- a/src/AIModel/AIFlightPlan.hxx
+++ b/src/AIModel/AIFlightPlan.hxx
@@ -166,7 +166,6 @@ public:
   FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
 
 private:
-  FGRunway* rwy;
   FGAIFlightPlan *sid;
   typedef std::vector <FGAIWaypoint*> wpt_vector_type;
   typedef wpt_vector_type::const_iterator wpt_vector_iterator;
diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx
index 3ed42fb89..d53dc4bd0 100644
--- a/src/AIModel/AIFlightPlanCreate.cxx
+++ b/src/AIModel/AIFlightPlanCreate.cxx
@@ -226,7 +226,8 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
         apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
                                             depHeading);
     }
-    rwy = apt->getRunwayByIdent(activeRunway);
+    FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
+    assert( rwy != NULL );
     SGGeod runwayTakeoff = rwy->pointOnCenterline(5.0);
 
     FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
@@ -456,9 +457,8 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
         apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
                                             heading);
     }
-    rwy = apt->getRunwayByIdent(activeRunway);
-
-
+    FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
+    assert( rwy != NULL );
 
     double airportElev = apt->getElevation();
     
@@ -513,7 +513,6 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
         double heading = ac->getTrafficRef()->getCourse();
         apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
                                             heading);
-        rwy = apt->getRunwayByIdent(activeRunway);
     }
     if (sid) {
         for (wpt_vector_iterator i = sid->getFirstWayPoint();
@@ -522,6 +521,9 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
             //cerr << " Cloning waypoint " << endl;
         }
     } else {
+        FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
+        assert( rwy != NULL );
+
         SGGeod climb1 = rwy->pointOnCenterline(10 * SG_NM_TO_METER);
         wpt = createInAir(ac, "10000ft climb", climb1, vClimb, 10000);
         wpt->setGear_down(true);
@@ -560,9 +562,8 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
     double heading = ac->getTrafficRef()->getCourse();
     apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway,
                                         heading);
-    rwy = apt->getRunwayByIdent(activeRunway);
-
-
+    FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
+    assert( rwy != NULL );
 
     // Create a slow descent path that ends 250 lateral to the runway.
     double initialTurnRadius = getTurnRadius(vDescent, true);
@@ -859,6 +860,9 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
     char buffer[12];
     for (int i = 1; i < 10; i++) {
         snprintf(buffer, 12, "wpt%d", i);
+        FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
+        assert( rwy != NULL );
+
         coord = rwy->pointOnCenterline(rwy->lengthM() * (i / 10.0));
         wpt = createOnGround(ac, buffer, coord, aptElev, (vTouchdown / i));
         wpt->setCrossat(apt->getElevation());
diff --git a/src/AIModel/AIFlightPlanCreateCruise.cxx b/src/AIModel/AIFlightPlanCreateCruise.cxx
index 0e8a97495..898e7ef5d 100644
--- a/src/AIModel/AIFlightPlanCreateCruise.cxx
+++ b/src/AIModel/AIFlightPlanCreateCruise.cxx
@@ -299,7 +299,8 @@ bool FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport
   string rwyClass = getRunwayClassFromTrafficType(fltType);
   double heading = ac->getTrafficRef()->getCourse();
   arr->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway, heading);
-  rwy = arr->getRunwayByIdent(activeRunway);
+  FGRunway* rwy = arr->getRunwayByIdent(activeRunway);
+  assert( rwy != NULL );
   // begin descent 110km out
   SGGeod beginDescentPoint     = rwy->pointOnCenterline(0);
   SGGeod secondaryDescentPoint = rwy->pointOnCenterline(-10000);
diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index ef17774c2..0345c2509 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -46,8 +46,6 @@ FGATCManager::~FGATCManager() {
 
 void FGATCManager::init() {
     SGSubsystem::init();
-    currentATCDialog = new FGATCDialogNew;
-    currentATCDialog->init();
 
     int leg = 0;
 
@@ -219,7 +217,7 @@ void FGATCManager::update ( double time ) {
     ai_ac.setSpeed(speed);
     ai_ac.update(time);
     controller = ai_ac.getATCController();
-    currentATCDialog->update(time);
+    FGATCDialogNew::instance()->update(time);
     if (controller) {
        //cerr << "name of previous waypoint : " << fp->getPreviousWaypoint()->getName() << endl;
 
diff --git a/src/ATC/atc_mgr.hxx b/src/ATC/atc_mgr.hxx
index 38a2def72..0d9efa730 100644
--- a/src/ATC/atc_mgr.hxx
+++ b/src/ATC/atc_mgr.hxx
@@ -50,7 +50,6 @@ private:
   AtcVec activeStations;
   FGAIAircraft ai_ac;
   FGATCController *controller, *prevController; // The ATC controller that is responsible for the user's aircraft. 
-  //FGATCDialogNew dialog;  // note that this variable should really replace the ugly global "currentATCDialog();
   bool networkVisible;
   bool initSucceeded;
 
@@ -60,7 +59,6 @@ public:
   void init();
   void addController(FGATCController *controller);
   void update(double time);
-  FGATCDialogNew * getATCDialog() {  return currentATCDialog; };
 };
   
 #endif // _ATC_MRG_HXX_
\ No newline at end of file
diff --git a/src/ATC/atcdialog.cxx b/src/ATC/atcdialog.cxx
index eb9533fbb..d2aad836e 100644
--- a/src/ATC/atcdialog.cxx
+++ b/src/ATC/atcdialog.cxx
@@ -35,11 +35,12 @@
 
 FGATCDialogNew *currentATCDialog;
 
-static bool doATCDialog(const SGPropertyNode* arg) {
+/*static bool doATCDialog(const SGPropertyNode* arg) {
         //cerr << "Running doATCDialog" << endl;
 	currentATCDialog->PopupDialog();
 	return(true);
-}
+}*/
+FGATCDialogNew * FGATCDialogNew::_instance = NULL;
 
 FGATCDialogNew::FGATCDialogNew()
 {
@@ -54,7 +55,7 @@ FGATCDialogNew::~FGATCDialogNew()
 
 void FGATCDialogNew::init() {
 	// Add ATC-dialog to the command list
-	globals->get_commands()->addCommand("ATC-dialog", doATCDialog);
+    globals->get_commands()->addCommand("ATC-dialog", FGATCDialogNew::popup );
 	// Add ATC-freq-search to the command list
 	//globals->get_commands()->addCommand("ATC-freq-search", do_ATC_freq_search);
 
diff --git a/src/ATC/atcdialog.hxx b/src/ATC/atcdialog.hxx
index f52b5b4f1..2e1c4ada6 100644
--- a/src/ATC/atcdialog.hxx
+++ b/src/ATC/atcdialog.hxx
@@ -43,13 +43,14 @@
 typedef vector<string> StringVec;
 typedef vector<string>:: iterator StringVecIterator;
 
-static bool doATCDialog(const SGPropertyNode* arg);
 
 class FGATCDialogNew {
 private:
      NewGUI *_gui;
      bool dialogVisible;
      StringVec commands;
+
+     static FGATCDialogNew *_instance;
 public:
 
     FGATCDialogNew();
@@ -61,8 +62,19 @@ public:
     void PopupDialog();
     void addEntry(int, string);
     void removeEntry(int);
+
+    static bool popup( const SGPropertyNode * ) {
+        instance()->PopupDialog();
+        return true;
+    }
+
+    inline static FGATCDialogNew * instance() {
+        if( _instance != NULL ) return _instance;
+        _instance = new FGATCDialogNew();
+        _instance->init();
+        return _instance;
+    }
 };
 
-extern FGATCDialogNew *currentATCDialog;
 
 #endif // _ATC_DIALOG_HXX_
\ No newline at end of file
diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx
index dc0552fe7..f2802d3b7 100644
--- a/src/ATC/trafficcontrol.cxx
+++ b/src/ATC/trafficcontrol.cxx
@@ -731,9 +731,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
             }
         }
     } else {
-        FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-        atc->getATCDialog()->addEntry(1, text);
-        
+        FGATCDialogNew::instance()->addEntry(1, text);
     }
 }
 
@@ -1151,8 +1149,7 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
                 trans_num->setIntValue(-1);
                  // PopupCallback(n);
                  //cerr << "Selected transmission message " << n << endl;
-                 FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-                 atc->getATCDialog()->removeEntry(1);
+                 FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), msgId, msgDir, false);
diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx
index 0da6af35c..3a3c6d714 100644
--- a/src/Airports/groundnetwork.cxx
+++ b/src/Airports/groundnetwork.cxx
@@ -679,7 +679,7 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic
                  // PopupCallback(n);
                  //cerr << "Selected transmission message " << n << endl;
                  FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-                 atc->getATCDialog()->removeEntry(1);
+                 FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), msgId, msgDir, false);

From 0fca002ab6c79e9c763e73221eb948eb09be3974 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Thu, 22 Sep 2011 21:38:37 +0200
Subject: [PATCH 54/85] Bugfix: Retrieval of the next radio frequency was
 broken. Contributed by Adrian Musceac.

---
 src/Airports/dynamics.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx
index c42635f4a..293d2ff6a 100644
--- a/src/Airports/dynamics.cxx
+++ b/src/Airports/dynamics.cxx
@@ -508,7 +508,7 @@ int FGAirportDynamics::getGroundFrequency(unsigned leg)
 
     if ((freqGround.size() < leg) && (leg > 0)) {
         groundFreq =
-            (freqGround.size() <
+            (freqGround.size() <=
              (leg - 1)) ? freqGround[freqGround.size() -
                                      1] : freqGround[leg - 1];
     }

From b482188848a193133afb9503f02cdb0983f79a3a Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Thu, 22 Sep 2011 22:08:20 +0200
Subject: [PATCH 55/85] Whoops, lazy copy/paste job.

---
 src/Main/fg_init.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index 6634b710d..88ea231fa 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -936,8 +936,8 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
         }
         if (acOperator.empty() || fltType == "NONE") {
             SG_LOG(SG_GENERAL, SG_INFO,
-                "Aircraft type information not found in: " << acData.str() << ". Using default value");
-                acOperator = fgGetString("/sim/aircraft-class"   );
+                "Aircraft operator information not found in: " << acData.str() << ". Using default value");
+                acOperator = fgGetString("/sim/aircraft-operator"   );
         }
 
         cerr << "Running aircraft " << fltType << " of livery " << acOperator << endl;

From 3bf8b9d91f9317afbb067b39a7956b38d1f71f5f Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sat, 24 Sep 2011 10:03:00 +0200
Subject: [PATCH 56/85] automake: Add missing GL and z libs to fgpanel.

---
 utils/fgpanel/Makefile.am | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/utils/fgpanel/Makefile.am b/utils/fgpanel/Makefile.am
index df6b6dde0..2057622cc 100644
--- a/utils/fgpanel/Makefile.am
+++ b/utils/fgpanel/Makefile.am
@@ -16,7 +16,7 @@ fgpanel_SOURCES = main.cxx \
 #LIBS =
 
 fgpanel_LDADD = \
-	-lGLU -lglut -lsgmath -lsgprops -lsgio -lsgdebug -lsgmisc -lsgstructure -lsgxml -lsgtiming \
+	-lGLU -lGL -lglut -lsgmath -lsgprops -lsgio -lsgdebug -lsgmisc -lsgstructure -lsgxml -lsgtiming \
 	-lplibpu -lplibfnt -lplibul -lsgthreads \
-	-lrt -lpng
+	-lz -lrt -lpng
 endif

From 1df7b9cdc243d1941047292baf37e5b18d8299e3 Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Mon, 26 Sep 2011 09:07:59 +0200
Subject: [PATCH 57/85] JSBSim fixes.

---
 src/FDM/JSBSim/FGFDMExec.cpp                           |  9 ++++++---
 src/FDM/JSBSim/models/FGFCS.cpp                        |  4 +++-
 src/FDM/JSBSim/models/FGOutput.cpp                     |  8 ++++++--
 .../JSBSim/models/atmosphere/FGStandardAtmosphere.cpp  |  4 ++--
 .../JSBSim/models/atmosphere/FGStandardAtmosphere.h    | 10 ++++++----
 src/FDM/JSBSim/models/atmosphere/FGWinds.cpp           |  5 +++++
 src/FDM/JSBSim/models/propulsion/FGPiston.cpp          |  9 +++++----
 src/FDM/JSBSim/models/propulsion/FGPropeller.cpp       |  4 +++-
 src/FDM/JSBSim/models/propulsion/FGPropeller.h         | 10 ++++++++--
 src/FDM/JSBSim/models/propulsion/FGRotor.cpp           |  8 ++++----
 src/FDM/JSBSim/models/propulsion/FGRotor.h             |  8 ++++----
 src/FDM/JSBSim/models/propulsion/FGTank.cpp            |  4 ++--
 src/FDM/JSBSim/models/propulsion/FGTank.h              |  4 ++--
 src/FDM/JSBSim/models/propulsion/FGThruster.h          |  6 ++++--
 src/FDM/JSBSim/models/propulsion/FGTurbine.cpp         |  3 ++-
 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp       |  6 ++++--
 16 files changed, 66 insertions(+), 36 deletions(-)
 mode change 100644 => 100755 src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp

diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp
index 8d29a688f..87ee94dad 100644
--- a/src/FDM/JSBSim/FGFDMExec.cpp
+++ b/src/FDM/JSBSim/FGFDMExec.cpp
@@ -70,7 +70,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.114 2011/09/11 11:36:04 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.115 2011/09/25 11:56:00 bcoconni Exp $";
 static const char *IdHdr = ID_FDMEXEC;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -564,8 +564,8 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC)
   LoadInputs(eAtmosphere);
   Atmosphere->Run(false);
   Winds->SetWindNED( FGIC->GetWindNFpsIC(),
-                          FGIC->GetWindEFpsIC(),
-                          FGIC->GetWindDFpsIC() );
+                     FGIC->GetWindEFpsIC(),
+                     FGIC->GetWindDFpsIC() );
   Auxiliary->Run(false);
 }
 
@@ -1152,11 +1152,14 @@ bool FGFDMExec::SetOutputDirectives(const string& fname)
   result = Output->Load(0);
 
   if (result) {
+    Output->Run(holding);
     Outputs.push_back(Output);
     typedef double (FGOutput::*iOPMF)(void) const;
     string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
     instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
   }
+  else
+    delete Output;
 
   return result;
 }
diff --git a/src/FDM/JSBSim/models/FGFCS.cpp b/src/FDM/JSBSim/models/FGFCS.cpp
index d781f54f1..3f659831f 100644
--- a/src/FDM/JSBSim/models/FGFCS.cpp
+++ b/src/FDM/JSBSim/models/FGFCS.cpp
@@ -64,7 +64,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGFCS.cpp,v 1.76 2011/08/14 20:15:56 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFCS.cpp,v 1.77 2011/09/25 14:05:40 bcoconni Exp $";
 static const char *IdHdr = ID_FCS;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -665,6 +665,8 @@ bool FGFCS::Load(Element* el, SystemType systype)
     channel_element = document->FindNextElement("channel");
   }
 
+  PostLoad(document, PropertyManager);
+
   ResetParser();
 
   return true;
diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp
index aa30ad07a..46c9b15ce 100644
--- a/src/FDM/JSBSim/models/FGOutput.cpp
+++ b/src/FDM/JSBSim/models/FGOutput.cpp
@@ -77,7 +77,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGOutput.cpp,v 1.60 2011/09/11 11:36:04 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGOutput.cpp,v 1.62 2011/09/25 15:38:30 bcoconni Exp $";
 static const char *IdHdr = ID_OUTPUT;
 
 // (stolen from FGFS native_fdm.cxx)
@@ -1003,8 +1003,12 @@ bool FGOutput::Load(Element* element)
 
   if (!document) return false;
 
-  name = FDMExec->GetRootDir() + document->GetAttributeValue("name");
   SetType(document->GetAttributeValue("type"));
+
+  name = document->GetAttributeValue("name");
+  if (((Type == otCSV) || (Type == otTab)) && (name != "cout") && (name !="COUT"))
+    name = FDMExec->GetRootDir() + name;
+
   Port = document->GetAttributeValue("port");
   if (!Port.empty() && (Type == otSocket || Type == otFlightGear)) {
     port = atoi(Port.c_str());
diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
index e25a7138b..fd40e9004 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
@@ -50,7 +50,7 @@ INCLUDES
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.19 2011/09/11 11:36:04 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.20 2011/09/18 12:06:21 bcoconni Exp $";
 static const char *IdHdr = ID_STANDARDATMOSPHERE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -420,7 +420,7 @@ void FGStandardAtmosphere::bind(void)
                                     (PMF)&FGStandardAtmosphere::SetTemperatureBias);
   PropertyManager->Tie("atmosphere/SL-graded-delta-T", this, eRankine,
                                     (PMFi)&FGStandardAtmosphere::GetTemperatureDeltaGradient,
-									(PMF)&FGStandardAtmosphere::SetSLTemperatureGradedDelta);
+                                    (PMF)&FGStandardAtmosphere::SetSLTemperatureGradedDelta);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
index 380550ade..2e5c37676 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
+++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.15 2011/08/17 23:56:01 jberndt Exp $"
+#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.16 2011/09/18 12:06:21 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -93,7 +93,7 @@ consistently and accurately calculated.
 
   @author Jon Berndt
   @see "U.S. Standard Atmosphere, 1976", NASA TM-X-74335
-  @version $Id: FGStandardAtmosphere.h,v 1.15 2011/08/17 23:56:01 jberndt Exp $
+  @version $Id: FGStandardAtmosphere.h,v 1.16 2011/09/18 12:06:21 bcoconni Exp $
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -139,11 +139,13 @@ public:
   virtual double GetStdTemperatureRatio(double h) const { return GetStdTemperature(h)*rSLtemperature; }
 
   /// Returns the temperature bias over the sea level value in degrees Rankine.
-  virtual double GetTemperatureBias(eTemperature to) const {return TemperatureBias;}
+  virtual double GetTemperatureBias(eTemperature to) const
+  { if (to == eCelsius || to == eKelvin) return TemperatureBias/1.80; else return TemperatureBias; }
 
   /// Returns the temperature gradient to be applied on top of the standard
   /// temperature gradient.
-  virtual double GetTemperatureDeltaGradient() { return TemperatureDeltaGradient;}
+  virtual double GetTemperatureDeltaGradient(eTemperature to)
+  { if (to == eCelsius || to == eKelvin) return TemperatureDeltaGradient/1.80; else return TemperatureDeltaGradient; }
 
   /// Sets the Sea Level temperature, if it is to be different than the standard.
   /// This function will calculate a bias - a difference - from the standard
diff --git a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
index c24648e3a..e54c348ec 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
@@ -284,8 +284,13 @@ void FGWinds::Turbulence(double h)
     double
       T_V = in.totalDeltaT, // for compatibility of nomenclature
       sig_p = 1.9/sqrt(L_w*b_w)*sig_w, // Yeager1998, eq. (8)
+<<<<<<< FGWinds.cpp
+//    sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
+///   sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
+=======
       //sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
       //sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
+>>>>>>> 1.5
       L_p = sqrt(L_w*b_w)/2.6, // eq. (10)
       tau_u = L_u/in.V, // eq. (6)
       tau_w = L_w/in.V, // eq. (3)
diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
index c3cb90800..304c00971 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp
@@ -50,7 +50,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPiston.cpp,v 1.65 2011/09/11 12:06:54 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGPiston.cpp,v 1.67 2011/09/25 23:56:11 jentron Exp $";
 static const char *IdHdr = ID_PISTON;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -336,8 +336,6 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input
   PropertyManager->Tie(property_name, &BoostSpeed);
   property_name = base_property_name + "/cht-degF";
   PropertyManager->Tie(property_name, this, &FGPiston::getCylinderHeadTemp_degF);
-  property_name = base_property_name + "/engine-rpm";
-  PropertyManager->Tie(property_name, this, &FGPiston::getRPM);
   property_name = base_property_name + "/oil-temperature-degF";
   PropertyManager->Tie(property_name, this, &FGPiston::getOilTemp_degF);
   property_name = base_property_name + "/oil-pressure-psi";
@@ -436,7 +434,9 @@ void FGPiston::Calculate(void)
 
   RunPreFunctions();
 
-  RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
+/* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */
+  RPM = Thruster->GetEngineRPM();
+
   MeanPistonSpeed_fps =  ( RPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS
 
   IAS = in.Vc;
@@ -479,6 +479,7 @@ void FGPiston::Calculate(void)
 double FGPiston::CalcFuelNeed(void)
 {
   FuelExpended = FuelFlowRate * in.TotalDeltaT;
+  if (!Starved) FuelUsedLbs += FuelExpended; 
   return FuelExpended;
 }
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
index 411f12a65..ead7dec9b 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.37 2011/09/11 12:06:54 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.38 2011/09/24 14:26:46 jentron Exp $";
 static const char *IdHdr = ID_PROPELLER;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -147,6 +147,8 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
 
   string property_name, base_property_name;
   base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNum);
+  property_name = base_property_name + "/engine-rpm";
+  PropertyManager->Tie( property_name.c_str(), this, &FGPropeller::GetEngineRPM );
   property_name = base_property_name + "/advance-ratio";
   PropertyManager->Tie( property_name.c_str(), &J );
   property_name = base_property_name + "/blade-angle";
diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.h b/src/FDM/JSBSim/models/propulsion/FGPropeller.h
index 94fb454ec..6e918a4eb 100644
--- a/src/FDM/JSBSim/models/propulsion/FGPropeller.h
+++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.h
@@ -45,7 +45,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_PROPELLER "$Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $"
+#define ID_PROPELLER "$Id: FGPropeller.h,v 1.19 2011/09/24 14:26:46 jentron Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -142,7 +142,7 @@ CLASS DOCUMENTATION
     <li>Various NACA Technical Notes and Reports</li>
     </ul>
     @author Jon S. Berndt
-    @version $Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $
+    @version $Id: FGPropeller.h,v 1.19 2011/09/24 14:26:46 jentron Exp $
     @see FGEngine
     @see FGThruster
 */
@@ -171,6 +171,9 @@ public:
       @param rpm the rotational velocity of the propeller */
   void SetRPM(double rpm) {RPM = rpm;}
 
+  /** Sets the Revolutions Per Minute for the propeller using the engine gear ratio **/
+  void SetEngineRPM(double rpm) {RPM = rpm/GearRatio;}
+
   /// Returns true of this propeller is variable pitch
   bool IsVPitch(void) {return MaxPitch != MinPitch;}
 
@@ -209,6 +212,9 @@ public:
   /// Retrieves the RPMs of the propeller
   double GetRPM(void)     const { return RPM;           } 
 
+  /// Calculates the RPMs of the engine based on gear ratio
+  double GetEngineRPM(void)     const { return RPM * GearRatio;  } 
+
   /// Retrieves the propeller moment of inertia
   double GetIxx(void)           { return Ixx;           }
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
index 55a711cee..0a733fb83 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGRotor.cpp
@@ -55,7 +55,7 @@ using std::cout;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGRotor.cpp,v 1.16 2011/09/17 16:39:19 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGRotor.cpp,v 1.17 2011/09/24 14:26:46 jentron Exp $";
 static const char *IdHdr = ID_ROTOR;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -706,7 +706,7 @@ bool FGRotor::BindModel(void)
   property_name = base_property_name + "/rotor-rpm";
   PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetRPM );
 
-  property_name = base_property_name + "/x-engine-rpm"; // used for RPM eXchange
+  property_name = base_property_name + "/engine-rpm";
   PropertyManager->Tie( property_name.c_str(), this, &FGRotor::GetEngineRPM );
 
   property_name = base_property_name + "/rotor-thrust-lbs"; // might be redundant - check!
@@ -778,11 +778,11 @@ bool FGRotor::BindModel(void)
       ExtRPMsource = PropertyManager->GetNode(property_name, true);
     } else if (RPMdefinition >= 0 && RPMdefinition != EngineNum) {
       string ipn = CreateIndexedPropertyName("propulsion/engine", RPMdefinition);
-      property_name = ipn + "/x-engine-rpm";
+      property_name = ipn + "/engine-rpm";
       ExtRPMsource = PropertyManager->GetNode(property_name, false);
       if (! ExtRPMsource) {
         cerr << "# Warning: Engine number " << EngineNum << "." << endl;
-        cerr << "# No 'x-engine-rpm' property found for engine " << RPMdefinition << "." << endl;
+        cerr << "# No 'engine-rpm' property found for engine " << RPMdefinition << "." << endl;
         cerr << "# Please check order of engine definitons."  << endl;
       }
     } else {
diff --git a/src/FDM/JSBSim/models/propulsion/FGRotor.h b/src/FDM/JSBSim/models/propulsion/FGRotor.h
index 85d1b3e6e..9e0bb0511 100644
--- a/src/FDM/JSBSim/models/propulsion/FGRotor.h
+++ b/src/FDM/JSBSim/models/propulsion/FGRotor.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_ROTOR "$Id: FGRotor.h,v 1.10 2011/09/17 16:39:19 bcoconni Exp $"
+#define ID_ROTOR "$Id: FGRotor.h,v 1.11 2011/09/24 14:26:46 jentron Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -205,7 +205,7 @@ CLASS DOCUMENTATION
     </dl>
 
     @author Thomas Kreitler
-    @version $Id: FGRotor.h,v 1.10 2011/09/17 16:39:19 bcoconni Exp $
+    @version $Id: FGRotor.h,v 1.11 2011/09/24 14:26:46 jentron Exp $
   */
 
 
@@ -238,11 +238,11 @@ public:
 
   /// Retrieves the RPMs of the rotor.
   double GetRPM(void) const { return RPM; }
-  
-  // void   SetRPM(double rpm) { RPM = rpm; }
+  void   SetRPM(double rpm) { RPM = rpm; }
   
   /// Retrieves the RPMs of the Engine, as seen from this rotor.
   double GetEngineRPM(void) const { return GearRatio*RPM; } // bit of a hack.
+  void SetEngineRPM(double rpm) { RPM = rpm/GearRatio; } // bit of a hack.
   /// Tells the rotor's gear ratio, usually the engine asks for this.
   double GetGearRatio(void) { return GearRatio; }
   /// Retrieves the thrust of the rotor.
diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.cpp b/src/FDM/JSBSim/models/propulsion/FGTank.cpp
index a0417d540..718185a65 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTank.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTank.cpp
@@ -47,7 +47,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTank.cpp,v 1.31 2011/08/03 03:21:06 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTank.cpp,v 1.32 2011/09/18 13:04:34 bcoconni Exp $";
 static const char *IdHdr = ID_TANK;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -204,7 +204,7 @@ const FGColumnVector3 FGTank::GetXYZ(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-const double FGTank::GetXYZ(int idx)
+double FGTank::GetXYZ(int idx)
 {
   return vXYZ_drain(idx) + (Contents/Capacity)*(vXYZ(idx)-vXYZ_drain(idx));
 }
diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.h b/src/FDM/JSBSim/models/propulsion/FGTank.h
index dc929beb5..c5c97ce98 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTank.h
+++ b/src/FDM/JSBSim/models/propulsion/FGTank.h
@@ -52,7 +52,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_TANK "$Id: FGTank.h,v 1.24 2011/08/03 03:21:06 jberndt Exp $"
+#define ID_TANK "$Id: FGTank.h,v 1.25 2011/09/18 13:04:34 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -289,7 +289,7 @@ public:
   void   SetExternalFlow(double f) { ExternalFlow = f; }
 
   const FGColumnVector3 GetXYZ(void);
-  const double GetXYZ(int idx);
+  double GetXYZ(int idx);
 
   const GrainType GetGrainType(void) {return grainType;}
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGThruster.h b/src/FDM/JSBSim/models/propulsion/FGThruster.h
index 04313d797..92d76c949 100644
--- a/src/FDM/JSBSim/models/propulsion/FGThruster.h
+++ b/src/FDM/JSBSim/models/propulsion/FGThruster.h
@@ -46,7 +46,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_THRUSTER "$Id: FGThruster.h,v 1.17 2011/08/03 03:21:06 jberndt Exp $"
+#define ID_THRUSTER "$Id: FGThruster.h,v 1.18 2011/09/24 14:26:46 jentron Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -74,7 +74,7 @@ CLASS DOCUMENTATION
     1.57 (pi/2) results in no thrust at all.
  
     @author Jon Berndt
-    @version $Id: FGThruster.h,v 1.17 2011/08/03 03:21:06 jberndt Exp $
+    @version $Id: FGThruster.h,v 1.18 2011/09/24 14:26:46 jentron Exp $
     */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -98,6 +98,7 @@ public:
   }
   void SetName(string name) {Name = name;}
   virtual void SetRPM(double rpm) {};
+  virtual void SetEngineRPM(double rpm) {};
   virtual double GetPowerRequired(void) {return 0.0;}
   virtual void SetdeltaT(double dt) {deltaT = dt;}
   double GetThrust(void) const {return Thrust;}
@@ -108,6 +109,7 @@ public:
   double GetClutchCtrl(void) const { return ClutchCtrlNorm; }
   void SetClutchCtrl(double c) { ClutchCtrlNorm = c; }
   virtual double GetRPM(void) const { return 0.0; };
+  virtual double GetEngineRPM(void) const { return 0.0; };
   double GetGearRatio(void) {return GearRatio; }
   virtual string GetThrusterLabels(int id, string delimeter);
   virtual string GetThrusterValues(int id, string delimeter);
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
index 5b676ed8f..b5712ad26 100644
--- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
@@ -49,7 +49,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.35 2011/08/04 13:45:42 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.36 2011/09/25 23:56:11 jentron Exp $";
 static const char *IdHdr = ID_TURBINE;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -385,6 +385,7 @@ double FGTurbine::CalcFuelNeed(void)
 {
   FuelFlowRate = FuelFlow_pph / 3600.0; // Calculates flow in lbs/sec from lbs/hr
   FuelExpended = FuelFlowRate * in.TotalDeltaT;     // Calculates fuel expended in this time step
+  if (!Starved) FuelUsedLbs += FuelExpended; 
   return FuelExpended;
 }
 
diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
old mode 100644
new mode 100755
index 58188112a..c0bb27912
--- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
+++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp
@@ -53,7 +53,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.22 2011/08/04 13:45:42 jberndt Exp $";
+static const char *IdSrc = "$Id: FGTurboProp.cpp,v 1.24 2011/09/25 23:56:11 jentron Exp $";
 static const char *IdHdr = ID_TURBOPROP;
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -170,7 +170,8 @@ void FGTurboProp::Calculate(void)
 
   ThrottlePos = in.ThrottlePos[EngineNumber];
 
-  RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
+/* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */
+  RPM = Thruster->GetEngineRPM();
   if (thrusterType == FGThruster::ttPropeller) {
     ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]);
     ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]);
@@ -409,6 +410,7 @@ double FGTurboProp::CalcFuelNeed(void)
 {
   FuelFlowRate = FuelFlow_pph / 3600.0;
   FuelExpended = FuelFlowRate * in.TotalDeltaT;
+  if (!Starved) FuelUsedLbs += FuelExpended;
   return FuelExpended;
 }
 

From dbe150485884a287d24303ba46c05f595aa271f3 Mon Sep 17 00:00:00 2001
From: Erik Hofman <erik@ehofman.com>
Date: Mon, 26 Sep 2011 10:50:48 +0200
Subject: [PATCH 58/85] remove a cvs conflict

---
 src/FDM/JSBSim/models/atmosphere/FGWinds.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
index e54c348ec..c24648e3a 100644
--- a/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
+++ b/src/FDM/JSBSim/models/atmosphere/FGWinds.cpp
@@ -284,13 +284,8 @@ void FGWinds::Turbulence(double h)
     double
       T_V = in.totalDeltaT, // for compatibility of nomenclature
       sig_p = 1.9/sqrt(L_w*b_w)*sig_w, // Yeager1998, eq. (8)
-<<<<<<< FGWinds.cpp
-//    sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
-///   sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
-=======
       //sig_q = sqrt(M_PI/2/L_w/b_w), // eq. (14)
       //sig_r = sqrt(2*M_PI/3/L_w/b_w), // eq. (17)
->>>>>>> 1.5
       L_p = sqrt(L_w*b_w)/2.6, // eq. (10)
       tau_u = L_u/in.V, // eq. (6)
       tau_w = L_w/in.V, // eq. (3)

From 16a424ae9088027e21cef7a1f25ddda806f19ab8 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Mon, 26 Sep 2011 09:56:29 +0100
Subject: [PATCH 59/85] Disable event-input by default on Linux, since libHAL
 is causing build/deployment issues on some Linux distributions.

---
 CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e1a6dcc7c..41478041a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,7 +52,8 @@ endif()
 IF(APPLE)
     set(EVENT_INPUT_DEFAULT 1)
 elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
-    set(EVENT_INPUT_DEFAULT 1)
+    # disabled while DBus / HAL / udev issues are decided
+    #set(EVENT_INPUT_DEFAULT 1)
 endif()
 
 find_package(Git)

From ab238a116137649ad90c7e3cf5f13cfea14d8b7a Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Mon, 26 Sep 2011 13:33:06 +0100
Subject: [PATCH 60/85] Make the common case the default: no library suffix for
 RelWithDbg or MinSizeRel builds. Of course you can still specify a suffix if
 desired.

---
 CMakeLists.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41478041a..221efc659 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,8 +10,8 @@ project(FlightGear)
 
 set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d on windows")
 set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
-set(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "add a postfix, usually empty on windows")
-set(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, usually empty on windows")
+set(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
+set(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
 
 # read 'version' file into a variable (stripping any newlines or spaces)
 file(READ version versionFile)
@@ -79,6 +79,7 @@ option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient
 option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
 option(WITH_FGPANEL "Set to ON to build the fgpanel application" ON)
 
+
 if (MSVC)
   GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
   if (CMAKE_CL_64)

From dbda2fb95d6e18a3e25d07a6c4114e0c32442c73 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 28 Sep 2011 09:06:31 +0100
Subject: [PATCH 61/85] Switch ATCmgr comm station search to filter by range in
 cartesian, not geodetic, space, to avoid numerical instability with extremely
 distant stations.

---
 src/ATC/CMakeLists.txt    | 11 +++++++++--
 src/ATCDCL/ATCmgr.cxx     | 22 ++++++++++++++++------
 src/ATCDCL/CMakeLists.txt | 16 ++++++++++++++--
 3 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/src/ATC/CMakeLists.txt b/src/ATC/CMakeLists.txt
index e055ec6dd..f7dd1f2df 100644
--- a/src/ATC/CMakeLists.txt
+++ b/src/ATC/CMakeLists.txt
@@ -6,5 +6,12 @@ set(SOURCES
 	trafficcontrol.cxx
 	CommStation.cxx
 	)
-	
-flightgear_component(ATC "${SOURCES}")
+
+set(HEADERS
+	atc_mgr.hxx
+	atcdialog.hxx
+	trafficcontrol.hxx
+	CommStation.hxx
+	)
+    	
+flightgear_component(ATC "${SOURCES}" "${HEADERS}")
diff --git a/src/ATCDCL/ATCmgr.cxx b/src/ATCDCL/ATCmgr.cxx
index 7a3da5969..dc0901153 100644
--- a/src/ATCDCL/ATCmgr.cxx
+++ b/src/ATCDCL/ATCmgr.cxx
@@ -253,16 +253,26 @@ void FGATCMgr::FreqSearch(const string navcomm, const int unit) {
 
     class RangeFilter : public CommStation::Filter {
     public:
-        RangeFilter( const SGGeod & pos ) : CommStation::Filter(), _pos(pos) {}
-        virtual bool pass(FGPositioned* aPos) const {
+        RangeFilter( const SGGeod & pos ) : 
+          CommStation::Filter(), 
+          _cart(SGVec3d::fromGeod(pos)),
+          _pos(pos)
+        {}
+      
+        virtual bool pass(FGPositioned* aPos) const
+        {
             flightgear::CommStation * stn = dynamic_cast<flightgear::CommStation*>(aPos);
             if( NULL == stn ) return false;
-            double dist = SGGeodesy::distanceNm( stn->geod(), _pos );
-            // if range is not configured, assume at least 10NM range
-            // TODO: maybe ramp down range with proximity to ground?
-            return dist <= SGMiscd::max( stn->rangeNm(), 10.0 );
+          // do the range check in cartesian space, since the distances are potentially
+          // large enough that the geodetic functions become unstable
+          // (eg, station on opposite side of the planet)
+            double rangeM = SGMiscd::max( stn->rangeNm(), 10.0 ) * SG_NM_TO_METER;
+            double d2 = distSqr( aPos->cart(), _cart);
+          
+            return d2 <= (rangeM * rangeM);
         }
     private:
+        SGVec3d _cart;
         SGGeod _pos;
     };
 
diff --git a/src/ATCDCL/CMakeLists.txt b/src/ATCDCL/CMakeLists.txt
index d0dde266a..8f0363135 100644
--- a/src/ATCDCL/CMakeLists.txt
+++ b/src/ATCDCL/CMakeLists.txt
@@ -9,5 +9,17 @@ set(SOURCES
 	ATCutils.cxx
 	ATCProjection.cxx
 	)
-	
-flightgear_component(ATCDCL "${SOURCES}")
+
+set(HEADERS
+	ATC.hxx
+	atis.hxx
+	ATCDialogOld.hxx
+	ATCVoice.hxx
+	ATCmgr.hxx
+	ATCutils.hxx
+	ATCProjection.hxx
+	atis_lexicon.hxx
+	atis_remap.hxx
+	)
+    	
+flightgear_component(ATCDCL "${SOURCES}" "${HEADERS}")

From ede92fce54698f55ef02067a6170e0b60dbc0eed Mon Sep 17 00:00:00 2001
From: Christian Schmitt <chris@ilovelinux.de>
Date: Wed, 28 Sep 2011 10:03:23 +0200
Subject: [PATCH 62/85] Fix a segfault that became apparent with a 850 apt.dat
 file

---
 src/Airports/apt_loader.cxx | 41 +++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx
index 5698eb16b..eca0afb5c 100644
--- a/src/Airports/apt_loader.cxx
+++ b/src/Airports/apt_loader.cxx
@@ -478,25 +478,30 @@ private:
     int freqKhz = atoi(token[1].c_str());
     int rangeNm = 50;
     FGPositioned::Type ty;
-    switch (lineId) {
-    case 50:
-        ty = FGPositioned::FREQ_AWOS;
-        if (token[2] == "ATIS") {
-            ty = FGPositioned::FREQ_ATIS;
-        }
-        break;
-        
-    case 51:    ty = FGPositioned::FREQ_UNICOM; break;
-    case 52:    ty = FGPositioned::FREQ_CLEARANCE; break;
-    case 53:    ty = FGPositioned::FREQ_GROUND; break;
-    case 54:    ty = FGPositioned::FREQ_TOWER; break;
-    case 55:    
-    case 56:    ty = FGPositioned::FREQ_APP_DEP; break;   
-    default:
-        throw sg_range_exception("unupported apt.dat comm station type");
-    }
+    // Make sure we only pass on stations with at least a name
+    if (token.size() >2){
 
-    commStations.push_back(new flightgear::CommStation(token[2], ty, pos, rangeNm, freqKhz));
+        switch (lineId) {
+            case 50:
+                ty = FGPositioned::FREQ_AWOS;
+                if (token[2] == "ATIS") {
+                    ty = FGPositioned::FREQ_ATIS;
+                }
+                break;
+
+            case 51:    ty = FGPositioned::FREQ_UNICOM; break;
+            case 52:    ty = FGPositioned::FREQ_CLEARANCE; break;
+            case 53:    ty = FGPositioned::FREQ_GROUND; break;
+            case 54:    ty = FGPositioned::FREQ_TOWER; break;
+            case 55:
+            case 56:    ty = FGPositioned::FREQ_APP_DEP; break;
+            default:
+                throw sg_range_exception("unupported apt.dat comm station type");
+        }
+
+        commStations.push_back(new flightgear::CommStation(token[2], ty, pos, rangeNm, freqKhz));
+    }
+    else SG_LOG( SG_GENERAL, SG_DEBUG, "Found unnamed comm. Skipping: " << lineId);
   }
 
 };

From 478e771632328366e575ed5748e9fdc2be3a42be Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Thu, 29 Sep 2011 00:01:44 +0200
Subject: [PATCH 63/85] Add a localizer audio ident class

This will be needed soon in the new navradio code.
---
 src/Sound/audioident.cxx | 7 ++++++-
 src/Sound/audioident.hxx | 5 +++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/Sound/audioident.cxx b/src/Sound/audioident.cxx
index a09b68d80..782526c9b 100644
--- a/src/Sound/audioident.cxx
+++ b/src/Sound/audioident.cxx
@@ -135,7 +135,12 @@ VORAudioIdent::VORAudioIdent( const std::string & fx_name )
 //FIXME: LOCAudioIdent at approx 7wpm (ICAO Annex 10 - 3.1.3.9.4)
 // not less than six times per minute at approx equal intervals
 // frequency 1020+/-50Hz (3.1.3.9.2)
+LOCAudioIdent::LOCAudioIdent( const std::string & fx_name )
+: AudioIdent( fx_name, 10, FGMorse::LO_FREQUENCY )
+{
+}
+
 
 // FIXME: NDBAudioIdent at approx 7 wpm (ICAO ANNEX 10 - 3.4.5.1)
 // at least once every 10s (3.4.5.2.1)
-// frequency 1020+/-50Hz or 400+/-25Hz (3.4.5.4)
\ No newline at end of file
+// frequency 1020+/-50Hz or 400+/-25Hz (3.4.5.4)
diff --git a/src/Sound/audioident.hxx b/src/Sound/audioident.hxx
index 723ddd70d..3fcc7cd52 100644
--- a/src/Sound/audioident.hxx
+++ b/src/Sound/audioident.hxx
@@ -62,4 +62,9 @@ public:
     VORAudioIdent( const std::string & fx_name );
 };
 
+class LOCAudioIdent : public AudioIdent {
+public:
+    LOCAudioIdent( const std::string & fx_name );
+};
+
 #endif // _FGAUDIOIDENT_HXX

From be720b424a725bac3ad89b73d06763c37a8ea1f8 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Fri, 30 Sep 2011 22:20:00 +0200
Subject: [PATCH 64/85] fgpanel: fixed some error handling/setup issues -
 Provide error message when fgdata path is missing. - Exit game mode when
 closing/aborting program (show mouse cursor etc). - Support absolute paths
 for "--panel" parameter. - Don't crash when a font is missing.

---
 utils/fgpanel/FGGLApplication.cxx    |  2 ++
 utils/fgpanel/FGPanelApplication.cxx | 13 +++++++++++++
 utils/fgpanel/panel.cxx              |  5 +++++
 3 files changed, 20 insertions(+)

diff --git a/utils/fgpanel/FGGLApplication.cxx b/utils/fgpanel/FGGLApplication.cxx
index b0f58d250..2783737d9 100644
--- a/utils/fgpanel/FGGLApplication.cxx
+++ b/utils/fgpanel/FGGLApplication.cxx
@@ -56,6 +56,8 @@ FGGLApplication::FGGLApplication( const char * aName, int argc, char ** argv ) :
 
 FGGLApplication::~FGGLApplication()
 {
+    if (gameMode)
+        glutLeaveGameMode();
 }
 
 void FGGLApplication::DisplayCallback()
diff --git a/utils/fgpanel/FGPanelApplication.cxx b/utils/fgpanel/FGPanelApplication.cxx
index b58700477..cf4bbcca3 100644
--- a/utils/fgpanel/FGPanelApplication.cxx
+++ b/utils/fgpanel/FGPanelApplication.cxx
@@ -90,6 +90,15 @@ FGPanelApplication::FGPanelApplication( int argc, char ** argv ) :
     throw exception();
   }
 
+  // see if we got a valid fgdata path
+  SGPath BaseCheck(ApplicationProperties::root);
+  BaseCheck.append("version");
+  if (!BaseCheck.exists())
+  {
+      cerr << "Missing base package. Use --fg-root=path_to_fgdata" << endl; 
+      throw exception();
+  }
+
   try {
     SGPath tpath = ApplicationProperties::GetRootPath( panelFilename.c_str() );
     readProperties( tpath.str(), ApplicationProperties::Properties );
@@ -284,8 +293,12 @@ double ApplicationProperties::getDouble( const char * name, double def )
   if( n == NULL ) return def;
   return n->getDoubleValue();
 }
+
 SGPath ApplicationProperties::GetRootPath( const char * sub )
 {
+  SGPath subpath( sub );
+  if ( subpath.isAbsolute() )
+    return subpath;
   SGPath path( ApplicationProperties::root );
   if( sub != NULL )
     path.append( sub );
diff --git a/utils/fgpanel/panel.cxx b/utils/fgpanel/panel.cxx
index 70c40876b..06a6159db 100644
--- a/utils/fgpanel/panel.cxx
+++ b/utils/fgpanel/panel.cxx
@@ -804,6 +804,11 @@ FGTextLayer::draw ()
     transform();
 
     text_renderer.setFont(ApplicationProperties::fontCache.getTexFont(_font_name.c_str()));
+    if (!text_renderer.getFont())
+    {
+        SG_LOG( SG_COCKPIT, SG_ALERT, "Missing font file: " << _font_name );
+        return;
+    }
 
     text_renderer.setPointSize(_pointSize);
     text_renderer.begin();

From 90b35f2cbe11bc6a8e9716fc138ce7062a8ab150 Mon Sep 17 00:00:00 2001
From: Anders Gidenstam <anders@gidenstam.org>
Date: Fri, 30 Sep 2011 23:40:55 +0200
Subject: [PATCH 65/85] Added /scenery/events as a new MP enabled property for
 sharing scenery events.

---
 src/MultiPlayer/multiplaymgr.cxx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx
index c94ea8466..271b0acba 100644
--- a/src/MultiPlayer/multiplaymgr.cxx
+++ b/src/MultiPlayer/multiplaymgr.cxx
@@ -172,6 +172,8 @@ static const IdPropertyList sIdPropertyList[] = {
 
   {1300, "tanker", simgear::props::INT},
 
+  {1400, "scenery/events", simgear::props::STRING},
+
   {10001, "sim/multiplay/transmission-freq-hz",  simgear::props::STRING},
   {10002, "sim/multiplay/chat",  simgear::props::STRING},
 

From af1e00ac72623013416b743dc0f22342f5fa4c75 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sun, 18 Sep 2011 08:11:33 +0200
Subject: [PATCH 66/85] clouds: remove unused bump mapping flag.

---
 src/Main/main.cxx | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/Main/main.cxx b/src/Main/main.cxx
index e16a68656..79fe251de 100644
--- a/src/Main/main.cxx
+++ b/src/Main/main.cxx
@@ -132,7 +132,6 @@ static void fgMainLoop( void ) {
         = fgGetNode("/sim/timing-statistics/min-time-ms", true);
 
     frame_signal->fireValueChanged();
-    SGCloudLayer::enable_bump_mapping = fgGetBool("/sim/rendering/bump-mapping");
     
     SG_LOG( SG_GENERAL, SG_DEBUG, "Running Main Loop");
     SG_LOG( SG_GENERAL, SG_DEBUG, "======= ==== ====");

From 978a577ea2091106b59b9d039571d96037707772 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sat, 1 Oct 2011 09:50:34 +0200
Subject: [PATCH 67/85] Ugly workaround for a crash on exit with multiple
 screens

---
 src/GUI/new_gui.cxx | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx
index 5d52b1c1d..ce4c7237d 100644
--- a/src/GUI/new_gui.cxx
+++ b/src/GUI/new_gui.cxx
@@ -22,6 +22,10 @@
 
 #include <Main/fg_props.hxx>
 
+#ifndef _WIN32
+#include "GL/glx.h"
+#endif
+
 #include "menubar.hxx"
 #include "dialog.hxx"
 
@@ -417,6 +421,11 @@ FGFontCache::FGFontCache() :
 
 FGFontCache::~FGFontCache()
 {
+#ifndef _WIN32
+   // Ugly workaround for a crash on exit with multiple screens configured
+   if (!glXGetCurrentContext())
+      return;
+#endif
    PuFontMap::iterator it, end = _puFonts.end();
    for (it = _puFonts.begin(); it != end; ++it)
        delete it->second;

From 283b26114c2341184965887c1cf1c4189b0166b1 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 1 Oct 2011 10:05:01 +0100
Subject: [PATCH 68/85] Fix glx shutdown to only apply on Unix & !Mac (but we
 should really add a proper ifdef for GLX)

---
 src/GUI/new_gui.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx
index ce4c7237d..b8834fdca 100644
--- a/src/GUI/new_gui.cxx
+++ b/src/GUI/new_gui.cxx
@@ -22,7 +22,7 @@
 
 #include <Main/fg_props.hxx>
 
-#ifndef _WIN32
+#if defined(SG_UNIX) && !defined(SG_MAC) 
 #include "GL/glx.h"
 #endif
 
@@ -421,7 +421,7 @@ FGFontCache::FGFontCache() :
 
 FGFontCache::~FGFontCache()
 {
-#ifndef _WIN32
+#if defined(SG_UNIX) && !defined(SG_MAC) 
    // Ugly workaround for a crash on exit with multiple screens configured
    if (!glXGetCurrentContext())
       return;

From 7645dd3a1d0b8d5e2e3a1fb33a51185f32e23739 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sat, 1 Oct 2011 18:37:55 +0200
Subject: [PATCH 69/85] hla: make use of createJoin/resignDestroy.

---
 src/Network/HLA/hla.cxx | 42 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx
index 8d6b696a8..f71446a67 100644
--- a/src/Network/HLA/hla.cxx
+++ b/src/Network/HLA/hla.cxx
@@ -920,30 +920,28 @@ FGHLA::open()
     // We need that to communicate to the rti
     switch (configReader.getRTIVersion()) {
     case RTI13:
-        if (!_hlaFederate->connect(simgear::HLAFederate::RTI13, configReader.getRTIArguments())) {
-            SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI13 federation.");
-            return false;
-        }
+        _hlaFederate->setVersion(simgear::HLAFederate::RTI13);
         break;
     case RTI1516:
-        if (!_hlaFederate->connect(simgear::HLAFederate::RTI1516, configReader.getRTIArguments())) {
-            SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI1516 federation.");
-            return false;
-        }
+        _hlaFederate->setVersion(simgear::HLAFederate::RTI1516);
         break;
     case RTI1516E:
-        if (!_hlaFederate->connect(simgear::HLAFederate::RTI1516E, configReader.getRTIArguments())) {
-            SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI1516E federation.");
-            return false;
-        }
+        _hlaFederate->setVersion(simgear::HLAFederate::RTI1516E);
         break;
     }
+    _hlaFederate->setConnectArguments(configReader.getRTIArguments());
+    _hlaFederate->setFederationExecutionName(_federation);
+    _hlaFederate->setFederationObjectModel(objectModel);
+    _hlaFederate->setFederateType(_federate);
 
-    // Try to create a new federation execution
-    _hlaFederate->createFederationExecution(_federation, objectModel);
+    // Now that it is paramtrized, connect
+    if (!_hlaFederate->connect()) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not connect to rti.");
+        return false;
+    }
 
-    // Try to join
-    if (!_hlaFederate->join(_federate, _federation)) {
+    // Try to create and join the new federation execution
+    if (!_hlaFederate->createJoinFederationExecution()) {
         SG_LOG(SG_IO, SG_ALERT, "Could not join federation");
         return false;
     }
@@ -1240,8 +1238,8 @@ FGHLA::process()
         }
     }
 
-    // Then get news from others ...
-    if (get_direction() & SG_IO_IN) {
+    // Then get news from others and process possible update requests
+    if (get_direction() & (SG_IO_IN|SG_IO_OUT)) {
 
         // I hoped that the tick call itself would do that job with the timestamps, but this way it works
         SGTimeStamp timestamp = SGTimeStamp::now();
@@ -1267,11 +1265,9 @@ FGHLA::close()
         _localAircraftInstance = 0;
     }
 
-    // Leave the federation
-    _hlaFederate->resign();
-
-    // Try to destroy the federation execution. Only works if no federate is joined
-    _hlaFederate->destroyFederationExecution(_federation);
+    // Leave the federation and try to destroy the federation execution.
+    // Only works if no federate is joined
+    _hlaFederate->resignDestroyFederationExecution();
 
     // throw away the HLAFederate
     _hlaFederate->disconnect();

From d64bcf0175dfbd44186e1454c1ba068a00eed80b Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 1 Oct 2011 22:41:53 +0200
Subject: [PATCH 70/85] Replay upgrade, part I: Add new flight recorder.

---
 projects/VC90/FlightGear/FlightGear.vcproj |   8 +
 src/Aircraft/CMakeLists.txt                |   4 +-
 src/Aircraft/Makefile.am                   |   3 +-
 src/Aircraft/flightrecorder.cxx            | 544 +++++++++++++++++++++
 src/Aircraft/flightrecorder.hxx            |  89 ++++
 5 files changed, 646 insertions(+), 2 deletions(-)
 create mode 100644 src/Aircraft/flightrecorder.cxx
 create mode 100644 src/Aircraft/flightrecorder.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index a4c24e46a..6859879e4 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -393,6 +393,14 @@
 				RelativePath="..\..\..\src\Aircraft\replay.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\Aircraft\flightrecorder.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Aircraft\flightrecorder.hxx"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="Lib_Airports"
diff --git a/src/Aircraft/CMakeLists.txt b/src/Aircraft/CMakeLists.txt
index 974d66559..3dcd385c3 100644
--- a/src/Aircraft/CMakeLists.txt
+++ b/src/Aircraft/CMakeLists.txt
@@ -3,12 +3,14 @@ include(FlightGearComponent)
 set(SOURCES
 	controls.cxx
 	replay.cxx
+	flightrecorder.cxx
 	)
 
 set(HEADERS
 	controls.hxx
 	replay.hxx
+	flightrecorder.hxx
 	)
 
 
-flightgear_component(Aircraft "${SOURCES}" "${HEADERS}")
\ No newline at end of file
+flightgear_component(Aircraft "${SOURCES}" "${HEADERS}")
diff --git a/src/Aircraft/Makefile.am b/src/Aircraft/Makefile.am
index 02b586a9f..c6ab897a2 100644
--- a/src/Aircraft/Makefile.am
+++ b/src/Aircraft/Makefile.am
@@ -2,6 +2,7 @@ noinst_LIBRARIES = libAircraft.a
 
 libAircraft_a_SOURCES = \
 	controls.cxx controls.hxx \
-	replay.cxx replay.hxx
+	replay.cxx replay.hxx \
+	flightrecorder.cxx flightrecorder.hxx
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
diff --git a/src/Aircraft/flightrecorder.cxx b/src/Aircraft/flightrecorder.cxx
new file mode 100644
index 000000000..6c3efc0a5
--- /dev/null
+++ b/src/Aircraft/flightrecorder.cxx
@@ -0,0 +1,544 @@
+// flightrecorder.cxx
+//
+// Written by Thorsten Brehm, started August 2011.
+//
+// Copyright (C) 2011 Thorsten Brehm - brehmt (at) gmail com
+//
+// 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, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/misc/ResourceManager.hxx>
+#include <simgear/misc/strutils.hxx>
+#include <simgear/structure/exception.hxx>
+#include <Main/fg_props.hxx>
+#include "flightrecorder.hxx"
+
+using namespace FlightRecorder;
+
+FGFlightRecorder::FGFlightRecorder(const char* pConfigName) :
+    m_RecorderNode(fgGetNode("/sim/flight-recorder", true)),
+    m_TotalRecordSize(0),
+    m_ConfigName(pConfigName)
+{
+}
+
+FGFlightRecorder::~FGFlightRecorder()
+{
+}
+
+void
+FGFlightRecorder::reinit(void)
+{
+    m_ConfigNode = 0;
+
+    m_TotalRecordSize = 0;
+
+    m_CaptureDouble.clear();
+    m_CaptureFloat.clear();
+    m_CaptureInteger.clear();
+    m_CaptureInt16.clear();
+    m_CaptureInt8.clear();
+    m_CaptureBool.clear();
+
+    int Selected = m_RecorderNode->getIntValue(m_ConfigName, 0);
+    SG_LOG(SG_SYSTEMS, SG_INFO, "FlightRecorder: Recorder configuration #" << Selected);
+    if (Selected >= 0)
+        m_ConfigNode = m_RecorderNode->getChild("config", Selected);
+
+    if (!m_ConfigNode.valid())
+        initDefault();
+
+    if (!m_ConfigNode.valid())
+    {
+        SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: Configuration is invalid. Flight recorder disabled.");
+    }
+    else
+    {
+        // set name of active flight recorder type 
+        const char* pRecorderName =
+                m_ConfigNode->getStringValue("name",
+                                             "aircraft-specific flight recorder");
+        SG_LOG(SG_SYSTEMS, SG_INFO, "FlightRecorder: Using custom recorder configuration: " << pRecorderName);
+        m_RecorderNode->setStringValue("active-config-name", pRecorderName);
+
+        // get signals
+        initSignalList("double", m_CaptureDouble,  m_ConfigNode );
+        initSignalList("float",  m_CaptureFloat ,  m_ConfigNode );
+        initSignalList("int",    m_CaptureInteger, m_ConfigNode );
+        initSignalList("int16",  m_CaptureInt16  , m_ConfigNode );
+        initSignalList("int8",   m_CaptureInt8   , m_ConfigNode );
+        initSignalList("bool",   m_CaptureBool   , m_ConfigNode );
+    }
+
+    // calculate size of a single record
+    m_TotalRecordSize = sizeof(double)        * 1 /* sim time */        +
+                        sizeof(double)        * m_CaptureDouble.size()  +
+                        sizeof(float)         * m_CaptureFloat.size()   +
+                        sizeof(int)           * m_CaptureInteger.size() +
+                        sizeof(short int)     * m_CaptureInt16.size()   +
+                        sizeof(signed char)   * m_CaptureInt8.size()    +
+                        sizeof(unsigned char) * ((m_CaptureBool.size()+7)/8); // 8 bools per byte
+
+    // expose size of actual flight recorder record
+    m_RecorderNode->setIntValue("record-size", m_TotalRecordSize);
+    SG_LOG(SG_SYSTEMS, SG_INFO, "FlightRecorder: record size is " << m_TotalRecordSize << " bytes");
+}
+
+/** Check if SignalList already contains the given property */
+bool
+FGFlightRecorder::haveProperty(FlightRecorder::TSignalList& SignalList,SGPropertyNode* pProperty)
+{
+    unsigned int Count = SignalList.size();
+    for (unsigned int i=0; i<Count; i++)
+    {
+        if (SignalList[i].Signal.get() == pProperty)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+/** Check if any signal list already contains the given property */
+bool
+FGFlightRecorder::haveProperty(SGPropertyNode* pProperty)
+{
+    if (haveProperty(m_CaptureDouble,  pProperty))
+        return true;
+    if (haveProperty(m_CaptureFloat,   pProperty))
+        return true;
+    if (haveProperty(m_CaptureInteger, pProperty))
+        return true;
+    if (haveProperty(m_CaptureInt16,   pProperty))
+        return true;
+    if (haveProperty(m_CaptureInt8,    pProperty))
+        return true;
+    if (haveProperty(m_CaptureBool,    pProperty))
+        return true;
+    return false;
+}
+
+/** Read default flight-recorder configuration.
+ * Default should match properties as hard coded for versions up to FG2.4.0. */
+void
+FGFlightRecorder::initDefault(void)
+{
+    // set name of active flight recorder type
+    SG_LOG(SG_SYSTEMS, SG_INFO, "FlightRecorder: No custom configuration. Loading generic default recorder.");
+
+    const char* Path = m_RecorderNode->getStringValue("default-config",NULL);
+    if (!Path)
+    {
+        SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: No default flight recorder specified! Check preferences.xml!");
+    }
+    else
+    {
+        SGPath path = globals->resolve_aircraft_path(Path);
+        if (path.isNull())
+        {
+            SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: Cannot find file '" << Path << "'.");
+        }
+        else
+        {
+            try
+            {
+                readProperties(path.str(), m_RecorderNode->getChild("config", 0 ,true), 0);
+                m_ConfigNode = m_RecorderNode->getChild("config", 0 ,false);
+            } catch (sg_io_exception &e)
+            {
+                SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: Error reading file '" <<
+                        Path << ": " << e.getFormattedMessage());
+            }
+        }
+    }
+}
+
+/** Read signal list below given base node.
+ * Only process properties of given signal type and add all signals to the given list.
+ * This method is called for all supported signal types - properties of each type are
+ * kept in separate lists for efficiency reasons. */
+void
+FGFlightRecorder::initSignalList(const char* pSignalType, TSignalList& SignalList, SGPropertyNode_ptr BaseNode)
+{
+    // clear old signals
+    SignalList.clear();
+
+    processSignalList(pSignalType, SignalList, BaseNode);
+
+    SG_LOG(SG_SYSTEMS, SG_DEBUG, "FlightRecorder: " << SignalList.size() << " signals of type " << pSignalType );
+}
+
+/** Process signal list below given base node.
+ * Only process properties of given signal type and add all signals to the given list.
+ * This method is called for all supported signal types - properties of each type are
+ * kept in separate lists for efficiency reasons. */
+void
+FGFlightRecorder::processSignalList(const char* pSignalType, TSignalList& SignalList, SGPropertyNode_ptr SignalListNode,
+                                    string PropPrefix, int Count)
+{
+    // get the list of signal sources (property paths) for this signal type
+    SGPropertyNode_ptr SignalNode;
+    int Index=0;
+
+    Count = SignalListNode->getIntValue("count",Count);
+    PropPrefix = simgear::strutils::strip(SignalListNode->getStringValue("prefix",PropPrefix.c_str()));
+    if ((!PropPrefix.empty())&&(PropPrefix[PropPrefix.size()-1] != '/'))
+        PropPrefix += "/";
+
+    do
+    {
+        SignalNode = SignalListNode->getChild("signal",Index,false);
+        if (SignalNode.valid()&&
+            (0==strcmp(pSignalType, SignalNode->getStringValue("type","float"))))
+        {
+            string PropertyPath = SignalNode->getStringValue("property","");
+            if (!PropertyPath.empty())
+            {
+                PropertyPath = PropPrefix + PropertyPath;
+                const char* pInterpolation = SignalNode->getStringValue("interpolation","linear");
+
+                // Check if current signal has a "%i" place holder. Otherwise count is 1.
+                string::size_type IndexPos = PropertyPath.find("%i");
+                int SignalCount = Count;
+                if (IndexPos == string::npos)
+                    SignalCount = 1;
+
+                for (int IndexValue=0;IndexValue<SignalCount;IndexValue++)
+                {
+                    string PPath = PropertyPath;
+                    if (IndexPos != string::npos)
+                    {
+                        char strbuf[20];
+                        snprintf(strbuf, 20, "%d", IndexValue);
+                        PPath = PPath.replace(IndexPos,2,strbuf);
+                    }
+                    TCapture Capture;
+                    Capture.Signal = fgGetNode(PPath.c_str(),false);
+                    if (!Capture.Signal.valid())
+                    {
+                        // warn user: we're maybe going to record useless data
+                        // Or maybe the data is only initialized later. Warn anyway, so we can catch useless data. 
+                        SG_LOG(SG_SYSTEMS, SG_INFO, "FlightRecorder: Recording non-existent property '" << PPath << "'.");
+                        Capture.Signal = fgGetNode(PPath.c_str(),true);
+                    }
+
+                    if (0==strcmp(pInterpolation,"discrete"))
+                        Capture.Interpolation = discrete;
+                    else 
+                    if ((0==strcmp(pInterpolation,"angular"))||
+                        (0==strcmp(pInterpolation,"angular-rad")))
+                        Capture.Interpolation = angular_rad;
+                    else
+                    if (0==strcmp(pInterpolation,"angular-deg"))
+                        Capture.Interpolation = angular_deg;
+                    else
+                    if (0==strcmp(pInterpolation,"linear"))
+                        Capture.Interpolation = linear;
+                    else
+                    {
+                        SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: Unsupported interpolation type '"
+                                << pInterpolation<< "' of signal '" << PPath << "'");
+                        Capture.Interpolation = linear;
+                    }
+                    if (haveProperty(Capture.Signal))
+                    {
+                        SG_LOG(SG_SYSTEMS, SG_ALERT, "FlightRecorder: Property '"
+                                << PPath << "' specified multiple times. Check flight recorder configuration.");
+                    }
+                    else
+                        SignalList.push_back(Capture);
+                }
+            }
+        }
+        Index++;
+    } while (SignalNode.valid());
+
+    // allow recursive definition of signal lists
+    simgear::PropertyList Nodes = SignalListNode->getChildren("signals");
+    for (unsigned int i=0;i<Nodes.size();i++)
+    {
+        processSignalList(pSignalType, SignalList, Nodes[i], PropPrefix, Count);
+    }
+}
+
+/** Get an empty container for a single capture. */
+FGReplayData*
+FGFlightRecorder::createEmptyRecord(void)
+{
+    if (!m_TotalRecordSize)
+        return NULL;
+    FGReplayData* p = (FGReplayData*) new unsigned char[m_TotalRecordSize];
+    return p;
+}
+
+/** Free given container with capture data. */
+void
+FGFlightRecorder::deleteRecord(FGReplayData* pRecord)
+{
+    delete[] pRecord;
+}
+
+/** Capture data.
+ * When pBuffer==NULL new memory is allocated.
+ * If pBuffer!=NULL memory of given buffer is reused.
+ */
+FGReplayData*
+FGFlightRecorder::capture(double SimTime, FGReplayData* pRecycledBuffer)
+{
+    if (!pRecycledBuffer)
+    {
+        pRecycledBuffer = createEmptyRecord();
+        if (!pRecycledBuffer)
+            return NULL;
+    }
+    unsigned char* pBuffer = (unsigned char*) pRecycledBuffer;
+
+    int Offset = 0;
+    pRecycledBuffer->sim_time = SimTime;
+    Offset += sizeof(double);
+
+    // 64bit aligned data first!
+    {
+        // capture doubles
+        double* pDoubles = (double*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureDouble.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            pDoubles[i] = m_CaptureDouble[i].Signal->getDoubleValue();
+        }
+        Offset += SignalCount * sizeof(double);
+    }
+    
+    // 32bit aligned data comes second...
+    {
+        // capture floats
+        float* pFloats = (float*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureFloat.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            pFloats[i] = m_CaptureFloat[i].Signal->getFloatValue();
+        }
+        Offset += SignalCount * sizeof(float);
+    }
+    
+    {
+        // capture integers (32bit aligned)
+        int* pInt = (int*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInteger.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            pInt[i] = m_CaptureInteger[i].Signal->getIntValue();
+        }
+        Offset += SignalCount * sizeof(int);
+    }
+    
+    // 16bit aligned data is next...
+    {
+        // capture 16bit short integers
+        short int* pShortInt = (short int*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInt16.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            pShortInt[i] = (short int) m_CaptureInt16[i].Signal->getIntValue();
+        }
+        Offset += SignalCount * sizeof(short int);
+    }
+    
+    // finally: byte aligned data is last...
+    {
+        // capture 8bit chars
+        signed char* pChar = (signed char*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInt8.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            pChar[i] = (signed char) m_CaptureInt8[i].Signal->getIntValue();
+        }
+        Offset += SignalCount * sizeof(signed char);
+    }
+    
+    {
+        // capture 1bit booleans (8bit aligned)
+        unsigned char* pFlags = (unsigned char*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureBool.size();
+        int Size = (SignalCount+7)/8;
+        Offset += Size;
+        memset(pFlags,0,Size);
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            if (m_CaptureBool[i].Signal->getBoolValue())
+                pFlags[i>>3] |= 1 << (i&7);
+        }
+    }
+
+    assert(Offset == m_TotalRecordSize);
+
+    return (FGReplayData*) pBuffer;
+}
+
+/** Do interpolation as defined by given interpolation type and weighting ratio. */
+static double
+weighting(TInterpolation interpolation, double ratio, double v1,double v2)
+{
+    switch (interpolation)
+    {
+        case linear:
+            return v1 + ratio*(v2-v1);
+        
+        case angular_deg:
+        {
+            // special handling of angular data
+            double tmp = v2 - v1;
+            if ( tmp > 180 )
+                tmp -= 360;
+            else if ( tmp < -180 )
+                tmp += 360;
+            return v1 + tmp * ratio;
+        }
+
+        case angular_rad:
+        {
+            // special handling of angular data
+            double tmp = v2 - v1;
+            if ( tmp > SGD_PI )
+                tmp -= SGD_2PI;
+            else if ( tmp < -SGD_PI )
+                tmp += SGD_2PI;
+            return v1 + tmp * ratio;
+        }
+
+        case discrete:
+            // fall through
+        default:
+            return v2;
+    }
+}
+
+/** Replay.
+ * Restore all properties with data from given buffer. */
+void
+FGFlightRecorder::replay(double SimTime, const FGReplayData* _pNextBuffer, const FGReplayData* _pLastBuffer)
+{
+    const char* pLastBuffer = (const char*) _pLastBuffer;
+    const char* pBuffer = (const char*) _pNextBuffer;
+    if (!pBuffer)
+        return;
+
+    int Offset = 0;
+    double ratio;
+    if (pLastBuffer)
+    {
+        double NextSimTime = _pNextBuffer->sim_time;
+        double LastSimTime = _pLastBuffer->sim_time;
+        ratio = (SimTime - LastSimTime) / (NextSimTime - LastSimTime);
+    }
+    else
+    {
+        ratio = 1.0;
+    }
+
+    Offset += sizeof(double);
+
+    // 64bit aligned data first!
+    {
+        // restore doubles
+        const double* pDoubles = (const double*) &pBuffer[Offset];
+        const double* pLastDoubles = (const double*) &pLastBuffer[Offset];
+        unsigned int SignalCount = m_CaptureDouble.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            double v = pDoubles[i];
+            if (pLastBuffer)
+            {
+                v = weighting(m_CaptureDouble[i].Interpolation, ratio,
+                              pLastDoubles[i], v);
+            }
+            m_CaptureDouble[i].Signal->setDoubleValue(v);
+        }
+        Offset += SignalCount * sizeof(double);
+    }
+
+    // 32bit aligned data comes second...
+    {
+        // restore floats
+        const float* pFloats = (const float*) &pBuffer[Offset];
+        const float* pLastFloats = (const float*) &pLastBuffer[Offset];
+        unsigned int SignalCount = m_CaptureFloat.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            float v = pFloats[i];
+            if (pLastBuffer)
+            {
+                v = weighting(m_CaptureFloat[i].Interpolation, ratio,
+                              pLastFloats[i], v);
+            }
+            m_CaptureFloat[i].Signal->setDoubleValue(v);//setFloatValue
+        }
+        Offset += SignalCount * sizeof(float);
+    }
+
+    {
+        // restore integers (32bit aligned)
+        const int* pInt = (const int*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInteger.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            m_CaptureInteger[i].Signal->setIntValue(pInt[i]);
+        }
+        Offset += SignalCount * sizeof(int);
+    }
+
+    // 16bit aligned data is next...
+    {
+        // restore 16bit short integers
+        const short int* pShortInt = (const short int*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInt16.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            m_CaptureInt16[i].Signal->setIntValue(pShortInt[i]);
+        }
+        Offset += SignalCount * sizeof(short int);
+    }
+
+    // finally: byte aligned data is last...
+    {
+        // restore 8bit chars
+        const signed char* pChar = (const signed char*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureInt8.size();
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            m_CaptureInt8[i].Signal->setIntValue(pChar[i]);
+        }
+        Offset += SignalCount * sizeof(signed char);
+    }
+
+    {
+        // restore 1bit booleans (8bit aligned)
+        const unsigned char* pFlags = (const unsigned char*) &pBuffer[Offset];
+        unsigned int SignalCount = m_CaptureBool.size();
+        int Size = (SignalCount+7)/8;
+        Offset += Size;
+        for (unsigned int i=0; i<SignalCount; i++)
+        {
+            m_CaptureBool[i].Signal->setBoolValue(0 != (pFlags[i>>3] & (1 << (i&7))));
+        }
+    }
+}
diff --git a/src/Aircraft/flightrecorder.hxx b/src/Aircraft/flightrecorder.hxx
new file mode 100644
index 000000000..a2045f64a
--- /dev/null
+++ b/src/Aircraft/flightrecorder.hxx
@@ -0,0 +1,89 @@
+// flightrecorder.hxx
+//
+// Written by Thorsten Brehm, started August 2011.
+//
+// Copyright (C) 2011 Thorsten Brehm - brehmt (at) gmail com
+//
+// 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, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef FLIGHTRECORDER_HXX_
+#define FLIGHTRECORDER_HXX_
+
+#include <simgear/props/props.hxx>
+#include "replay.hxx"
+
+namespace FlightRecorder
+{
+
+    typedef enum
+    {
+        discrete    = 0,   // no interpolation
+        linear      = 1,  // linear interpolation
+        angular_rad = 2,  // angular interpolation, value in radians
+        angular_deg = 3   // angular interpolation, value in degrees
+    } TInterpolation;
+
+    typedef struct
+    {
+        SGPropertyNode_ptr  Signal;
+        TInterpolation      Interpolation;
+    } TCapture;
+
+    typedef std::vector<TCapture> TSignalList;
+
+}
+
+class FGFlightRecorder
+{
+public:
+    FGFlightRecorder(const char* pConfigName);
+    virtual ~FGFlightRecorder();
+
+    void            reinit              (void);
+    FGReplayData*   createEmptyRecord   (void);
+    FGReplayData*   capture             (double SimTime, FGReplayData* pRecycledBuffer);
+    void            replay              (double SimTime, const FGReplayData* pNextBuffer,
+                                         const FGReplayData* pLastBuffer = NULL);
+    void            deleteRecord        (FGReplayData* pRecord);
+
+    int             getRecordSize       (void) { return m_TotalRecordSize;}
+
+private:
+    void initDefault(void);
+    void initSignalList(const char* pSignalType, FlightRecorder::TSignalList& SignalList,
+                        SGPropertyNode_ptr BaseNode);
+    void processSignalList(const char* pSignalType, FlightRecorder::TSignalList& SignalList,
+                           SGPropertyNode_ptr SignalListNode,
+                           string PropPrefix="", int Count = 1);
+    bool haveProperty(FlightRecorder::TSignalList& Capture,SGPropertyNode* pProperty);
+    bool haveProperty(SGPropertyNode* pProperty);
+
+    SGPropertyNode_ptr m_RecorderNode;
+    SGPropertyNode_ptr m_ConfigNode;
+
+    FlightRecorder::TSignalList m_CaptureDouble;
+    FlightRecorder::TSignalList m_CaptureFloat;
+    FlightRecorder::TSignalList m_CaptureInteger;
+    FlightRecorder::TSignalList m_CaptureInt16;
+    FlightRecorder::TSignalList m_CaptureInt8;
+    FlightRecorder::TSignalList m_CaptureBool;
+
+    int m_TotalRecordSize;
+    string m_ConfigName;
+};
+
+#endif /* FLIGHTRECORDER_HXX_ */

From ab84ff5904df7682316cf114014b8cd24fe7b359 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 1 Oct 2011 22:58:40 +0200
Subject: [PATCH 71/85] Replay upgrade, part II: Integrate flight recorder,
 update replay system. Drop hard-coded replay property logic, cut ties to
 net_ctrls, net_fdm. Improve replay system controls and status information.

---
 src/Aircraft/replay.cxx  | 561 ++++++++++++++++-----------------------
 src/Aircraft/replay.hxx  |  46 ++--
 src/FDM/flight.cxx       |   3 +-
 src/FDM/flight.hxx       |   1 +
 src/Main/fg_commands.cxx |  44 +--
 5 files changed, 282 insertions(+), 373 deletions(-)

diff --git a/src/Aircraft/replay.cxx b/src/Aircraft/replay.cxx
index 2baf32855..8dd04d871 100644
--- a/src/Aircraft/replay.cxx
+++ b/src/Aircraft/replay.cxx
@@ -1,6 +1,7 @@
 // replay.cxx - a system to record and replay FlightGear flights
 //
-// Written by Curtis Olson, started Juley 2003.
+// Written by Curtis Olson, started July 2003.
+// Updated by Thorsten Brehm, September 2011.
 //
 // Copyright (C) 2003  Curtis L. Olson  - http://www.flightgear.org/~curt
 //
@@ -25,36 +26,31 @@
 #endif
 
 #include <float.h>
+
 #include <simgear/constants.h>
 #include <simgear/structure/exception.hxx>
 
 #include <Main/fg_props.hxx>
-#include <Network/native_ctrls.hxx>
-#include <Network/native_fdm.hxx>
-#include <Network/net_ctrls.hxx>
-#include <Network/net_fdm.hxx>
 #include <FDM/fdm_shell.hxx>
 
 #include "replay.hxx"
-
-const double FGReplay::st_list_time = 60.0;   // 60 secs of high res data
-const double FGReplay::mt_list_time = 600.0;  // 10 mins of 1 fps data
-const double FGReplay::lt_list_time = 3600.0; // 1 hr of 10 spf data
-
-// short term sample rate is as every frame
-const double FGReplay::mt_dt = 0.5; // medium term sample rate (sec)
-const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
+#include "flightrecorder.hxx"
 
 /**
  * Constructor
  */
 
 FGReplay::FGReplay() :
-    last_replay_state(0)
+    last_replay_state(0),
+    m_high_res_time(60.0),
+    m_medium_res_time(600.0),
+    m_low_res_time(3600.0),
+    m_medium_sample_rate(0.5), // medium term sample rate (sec)
+    m_long_sample_rate(5.0),   // long term sample rate (sec)
+    m_pRecorder(new FGFlightRecorder("replay-config"))
 {
 }
 
-
 /**
  * Destructor
  */
@@ -62,31 +58,35 @@ FGReplay::FGReplay() :
 FGReplay::~FGReplay()
 {
     clear();
+
+    delete m_pRecorder;
+    m_pRecorder = NULL;
 }
 
 /**
  * Clear all internal buffers.
  */
-void FGReplay::clear()
+void
+FGReplay::clear()
 {
     while ( !short_term.empty() )
     {
-        delete short_term.front();
+        m_pRecorder->deleteRecord(short_term.front());
         short_term.pop_front();
     }
     while ( !medium_term.empty() )
     {
-        delete medium_term.front();
+        m_pRecorder->deleteRecord(medium_term.front());
         medium_term.pop_front();
     }
     while ( !long_term.empty() )
     {
-        delete long_term.front();
+        m_pRecorder->deleteRecord(long_term.front());
         long_term.pop_front();
     }
     while ( !recycler.empty() )
     {
-        delete recycler.front();
+        m_pRecorder->deleteRecord(recycler.front());
         recycler.pop_front();
     }
 }
@@ -95,12 +95,15 @@ void FGReplay::clear()
  * Initialize the data structures
  */
 
-void FGReplay::init()
+void
+FGReplay::init()
 {
-    disable_replay = fgGetNode( "/sim/replay/disable", true );
-    replay_master = fgGetNode( "/sim/freeze/replay-state", true );
-    replay_time = fgGetNode( "/sim/replay/time", true);
-    replay_looped = fgGetNode( "/sim/replay/looped", true);
+    disable_replay  = fgGetNode("/sim/replay/disable",      true);
+    replay_master   = fgGetNode("/sim/freeze/replay-state", true);
+    replay_time     = fgGetNode("/sim/replay/time",         true);
+    replay_time_str = fgGetNode("/sim/replay/time-str",     true);
+    replay_looped   = fgGetNode("/sim/replay/looped",       true);
+    speed_up        = fgGetNode("/sim/speed-up",            true);
     reinit();
 }
 
@@ -108,33 +111,50 @@ void FGReplay::init()
  * Reset replay queues.
  */
 
-void FGReplay::reinit()
+void
+FGReplay::reinit()
 {
     sim_time = 0.0;
     last_mt_time = 0.0;
     last_lt_time = 0.0;
 
-    // Make sure all queues are flushed
+    // Flush queues
     clear();
+    m_pRecorder->reinit();
+
+    m_high_res_time   = fgGetDouble("/sim/replay/buffer/high-res-time",    60.0);
+    m_medium_res_time = fgGetDouble("/sim/replay/buffer/medium-res-time", 600.0); // 10 mins
+    m_low_res_time    = fgGetDouble("/sim/replay/buffer/low-res-time",   3600.0); // 1 h
+    // short term sample rate is as every frame
+    m_medium_sample_rate = fgGetDouble("/sim/replay/buffer/medium-res-sample-dt", 0.5); // medium term sample rate (sec)
+    m_long_sample_rate   = fgGetDouble("/sim/replay/buffer/low-res-sample-dt",    5.0); // long term sample rate (sec)
 
     // Create an estimated nr of required ReplayData objects
-    // 120 is an estimated maximum frame rate. 
-    int estNrObjects = (int) ((st_list_time*120) + (mt_list_time*mt_dt) +
-                             (lt_list_time*lt_dt)); 
+    // 120 is an estimated maximum frame rate.
+    int estNrObjects = (int) ((m_high_res_time*120) + (m_medium_res_time*m_medium_sample_rate) +
+                             (m_low_res_time*m_long_sample_rate)); 
     for (int i = 0; i < estNrObjects; i++)
     {
-        recycler.push_back(new FGReplayData);
+        FGReplayData* r = m_pRecorder->createEmptyRecord();
+        if (r)
+            recycler.push_back(r);
+        else
+        {
+            SG_LOG(SG_SYSTEMS, SG_ALERT, "ReplaySystem: Out of memory!");
+        }
     }
     replay_master->setIntValue(0);
     disable_replay->setBoolValue(0);
     replay_time->setDoubleValue(0);
+    replay_time_str->setStringValue("");
 }
 
 /** 
  * Bind to the property tree
  */
 
-void FGReplay::bind()
+void
+FGReplay::bind()
 {
 }
 
@@ -143,26 +163,85 @@ void FGReplay::bind()
  *  Unbind from the property tree
  */
 
-void FGReplay::unbind()
+void
+FGReplay::unbind()
 {
     // nothing to unbind
 }
 
+static void
+printTimeStr(char* pStrBuffer,double _Time, bool ShowDecimal=true)
+{
+    if (_Time<0)
+        _Time = 0;
+    unsigned int Time = (unsigned int) (_Time*10);
+    int h = Time/36000;
+    int m = (Time % 36000)/600;
+    int s = (Time % 600)/10;
+    int d = Time % 10;
+    if (h>0)
+        sprintf(pStrBuffer,"%u:%02u",h,m);
+    else
+        sprintf(pStrBuffer,"%u",m);
+    if (ShowDecimal)
+        sprintf(pStrBuffer,"%s:%02u.%u",pStrBuffer,s,d);
+    else
+        sprintf(pStrBuffer,"%s:%02u",pStrBuffer,s);
+}
+
+/** Start replay session
+ */
+bool
+FGReplay::start()
+{
+    // freeze the fdm, resume from sim pause
+    double StartTime = get_start_time();
+    double EndTime = get_end_time();
+    fgSetDouble("/sim/replay/start-time", StartTime);
+    fgSetDouble("/sim/replay/end-time",   EndTime);
+    char StrBuffer[30];
+    printTimeStr(StrBuffer,StartTime,false);
+    fgSetString("/sim/replay/start-time-str", StrBuffer);
+    printTimeStr(StrBuffer,EndTime,false);
+    fgSetString("/sim/replay/end-time-str",   StrBuffer);
+
+    unsigned long buffer_elements =  short_term.size()+medium_term.size()+long_term.size();
+    fgSetDouble("/sim/replay/buffer-size-mbyte",
+                buffer_elements*m_pRecorder->getRecordSize() / (1024*1024.0));
+    if ((fgGetBool("/sim/freeze/master"))||
+        (0 == replay_master->getIntValue()))
+        fgSetString("/sim/messages/copilot", "Replay active. 'Esc' to stop.");
+    fgSetBool  ("/sim/freeze/master",     0);
+    fgSetBool  ("/sim/freeze/clock",      0);
+    if (0 == replay_master->getIntValue())
+    {
+        replay_master->setIntValue(1);
+        replay_time->setDoubleValue(-1);
+        replay_time_str->setStringValue("");
+    }
+    return true;
+}
 
 /** 
  *  Update the saved data
  */
 
-void FGReplay::update( double dt )
+void
+FGReplay::update( double dt )
 {
+    int current_replay_state = last_replay_state;
     timingInfo.clear();
     stamp("begin");
 
     if ( disable_replay->getBoolValue() )
     {
+        current_replay_state = replay_master->getIntValue();
         replay_master->setIntValue(0);
         replay_time->setDoubleValue(0);
+        replay_time_str->setStringValue("");
         disable_replay->setBoolValue(0);
+        speed_up->setDoubleValue(1.0);
+        fgSetString("/sim/messages/copilot", "Replay stopped");
     }
 
     int replay_state = replay_master->getIntValue();
@@ -180,8 +259,17 @@ void FGReplay::update( double dt )
     if ((replay_state == 0)&&
         (last_replay_state > 0))
     {
-        // replay was active, restore most recent frame
-        replay(DBL_MAX);
+        if (current_replay_state == 3)
+        {
+            // "my controls!" requested: pilot takes control at current replay position...
+            // May need to uncrash the aircraft here :)
+            fgSetBool("/sim/crashed", false);
+        }
+        else
+        {
+            // replay was active, restore most recent frame
+            replay(DBL_MAX);
+        }
         // replay is finished, resume FDM
         ((FDMShell*) globals->get_subsystem("flight"))->getFDM()->resume();
     }
@@ -195,30 +283,36 @@ void FGReplay::update( double dt )
             // replay inactive, keep recording
             break;
         case 1:
+        {
+            // replay active
+            double current_time = replay_time->getDoubleValue();
+            if (current_time<=0.0)
             {
-                // replay active
-                double current_time = replay_time->getDoubleValue();
-                if (current_time<0.0)
-                {
-                    // initialize start time
-                    fgSetDouble( "/sim/replay/start-time", get_start_time() );
-                    fgSetDouble( "/sim/replay/end-time", get_end_time() );
-                    double duration = fgGetDouble( "/sim/replay/duration" );
-                    if( duration && duration < (get_end_time() - get_start_time()) ) {
-                        current_time = get_end_time() - duration;
-                    } else {
-                        current_time = get_start_time();
-                    }
+                // initialize start time
+                double startTime = get_start_time();
+                double endTime = get_end_time();
+                fgSetDouble( "/sim/replay/start-time", startTime );
+                fgSetDouble( "/sim/replay/end-time", endTime );
+                double duration = fgGetDouble( "/sim/replay/duration" );
+                if( duration && (duration < (endTime - startTime)) ) {
+                    current_time = endTime - duration;
+                } else {
+                    current_time = startTime;
                 }
-                bool IsFinished = replay( replay_time->getDoubleValue() );
-                if ((IsFinished)&&(replay_looped->getBoolValue()))
-                    current_time = -1;
-                else
-                    current_time += dt * fgGetInt("/sim/speed-up");
-                replay_time->setDoubleValue(current_time);
             }
+            bool IsFinished = replay( replay_time->getDoubleValue() );
+            if (IsFinished)
+                current_time = (replay_looped->getBoolValue()) ? -1 : get_end_time()+0.01;
+            else
+                current_time += dt * speed_up->getDoubleValue();
+            replay_time->setDoubleValue(current_time);
+            char StrBuffer[30];
+            printTimeStr(StrBuffer,current_time);
+            replay_time_str->setStringValue((const char*)StrBuffer);
             return; // don't record the replay session 
-        case 2:
+        }
+        case 2: // normal replay operation
+        case 3: // replay operation, prepare to resume normal flight at current replay position 
             // replay paused, no-op
             return; // don't record the replay session
         default:
@@ -228,78 +322,64 @@ void FGReplay::update( double dt )
     // flight recording
 
     //cerr << "Recording replay" << endl;
-    sim_time += dt;
-
-    // build the replay record
-    //FGNetFDM f;
-    //FGProps2NetFDM( &f, false );
+    sim_time += dt * speed_up->getDoubleValue();
 
     // sanity check, don't collect data if FDM data isn't good
     if (!fgGetBool("/sim/fdm-initialized", false)) {
         return;
     }
-    
-    //FGNetCtrls c;
-    //FGProps2NetCtrls( &c, false, false );
-    //stamp("point_04ba");
-    FGReplayData *r;
-    //stamp("point_04bb");
-    if (!recycler.size()) {
-        stamp("Replay_01");
-        r = new FGReplayData;
-        stamp("Replay_02");
-    } else {
-        r = recycler.front();
-        recycler.pop_front();
-        //stamp("point_04be");
-    }
 
-    r->sim_time = sim_time;
-    //r->ctrls = c;
-    //stamp("point_04e");
-    FGProps2NetFDM( &(r->fdm), false );
-    FGProps2NetCtrls( &(r->ctrls), false, false );
-    //r->fdm = f;
-    //stamp("point_05");
+    FGReplayData* r = record(sim_time);
+    if (!r)
+    {
+        SG_LOG(SG_SYSTEMS, SG_ALERT, "ReplaySystem: Out of memory!");
+        return;
+    }
 
     // update the short term list
     //stamp("point_06");
     short_term.push_back( r );
     //stamp("point_07");
     FGReplayData *st_front = short_term.front();
-    if ( sim_time - st_front->sim_time > st_list_time ) {
-        while ( sim_time - st_front->sim_time > st_list_time ) {
+    
+    if (!st_front)
+    {
+        SG_LOG(SG_SYSTEMS, SG_ALERT, "ReplaySystem: Inconsistent data!");
+    }
+
+    if ( sim_time - st_front->sim_time > m_high_res_time ) {
+        while ( sim_time - st_front->sim_time > m_high_res_time ) {
             st_front = short_term.front();
             recycler.push_back(st_front);
             short_term.pop_front();
         }
         //stamp("point_08");
         // update the medium term list
-        if ( sim_time - last_mt_time > mt_dt ) {
+        if ( sim_time - last_mt_time > m_medium_sample_rate ) {
             last_mt_time = sim_time;
             st_front = short_term.front();
             medium_term.push_back( st_front );
             short_term.pop_front();
 
             FGReplayData *mt_front = medium_term.front();
-            if ( sim_time - mt_front->sim_time > mt_list_time ) {
+            if ( sim_time - mt_front->sim_time > m_medium_res_time ) {
             //stamp("point_09");
-                while ( sim_time - mt_front->sim_time > mt_list_time ) {
+                while ( sim_time - mt_front->sim_time > m_medium_res_time ) {
                     mt_front = medium_term.front();
                     recycler.push_back(mt_front);
                     medium_term.pop_front();
                 }
                 // update the long term list
-                if ( sim_time - last_lt_time > lt_dt ) {
+                if ( sim_time - last_lt_time > m_long_sample_rate ) {
                     last_lt_time = sim_time;
                     mt_front = medium_term.front();
                     long_term.push_back( mt_front );
                     medium_term.pop_front();
 
                     FGReplayData *lt_front = long_term.front();
-                    if ( sim_time - lt_front->sim_time > lt_list_time ) {
+                    if ( sim_time - lt_front->sim_time > m_low_res_time ) {
                         //stamp("point_10");
-                        while ( sim_time - lt_front->sim_time > lt_list_time ) {
+                        while ( sim_time - lt_front->sim_time > m_low_res_time ) {
                             lt_front = long_term.front();
                             recycler.push_back(lt_front);
                             long_term.pop_front();
@@ -324,224 +404,37 @@ void FGReplay::update( double dt )
    //stamp("point_finished");
 }
 
-
-static double weight( double data1, double data2, double ratio,
-                      bool rotational = false ) {
-    if ( rotational ) {
-        // special handling of rotational data
-        double tmp = data2 - data1;
-        if ( tmp > SGD_PI ) {
-            tmp -= SGD_2PI;
-        } else if ( tmp < -SGD_PI ) {
-            tmp += SGD_2PI;
-        }
-        return data1 + tmp * ratio;
-    } else {
-        // normal "linear" data
-        return data1 + ( data2 - data1 ) * ratio;
-    }
-}
-
-/** 
- * given two FGReplayData elements and a time, interpolate between them
- */
-static void update_fdm( FGReplayData frame ) {
-    FGNetFDM2Props( &frame.fdm, false );
-    FGNetCtrls2Props( &frame.ctrls, false, false );
-}
-
-/** 
- * given two FGReplayData elements and a time, interpolate between them
- */
-static FGReplayData interpolate( double time, FGReplayData f1, FGReplayData f2 )
+FGReplayData*
+FGReplay::record(double time)
 {
-    FGReplayData result = f1;
+    FGReplayData* r = NULL;
 
-    FGNetFDM fdm1 = f1.fdm;
-    FGNetFDM fdm2 = f2.fdm;
-
-    FGNetCtrls ctrls1 = f1.ctrls;
-    FGNetCtrls ctrls2 = f2.ctrls;
-
-    double ratio = (time - f1.sim_time) / (f2.sim_time - f1.sim_time);
-
-    // Interpolate FDM data
-
-    // Positions
-    result.fdm.longitude = weight( fdm1.longitude, fdm2.longitude, ratio );
-    result.fdm.latitude = weight( fdm1.latitude, fdm2.latitude, ratio );
-    result.fdm.altitude = weight( fdm1.altitude, fdm2.altitude, ratio );
-    result.fdm.agl = weight( fdm1.agl, fdm2.agl, ratio );
-    result.fdm.phi = weight( fdm1.phi, fdm2.phi, ratio, true );
-    result.fdm.theta = weight( fdm1.theta, fdm2.theta, ratio, true );
-    result.fdm.psi = weight( fdm1.psi, fdm2.psi, ratio, true );
-
-    // Velocities
-    result.fdm.phidot = weight( fdm1.phidot, fdm2.phidot, ratio, true );
-    result.fdm.thetadot = weight( fdm1.thetadot, fdm2.thetadot, ratio, true );
-    result.fdm.psidot = weight( fdm1.psidot, fdm2.psidot, ratio, true );
-    result.fdm.vcas = weight( fdm1.vcas, fdm2.vcas, ratio );
-    result.fdm.climb_rate = weight( fdm1.climb_rate, fdm2.climb_rate, ratio );
-    result.fdm.v_north = weight( fdm1.v_north, fdm2.v_north, ratio );
-    result.fdm.v_east = weight( fdm1.v_east, fdm2.v_east, ratio );
-    result.fdm.v_down = weight( fdm1.v_down, fdm2.v_down, ratio );
-
-    result.fdm.v_wind_body_north
-        = weight( fdm1.v_wind_body_north, fdm2.v_wind_body_north, ratio );
-    result.fdm.v_wind_body_east
-        = weight( fdm1.v_wind_body_east, fdm2.v_wind_body_east, ratio );
-    result.fdm.v_wind_body_down
-        = weight( fdm1.v_wind_body_down, fdm2.v_wind_body_down, ratio );
-
-    // Stall
-    result.fdm.stall_warning
-        = weight( fdm1.stall_warning, fdm2.stall_warning, ratio );
-
-    // Accelerations
-    result.fdm.A_X_pilot = weight( fdm1.A_X_pilot, fdm2.A_X_pilot, ratio );
-    result.fdm.A_Y_pilot = weight( fdm1.A_Y_pilot, fdm2.A_Y_pilot, ratio );
-    result.fdm.A_Z_pilot = weight( fdm1.A_Z_pilot, fdm2.A_Z_pilot, ratio );
-
-    unsigned int i;
-
-    // Engine status
-    for ( i = 0; i < fdm1.num_engines; ++i ) {
-        result.fdm.eng_state[i] = fdm1.eng_state[i];
-        result.fdm.rpm[i] = weight( fdm1.rpm[i], fdm2.rpm[i], ratio );
-        result.fdm.fuel_flow[i]
-            = weight( fdm1.fuel_flow[i], fdm2.fuel_flow[i], ratio );
-        result.fdm.fuel_px[i]
-            = weight( fdm1.fuel_px[i], fdm2.fuel_px[i], ratio );
-        result.fdm.egt[i] = weight( fdm1.egt[i], fdm2.egt[i], ratio );
-        result.fdm.cht[i] = weight( fdm1.cht[i], fdm2.cht[i], ratio );
-        result.fdm.mp_osi[i] = weight( fdm1.mp_osi[i], fdm2.mp_osi[i], ratio );
-        result.fdm.tit[i] = weight( fdm1.tit[i], fdm2.tit[i], ratio );
-        result.fdm.oil_temp[i]
-            = weight( fdm1.oil_temp[i], fdm2.oil_temp[i], ratio );
-        result.fdm.oil_px[i] = weight( fdm1.oil_px[i], fdm2.oil_px[i], ratio );
+    if (recycler.size())
+    {
+        r = recycler.front();
+        recycler.pop_front();
     }
 
-    // Consumables
-    for ( i = 0; i < fdm1.num_tanks; ++i ) {
-        result.fdm.fuel_quantity[i]
-            = weight( fdm1.fuel_quantity[i], fdm2.fuel_quantity[i], ratio );
-    }
+    r = m_pRecorder->capture(time, r);
 
-    // Gear status
-    for ( i = 0; i < fdm1.num_wheels; ++i ) {
-        result.fdm.wow[i] = (int)(weight( fdm1.wow[i], fdm2.wow[i], ratio ));
-        result.fdm.gear_pos[i]
-            = weight( fdm1.gear_pos[i], fdm2.gear_pos[i], ratio );
-        result.fdm.gear_steer[i]
-            = weight( fdm1.gear_steer[i], fdm2.gear_steer[i], ratio );
-        result.fdm.gear_compression[i]
-            = weight( fdm1.gear_compression[i], fdm2.gear_compression[i],
-                      ratio );
-    }
-
-    // Environment
-    result.fdm.cur_time = fdm1.cur_time;
-    result.fdm.warp = fdm1.warp;
-    result.fdm.visibility = weight( fdm1.visibility, fdm2.visibility, ratio );
-
-    // Control surface positions (normalized values)
-    result.fdm.elevator = weight( fdm1.elevator, fdm2.elevator, ratio );
-    result.fdm.left_flap = weight( fdm1.left_flap, fdm2.left_flap, ratio );
-    result.fdm.right_flap = weight( fdm1.right_flap, fdm2.right_flap, ratio );
-    result.fdm.left_aileron
-        = weight( fdm1.left_aileron, fdm2.left_aileron, ratio );
-    result.fdm.right_aileron
-        = weight( fdm1.right_aileron, fdm2.right_aileron, ratio );
-    result.fdm.rudder = weight( fdm1.rudder, fdm2.rudder, ratio );
-    result.fdm.speedbrake = weight( fdm1.speedbrake, fdm2.speedbrake, ratio );
-    result.fdm.spoilers = weight( fdm1.spoilers, fdm2.spoilers, ratio );
-     
-    // Interpolate Control input data
-
-    // Aero controls
-    result.ctrls.aileron = weight( ctrls1.aileron, ctrls2.aileron, ratio );
-    result.ctrls.elevator = weight( ctrls1.elevator, ctrls2.elevator, ratio );
-    result.ctrls.rudder = weight( ctrls1.rudder, ctrls2.rudder, ratio );
-    result.ctrls.aileron_trim
-        = weight( ctrls1.aileron_trim, ctrls2.aileron_trim, ratio );
-    result.ctrls.elevator_trim
-        = weight( ctrls1.elevator_trim, ctrls2.elevator_trim, ratio );
-    result.ctrls.rudder_trim
-        = weight( ctrls1.rudder_trim, ctrls2.rudder_trim, ratio );
-    result.ctrls.flaps = weight( ctrls1.flaps, ctrls2.flaps, ratio );
-    result.ctrls.flaps_power = ctrls1.flaps_power;
-    result.ctrls.flap_motor_ok = ctrls1.flap_motor_ok;
-
-    // Engine controls
-    for ( i = 0; i < ctrls1.num_engines; ++i ) {
-        result.ctrls.master_bat[i] = ctrls1.master_bat[i];
-        result.ctrls.master_alt[i] = ctrls1.master_alt[i];
-        result.ctrls.magnetos[i] = ctrls1.magnetos[i];
-        result.ctrls.starter_power[i] = ctrls1.starter_power[i];
-        result.ctrls.throttle[i]
-            = weight( ctrls1.throttle[i], ctrls2.throttle[i], ratio );
-        result.ctrls.mixture[i]
-            = weight( ctrls1.mixture[i], ctrls2.mixture[i], ratio );
-        result.ctrls.fuel_pump_power[i] = ctrls1.fuel_pump_power[i];
-        result.ctrls.prop_advance[i]
-            = weight( ctrls1.prop_advance[i], ctrls2.prop_advance[i], ratio );
-        result.ctrls.engine_ok[i] = ctrls1.engine_ok[i];
-        result.ctrls.mag_left_ok[i] = ctrls1.mag_left_ok[i];
-        result.ctrls.mag_right_ok[i] = ctrls1.mag_right_ok[i];
-        result.ctrls.spark_plugs_ok[i] = ctrls1.spark_plugs_ok[i];
-        result.ctrls.oil_press_status[i] = ctrls1.oil_press_status[i];
-        result.ctrls.fuel_pump_ok[i] = ctrls1.fuel_pump_ok[i];
-    }
-
-    // Fuel management
-    for ( i = 0; i < ctrls1.num_tanks; ++i ) {
-        result.ctrls.fuel_selector[i] = ctrls1.fuel_selector[i];
-    }
-
-    // Brake controls
-    result.ctrls.brake_left
-            = weight( ctrls1.brake_left, ctrls2.brake_left, ratio );
-    result.ctrls.brake_right
-            = weight( ctrls1.brake_right, ctrls2.brake_right, ratio );
-    result.ctrls.brake_parking
-            = weight( ctrls1.brake_parking, ctrls2.brake_parking, ratio );
-
-    // Landing Gear
-    result.ctrls.gear_handle = ctrls1.gear_handle;
-
-    // Switches
-    result.ctrls.turbulence_norm = ctrls1.turbulence_norm;
-
-    // wind and turbulance
-    result.ctrls.wind_speed_kt
-        = weight( ctrls1.wind_speed_kt, ctrls2.wind_speed_kt, ratio );
-    result.ctrls.wind_dir_deg
-        = weight( ctrls1.wind_dir_deg, ctrls2.wind_dir_deg, ratio );
-    result.ctrls.turbulence_norm
-        = weight( ctrls1.turbulence_norm, ctrls2.turbulence_norm, ratio );
-
-    // other information about environment
-    result.ctrls.hground = weight( ctrls1.hground, ctrls2.hground, ratio );
-    result.ctrls.magvar = weight( ctrls1.magvar, ctrls2.magvar, ratio );
-
-    // simulation control
-    result.ctrls.speedup = ctrls1.speedup;
-    result.ctrls.freeze = ctrls1.freeze;
-
-    return result;
+    return r;
 }
 
 /** 
  * interpolate a specific time from a specific list
  */
-static void interpolate( double time, const replay_list_type &list ) {
+void
+FGReplay::interpolate( double time, const replay_list_type &list)
+{
     // sanity checking
-    if ( list.size() == 0 ) {
+    if ( list.size() == 0 )
+    {
         // handle empty list
         return;
-    } else if ( list.size() == 1 ) {
+    } else if ( list.size() == 1 )
+    {
         // handle list size == 1
-        update_fdm( (*list[0]) );
+        replay(time, list[0]);
         return;
     }
 
@@ -549,9 +442,9 @@ static void interpolate( double time, const replay_list_type &list ) {
     unsigned int first = 0;
     unsigned int mid = ( last + first ) / 2;
 
-
     bool done = false;
-    while ( !done ) {
+    while ( !done )
+    {
         // cout << "  " << first << " <=> " << last << endl;
         if ( last == first ) {
             done = true;
@@ -568,19 +461,17 @@ static void interpolate( double time, const replay_list_type &list ) {
         }
     }
 
-    FGReplayData result = interpolate( time, (*list[mid]), (*list[mid+1]) );
-
-    update_fdm( result );
+    replay(time, list[mid+1], list[mid]);
 }
 
-
 /** 
  *  Replay a saved frame based on time, interpolate from the two
  *  nearest saved frames.
  *  Returns true when replay sequence has finished, false otherwise.
  */
 
-bool FGReplay::replay( double time ) {
+bool
+FGReplay::replay( double time ) {
     // cout << "replay: " << time << " ";
     // find the two frames to interpolate between
     double t1, t2;
@@ -590,7 +481,7 @@ bool FGReplay::replay( double time ) {
         t2 = short_term.front()->sim_time;
         if ( time > t1 ) {
             // replay the most recent frame
-            update_fdm( (*short_term.back()) );
+            replay( time, short_term.back() );
             // replay is finished now
             return true;
             // cout << "first frame" << endl;
@@ -600,11 +491,9 @@ bool FGReplay::replay( double time ) {
         } else if ( medium_term.size() > 0 ) {
             t1 = short_term.front()->sim_time;
             t2 = medium_term.back()->sim_time;
-            if ( time <= t1 && time >= t2 ) {
-                FGReplayData result = interpolate( time,
-                                                   (*medium_term.back()),
-                                                   (*short_term.front()) );
-                update_fdm( result );
+            if ( time <= t1 && time >= t2 )
+            {
+                replay(time, medium_term.back(), short_term.front());
                 // cout << "from short/medium term" << endl;
             } else {
                 t1 = medium_term.back()->sim_time;
@@ -615,11 +504,9 @@ bool FGReplay::replay( double time ) {
                 } else if ( long_term.size() > 0 ) {
                     t1 = medium_term.front()->sim_time;
                     t2 = long_term.back()->sim_time;
-                    if ( time <= t1 && time >= t2 ) {
-                        FGReplayData result = interpolate( time,
-                                                           (*long_term.back()),
-                                                           (*medium_term.front()));
-                        update_fdm( result );
+                    if ( time <= t1 && time >= t2 )
+                    {
+                        replay(time, long_term.back(), medium_term.front());
                         // cout << "from medium/long term" << endl;
                     } else {
                         t1 = long_term.back()->sim_time;
@@ -629,19 +516,19 @@ bool FGReplay::replay( double time ) {
                             // cout << "from long term" << endl;
                         } else {
                             // replay the oldest long term frame
-                            update_fdm( (*long_term.front()) );
+                            replay(time, long_term.front());
                             // cout << "oldest long term frame" << endl;
                         }
                     }
                 } else {
                     // replay the oldest medium term frame
-                    update_fdm( (*medium_term.front()) );
+                    replay(time, medium_term.front());
                     // cout << "oldest medium term frame" << endl;
                 }
             }
         } else {
             // replay the oldest short term frame
-            update_fdm( (*short_term.front()) );
+            replay(time, short_term.front());
             // cout << "oldest short term frame" << endl;
         }
     } else {
@@ -651,23 +538,41 @@ bool FGReplay::replay( double time ) {
     return false;
 }
 
+/** 
+ * given two FGReplayData elements and a time, interpolate between them
+ */
+void
+FGReplay::replay(double time, FGReplayData* pCurrentFrame, FGReplayData* pOldFrame)
+{
+    m_pRecorder->replay(time,pCurrentFrame,pOldFrame);
+}
 
-double FGReplay::get_start_time() {
-    if ( long_term.size() > 0 ) {
-        return (*long_term.front()).sim_time;
-    } else if ( medium_term.size() > 0 ) {
-        return (*medium_term.front()).sim_time;
-    } else if ( short_term.size() ) {
-        return (*short_term.front()).sim_time;
-    } else {
+double
+FGReplay::get_start_time()
+{
+    if ( long_term.size() > 0 )
+    {
+        return long_term.front()->sim_time;
+    } else if ( medium_term.size() > 0 )
+    {
+        return medium_term.front()->sim_time;
+    } else if ( short_term.size() )
+    {
+        return short_term.front()->sim_time;
+    } else
+    {
         return 0.0;
     }
 }
 
-double FGReplay::get_end_time() {
-    if ( short_term.size() ) {
-        return (*short_term.back()).sim_time;
-    } else {
+double
+FGReplay::get_end_time()
+{
+    if ( short_term.size() )
+    {
+        return short_term.back()->sim_time;
+    } else
+    {
         return 0.0;
     } 
 }
diff --git a/src/Aircraft/replay.hxx b/src/Aircraft/replay.hxx
index 0d48ff4ef..7eaa5913c 100644
--- a/src/Aircraft/replay.hxx
+++ b/src/Aircraft/replay.hxx
@@ -1,6 +1,6 @@
 // replay.hxx - a system to record and replay FlightGear flights
 //
-// Written by Curtis Olson, started Juley 2003.
+// Written by Curtis Olson, started July 2003.
 //
 // Copyright (C) 2003  Curtis L. Olson  - http://www.flightgear.org/~curt
 //
@@ -36,20 +36,15 @@
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 
-#include <Network/net_ctrls.hxx>
-#include <Network/net_fdm.hxx>
-
 using std::deque;
 
+class FGFlightRecorder;
 
-class FGReplayData {
-
-public:
-
+typedef struct {
     double sim_time;
-    FGNetFDM fdm;
-    FGNetCtrls ctrls;
-};
+    char   raw_data;
+    /* more data here, hidden to the outside world */
+} FGReplayData;
 
 typedef deque < FGReplayData *> replay_list_type;
 
@@ -73,21 +68,17 @@ public:
     virtual void bind();
     virtual void unbind();
     virtual void update( double dt );
+    bool start();
+
+private:
+    void clear();
+    FGReplayData* record(double time);
+    void interpolate(double time, const replay_list_type &list);
+    void replay(double time, FGReplayData* pCurrentFrame, FGReplayData* pOldFrame=NULL);
 
     bool replay( double time );
     double get_start_time();
     double get_end_time();
-    
-private:
-    void clear();
-
-    static const double st_list_time;   // 60 secs of high res data
-    static const double mt_list_time;  // 10 mins of 1 fps data
-    static const double lt_list_time; // 1 hr of 10 spf data
-
-    // short term sample rate is as every frame
-    static const double mt_dt; // medium term sample rate (sec)
-    static const double lt_dt; // long term sample rate (sec)
 
     double sim_time;
     double last_mt_time;
@@ -101,7 +92,18 @@ private:
     SGPropertyNode_ptr disable_replay;
     SGPropertyNode_ptr replay_master;
     SGPropertyNode_ptr replay_time;
+    SGPropertyNode_ptr replay_time_str;
     SGPropertyNode_ptr replay_looped;
+    SGPropertyNode_ptr speed_up;
+
+    double m_high_res_time;    // default: 60 secs of high res data
+    double m_medium_res_time;  // default: 10 mins of 1 fps data
+    double m_low_res_time;     // default: 1 hr of 10 spf data
+    // short term sample rate is as every frame
+    double m_medium_sample_rate; // medium term sample rate (sec)
+    double m_long_sample_rate;   // long term sample rate (sec)
+
+    FGFlightRecorder* m_pRecorder;
 };
 
 
diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx
index 431605a9f..f3d55075a 100644
--- a/src/FDM/flight.cxx
+++ b/src/FDM/flight.cxx
@@ -305,7 +305,8 @@ FGInterface::bind ()
   
                                 // Ground speed knots
   fgTie("/velocities/groundspeed-kt", this,
-        &FGInterface::get_V_ground_speed_kt); // read-only
+        &FGInterface::get_V_ground_speed_kt,
+        &FGInterface::set_V_ground_speed_kt); // read-only
 
 				// Calibrated airspeed
   fgTie("/velocities/airspeed-kt", this,
diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx
index 6965d3098..35ae2550a 100644
--- a/src/FDM/flight.hxx
+++ b/src/FDM/flight.hxx
@@ -552,6 +552,7 @@ public:
 
     inline double get_V_ground_speed() const { return v_ground_speed; }
     inline double get_V_ground_speed_kt() const { return v_ground_speed * SG_FEET_TO_METER * 3600 * SG_METER_TO_NM; }
+    inline void   set_V_ground_speed_kt(double ground_speed) { v_ground_speed = ground_speed / ( SG_FEET_TO_METER * 3600 * SG_METER_TO_NM); }
 
     inline double get_V_equiv_kts() const { return v_equiv_kts; }
 
diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx
index ee56f9ad8..db234bfc9 100644
--- a/src/Main/fg_commands.cxx
+++ b/src/Main/fg_commands.cxx
@@ -318,14 +318,32 @@ do_resume (const SGPropertyNode * arg)
 
 #endif
 
+/**
+ * Built-in command: replay the FDR buffer
+ */
+static bool
+do_replay (const SGPropertyNode * arg)
+{
+    FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
+    return r->start();
+}
+
+/**
+ * Built-in command: pause/unpause the sim
+ */
 static bool
 do_pause (const SGPropertyNode * arg)
 {
     bool paused = fgGetBool("/sim/freeze/master",true) || fgGetBool("/sim/freeze/clock",true);
-    fgSetBool("/sim/freeze/master",!paused);
-    fgSetBool("/sim/freeze/clock",!paused);
-    if (fgGetBool("/sim/freeze/replay-state",false))
-        fgSetBool("/sim/replay/disable",true);
+    if (paused && (fgGetInt("/sim/freeze/replay-state",0)>0))
+    {
+        do_replay(NULL);
+    }
+    else
+    {
+        fgSetBool("/sim/freeze/master",!paused);
+        fgSetBool("/sim/freeze/clock",!paused);
+    }
     return true;
 }
 
@@ -1170,24 +1188,6 @@ do_log_level (const SGPropertyNode * arg)
    return true;
 }
 
-/**
- * Built-in command: replay the FDR buffer
- */
-static bool
-do_replay (const SGPropertyNode * arg)
-{
-    // freeze the fdm, resume from sim pause 
-    fgSetInt( "/sim/freeze/replay-state", 1 );
-    fgSetBool("/sim/freeze/master", 0 );
-    fgSetBool("/sim/freeze/clock", 0 );
-    fgSetDouble( "/sim/replay/time", -1 );
-
-    // cout << "start = " << r->get_start_time()
-    //      << "  end = " << r->get_end_time() << endl;
-
-    return true;
-}
-
 /*
 static bool
 do_decrease_visibility (const SGPropertyNode * arg)

From a6a6910653a89f10627debaeb803ca78e91ea6fd Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 2 Oct 2011 13:22:09 +0200
Subject: [PATCH 72/85] ATCMGR: fix minor output formatting issue

---
 src/ATC/atc_mgr.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index 0345c2509..409f8668d 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -109,7 +109,7 @@ void FGATCManager::init() {
             if (park_index < 0) {
                   SG_LOG( SG_GENERAL, SG_ALERT,
                         "Failed to find parking position " << parking <<
-                        " at airport " << airport << "at " << SG_ORIGIN);
+                        " at airport " << airport << " at " << SG_ORIGIN);
             }
         if (parking.empty() || (park_index < 0)) {
             controller = apt->getDynamics()->getTowerController();

From 558f0c2d8f7465066b134120a4a62b286676ef24 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 2 Oct 2011 13:23:31 +0200
Subject: [PATCH 73/85] multiplay manager: option to disable freeze-on-replay
 feature

---
 src/MultiPlayer/multiplaymgr.cxx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx
index 271b0acba..060f28638 100644
--- a/src/MultiPlayer/multiplaymgr.cxx
+++ b/src/MultiPlayer/multiplaymgr.cxx
@@ -638,7 +638,8 @@ FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
 
   strncpy(PosMsg->Model, fgGetString("/sim/model/path"), MAX_MODEL_NAME_LEN);
   PosMsg->Model[MAX_MODEL_NAME_LEN - 1] = '\0';
-  if (fgGetBool("/sim/freeze/replay-state", true))
+  if (fgGetBool("/sim/freeze/replay-state", true)&&
+      fgGetBool("/sim/multiplay/freeze-on-replay",true))
   {
       // do not send position updates during replay
       for (unsigned i = 0 ; i < 3; ++i)

From 56912c17c5139c45b582a6a40d8e3089e29142e1 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 2 Oct 2011 13:24:12 +0200
Subject: [PATCH 74/85] adf: fix "in-range" node "in-range" should also be
 false when no station is available

---
 src/Instrumentation/adf.cxx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx
index 805be1040..386f93dcb 100644
--- a/src/Instrumentation/adf.cxx
+++ b/src/Instrumentation/adf.cxx
@@ -124,6 +124,7 @@ ADF::update (double delta_time_sec)
     if (_electrical_node->getDoubleValue() < 8.0
             || !_serviceable_node->getBoolValue()
             || !_power_btn_node->getBoolValue()     ) {
+        _in_range_node->setBoolValue(false);
         _ident_node->setStringValue("");
         return;
     }
@@ -131,6 +132,7 @@ ADF::update (double delta_time_sec)
     string mode = _mode_node->getStringValue();
     if (mode == "ant" || mode == "test") set_bearing(delta_time_sec, 90);
     if (mode != "bfo" && mode != "adf") {
+        _in_range_node->setBoolValue(false);
         _ident_node->setStringValue("");
         return;
     }
@@ -155,6 +157,7 @@ ADF::update (double delta_time_sec)
         search(frequency_khz, longitude_rad, latitude_rad, altitude_m);
 
     if (!_transmitter_valid) {
+        _in_range_node->setBoolValue(false);
         _ident_node->setStringValue("");
         return;
     }

From 761644c51de05eec2527324aa0fe91e7128e8f64 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Sun, 2 Oct 2011 15:13:55 +0200
Subject: [PATCH 75/85] hla: use the new HLAFederate::processMessages() call.

---
 src/Network/HLA/hla.cxx | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx
index f71446a67..4f5e85ffb 100644
--- a/src/Network/HLA/hla.cxx
+++ b/src/Network/HLA/hla.cxx
@@ -1240,14 +1240,7 @@ FGHLA::process()
 
     // Then get news from others and process possible update requests
     if (get_direction() & (SG_IO_IN|SG_IO_OUT)) {
-
-        // I hoped that the tick call itself would do that job with the timestamps, but this way it works
-        SGTimeStamp timestamp = SGTimeStamp::now();
-        timestamp += SGTimeStamp::fromSec(0.01);
-        do {
-            if (!_hlaFederate->tick(0.0, 0.0))
-                break;
-        } while (SGTimeStamp::now() <= timestamp);
+        _hlaFederate->processMessages();
     }
 
     return true;

From 465557cfa779cc45f98c3edad95297275e6db66f Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 2 Oct 2011 14:30:06 +0100
Subject: [PATCH 76/85] Improve magnetic heading handling in MapWidget -
 following some testing at NZCH

---
 src/GUI/MapWidget.cxx | 54 ++++++++++++++++++++++++++++++-------------
 src/GUI/MapWidget.hxx |  3 +++
 2 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx
index 47ec864c0..f5d2cbd71 100644
--- a/src/GUI/MapWidget.cxx
+++ b/src/GUI/MapWidget.cxx
@@ -397,6 +397,7 @@ MapWidget::MapWidget(int x, int y, int maxX, int maxY) :
 MapWidget::~MapWidget()
 {
   delete _magVar;
+  clearData();
 }
 
 void MapWidget::setProperty(SGPropertyNode_ptr prop)
@@ -535,10 +536,14 @@ void MapWidget::draw(int dx, int dy)
 {
   _aircraft = SGGeod::fromDeg(fgGetDouble("/position/longitude-deg"),
     fgGetDouble("/position/latitude-deg"));
-  _magneticHeadings = _root->getBoolValue("magnetic-headings");
-
-  if (_hasPanned)
-  {
+    
+  bool mag = _root->getBoolValue("magnetic-headings");
+  if (mag != _magneticHeadings) {
+    clearData(); // flush cached data text, since it often includes heading
+    _magneticHeadings =  mag;
+  }
+  
+  if (_hasPanned) {
       _root->setBoolValue("centre-on-aircraft", false);
       _hasPanned = false;
   }
@@ -630,14 +635,9 @@ void MapWidget::paintRuler()
 
   double dist, az, az2;
   SGGeodesy::inverse(_aircraft, _clickGeod, az, az2, dist);
-  if (_magneticHeadings) {
-    az -= _magVar->get_magvar();
-    SG_NORMALIZE_RANGE(az, 0.0, 360.0);
-  }
-
   char buffer[1024];
 	::snprintf(buffer, 1024, "%03d/%.1fnm",
-		SGMiscd::roundToInt(az), dist * SG_METER_TO_NM);
+		displayHeading(az), dist * SG_METER_TO_NM);
 
   MapData* d = getOrCreateDataForKey((void*) RULER_LEGEND_KEY);
   d->setLabel(buffer);
@@ -1243,13 +1243,13 @@ void MapWidget::drawRunway(FGRunway* rwy)
     setAnchorForKey(rwy, (p1 + p2) * 0.5);
     return;
   }
-
+  
 	char buffer[1024];
-	::snprintf(buffer, 1024, "%s/%s\n%3.0f/%3.0f\n%.0f'",
+	::snprintf(buffer, 1024, "%s/%s\n%03d/%03d\n%.0f'",
 		rwy->ident().c_str(),
 		rwy->reciprocalRunway()->ident().c_str(),
-		rwy->headingDeg(),
-		rwy->reciprocalRunway()->headingDeg(),
+		displayHeading(rwy->headingDeg()),
+		displayHeading(rwy->reciprocalRunway()->headingDeg()),
 		rwy->lengthFt());
 
   MapData* d = createDataForKey(rwy);
@@ -1311,8 +1311,10 @@ void MapWidget::drawILS(bool tuned, FGRunway* rwy)
   }
 
 	char buffer[1024];
-	::snprintf(buffer, 1024, "%s\n%s\n%3.2fMHz",
-		loc->name().c_str(), loc->ident().c_str(),loc->get_freq()/100.0);
+	::snprintf(buffer, 1024, "%s\n%s\n%03d - %3.2fMHz",
+		loc->ident().c_str(), loc->name().c_str(),
+    displayHeading(radial),
+    loc->get_freq()/100.0);
 
   MapData* d = createDataForKey(loc);
   d->setPriority(40);
@@ -1680,3 +1682,23 @@ MapData* MapWidget::createDataForKey(void* key)
   d->resetAge();
   return d;
 }
+
+void MapWidget::clearData()
+{
+  KeyDataMap::iterator it = _mapData.begin();
+  for (; it != _mapData.end(); ++it) {
+    delete it->second;
+  }
+  
+  _mapData.clear();
+}
+
+int MapWidget::displayHeading(double h) const
+{
+  if (_magneticHeadings) {
+    h -= _magVar->get_magvar() * SG_RADIANS_TO_DEGREES;
+  }
+  
+  SG_NORMALIZE_RANGE(h, 0.0, 360.0);
+  return SGMiscd::roundToInt(h);
+}
diff --git a/src/GUI/MapWidget.hxx b/src/GUI/MapWidget.hxx
index 8c3ae0b5b..3f7158250 100644
--- a/src/GUI/MapWidget.hxx
+++ b/src/GUI/MapWidget.hxx
@@ -73,11 +73,14 @@ private:
   MapData* getOrCreateDataForKey(void* key);
   MapData* createDataForKey(void* key);
   void setAnchorForKey(void* key, const SGVec2d& anchor);
+  void clearData();
   
   SGVec2d project(const SGGeod& geod) const;
   SGGeod unproject(const SGVec2d& p) const;
   double currentScale() const;
   
+  int displayHeading(double trueHeading) const;
+  
   void circleAt(const SGVec2d& center, int nSides, double r);
   void circleAtAlt(const SGVec2d& center, int nSides, double r, double r2);
   void drawLine(const SGVec2d& p1, const SGVec2d& p2);

From 3451012bca81614748508cdb2041c25b5ceb1a02 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Mon, 3 Oct 2011 12:01:58 +0200
Subject: [PATCH 77/85] Make LOD properties of AI/MP aircraft run-time
 configurable.

---
 src/AIModel/AIBase.cxx    | 50 +++++++++++++++++++++++++++------------
 src/AIModel/AIBase.hxx    |  3 ++-
 src/AIModel/AIManager.cxx | 19 ++++++++++++++-
 src/AIModel/AIManager.hxx |  4 ++++
 4 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx
index 8a8e1c8f3..f967995f6 100644
--- a/src/AIModel/AIBase.cxx
+++ b/src/AIModel/AIBase.cxx
@@ -179,6 +179,27 @@ void FGAIBase::update(double dt) {
     ft_per_deg_lon = 365228.16 * cos(pos.getLatitudeRad());
 }
 
+/** update LOD properties of the model */
+void FGAIBase::updateLOD()
+{
+    double maxRangeDetail = fgGetDouble("/sim/rendering/static-lod/ai-detailed", 10000.0);
+    double maxRangeBare   = fgGetDouble("/sim/rendering/static-lod/ai-bare", 20000.0);
+    if (_model.valid())
+    {
+        if( maxRangeDetail == 0.0 )
+        {
+            // disable LOD
+            _model->setRange(0, 0.0,     FLT_MAX);
+            _model->setRange(1, FLT_MAX, FLT_MAX);
+        }
+        else
+        {
+            _model->setRange(0, 0.0, maxRangeDetail);
+            _model->setRange(1, maxRangeDetail,maxRangeBare);
+        }
+    }
+}
+
 void FGAIBase::Transform() {
 
     if (!invisible) {
@@ -226,23 +247,22 @@ bool FGAIBase::init(bool search_in_AI_path) {
         _installed = true;
 
     osg::Node * mdl = SGModelLib::loadPagedModel(f, props, new FGNasalModelData(props));
-    model = mdl;
 
-    double aiModelMaxRange = fgGetDouble("/sim/rendering/static-lod/ai", 0.0);
-    if( aiModelMaxRange > 0.0 ) {
-        osg::LOD * lod = new osg::LOD;
-        lod->setName("AI-model range animation node");
+    _model = new osg::LOD;
+    _model->setName("AI-model range animation node");
 
-        lod->addChild( mdl, 0, aiModelMaxRange );
-        lod->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
-        lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
-
-        model = lod;
-    }
+    _model->addChild( mdl, 0, FLT_MAX );
+    _model->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
+    _model->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
+//    We really need low-resolution versions of AI/MP aircraft.
+//    Or at least dummy "stubs" with some default silhouette.
+//        _model->addChild( SGModelLib::loadPagedModel(fgGetString("/sim/multiplay/default-model", default_model),
+//                                                    props, new FGNasalModelData(props)), FLT_MAX, FLT_MAX);
+    updateLOD();
 
     initModel(mdl);
-    if (model.valid() && _initialized == false) {
-        aip.init( model.get() );
+    if (_model.valid() && _initialized == false) {
+        aip.init( _model.get() );
         aip.setVisible(true);
         invisible = false;
         globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
@@ -260,7 +280,7 @@ bool FGAIBase::init(bool search_in_AI_path) {
 
 void FGAIBase::initModel(osg::Node *node)
 {
-    if (model.valid()) { 
+    if (_model.valid()) { 
 
         if( _path != ""){
             props->setStringValue("submodels/path", _path.c_str());
@@ -523,7 +543,7 @@ SGVec3d FGAIBase::getCartPos() const {
 bool FGAIBase::getGroundElevationM(const SGGeod& pos, double& elev,
                                    const SGMaterial** material) const {
     return globals->get_scenery()->get_elevation_m(pos, elev, material,
-                                                   model.get());
+                                                   _model.get());
 }
 
 double FGAIBase::_getCartPosX() const {
diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx
index fa85d5d2b..298d67cf0 100644
--- a/src/AIModel/AIBase.hxx
+++ b/src/AIModel/AIBase.hxx
@@ -64,6 +64,7 @@ public:
     virtual void unbind();
     virtual void reinit() {}
 
+    void updateLOD();
     void setManager(FGAIManager* mgr, SGPropertyNode* p);
     void setPath( const char* model );
     void setSMPath( const string& p );
@@ -186,7 +187,6 @@ protected:
     double ht_diff;		 // value used by radar display instrument
 
     string model_path;	   //Path to the 3D model
-    osg::ref_ptr<osg::Node> model; //The 3D model object
     SGModelPlacement aip;
 
     bool delete_me;
@@ -222,6 +222,7 @@ private:
     int _refID;
     object_type _otype;
     bool _initialized;
+    osg::ref_ptr<osg::LOD> _model; //The 3D model LOD object
 
 public:
     object_type getType();
diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx
index 91ef65271..2ad548371 100644
--- a/src/AIModel/AIManager.cxx
+++ b/src/AIModel/AIManager.cxx
@@ -43,7 +43,12 @@
 #include "AIGroundVehicle.hxx"
 #include "AIEscort.hxx"
 
-FGAIManager::FGAIManager() {
+FGAIManager::FGAIManager() :
+    cb_ai_bare(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
+               fgGetNode("/sim/rendering/static-lod/ai-bare", true))),
+    cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
+                   fgGetNode("/sim/rendering/static-lod/ai-detailed", true)))
+{
     _dt = 0.0;
     mNumAiModels = 0;
 
@@ -181,6 +186,18 @@ FGAIManager::update(double dt) {
     thermal_lift_node->setDoubleValue( strength );  // for thermals
 }
 
+/** update LOD settings of all AI/MP models */
+void
+FGAIManager::updateLOD(SGPropertyNode* node)
+{
+    ai_list_iterator ai_list_itr = ai_list.begin();
+    while(ai_list_itr != ai_list.end())
+    {
+        (*ai_list_itr)->updateLOD();
+        ++ai_list_itr;
+    }
+}
+
 void
 FGAIManager::attach(FGAIBase *model)
 {
diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx
index d08bf17f0..5c951912e 100644
--- a/src/AIModel/AIManager.hxx
+++ b/src/AIModel/AIManager.hxx
@@ -27,6 +27,7 @@
 
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/props/props_io.hxx>
 
 #include <Main/fg_props.hxx>
 
@@ -66,6 +67,7 @@ public:
     void bind();
     void unbind();
     void update(double dt);
+    void updateLOD(SGPropertyNode* node);
     void attach(FGAIBase *model);
 
     void destroyObject( int ID );
@@ -135,6 +137,8 @@ private:
     double strength;
     void processThermal( FGAIThermal* thermal ); 
 
+    SGPropertyChangeCallback<FGAIManager> cb_ai_bare;
+    SGPropertyChangeCallback<FGAIManager> cb_ai_detailed;
 };
 
 #endif  // _FG_AIMANAGER_HXX

From 40d72b3ba752275feafe298b27f8fbf727b3e036 Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Mon, 3 Oct 2011 12:59:51 +0200
Subject: [PATCH 78/85] hla: use the property based interface from the property
 data element.

---
 src/Network/HLA/hla.cxx | 51 +++++++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx
index 4f5e85ffb..28102336b 100644
--- a/src/Network/HLA/hla.cxx
+++ b/src/Network/HLA/hla.cxx
@@ -323,6 +323,34 @@ private:
     ObjectClassConfigList _objectClassConfigList;
 };
 
+class PropertyReferenceSet : public SGReferenced {
+public:
+    void insert(const std::string& relativePath, const SGSharedPtr<sg::HLAPropertyDataElement>& dataElement)
+    {
+        if (_rootNode.valid())
+            dataElement->setPropertyNode(_rootNode->getNode(relativePath, true));
+        _pathDataElementPairList.push_back(PathDataElementPair(relativePath, dataElement));
+    }
+
+    void setRootNode(SGPropertyNode* rootNode)
+    {
+        _rootNode = rootNode;
+        for (PathDataElementPairList::iterator i = _pathDataElementPairList.begin();
+             i != _pathDataElementPairList.end(); ++i) {
+            i->second->setPropertyNode(_rootNode->getNode(i->first, true));
+        }
+    }
+    SGPropertyNode* getRootNode()
+    { return _rootNode.get(); }
+
+private:
+    SGSharedPtr<SGPropertyNode> _rootNode;
+
+    typedef std::pair<std::string, SGSharedPtr<sg::HLAPropertyDataElement> > PathDataElementPair;
+    typedef std::list<PathDataElementPair> PathDataElementPairList;
+    PathDataElementPairList _pathDataElementPairList;
+};
+
 class AbstractSimTime : public SGReferenced {
 public:
     virtual ~AbstractSimTime() {}
@@ -533,7 +561,7 @@ private:
 // Factory class that is used to create an apternative data element for the multiplayer property attribute
 class MPPropertyVariantDataElementFactory : public sg::HLAVariantArrayDataElement::AlternativeDataElementFactory {
 public:
-    MPPropertyVariantDataElementFactory(sg::HLAPropertyReferenceSet* propertyReferenceSet) :
+    MPPropertyVariantDataElementFactory(PropertyReferenceSet* propertyReferenceSet) :
         _propertyReferenceSet(propertyReferenceSet)
     { }
 
@@ -551,19 +579,19 @@ public:
 
         // The relative property path should be in the semantics field name
         std::string relativePath = dataType->getAlternativeSemantics(index);
-        sg::HLAPropertyReference* propertyReference = new sg::HLAPropertyReference(relativePath);
-        _propertyReferenceSet->insert(propertyReference);
-        return new sg::HLAPropertyDataElement(alternativeDataType, propertyReference);
+        sg::HLAPropertyDataElement* dataElement = new sg::HLAPropertyDataElement(alternativeDataType, (SGPropertyNode*)0);
+        _propertyReferenceSet->insert(relativePath, dataElement);
+        return dataElement;
     }
 
 private:
-    SGSharedPtr<sg::HLAPropertyReferenceSet> _propertyReferenceSet;
+    SGSharedPtr<PropertyReferenceSet> _propertyReferenceSet;
 };
 
 class MPAttributeCallback : public sg::HLAObjectInstance::AttributeCallback {
 public:
     MPAttributeCallback() :
-        _propertyReferenceSet(new sg::HLAPropertyReferenceSet),
+        _propertyReferenceSet(new PropertyReferenceSet),
         _mpProperties(new sg::HLAVariantArrayDataElement)
     {
         _mpProperties->setAlternativeDataElementFactory(new MPPropertyVariantDataElementFactory(_propertyReferenceSet.get()));
@@ -595,7 +623,7 @@ public:
     sg::HLAVariantArrayDataElement* getMPProperties() const
     { return _mpProperties.get(); }
 
-    SGSharedPtr<sg::HLAPropertyReferenceSet> _propertyReferenceSet;
+    SGSharedPtr<PropertyReferenceSet> _propertyReferenceSet;
 
 protected:
     SGSharedPtr<sg::HLAAbstractLocation> _location;
@@ -792,7 +820,7 @@ private:
 
         objectInstance.setAttributes(attributePathElementMap);
     }
-    void attachPropertyDataElements(sg::HLAPropertyReferenceSet& propertyReferenceSet,
+    void attachPropertyDataElements(PropertyReferenceSet& propertyReferenceSet,
                                     sg::HLAAttributePathElementMap& attributePathElementMap,
                                     const AttributePathPropertyMap& attributePathPropertyMap)
     {
@@ -800,10 +828,9 @@ private:
              i != attributePathPropertyMap.end(); ++i) {
             for (PathPropertyMap::const_iterator j = i->second.begin();
                  j != i->second.end(); ++j) {
-                SGSharedPtr<sg::HLAPropertyReference> propertyReference;
-                propertyReference = new sg::HLAPropertyReference(j->second);
-                propertyReferenceSet.insert(propertyReference);
-                attributePathElementMap[i->first][j->first] = new sg::HLAPropertyDataElement(propertyReference);
+                sg::HLAPropertyDataElement* dataElement = new sg::HLAPropertyDataElement;
+                propertyReferenceSet.insert(j->second, dataElement);
+                attributePathElementMap[i->first][j->first] = dataElement;
             }
         }
     }

From 4640f5bb025f2466184083803a31dc0b742f3d9c Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Mon, 3 Oct 2011 20:54:58 +0200
Subject: [PATCH 79/85] * A new algorithm for determining hold position
 instructions. This version still needs some finetuning, but already appears
 to be more solid than the old version. * Some tweaks to the traffic
 scheduling algorithm. * Misc cleanup.

---
 src/AIModel/AIAircraft.cxx         |  34 +-
 src/AIModel/AIFlightPlanCreate.cxx |   5 +
 src/ATC/atc_mgr.cxx                |   4 +-
 src/ATC/trafficcontrol.cxx         | 468 +++++++++++----------
 src/ATC/trafficcontrol.hxx         | 642 ++++++++++++++++++-----------
 src/Airports/dynamics.hxx          | 168 ++++----
 src/Airports/groundnetwork.cxx     | 453 +++++++++++++-------
 src/Airports/groundnetwork.hxx     | 401 ++++++++++--------
 src/Traffic/Schedule.cxx           |   4 +-
 9 files changed, 1301 insertions(+), 878 deletions(-)

diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
index be0556c85..98d2782f5 100644
--- a/src/AIModel/AIAircraft.cxx
+++ b/src/AIModel/AIAircraft.cxx
@@ -773,10 +773,10 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
     } 
     if (trafficRef) {
          //cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
-/*         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
               cerr << trafficRef->getCallSign() << " " << tgt_altitude_ft << " " << _getSpeed() << " " 
-                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl; 
-         }*/
+                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->getName() << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << " " << invisible << endl; 
+         }
      }
     if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
         minBearing = 360;
@@ -1223,20 +1223,20 @@ bool FGAIAircraft::reachedEndOfCruise(double &distance) {
         double distanceCovered   = descentSpeed * descentTimeNeeded; 
 
         //cerr << "Tracking  : " << fgGetString("/ai/track-callsign");
-        if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-            cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
-            cerr << "Descent rate      : " << descentRate << endl;
-            cerr << "Descent speed     : " << descentSpeed << endl;
-            cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
-            cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
-            cerr << "DistanceCovered   : " << distanceCovered   << endl;
-        }
+//         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+//             cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
+//             cerr << "Descent rate      : " << descentRate << endl;
+//             cerr << "Descent speed     : " << descentSpeed << endl;
+//             cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
+//             cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
+//             cerr << "DistanceCovered   : " << distanceCovered   << endl;
+//         }
         //cerr << "Distance = " << distance << endl;
         distance = distanceCovered;
         if (dist < distanceCovered) {
-              if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-                   //exit(1);
-              }
+//               if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+//                    //exit(1);
+//               }
               return true;
         } else {
               return false;
@@ -1290,8 +1290,8 @@ time_t FGAIAircraft::checkForArrivalTime(string wptName) {
      
      time_t ete = tracklength / ((speed * SG_NM_TO_METER) / 3600.0); 
      time_t secondsToGo = arrivalTime - now;
-     if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
-          cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
-     }
+//      if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
+//           cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
+//      }
      return (ete - secondsToGo); // Positive when we're too slow...
 }
diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx
index d53dc4bd0..075337470 100644
--- a/src/AIModel/AIFlightPlanCreate.cxx
+++ b/src/AIModel/AIFlightPlanCreate.cxx
@@ -62,6 +62,11 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
     case 1:
         retVal = createPushBack(ac, firstFlight, dep, latitude, longitude,
                                 radius, fltType, aircraftType, airline);
+        // Pregenerate the 
+        if (retVal) {
+            waypoints.back()->setName( waypoints.back()->getName() + string("legend")); 
+            retVal = createTakeoffTaxi(ac, false, dep, radius, fltType, aircraftType, airline);
+        }
         break;
     case 2:
         retVal =  createTakeoffTaxi(ac, firstFlight, dep, radius, fltType,
diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index 0345c2509..e4b73e161 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -247,5 +247,7 @@ void FGATCManager::update ( double time ) {
         //cerr << "Adding groundnetWork to the scenegraph::update" << endl;
         prevController = controller;
    }
-   //globals->get_scenery()->get_scene_graph()->addChild(node);
+   for (AtcVecIterator atc = activeStations.begin(); atc != activeStations.end(); atc++) {
+       (*atc)->update(time);
+   }
 }
diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx
index f2802d3b7..685df21da 100644
--- a/src/ATC/trafficcontrol.cxx
+++ b/src/ATC/trafficcontrol.cxx
@@ -65,7 +65,7 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
         TimeVectorIterator i = estimatedArrivalTimes.begin();
         //cerr << "Checking eta slots " << eta << ": " << endl;
         for (i = estimatedArrivalTimes.begin();
-             i != estimatedArrivalTimes.end(); i++) {
+                i != estimatedArrivalTimes.end(); i++) {
             //cerr << "Stored time : " << (*i) << endl;
         }
         i = estimatedArrivalTimes.begin();
@@ -144,18 +144,20 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
  * FGTrafficRecord
  **************************************************************************/
 FGTrafficRecord::FGTrafficRecord():
-id(0), waitsForId(0),
-currentPos(0),
-leg(0),
-frequencyId(0),
-state(0),
-allowTransmission(true),
-latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0)
+        id(0), waitsForId(0),
+        currentPos(0),
+        leg(0),
+        frequencyId(0),
+        state(0),
+        allowTransmission(true),
+        allowPushback(true),
+        priority(0),
+        latitude(0), longitude(0), heading(0), speed(0), altitude(0), radius(0)
 {
 }
 
 void FGTrafficRecord::setPositionAndIntentions(int pos,
-                                               FGAIFlightPlan * route)
+        FGAIFlightPlan * route)
 {
 
     currentPos = pos;
@@ -166,7 +168,7 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
                    "Error in FGTrafficRecord::setPositionAndIntentions");
             //cerr << "Pos : " << pos << " Curr " << *(intentions.begin())  << endl;
             for (intVecIterator i = intentions.begin();
-                 i != intentions.end(); i++) {
+                    i != intentions.end(); i++) {
                 //cerr << (*i) << " ";
             }
             //cerr << endl;
@@ -194,7 +196,7 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
     //exit(1);
 }
 /**
- * Check if another aircraft is ahead of the current one, and on the same 
+ * Check if another aircraft is ahead of the current one, and on the same
  * return true / false is the is/isn't the case.
  *
  ****************************************************************************/
@@ -207,10 +209,10 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
         //cerr << callsign << ": Check Position and intentions: we are on the same taxiway" << other.callsign << "Index = " << currentPos << endl;
         result = true;
     }
-    //  else if (other.intentions.size()) 
+    //  else if (other.intentions.size())
     //     {
     //       cerr << "Start check 2" << endl;
-    //       intVecIterator i = other.intentions.begin(); 
+    //       intVecIterator i = other.intentions.begin();
     //       while (!((i == other.intentions.end()) || ((*i) == currentPos)))
     //     i++;
     //       if (i != other.intentions.end()) {
@@ -237,8 +239,8 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
 }
 
 void FGTrafficRecord::setPositionAndHeading(double lat, double lon,
-                                            double hdg, double spd,
-                                            double alt)
+        double hdg, double spd,
+        double alt)
 {
     latitude = lat;
     longitude = lon;
@@ -251,12 +253,12 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
                              FGTrafficRecord & other)
 {
     if (checkPositionAndIntentions(other)
-        || (other.checkPositionAndIntentions(*this)))
+            || (other.checkPositionAndIntentions(*this)))
         return -1;
     intVecIterator i, j;
     int currentTargetNode = 0, otherTargetNode = 0;
     if (currentPos > 0)
-        currentTargetNode = net->findSegment(currentPos)->getEnd()->getIndex(); // OKAY,... 
+        currentTargetNode = net->findSegment(currentPos)->getEnd()->getIndex(); // OKAY,...
     if (other.currentPos > 0)
         otherTargetNode = net->findSegment(other.currentPos)->getEnd()->getIndex();     // OKAY,...
     if ((currentTargetNode == otherTargetNode) && currentTargetNode > 0)
@@ -265,7 +267,7 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
         for (i = intentions.begin(); i != intentions.end(); i++) {
             if ((*i) > 0) {
                 if ((currentTargetNode ==
-                     net->findSegment(*i)->getEnd()->getIndex())) {
+                        net->findSegment(*i)->getEnd()->getIndex())) {
                     //cerr << "Current crosses at " << currentTargetNode <<endl;
                     return currentTargetNode;
                 }
@@ -274,10 +276,10 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
     }
     if (other.intentions.size()) {
         for (i = other.intentions.begin(); i != other.intentions.end();
-             i++) {
+                i++) {
             if ((*i) > 0) {
                 if (otherTargetNode ==
-                    net->findSegment(*i)->getEnd()->getIndex()) {
+                        net->findSegment(*i)->getEnd()->getIndex()) {
                     //cerr << "Other crosses at " << currentTargetNode <<endl;
                     return otherTargetNode;
                 }
@@ -287,7 +289,7 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net,
     if (intentions.size() && other.intentions.size()) {
         for (i = intentions.begin(); i != intentions.end(); i++) {
             for (j = other.intentions.begin(); j != other.intentions.end();
-                 j++) {
+                    j++) {
                 //cerr << "finding segment " << *i << " and " << *j << endl;
                 if (((*i) > 0) && ((*j) > 0)) {
                     currentTargetNode =
@@ -318,7 +320,7 @@ bool FGTrafficRecord::onRoute(FGGroundNetwork * net,
         return true;
     if (other.intentions.size()) {
         for (intVecIterator i = other.intentions.begin();
-             i != other.intentions.end(); i++) {
+                i != other.intentions.end(); i++) {
             if (*i > 0) {
                 othernode = net->findSegment(*i)->getEnd()->getIndex();
                 if ((node == othernode) && (node > -1))
@@ -332,7 +334,7 @@ bool FGTrafficRecord::onRoute(FGGroundNetwork * net,
     //  {
     //    for (intVecIterator i = intentions.begin(); i != intentions.end(); i++)
     //    {
-    //      if (*i > 0) 
+    //      if (*i > 0)
     //        {
     //          node = net->findSegment(*i)->getEnd()->getIndex();
     //          if ((node == othernode) && (node > -1))
@@ -358,13 +360,13 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
         }
 
         for (intVecIterator i = intentions.begin(); i != intentions.end();
-             i++) {
+                i++) {
             if ((opp = net->findSegment(other.currentPos)->opposite())) {
                 if ((*i) > 0)
                     if (opp->getIndex() ==
-                        net->findSegment(*i)->getIndex()) {
+                            net->findSegment(*i)->getIndex()) {
                         if (net->findSegment(*i)->getStart()->getIndex() ==
-                            node) {
+                                node) {
                             {
                                 //cerr << "Found the node " << node << endl;
                                 return true;
@@ -374,17 +376,17 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
             }
             if (other.intentions.size()) {
                 for (intVecIterator j = other.intentions.begin();
-                     j != other.intentions.end(); j++) {
+                        j != other.intentions.end(); j++) {
                     // cerr << "Current segment 1 " << (*i) << endl;
                     if ((*i) > 0) {
                         if ((opp = net->findSegment(*i)->opposite())) {
                             if (opp->getIndex() ==
-                                net->findSegment(*j)->getIndex()) {
+                                    net->findSegment(*j)->getIndex()) {
                                 //cerr << "Nodes " << net->findSegment(*i)->getIndex()
                                 //   << " and  " << net->findSegment(*j)->getIndex()
                                 //   << " are opposites " << endl;
                                 if (net->findSegment(*i)->getStart()->
-                                    getIndex() == node) {
+                                        getIndex() == node) {
                                     {
                                         //cerr << "Found the node " << node << endl;
                                         return true;
@@ -400,6 +402,14 @@ bool FGTrafficRecord::isOpposing(FGGroundNetwork * net,
     return false;
 }
 
+bool FGTrafficRecord::isActive(int margin)
+{
+    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+    time_t deptime = aircraft->getTrafficRef()->getDepartureTime();
+    return ((now + margin) > deptime);
+}
+
+
 void FGTrafficRecord::setSpeedAdjustment(double spd)
 {
     instruction.setChangeSpeed(true);
@@ -414,31 +424,12 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
 
 bool FGTrafficRecord::pushBackAllowed()
 {
-    // With the user ATC / AI integration, checking whether the user's aircraft is near no longer works, because
-    // this will effectively block the user's aircraft itself from receiving pushback clearance. 
-    // So, what can we do?
-    /*
-    double course, az2, dist;
-    SGGeod curr(SGGeod::fromDegM(getLongitude(),
-                                 getLatitude(), getAltitude()));
-
-    double userLatitude = fgGetDouble("/position/latitude-deg");
-    double userLongitude = fgGetDouble("/position/longitude-deg");
-    SGGeod user(SGGeod::fromDeg(userLongitude, userLatitude));
-    SGGeodesy::inverse(curr, user, course, az2, dist);
-    //cerr << "Distance to user : " << dist << endl;
-    return (dist > 250);
-    */
-
-
-    // In essence, we should check whether the pusbback route itself, as well as the associcated
-    // taxiways near the pushback point are free of traffic. 
-    // To do so, we need to 
-    return true;
+    return allowPushback;
 }
 
 
 
+
 /***************************************************************************
  * FGATCInstruction
  *
@@ -483,7 +474,7 @@ FGATCController::FGATCController()
 
 FGATCController::~FGATCController()
 {
-     //cerr << "running FGATController destructor" << endl;
+    //cerr << "running FGATController destructor" << endl;
 }
 
 string FGATCController::getGateName(FGAIAircraft * ref)
@@ -491,9 +482,9 @@ string FGATCController::getGateName(FGAIAircraft * ref)
     return ref->atGate();
 }
 
-bool FGATCController::isUserAircraft(FGAIAircraft* ac) 
-{ 
-    return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false; 
+bool FGATCController::isUserAircraft(FGAIAircraft* ac)
+{
+    return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false;
 };
 
 void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
@@ -536,7 +527,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
         taxiFreq =
             rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
             getDynamics()->getGroundFrequency(2);
-        towerFreq = 
+        towerFreq =
             rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
             getDynamics()->getTowerFrequency(2);
         receiver =
@@ -585,11 +576,11 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
             getRunwayClassFromTrafficType(fltType);
 
         rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
-            getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
-                                           heading);
+        getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
+                                       heading);
         rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway);
         fp = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
-            getDynamics()->getSID(activeRunway, heading);
+             getDynamics()->getSID(activeRunway, heading);
         rec->getAircraft()->GetFlightPlan()->setSID(fp);
         if (fp) {
             SID = fp->getName() + " departure";
@@ -681,17 +672,17 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
     case MSG_REPORT_RUNWAY_HOLD_SHORT:
         activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
         //activeRunway = "test";
-        text = receiver + ". Holding short runway " 
-                        + activeRunway 
-                        + ". " + sender;
+        text = receiver + ". Holding short runway "
+               + activeRunway
+               + ". " + sender;
         //text = "test1";
         //cerr << "1 Currently at leg " << rec->getLeg() << endl;
         break;
     case MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT:
         activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
-        text = receiver + "Roger. Holding short runway " 
-        //                + activeRunway 
-                        + ". " + sender;
+        text = receiver + "Roger. Holding short runway "
+               //                + activeRunway
+               + ". " + sender;
         //text = "test2";
         //cerr << "2 Currently at leg " << rec->getLeg() << endl;
         break;
@@ -725,7 +716,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
         // the relevant frequency.
         // Note that distance attenuation is currently not yet implemented
         if ((onBoardRadioFreqI0 == stationFreq)
-            || (onBoardRadioFreqI1 == stationFreq)) {
+                || (onBoardRadioFreqI1 == stationFreq)) {
             if (rec->allowTransmissions()) {
                 fgSetString("/sim/messages/atc", text.c_str());
             }
@@ -743,7 +734,7 @@ string FGATCController::formatATCFrequency3_2(int freq)
 }
 
 // TODO: Set transponder codes according to real-world routes.
-// The current version just returns a random string of four octal numbers. 
+// The current version just returns a random string of four octal numbers.
 string FGATCController::genTransponderCode(string fltRules)
 {
     if (fltRules == "VFR") {
@@ -756,12 +747,12 @@ string FGATCController::genTransponderCode(string fltRules)
     }
 }
 
-void FGATCController::init() 
+void FGATCController::init()
 {
-   if (!initialized) {
-       FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
-       mgr->addController(this);
-       initialized = true;
+    if (!initialized) {
+        FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC");
+        mgr->addController(this);
+        initialized = true;
     }
 }
 
@@ -770,19 +761,19 @@ void FGATCController::init()
  *
  **************************************************************************/
 FGTowerController::FGTowerController(FGAirportDynamics *par) :
-FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
-// 
+//
 void FGTowerController::announcePosition(int id,
-                                         FGAIFlightPlan * intendedRoute,
-                                         int currentPosition, double lat,
-                                         double lon, double heading,
-                                         double speed, double alt,
-                                         double radius, int leg,
-                                         FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition, double lat,
+        double lon, double heading,
+        double speed, double alt,
+        double radius, int leg,
+        FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
@@ -809,7 +800,7 @@ void FGTowerController::announcePosition(int id,
         rec.setRadius(radius);
         rec.setAircraft(ref);
         activeTraffic.push_back(rec);
-        // Don't just schedule the aircraft for the tower controller, also assign if to the correct active runway. 
+        // Don't just schedule the aircraft for the tower controller, also assign if to the correct active runway.
         ActiveRunwayVecIterator rwy = activeRunways.begin();
         if (activeRunways.size()) {
             while (rwy != activeRunways.end()) {
@@ -835,8 +826,8 @@ void FGTowerController::announcePosition(int id,
 }
 
 void FGTowerController::updateAircraftInformation(int id, double lat, double lon,
-                                                  double heading, double speed, double alt,
-                                                  double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search whether the current id has an entry
@@ -863,7 +854,7 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
 
     // see if we already have a clearance record for the currently active runway
     // NOTE: dd. 2011-08-07: Because the active runway has been constructed in the announcePosition function, we may safely assume that is
-    // already exists here. So, we can simplify the current code. 
+    // already exists here. So, we can simplify the current code.
     ActiveRunwayVecIterator rwy = activeRunways.begin();
     while (rwy != activeRunways.end()) {
         if (rwy->getRunwayName() == current->getRunway()) {
@@ -899,6 +890,8 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
                 rwy->setCleared(id);
             }
         }
+    } else {
+        
     }
 }
 
@@ -947,7 +940,7 @@ void FGTowerController::signOff(int id)
 
 // NOTE:
 // IF WE MAKE TRAFFICRECORD A MEMBER OF THE BASE CLASS
-// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN 
+// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN
 // BECOME DEVIRTUALIZED AND BE A MEMBER OF THE BASE ATCCONTROLLER CLASS
 // WHICH WOULD SIMPLIFY CODE MAINTENANCE.
 // Note that this function is probably obsolete
@@ -1006,6 +999,11 @@ string FGTowerController::getName() {
     return string(parent->getId() + "-tower");
 }
 
+void FGTowerController::update(double dt)
+{
+
+}
+
 
 
 /***************************************************************************
@@ -1013,18 +1011,18 @@ string FGTowerController::getName() {
  *
  **************************************************************************/
 FGStartupController::FGStartupController(FGAirportDynamics *par):
-    FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
 void FGStartupController::announcePosition(int id,
-                                           FGAIFlightPlan * intendedRoute,
-                                           int currentPosition, double lat,
-                                           double lon, double heading,
-                                           double speed, double alt,
-                                           double radius, int leg,
-                                           FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition, double lat,
+        double lon, double heading,
+        double speed, double alt,
+        double radius, int leg,
+        FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
@@ -1061,7 +1059,7 @@ void FGStartupController::announcePosition(int id,
 
 // NOTE:
 // IF WE MAKE TRAFFICRECORD A MEMBER OF THE BASE CLASS
-// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN 
+// THE FOLLOWING THREE FUNCTIONS: SIGNOFF, HAS INSTRUCTION AND GETINSTRUCTION CAN
 // BECOME DEVIRTUALIZED AND BE A MEMBER OF THE BASE ATCCONTROLLER CLASS
 // WHICH WOULD SIMPLIFY CODE MAINTENANCE.
 // Note that this function is probably obsolete
@@ -1136,20 +1134,20 @@ void FGStartupController::signOff(int id)
 }
 
 bool FGStartupController::checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
-                               AtcMsgDir msgDir)
+        AtcMsgDir msgDir)
 {
     int state = i->getState();
     if ((state == st) && available) {
         if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) {
-            
+
             //cerr << "Checking state " << st << " for " << i->getAircraft()->getCallSign() << endl;
             static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
             int n = trans_num->getIntValue();
             if (n == 0) {
                 trans_num->setIntValue(-1);
-                 // PopupCallback(n);
-                 //cerr << "Selected transmission message " << n << endl;
-                 FGATCDialogNew::instance()->removeEntry(1);
+                // PopupCallback(n);
+                //cerr << "Selected transmission message " << n << endl;
+                FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), msgId, msgDir, false);
@@ -1169,8 +1167,8 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
 }
 
 void FGStartupController::updateAircraftInformation(int id, double lat, double lon,
-                                                    double heading, double speed, double alt,
-                                                    double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
@@ -1198,11 +1196,11 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
 
     int state = i->getState();
 
-    // The user controlled aircraft should have crased here, because it doesn't have a traffic reference. 
+    // The user controlled aircraft should have crased here, because it doesn't have a traffic reference.
     // NOTE: if we create a traffic schedule for the user aircraft, we can use this to plan a flight.
     time_t startTime = i->getAircraft()->getTrafficRef()->getDepartureTime();
     time_t now = time(NULL) + fgGetLong("/sim/time/warp");
-    //cerr << i->getAircraft()->getTrafficRef()->getCallSign() 
+    //cerr << i->getAircraft()->getTrafficRef()->getCallSign()
     //     << " is scheduled to depart in " << startTime-now << " seconds. Available = " << available
     //     << " at parking " << getGateName(i->getAircraft()) << endl;
 
@@ -1222,7 +1220,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
     checkTransmissionState(7, now, (startTime + 180), i, MSG_REQUEST_PUSHBACK_CLEARANCE,                ATC_AIR_TO_GROUND);
 
 
-   
+
     if ((state == 8) && available) {
         if (now > startTime + 200) {
             if (i->pushBackAllowed()) {
@@ -1269,10 +1267,10 @@ void FGStartupController::render(bool visible)
         //while (group->getNumChildren()) {
         //  cerr << "Number of children: " << group->getNumChildren() << endl;
         //simgear::EffectGeode* geode = (simgear::EffectGeode*) group->getChild(0);
-          //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
-           //geode->releaseGLObjects();
-           //group->removeChild(geode);
-           //delete geode;
+        //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
+        //geode->releaseGLObjects();
+        //group->removeChild(geode);
+        //delete geode;
         group = 0;
     }
     if (visible) {
@@ -1285,135 +1283,64 @@ void FGStartupController::render(bool visible)
         //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
         double dx = 0;
         for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
-            // Handle start point
-            int pos = i->getCurrentPosition();
-            //cerr << "rendering for " << i->getAircraft()->getCallSign() << "pos = " << pos << endl;
-            if (pos > 0) {
-                FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(pos);
-                SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
-                SGGeod end  (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude()));
+            if (i->isActive(300)) {
+                // Handle start point
+                int pos = i->getCurrentPosition();
+                //cerr << "rendering for " << i->getAircraft()->getCallSign() << "pos = " << pos << endl;
+                if (pos > 0) {
+                    FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(pos);
+                    SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
+                    SGGeod end  (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude()));
 
-                double length = SGGeodesy::distanceM(start, end);
-                //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
+                    double length = SGGeodesy::distanceM(start, end);
+                    //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
 
-                double az2, heading; //, distanceM;
-                SGGeodesy::inverse(start, end, heading, az2, length);
-                double coveredDistance = length * 0.5;
-                SGGeod center;
-                SGGeodesy::direct(start, heading, coveredDistance, center, az2);
-                //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
-                ///////////////////////////////////////////////////////////////////////////////
-                // Make a helper function out of this
-                osg::Matrix obj_pos;
-                osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
-                obj_trans->setDataVariance(osg::Object::STATIC);
-                // Experimental: Calculate slope here, based on length, and the individual elevations
-                double elevationStart;
-                if (isUserAircraft((i)->getAircraft())) {
-                    elevationStart = fgGetDouble("/position/ground-elev-m");
-                } else {
-                    elevationStart = ((i)->getAircraft()->_getAltitude()); 
-                }
-                double elevationEnd   = segment->getEnd()->getElevation();
-                if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
-                    SGGeod center2 = end;
-                    center2.setElevationM(SG_MAX_ELEVATION_M);
-                    if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
-                        elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
-                            //elevation_meters += 0.5;
-                    }
-                    else { 
-                        elevationEnd = parent->getElevation();
-                    }
-                    segment->getEnd()->setElevation(elevationEnd);
-                }
-
-                double elevationMean  = (elevationStart + elevationEnd) / 2.0;
-                double elevDiff       = elevationEnd - elevationStart;
-               
-               double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-               //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
-
-                WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), elevationMean + 0.5, -(heading), slope );
-;
-
-                obj_trans->setMatrix( obj_pos );
-                //osg::Vec3 center(0, 0, 0)
-
-                float width = length /2.0;
-                osg::Vec3 corner(-width, 0, 0.25f);
-                osg::Vec3 widthVec(2*width + 1, 0, 0);
-                osg::Vec3 heightVec(0, 1, 0);
-                osg::Geometry* geometry;
-                geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
-                simgear::EffectGeode* geode = new simgear::EffectGeode;
-                geode->setName("test");
-                geode->addDrawable(geometry);
-                //osg::Node *custom_obj;
-                SGMaterial *mat = matlib->find("UnidirectionalTaper");
-                if (mat)
-                    geode->setEffect(mat->get_effect());
-                obj_trans->addChild(geode);
-                // wire as much of the scene graph together as we can
-                //->addChild( obj_trans );
-                group->addChild( obj_trans );
-                /////////////////////////////////////////////////////////////////////
-            } else {
-                //cerr << "BIG FAT WARNING: current position is here : " << pos << endl;
-            }
-            for(intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
-                osg::Matrix obj_pos;
-                int k = (*j);
-                if (k > 0) {
-                    //cerr << "rendering for " << i->getAircraft()->getCallSign() << "intention = " << k << endl;
+                    double az2, heading; //, distanceM;
+                    SGGeodesy::inverse(start, end, heading, az2, length);
+                    double coveredDistance = length * 0.5;
+                    SGGeod center;
+                    SGGeodesy::direct(start, heading, coveredDistance, center, az2);
+                    //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
+                    ///////////////////////////////////////////////////////////////////////////////
+                    // Make a helper function out of this
+                    osg::Matrix obj_pos;
                     osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
                     obj_trans->setDataVariance(osg::Object::STATIC);
-                    FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(k);
-
-                    double elevationStart = segment->getStart()->getElevation();
-                    double elevationEnd   = segment->getEnd  ()->getElevation();
-                    if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
-                        SGGeod center2 = segment->getStart()->getGeod();
-                        center2.setElevationM(SG_MAX_ELEVATION_M);
-                        if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
-                            elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
-                            //elevation_meters += 0.5;
-                        }
-                        else { 
-                            elevationStart = parent->getElevation();
-                        }
-                        segment->getStart()->setElevation(elevationStart);
+                    // Experimental: Calculate slope here, based on length, and the individual elevations
+                    double elevationStart;
+                    if (isUserAircraft((i)->getAircraft())) {
+                        elevationStart = fgGetDouble("/position/ground-elev-m");
+                    } else {
+                        elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER);
                     }
+                    double elevationEnd   = segment->getEnd()->getElevation();
                     if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
-                        SGGeod center2 = segment->getEnd()->getGeod();
+                        SGGeod center2 = end;
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
                             elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
                             //elevation_meters += 0.5;
                         }
-                        else { 
+                        else {
                             elevationEnd = parent->getElevation();
                         }
                         segment->getEnd()->setElevation(elevationEnd);
                     }
- 
+
                     double elevationMean  = (elevationStart + elevationEnd) / 2.0;
                     double elevDiff       = elevationEnd - elevationStart;
-                    double length         = segment->getLength();
+
                     double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-                    //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
+                    //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
-                    WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5, -(segment->getHeading()), slope );
-
-                    //WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
+                    WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), elevationMean + 0.5 + dx, -(heading), slope );
+                    ;
 
                     obj_trans->setMatrix( obj_pos );
                     //osg::Vec3 center(0, 0, 0)
 
-                    float width = segment->getLength() /2.0;
+                    float width = length /2.0;
                     osg::Vec3 corner(-width, 0, 0.25f);
                     osg::Vec3 widthVec(2*width + 1, 0, 0);
                     osg::Vec3 heightVec(0, 1, 0);
@@ -1423,18 +1350,101 @@ void FGStartupController::render(bool visible)
                     geode->setName("test");
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
-                    SGMaterial *mat = matlib->find("UnidirectionalTaper");
+                    SGMaterial *mat;
+                    if (segment->hasBlock()) {
+                        mat = matlib->find("UnidirectionalTaperRed");
+                    } else {
+                        mat = matlib->find("UnidirectionalTaperGreen");
+                    }
                     if (mat)
                         geode->setEffect(mat->get_effect());
                     obj_trans->addChild(geode);
                     // wire as much of the scene graph together as we can
                     //->addChild( obj_trans );
                     group->addChild( obj_trans );
+                    /////////////////////////////////////////////////////////////////////
                 } else {
-                    //cerr << "BIG FAT WARNING: k is here : " << pos << endl;
+                    //cerr << "BIG FAT WARNING: current position is here : " << pos << endl;
                 }
+                for (intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
+                    osg::Matrix obj_pos;
+                    int k = (*j);
+                    if (k > 0) {
+                        //cerr << "rendering for " << i->getAircraft()->getCallSign() << "intention = " << k << endl;
+                        osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
+                        obj_trans->setDataVariance(osg::Object::STATIC);
+                        FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(k);
+
+                        double elevationStart = segment->getStart()->getElevation();
+                        double elevationEnd   = segment->getEnd  ()->getElevation();
+                        if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
+                            SGGeod center2 = segment->getStart()->getGeod();
+                            center2.setElevationM(SG_MAX_ELEVATION_M);
+                            if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
+                                elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
+                                //elevation_meters += 0.5;
+                            }
+                            else {
+                                elevationStart = parent->getElevation();
+                            }
+                            segment->getStart()->setElevation(elevationStart);
+                        }
+                        if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
+                            SGGeod center2 = segment->getEnd()->getGeod();
+                            center2.setElevationM(SG_MAX_ELEVATION_M);
+                            if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
+                                elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
+                                //elevation_meters += 0.5;
+                            }
+                            else {
+                                elevationEnd = parent->getElevation();
+                            }
+                            segment->getEnd()->setElevation(elevationEnd);
+                        }
+
+                        double elevationMean  = (elevationStart + elevationEnd) / 2.0;
+                        double elevDiff       = elevationEnd - elevationStart;
+                        double length         = segment->getLength();
+                        double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
+
+                        //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
+
+
+                        WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
+
+                        //WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
+
+                        obj_trans->setMatrix( obj_pos );
+                        //osg::Vec3 center(0, 0, 0)
+
+                        float width = segment->getLength() /2.0;
+                        osg::Vec3 corner(-width, 0, 0.25f);
+                        osg::Vec3 widthVec(2*width + 1, 0, 0);
+                        osg::Vec3 heightVec(0, 1, 0);
+                        osg::Geometry* geometry;
+                        geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
+                        simgear::EffectGeode* geode = new simgear::EffectGeode;
+                        geode->setName("test");
+                        geode->addDrawable(geometry);
+                        //osg::Node *custom_obj;
+                        SGMaterial *mat;
+                        if (segment->hasBlock()) {
+                            mat = matlib->find("UnidirectionalTaperRed");
+                        } else {
+                            mat = matlib->find("UnidirectionalTaperGreen");
+                        }
+                        if (mat)
+                            geode->setEffect(mat->get_effect());
+                        obj_trans->addChild(geode);
+                        // wire as much of the scene graph together as we can
+                        //->addChild( obj_trans );
+                        group->addChild( obj_trans );
+                    } else {
+                        //cerr << "BIG FAT WARNING: k is here : " << pos << endl;
+                    }
+                }
+                dx += 0.2;
             }
-            //dx += 0.1;
         }
         globals->get_scenery()->get_scene_graph()->addChild(group);
     }
@@ -1444,25 +1454,31 @@ string FGStartupController::getName() {
     return string(parent->getId() + "-startup");
 }
 
+void FGStartupController::update(double dt)
+{
+
+}
+
+
 
 /***************************************************************************
  * class FGApproachController
  *
  **************************************************************************/
 FGApproachController::FGApproachController(FGAirportDynamics *par):
-FGATCController()
+        FGATCController()
 {
     parent = par;
 }
 
-// 
+//
 void FGApproachController::announcePosition(int id,
-                                            FGAIFlightPlan * intendedRoute,
-                                            int currentPosition,
-                                            double lat, double lon,
-                                            double heading, double speed,
-                                            double alt, double radius,
-                                            int leg, FGAIAircraft * ref)
+        FGAIFlightPlan * intendedRoute,
+        int currentPosition,
+        double lat, double lon,
+        double heading, double speed,
+        double alt, double radius,
+        int leg, FGAIAircraft * ref)
 {
     init();
     TrafficVectorIterator i = activeTraffic.begin();
@@ -1494,8 +1510,8 @@ void FGApproachController::announcePosition(int id,
 }
 
 void FGApproachController::updateAircraftInformation(int id, double lat, double lon,
-                                                     double heading, double speed, double alt,
-                                                     double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     TrafficVectorIterator i = activeTraffic.begin();
     // Search search if the current id has an entry
@@ -1567,6 +1583,10 @@ void FGApproachController::signOff(int id)
     }
 }
 
+void FGApproachController::update(double dt)
+{
+
+}
 
 
 
diff --git a/src/ATC/trafficcontrol.hxx b/src/ATC/trafficcontrol.hxx
index 6aae0ab9e..e4ce4c6bb 100644
--- a/src/ATC/trafficcontrol.hxx
+++ b/src/ATC/trafficcontrol.hxx
@@ -38,11 +38,14 @@
 #include <simgear/structure/SGReferenced.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 
+
 #include <string>
 #include <vector>
+#include <list>
 
 using std::string;
 using std::vector;
+using std::list;
 
 
 typedef vector<int> intVec;
@@ -62,43 +65,79 @@ class FGAirportDynamics;
 class FGATCInstruction
 {
 private:
-  bool holdPattern;
-  bool holdPosition;
-  bool changeSpeed;
-  bool changeHeading;
-  bool changeAltitude;
-  bool resolveCircularWait;
+    bool holdPattern;
+    bool holdPosition;
+    bool changeSpeed;
+    bool changeHeading;
+    bool changeAltitude;
+    bool resolveCircularWait;
 
-  double speed;
-  double heading;
-  double alt;
+    double speed;
+    double heading;
+    double alt;
 public:
 
-  FGATCInstruction();
-  bool hasInstruction   ();
-  bool getHoldPattern   () { return holdPattern;    };
-  bool getHoldPosition  () { return holdPosition;   };
-  bool getChangeSpeed   () { return changeSpeed;    };
-  bool getChangeHeading () { return changeHeading;  };
-  bool getChangeAltitude() { return changeAltitude; };
+    FGATCInstruction();
+    bool hasInstruction   ();
+    bool getHoldPattern   () {
+        return holdPattern;
+    };
+    bool getHoldPosition  () {
+        return holdPosition;
+    };
+    bool getChangeSpeed   () {
+        return changeSpeed;
+    };
+    bool getChangeHeading () {
+        return changeHeading;
+    };
+    bool getChangeAltitude() {
+        return changeAltitude;
+    };
 
-  double getSpeed       () { return speed; };
-  double getHeading     () { return heading; };
-  double getAlt         () { return alt; };
+    double getSpeed       () {
+        return speed;
+    };
+    double getHeading     () {
+        return heading;
+    };
+    double getAlt         () {
+        return alt;
+    };
 
-  bool getCheckForCircularWait() { return resolveCircularWait; };
+    bool getCheckForCircularWait() {
+        return resolveCircularWait;
+    };
 
-  void setHoldPattern   (bool val) { holdPattern    = val; };
-  void setHoldPosition  (bool val) { holdPosition   = val; };
-  void setChangeSpeed   (bool val) { changeSpeed    = val; };
-  void setChangeHeading (bool val) { changeHeading  = val; };
-  void setChangeAltitude(bool val) { changeAltitude = val; };
+    void setHoldPattern   (bool val) {
+        holdPattern    = val;
+    };
+    void setHoldPosition  (bool val) {
+        holdPosition   = val;
+    };
+    void setChangeSpeed   (bool val) {
+        changeSpeed    = val;
+    };
+    void setChangeHeading (bool val) {
+        changeHeading  = val;
+    };
+    void setChangeAltitude(bool val) {
+        changeAltitude = val;
+    };
 
-  void setResolveCircularWait (bool val) { resolveCircularWait = val; }; 
+    void setResolveCircularWait (bool val) {
+        resolveCircularWait = val;
+    };
 
-  void setSpeed       (double val) { speed   = val; };
-  void setHeading     (double val) { heading = val; };
-  void setAlt         (double val) { alt     = val; };
+    void setSpeed       (double val) {
+        speed   = val;
+    };
+    void setHeading     (double val) {
+        heading = val;
+    };
+    void setAlt         (double val) {
+        alt     = val;
+    };
 };
 
 
@@ -111,88 +150,175 @@ public:
 class FGTrafficRecord
 {
 private:
-  int id, waitsForId;
-  int currentPos;
-  int leg;
-  int frequencyId;
-  int state;
-  bool allowTransmission;
-  time_t timer;
-  intVec intentions;
-  FGATCInstruction instruction;
-  double latitude, longitude, heading, speed, altitude, radius;
-  string runway;
-  //FGAISchedule *trafficRef;
-  FGAIAircraft *aircraft;
-  
-  
+    int id, waitsForId;
+    int currentPos;
+    int leg;
+    int frequencyId;
+    int state;
+    bool allowTransmission;
+    bool allowPushback;
+    int priority;
+    time_t timer;
+    intVec intentions;
+    FGATCInstruction instruction;
+    double latitude, longitude, heading, speed, altitude, radius;
+    string runway;
+    //FGAISchedule *trafficRef;
+    FGAIAircraft *aircraft;
+
+
 public:
-  FGTrafficRecord();
-  
-  void setId(int val)  { id = val; };
-  void setRadius(double rad) { radius = rad;};
-  void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
-  void setRunway(string rwy) { runway = rwy;};
-  void setLeg(int lg) { leg = lg;};
-  int getId() { return id;};
-  int getState() { return state;};
-  void setState(int s) { state = s;}
-  FGATCInstruction getInstruction() { return instruction;};
-  bool hasInstruction() { return instruction.hasInstruction(); };
-  void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
-  bool checkPositionAndIntentions(FGTrafficRecord &other);
-  int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other); 
-  bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
+    FGTrafficRecord();
 
-  bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
+    void setId(int val)  {
+        id = val;
+    };
+    void setRadius(double rad) {
+        radius = rad;
+    };
+    void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
+    void setRunway(string rwy) {
+        runway = rwy;
+    };
+    void setLeg(int lg) {
+        leg = lg;
+    };
+    int getId() {
+        return id;
+    };
+    int getState() {
+        return state;
+    };
+    void setState(int s) {
+        state = s;
+    }
+    FGATCInstruction getInstruction() {
+        return instruction;
+    };
+    bool hasInstruction() {
+        return instruction.hasInstruction();
+    };
+    void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
+    bool checkPositionAndIntentions(FGTrafficRecord &other);
+    int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other);
+    bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
+    
+    bool isActive(int margin);
 
-  bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
-  
-  double getLatitude () { return latitude ; };
-  double getLongitude() { return longitude; };
-  double getHeading  () { return heading  ; };
-  double getSpeed    () { return speed    ; };
-  double getAltitude () { return altitude ; };
-  double getRadius   () { return radius   ; };
+    bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
 
-  int getWaitsForId  () { return waitsForId; };
+    bool getSpeedAdjustment() {
+        return instruction.getChangeSpeed();
+    };
 
-  void setSpeedAdjustment(double spd);
-  void setHeadingAdjustment(double heading);
-  void clearSpeedAdjustment  () { instruction.setChangeSpeed  (false); };
-  void clearHeadingAdjustment() { instruction.setChangeHeading(false); };
+    double getLatitude () {
+        return latitude ;
+    };
+    double getLongitude() {
+        return longitude;
+    };
+    double getHeading  () {
+        return heading  ;
+    };
+    double getSpeed    () {
+        return speed    ;
+    };
+    double getAltitude () {
+        return altitude ;
+    };
+    double getRadius   () {
+        return radius   ;
+    };
 
-  bool hasHeadingAdjustment() { return instruction.getChangeHeading(); };
-  bool hasHoldPosition() { return instruction.getHoldPosition(); };
-  void setHoldPosition (bool inst) { instruction.setHoldPosition(inst); };
+    int getWaitsForId  () {
+        return waitsForId;
+    };
 
-  void setWaitsForId(int id) { waitsForId = id; };
+    void setSpeedAdjustment(double spd);
+    void setHeadingAdjustment(double heading);
+    void clearSpeedAdjustment  () {
+        instruction.setChangeSpeed  (false);
+    };
+    void clearHeadingAdjustment() {
+        instruction.setChangeHeading(false);
+    };
 
-  void setResolveCircularWait()   { instruction.setResolveCircularWait(true);  };
-  void clearResolveCircularWait() { instruction.setResolveCircularWait(false); };
+    bool hasHeadingAdjustment() {
+        return instruction.getChangeHeading();
+    };
+    bool hasHoldPosition() {
+        return instruction.getHoldPosition();
+    };
+    void setHoldPosition (bool inst) {
+        instruction.setHoldPosition(inst);
+    };
 
-  string getRunway() { return runway; };
-  //void setCallSign(string clsgn) { callsign = clsgn; };
-  void setAircraft(FGAIAircraft *ref) { aircraft = ref;};
-  void updateState() { state++; allowTransmission=true; };
-  //string getCallSign() { return callsign; };
-  FGAIAircraft *getAircraft() { return aircraft;};
-  int getTime() { return timer; };
-  int getLeg() { return leg; };
-  void setTime(time_t time) { timer = time; };
+    void setWaitsForId(int id) {
+        waitsForId = id;
+    };
 
-  bool pushBackAllowed();
-  bool allowTransmissions() { return allowTransmission; };
-  void suppressRepeatedTransmissions () { allowTransmission=false; };
-  void allowRepeatedTransmissions () { allowTransmission=true; };
-  void nextFrequency() { frequencyId++; };
-  int  getNextFrequency() { return frequencyId; };
-  intVec& getIntentions() { return intentions; };
-  int getCurrentPosition() { return currentPos; };
+    void setResolveCircularWait()   {
+        instruction.setResolveCircularWait(true);
+    };
+    void clearResolveCircularWait() {
+        instruction.setResolveCircularWait(false);
+    };
+
+    string getRunway() {
+        return runway;
+    };
+    //void setCallSign(string clsgn) { callsign = clsgn; };
+    void setAircraft(FGAIAircraft *ref) {
+        aircraft = ref;
+    };
+    void updateState() {
+        state++;
+        allowTransmission=true;
+    };
+    //string getCallSign() { return callsign; };
+    FGAIAircraft *getAircraft() {
+        return aircraft;
+    };
+    int getTime() {
+        return timer;
+    };
+    int getLeg() {
+        return leg;
+    };
+    void setTime(time_t time) {
+        timer = time;
+    };
+
+    bool pushBackAllowed();
+    bool allowTransmissions() {
+        return allowTransmission;
+    };
+    void allowPushBack() { allowPushback =true;};
+    void denyPushBack () { allowPushback = false;};
+    void suppressRepeatedTransmissions () {
+        allowTransmission=false;
+    };
+    void allowRepeatedTransmissions () {
+        allowTransmission=true;
+    };
+    void nextFrequency() {
+        frequencyId++;
+    };
+    int  getNextFrequency() {
+        return frequencyId;
+    };
+    intVec& getIntentions() {
+        return intentions;
+    };
+    int getCurrentPosition() {
+        return currentPos;
+    };
+    void setPriority(int p) { priority = p; };
+    int getPriority()       { return priority; };
 };
 
-typedef vector<FGTrafficRecord> TrafficVector;
-typedef vector<FGTrafficRecord>::iterator TrafficVectorIterator;
+typedef list<FGTrafficRecord> TrafficVector;
+typedef list<FGTrafficRecord>::iterator TrafficVectorIterator;
 
 typedef vector<time_t> TimeVector;
 typedef vector<time_t>::iterator TimeVectorIterator;
@@ -207,28 +333,48 @@ typedef vector<FGAIAircraft*>::iterator AircraftVecIterator;
 class ActiveRunway
 {
 private:
-  string rwy;
-  int currentlyCleared;
-  double distanceToFinal;
-  TimeVector estimatedArrivalTimes;
-  AircraftVec departureCue;
+    string rwy;
+    int currentlyCleared;
+    double distanceToFinal;
+    TimeVector estimatedArrivalTimes;
+    AircraftVec departureCue;
 
 public:
-  ActiveRunway(string r, int cc) { rwy = r; currentlyCleared = cc; distanceToFinal = 6.0 * SG_NM_TO_METER; };
-  
-  string getRunwayName() { return rwy; };
-  int    getCleared   () { return currentlyCleared; };
-  double getApproachDistance() { return distanceToFinal; };
-  //time_t getEstApproachTime() { return estimatedArrival; };
+    ActiveRunway(string r, int cc) {
+        rwy = r;
+        currentlyCleared = cc;
+        distanceToFinal = 6.0 * SG_NM_TO_METER;
+    };
 
-  //void setEstApproachTime(time_t time) { estimatedArrival = time; };
-  void addToDepartureCue(FGAIAircraft *ac) { departureCue.push_back(ac); };
-  void setCleared(int number) { currentlyCleared = number; };
-  time_t requestTimeSlot(time_t eta);
+    string getRunwayName() {
+        return rwy;
+    };
+    int    getCleared   () {
+        return currentlyCleared;
+    };
+    double getApproachDistance() {
+        return distanceToFinal;
+    };
+    //time_t getEstApproachTime() { return estimatedArrival; };
 
-   int getDepartureCueSize() { return departureCue.size(); };
-   FGAIAircraft* getFirstAircraftInDepartureCue() { return departureCue.size() ? *(departureCue.begin()) : NULL; };
-   void updateDepartureCue() { departureCue.erase(departureCue.begin()); }
+    //void setEstApproachTime(time_t time) { estimatedArrival = time; };
+    void addToDepartureCue(FGAIAircraft *ac) {
+        departureCue.push_back(ac);
+    };
+    void setCleared(int number) {
+        currentlyCleared = number;
+    };
+    time_t requestTimeSlot(time_t eta);
+
+    int getDepartureCueSize() {
+        return departureCue.size();
+    };
+    FGAIAircraft* getFirstAircraftInDepartureCue() {
+        return departureCue.size() ? *(departureCue.begin()) : NULL;
+    };
+    void updateDepartureCue() {
+        departureCue.erase(departureCue.begin());
+    }
 };
 
 typedef vector<ActiveRunway> ActiveRunwayVec;
@@ -236,79 +382,86 @@ typedef vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
 
 /**
  * class FGATCController
- * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers. 
+ * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
  *************************************************************************************/
 class FGATCController
 {
 private:
-    
+
 
 protected:
-  bool initialized;
-  bool available;
-  time_t lastTransmission;
+    bool initialized;
+    bool available;
+    time_t lastTransmission;
 
-  double dt_count;
-  osg::Group* group;
+    double dt_count;
+    osg::Group* group;
 
-  string formatATCFrequency3_2(int );
-  string genTransponderCode(string fltRules);
-  bool isUserAircraft(FGAIAircraft*); 
+    string formatATCFrequency3_2(int );
+    string genTransponderCode(string fltRules);
+    bool isUserAircraft(FGAIAircraft*);
 
 public:
-  typedef enum {
-      MSG_ANNOUNCE_ENGINE_START,
-      MSG_REQUEST_ENGINE_START,
-      MSG_PERMIT_ENGINE_START,
-      MSG_DENY_ENGINE_START,
-      MSG_ACKNOWLEDGE_ENGINE_START,
-      MSG_REQUEST_PUSHBACK_CLEARANCE,
-      MSG_PERMIT_PUSHBACK_CLEARANCE,
-      MSG_HOLD_PUSHBACK_CLEARANCE,
-      MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
-      MSG_INITIATE_CONTACT,
-      MSG_ACKNOWLEDGE_INITIATE_CONTACT,
-      MSG_REQUEST_TAXI_CLEARANCE,
-      MSG_ISSUE_TAXI_CLEARANCE,
-      MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
-      MSG_HOLD_POSITION,
-      MSG_ACKNOWLEDGE_HOLD_POSITION,
-      MSG_RESUME_TAXI,
-      MSG_ACKNOWLEDGE_RESUME_TAXI,
-      MSG_REPORT_RUNWAY_HOLD_SHORT,
-      MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
-      MSG_SWITCH_TOWER_FREQUENCY,
-      MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
-  } AtcMsgId;
+    typedef enum {
+        MSG_ANNOUNCE_ENGINE_START,
+        MSG_REQUEST_ENGINE_START,
+        MSG_PERMIT_ENGINE_START,
+        MSG_DENY_ENGINE_START,
+        MSG_ACKNOWLEDGE_ENGINE_START,
+        MSG_REQUEST_PUSHBACK_CLEARANCE,
+        MSG_PERMIT_PUSHBACK_CLEARANCE,
+        MSG_HOLD_PUSHBACK_CLEARANCE,
+        MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
+        MSG_INITIATE_CONTACT,
+        MSG_ACKNOWLEDGE_INITIATE_CONTACT,
+        MSG_REQUEST_TAXI_CLEARANCE,
+        MSG_ISSUE_TAXI_CLEARANCE,
+        MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
+        MSG_HOLD_POSITION,
+        MSG_ACKNOWLEDGE_HOLD_POSITION,
+        MSG_RESUME_TAXI,
+        MSG_ACKNOWLEDGE_RESUME_TAXI,
+        MSG_REPORT_RUNWAY_HOLD_SHORT,
+        MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
+        MSG_SWITCH_TOWER_FREQUENCY,
+        MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
+    } AtcMsgId;
 
-  typedef enum {
-      ATC_AIR_TO_GROUND,
-      ATC_GROUND_TO_AIR } AtcMsgDir;
-  FGATCController();
-  virtual ~FGATCController();
-  void init();
+    typedef enum {
+        ATC_AIR_TO_GROUND,
+        ATC_GROUND_TO_AIR
+    } AtcMsgDir;
+    FGATCController();
+    virtual ~FGATCController();
+    void init();
 
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-                                double lat, double lon,
-                                double hdg, double spd, double alt, double radius, int leg,
-                                FGAIAircraft *aircraft) = 0;
-  virtual void             signOff(int id) = 0;
-  virtual void             updateAircraftInformation(int id, double lat, double lon, 
-                                                     double heading, double speed, double alt, double dt) = 0;
-  virtual bool             hasInstruction(int id) = 0;
-  virtual FGATCInstruction getInstruction(int id) = 0;
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft) = 0;
+    virtual void             signOff(int id) = 0;
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt) = 0;
+    virtual bool             hasInstruction(int id) = 0;
+    virtual FGATCInstruction getInstruction(int id) = 0;
 
-  double getDt() { return dt_count; };
-  void   setDt(double dt) { dt_count = dt;};
-  void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
-  string getGateName(FGAIAircraft *aircraft);
-  virtual void render(bool) = 0;
-  virtual string getName()  = 0;
+    double getDt() {
+        return dt_count;
+    };
+    void   setDt(double dt) {
+        dt_count = dt;
+    };
+    void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
+    string getGateName(FGAIAircraft *aircraft);
+    virtual void render(bool) = 0;
+    virtual string getName()  = 0;
+
+    virtual void update(double) = 0;
 
 
 private:
 
- AtcMsgDir lastTransmissionDirection;
+    AtcMsgDir lastTransmissionDirection;
 };
 
 /******************************************************************************
@@ -317,65 +470,75 @@ private:
 class FGTowerController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  ActiveRunwayVec activeRunways;
-  FGAirportDynamics *parent;
-  
-public:
-  FGTowerController(FGAirportDynamics *parent);
-  virtual ~FGTowerController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-				double lat, double lon,
-				double hdg, double spd, double alt, double radius, int leg,
-				FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             updateAircraftInformation(int id, double lat, double lon, 
-				  double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
+    TrafficVector activeTraffic;
+    ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
 
-  virtual void render(bool);
-  virtual string getName();
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
+public:
+    FGTowerController(FGAirportDynamics *parent);
+    virtual ~FGTowerController() {};
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
+
+    virtual void render(bool);
+    virtual string getName();
+    virtual void update(double dt);
+    bool hasActiveTraffic() {
+        return activeTraffic.size() != 0;
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
 };
 
 /******************************************************************************
  * class FGStartupController
- * handle 
+ * handle
  *****************************************************************************/
 
 class FGStartupController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  //ActiveRunwayVec activeRunways;
-  FGAirportDynamics *parent;
-  
+    TrafficVector activeTraffic;
+    //ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
+
 public:
-  FGStartupController(FGAirportDynamics *parent);
-  virtual ~FGStartupController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-				double lat, double lon,
-				double hdg, double spd, double alt, double radius, int leg,
-				FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             updateAircraftInformation(int id, double lat, double lon, 
-				  double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
+    FGStartupController(FGAirportDynamics *parent);
+    virtual ~FGStartupController() {};
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
 
-  virtual void render(bool);
-  virtual string getName();
+    virtual void render(bool);
+    virtual string getName();
+    virtual void update(double dt);
 
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
+    bool hasActiveTraffic() {
+        return activeTraffic.size() != 0;
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
 
-  // Hpoefully, we can move this function to the base class, but I need to verify what is needed for the other controllers before doing so.
-  bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
-                               AtcMsgDir msgDir);
+    // Hpoefully, we can move this function to the base class, but I need to verify what is needed for the other controllers before doing so.
+    bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
+                                AtcMsgDir msgDir);
 
-}; 
+};
 
 /******************************************************************************
  * class FGTowerControl
@@ -383,30 +546,35 @@ public:
 class FGApproachController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  ActiveRunwayVec activeRunways;
-  FGAirportDynamics *parent;
-  
+    TrafficVector activeTraffic;
+    ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
+
 public:
-  FGApproachController(FGAirportDynamics * parent);
-  virtual ~FGApproachController() { };
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-				double lat, double lon,
-				double hdg, double spd, double alt, double radius, int leg,
-				FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             updateAircraftInformation(int id, double lat, double lon, 
-				  double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
+    FGApproachController(FGAirportDynamics * parent);
+    virtual ~FGApproachController() { };
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
 
-  virtual void render(bool);
-  virtual string getName();
+    virtual void render(bool);
+    virtual string getName();
+    virtual void update(double dt);
 
-  ActiveRunway* getRunway(string name);
+    ActiveRunway* getRunway(string name);
 
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
+    bool hasActiveTraffic() {
+        return activeTraffic.size() != 0;
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
 };
 
 
diff --git a/src/Airports/dynamics.hxx b/src/Airports/dynamics.hxx
index d3dbedaa2..7e828e4f9 100644
--- a/src/Airports/dynamics.hxx
+++ b/src/Airports/dynamics.hxx
@@ -35,93 +35,117 @@ class FGEnvironment;
 class FGAirportDynamics {
 
 private:
-  FGAirport* _ap;
+    FGAirport* _ap;
 
-  FGParkingVec         parkings;
-  FGRunwayPreference   rwyPrefs;
-  FGSidStar            SIDs;
-  FGStartupController  startupController;
-  FGGroundNetwork      groundNetwork;
-  FGTowerController    towerController;
-  FGApproachController approachController;
+    FGParkingVec         parkings;
+    FGRunwayPreference   rwyPrefs;
+    FGSidStar            SIDs;
+    FGStartupController  startupController;
+    FGGroundNetwork      groundNetwork;
+    FGTowerController    towerController;
+    FGApproachController approachController;
 
-  time_t lastUpdate;
-  std::string prevTrafficType;
-  stringVec landing;
-  stringVec takeoff;
-  stringVec milActive, comActive, genActive, ulActive;
-  stringVec *currentlyActive;
-  intVec freqAwos;     // </AWOS>
-  intVec freqUnicom;   // </UNICOM>
-  intVec freqClearance;// </CLEARANCE>
-  intVec freqGround;   // </GROUND>
-  intVec freqTower;    // </TOWER>
-  intVec freqApproach; // </APPROACH>
+    time_t lastUpdate;
+    std::string prevTrafficType;
+    stringVec landing;
+    stringVec takeoff;
+    stringVec milActive, comActive, genActive, ulActive;
+    stringVec *currentlyActive;
+    intVec freqAwos;     // </AWOS>
+    intVec freqUnicom;   // </UNICOM>
+    intVec freqClearance;// </CLEARANCE>
+    intVec freqGround;   // </GROUND>
+    intVec freqTower;    // </TOWER>
+    intVec freqApproach; // </APPROACH>
 
-  int atisSequenceIndex;
-  double atisSequenceTimeStamp;
-  
-  std::string chooseRunwayFallback();
-  bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, double heading);
-  std::string chooseRwyByHeading(stringVec rwys, double heading);
+    int atisSequenceIndex;
+    double atisSequenceTimeStamp;
 
-  double elevation;
+    std::string chooseRunwayFallback();
+    bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, double heading);
+    std::string chooseRwyByHeading(stringVec rwys, double heading);
+
+    double elevation;
 
 public:
-  FGAirportDynamics(FGAirport* ap);
-  ~FGAirportDynamics();
+    FGAirportDynamics(FGAirport* ap);
+    ~FGAirportDynamics();
 
-  void addAwosFreq     (int val) { freqAwos.push_back(val);      };
-  void addUnicomFreq   (int val) { freqUnicom.push_back(val);    };
-  void addClearanceFreq(int val) { freqClearance.push_back(val); };
-  void addGroundFreq   (int val) { freqGround.push_back(val);    };
-  void addTowerFreq    (int val) { freqTower.push_back(val);     };
-  void addApproachFreq (int val) { freqApproach.push_back(val);  };
+    void addAwosFreq     (int val) {
+        freqAwos.push_back(val);
+    };
+    void addUnicomFreq   (int val) {
+        freqUnicom.push_back(val);
+    };
+    void addClearanceFreq(int val) {
+        freqClearance.push_back(val);
+    };
+    void addGroundFreq   (int val) {
+        freqGround.push_back(val);
+    };
+    void addTowerFreq    (int val) {
+        freqTower.push_back(val);
+    };
+    void addApproachFreq (int val) {
+        freqApproach.push_back(val);
+    };
 
-  void init();
-  double getLongitude() const; 
-  // Returns degrees
-  double getLatitude()  const; 
-  // Returns ft
-  double getElevation() const; 
-  const string& getId() const; 
-  
-  void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
+    void init();
+    double getLongitude() const;
+    // Returns degrees
+    double getLatitude()  const;
+    // Returns ft
+    double getElevation() const;
+    const string& getId() const;
 
-  void addParking(FGParking& park);
-  bool getAvailableParking(double *lat, double *lon, 
-			   double *heading, int *gate, double rad, const string& fltype, 
-			   const string& acType, const string& airline);
-  void getParking         (int id, double *lat, double* lon, double *heading);
-  FGParking *getParking(int i);
-  void releaseParking(int id);
-  string getParkingName(int i); 
-  int getNrOfParkings() { return parkings.size(); };
-  //FGAirport *getAddress() { return this; };
-  //const string &getName() const { return _name;};
-  // Returns degrees
+    void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
 
-  // Departure / Arrival procedures
-  FGSidStar * getSIDs() { return &SIDs; };
-  FGAIFlightPlan * getSID(string activeRunway, double heading);
+    void addParking(FGParking& park);
+    bool getAvailableParking(double *lat, double *lon,
+                             double *heading, int *gate, double rad, const string& fltype,
+                             const string& acType, const string& airline);
+    void getParking         (int id, double *lat, double* lon, double *heading);
+    FGParking *getParking(int i);
+    void releaseParking(int id);
+    string getParkingName(int i);
+    int getNrOfParkings() {
+        return parkings.size();
+    };
+    //FGAirport *getAddress() { return this; };
+    //const string &getName() const { return _name;};
+    // Returns degrees
+
+    // Departure / Arrival procedures
+    FGSidStar * getSIDs() {
+        return &SIDs;
+    };
+    FGAIFlightPlan * getSID(string activeRunway, double heading);
 
 
-  // ATC related functions. 
-  FGStartupController    *getStartupController()    { return &startupController; };
-  FGGroundNetwork        *getGroundNetwork()        { return &groundNetwork; };
-  FGTowerController      *getTowerController()      { return &towerController; };
-  FGApproachController   *getApproachController()   { return &approachController; };
+    // ATC related functions.
+    FGStartupController    *getStartupController()    {
+        return &startupController;
+    };
+    FGGroundNetwork        *getGroundNetwork()        {
+        return &groundNetwork;
+    };
+    FGTowerController      *getTowerController()      {
+        return &towerController;
+    };
+    FGApproachController   *getApproachController()   {
+        return &approachController;
+    };
 
-  int getGroundFrequency(unsigned leg);
-  int getTowerFrequency  (unsigned nr);
-  
-  /// get current ATIS sequence letter
-  const std::string getAtisSequence();
+    int getGroundFrequency(unsigned leg);
+    int getTowerFrequency  (unsigned nr);
 
-  /// get the current ATIS sequence number, updating it if necessary
-  int updateAtisSequence(int interval, bool forceUpdate);
+    /// get current ATIS sequence letter
+    const std::string getAtisSequence();
 
-  void setRwyUse(const FGRunwayPreference& ref);
+    /// get the current ATIS sequence number, updating it if necessary
+    int updateAtisSequence(int interval, bool forceUpdate);
+
+    void setRwyUse(const FGRunwayPreference& ref);
 };
 
 
diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx
index 3a3c6d714..47753b288 100644
--- a/src/Airports/groundnetwork.cxx
+++ b/src/Airports/groundnetwork.cxx
@@ -88,7 +88,7 @@ void FGTaxiSegment::setEnd(FGTaxiNodeVector * nodes)
 
 
 
-// There is probably a computationally cheaper way of 
+// There is probably a computationally cheaper way of
 // doing this.
 void FGTaxiSegment::setDimensions(double elevation)
 {
@@ -164,9 +164,9 @@ bool FGTaxiRoute::next(int *nde, int *rte)
     } else {
         // If currNode points to the first node, this means the aircraft is not on the taxi node
         // yet. Make sure to return a unique identifyer in this situation though, because otherwise
-        // the speed adjust AI code may be unable to resolve whether two aircraft are on the same 
-        // taxi route or not. the negative of the preceding route seems a logical choice, as it is 
-        // unique for any starting location. 
+        // the speed adjust AI code may be unable to resolve whether two aircraft are on the same
+        // taxi route or not. the negative of the preceding route seems a logical choice, as it is
+        // unique for any starting location.
         // Note that this is probably just a temporary fix until I get Parking / tower control working.
         *rte = -1 * *(currRoute);
     }
@@ -205,6 +205,11 @@ bool compare_segments(FGTaxiSegment * a, FGTaxiSegment * b)
     return (*a) < (*b);
 }
 
+bool compare_trafficrecords(FGTrafficRecord a, FGTrafficRecord b)
+{
+    return (a.getIntentions().size() < b.getIntentions().size());
+}
+
 FGGroundNetwork::FGGroundNetwork()
 {
     hasNetwork = false;
@@ -244,18 +249,18 @@ FGGroundNetwork::~FGGroundNetwork()
     }
     cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
     for (FGTaxiNodeVectorIterator node = nodes.begin();
-         node != nodes.end(); node++) {
-         if (saveData) {
+            node != nodes.end(); node++) {
+        if (saveData) {
             cachefile << (*node)->getIndex     () << " "
-                      << (*node)->getElevation ()   << " " 
-                      << endl;
-         }
+            << (*node)->getElevation ()   << " "
+            << endl;
+        }
         delete(*node);
     }
     nodes.clear();
     pushBackNodes.clear();
     for (FGTaxiSegmentVectorIterator seg = segments.begin();
-         seg != segments.end(); seg++) {
+            seg != segments.end(); seg++) {
         delete(*seg);
     }
     segments.clear();
@@ -288,12 +293,12 @@ void FGGroundNetwork::saveElevationCache() {
     }
     cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
     for (FGTaxiNodeVectorIterator node = nodes.begin();
-         node != nodes.end(); node++) {
-         if (saveData) {
+            node != nodes.end(); node++) {
+        if (saveData) {
             cachefile << (*node)->getIndex     () << " "
-                      << (*node)->getElevation () << " " 
-                      << endl;
-         }
+            << (*node)->getElevation () << " "
+            << endl;
+        }
     }
     if (saveData) {
         cachefile.close();
@@ -405,12 +410,12 @@ void FGGroundNetwork::init()
                 string revisionStr;
                 data >> revisionStr;
                 if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
-                    SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " << 
-                            cacheData.c_str() << " for Airport " << airport);
+                    SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
+                           cacheData.c_str() << " for Airport " << airport);
                 } else {
                     for (FGTaxiNodeVectorIterator i = nodes.begin();
-                        i != nodes.end(); 
-                        i++) {
+                            i != nodes.end();
+                            i++) {
                         (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
                         data >> index >> elev;
                         if (data.eof())
@@ -435,7 +440,7 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
     int index = -1;
 
     for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
-         itr++) {
+            itr++) {
         double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
         if (d < minDist) {
             minDist = d;
@@ -454,7 +459,7 @@ int FGGroundNetwork::findNearestNode(double lat, double lon)
 
 FGTaxiNode *FGGroundNetwork::findNode(unsigned idx)
 {                               /*
-                                   for (FGTaxiNodeVectorIterator 
+                                   for (FGTaxiNodeVectorIterator
                                    itr = nodes.begin();
                                    itr != nodes.end(); itr++)
                                    {
@@ -470,13 +475,13 @@ FGTaxiNode *FGGroundNetwork::findNode(unsigned idx)
 
 FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
 {                               /*
-                                   for (FGTaxiSegmentVectorIterator 
+                                   for (FGTaxiSegmentVectorIterator
                                    itr = segments.begin();
                                    itr != segments.end(); itr++)
                                    {
                                    if (itr->getIndex() == idx)
                                    return itr->getAddress();
-                                   } 
+                                   }
                                  */
     if ((idx > 0) && (idx <= segments.size()))
         return segments[idx - 1]->getAddress();
@@ -488,7 +493,7 @@ FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
 
 
 FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
-                                               bool fullSearch)
+        bool fullSearch)
 {
 //implements Dijkstra's algorithm to find shortest distance route from start to end
 //taken from http://en.wikipedia.org/wiki/Dijkstra's_algorithm
@@ -504,7 +509,7 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
     }
 
     for (FGTaxiNodeVectorIterator
-         itr = currNodesSet->begin(); itr != currNodesSet->end(); itr++) {
+            itr = currNodesSet->begin(); itr != currNodesSet->end(); itr++) {
         (*itr)->setPathScore(HUGE_VAL); //infinity by all practical means
         (*itr)->setPreviousNode(0);     //
         (*itr)->setPreviousSeg(0);      //
@@ -520,7 +525,7 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
     while (!unvisited.empty()) {
         FGTaxiNode *best = *(unvisited.begin());
         for (FGTaxiNodeVectorIterator
-             itr = unvisited.begin(); itr != unvisited.end(); itr++) {
+                itr = unvisited.begin(); itr != unvisited.end(); itr++) {
             if ((*itr)->getPathScore() < best->getPathScore())
                 best = (*itr);
         }
@@ -533,8 +538,8 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
             break;
         } else {
             for (FGTaxiSegmentVectorIterator
-                 seg = best->getBeginRoute();
-                 seg != best->getEndRoute(); seg++) {
+                    seg = best->getBeginRoute();
+                    seg != best->getEndRoute(); seg++) {
                 if (fullSearch || (*seg)->isPushBack()) {
                     FGTaxiNode *tgt = (*seg)->getEnd();
                     double alt =
@@ -623,7 +628,8 @@ void FGGroundNetwork::announcePosition(int id,
         rec.setPositionAndHeading(lat, lon, heading, speed, alt);
         rec.setRadius(radius);  // only need to do this when creating the record.
         rec.setAircraft(aircraft);
-        activeTraffic.push_back(rec);
+        activeTraffic.push_front(rec);
+        
     } else {
         i->setPositionAndIntentions(currentPosition, intendedRoute);
         i->setPositionAndHeading(lat, lon, heading, speed, alt);
@@ -666,7 +672,7 @@ void FGGroundNetwork::signOff(int id)
  * 9 = Acknowledge switch tower frequency
  *************************************************************************************************************************/
 bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
-                               AtcMsgDir msgDir)
+        AtcMsgDir msgDir)
 {
     int state = i->getState();
     if ((state >= minState) && (state <= maxState) && available) {
@@ -676,10 +682,10 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic
             int n = trans_num->getIntValue();
             if (n == 0) {
                 trans_num->setIntValue(-1);
-                 // PopupCallback(n);
-                 //cerr << "Selected transmission message " << n << endl;
-                 FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
-                 FGATCDialogNew::instance()->removeEntry(1);
+                // PopupCallback(n);
+                //cerr << "Selected transmission message " << n << endl;
+                FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
+                FGATCDialogNew::instance()->removeEntry(1);
             } else {
                 //cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
                 transmit(&(*i), msgId, msgDir, false);
@@ -696,18 +702,18 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic
 }
 
 void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
-                                                double heading, double speed, double alt,
-                                                double dt)
+        double heading, double speed, double alt,
+        double dt)
 {
     time_t currentTime = time(NULL);
     if (nextSave < currentTime) {
         saveElevationCache();
         nextSave = currentTime + 100 + rand() % 200;
     }
-    // Check whether aircraft are on hold due to a preceding pushback. If so, make sure to 
+    // Check whether aircraft are on hold due to a preceding pushback. If so, make sure to
     // Transmit air-to-ground "Ready to taxi request:
     // Transmit ground to air approval / hold
-    // Transmit confirmation ... 
+    // Transmit confirmation ...
     // Probably use a status mechanism similar to the Engine start procedure in the startup controller.
 
 
@@ -747,9 +753,9 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
     bool needsTaxiClearance = current->getAircraft()->getTaxiClearanceRequest();
     if (!needsTaxiClearance) {
         checkHoldPosition(id, lat, lon, heading, speed, alt);
-        if (checkForCircularWaits(id)) {
-            i->setResolveCircularWait();
-        }
+        //if (checkForCircularWaits(id)) {
+        //    i->setResolveCircularWait();
+        //}
     } else {
         current->setHoldPosition(true);
         int state = current->getState();
@@ -783,7 +789,7 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
    aircraft. For traffic that is on other routes we need to issue a "HOLD Position"
    instruction. See below for the hold position instruction.
 
-   Note that there currently still is one flaw in the logic that needs to be addressed. 
+   Note that there currently still is one flaw in the logic that needs to be addressed.
    There can be situations where one aircraft is in front of the current aircraft, on a separate
    route, but really close after an intersection coming off the current route. This
    aircraft is still close enough to block the current aircraft. This situation is currently
@@ -791,11 +797,11 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
 */
 
 void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
-                                           double lon, double heading,
-                                           double speed, double alt)
+        double lon, double heading,
+        double speed, double alt)
 {
 
-    TrafficVectorIterator current, closest;
+    TrafficVectorIterator current, closest, closestOnNetwork;
     TrafficVectorIterator i = activeTraffic.begin();
     bool otherReasonToSlowDown = false;
     bool previousInstruction;
@@ -825,7 +831,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
         //TrafficVector iterator closest;
         closest = current;
         for (TrafficVectorIterator i = activeTraffic.begin();
-             i != activeTraffic.end(); i++) {
+                i != activeTraffic.end(); i++) {
             if (i == current) {
                 continue;
             }
@@ -840,14 +846,16 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
             if ((dist < mindist) && (bearing < 60.0)) {
                 mindist = dist;
                 closest = i;
+                closestOnNetwork = i;
                 minbearing = bearing;
+                
             }
         }
         //Check traffic at the tower controller
         if (towerController->hasActiveTraffic()) {
             for (TrafficVectorIterator i =
-                 towerController->getActiveTraffic().begin();
-                 i != towerController->getActiveTraffic().end(); i++) {
+                        towerController->getActiveTraffic().begin();
+                    i != towerController->getActiveTraffic().end(); i++) {
                 //cerr << "Comparing " << current->getId() << " and " << i->getId() << endl;
                 SGGeod other(SGGeod::fromDegM(i->getLongitude(),
                                               i->getLatitude(),
@@ -858,8 +866,8 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
                     bearing = 360 - bearing;
                 if ((dist < mindist) && (bearing < 60.0)) {
                     //cerr << "Current aircraft " << current->getAircraft()->getTrafficRef()->getCallSign()
-                    //     << " is closest to " << i->getAircraft()->getTrafficRef()->getCallSign() 
-                    //     << ", which has status " << i->getAircraft()->isScheduledForTakeoff() 
+                    //     << " is closest to " << i->getAircraft()->getTrafficRef()->getCallSign()
+                    //     << ", which has status " << i->getAircraft()->isScheduledForTakeoff()
                     //     << endl;
                     mindist = dist;
                     closest = i;
@@ -887,9 +895,9 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
         }
         */
         current->clearSpeedAdjustment();
-
+        bool needBraking = false;
         if (current->checkPositionAndIntentions(*closest)
-            || otherReasonToSlowDown) {
+                || otherReasonToSlowDown) {
             double maxAllowableDistance =
                 (1.1 * current->getRadius()) +
                 (1.1 * closest->getRadius());
@@ -901,12 +909,13 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
                 if (closest->getId() != current->getId()) {
                     current->setSpeedAdjustment(closest->getSpeed() *
                                                 (mindist / 100));
-                    if ( 
-                        closest->getAircraft()->getTakeOffStatus() && 
+                    needBraking = true;
+                    if (
+                        closest->getAircraft()->getTakeOffStatus() &&
                         (current->getAircraft()->getTrafficRef()->getDepartureAirport() ==  closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
                         (current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
-                       )
-                            current->getAircraft()->scheduleForATCTowerDepartureControl(1); 
+                    )
+                        current->getAircraft()->scheduleForATCTowerDepartureControl(1);
                 } else {
                     current->setSpeedAdjustment(0);     // This can only happen when the user aircraft is the one closest
                 }
@@ -920,6 +929,9 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
                 }
             }
         }
+        if ((closest == closestOnNetwork) && (current->getPriority() < closest->getPriority()) && needBraking) {
+            swap(current, closest);
+        }
     }
 }
 
@@ -938,7 +950,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
     TrafficVectorIterator current;
     TrafficVectorIterator i = activeTraffic.begin();
     if (activeTraffic.size()) {
-        //while ((i->getId() != id) && i != activeTraffic.end()) 
+        //while ((i->getId() != id) && i != activeTraffic.end())
         while (i != activeTraffic.end()) {
             if (i->getId() == id) {
                 break;
@@ -956,80 +968,100 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
     bool origStatus = current->hasHoldPosition();
     current->setHoldPosition(false);
     SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
+    int currentRoute = i->getCurrentPosition();
+    int nextRoute;
+    if (i->getIntentions().size()) {
+        nextRoute    = (*(i->getIntentions().begin()));
+    } else {
+        nextRoute = 0;
+    }       
+    if (currentRoute > 0) {
+        FGTaxiSegment *tx = findSegment(currentRoute);
+        FGTaxiSegment *nx;
+        if (nextRoute) {
+            nx = findSegment(nextRoute);
+        } else {
+            nx = tx;
+        }
+        if (tx->hasBlock() || nx->hasBlock() ) {
+            current->setHoldPosition(true);
+        }
+    }
 
-    for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
-        if (i->getId() != current->getId()) {
-            int node = current->crosses(this, *i);
-            if (node != -1) {
-                FGTaxiNode *taxiNode = findNode(node);
 
-                // Determine whether it's save to continue or not. 
-                // If we have a crossing route, there are two possibilities:
-                // 1) This is an interestion
-                // 2) This is oncoming two-way traffic, using the same taxiway.
-                //cerr << "Hold check 1 : " << id << " has common node " << node << endl;
+    /*    for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+            if (i->getId() != current->getId()) {
+                int node = current->crosses(this, *i);
+                if (node != -1) {
+                    FGTaxiNode *taxiNode = findNode(node);
 
-                SGGeod other(SGGeod::
-                             fromDegM(i->getLongitude(), i->getLatitude(),
-                                      i->getAltitude()));
-                bool needsToWait;
-                bool opposing;
-                if (current->isOpposing(this, *i, node)) {
-                    needsToWait = true;
-                    opposing = true;
-                    //cerr << "Hold check 2 : " << node << "  has opposing segment " << endl;
-                    // issue a "Hold Position" as soon as we're close to the offending node
-                    // For now, I'm doing this as long as the other aircraft doesn't
-                    // have a hold instruction as soon as we're within a reasonable 
-                    // distance from the offending node.
-                    // This may be a bit of a conservative estimate though, as it may
-                    // be well possible that both aircraft can both continue to taxi 
-                    // without crashing into each other.
-                } else {
-                    opposing = false;
-                    if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 200) // 2.0*i->getRadius())
-                    {
-                        needsToWait = false;
-                        //cerr << "Hold check 3 : " << id <<"  Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue " 
-                        //           << endl;
-                    } else {
+                    // Determine whether it's save to continue or not.
+                    // If we have a crossing route, there are two possibilities:
+                    // 1) This is an interestion
+                    // 2) This is oncoming two-way traffic, using the same taxiway.
+                    //cerr << "Hold check 1 : " << id << " has common node " << node << endl;
+
+                    SGGeod other(SGGeod::
+                                 fromDegM(i->getLongitude(), i->getLatitude(),
+                                          i->getAltitude()));
+                    bool needsToWait;
+                    bool opposing;
+                    if (current->isOpposing(this, *i, node)) {
                         needsToWait = true;
-                        //cerr << "Hold check 4: " << id << "  Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
-                    }
-                }
-
-                double dist =
-                    SGGeodesy::distanceM(curr, taxiNode->getGeod());
-                if (!(i->hasHoldPosition())) {
-
-                    if ((dist < 200) && //2.5*current->getRadius()) && 
-                        (needsToWait) && (i->onRoute(this, *current)) &&
-                        //((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
-                        (!(current->getId() == i->getWaitsForId())))
-                        //(!(i->getSpeedAdjustment()))) // &&
-                        //(!(current->getSpeedAdjustment())))
-
-                    {
-                        if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
-                            current->setHoldPosition(true);
-                            current->setWaitsForId(i->getId());
-                        }
-                        //cerr << "Hold check 5: " << current->getCallSign() <<"  Setting Hold Position: distance to node ("  << node << ") "
-                        //           << dist << " meters. Waiting for " << i->getCallSign();
-                        //if (opposing)
-                        //cerr <<" [opposing] " << endl;
-                        //else
-                        //        cerr << "[non-opposing] " << endl;
-                        //if (i->hasSpeefAdjustment())
-                        //        {
-                        //          cerr << " (which in turn waits for ) " << i->
+                        opposing = true;
+                        //cerr << "Hold check 2 : " << node << "  has opposing segment " << endl;
+                        // issue a "Hold Position" as soon as we're close to the offending node
+                        // For now, I'm doing this as long as the other aircraft doesn't
+                        // have a hold instruction as soon as we're within a reasonable
+                        // distance from the offending node.
+                        // This may be a bit of a conservative estimate though, as it may
+                        // be well possible that both aircraft can both continue to taxi
+                        // without crashing into each other.
                     } else {
-                        //cerr << "Hold check 6: " << id << "  No need to hold yet: Distance to node : " << dist << " nm"<< endl;
+                        opposing = false;
+                        if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 200) // 2.0*i->getRadius())
+                        {
+                            needsToWait = false;
+                            //cerr << "Hold check 3 : " << id <<"  Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue "
+                            //           << endl;
+                        } else {
+                            needsToWait = true;
+                            //cerr << "Hold check 4: " << id << "  Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
+                        }
+                    }
+
+                    double dist =
+                        SGGeodesy::distanceM(curr, taxiNode->getGeod());
+                    if (!(i->hasHoldPosition())) {
+
+                        if ((dist < 200) && //2.5*current->getRadius()) &&
+                            (needsToWait) && (i->onRoute(this, *current)) &&
+                            //((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
+                            (!(current->getId() == i->getWaitsForId())))
+                            //(!(i->getSpeedAdjustment()))) // &&
+                            //(!(current->getSpeedAdjustment())))
+
+                        {
+                            if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
+                                current->setHoldPosition(true);
+                                current->setWaitsForId(i->getId());
+                            }
+                            //cerr << "Hold check 5: " << current->getCallSign() <<"  Setting Hold Position: distance to node ("  << node << ") "
+                            //           << dist << " meters. Waiting for " << i->getCallSign();
+                            //if (opposing)
+                            //cerr <<" [opposing] " << endl;
+                            //else
+                            //        cerr << "[non-opposing] " << endl;
+                            //if (i->hasSpeefAdjustment())
+                            //        {
+                            //          cerr << " (which in turn waits for ) " << i->
+                        } else {
+                            //cerr << "Hold check 6: " << id << "  No need to hold yet: Distance to node : " << dist << " nm"<< endl;
+                        }
                     }
                 }
             }
-        }
-    }
+        } */
     bool currStatus = current->hasHoldPosition();
     current->setHoldPosition(origStatus);
     // Either a Hold Position or a resume taxi transmission has been issued
@@ -1064,17 +1096,17 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
 
     //int state = current->getState();
     if (checkTransmissionState(1,1, current, now, MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND)) {
-            current->setState(0);
-            current->setHoldPosition(true);
+        current->setState(0);
+        current->setHoldPosition(true);
     }
     if (checkTransmissionState(2,2, current, now, MSG_ACKNOWLEDGE_RESUME_TAXI, ATC_AIR_TO_GROUND)) {
-            current->setState(0);
-            current->setHoldPosition(false);
+        current->setState(0);
+        current->setHoldPosition(false);
     }
     if (current->getAircraft()->getTakeOffStatus() && (current->getState() == 0)) {
-            //cerr << "Scheduling " << current->getAircraft()->getCallSign() << " for hold short" << endl;
-            current->setState(6);
-        }
+        //cerr << "Scheduling " << current->getAircraft()->getCallSign() << " for hold short" << endl;
+        current->setState(6);
+    }
     if (checkTransmissionState(6,6, current, now, MSG_REPORT_RUNWAY_HOLD_SHORT, ATC_AIR_TO_GROUND)) {
     }
     if (checkTransmissionState(7,7, current, now, MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT, ATC_GROUND_TO_AIR)) {
@@ -1086,15 +1118,15 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
 
 
 
-            //current->setState(0);
-} 
+    //current->setState(0);
+}
 
 /**
  * Check whether situations occur where the current aircraft is waiting for itself
- * due to higher order interactions. 
+ * due to higher order interactions.
  * A 'circular' wait is a situation where a waits for b, b waits for c, and c waits
- * for a. Ideally each aircraft only waits for one other aircraft, so by tracing 
- * through this list of waiting aircraft, we can check if we'd eventually end back 
+ * for a. Ideally each aircraft only waits for one other aircraft, so by tracing
+ * through this list of waiting aircraft, we can check if we'd eventually end back
  * at the current aircraft.
  *
  * Note that we should consider the situation where we are actually checking aircraft
@@ -1140,7 +1172,7 @@ bool FGGroundNetwork::checkForCircularWaits(int id)
         //printed = true;
         TrafficVectorIterator i = activeTraffic.begin();
         if (trafficSize) {
-            //while ((i->getId() != id) && i != activeTraffic.end()) 
+            //while ((i->getId() != id) && i != activeTraffic.end())
             while (i != activeTraffic.end()) {
                 if (i->getId() == target) {
                     break;
@@ -1161,7 +1193,7 @@ bool FGGroundNetwork::checkForCircularWaits(int id)
 
         // actually this trap isn't as impossible as it first seemed:
         // the setWaitsForID(id) is set to current when the aircraft
-        // is waiting for the user controlled aircraft. 
+        // is waiting for the user controlled aircraft.
         //if (current->getId() == other->getId()) {
         //    cerr << "Caught the impossible trap" << endl;
         //    cerr << "Current = " << current->getId() << endl;
@@ -1175,7 +1207,7 @@ bool FGGroundNetwork::checkForCircularWaits(int id)
         if (current->getId() == other->getId())
             return false;
         //}
-        //cerr << current->getCallSign() << " (" << current->getId()  << ") " << " -> " << other->getCallSign() 
+        //cerr << current->getCallSign() << " (" << current->getId()  << ") " << " -> " << other->getCallSign()
         //     << " (" << other->getId()  << "); " << endl;;
         //current = other;
     }
@@ -1271,10 +1303,10 @@ void FGGroundNetwork::render(bool visible)
         //while (group->getNumChildren()) {
         //  cerr << "Number of children: " << group->getNumChildren() << endl;
         //simgear::EffectGeode* geode = (simgear::EffectGeode*) group->getChild(0);
-          //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
-           //geode->releaseGLObjects();
-           //group->removeChild(geode);
-           //delete geode;
+        //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0);
+        //geode->releaseGLObjects();
+        //group->removeChild(geode);
+        //delete geode;
         group = 0;
     }
     if (visible) {
@@ -1288,7 +1320,7 @@ void FGGroundNetwork::render(bool visible)
             // Handle start point
             int pos = i->getCurrentPosition() - 1;
             if (pos >= 0) {
-            
+
                 SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
                 SGGeod end  (SGGeod::fromDeg(segments[pos]->getEnd()->getLongitude(), segments[pos]->getEnd()->getLatitude()));
 
@@ -1301,7 +1333,7 @@ void FGGroundNetwork::render(bool visible)
                 SGGeod center;
                 SGGeodesy::direct(start, heading, coveredDistance, center, az2);
                 //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
-            ///////////////////////////////////////////////////////////////////////////////
+                ///////////////////////////////////////////////////////////////////////////////
                 // Make a helper function out of this
                 osg::Matrix obj_pos;
                 osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
@@ -1311,7 +1343,7 @@ void FGGroundNetwork::render(bool visible)
                 if (isUserAircraft((i)->getAircraft())) {
                     elevationStart = fgGetDouble("/position/ground-elev-m");
                 } else {
-                    elevationStart = ((i)->getAircraft()->_getAltitude()); 
+                    elevationStart = ((i)->getAircraft()->_getAltitude());
                 }
                 double elevationEnd   = segments[pos]->getEnd()->getElevation();
                 //cerr << "Using elevation " << elevationEnd << endl;
@@ -1321,19 +1353,19 @@ void FGGroundNetwork::render(bool visible)
                     center2.setElevationM(SG_MAX_ELEVATION_M);
                     if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
                         elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
-                            //elevation_meters += 0.5;
+                        //elevation_meters += 0.5;
                     }
-                    else { 
+                    else {
                         elevationEnd = parent->getElevation();
                     }
                     segments[pos]->getEnd()->setElevation(elevationEnd);
                 }
                 double elevationMean  = (elevationStart + elevationEnd) / 2.0;
                 double elevDiff       = elevationEnd - elevationStart;
-               
-               double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-               //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
+
+                double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
+
+                //cerr << "1. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
                 WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), elevationMean+ 0.5, -(heading), slope );
 
@@ -1350,18 +1382,23 @@ void FGGroundNetwork::render(bool visible)
                 geode->setName("test");
                 geode->addDrawable(geometry);
                 //osg::Node *custom_obj;
-                SGMaterial *mat = matlib->find("UnidirectionalTaper");
+                SGMaterial *mat;
+                if (segments[pos]->hasBlock()) {
+                    mat = matlib->find("UnidirectionalTaperRed");
+                } else {
+                    mat = matlib->find("UnidirectionalTaperGreen");
+                }
                 if (mat)
                     geode->setEffect(mat->get_effect());
                 obj_trans->addChild(geode);
                 // wire as much of the scene graph together as we can
                 //->addChild( obj_trans );
                 group->addChild( obj_trans );
-            /////////////////////////////////////////////////////////////////////
+                /////////////////////////////////////////////////////////////////////
             } else {
                 //cerr << "BIG FAT WARNING: current position is here : " << pos << endl;
             }
-            for(intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
+            for (intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) {
                 osg::Matrix obj_pos;
                 int k = (*j)-1;
                 if (k >= 0) {
@@ -1378,7 +1415,7 @@ void FGGroundNetwork::render(bool visible)
                             elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
                             //elevation_meters += 0.5;
                         }
-                        else { 
+                        else {
                             elevationStart = parent->getElevation();
                         }
                         segments[k]->getStart()->setElevation(elevationStart);
@@ -1390,7 +1427,7 @@ void FGGroundNetwork::render(bool visible)
                             elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
                             //elevation_meters += 0.5;
                         }
-                        else { 
+                        else {
                             elevationEnd = parent->getElevation();
                         }
                         segments[k]->getEnd()->setElevation(elevationEnd);
@@ -1400,8 +1437,8 @@ void FGGroundNetwork::render(bool visible)
                     double elevDiff       = elevationEnd - elevationStart;
                     double length         = segments[k]->getLength();
                     double slope = atan2(elevDiff, length) * SGD_RADIANS_TO_DEGREES;
-                
-                   // cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
+
+                    // cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
 
                     WorldCoordinate( obj_pos, segments[k]->getLatitude(), segments[k]->getLongitude(), elevationMean+ 0.5, -(segments[k]->getHeading()), slope );
@@ -1419,7 +1456,12 @@ void FGGroundNetwork::render(bool visible)
                     geode->setName("test");
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
-                    SGMaterial *mat = matlib->find("UnidirectionalTaper");
+                    SGMaterial *mat;
+                    if (segments[k]->hasBlock()) {
+                        mat = matlib->find("UnidirectionalTaperRed");
+                    } else {
+                        mat = matlib->find("UnidirectionalTaperGreen");
+                    }
                     if (mat)
                         geode->setEffect(mat->get_effect());
                     obj_trans->addChild(geode);
@@ -1437,3 +1479,96 @@ void FGGroundNetwork::render(bool visible)
 string FGGroundNetwork::getName() {
     return string(parent->getId() + "-ground");
 }
+
+void FGGroundNetwork::update(double dt)
+{
+    for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
+        (*tsi)->unblock();
+    }
+    int priority = 1;
+    //sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords);
+    // Handle traffic that is under ground control first; this way we'll prevent clutter at the gate areas.
+    // Don't allow an aircraft to pushback when a taxiing aircraft is currently using part of the intended route.
+    for   (TrafficVectorIterator i = parent->getDynamics()->getStartupController()->getActiveTraffic().begin();
+            i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) {
+        i->allowPushBack();
+        i->setPriority(priority++);
+        if (i->isActive(60)) {
+
+            // Check for all active aircraft whether it's current pos segment is
+            // an opposite of one of the departing aircraft's intentions
+            for (TrafficVectorIterator j = activeTraffic.begin(); j != activeTraffic.end(); j++) {
+                int pos = j->getCurrentPosition();
+                if (pos > 0) {
+                    FGTaxiSegment *seg = segments[pos-1]->opposite();
+                    if (seg) {
+                        int posReverse = seg->getIndex();
+                        for (intVecIterator k = i->getIntentions().begin(); k != i->getIntentions().end(); k++) {
+                            if ((*k) == posReverse) {
+                                i->denyPushBack();
+                                segments[posReverse-1]->block();
+                            }
+                        }
+                    }
+                }
+            }
+            // if the current aircraft is still allowed to pushback, we can start reserving a route for if by blocking all the entry taxiways.
+            if (i->pushBackAllowed()) {
+                int pos = i->getCurrentPosition();
+                if (pos > 0) {
+                    FGTaxiSegment *seg = segments[pos-1];
+                    FGTaxiNode *node = seg->getEnd();
+                    for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
+                        if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
+                            (*tsi)->block();
+                        }
+                    }
+                }
+                for (intVecIterator j = i->getIntentions().begin(); j != i->getIntentions().end(); j++) {
+                    int pos = (*j);
+                    if (pos > 0) {
+                        FGTaxiSegment *seg = segments[pos-1];
+                        FGTaxiNode *node = seg->getEnd();
+                        for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
+                            if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
+                                (*tsi)->block();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+        i->setPriority(priority++);
+        int pos = i->getCurrentPosition();
+        if (pos > 0) {
+            if (segments[pos-1]->hasBlock()) {
+                SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
+            }
+
+        }
+        intVecIterator ivi;
+        for (ivi = i->getIntentions().begin(); ivi != i->getIntentions().end(); ivi++) {
+            int segIndex = (*ivi);
+            if (segIndex > 0) {
+                if (segments[segIndex-1]->hasBlock())
+                    break;
+            }
+        }
+        //after this, ivi points just behind the last valid unblocked taxi segment.
+        for (intVecIterator j = i->getIntentions().begin(); j != ivi; j++) {
+            int pos = (*j);
+            if (pos > 0) {
+                FGTaxiSegment *seg = segments[pos-1];
+                FGTaxiNode *node = seg->getEnd();
+                for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
+                    if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
+                        (*tsi)->block();
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx
index a49342687..cec19d38b 100644
--- a/src/Airports/groundnetwork.hxx
+++ b/src/Airports/groundnetwork.hxx
@@ -60,98 +60,143 @@ typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
 class FGTaxiSegment
 {
 private:
-  int startNode;
-  int endNode;
-  double length;
-  double heading;
-  SGGeod center;
-  bool isActive;
-  bool isPushBackRoute;
-  FGTaxiNode *start;
-  FGTaxiNode *end;
-  int index;
-  FGTaxiSegment *oppositeDirection;
+    int startNode;
+    int endNode;
+    double length;
+    double heading;
+    SGGeod center;
+    bool isActive;
+    bool isPushBackRoute;
+    bool isBlocked;
+    FGTaxiNode *start;
+    FGTaxiNode *end;
+    int index;
+    FGTaxiSegment *oppositeDirection;
+
 
- 
 
 public:
-  FGTaxiSegment() :
-      startNode(0),
-      endNode(0),
-      length(0),
-      heading(0),
-      isActive(0),
-      isPushBackRoute(0),
-      start(0),
-      end(0),
-      index(0),
-      oppositeDirection(0)
-  {
-  };
+    FGTaxiSegment() :
+            startNode(0),
+            endNode(0),
+            length(0),
+            heading(0),
+            isActive(0),
+            isPushBackRoute(0),
+            isBlocked(0),
+            start(0),
+            end(0),
+            index(0),
+            oppositeDirection(0)
+    {
+    };
 
-  FGTaxiSegment         (const FGTaxiSegment &other) :
-      startNode         (other.startNode),
-      endNode           (other.endNode),
-      length            (other.length),
-      heading           (other.heading),
-      center            (other.center),
-      isActive          (other.isActive),
-      isPushBackRoute   (other.isPushBackRoute),
-      start             (other.start),
-      end               (other.end),
-      index             (other.index),
-      oppositeDirection (other.oppositeDirection)
-  {
-  };
+    FGTaxiSegment         (const FGTaxiSegment &other) :
+            startNode         (other.startNode),
+            endNode           (other.endNode),
+            length            (other.length),
+            heading           (other.heading),
+            center            (other.center),
+            isActive          (other.isActive),
+            isPushBackRoute   (other.isPushBackRoute),
+            isBlocked         (other.isBlocked),
+            start             (other.start),
+            end               (other.end),
+            index             (other.index),
+            oppositeDirection (other.oppositeDirection)
+    {
+    };
 
-  FGTaxiSegment& operator=(const FGTaxiSegment &other)
-  {
-      startNode          = other.startNode;
-      endNode            = other.endNode;
-      length             = other.length;
-      heading            = other.heading;
-      center             = other.center;
-      isActive           = other.isActive;
-      isPushBackRoute    = other.isPushBackRoute;
-      start              = other.start;
-      end                = other.end;
-      index              = other.index;
-      oppositeDirection  = other.oppositeDirection;
-      return *this;
-  };
+    FGTaxiSegment& operator=(const FGTaxiSegment &other)
+    {
+        startNode          = other.startNode;
+        endNode            = other.endNode;
+        length             = other.length;
+        heading            = other.heading;
+        center             = other.center;
+        isActive           = other.isActive;
+        isPushBackRoute    = other.isPushBackRoute;
+        isBlocked          = other.isBlocked;
+        start              = other.start;
+        end                = other.end;
+        index              = other.index;
+        oppositeDirection  = other.oppositeDirection;
+        return *this;
+    };
 
-  void setIndex        (int val) { index     = val; };
-  void setStartNodeRef (int val) { startNode = val; };
-  void setEndNodeRef   (int val) { endNode   = val; };
+    void setIndex        (int val) {
+        index     = val;
+    };
+    void setStartNodeRef (int val) {
+        startNode = val;
+    };
+    void setEndNodeRef   (int val) {
+        endNode   = val;
+    };
 
-  void setOpposite(FGTaxiSegment *opp) { oppositeDirection = opp; };
+    void setOpposite(FGTaxiSegment *opp) {
+        oppositeDirection = opp;
+    };
 
-  void setStart(FGTaxiNodeVector *nodes);
-  void setEnd  (FGTaxiNodeVector *nodes);
-  void setPushBackType(bool val) { isPushBackRoute = val; };
-  void setDimensions(double elevation);
+    void setStart(FGTaxiNodeVector *nodes);
+    void setEnd  (FGTaxiNodeVector *nodes);
+    void setPushBackType(bool val) {
+        isPushBackRoute = val;
+    };
+    void setDimensions(double elevation);
+    void block() {
+        isBlocked = true;
+    }
+    void unblock() {
+        isBlocked = false;
+    };
+    bool hasBlock() {
+        return isBlocked;
+    };
 
-  FGTaxiNode * getEnd() { return end;};
-  FGTaxiNode * getStart() { return start; };
-  double getLength() { return length; };
-  int getIndex() { return index; };
-  double getLatitude()  { return center.getLatitudeDeg();  };
-  double getLongitude() { return center.getLongitudeDeg(); };
-  double getHeading()   { return heading; }; 
-  bool isPushBack() { return isPushBackRoute; };
+    FGTaxiNode * getEnd() {
+        return end;
+    };
+    FGTaxiNode * getStart() {
+        return start;
+    };
+    double getLength() {
+        return length;
+    };
+    int getIndex() {
+        return index;
+    };
+    double getLatitude()  {
+        return center.getLatitudeDeg();
+    };
+    double getLongitude() {
+        return center.getLongitudeDeg();
+    };
+    double getHeading()   {
+        return heading;
+    };
+    bool isPushBack() {
+        return isPushBackRoute;
+    };
 
-  int getPenalty(int nGates);
+    int getPenalty(int nGates);
 
-  FGTaxiSegment *getAddress() { return this;};
+    FGTaxiSegment *getAddress() {
+        return this;
+    };
+
+    bool operator<(const FGTaxiSegment &other) const {
+        return index < other.index;
+    };
+    //bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
+    FGTaxiSegment *opposite() {
+        return oppositeDirection;
+    };
+    void setCourseDiff(double crse);
 
-  bool operator<(const FGTaxiSegment &other) const { return index < other.index; };
-  //bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
-  FGTaxiSegment *opposite() { return oppositeDirection; };
-  void setCourseDiff(double crse);
 
 
 
-  
 };
 
 
@@ -168,52 +213,67 @@ typedef vector<int>::iterator intVecIterator;
 class FGTaxiRoute
 {
 private:
-  intVec nodes;
-  intVec routes;
-  double distance;
+    intVec nodes;
+    intVec routes;
+    double distance;
 //  int depth;
-  intVecIterator currNode;
-  intVecIterator currRoute;
+    intVecIterator currNode;
+    intVecIterator currRoute;
 
 public:
-  FGTaxiRoute() { distance = 0; currNode = nodes.begin(); currRoute = routes.begin();};
-  FGTaxiRoute(intVec nds, intVec rts, double dist, int dpth) { 
-    nodes = nds; 
-    routes = rts;
-    distance = dist; 
-    currNode = nodes.begin();
-    currRoute = routes.begin();
+    FGTaxiRoute() {
+        distance = 0;
+        currNode = nodes.begin();
+        currRoute = routes.begin();
+    };
+    FGTaxiRoute(intVec nds, intVec rts, double dist, int dpth) {
+        nodes = nds;
+        routes = rts;
+        distance = dist;
+        currNode = nodes.begin();
+        currRoute = routes.begin();
 //    depth = dpth;
-  };
+    };
 
-  FGTaxiRoute& operator= (const FGTaxiRoute &other) {
-    nodes = other.nodes;
-    routes = other.routes;
-    distance = other.distance;
+    FGTaxiRoute& operator= (const FGTaxiRoute &other) {
+        nodes = other.nodes;
+        routes = other.routes;
+        distance = other.distance;
 //    depth = other.depth;
-    currNode = nodes.begin();
-    currRoute = routes.begin();
-    return *this;
-  };
+        currNode = nodes.begin();
+        currRoute = routes.begin();
+        return *this;
+    };
 
-  FGTaxiRoute(const FGTaxiRoute& copy) :
-    nodes(copy.nodes),
-    routes(copy.routes),
-    distance(copy.distance),
+    FGTaxiRoute(const FGTaxiRoute& copy) :
+            nodes(copy.nodes),
+            routes(copy.routes),
+            distance(copy.distance),
 //    depth(copy.depth),
-    currNode(nodes.begin()),
-    currRoute(routes.begin())
-  {};
+            currNode(nodes.begin()),
+            currRoute(routes.begin())
+    {};
 
-  bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
-  bool empty () { return nodes.begin() == nodes.end(); };
-  bool next(int *nde); 
-  bool next(int *nde, int *rte);
-  void rewind(int legNr);
-  
-  void first() { currNode = nodes.begin(); currRoute = routes.begin(); };
-  int size() { return nodes.size(); };
-  int nodesLeft() { return nodes.end() - currNode; };
+    bool operator< (const FGTaxiRoute &other) const {
+        return distance < other.distance;
+    };
+    bool empty () {
+        return nodes.begin() == nodes.end();
+    };
+    bool next(int *nde);
+    bool next(int *nde, int *rte);
+    void rewind(int legNr);
+
+    void first() {
+        currNode = nodes.begin();
+        currRoute = routes.begin();
+    };
+    int size() {
+        return nodes.size();
+    };
+    int nodesLeft() {
+        return nodes.end() - currNode;
+    };
 
 //  int getDepth() { return depth; };
 };
@@ -227,75 +287,84 @@ typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
 class FGGroundNetwork : public FGATCController
 {
 private:
-  bool hasNetwork;
-  bool networkInitialized;
-  time_t nextSave;
-  //int maxDepth;
-  int count;
-  FGTaxiNodeVector    nodes;
-  FGTaxiNodeVector    pushBackNodes;
-  FGTaxiSegmentVector segments;
-  //intVec route;
-  //intVec nodesStack;
-  //intVec routesStack;
-  TaxiRouteVector routes;
-  TrafficVector activeTraffic;
-  TrafficVectorIterator currTraffic;
+    bool hasNetwork;
+    bool networkInitialized;
+    time_t nextSave;
+    //int maxDepth;
+    int count;
+    FGTaxiNodeVector    nodes;
+    FGTaxiNodeVector    pushBackNodes;
+    FGTaxiSegmentVector segments;
+    //intVec route;
+    //intVec nodesStack;
+    //intVec routesStack;
+    TaxiRouteVector routes;
+    TrafficVector activeTraffic;
+    TrafficVectorIterator currTraffic;
 
-  bool foundRoute;
-  double totalDistance, maxDistance;
-  FGTowerController *towerController;
-  FGAirport *parent;
+    bool foundRoute;
+    double totalDistance, maxDistance;
+    FGTowerController *towerController;
+    FGAirport *parent;
 
 
-  //void printRoutingError(string);
+    //void printRoutingError(string);
 
-  void checkSpeedAdjustment(int id, double lat, double lon, 
-			    double heading, double speed, double alt);
-  void checkHoldPosition(int id, double lat, double lon, 
-			 double heading, double speed, double alt);
+    void checkSpeedAdjustment(int id, double lat, double lon,
+                              double heading, double speed, double alt);
+    void checkHoldPosition(int id, double lat, double lon,
+                           double heading, double speed, double alt);
 
 
 
 public:
-  FGGroundNetwork();
-  ~FGGroundNetwork();
+    FGGroundNetwork();
+    ~FGGroundNetwork();
 
-  void addNode   (const FGTaxiNode& node);
-  void addNodes  (FGParkingVec *parkings);
-  void addSegment(const FGTaxiSegment& seg); 
+    void addNode   (const FGTaxiNode& node);
+    void addNodes  (FGParkingVec *parkings);
+    void addSegment(const FGTaxiSegment& seg);
 
-  void init();
-  bool exists() { return hasNetwork; };
-  void setTowerController(FGTowerController *twrCtrlr) { towerController = twrCtrlr; };
+    void init();
+    bool exists() {
+        return hasNetwork;
+    };
+    void setTowerController(FGTowerController *twrCtrlr) {
+        towerController = twrCtrlr;
+    };
 
-  int findNearestNode(double lat, double lon);
-  int findNearestNode(const SGGeod& aGeod);
+    int findNearestNode(double lat, double lon);
+    int findNearestNode(const SGGeod& aGeod);
 
-  FGTaxiNode *findNode(unsigned idx);
-  FGTaxiSegment *findSegment(unsigned idx);
-  FGTaxiRoute findShortestRoute(int start, int end, bool fullSearch=true);
-  //void trace(FGTaxiNode *, int, int, double dist);
+    FGTaxiNode *findNode(unsigned idx);
+    FGTaxiSegment *findSegment(unsigned idx);
+    FGTaxiRoute findShortestRoute(int start, int end, bool fullSearch=true);
+    //void trace(FGTaxiNode *, int, int, double dist);
 
-  int getNrOfNodes() { return nodes.size(); };
+    int getNrOfNodes() {
+        return nodes.size();
+    };
 
-  void setParent(FGAirport *par) { parent = par; };
+    void setParent(FGAirport *par) {
+        parent = par;
+    };
 
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, 
-				double lat, double lon, double hdg, double spd, double alt, 
-				double radius, int leg, FGAIAircraft *aircraft);
-  virtual void signOff(int id);
-  virtual void updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt);
-  virtual bool hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon, double hdg, double spd, double alt,
+                                  double radius, int leg, FGAIAircraft *aircraft);
+    virtual void signOff(int id);
+    virtual void updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt);
+    virtual bool hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
 
-  bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
-                               AtcMsgDir msgDir);
-  bool checkForCircularWaits(int id);
-  virtual void render(bool);
-  virtual string getName();
+    bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
+                                AtcMsgDir msgDir);
+    bool checkForCircularWaits(int id);
+    virtual void render(bool);
+    virtual string getName();
+    virtual void update(double dt);
 
-  void saveElevationCache();
+    void saveElevationCache();
 };
 
 
diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx
index a4a18ca17..235154385 100644
--- a/src/Traffic/Schedule.cxx
+++ b/src/Traffic/Schedule.cxx
@@ -380,7 +380,7 @@ void FGAISchedule::scheduleFlights(time_t now)
   FGScheduledFlight *flight = NULL;
   do {
     if (currentDestination.empty()) {
-        flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400));
+        //flight = findAvailableFlight(userPort, flightIdentifier, now, (now+1800));
         if (!flight)
             flight = findAvailableFlight(currentDestination, flightIdentifier);
     } else {
@@ -423,7 +423,7 @@ void FGAISchedule::scheduleFlights(time_t now)
                              << "  "        << arrT << ":");
   
     flights.push_back(flight);
-  } while (currentDestination != startingPort);
+  } while (1); //(currentDestination != startingPort);
   SG_LOG(SG_GENERAL, SG_BULK, " Done ");
 }
 

From 41759b15d6103c13fe9a222e286e257bdab575c8 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 4 Oct 2011 08:58:09 +0100
Subject: [PATCH 80/85] Work on the NavDisplay instrument.

---
 src/Instrumentation/CMakeLists.txt     | 135 +++++++++++++++++--------
 src/Instrumentation/NavDisplay.cxx     |  36 ++++---
 src/Instrumentation/instrument_mgr.cxx |   6 +-
 3 files changed, 121 insertions(+), 56 deletions(-)

diff --git a/src/Instrumentation/CMakeLists.txt b/src/Instrumentation/CMakeLists.txt
index 96c11b519..f65da924a 100644
--- a/src/Instrumentation/CMakeLists.txt
+++ b/src/Instrumentation/CMakeLists.txt
@@ -1,42 +1,42 @@
 include(FlightGearComponent)
 
 set(SOURCES
-	adf.cxx
-	agradar.cxx
-	airspeed_indicator.cxx
-	altimeter.cxx
-	attitude_indicator.cxx
-	clock.cxx
-	dclgps.cxx
-	dme.cxx
-	gps.cxx
-	groundradar.cxx
-	gsdi.cxx
-	gyro.cxx
-	heading_indicator.cxx
-	heading_indicator_dg.cxx
-	heading_indicator_fg.cxx
-	inst_vertical_speed_indicator.cxx
-	instrument_mgr.cxx
-	kr_87.cxx
-	kt_70.cxx
-	mag_compass.cxx
-	marker_beacon.cxx
-	mk_viii.cxx
-	mrg.cxx
-	navradio.cxx
-	od_gauge.cxx
-	rad_alt.cxx
-	render_area_2d.cxx
-	rnav_waypt_controller.cxx
-	slip_skid_ball.cxx
-	tacan.cxx
-	tcas.cxx
-	transponder.cxx
-	turn_indicator.cxx
-	vertical_speed_indicator.cxx
-	wxradar.cxx
-	NavDisplay.cxx
+    adf.cxx
+    agradar.cxx
+    airspeed_indicator.cxx
+    altimeter.cxx
+    attitude_indicator.cxx
+    clock.cxx
+    dclgps.cxx
+    dme.cxx
+    gps.cxx
+    groundradar.cxx
+    gsdi.cxx
+    gyro.cxx
+    heading_indicator.cxx
+    heading_indicator_dg.cxx
+    heading_indicator_fg.cxx
+    inst_vertical_speed_indicator.cxx
+    instrument_mgr.cxx
+    kr_87.cxx
+    kt_70.cxx
+    mag_compass.cxx
+    marker_beacon.cxx
+    mk_viii.cxx
+    mrg.cxx
+    navradio.cxx
+    od_gauge.cxx
+    rad_alt.cxx
+    render_area_2d.cxx
+    rnav_waypt_controller.cxx
+    slip_skid_ball.cxx
+    tacan.cxx
+    tcas.cxx
+    transponder.cxx
+    turn_indicator.cxx
+    vertical_speed_indicator.cxx
+    wxradar.cxx
+    NavDisplay.cxx
     HUD/HUD.cxx
     HUD/HUD_dial.cxx
     HUD/HUD_gauge.cxx
@@ -64,7 +64,62 @@ set(SOURCES
     KLN89/kln89_page_usr.cxx
     KLN89/kln89_page_vor.cxx
     KLN89/kln89_page_alt.cxx
-	)
-	
-	
-flightgear_component(Instruments "${SOURCES}")
\ No newline at end of file
+    )
+
+set(HEADERS
+    adf.hxx
+    agradar.hxx
+    airspeed_indicator.hxx
+    altimeter.hxx
+    attitude_indicator.hxx
+    clock.hxx
+    dclgps.hxx
+    dme.hxx
+    gps.hxx
+    groundradar.hxx
+    gsdi.hxx
+    gyro.hxx
+    heading_indicator.hxx
+    heading_indicator_dg.hxx
+    heading_indicator_fg.hxx
+    inst_vertical_speed_indicator.hxx
+    instrument_mgr.hxx
+    kr_87.hxx
+    kt_70.hxx
+    mag_compass.hxx
+    marker_beacon.hxx
+    mk_viii.hxx
+    mrg.hxx
+    navradio.hxx
+    od_gauge.hxx
+    rad_alt.hxx
+    render_area_2d.hxx
+    rnav_waypt_controller.hxx
+    slip_skid_ball.hxx
+    tacan.hxx
+    tcas.hxx
+    transponder.hxx
+    turn_indicator.hxx
+    vertical_speed_indicator.hxx
+    wxradar.hxx
+    NavDisplay.hxx
+    HUD/HUD.hxx
+    KLN89/kln89.hxx
+    KLN89/kln89_page.hxx
+    KLN89/kln89_page_act.hxx
+    KLN89/kln89_page_apt.hxx
+    KLN89/kln89_page_cal.hxx
+    KLN89/kln89_page_dir.hxx
+    KLN89/kln89_page_fpl.hxx
+    KLN89/kln89_page_int.hxx
+    KLN89/kln89_page_nav.hxx
+    KLN89/kln89_page_ndb.hxx
+    KLN89/kln89_page_nrst.hxx
+    KLN89/kln89_page_oth.hxx
+    KLN89/kln89_page_set.hxx
+    KLN89/kln89_page_usr.hxx
+    KLN89/kln89_page_vor.hxx
+    KLN89/kln89_page_alt.hxx
+    )   
+    
+flightgear_component(Instruments "${SOURCES}" "${HEADERS}")
\ No newline at end of file
diff --git a/src/Instrumentation/NavDisplay.cxx b/src/Instrumentation/NavDisplay.cxx
index 164fb40fd..64c490ca1 100644
--- a/src/Instrumentation/NavDisplay.cxx
+++ b/src/Instrumentation/NavDisplay.cxx
@@ -124,12 +124,12 @@ static string formatPropertyValue(SGPropertyNode* nd, const string& format)
 {
     assert(nd);
     static char buf[512];
-    if (format.find('d') >= 0) {
+    if (format.find('d') != string::npos) {
         ::snprintf(buf, 512, format.c_str(), nd->getIntValue());
         return buf;
     }
     
-    if (format.find('s') >= 0) {
+    if (format.find('s') != string::npos) {
         ::snprintf(buf, 512, format.c_str(), nd->getStringValue());
         return buf;
     }
@@ -150,7 +150,7 @@ static osg::Vec2 mult(const osg::Vec2& v, const osg::Matrixf& m)
 class SymbolDef
 {
 public:
-    void initFromNode(SGPropertyNode* node)
+    bool initFromNode(SGPropertyNode* node)
     {
         type = node->getStringValue("type");
         enable = sgReadCondition(fgGetNode("/"), node->getChild("enable"));
@@ -202,6 +202,8 @@ public:
             stretchV2 = node->getFloatValue("v2");
             stretchV3 = node->getFloatValue("v3");
         }
+      
+        return true;
     }
     
     SGCondition* enable;
@@ -279,27 +281,27 @@ public:
         assert(definition->hasText);
         string r;
         
-        int pos = 0;
+        size_t pos = 0;
         int lastPos = 0;
         
-        for (; pos < (int) definition->textTemplate.size();) {
+        for (; pos < definition->textTemplate.size();) {
             pos = definition->textTemplate.find('{', pos);
-            if (pos == -1) { // no more replacements
+          if (pos == string::npos) { // no more replacements
                 r.append(definition->textTemplate.substr(lastPos));
                 break;
             }
             
             r.append(definition->textTemplate.substr(lastPos, pos - lastPos));
             
-            int endReplacement = definition->textTemplate.find('}', pos+1);
+            size_t endReplacement = definition->textTemplate.find('}', pos+1);
             if (endReplacement <= pos) {
                 return "bad replacement";
             }
 
             string spec = definition->textTemplate.substr(pos + 1, endReplacement - (pos + 1));
         // look for formatter in spec
-            int colonPos = spec.find(':');
-            if (colonPos < 0) {
+            size_t colonPos = spec.find(':');
+          if (colonPos == string::npos) {
             // simple replacement
                 r.append(props->getStringValue(spec));
             } else {
@@ -343,6 +345,18 @@ NavDisplay::NavDisplay(SGPropertyNode *node) :
     INITFONT("color/alpha", 1, Float);
 #undef INITFONT
 
+    SGPropertyNode* symbolsNode = node->getNode("symbols");
+    SGPropertyNode* symbol;
+  
+    for (int i = 0; (symbol = symbolsNode->getChild("symbol", i)) != NULL; ++i) {
+        SymbolDef* def = new SymbolDef;
+        if (!def->initFromNode(symbol)) {
+          delete def;
+          continue;
+        }
+        
+        _rules.push_back(def);
+    } // of symbol definition parsing
 }
 
 
@@ -542,12 +556,8 @@ NavDisplay::updateFont()
         tpath = path;
     }
 
-#if (FG_OSG_VERSION >= 21000)
     osg::ref_ptr<osgDB::ReaderWriter::Options> fontOptions = new osgDB::ReaderWriter::Options("monochrome");
     osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str(), fontOptions.get());
-#else
-    osg::ref_ptr<osgText::Font> font = osgText::readFontFile(tpath.c_str());
-#endif
 
     if (font != 0) {
         _font = font;
diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx
index 4ebda4fa1..9bdd1bd7a 100644
--- a/src/Instrumentation/instrument_mgr.cxx
+++ b/src/Instrumentation/instrument_mgr.cxx
@@ -81,13 +81,13 @@ void FGInstrumentMgr::init()
   try {
     readProperties( config.str(), config_props );
     if (!build(config_props)) {
-      throw sg_error(
+      throw sg_exception(
                     "Detected an internal inconsistency in the instrumentation\n"
                     "system specification file.  See earlier errors for details.");
     }
-  } catch (const sg_exception&) {
+  } catch (const sg_exception& e) {
     SG_LOG(SG_COCKPIT, SG_ALERT, "Failed to load instrumentation system model: "
-                    << config.str() );
+                    << config.str() << ":" << e.getFormattedMessage() );
   }
 
 

From 1692bc749e01bc5713ec9c05ac8c80887f089434 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 4 Oct 2011 09:14:15 +0100
Subject: [PATCH 81/85] Mac: Work-around for OSG3's Cocoa Viewer interacting
 badly with PUI

---
 src/Main/FGEventHandler.cxx | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/Main/FGEventHandler.cxx b/src/Main/FGEventHandler.cxx
index f6fc75c76..950ccfd10 100644
--- a/src/Main/FGEventHandler.cxx
+++ b/src/Main/FGEventHandler.cxx
@@ -18,6 +18,12 @@
 #define X_DOUBLE_SCROLL_BUG 1
 #endif
 
+#ifdef SG_MAC
+// hack - during interactive resize on Mac, OSG queues and then flushes
+// a large number of resize events, without doing any drawing.
+extern void puCleanUpJunk ( void ) ;
+#endif
+
 namespace flightgear
 {
 const int displayStatsKey = 1;
@@ -234,6 +240,12 @@ bool FGEventHandler::handle(const osgGA::GUIEventAdapter& ea,
         CameraGroup::getDefault()->resized();
         if (resizable)
           globals->get_renderer()->resize(ea.getWindowWidth(), ea.getWindowHeight());
+      #ifdef SG_MAC
+        // work around OSG Cocoa-Viewer issue with resize event handling,
+        // where resize events are queued up, then dispatched in a batch, with
+        // no interveningd drawing calls.
+        puCleanUpJunk();
+      #endif
         return true;
      case osgGA::GUIEventAdapter::CLOSE_WINDOW:
     case osgGA::GUIEventAdapter::QUIT_APPLICATION:

From c4c5cc850bc8f006957592f67fafdaf7393c1b94 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 4 Oct 2011 09:17:56 +0100
Subject: [PATCH 82/85] Adjust cursor-setting code, for better compatibility
 with Cocoa-Viewer (OSG patch still required, unfortunately)

---
 src/Main/fg_os_osgviewer.cxx | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx
index 6952195f5..e8ba901a2 100644
--- a/src/Main/fg_os_osgviewer.cxx
+++ b/src/Main/fg_os_osgviewer.cxx
@@ -45,6 +45,7 @@
 #include <osg/View>
 #include <osgViewer/ViewerEventHandlers>
 #include <osgViewer/Viewer>
+#include <osgViewer/GraphicsWindow>
 
 #include <Scenery/scenery.hxx>
 #include "fg_os.hxx"
@@ -313,24 +314,23 @@ void fgOSFullScreen()
 {
 }
 
-static void setMouseCursor(osg::Camera* camera, int cursor)
+static void setMouseCursor(osgViewer::GraphicsWindow* gw, int cursor)
 {
-    if (!camera)
+    if (!gw) {
         return;
-    osg::GraphicsContext* gc = camera->getGraphicsContext();
-    if (!gc)
-        return;
-    osgViewer::GraphicsWindow* gw;
-    gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc);
-    if (!gw)
-        return;
-    
+    }
+  
     osgViewer::GraphicsWindow::MouseCursor mouseCursor;
     mouseCursor = osgViewer::GraphicsWindow::InheritCursor;
-    if     (cursor == MOUSE_CURSOR_NONE)
+    if (cursor == MOUSE_CURSOR_NONE)
         mouseCursor = osgViewer::GraphicsWindow::NoCursor;
     else if(cursor == MOUSE_CURSOR_POINTER)
+#ifdef SG_MAC
+        // osgViewer-Cocoa lacks RightArrowCursor, use Left
+        mouseCursor = osgViewer::GraphicsWindow::LeftArrowCursor;
+#else
         mouseCursor = osgViewer::GraphicsWindow::RightArrowCursor;
+#endif
     else if(cursor == MOUSE_CURSOR_WAIT)
         mouseCursor = osgViewer::GraphicsWindow::WaitCursor;
     else if(cursor == MOUSE_CURSOR_CROSSHAIR)
@@ -362,9 +362,12 @@ static int _cursor = -1;
 void fgSetMouseCursor(int cursor)
 {
     _cursor = cursor;
-    setMouseCursor(viewer->getCamera(), cursor);
-    for (unsigned i = 0; i < viewer->getNumSlaves(); ++i)
-        setMouseCursor(viewer->getSlave(i)._camera.get(), cursor);
+  
+    std::vector<osgViewer::GraphicsWindow*> windows;
+    viewer->getWindows(windows);
+    BOOST_FOREACH(osgViewer::GraphicsWindow* gw, windows) {
+        setMouseCursor(gw, cursor);
+    }
 }
 
 int fgGetMouseCursor()

From a486eebeefd485e4f8871194a340b2144116b5bb Mon Sep 17 00:00:00 2001
From: Mathias Froehlich <Mathias.Froehlich@web.de>
Date: Tue, 4 Oct 2011 20:57:15 +0200
Subject: [PATCH 83/85] hla: Avoid explicit attribute update request. Is
 already done by simgear.

---
 src/Network/HLA/hla.cxx | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx
index 28102336b..22450de10 100644
--- a/src/Network/HLA/hla.cxx
+++ b/src/Network/HLA/hla.cxx
@@ -710,7 +710,6 @@ public:
             aiMgr->attach(_aiMultiplayer.get());
 
             _propertyReferenceSet->setRootNode(_aiMultiplayer->getPropertyRoot());
-            objectInstance.requestAttributeUpdate();
         }
     }
 
@@ -739,7 +738,6 @@ public:
         MPInAttributeCallback* attributeCallback = new MPInAttributeCallback;
         objectInstance.setAttributeCallback(attributeCallback);
         attachDataElements(objectInstance, *attributeCallback, false);
-        objectInstance.requestAttributeUpdate();
     }
 
     virtual void removeInstance(const sg::HLAObjectClass& objectClass, sg::HLAObjectInstance& objectInstance, const sg::RTIData& tag)

From e9d24b05ca09c6f9819d80f45905198abe9422ba Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Wed, 5 Oct 2011 15:26:41 +0200
Subject: [PATCH 84/85] Introducing: The new navradio code (WIP)

Here comes the work-in-progres code for a new navradio
implementation. Once completed, it will replace the
old/current navradio implementation.
The new code can be activated by setting
/instrumentation/use-new-navradio=true
at startup. This disables the old navradio implementation.

Current state:
- VOR works pretty good including the new
functionality 'code of confusion'.
- LOC and GS basically work
- backward compatibility (many properties) is to be implemented
---
 projects/VC90/FlightGear/FlightGear.vcproj |   8 +
 src/Instrumentation/CMakeLists.txt         |   4 +-
 src/Instrumentation/Makefile.am            |   1 +
 src/Instrumentation/instrument_mgr.cxx     |   4 +-
 src/Instrumentation/newnavradio.cxx        | 968 +++++++++++++++++++++
 src/Instrumentation/newnavradio.hxx        |  18 +
 6 files changed, 1000 insertions(+), 3 deletions(-)
 create mode 100755 src/Instrumentation/newnavradio.cxx
 create mode 100755 src/Instrumentation/newnavradio.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index 6859879e4..58633d244 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3761,6 +3761,14 @@
 				RelativePath="..\..\..\src\Instrumentation\navradio.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\Instrumentation\newnavradio.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Instrumentation\newnavradio.hxx"
+				>
+			</File>
 			<File
 				RelativePath="..\..\..\src\Instrumentation\od_gauge.cxx"
 				>
diff --git a/src/Instrumentation/CMakeLists.txt b/src/Instrumentation/CMakeLists.txt
index f65da924a..7ae7cf343 100644
--- a/src/Instrumentation/CMakeLists.txt
+++ b/src/Instrumentation/CMakeLists.txt
@@ -25,6 +25,7 @@ set(SOURCES
     mk_viii.cxx
     mrg.cxx
     navradio.cxx
+    newnavradio.cxx
     od_gauge.cxx
     rad_alt.cxx
     render_area_2d.cxx
@@ -91,6 +92,7 @@ set(HEADERS
     mk_viii.hxx
     mrg.hxx
     navradio.hxx
+    newnavradio.hxx
     od_gauge.hxx
     rad_alt.hxx
     render_area_2d.hxx
@@ -122,4 +124,4 @@ set(HEADERS
     KLN89/kln89_page_alt.hxx
     )   
     
-flightgear_component(Instruments "${SOURCES}" "${HEADERS}")
\ No newline at end of file
+flightgear_component(Instruments "${SOURCES}" "${HEADERS}")
diff --git a/src/Instrumentation/Makefile.am b/src/Instrumentation/Makefile.am
index 7930fdbfb..23292e17c 100644
--- a/src/Instrumentation/Makefile.am
+++ b/src/Instrumentation/Makefile.am
@@ -22,6 +22,7 @@ libInstrumentation_a_SOURCES = \
         marker_beacon.cxx marker_beacon.hxx \
 	mrg.cxx mrg.hxx\
         navradio.cxx navradio.hxx \
+        newnavradio.cxx newnavradio.hxx \
         slip_skid_ball.cxx slip_skid_ball.hxx \
 	transponder.cxx transponder.hxx \
         turn_indicator.cxx turn_indicator.hxx \
diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx
index 9bdd1bd7a..c6694173f 100644
--- a/src/Instrumentation/instrument_mgr.cxx
+++ b/src/Instrumentation/instrument_mgr.cxx
@@ -37,7 +37,7 @@
 #include "kt_70.hxx"
 #include "mag_compass.hxx"
 #include "marker_beacon.hxx"
-#include "navradio.hxx"
+#include "newnavradio.hxx"
 #include "slip_skid_ball.hxx"
 #include "transponder.hxx"
 #include "turn_indicator.hxx"
@@ -188,7 +188,7 @@ bool FGInstrumentMgr::build (SGPropertyNode* config_props)
             set_subsystem( id, new FGMarkerBeacon( node ) );
 
         } else if ( name == "nav-radio" ) {
-            set_subsystem( id, new FGNavRadio( node ) );
+            set_subsystem( id, Instrumentation::NavRadio::createInstance( node ) );
 
         } else if ( name == "slip-skid-ball" ) {
             set_subsystem( id, new SlipSkidBall( node ) );
diff --git a/src/Instrumentation/newnavradio.cxx b/src/Instrumentation/newnavradio.cxx
new file mode 100755
index 000000000..f98f5aee8
--- /dev/null
+++ b/src/Instrumentation/newnavradio.cxx
@@ -0,0 +1,968 @@
+// navradio.cxx -- class to manage a nav radio instance
+//
+// Written by Curtis Olson, started April 2000.
+// Rewritten by Torsten Dreyer, August 2011
+//
+// Copyright (C) 2000 - 2002  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "newnavradio.hxx"
+
+#include <assert.h>
+#include <boost/foreach.hpp>
+
+#include <simgear/math/SGMath.hxx>
+#include <simgear/math/interpolater.hxx>
+#include <simgear/sg_inlines.h>
+#include <simgear/props/propertyObject.hxx>
+
+#include <Main/fg_props.hxx>
+#include <Navaids/navlist.hxx>
+#include <Sound/audioident.hxx>
+
+#include "navradio.hxx"
+
+
+namespace Instrumentation {
+
+using simgear::PropertyObject;
+
+/* --------------The Navigation Indicator ----------------------------- */
+
+class NavIndicator {
+public:
+    NavIndicator( SGPropertyNode * rootNode ) :
+      _cdi( rootNode->getNode("heading-needle-deflection", true ) ),
+      _cdiNorm( rootNode->getNode("heading-needle-deflection-norm", true ) ),
+      _course( rootNode->getNode("radials/selected-deg", true ) ),
+      _toFlag( rootNode->getNode("to-flag", true ) ),
+      _fromFlag( rootNode->getNode("from-flag", true ) ),
+      _signalQuality( rootNode->getNode("signal-quality-norm", true ) ),
+      _hasGS( rootNode->getNode("has-gs", true ) ),
+      _gsDeflection(rootNode->getNode("gs-needle-deflection", true )),
+      _gsDeflectionDeg(rootNode->getNode("gs-needle-deflection-deg", true )),
+      _gsDeflectionNorm(rootNode->getNode("gs-needle-deflection-norm", true ))
+  {
+  }
+
+  virtual ~NavIndicator() {}
+
+  /**
+   * set the normalized CDI deflection
+   * @param norm the cdi deflection normalized [-1..1]
+   */
+  void setCDI( double norm )
+  {
+      _cdi = norm * 10.0;
+      _cdiNorm = norm;
+  }
+
+  /**
+   * set the normalized GS deflection
+   * @param norm the gs deflection normalized to [-1..1]
+   */
+  void setGS( double norm )
+  {
+      _gsDeflectionNorm = norm;
+      _gsDeflectionDeg = norm * 0.7;
+      _gsDeflection = norm * 3.5;
+  }
+
+  void setGS( bool enabled )
+  {
+      _hasGS = enabled;
+      if( !enabled ) {
+        setGS( 0.0 );
+      }
+  }
+
+  void showFrom( bool on )
+  {
+      _fromFlag = on;
+  }
+
+  void showTo( bool on )
+  {
+      _toFlag = on;
+  }
+      
+  void setSelectedCourse( double course )
+  {
+      _course = course;
+  }
+
+  double getSelectedCourse() const
+  {
+      return SGMiscd::normalizePeriodic(0.0, 360.0, _course );
+  }
+
+  void setSignalQuality( double signalQuality )
+  {
+      _signalQuality = signalQuality;
+  }
+
+private:
+  PropertyObject<double> _cdi;
+  PropertyObject<double> _cdiNorm;
+  PropertyObject<double> _course;
+  PropertyObject<double> _toFlag;
+  PropertyObject<double> _fromFlag;
+  PropertyObject<double> _signalQuality;
+  PropertyObject<double> _hasGS;
+  PropertyObject<double> _gsDeflection;
+  PropertyObject<double> _gsDeflectionDeg;
+  PropertyObject<double> _gsDeflectionNorm;
+};
+
+/* ---------------------------------------------------------------- */
+
+class NavRadioComponent {
+public:
+  NavRadioComponent( const std::string & name, SGPropertyNode_ptr rootNode );
+  virtual ~NavRadioComponent();
+
+  virtual void   update( double dt, const SGGeod & aircraftPosition );
+  virtual void   search( double frequency, const SGGeod & aircraftPosition );
+  virtual double getRange_nm( const SGGeod & aircraftPosition );
+  virtual void   display( NavIndicator & navIndicator ) = 0;
+  virtual bool   valid() const { return NULL != _navRecord && true == _serviceable; }
+
+protected:
+  virtual double computeSignalQuality_norm( const SGGeod & aircraftPosition );
+  virtual FGNavList * getNavaidList() = 0;
+
+  // General-purpose sawtooth function.  Graph looks like this:
+  //         /\                                    .
+  //       \/
+  // Odd symmetry, inversion symmetry about the origin.
+  // Unit slope at the origin.
+  // Max 1, min -1, period 4.
+  // Two zero-crossings per period, one with + slope, one with - slope.
+  // Useful for false localizer courses.
+  static double sawtooth(double xx)
+  {
+    return 4.0 * fabs(xx/4.0 + 0.25 - floor(xx/4.0 + 0.75)) - 1.0;
+  }
+
+  SGPropertyNode_ptr _rootNode;
+  const std::string _name;
+  FGNavRecord * _navRecord;
+  PropertyObject<bool>   _serviceable;
+  PropertyObject<double> _signalQuality_norm;
+  PropertyObject<double> _trueBearingTo_deg;
+  PropertyObject<double> _trueBearingFrom_deg;
+  PropertyObject<double> _trackDistance_m;
+  PropertyObject<double> _slantDistance_m;
+  PropertyObject<double> _heightAboveStation_ft;
+  PropertyObject<string> _ident;
+  PropertyObject<bool>   _inRange;
+  PropertyObject<double> _range_nm;
+};
+
+class NavRadioComponentWithIdent : public NavRadioComponent {
+public:
+  NavRadioComponentWithIdent( const std::string & name, SGPropertyNode_ptr rootNode, AudioIdent * audioIdent );
+  virtual ~NavRadioComponentWithIdent();
+  void update( double dt, const SGGeod & aircraftPosition );
+protected:
+  static std::string getIdentString( const std::string & name, int index );
+private:
+  AudioIdent * _audioIdent;
+  PropertyObject<double> _identVolume;
+  PropertyObject<bool>   _identEnabled;
+};
+
+std::string NavRadioComponentWithIdent::getIdentString( const std::string & name, int index )
+{
+  std::ostringstream temp;
+  temp << name << "-ident-" << index;
+  return temp.str();
+}
+
+NavRadioComponentWithIdent::NavRadioComponentWithIdent( const std::string & name, SGPropertyNode_ptr rootNode, AudioIdent * audioIdent ) :
+  NavRadioComponent( name, rootNode ),
+  _audioIdent( audioIdent ),
+  _identVolume( rootNode->getNode(name,true)->getNode("ident-volume",true) ),
+  _identEnabled( rootNode->getNode(name,true)->getNode("ident-enabled",true) )
+{
+  _audioIdent->init();
+
+}
+NavRadioComponentWithIdent::~NavRadioComponentWithIdent()
+{
+  delete _audioIdent;
+}
+
+void NavRadioComponentWithIdent::update( double dt, const SGGeod & aircraftPosition )
+{
+  NavRadioComponent::update( dt, aircraftPosition );
+  _audioIdent->update( dt );
+
+  if( false == ( valid() && _identEnabled && _signalQuality_norm > 0.1 ) ) {
+      _audioIdent->setIdent("", 0.0 );
+      return;
+  }
+  _audioIdent->setIdent( _navRecord->get_trans_ident(), SGMiscd::clip(_identVolume, 0.0, 1.0) );
+}
+
+NavRadioComponent::NavRadioComponent( const std::string & name, SGPropertyNode_ptr rootNode ) :
+  _rootNode(rootNode),
+  _name(name),
+  _navRecord(NULL),
+  _serviceable( rootNode->getNode(name,true)->getNode("serviceable",true) ),
+  _signalQuality_norm( rootNode->getNode(name,true)->getNode("signal-quality-norm",true) ),
+  _trueBearingTo_deg( rootNode->getNode(name,true)->getNode("true-bearing-to-deg",true) ),
+  _trueBearingFrom_deg( rootNode->getNode(name,true)->getNode("true-bearing-from-deg",true) ),
+  _trackDistance_m( rootNode->getNode(name,true)->getNode("track-distance-m",true) ),
+  _slantDistance_m( rootNode->getNode(name,true)->getNode("slant-distance-m",true) ),
+  _heightAboveStation_ft( rootNode->getNode(name,true)->getNode("height-above-station-ft",true) ),
+  _ident( rootNode->getNode(name,true)->getNode("ident",true) ),
+  _inRange( rootNode->getNode(name,true)->getNode("in-range",true) ),
+  _range_nm( rootNode->getNode(_name,true)->getNode("range-nm",true) )
+{
+  simgear::props::Type typ = _serviceable.node()->getType();
+  if ((typ == simgear::props::NONE) || (typ == simgear::props::UNSPECIFIED))
+    _serviceable = true;
+}
+
+NavRadioComponent::~NavRadioComponent()
+{
+}
+
+double NavRadioComponent::getRange_nm( const SGGeod & aircraftPosition )
+{ 
+  if( _navRecord == NULL ) return 0.0; // no station: no range
+  double d = _navRecord->get_range();
+  if( d <= SGLimitsd::min() ) return 25.0; // no configured range: arbitrary number
+  return d; // configured range
+}
+
+void NavRadioComponent::search( double frequency, const SGGeod & aircraftPosition )
+{
+  if( NULL == (_navRecord = getNavaidList()->findByFreq(frequency, aircraftPosition )) ) {
+    SG_LOG(SG_INSTR,SG_ALERT, "No " << _name << " available at " << frequency );
+    _ident = "";
+    return;
+  }
+  SG_LOG(SG_INSTR,SG_ALERT, "Using " << _name << "'" << _navRecord->get_ident() << "' for " << frequency );
+  _ident = _navRecord->ident();
+}
+
+double NavRadioComponent::computeSignalQuality_norm( const SGGeod & aircraftPosition )
+{
+  if( false == valid() ) return 0.0;
+
+  double distance_nm = _slantDistance_m * SG_METER_TO_NM;
+  double range_nm = _range_nm;
+
+  // assume signal quality is 100% up to the published range and 
+  // decay with the distance squared further out
+  if ( distance_nm <= range_nm ) return 1.0;
+  return range_nm*range_nm/(distance_nm*distance_nm);
+}
+
+void NavRadioComponent::update( double dt, const SGGeod & aircraftPosition )
+{
+    if( false == valid() ) {
+      _signalQuality_norm = 0.0;
+      _trueBearingTo_deg = 0.0;
+      _trueBearingFrom_deg = 0.0;
+      _trackDistance_m = 0.0;
+      _slantDistance_m = 0.0;
+      return;
+    } 
+
+    _slantDistance_m = dist(_navRecord->cart(), SGVec3d::fromGeod(aircraftPosition));
+
+    double az1 = 0.0, az2 = 0.0, dist = 0.0;
+    SGGeodesy::inverse(aircraftPosition, _navRecord->geod(), az1, az2, dist );
+    _trueBearingTo_deg = az1; _trueBearingFrom_deg = az2; _trackDistance_m = dist;
+    _heightAboveStation_ft = SGMiscd::max(0.0, aircraftPosition.getElevationFt() - _navRecord->get_elev_ft());
+
+    _range_nm = getRange_nm(aircraftPosition);
+    _signalQuality_norm = computeSignalQuality_norm( aircraftPosition );
+    _inRange = _signalQuality_norm > 0.2;
+}
+
+/* ---------------------------------------------------------------- */
+
+static std::string VORTablePath( const char * name )
+{
+    SGPath path( globals->get_fg_root() );
+    path.append( "Navaids" );
+    path.append(name);
+    return path.str();
+}
+
+class VOR : public NavRadioComponentWithIdent {
+public:
+  VOR( SGPropertyNode_ptr rootNode);
+  virtual ~VOR();
+  virtual void update( double dt, const SGGeod & aircraftPosition );
+  virtual void display( NavIndicator & navIndicator );
+  virtual double getRange_nm(const SGGeod & aircraftPosition);
+protected:
+  virtual double computeSignalQuality_norm( const SGGeod & aircraftPosition );
+  virtual FGNavList * getNavaidList();
+
+private:
+  double _totalTime;
+  class ServiceVolume {
+  public:
+    ServiceVolume() :
+      term_tbl(VORTablePath("range.term")),
+      low_tbl(VORTablePath("range.low")),
+      high_tbl(VORTablePath("range.high")) {
+    }
+    double adjustRange( double height_ft, double nominalRange_nm );
+
+  private:
+    SGInterpTable term_tbl;
+    SGInterpTable low_tbl;
+    SGInterpTable high_tbl;
+  } _serviceVolume;
+
+  PropertyObject<double> _radial;
+  PropertyObject<double> _radialInbound;
+};
+
+// model standard VOR/DME/TACAN service volumes as per AIM 1-1-8
+double VOR::ServiceVolume::adjustRange( double height_ft, double nominalRange_nm )
+{
+    if (nominalRange_nm < SGLimitsd::min() )
+      nominalRange_nm = FG_NAV_DEFAULT_RANGE;
+    
+    // extend out actual usable range to be 1.3x the published safe range
+    const double usability_factor = 1.3;
+
+    // assumptions we model the standard service volume, plus
+    // ... rather than specifying a cylinder, we model a cone that
+    // contains the cylinder.  Then we put an upside down cone on top
+    // to model diminishing returns at too-high altitudes.
+
+    if ( nominalRange_nm < 25.0 + SG_EPSILON ) {
+	// Standard Terminal Service Volume
+	return term_tbl.interpolate( height_ft ) * usability_factor;
+    } else if ( nominalRange_nm < 50.0 + SG_EPSILON ) {
+	// Standard Low Altitude Service Volume
+	// table is based on range of 40, scale to actual range
+	return low_tbl.interpolate( height_ft ) * nominalRange_nm / 40.0
+	    * usability_factor;
+    } else {
+	// Standard High Altitude Service Volume
+	// table is based on range of 130, scale to actual range
+	return high_tbl.interpolate( height_ft ) * nominalRange_nm / 130.0
+	    * usability_factor;
+    }
+}
+
+VOR::VOR( SGPropertyNode_ptr rootNode) :
+  NavRadioComponentWithIdent("vor", rootNode, new VORAudioIdent(getIdentString(string("vor"), rootNode->getIndex()))),
+  _totalTime(0.0),
+  _radial( rootNode->getNode(_name,true)->getNode("radial",true) ),
+  _radialInbound( rootNode->getNode(_name,true)->getNode("radial-inbound",true) )
+{
+}
+
+VOR::~VOR()
+{
+}
+
+double VOR::getRange_nm( const SGGeod & aircraftPosition )
+{
+  return _serviceVolume.adjustRange( _heightAboveStation_ft, _navRecord->get_range() );
+}
+
+FGNavList * VOR::getNavaidList()
+{
+  return globals->get_navlist();
+}
+
+double VOR::computeSignalQuality_norm( const SGGeod & aircraftPosition )
+{
+  // apply cone of confusion. Some sources say it's opening angle is 53deg, others estimate
+  // a diameter of 1NM per 6000ft (approx. 45deg). ICAO Annex 10 says minimum 40deg.
+  // We use 1NM@6000ft and a distance-squared
+  // function to make signal-quality=100% 0.5NM@6000ft from the center and zero overhead
+  double cone_of_confusion_width = 0.5 * _heightAboveStation_ft / 6000.0 * SG_NM_TO_METER;
+  if( _trackDistance_m < cone_of_confusion_width ) {
+    double d = cone_of_confusion_width <= SGLimitsd::min() ? 1 : 
+              (1 - _trackDistance_m/cone_of_confusion_width);
+    return 1-d*d;
+  } 
+
+  // use default decay function outside the cone of confusion
+  return NavRadioComponentWithIdent::computeSignalQuality_norm( aircraftPosition );
+}
+
+void VOR::update( double dt, const SGGeod & aircraftPosition )
+{
+  _totalTime += dt;
+  NavRadioComponentWithIdent::update( dt, aircraftPosition );
+
+  if( false == valid() ) {
+      _radial = 0.0;
+      return;
+  }
+
+  // an arbitrary error function
+  double error = 0.5*(sin(_totalTime/11.0) + sin(_totalTime/23.0));
+
+  // add 1% error at 100% signal-quality
+  // add 50% error at  0% signal-quality
+  // of full deflection (+/-10deg)
+  double e = 10.0 * ( 0.01 + (1-_signalQuality_norm) * 0.49 ) * error;
+
+  // compute magnetic bearing from the station (aka current radial)
+  double r = SGMiscd::normalizePeriodic(0.0, 360.0, _trueBearingFrom_deg - _navRecord->get_multiuse() + e );
+
+  _radial = r;
+  _radialInbound = SGMiscd::normalizePeriodic(0.0,360.0, 180.0 + _radial);
+}
+
+void VOR::display( NavIndicator & navIndicator )
+{
+  if( false == valid() ) return;
+
+  double offset = SGMiscd::normalizePeriodic(-180.0,180.0,_radial - navIndicator.getSelectedCourse());
+  bool to = fabs(offset) >= 90.0;
+
+  if( to ) offset = -offset + copysign(180.0,offset);
+
+  navIndicator.showTo( to );
+  navIndicator.showFrom( !to );
+  // normalize to +/- 1.0 for +/- 10deg, decrease deflection with decreasing signal
+  navIndicator.setCDI( SGMiscd::clip( -offset/10.0, -1.0, 1.0 ) * _signalQuality_norm );
+  navIndicator.setSignalQuality( _signalQuality_norm );
+}
+
+/* ---------------------------------------------------------------- */
+class LOC : public NavRadioComponentWithIdent {
+public:
+  LOC( SGPropertyNode_ptr rootNode );
+  virtual ~LOC();
+  virtual void update( double dt, const SGGeod & aircraftPosition );
+  virtual void search( double frequency, const SGGeod & aircraftPosition );
+  virtual void display( NavIndicator & navIndicator );
+  virtual double getRange_nm(const SGGeod & aircraftPosition);
+
+protected:
+  virtual double computeSignalQuality_norm( const SGGeod & aircraftPosition );
+  virtual FGNavList * getNavaidList();
+
+private:
+  class ServiceVolume {
+  public:
+      ServiceVolume();
+      double adjustRange( double azimuthAngle_deg, double elevationAngle_deg );
+  private:
+      SGInterpTable _azimuthTable;
+      SGInterpTable _elevationTable;
+  } _serviceVolume;
+  PropertyObject<double> _localizerOffset_norm;
+  PropertyObject<double> _localizerWidth_deg;
+};
+
+LOC::ServiceVolume::ServiceVolume()
+{
+// maybe this: http://www.tpub.com/content/aviation2/P-1244/P-12440125.htm
+  // ICAO Annex 10 - 3.1.3.2.2: The emission from the localizer
+  // shall be horizontally polarized
+  // very rough abstraction of a 5-element yagi antenna's
+  // E-plane radiation diagram
+  _azimuthTable.addEntry(   0.0, 1.0 );
+  _azimuthTable.addEntry(  10.0, 1.0 );
+  _azimuthTable.addEntry(  30.0, 0.75 );
+  _azimuthTable.addEntry(  40.0, 0.50 );
+  _azimuthTable.addEntry(  50.0, 0.20 );
+  _azimuthTable.addEntry(  60.0, 0.10 );
+  _azimuthTable.addEntry(  70.0, 0.20 );
+  _azimuthTable.addEntry(  80.0, 0.10 );
+  _azimuthTable.addEntry(  90.0, 0.05 );
+  _azimuthTable.addEntry( 105.0, 0.10 );
+  _azimuthTable.addEntry( 130.0, 0.05 );
+  _azimuthTable.addEntry( 150.0, 0.30 );
+  _azimuthTable.addEntry( 160.0, 0.40 );
+  _azimuthTable.addEntry( 170.0, 0.50 );
+  _azimuthTable.addEntry( 180.0, 0.50 );
+
+  _elevationTable.addEntry(   0.0, 0.1 );
+  _elevationTable.addEntry(  1.05, 1.0 );
+  _elevationTable.addEntry(  7.00, 1.0 );
+  _elevationTable.addEntry(  45.0, 0.3 );
+  _elevationTable.addEntry(  90.0, 0.1 );
+  _elevationTable.addEntry( 180.0, 0.01 );
+}
+
+double LOC::ServiceVolume::adjustRange( double azimuthAngle_deg, double elevationAngle_deg )
+{
+    return _azimuthTable.interpolate( fabs(azimuthAngle_deg) ) * 
+        _elevationTable.interpolate( fabs(elevationAngle_deg) );
+}
+
+LOC::LOC( SGPropertyNode_ptr rootNode) :
+  NavRadioComponentWithIdent("loc", rootNode, new LOCAudioIdent(getIdentString(string("loc"), rootNode->getIndex()))),
+  _serviceVolume(),
+  _localizerOffset_norm( rootNode->getNode(_name,true)->getNode("offset-norm",true) ),
+  _localizerWidth_deg( rootNode->getNode(_name,true)->getNode("width-deg",true) )
+{
+}
+
+LOC::~LOC()
+{
+}
+
+FGNavList * LOC::getNavaidList()
+{
+  return globals->get_loclist();
+}
+
+void LOC::search( double frequency, const SGGeod & aircraftPosition )
+{
+  NavRadioComponentWithIdent::search( frequency, aircraftPosition );
+  if( false == valid() ) {
+      _localizerWidth_deg = 0.0;
+      return;
+  }
+
+  // cache slightly expensive value, 
+  // sanitized in FGNavRecord::localizerWidth() to  never become zero
+  _localizerWidth_deg = _navRecord->localizerWidth();
+}
+
+/* Localizer coverage (ICAO Annex 10 Volume I 3.1.3.3 
+  25NM within +/-10 deg from the front course line
+  17NM between 10 and 35deg from the front course line
+  10NM outside of +/- 35deg  if coverage is provided
+  at and above a height of 2000ft above threshold or
+  1000ft above the highest point within intermediate
+  and final approach areas. Upper limit is a surface
+  extending outward from the localizer and inclined at
+  7 degrees above the horizontal
+ */
+double LOC::getRange_nm(const SGGeod & aircraftPosition)
+{
+  double elevationAngle = ::atan2(_heightAboveStation_ft*SG_FEET_TO_METER, _trackDistance_m)*SG_RADIANS_TO_DEGREES;
+  double azimuthAngle = SGMiscd::normalizePeriodic( -180.0, 180.0, _trueBearingFrom_deg + 180.0 - _navRecord->get_multiuse() );
+
+  // looks like our navrecord declared range is based on 10NM?
+  return  _navRecord->get_range() * _serviceVolume.adjustRange( azimuthAngle, elevationAngle );
+}
+
+double LOC::computeSignalQuality_norm( const SGGeod & aircraftPosition )
+{
+  return NavRadioComponentWithIdent::computeSignalQuality_norm( aircraftPosition );
+}
+
+void LOC::update( double dt, const SGGeod & aircraftPosition )
+{
+  NavRadioComponentWithIdent::update( dt, aircraftPosition );
+
+  if( false == valid() ) {
+    _localizerOffset_norm = 0.0;
+    return;
+  }
+
+  double offset = SGMiscd::normalizePeriodic( -180.0, 180.0, _trueBearingFrom_deg + 180.0 - _navRecord->get_multiuse() );
+
+  // The factor of 30.0 gives a period of 120 which gives us 3 cycles and six 
+  // zeros i.e. six courses: one front course, one back course, and four 
+  // false courses. Three of the six are reverse sensing.
+  offset = 30.0 * sawtooth(offset / 30.0);
+
+  // normalize offset to the localizer width, scale and clip to [-1..1]
+  offset = SGMiscd::clip( 2.0 * offset / _localizerWidth_deg, -1.0, 1.0 );
+  
+  _localizerOffset_norm = offset;
+}
+
+void LOC::display( NavIndicator & navIndicator )
+{
+  if( false == valid() ) 
+    return;
+
+  navIndicator.showTo( true );
+  navIndicator.showFrom( false );
+
+  navIndicator.setCDI( _localizerOffset_norm * _signalQuality_norm );
+  navIndicator.setSignalQuality( _signalQuality_norm );
+}
+
+class GS : public NavRadioComponent {
+public:
+  GS( SGPropertyNode_ptr rootNode);
+  virtual ~GS();
+  virtual void update( double dt, const SGGeod & aircraftPosition );
+  virtual void search( double frequency, const SGGeod & aircraftPosition );
+  virtual void display( NavIndicator & navIndicator );
+
+  virtual double getRange_nm(const SGGeod & aircraftPosition);
+protected:
+  virtual FGNavList * getNavaidList();
+
+private:
+  class ServiceVolume {
+  public:
+      ServiceVolume();
+      double adjustRange( double azimuthAngle_deg, double elevationAngle_deg );
+  private:
+      SGInterpTable _azimuthTable;
+      SGInterpTable _elevationTable;
+  } _serviceVolume;
+  static SGVec3d tangentVector(const SGGeod& midpoint, const double heading);
+
+  PropertyObject<double>  _targetGlideslope_deg;
+  PropertyObject<double>  _glideslopeOffset_norm;
+  SGVec3d _gsAxis;
+  SGVec3d _gsVertical;
+};
+
+GS::ServiceVolume::ServiceVolume()
+{
+// maybe this: http://www.tpub.com/content/aviation2/P-1244/P-12440125.htm
+  // ICAO Annex 10 - 3.1.5.2.2: The emission from the glide path equipment
+  // shall be horizontally polarized
+  // very rough abstraction of a 5-element yagi antenna's
+  // E-plane radiation diagram
+  _azimuthTable.addEntry(   0.0, 1.0 );
+  _azimuthTable.addEntry(  10.0, 1.0 );
+  _azimuthTable.addEntry(  30.0, 0.75 );
+  _azimuthTable.addEntry(  40.0, 0.50 );
+  _azimuthTable.addEntry(  50.0, 0.20 );
+  _azimuthTable.addEntry(  60.0, 0.10 );
+  _azimuthTable.addEntry(  70.0, 0.20 );
+  _azimuthTable.addEntry(  80.0, 0.10 );
+  _azimuthTable.addEntry(  90.0, 0.05 );
+  _azimuthTable.addEntry( 105.0, 0.10 );
+  _azimuthTable.addEntry( 130.0, 0.05 );
+  _azimuthTable.addEntry( 150.0, 0.30 );
+  _azimuthTable.addEntry( 160.0, 0.40 );
+  _azimuthTable.addEntry( 170.0, 0.50 );
+  _azimuthTable.addEntry( 180.0, 0.50 );
+
+  _elevationTable.addEntry(   0.0, 0.1 );
+  _elevationTable.addEntry(  1.05, 1.0 );
+  _elevationTable.addEntry(  7.00, 1.0 );
+  _elevationTable.addEntry(  45.0, 0.3 );
+  _elevationTable.addEntry(  90.0, 0.1 );
+  _elevationTable.addEntry( 180.0, 0.01 );
+}
+
+double GS::ServiceVolume::adjustRange( double azimuthAngle_deg, double elevationAngle_deg )
+{
+    return _azimuthTable.interpolate( fabs(azimuthAngle_deg) ) * 
+        _elevationTable.interpolate( fabs(elevationAngle_deg) );
+}
+
+GS::GS( SGPropertyNode_ptr rootNode) :
+  NavRadioComponent("gs", rootNode ),
+  _targetGlideslope_deg( rootNode->getNode(_name,true)->getNode("slope",true) ),
+  _glideslopeOffset_norm( rootNode->getNode(_name,true)->getNode("offset-norm",true) ),
+  _gsAxis(SGVec3d::zeros()),
+  _gsVertical(SGVec3d::zeros())
+{
+}
+
+GS::~GS()
+{
+}
+
+FGNavList * GS::getNavaidList()
+{
+  return globals->get_gslist();
+}
+
+double GS::getRange_nm(const SGGeod & aircraftPosition)
+{
+  double elevationAngle = ::atan2(_heightAboveStation_ft*SG_FEET_TO_METER, _trackDistance_m)*SG_RADIANS_TO_DEGREES;
+  double azimuthAngle = SGMiscd::normalizePeriodic( -180.0, 180.0, _trueBearingFrom_deg + 180.0 - fmod(_navRecord->get_multiuse(), 1000.0) );
+  return  _navRecord->get_range() * _serviceVolume.adjustRange( azimuthAngle, elevationAngle );
+}
+
+// Calculate a Cartesian unit vector in the
+// local horizontal plane, i.e. tangent to the 
+// surface of the earth at the local ground zero.
+// The tangent vector passes through the given  <midpoint> 
+// and points forward along the given <heading>.
+// The <heading> is given in degrees.
+SGVec3d GS::tangentVector(const SGGeod& midpoint, const double heading)
+{
+  // move 100m away from the midpoint - arbitrary number
+  const double delta(100.0);
+  SGGeod head, tail;
+  double az2;                   // ignored
+  SGGeodesy::direct(midpoint, heading,     delta, head, az2);
+  SGGeodesy::direct(midpoint, 180+heading, delta, tail, az2);
+  head.setElevationM(midpoint.getElevationM());
+  tail.setElevationM(midpoint.getElevationM());
+  SGVec3d head_xyz = SGVec3d::fromGeod(head);
+  SGVec3d tail_xyz = SGVec3d::fromGeod(tail);
+// Awkward formula here, needed because vector-by-scalar
+// multiplication is defined, but not vector-by-scalar division.
+  return (head_xyz - tail_xyz) * (0.5/delta);
+}
+
+void GS::search( double frequency, const SGGeod & aircraftPosition )
+{
+  NavRadioComponent::search( frequency, aircraftPosition );
+  if( false == valid() ) {
+      _gsAxis = SGVec3d::zeros();
+      _gsVertical = SGVec3d::zeros();
+      _targetGlideslope_deg = 3.0;
+      return;
+  }
+  
+  double gs_radial = SGMiscd::normalizePeriodic(0.0, 360.0, fmod(_navRecord->get_multiuse(), 1000.0) );
+
+  _gsAxis = tangentVector(_navRecord->geod(), gs_radial);
+  SGVec3d gsBaseline = tangentVector(_navRecord->geod(), gs_radial + 90.0);
+  _gsVertical = cross(gsBaseline, _gsAxis);
+
+  int tmp = (int)(_navRecord->get_multiuse() / 1000.0);
+  // catch unconfigured glideslopes here, they will cause nan later
+  _targetGlideslope_deg = SGMiscd::max( 1.0, (double)tmp / 100.0 );
+}
+
+void GS::update( double dt, const SGGeod & aircraftPosition )
+{
+  NavRadioComponent::update( dt, aircraftPosition );
+  if( false == valid() ) {
+      _glideslopeOffset_norm = 0.0;
+      return;
+  }
+  
+  SGVec3d pos = SGVec3d::fromGeod(aircraftPosition) - _navRecord->cart(); // relative vector from gs antenna to aircraft
+  // The positive GS axis points along the runway in the landing direction,
+  // toward the far end, not toward the approach area, so we need a - sign here:
+  double comp_h = -dot(pos, _gsAxis);      // component in horiz direction
+  double comp_v = dot(pos, _gsVertical);   // component in vertical direction
+  //double comp_b = dot(pos, _gsBaseline);   // component in baseline direction
+  //if (comp_b) {}                           // ... (useful for debugging)
+
+// _gsDirect represents the angle of elevation of the aircraft
+// as seen by the GS transmitter.
+  double gsDirect = atan2(comp_v, comp_h) * SGD_RADIANS_TO_DEGREES;
+// At this point, if the aircraft is centered on the glide slope,
+// _gsDirect will be a small positive number, e.g. 3.0 degrees
+
+// Aim the branch cut straight down 
+// into the ground below the GS transmitter:
+  if (gsDirect < -90.0) gsDirect += 360.0;
+
+  double offset = _targetGlideslope_deg - gsDirect;
+  if( offset < 0.0 )
+    offset = _targetGlideslope_deg/2 * sawtooth(2.0*offset/_targetGlideslope_deg);
+  assert( false == isnan(offset) );
+// GS is documented to be 1.4 degrees thick, 
+// i.e. plus or minus 0.7 degrees from the midline:
+  _glideslopeOffset_norm = SGMiscd::clip(offset/0.7, -1.0, 1.0);
+}
+
+void GS::display( NavIndicator & navIndicator )
+{
+  if( false == valid() ) {
+    navIndicator.setGS( false );
+    return;
+  }
+  navIndicator.setGS( true );
+  navIndicator.setGS( _glideslopeOffset_norm );
+}
+
+/* ------------- A NAV/COMM Frequency formatter ---------------------- */
+
+class FrequencyFormatter : public SGPropertyChangeListener {
+public:
+  FrequencyFormatter( SGPropertyNode_ptr freqNode, SGPropertyNode_ptr fmtFreqNode, double channelSpacing ) :
+    _freqNode( freqNode ),
+    _fmtFreqNode( fmtFreqNode ),
+    _channelSpacing(channelSpacing)
+  {
+    _freqNode->addChangeListener( this );
+    valueChanged(_freqNode);
+  }
+  ~FrequencyFormatter()
+  {
+    _freqNode->removeChangeListener( this );
+  }
+
+  void valueChanged (SGPropertyNode * prop)
+  {
+    // format as fixed decimal "nnn.nn"
+    ostringstream buf;
+    buf << std::fixed 
+        << std::setw(5) 
+        << std::setfill('0') 
+        << std::setprecision(2)
+        << getFrequency();
+    _fmtFreqNode->setStringValue( buf.str() );
+  }
+
+  double getFrequency() const 
+  {
+    double d = SGMiscd::roundToInt(_freqNode->getDoubleValue() / _channelSpacing) * _channelSpacing;
+    // strip last digit, do not round
+    return ((int)(d*100))/100.0;
+  }
+
+private:
+  SGPropertyNode_ptr _freqNode;
+  SGPropertyNode_ptr _fmtFreqNode;
+  double _channelSpacing;
+};
+
+
+/* ------------- The NavRadio implementation ---------------------- */
+
+class NavRadioImpl : public NavRadio {
+public:
+  NavRadioImpl( SGPropertyNode_ptr node );
+  virtual ~NavRadioImpl();
+
+  virtual void update( double dt );
+  virtual void init();
+private:
+  void search();
+
+  class Legacy {
+  public:
+      Legacy( NavRadioImpl * navRadioImpl ) : _navRadioImpl( navRadioImpl ) {}
+
+      void init();
+      void update( double dt );
+  private:
+      NavRadioImpl * _navRadioImpl;
+      SGPropertyNode_ptr is_valid_node;
+      SGPropertyNode_ptr nav_serviceable_node;
+  } _legacy;
+
+  const static int VOR_COMPONENT = 0;
+  const static int LOC_COMPONENT = 1;
+  const static int GS_COMPONENT  = 2;
+
+  std::string _name;
+  int         _num;
+  SGPropertyNode_ptr _rootNode;
+  FrequencyFormatter _useFrequencyFormatter;
+  FrequencyFormatter _stbyFrequencyFormatter;
+  std::vector<NavRadioComponent*> _components;
+  NavIndicator _navIndicator;
+  double _stationTTL;
+  double _frequency;
+  PropertyObject<bool> _cdiDisconnected;
+};
+
+NavRadioImpl::NavRadioImpl( SGPropertyNode_ptr node ) :
+  _legacy( this ),
+  _name(node->getStringValue("name", "nav")),
+  _num(node->getIntValue("number", 0)),
+  _rootNode(fgGetNode( string("/instrumentation/") + _name, _num, true)),
+  _useFrequencyFormatter( _rootNode->getNode("frequencies/selected-mhz",true), _rootNode->getNode("frequencies/selected-mhz-fmt",true), 0.05 ),
+  _stbyFrequencyFormatter( _rootNode->getNode("frequencies/standby-mhz",true), _rootNode->getNode("frequencies/standby-mhz-fmt",true), 0.05 ),
+  _navIndicator(_rootNode),
+  _stationTTL(0.0),
+  _frequency(-1.0),
+  _cdiDisconnected(_rootNode->getNode("cdi-disconnected",true))
+{
+}
+
+NavRadioImpl::~NavRadioImpl()
+{
+  BOOST_FOREACH( NavRadioComponent * p, _components ) {
+    delete p;
+  }
+}
+
+void NavRadioImpl::init()
+{
+  if( 0 < _components.size() )
+    return;
+
+  _components.push_back( new VOR(_rootNode) );
+  _components.push_back( new LOC(_rootNode) );
+  _components.push_back( new GS(_rootNode) );
+
+  _legacy.init();
+}
+
+void NavRadioImpl::search()
+{
+}
+
+void NavRadioImpl::update( double dt )
+{
+  if( dt < SGLimitsd::min() ) return;
+
+  SGGeod position;
+
+  try {
+    position = globals->get_aircraft_position();
+  }
+  catch( exception & ) {
+    return;
+  }
+
+  _stationTTL -= dt;
+  if( _frequency != _useFrequencyFormatter.getFrequency() ) {
+      _frequency = _useFrequencyFormatter.getFrequency();
+      _stationTTL = 0.0;
+  }
+
+  BOOST_FOREACH( NavRadioComponent * p, _components ) {
+      if( _stationTTL <= 0.0 )
+          p->search( _frequency, position );
+      p->update( dt, position );
+
+      if( false == _cdiDisconnected )
+          p->display( _navIndicator );
+  }
+
+  if( _stationTTL <= 0.0 )
+      _stationTTL = 30.0;
+
+  _legacy.init();
+}
+
+void NavRadioImpl::Legacy::init()
+{
+    is_valid_node = _navRadioImpl->_rootNode->getChild("data-is-valid", 0, true);
+    nav_serviceable_node = _navRadioImpl->_rootNode->getChild("serviceable", 0, true);
+
+}
+
+void NavRadioImpl::Legacy::update( double dt )
+{
+    is_valid_node->setBoolValue( 
+        _navRadioImpl->_components[VOR_COMPONENT]->valid() || _navRadioImpl->_components[LOC_COMPONENT]->valid()  
+        );
+}
+
+
+SGSubsystem * NavRadio::createInstance( SGPropertyNode_ptr rootNode )
+{
+    // use old navradio code by default
+    if( fgGetBool( "/instrumentation/use-new-navradio", false ) )
+        return new NavRadioImpl( rootNode );
+
+    return new FGNavRadio( rootNode );
+}
+
+} // namespace Instrumentation
+
diff --git a/src/Instrumentation/newnavradio.hxx b/src/Instrumentation/newnavradio.hxx
new file mode 100755
index 000000000..59654679d
--- /dev/null
+++ b/src/Instrumentation/newnavradio.hxx
@@ -0,0 +1,18 @@
+
+
+#ifndef _FG_INSTRUMENTATION_NAVRADIO_HXX
+#define _FG_INSTRUMENTATION_NAVRADIO_HXX
+
+#include <simgear/props/props.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+namespace Instrumentation {
+class NavRadio : public SGSubsystem
+{
+public:
+  static SGSubsystem * createInstance( SGPropertyNode_ptr rootNode );
+};
+
+}
+
+#endif // _FG_INSTRUMENTATION_NAVRADIO_HXX

From a9ac75b9c9ec473a97ae74d45ee938cd9d8e31d6 Mon Sep 17 00:00:00 2001
From: Durk Talsma <durktals@gmail.com>
Date: Wed, 5 Oct 2011 21:40:47 +0200
Subject: [PATCH 85/85] Revert back to the version from sept 4. Vertical speed
 calculations of decending AI aircraft were messed up.

---
 src/AIModel/AIAircraft.cxx | 56 ++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 33 deletions(-)

diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
index 98d2782f5..3791585ec 100644
--- a/src/AIModel/AIAircraft.cxx
+++ b/src/AIModel/AIAircraft.cxx
@@ -1,4 +1,4 @@
-// FGAIAircraft - FGAIBase-derived class creates an AI airplane
+// // FGAIAircraft - FGAIBase-derived class creates an AI airplane
 //
 // Written by David Culp, started October 2003.
 //
@@ -48,8 +48,6 @@ using std::string;
 #include "performancedata.hxx"
 #include "performancedb.hxx"
 
-
-#define TGT_VS_CUTOFF 10000
 //#include <Airports/trafficcontroller.hxx>
 
 static string tempReg;
@@ -157,7 +155,6 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
 
 
  void FGAIAircraft::Run(double dt) {
-      
       FGAIAircraft::dt = dt;
     
      bool outOfSight = false, 
@@ -358,14 +355,9 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
             tgt_altitude_ft = prev->getAltitude();
             if (curr->getCrossat() > -1000.0) {
                 use_perf_vs = false;
-//                 tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
-//                          / 6076.0 / speed*60.0);
-//                 if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN << ". Corresponding to " << (tgt_vs * .005) << "degrees of pitch angle" << prev->getName()); };
-//                 if (tgt_vs < -1500)
-//                     tgt_vs = -1500;
-//                 if (tgt_vs > 1500) 
-//                     tgt_vs = 1500;
-//                 checkTcas();
+                tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
+                         / 6076.0 / speed*60.0);
+                checkTcas();
                 tgt_altitude_ft = curr->getCrossat();
             } else {
                 use_perf_vs = true;
@@ -505,7 +497,6 @@ void FGAIAircraft::getGroundElev(double dt) {
 
 
 void FGAIAircraft::doGroundAltitude() {
-
     if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
         (isStationary()))
         altitude_ft = (tgt_altitude_ft + groundOffset);
@@ -685,11 +676,10 @@ void FGAIAircraft::handleFirstWaypoint() {
     if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
     {
         use_perf_vs = false;
-/*        tgt_vs = (curr->getCrossat() - prev->getAltitude())
+        tgt_vs = (curr->getCrossat() - prev->getAltitude())
                  / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
                     / 6076.0 / prev->getSpeed()*60.0);
-        if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN); };
-        checkTcas();*/
+        checkTcas();
         tgt_altitude_ft = curr->getCrossat();
     } else {
         use_perf_vs = true;
@@ -773,10 +763,10 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
     } 
     if (trafficRef) {
          //cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
-         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+/*         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
               cerr << trafficRef->getCallSign() << " " << tgt_altitude_ft << " " << _getSpeed() << " " 
-                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->getName() << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << " " << invisible << endl; 
-         }
+                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl; 
+         }*/
      }
     if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
         minBearing = 360;
@@ -1223,20 +1213,20 @@ bool FGAIAircraft::reachedEndOfCruise(double &distance) {
         double distanceCovered   = descentSpeed * descentTimeNeeded; 
 
         //cerr << "Tracking  : " << fgGetString("/ai/track-callsign");
-//         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-//             cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
-//             cerr << "Descent rate      : " << descentRate << endl;
-//             cerr << "Descent speed     : " << descentSpeed << endl;
-//             cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
-//             cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
-//             cerr << "DistanceCovered   : " << distanceCovered   << endl;
-//         }
+        if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+            cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
+            cerr << "Descent rate      : " << descentRate << endl;
+            cerr << "Descent speed     : " << descentSpeed << endl;
+            cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
+            cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
+            cerr << "DistanceCovered   : " << distanceCovered   << endl;
+        }
         //cerr << "Distance = " << distance << endl;
         distance = distanceCovered;
         if (dist < distanceCovered) {
-//               if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-//                    //exit(1);
-//               }
+              if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+                   //exit(1);
+              }
               return true;
         } else {
               return false;
@@ -1290,8 +1280,8 @@ time_t FGAIAircraft::checkForArrivalTime(string wptName) {
      
      time_t ete = tracklength / ((speed * SG_NM_TO_METER) / 3600.0); 
      time_t secondsToGo = arrivalTime - now;
-//      if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
-//           cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
-//      }
+     if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
+          cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
+     }
      return (ete - secondsToGo); // Positive when we're too slow...
 }