fixed flakey functionality of booleans
diff --git a/source/1.0/doc/CHANGES-1.0.txt b/source/1.0/doc/CHANGES-1.0.txt
index 0ec3471..60e8040 100644
--- a/source/1.0/doc/CHANGES-1.0.txt
+++ b/source/1.0/doc/CHANGES-1.0.txt
@@ -4,8 +4,11 @@
 Changes with 1.0.4
 ------------------
 
-Fixed usage of ``expn`` under FreeBSD 7.2 (FreeNAS 0.7.1) that was causing many
-unit tests to fail.
+Fixed issue #10. Usage of ``expn`` under FreeBSD 7.2 (FreeNAS 0.7.1) and FreeBSD
+8.0 that was causing many unit tests to fail.
+
+Fixed issue where booleans were sometimes mis-configured to require additional
+values like other flags.
 
 
 Changes with 1.0.3
diff --git a/source/1.0/doc/RELEASE_NOTES-1.0.4.txt b/source/1.0/doc/RELEASE_NOTES-1.0.4.txt
new file mode 100644
index 0000000..06cca0d
--- /dev/null
+++ b/source/1.0/doc/RELEASE_NOTES-1.0.4.txt
@@ -0,0 +1,81 @@
+------------------------------
+shFlags.sh 1.0.4 Release Notes
+------------------------------
+
+Preface
+=======
+Copyright 2008-2009 Kate Ward. All Rights Reserved.
+Released under the LGPL (GNU Lesser General Public License)
+Author: kate.ward@forestent.com (Kate Ward)
+
+This document covers any known issues and workarounds for the stated release of
+shFlags.
+
+Release info
+============
+
+This is a minor bug fix release.
+
+Please see the CHANGES-1.0.txt file for a complete list of changes.
+
+Major changes
+-------------
+
+Obsolete items
+--------------
+
+Bug fixes
+---------
+
+Issue #10 - Changed the internal usage of the ``expn`` command to fix issues
+under FreeBSD.
+
+General info
+============
+
+The unit tests
+--------------
+
+shFlags is designed to work on as many environments as possible, but not all
+environments are created equal. As such, not all of the unit tests will succeed
+on every platform. The unit tests are therefore designed to fail, indicating to
+the tester that the supported functionality is not present, but an additional
+test is present to verify that shFlags properly caught the limitation and
+presented the user with an appropriate error message.
+
+shFlags tries to support both the standard and enhanced versions of ``getopt``.
+As each responds differently, and not everything is supported on the standard
+version, some unit tests will be skipped (i.e. ASSERTS will not be thrown) when
+the standard version of ``getopt`` is detected. The reason being that there is
+no point testing for functionality that is positively known not to exist. A
+tally of skipped tests will be kept for later reference.
+
+Standard vs Enhanced getopt
+---------------------------
+
+Here is a matrix of the supported features of the various **getopt** variants.
+
++=========================================+=====+=====+
+| Feature                                 | std | enh |
++-----------------------------------------+-----+-----+
+| short option names                      |  Y  |  Y  |
+| long option names                       |  N  |  Y  |
+| spaces in string options                |  N  |  Y  |
+| intermixing of flag and non-flag values |  N  |  Y  |
++=========================================+=====+=====+
+
+Known Issues
+------------
+
+The **getopt** version provided by default with all versions of Mac OS X (up to
+and including 10.5.6) and Solaris (up to and including Solaris 10 and
+OpenSolaris) is the standard version.
+
+Workarounds
+-----------
+
+The Zsh shell requires the ``shwordsplit`` option to be set and the special
+``FLAGS_PARENT`` variable must be defined. See ``src/shflags_test_helpers`` to
+see how the unit tests do this.
+
+.. vim:fileencoding=latin1:ft=rst:spell:tw=80
diff --git a/source/1.0/src/shflags b/source/1.0/src/shflags
index aaea760..0d0f9de 100644
--- a/source/1.0/src/shflags
+++ b/source/1.0/src/shflags
@@ -86,7 +86,7 @@
 FLAGS_ERROR=2
 
 # reserved flag names
-FLAGS_RESERVED='ARGC ARGV ERROR FALSE HELP PARENT RESERVED TRUE VERSION'
+FLAGS_RESERVED_LIST=' ARGC ARGV ERROR FALSE HELP PARENT RESERVED TRUE VERSION '
 
 _flags_debug() { echo "flags:DEBUG $@" >&2; }
 _flags_warn() { echo "flags:WARN $@" >&2; }
@@ -229,8 +229,8 @@
   # TODO(kward): check for validity of the flag name (e.g. dashes)
 
   # check whether the flag name is reserved
-  echo " ${FLAGS_RESERVED} " |grep " ${_flags_name_} " >/dev/null
-  if [ $? -eq 0 ]; then
+  _flags_itemInList ${_flags_name_} "${FLAGS_RESERVED_LIST}"
+  if [ $? -eq ${FLAGS_TRUE} ]; then
     flags_error="flag name (${_flags_name_}) is reserved"
     _flags_return_=${FLAGS_ERROR}
   fi
@@ -352,6 +352,8 @@
 
   for _flags_flag_ in ${__flags_longNames}; do
     _flags_type_=`_flags_getFlagInfo ${_flags_flag_} ${__FLAGS_INFO_TYPE}`
+    [ $? -eq ${FLAGS_TRUE} ] || \
+        ( _flags_fatal 'call to _flags_type_ failed'; return ${FLAGS_ERROR} )
     case ${_flags_optStrType_} in
       ${__FLAGS_OPTSTR_SHORT})
         _flags_shortName_=`_flags_getFlagInfo \
@@ -394,9 +396,9 @@
   _flags_info_=$2
 
   _flags_nameVar_="__flags_${_flags_name_}_${_flags_info_}"
-  _flags_strToEval_="_flags_value_=\"\${${_flags_nameVar_}:-}\""
+  _flags_strToEval_="_flags_nameValue_=\"\${${_flags_nameVar_}:-}\""
   eval "${_flags_strToEval_}"
-  if [ -n "${_flags_value_}" ]; then
+  if [ -n "${_flags_nameValue_}" ]; then
     flags_return=${FLAGS_TRUE}
   else
     # see if the _flags_name_ variable is a string as strings can be empty...
@@ -407,9 +409,9 @@
     # try to find the _type variable of the _type variable, and so on. Not so
     # good ;-)
     _flags_typeVar_="__flags_${_flags_name_}_${__FLAGS_INFO_TYPE}"
-    _flags_strToEval_="_flags_type_=\"\${${_flags_typeVar_}:-}\""
+    _flags_strToEval_="_flags_typeValue_=\"\${${_flags_typeVar_}:-}\""
     eval "${_flags_strToEval_}"
-    if [ "${_flags_type_}" = "${__FLAGS_TYPE_STRING}" ]; then
+    if [ "${_flags_typeValue_}" = "${__FLAGS_TYPE_STRING}" ]; then
       flags_return=${FLAGS_TRUE}
     else
       flags_return=${FLAGS_ERROR}
@@ -417,9 +419,9 @@
     fi
   fi
 
-  echo "${_flags_value_}"
-  unset _flags_info_ _flags_name_ _flags_strToEval_ _flags_type_ _flags_value_ \
-      _flags_nameVar_ _flags_typeVar_
+  echo "${_flags_nameValue_}"
+  unset _flags_info_ _flags_name_ _flags_nameValue_ _flags_nameVar_ \
+      _flags_strToEval_ _flags_typeValue_ _flags_typeVar_
   [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}"
   return ${flags_return}
 }
diff --git a/source/1.0/src/shflags_test_private.sh b/source/1.0/src/shflags_test_private.sh
index f145593..6f15bb8 100755
--- a/source/1.0/src/shflags_test_private.sh
+++ b/source/1.0/src/shflags_test_private.sh
@@ -16,6 +16,47 @@
 # suite tests
 #
 
+testColumns()
+{
+  cols=`_flags_columns`
+  value=`expr "${cols}" : '\([0-9]*\)'`
+  assertNotNull "unexpected screen width (${cols})" "${value}"
+}
+
+testGenOptStr()
+{
+  _testGenOptStr '' ''
+
+  DEFINE_boolean bool false 'boolean value' b
+  _testGenOptStr 'b' 'bool'
+
+  DEFINE_float float 0.0 'float value' f
+  _testGenOptStr 'bf:' 'bool,float:'
+
+  DEFINE_integer int 0 'integer value' i
+  _testGenOptStr 'bf:i:' 'bool,float:,int:'
+
+  DEFINE_string str 0 'string value' s
+  _testGenOptStr 'bf:i:s:' 'bool,float:,int:,str:'
+
+  DEFINE_boolean help false 'show help' h
+  _testGenOptStr 'bf:i:s:h' 'bool,float:,int:,str:,help'
+}
+
+_testGenOptStr()
+{
+  short=$1
+  long=$2
+
+  result=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
+  assertTrue 'short option string generation failed' $?
+  assertEquals "${short}" "${result}"
+
+  result=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}`
+  assertTrue 'long option string generation failed' $?
+  assertEquals "${long}" "${result}"
+}
+
 testGetFlagInfo()
 {
   __flags_blah_foobar='1234'
@@ -52,13 +93,6 @@
   assertFalse 'empty lists should not match' $?
 }
 
-testColumns()
-{
-  cols=`_flags_columns`
-  value=`expr "${cols}" : '\([0-9]*\)'`
-  assertNotNull "unexpected screen width (${cols})" "${value}"
-}
-
 testValidateBoolean()
 {
   # valid values