diff --git a/.compat-gcc-32.metadata b/.compat-gcc-32.metadata
new file mode 100644
index 0000000..72c60aa
--- /dev/null
+++ b/.compat-gcc-32.metadata
@@ -0,0 +1,2 @@
+a84db98823c0ba09ce58bfef3b7b4d29face6b6b SOURCES/gcc-3.2.3-20040701.tar.bz2
+dc1cf5b69b132ba4995adf4427196d77dea11d30 SOURCES/libstdc++-3.3.4-20040818.tar.bz2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1e7354d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+SOURCES/gcc-3.2.3-20040701.tar.bz2
+SOURCES/libstdc++-3.3.4-20040818.tar.bz2
diff --git a/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch b/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch
new file mode 100644
index 0000000..9726836
--- /dev/null
+++ b/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch
@@ -0,0 +1,60 @@
+2004-10-28  Paolo Carlini  <pcarlini@suse.de>
+
+	PR libstdc++/16612
+	* include/bits/basic_string.h (basic_string()): When
+	_GLIBCXX_FULLY_DYNAMIC_STRING is defined, don't deal with _S_empty_rep.
+	* include/bits/basic_string.tcc (_S_construct): Likewise.
+
+--- libstdc++33-v3/include/bits/basic_string.tcc.jj	2002-11-09 18:42:55.000000000 +0100
++++ libstdc++33-v3/include/bits/basic_string.tcc	2004-11-12 14:17:19.946131774 +0100
+@@ -77,8 +77,10 @@ namespace std
+       _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
+ 		   input_iterator_tag)
+       {
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refcopy();
++#endif
+ 	// Avoid reallocation for common case.
+ 	_CharT __buf[100];
+ 	size_type __i = 0;
+@@ -137,11 +139,13 @@ namespace std
+       _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 
+ 		   forward_iterator_tag)
+       {
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refcopy();
++#endif
+ 
+ 	// NB: Not required, but considered best practice.
+-	if (__builtin_expect(__beg == _InIter(), 0))
++	if (__builtin_expect(__beg == _InIter() && __beg != __end, 0))
+ 	  __throw_logic_error("attempt to create string with null pointer");
+ 
+ 	size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
+@@ -166,8 +170,10 @@ namespace std
+     basic_string<_CharT, _Traits, _Alloc>::
+     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
+     {
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+       if (__n == 0 && __a == _Alloc())
+ 	return _S_empty_rep()._M_refcopy();
++#endif
+ 
+       // Check for out_of_range and length_error exceptions.
+       _Rep* __r = _Rep::_S_create(__n, __a);
+--- libstdc++33-v3/include/bits/basic_string.h.jj	2002-05-22 15:39:29.000000000 +0200
++++ libstdc++33-v3/include/bits/basic_string.h	2004-11-12 14:14:42.831975711 +0100
+@@ -923,7 +923,11 @@ namespace std
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     inline basic_string<_CharT, _Traits, _Alloc>::
+     basic_string()
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
++#else
++    : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
++#endif
+ 
+   // operator+
+   template<typename _CharT, typename _Traits, typename _Alloc>
diff --git a/SOURCES/compat-libstdc++33++-symver2.patch b/SOURCES/compat-libstdc++33++-symver2.patch
new file mode 100644
index 0000000..e625dee
--- /dev/null
+++ b/SOURCES/compat-libstdc++33++-symver2.patch
@@ -0,0 +1,36 @@
+2005-05-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* src/globals.cc (_GLIBCPP_ASM_SYMVER): For non-PIC, redefine to a
+	hidden alias.
+	* src/locale.cc (_GLIBCPP_ASM_SYMVER): Likewise.
+
+--- libstdc++33-v3/src/globals.cc.jj	2002-10-23 01:24:11.000000000 +0200
++++ libstdc++33-v3/src/globals.cc	2005-05-13 12:30:26.000000000 +0200
+@@ -33,6 +33,12 @@
+ #include <locale>
+ #include <ext/stdio_filebuf.h>
+ 
++#ifndef PIC
++# undef _GLIBCPP_ASM_SYMVER
++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \
++  asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur);
++#endif
++
+ // On AIX, and perhaps other systems, library initialization order is
+ // not guaranteed.  For example, the static initializers for the main
+ // program might run before the static initializers for this library.
+--- libstdc++33-v3/src/locale.cc.jj	2003-01-17 18:44:45.000000000 +0100
++++ libstdc++33-v3/src/locale.cc	2005-05-13 13:02:36.000000000 +0200
+@@ -34,6 +34,12 @@
+ #include <locale>
+ #include <bits/atomicity.h>
+ 
++#ifndef PIC
++# undef _GLIBCPP_ASM_SYMVER
++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \
++  asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur);
++#endif
++
+ namespace __gnu_cxx
+ {
+   // Defined in globals.cc.
diff --git a/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch b/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch
new file mode 100644
index 0000000..0689886
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch
@@ -0,0 +1,49 @@
+2005-02-15  Jakub Jelinek  <jakub@redhat.com>
+
+	PR libstdc++/19946
+	* testsuite/demangle/abi_examples/01.cc (main): Adjust for 2005-02-13
+	demangler change.
+	* testsuite/demangle/abi_examples/02.cc (main): Likewise.
+
+--- libstdc++33-v3/testsuite/demangle/abi_examples/01.cc.jj	2004-03-09 16:09:24.000000000 +0100
++++ libstdc++33-v3/testsuite/demangle/abi_examples/01.cc	2005-02-14 09:05:09.383834357 +0100
+@@ -1,6 +1,6 @@
+ // 2003-02-26 Benjamin Kosnik <bkoz@redhat.com>
+ 
+-// Copyright (C) 2003 Free Software Foundation, Inc.
++// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+@@ -31,7 +31,9 @@ int main()
+   // extern "C" function 
+   // extern "C" float f(void) { };
+   // T f
+-  verify_demangle("f", "error code = -2: invalid mangled name");
++  // f is ambiguous between "C" external name and internal built-in type
++  // name.  The ambiguity is resolved to the built-in type name.
++  verify_demangle("f", "float");
+ 
+   return 0;
+ }
+--- libstdc++33-v3/testsuite/demangle/abi_examples/02.cc.jj	2004-03-09 16:09:24.000000000 +0100
++++ libstdc++33-v3/testsuite/demangle/abi_examples/02.cc	2005-02-14 09:05:59.661857808 +0100
+@@ -1,6 +1,6 @@
+ // 2003-02-26 Benjamin Kosnik <bkoz@redhat.com>
+ 
+-// Copyright (C) 2003 Free Software Foundation, Inc.
++// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+@@ -31,7 +31,9 @@ int main()
+   // or variable "f" 
+   // int f;
+   // B f
+-  verify_demangle("f", "error code = -2: invalid mangled name");
++  // f is ambiguous between variable external name and internal built-in type
++  // name.  The ambiguity is resolved to the built-in type name.
++  verify_demangle("f", "float");
+ 
+   return 0;
+ }
diff --git a/SOURCES/compat-libstdc++33-incdir.patch b/SOURCES/compat-libstdc++33-incdir.patch
new file mode 100644
index 0000000..b64d8c5
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-incdir.patch
@@ -0,0 +1,33 @@
+--- libstdc++33-v3/aclocal.m4.jj	2004-06-24 12:06:53.000000000 -0400
++++ libstdc++33-v3/aclocal.m4	2004-10-14 12:58:50.000000000 -0400
+@@ -1956,7 +1956,7 @@ AC_MSG_RESULT($version_specific_libs)
+ 
+ # Default case for install directory for include files.
+ if test $version_specific_libs = no && test $gxx_include_dir = no; then
+-  gxx_include_dir='$(prefix)'/include/c++/${gcc_version}
++  gxx_include_dir='$(prefix)'/include/c++/3.3.4
+ fi
+ 
+ # Version-specific runtime libs processing.
+--- libstdc++33-v3/acinclude.m4.jj	2004-06-24 12:06:53.000000000 -0400
++++ libstdc++33-v3/acinclude.m4	2004-10-14 12:59:32.000000000 -0400
+@@ -1944,7 +1944,7 @@ AC_MSG_RESULT($version_specific_libs)
+ 
+ # Default case for install directory for include files.
+ if test $version_specific_libs = no && test $gxx_include_dir = no; then
+-  gxx_include_dir='$(prefix)'/include/c++/${gcc_version}
++  gxx_include_dir='$(prefix)'/include/c++/3.3.4
+ fi
+ 
+ # Version-specific runtime libs processing.
+--- libstdc++33-v3/configure.jj	2004-10-14 12:35:55.000000000 -0400
++++ libstdc++33-v3/configure	2004-10-14 13:00:05.000000000 -0400
+@@ -24109,7 +24109,7 @@ echo "$ac_t""$version_specific_libs" 1>&
+ 
+ # Default case for install directory for include files.
+ if test $version_specific_libs = no && test $gxx_include_dir = no; then
+-  gxx_include_dir='$(prefix)'/include/c++/${gcc_version}
++  gxx_include_dir='$(prefix)'/include/c++/3.3.4
+ fi
+ 
+ # Version-specific runtime libs processing.
diff --git a/SOURCES/compat-libstdc++33-ldbl.patch b/SOURCES/compat-libstdc++33-ldbl.patch
new file mode 100644
index 0000000..3ed79c0
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-ldbl.patch
@@ -0,0 +1,45 @@
+--- libstdc++33-v3/libmath/stubs.c.jj	2003-06-03 08:48:02.000000000 -0400
++++ libstdc++33-v3/libmath/stubs.c	2006-08-21 09:18:10.000000000 -0400
+@@ -27,9 +27,29 @@
+    invalidate any other reasons why the executable file might be covered by
+    the GNU General Public License.  */
+ 
++#if defined __s390__ || defined __powerpc__
++/* Lie.  */
++#define __LONG_DOUBLE_128__ 1
++#endif
++
+ #include <math.h>
+ #include "config.h"
+ 
++#if defined __s390__ || defined __powerpc__
++#undef HAVE_ATAN2L
++#undef HAVE_COSHL
++#undef HAVE_COSL
++#undef HAVE_EXPL
++#undef HAVE_LOG10L
++#undef HAVE_LOGL
++#undef HAVE_POWL
++#undef HAVE_SINHL
++#undef HAVE_SINL
++#undef HAVE_SQRTL
++#undef HAVE_TANHL
++#undef HAVE_TANL
++#endif
++
+ /* For targets which do not have support for long double versions,
+    we use the crude approximation.  We'll do better later.  */
+ 
+@@ -137,6 +157,12 @@ hypotl(long double x, long double y)
+   x /= s; y /= s;
+   return s * sqrtl(x * x + y * y);
+ }
++#elif (defined __s390__ || defined __powerpc__) && defined HAVE_HYPOT
++long double
++hypotl(long double x, long double y)
++{
++  return hypot((double) x, (double) y);
++}
+ #endif
+ 
+ 
diff --git a/SOURCES/compat-libstdc++33-limits.patch b/SOURCES/compat-libstdc++33-limits.patch
new file mode 100644
index 0000000..4803a55
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-limits.patch
@@ -0,0 +1,2715 @@
+2004-10-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* include/std/std_limits.h: For GCC 3.2.x and earlier include
+	GCC 3.2.3 std_limits.h.
+
+	Revert:
+	2002-09-25  Benjamin Kosnik  <bkoz@redhat.com>
+
+        * include/Makefile.am (target_headers): Remove cpu_limits.h.
+        * include/Makefile.in: Regenerate.
+        * configure.in (CPU_LIMITS_INC_SRCDIR): Remove
+        * configure: Regenerate.
+        * configure.target (CPULIMITS): Remove.
+
+        * config/os/solaris/solaris2.7/os_defines.h (__glibcpp_long_bits):
+        Remove.
+        * config/os/irix/irix6.5/os_defines.h
+        (__glibcpp_long_double_bits): Remove.
+        (__glibcpp_wchar_t_bits): Remove.
+        (__glibcpp_long_bits): Remove.
+        * config/os/irix/irix5.2/os_defines.h
+        (__glibcpp_long_double_bits): Remove.
+        (__glibcpp_long_bits): Remove.
+        * config/os/hpux/os_defines.h (__glibcpp_wchar_t_is_signed): Remove.
+        * config/os/bsd/freebsd/os_defines.h:
+        (__glibcpp_long_double_bits): Remove.
+        * config/os/aix/os_defines.h (__glibcpp_wchar_t_bits): Remove.
+        (__glibcpp_wchar_t_is_signed): Remove.
+        (__glibcpp_long_bits): Remove.
+        * config/os/gnu-linux/os_defines.h (__glibcpp_long_bits): Remove.
+        (__glibcpp_long_double_bits): Remove.
+
+        * config/os/osf/osf5.0/cpu_limits.h: Remove.
+        * config/cpu/alpha/cpu_limits.h: Remove.
+        * config/cpu/arm/cpu_limits.h: Remove.
+        * config/cpu/cris/cpu_limits.h: Remove.
+        * config/cpu/generic/cpu_limits.h: Remove.
+        * config/cpu/generic/limits.h: Remove.
+        * config/cpu/ia64/cpu_limits.h: Remove.
+        * config/cpu/m68k/cpu_limits.h: Remove.
+        * config/cpu/mmix/cpu_limits.h: Remove.
+        * config/cpu/powerpc/cpu_limits.h: Remove.
+        * config/cpu/S390/cpu_limits.h: Remove.
+
+--- libstdc++33-v3/libmath/Makefile.in.jj	2003-03-17 14:07:39.000000000 -0500
++++ libstdc++33-v3/libmath/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/libsupc++/Makefile.in.jj	2004-06-28 18:29:56.000000000 -0400
++++ libstdc++33-v3/libsupc++/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -82,6 +82,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/src/Makefile.in.jj	2004-01-20 06:36:07.000000000 -0500
++++ libstdc++33-v3/src/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -82,6 +82,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/config/os/bsd/freebsd/os_defines.h.jj	2003-05-15 18:08:04.000000000 -0400
++++ libstdc++33-v3/config/os/bsd/freebsd/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -41,4 +41,6 @@
+ #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1
+ #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE
+ 
++#define __glibcpp_long_double_bits __glibcpp_double_bits
++
+ #endif
+--- libstdc++33-v3/config/os/aix/os_defines.h.jj	2002-09-26 01:25:10.000000000 -0400
++++ libstdc++33-v3/config/os/aix/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -55,4 +55,13 @@
+ #undef _G_USING_THUNKS
+ #define _G_USING_THUNKS 0
+ 
++#if !defined(_AIX51) || !defined(__64BIT__)
++#define __glibcpp_wchar_t_bits 16
++#define __glibcpp_wchar_t_is_signed false
++#endif
++
++#ifdef __64BIT__
++#define __glibcpp_long_bits 64
++#endif
++
+ #endif
+--- libstdc++33-v3/config/os/gnu-linux/os_defines.h.jj	2002-09-26 01:25:10.000000000 -0400
++++ libstdc++33-v3/config/os/gnu-linux/os_defines.h	2004-10-14 12:52:11.000000000 -0400
+@@ -65,4 +65,95 @@ typedef __loff_t __off64_t;
+ #define __NO_STRING_INLINES
+ #endif
+ 
++#if (defined(__hppa__) && defined(__LP64__)) || defined(__powerpc64__) || defined(__s390x__) || (defined(__sparc__) && defined(__arch64__))
++#define __glibcpp_long_bits 64
++#endif
++
++#if defined(__hppa__) || (defined(__sparc__) && !defined(__arch64__))
++#define __glibcpp_long_double_bits 64
++#endif
++
++/* RHEL3 hack.  */
++#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__IBMCPP__) \
++    && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__) \
++	|| defined(__s390__) || defined(__s390x__) || defined(__powerpc__) \
++	|| defined(__powerpc64__))
++#define __glibcpp_float_has_quiet_NaN true
++#define __glibcpp_float_has_signaling_NaN true
++#define __glibcpp_float_has_denorm denorm_present
++#define __glibcpp_float_has_infinity true
++#define __glibcpp_float_round_style round_to_nearest
++#define __glibcpp_float_is_iec559 true
++#define __glibcpp_double_has_quiet_NaN true
++#define __glibcpp_double_has_signaling_NaN true
++#define __glibcpp_double_has_denorm denorm_present
++#define __glibcpp_double_has_infinity true
++#define __glibcpp_double_round_style round_to_nearest
++#define __glibcpp_double_is_iec559 true
++#define __glibcpp_long_double_has_quiet_NaN true
++#define __glibcpp_long_double_has_signaling_NaN true
++#define __glibcpp_long_double_has_denorm denorm_present
++#define __glibcpp_long_double_has_infinity true
++#define __glibcpp_long_double_round_style round_to_nearest
++#define __glibcpp_long_double_is_iec559 true
++
++#define __glibcpp_f32_round_error 0.5F
++#define __glibcpp_f64_round_error 0.5
++#define __glibcpp_f80_round_error 0.5L
++#define __glibcpp_f96_round_error 0.5L
++#define __glibcpp_f128_round_error 0.5L
++
++#define __glibcpp_float_infinity 1.0e+40F
++#define __glibcpp_double_infinity 1.0e+320
++#define __glibcpp_long_double_infinity 1.0e+5000L
++
++#define __glibcpp_float_denorm_min 1.40129846e-45F
++#define __glibcpp_double_denorm_min 4.9406564584124654e-324
++
++#define __glibcpp_float_quiet_NaN \
++  (__extension__ ((union { unsigned int __l; float __d; })		\
++		  { __l: 0x7fc00000 }).__d)
++#define __glibcpp_double_quiet_NaN \
++  (__extension__ ((union { unsigned long long __l; double __d; })	\
++		  { __l: 0x7ff8000000000000ULL }).__d)
++
++#define __glibcpp_float_signaling_NaN \
++  (__extension__ ({ union { unsigned int __l; float __d; } __u;		\
++		    __u.__l = 0x7fa00000;				\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++#define __glibcpp_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l; double __d; } __u;	\
++		    __u.__l = 0x7ff4000000000000ULL;			\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#if __glibcpp_long_double_bits == 80
++
++#define __glibcpp_long_double_denorm_min 3.64519953188247460253e-4951L
++#define __glibcpp_long_double_quiet_NaN \
++  (__extension__ ({ union { unsigned long long __l[2];			\
++			    long double __d; } __u;			\
++		    __u.__l[0] = 0xcULL << 60; __u.__l[1] = 0x7fff;	\
++		    __u.__d; }))
++#define __glibcpp_long_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l[2];			\
++			    long double __d; } __u;			\
++		    __u.__l[0] = 0xaULL << 60; __u.__l[1] = 0x7fff;	\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#else
++
++#define __glibcpp_long_double_denorm_min 4.9406564584124654e-324L
++#define __glibcpp_long_double_quiet_NaN \
++  (__extension__ ((union { unsigned long long __l; long double __d; })	\
++		  { __l: 0x7ff8000000000000ULL }).__d)
++#define __glibcpp_long_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l;			\
++			    long double __d; } __u;			\
++		     __u.__l = 0x7ff4000000000000ULL;			\
++		     __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#endif
++
++#endif
++
+ #endif
+--- libstdc++33-v3/config/os/hpux/os_defines.h.jj	2003-09-04 08:39:34.000000000 -0400
++++ libstdc++33-v3/config/os/hpux/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -37,6 +37,8 @@
+ #define __off64_t off64_t
+ #define __ssize_t ssize_t
+ 
++#define __glibcpp_wchar_t_is_signed false
++
+ // Use macro form of ctype functions to ensure __SB_masks is defined.
+ #define _SB_CTYPE_MACROS 1
+ 
+--- libstdc++33-v3/config/os/irix/irix5.2/os_defines.h.jj	2002-09-26 01:25:11.000000000 -0400
++++ libstdc++33-v3/config/os/irix/irix5.2/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -51,5 +51,11 @@
+ // GCC does not use thunks on IRIX. 
+ #define _G_USING_THUNKS 0
+ 
++#define __glibcpp_long_double_bits 64
++
++#if __LONG_MAX__ > 2147483647
++#define __glibcpp_long_bits 64
++#endif
++
+ #endif
+ 
+--- libstdc++33-v3/config/os/irix/irix6.5/os_defines.h.jj	2002-09-26 01:25:11.000000000 -0400
++++ libstdc++33-v3/config/os/irix/irix6.5/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -51,5 +51,12 @@
+ // GCC does not use thunks on IRIX. 
+ #define _G_USING_THUNKS 0
+ 
++#define __glibcpp_long_double_bits 64
++
++#if __LONG_MAX__ > 2147483647
++#define __glibcpp_wchar_t_bits 64
++#define __glibcpp_long_bits 64
++#endif
++
+ #endif
+ 
+--- libstdc++33-v3/config/os/solaris/solaris2.7/os_defines.h.jj	2002-09-26 01:25:11.000000000 -0400
++++ libstdc++33-v3/config/os/solaris/solaris2.7/os_defines.h	2004-10-14 12:28:01.000000000 -0400
+@@ -39,5 +39,9 @@
+ #define __off64_t   off64_t
+ #define __ssize_t   ssize_t
+ 
++#if defined(__sparcv9) || defined(__arch64__)
++#define __glibcpp_long_bits 64
++#endif
++
+ #endif
+ 
+--- libstdc++33-v3/config/cpu/alpha/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/alpha/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,38 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_bits 64
++
++#define __glibcpp_long_double_bits 64
++
++#endif
++
++
++
+--- libstdc++33-v3/config/cpu/s390/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/s390/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,33 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_double_bits 64
++
++#endif
+--- libstdc++33-v3/config/cpu/cris/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/cris/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,33 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_double_bits 64
++
++#endif
+--- libstdc++33-v3/config/cpu/powerpc/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/powerpc/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,42 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#ifdef __powerpc64__
++#define __glibcpp_long_bits 64
++#endif
++
++#ifndef __LONG_DOUBLE_128__
++#define __glibcpp_long_double_bits 64
++#endif
++
++#endif
++
++
++
+--- libstdc++33-v3/config/cpu/i386/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/i386/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,33 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_double_bits 80
++
++#endif
+--- libstdc++33-v3/config/cpu/m68k/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/m68k/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,35 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_double_bits 96
++
++#endif
++
++
+--- libstdc++33-v3/config/cpu/ia64/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/ia64/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,36 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#define __glibcpp_long_bits 64
++
++// While sizeof(long double) == 16, the format is the same as the x86.
++#define __glibcpp_long_double_bits 80
++
++#endif
+--- libstdc++33-v3/config/cpu/generic/cpu_limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/generic/cpu_limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,41 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++// Nothing is defined in the generic file.  In that way, we fall back
++// on the defaults in std_limits.h.
++
++// If you need to override these defaults, you can either use a
++// CPU-specific version (in which case you must modify
++// configure.target) or you must add the overrides to your
++// os_defines.h.  In general, if all systems for your CPU use the
++// same values, it is best to use a cpu-specific configuration file.
++
++#endif
++
+--- libstdc++33-v3/config/cpu/generic/limits.h.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/config/cpu/generic/limits.h	2004-10-14 12:28:01.000000000 -0400
+@@ -0,0 +1,40 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++// Nothing is defined in the generic file.  In that way, we fall back
++// on the defaults in std_limits.h.
++
++// If you need to override these defaults, you can either use a
++// CPU-specific version (in which case you must modify
++// configure.target) or you must add the overrides to your
++// os_defines.h.  In general, if all systems for your CPU use the
++// same values, it is best to use a cpu-specific configuration file.
++
++#endif
+--- libstdc++33-v3/config/cpu/x86-64/cpu_limits.h.jj	2004-10-14 12:53:35.000000000 -0400
++++ libstdc++33-v3/config/cpu/x86-64/cpu_limits.h	2004-10-14 12:53:42.000000000 -0400
+@@ -0,0 +1,37 @@
++// Copyright (C) 2001 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This library 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 library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++#ifndef _GLIBCPP_CPU_LIMITS
++#define _GLIBCPP_CPU_LIMITS 1
++
++#ifdef __x86_64__
++#define __glibcpp_long_bits 64
++#endif
++
++#define __glibcpp_long_double_bits 80
++
++#endif
+--- libstdc++33-v3/libio/Makefile.in.jj	2003-03-17 14:07:38.000000000 -0500
++++ libstdc++33-v3/libio/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/include/std/std_limits.h.jj	2002-12-19 06:44:30.000000000 -0500
++++ libstdc++33-v3/include/std/std_limits.h	2004-10-14 12:51:05.000000000 -0400
+@@ -45,6 +45,1898 @@
+ 
+ #pragma GCC system_header
+ 
++#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 2)
++
++#include <bits/cpu_limits.h>
++#include <bits/c++config.h>
++
++//
++// The numeric_limits<> traits document implementation-defined aspects
++// of fundamental arithmetic data types (integers and floating points).
++// From Standard C++ point of view, there are 13 such types:
++//   * integers
++//         bool						        (1)
++//         char, signed char, unsigned char			(3)
++//         short, unsigned short				(2)
++//         int, unsigned					(2)
++//         long, unsigned long					(2)
++//
++//   * floating points
++//         float						(1)
++//         double						(1)
++//         long double						(1)
++//
++// GNU C++ undertstands (where supported by the host C-library) 
++//   * integer
++//         long long, unsigned long long			(2)
++//
++// which brings us to 15 fundamental arithmetic data types in GNU C++.
++//
++// 
++// Since a numeric_limits<> is a bit tricky to get right, we rely on
++// an interface composed of macros which should be defined in config/os
++// or config/cpu when they differ from the generic (read arbitrary)
++// definitions given here.
++//
++
++// These values can be overridden in the target configuration file.
++// The default values are appropriate for many 32-bit targets.
++
++#ifndef __glibcpp_char_bits
++#define __glibcpp_char_bits 8
++#endif
++#ifdef __CHAR_UNSIGNED__
++#define __glibcpp_plain_char_is_signed false
++#else
++#define __glibcpp_plain_char_is_signed true
++#endif
++#ifndef __glibcpp_short_bits
++#define __glibcpp_short_bits 16
++#endif
++#ifndef __glibcpp_int_bits
++#define __glibcpp_int_bits 32
++#endif
++#ifndef __glibcpp_long_bits
++#define __glibcpp_long_bits 32
++#endif
++#ifndef __glibcpp_wchar_t_bits
++#define __glibcpp_wchar_t_bits 32
++#endif
++#ifndef __glibcpp_wchar_t_is_signed
++#define __glibcpp_wchar_t_is_signed true
++#endif
++#ifndef __glibcpp_long_long_bits
++#define __glibcpp_long_long_bits 64
++#endif
++#ifndef __glibcpp_float_bits
++#define __glibcpp_float_bits 32
++#endif
++#ifndef __glibcpp_double_bits
++#define __glibcpp_double_bits 64
++#endif
++#ifndef __glibcpp_long_double_bits
++#define __glibcpp_long_double_bits 128
++#endif
++
++#ifndef __glibcpp_char_traps
++#define __glibcpp_char_traps true
++#endif
++#ifndef __glibcpp_short_traps
++#define __glibcpp_short_traps true
++#endif
++#ifndef __glibcpp_int_traps
++#define __glibcpp_int_traps true
++#endif
++#ifndef __glibcpp_long_traps
++#define __glibcpp_long_traps true
++#endif
++#ifndef __glibcpp_wchar_t_traps
++#define __glibcpp_wchar_t_traps true
++#endif
++#ifndef __glibcpp_long_long_traps
++#define __glibcpp_long_long_traps true
++#endif
++
++// You should not need to define any macros below this point, unless
++// you have a machine with non-standard bit-widths.
++
++// These values are the minimums and maximums for standard data types
++// of common widths.
++
++#define __glibcpp_s8_max 127
++#define __glibcpp_s8_min (-__glibcpp_s8_max - 1)
++#define __glibcpp_s8_digits 7
++#define __glibcpp_s8_digits10 2
++#define __glibcpp_u8_min 0U
++#define __glibcpp_u8_max (__glibcpp_s8_max * 2 + 1)
++#define __glibcpp_u8_digits 8
++#define __glibcpp_u8_digits10 2
++#define __glibcpp_s16_max 32767
++#define __glibcpp_s16_min (-__glibcpp_s16_max - 1)
++#define __glibcpp_s16_digits 15
++#define __glibcpp_s16_digits10 4
++#define __glibcpp_u16_min 0U
++#define __glibcpp_u16_max (__glibcpp_s16_max * 2 + 1)
++#define __glibcpp_u16_digits 16
++#define __glibcpp_u16_digits10 4
++#define __glibcpp_s32_max 2147483647L
++#define __glibcpp_s32_min (-__glibcpp_s32_max - 1)
++#define __glibcpp_s32_digits 31
++#define __glibcpp_s32_digits10 9
++#define __glibcpp_u32_min 0UL
++#define __glibcpp_u32_max (__glibcpp_s32_max * 2U + 1)
++#define __glibcpp_u32_digits 32
++#define __glibcpp_u32_digits10 9
++#define __glibcpp_s64_max 9223372036854775807LL
++#define __glibcpp_s64_min (-__glibcpp_s64_max - 1)
++#define __glibcpp_s64_digits 63
++#define __glibcpp_s64_digits10 18
++#define __glibcpp_u64_min 0ULL
++#define __glibcpp_u64_max (__glibcpp_s64_max * 2ULL + 1)
++#define __glibcpp_u64_digits 64
++#define __glibcpp_u64_digits10 19
++
++#define __glibcpp_f32_min 1.17549435e-38F
++#define __glibcpp_f32_max 3.40282347e+38F
++#define __glibcpp_f32_digits 24
++#define __glibcpp_f32_digits10 6
++#define __glibcpp_f32_radix 2
++#define __glibcpp_f32_epsilon 1.19209290e-07F
++#ifndef __glibcpp_f32_round_error
++#define __glibcpp_f32_round_error 1.0F
++#endif
++#define __glibcpp_f32_min_exponent -125
++#define __glibcpp_f32_min_exponent10 -37
++#define __glibcpp_f32_max_exponent 128
++#define __glibcpp_f32_max_exponent10 38
++#define __glibcpp_f64_min 2.2250738585072014e-308
++#define __glibcpp_f64_max 1.7976931348623157e+308
++#define __glibcpp_f64_digits 53
++#define __glibcpp_f64_digits10 15
++#define __glibcpp_f64_radix 2
++#define __glibcpp_f64_epsilon 2.2204460492503131e-16
++#ifndef __glibcpp_f64_round_error
++#define __glibcpp_f64_round_error 1.0
++#endif
++#define __glibcpp_f64_min_exponent -1021
++#define __glibcpp_f64_min_exponent10 -307
++#define __glibcpp_f64_max_exponent 1024
++#define __glibcpp_f64_max_exponent10 308
++#define __glibcpp_f80_min 3.36210314311209350626e-4932L
++#define __glibcpp_f80_max 1.18973149535723176502e+4932L
++#define __glibcpp_f80_digits 64
++#define __glibcpp_f80_digits10 18
++#define __glibcpp_f80_radix 2
++#define __glibcpp_f80_epsilon 1.08420217248550443401e-19L
++#ifndef __glibcpp_f80_round_error
++#define __glibcpp_f80_round_error 1.0L
++#endif
++#define __glibcpp_f80_min_exponent -16381
++#define __glibcpp_f80_min_exponent10 -4931
++#define __glibcpp_f80_max_exponent 16384
++#define __glibcpp_f80_max_exponent10 4932
++#define __glibcpp_f96_min 1.68105157155604675313e-4932L
++#define __glibcpp_f96_max 1.18973149535723176502e+4932L
++#define __glibcpp_f96_digits 64
++#define __glibcpp_f96_digits10 18
++#define __glibcpp_f96_radix 2
++#define __glibcpp_f96_epsilon 1.08420217248550443401e-19L
++#ifndef __glibcpp_f96_round_error
++#define __glibcpp_f96_round_error 1.0L
++#endif
++#define __glibcpp_f96_min_exponent -16382
++#define __glibcpp_f96_min_exponent10 -4931
++#define __glibcpp_f96_max_exponent 16384
++#define __glibcpp_f96_max_exponent10 4932
++#define __glibcpp_f128_min 3.362103143112093506262677817321752603E-4932L
++#define __glibcpp_f128_max 1.189731495357231765085759326628007016E+4932L
++#define __glibcpp_f128_digits 113
++#define __glibcpp_f128_digits10 33
++#define __glibcpp_f128_radix 2
++#define __glibcpp_f128_epsilon 1.925929944387235853055977942584927319E-34L
++#ifndef __glibcpp_f128_round_error
++#define __glibcpp_f128_round_error 1.0L
++#endif
++#define __glibcpp_f128_min_exponent -16381
++#define __glibcpp_f128_min_exponent10 -4931
++#define __glibcpp_f128_max_exponent 16384
++#define __glibcpp_f128_max_exponent10 4932
++
++// bool-specific hooks:
++//     __glibcpp_bool_digits  __glibcpp_int_traps __glibcpp_long_traps
++
++#ifndef __glibcpp_bool_digits
++#define __glibcpp_bool_digits 1
++#endif
++
++// char.
++
++#define __glibcpp_plain_char_traps true
++#define __glibcpp_signed_char_traps true
++#define __glibcpp_unsigned_char_traps true
++#ifndef __glibcpp_char_is_modulo
++#define __glibcpp_char_is_modulo true
++#endif
++#ifndef __glibcpp_signed_char_is_modulo
++#define __glibcpp_signed_char_is_modulo true
++#endif
++#if __glibcpp_char_bits == 8
++#define __glibcpp_signed_char_min __glibcpp_s8_min
++#define __glibcpp_signed_char_max __glibcpp_s8_max
++#define __glibcpp_signed_char_digits __glibcpp_s8_digits
++#define __glibcpp_signed_char_digits10 __glibcpp_s8_digits10
++#define __glibcpp_unsigned_char_min __glibcpp_u8_min
++#define __glibcpp_unsigned_char_max __glibcpp_u8_max
++#define __glibcpp_unsigned_char_digits __glibcpp_u8_digits
++#define __glibcpp_unsigned_char_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_char_bits == 16
++#define __glibcpp_signed_char_min __glibcpp_s16_min
++#define __glibcpp_signed_char_max __glibcpp_s16_max
++#define __glibcpp_signed_char_digits __glibcpp_s16_digits
++#define __glibcpp_signed_char_digits10 __glibcpp_s16_digits10
++#define __glibcpp_unsigned_char_min __glibcpp_u16_min
++#define __glibcpp_unsigned_char_max __glibcpp_u16_max
++#define __glibcpp_unsigned_char_digits __glibcpp_u16_digits
++#define __glibcpp_unsigned_char_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_char_bits == 32
++#define __glibcpp_signed_char_min (signed char)__glibcpp_s32_min
++#define __glibcpp_signed_char_max (signed char)__glibcpp_s32_max
++#define __glibcpp_signed_char_digits __glibcpp_s32_digits
++#define __glibcpp_signed_char_digits10 __glibcpp_s32_digits10
++#define __glibcpp_unsigned_char_min (unsigned char)__glibcpp_u32_min
++#define __glibcpp_unsigned_char_max (unsigned char)__glibcpp_u32_max
++#define __glibcpp_unsigned_char_digits __glibcpp_u32_digits
++#define __glibcpp_unsigned_char_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_char_bits == 64
++#define __glibcpp_signed_char_min (signed char)__glibcpp_s64_min
++#define __glibcpp_signed_char_max (signed char)__glibcpp_s64_max
++#define __glibcpp_signed_char_digits __glibcpp_s64_digits
++#define __glibcpp_signed_char_digits10 __glibcpp_s64_digits10
++#define __glibcpp_unsigned_char_min (unsigned char)__glibcpp_u64_min
++#define __glibcpp_unsigned_char_max (unsigned char)__glibcpp_u64_max
++#define __glibcpp_unsigned_char_digits __glibcpp_u64_digits
++#define __glibcpp_unsigned_char_digits10 __glibcpp_u64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++#if __glibcpp_plain_char_is_signed
++#define __glibcpp_char_min (char)__glibcpp_signed_char_min
++#define __glibcpp_char_max (char)__glibcpp_signed_char_max
++#define __glibcpp_char_digits __glibcpp_signed_char_digits
++#define __glibcpp_char_digits10 __glibcpp_signed_char_digits10
++#else
++#define __glibcpp_char_min (char)__glibcpp_unsigned_char_min
++#define __glibcpp_char_max (char)__glibcpp_unsigned_char_max
++#define __glibcpp_char_digits __glibcpp_unsigned_char_digits
++#define __glibcpp_char_digits10 __glibcpp_unsigned_char_digits10
++#endif
++
++// short
++
++#define __glibcpp_signed_short_traps true
++#define __glibcpp_unsigned_short_traps true
++#ifndef __glibcpp_signed_short_is_modulo
++#define __glibcpp_signed_short_is_modulo true
++#endif
++#if __glibcpp_short_bits == 8
++#define __glibcpp_signed_short_min __glibcpp_s8_min
++#define __glibcpp_signed_short_max __glibcpp_s8_max
++#define __glibcpp_signed_short_digits __glibcpp_s8_digits
++#define __glibcpp_signed_short_digits10 __glibcpp_s8_digits10
++#define __glibcpp_unsigned_short_min __glibcpp_u8_min
++#define __glibcpp_unsigned_short_max __glibcpp_u8_max
++#define __glibcpp_unsigned_short_digits __glibcpp_u8_digits
++#define __glibcpp_unsigned_short_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_short_bits == 16
++#define __glibcpp_signed_short_min __glibcpp_s16_min
++#define __glibcpp_signed_short_max __glibcpp_s16_max
++#define __glibcpp_signed_short_digits __glibcpp_s16_digits
++#define __glibcpp_signed_short_digits10 __glibcpp_s16_digits10
++#define __glibcpp_unsigned_short_min __glibcpp_u16_min
++#define __glibcpp_unsigned_short_max __glibcpp_u16_max
++#define __glibcpp_unsigned_short_digits __glibcpp_u16_digits
++#define __glibcpp_unsigned_short_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_short_bits == 32
++#define __glibcpp_signed_short_min (short)__glibcpp_s32_min
++#define __glibcpp_signed_short_max (short)__glibcpp_s32_max
++#define __glibcpp_signed_short_digits __glibcpp_s32_digits
++#define __glibcpp_signed_short_digits10 __glibcpp_s32_digits10
++#define __glibcpp_unsigned_short_min (unsigned short)__glibcpp_u32_min
++#define __glibcpp_unsigned_short_max (unsigned short)__glibcpp_u32_max
++#define __glibcpp_unsigned_short_digits __glibcpp_u32_digits
++#define __glibcpp_unsigned_short_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_short_bits == 64
++#define __glibcpp_signed_short_min (short)__glibcpp_s64_min
++#define __glibcpp_signed_short_max (short)__glibcpp_s64_max
++#define __glibcpp_signed_short_digits __glibcpp_s64_digits
++#define __glibcpp_signed_short_digits10 __glibcpp_s64_digits10
++#define __glibcpp_unsigned_short_min (unsigned short)__glibcpp_u64_min
++#define __glibcpp_unsigned_short_max (unsigned short)__glibcpp_u64_max
++#define __glibcpp_unsigned_short_digits __glibcpp_u64_digits
++#define __glibcpp_unsigned_short_digits10 __glibcpp_u64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// int
++
++#define __glibcpp_signed_int_traps true
++#define __glibcpp_unsigned_int_traps true
++#ifndef __glibcpp_signed_int_is_modulo
++#define __glibcpp_signed_int_is_modulo true
++#endif
++#if __glibcpp_int_bits == 8
++#define __glibcpp_signed_int_min __glibcpp_s8_min
++#define __glibcpp_signed_int_max __glibcpp_s8_max
++#define __glibcpp_signed_int_digits __glibcpp_s8_digits
++#define __glibcpp_signed_int_digits10 __glibcpp_s8_digits10
++#define __glibcpp_unsigned_int_min __glibcpp_u8_min
++#define __glibcpp_unsigned_int_max __glibcpp_u8_max
++#define __glibcpp_unsigned_int_digits __glibcpp_u8_digits
++#define __glibcpp_unsigned_int_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_int_bits == 16
++#define __glibcpp_signed_int_min __glibcpp_s16_min
++#define __glibcpp_signed_int_max __glibcpp_s16_max
++#define __glibcpp_signed_int_digits __glibcpp_s16_digits
++#define __glibcpp_signed_int_digits10 __glibcpp_s16_digits10
++#define __glibcpp_unsigned_int_min __glibcpp_u16_min
++#define __glibcpp_unsigned_int_max __glibcpp_u16_max
++#define __glibcpp_unsigned_int_digits __glibcpp_u16_digits
++#define __glibcpp_unsigned_int_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_int_bits == 32
++#define __glibcpp_signed_int_min (int)__glibcpp_s32_min
++#define __glibcpp_signed_int_max (int)__glibcpp_s32_max
++#define __glibcpp_signed_int_digits __glibcpp_s32_digits
++#define __glibcpp_signed_int_digits10 __glibcpp_s32_digits10
++#define __glibcpp_unsigned_int_min (unsigned)__glibcpp_u32_min
++#define __glibcpp_unsigned_int_max (unsigned)__glibcpp_u32_max
++#define __glibcpp_unsigned_int_digits __glibcpp_u32_digits
++#define __glibcpp_unsigned_int_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_int_bits == 64
++#define __glibcpp_signed_int_min (int)__glibcpp_s64_min
++#define __glibcpp_signed_int_max (int)__glibcpp_s64_max
++#define __glibcpp_signed_int_digits __glibcpp_s64_digits
++#define __glibcpp_signed_int_digits10 __glibcpp_s64_digits10
++#define __glibcpp_unsigned_int_min (unsigned)__glibcpp_u64_min
++#define __glibcpp_unsigned_int_max (unsigned)__glibcpp_u64_max
++#define __glibcpp_unsigned_int_digits __glibcpp_u64_digits
++#define __glibcpp_unsigned_int_digits10 __glibcpp_u64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// long
++
++#define __glibcpp_signed_long_traps true
++#define __glibcpp_unsigned_long_traps true
++#ifndef __glibcpp_signed_long_is_modulo
++#define __glibcpp_signed_long_is_modulo true
++#endif
++#if __glibcpp_long_bits == 8
++#define __glibcpp_signed_long_min __glibcpp_s8_min
++#define __glibcpp_signed_long_max __glibcpp_s8_max
++#define __glibcpp_signed_long_digits __glibcpp_s8_digits
++#define __glibcpp_signed_long_digits10 __glibcpp_s8_digits10
++#define __glibcpp_unsigned_long_min __glibcpp_u8_min
++#define __glibcpp_unsigned_long_max __glibcpp_u8_max
++#define __glibcpp_unsigned_long_digits __glibcpp_u8_digits
++#define __glibcpp_unsigned_long_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_long_bits == 16
++#define __glibcpp_signed_long_min __glibcpp_s16_min
++#define __glibcpp_signed_long_max __glibcpp_s16_max
++#define __glibcpp_signed_long_digits __glibcpp_s16_digits
++#define __glibcpp_signed_long_digits10 __glibcpp_s16_digits10
++#define __glibcpp_unsigned_long_min __glibcpp_u16_min
++#define __glibcpp_unsigned_long_max __glibcpp_u16_max
++#define __glibcpp_unsigned_long_digits __glibcpp_u16_digits
++#define __glibcpp_unsigned_long_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_long_bits == 32
++#define __glibcpp_signed_long_min __glibcpp_s32_min
++#define __glibcpp_signed_long_max __glibcpp_s32_max
++#define __glibcpp_signed_long_digits __glibcpp_s32_digits
++#define __glibcpp_signed_long_digits10 __glibcpp_s32_digits10
++#define __glibcpp_unsigned_long_min __glibcpp_u32_min
++#define __glibcpp_unsigned_long_max __glibcpp_u32_max
++#define __glibcpp_unsigned_long_digits __glibcpp_u32_digits
++#define __glibcpp_unsigned_long_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_long_bits == 64
++#define __glibcpp_signed_long_min (long)__glibcpp_s64_min
++#define __glibcpp_signed_long_max (long)__glibcpp_s64_max
++#define __glibcpp_signed_long_digits __glibcpp_s64_digits
++#define __glibcpp_signed_long_digits10 __glibcpp_s64_digits10
++#define __glibcpp_unsigned_long_min (unsigned long)__glibcpp_u64_min
++#define __glibcpp_unsigned_long_max (unsigned long)__glibcpp_u64_max
++#define __glibcpp_unsigned_long_digits __glibcpp_u64_digits
++#define __glibcpp_unsigned_long_digits10 __glibcpp_u64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// long long
++
++#define __glibcpp_signed_long_long_traps true
++#define __glibcpp_signed_long_long_traps true
++#ifndef __glibcpp_signed_long_long_is_modulo
++#define __glibcpp_signed_long_long_is_modulo true
++#endif
++#if __glibcpp_long_long_bits == 8
++#define __glibcpp_signed_long_long_min __glibcpp_s8_min
++#define __glibcpp_signed_long_long_max __glibcpp_s8_max
++#define __glibcpp_signed_long_long_digits __glibcpp_s8_digits
++#define __glibcpp_signed_long_long_digits10 __glibcpp_s8_digits10
++#define __glibcpp_unsigned_long_long_min __glibcpp_u8_min
++#define __glibcpp_unsigned_long_long_max __glibcpp_u8_max
++#define __glibcpp_unsigned_long_long_digits __glibcpp_u8_digits
++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_long_long_bits == 16
++#define __glibcpp_signed_long_long_min __glibcpp_s16_min
++#define __glibcpp_signed_long_long_max __glibcpp_s16_max
++#define __glibcpp_signed_long_long_digits __glibcpp_s16_digits
++#define __glibcpp_signed_long_long_digits10 __glibcpp_s16_digits10
++#define __glibcpp_unsigned_long_long_min __glibcpp_u16_min
++#define __glibcpp_unsigned_long_long_max __glibcpp_u16_max
++#define __glibcpp_unsigned_long_long_digits __glibcpp_u16_digits
++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_long_long_bits == 32
++#define __glibcpp_signed_long_long_min __glibcpp_s32_min
++#define __glibcpp_signed_long_long_max __glibcpp_s32_max
++#define __glibcpp_signed_long_long_digits __glibcpp_s32_digits
++#define __glibcpp_signed_long_long_digits10 __glibcpp_s32_digits10
++#define __glibcpp_unsigned_long_long_min __glibcpp_u32_min
++#define __glibcpp_unsigned_long_long_max __glibcpp_u32_max
++#define __glibcpp_unsigned_long_long_digits __glibcpp_u32_digits
++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_long_long_bits == 64
++#define __glibcpp_signed_long_long_min __glibcpp_s64_min
++#define __glibcpp_signed_long_long_max __glibcpp_s64_max
++#define __glibcpp_signed_long_long_digits __glibcpp_s64_digits
++#define __glibcpp_signed_long_long_digits10 __glibcpp_s64_digits10
++#define __glibcpp_signed_long_long_traps true
++#define __glibcpp_unsigned_long_long_min __glibcpp_u64_min
++#define __glibcpp_unsigned_long_long_max __glibcpp_u64_max
++#define __glibcpp_unsigned_long_long_digits __glibcpp_u64_digits
++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u64_digits10
++#define __glibcpp_unsigned_long_long_traps true
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// wchar_t
++
++#define __glibcpp_wchar_t_traps true
++#ifndef __glibcpp_wchar_t_is_modulo
++#define __glibcpp_wchar_t_is_modulo true
++#endif
++#if __glibcpp_wchar_t_is_signed
++#if __glibcpp_wchar_t_bits == 8
++#define __glibcpp_wchar_t_min __glibcpp_s8_min
++#define __glibcpp_wchar_t_max __glibcpp_s8_max
++#define __glibcpp_wchar_t_digits __glibcpp_s8_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_s8_digits10
++#elif __glibcpp_wchar_t_bits == 16
++#define __glibcpp_wchar_t_min __glibcpp_s16_min
++#define __glibcpp_wchar_t_max __glibcpp_s16_max
++#define __glibcpp_wchar_t_digits __glibcpp_s16_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_s16_digits10
++#elif __glibcpp_wchar_t_bits == 32
++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_s32_min
++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_s32_max
++#define __glibcpp_wchar_t_digits __glibcpp_s32_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_s32_digits10
++#elif __glibcpp_wchar_t_bits == 64
++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_s64_min
++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_s64_max
++#define __glibcpp_wchar_t_digits __glibcpp_s64_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_s64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++#else
++#if __glibcpp_wchar_t_bits == 8
++#define __glibcpp_wchar_t_min __glibcpp_u8_min
++#define __glibcpp_wchar_t_max __glibcpp_u8_max
++#define __glibcpp_wchar_t_digits __glibcpp_u8_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_u8_digits10
++#elif __glibcpp_wchar_t_bits == 16
++#define __glibcpp_wchar_t_min __glibcpp_u16_min
++#define __glibcpp_wchar_t_max __glibcpp_u16_max
++#define __glibcpp_wchar_t_digits __glibcpp_u16_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_u16_digits10
++#elif __glibcpp_wchar_t_bits == 32
++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_u32_min
++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_u32_max
++#define __glibcpp_wchar_t_digits __glibcpp_u32_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_u32_digits10
++#elif __glibcpp_wchar_t_bits == 64
++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_u64_min
++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_u64_max
++#define __glibcpp_wchar_t_digits __glibcpp_u64_digits
++#define __glibcpp_wchar_t_digits10 __glibcpp_u64_digits10
++#else
++// You must define these macros in the configuration file.
++#endif
++#endif
++
++// float
++//
++
++#if __glibcpp_float_bits == 32
++#define __glibcpp_float_min __glibcpp_f32_min
++#define __glibcpp_float_max __glibcpp_f32_max
++#define __glibcpp_float_digits __glibcpp_f32_digits
++#define __glibcpp_float_digits10 __glibcpp_f32_digits10
++#define __glibcpp_float_radix __glibcpp_f32_radix
++#define __glibcpp_float_epsilon __glibcpp_f32_epsilon
++#define __glibcpp_float_round_error __glibcpp_f32_round_error
++#define __glibcpp_float_min_exponent __glibcpp_f32_min_exponent
++#define __glibcpp_float_min_exponent10 __glibcpp_f32_min_exponent10
++#define __glibcpp_float_max_exponent __glibcpp_f32_max_exponent
++#define __glibcpp_float_max_exponent10 __glibcpp_f32_max_exponent10
++#elif __glibcpp_float_bits == 64
++#define __glibcpp_float_min __glibcpp_f64_min
++#define __glibcpp_float_max __glibcpp_f64_max
++#define __glibcpp_float_digits __glibcpp_f64_digits
++#define __glibcpp_float_digits10 __glibcpp_f64_digits10
++#define __glibcpp_float_radix __glibcpp_f64_radix
++#define __glibcpp_float_epsilon __glibcpp_f64_epsilon
++#define __glibcpp_float_round_error __glibcpp_f64_round_error
++#define __glibcpp_float_min_exponent __glibcpp_f64_min_exponent
++#define __glibcpp_float_min_exponent10 __glibcpp_f64_min_exponent10
++#define __glibcpp_float_max_exponent __glibcpp_f64_max_exponent
++#define __glibcpp_float_max_exponent10 __glibcpp_f64_max_exponent10
++#elif __glibcpp_float_bits == 80
++#define __glibcpp_float_min __glibcpp_f80_min
++#define __glibcpp_float_max __glibcpp_f80_max
++#define __glibcpp_float_digits __glibcpp_f80_digits
++#define __glibcpp_float_digits10 __glibcpp_f80_digits10
++#define __glibcpp_float_radix __glibcpp_f80_radix
++#define __glibcpp_float_epsilon __glibcpp_f80_epsilon
++#define __glibcpp_float_round_error __glibcpp_f80_round_error
++#define __glibcpp_float_min_exponent __glibcpp_f80_min_exponent
++#define __glibcpp_float_min_exponent10 __glibcpp_f80_min_exponent10
++#define __glibcpp_float_max_exponent __glibcpp_f80_max_exponent
++#define __glibcpp_float_max_exponent10 __glibcpp_f80_max_exponent10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// FIXME: These are just stubs and inkorrect
++
++#ifndef __glibcpp_float_has_infinity
++#define __glibcpp_float_has_infinity false
++#endif
++
++#ifndef __glibcpp_float_has_quiet_NaN
++#define __glibcpp_float_has_quiet_NaN false
++#endif
++
++#ifndef __glibcpp_float_has_signaling_NaN
++#define __glibcpp_float_has_signaling_NaN false
++#endif
++
++#ifndef __glibcpp_float_has_denorm
++#define __glibcpp_float_has_denorm denorm_absent
++#endif
++
++#ifndef __glibcpp_float_has_denorm_loss
++#define __glibcpp_float_has_denorm_loss false
++#endif
++
++#ifndef __glibcpp_float_infinity
++#define __glibcpp_float_infinity 0.0F
++#endif
++
++#ifndef __glibcpp_float_quiet_NaN
++#define __glibcpp_float_quiet_NaN 0.0F
++#endif
++
++#ifndef __glibcpp_float_signaling_NaN
++#define __glibcpp_float_signaling_NaN 0.0F
++#endif
++
++#ifndef __glibcpp_float_denorm_min
++#define __glibcpp_float_denorm_min 0.0F
++#endif
++
++#ifndef __glibcpp_float_is_iec559
++#define __glibcpp_float_is_iec559 false
++#endif
++
++#ifndef __glibcpp_float_is_bounded
++#define __glibcpp_float_is_bounded true
++#endif
++
++#ifndef __glibcpp_float_is_modulo
++#define __glibcpp_float_is_modulo false
++#endif
++
++#ifndef __glibcpp_float_traps
++#define __glibcpp_float_traps false
++#endif
++
++#ifndef __glibcpp_float_tinyness_before
++#define __glibcpp_float_tinyness_before false
++#endif
++
++#ifndef __glibcpp_float_round_style
++#define __glibcpp_float_round_style round_toward_zero
++#endif
++
++// double
++
++#if __glibcpp_double_bits == 32
++#define __glibcpp_double_min __glibcpp_f32_min
++#define __glibcpp_double_max __glibcpp_f32_max
++#define __glibcpp_double_digits __glibcpp_f32_digits
++#define __glibcpp_double_digits10 __glibcpp_f32_digits10
++#define __glibcpp_double_radix __glibcpp_f32_radix
++#define __glibcpp_double_epsilon __glibcpp_f32_epsilon
++#define __glibcpp_double_round_error __glibcpp_f32_round_error
++#define __glibcpp_double_min_exponent __glibcpp_f32_min_exponent
++#define __glibcpp_double_min_exponent10 __glibcpp_f32_min_exponent10
++#define __glibcpp_double_max_exponent __glibcpp_f32_max_exponent
++#define __glibcpp_double_max_exponent10 __glibcpp_f32_max_exponent10
++#elif __glibcpp_double_bits == 64
++#define __glibcpp_double_min __glibcpp_f64_min
++#define __glibcpp_double_max __glibcpp_f64_max
++#define __glibcpp_double_digits __glibcpp_f64_digits
++#define __glibcpp_double_digits10 __glibcpp_f64_digits10
++#define __glibcpp_double_radix __glibcpp_f64_radix
++#define __glibcpp_double_epsilon __glibcpp_f64_epsilon
++#define __glibcpp_double_round_error __glibcpp_f64_round_error
++#define __glibcpp_double_min_exponent __glibcpp_f64_min_exponent
++#define __glibcpp_double_min_exponent10 __glibcpp_f64_min_exponent10
++#define __glibcpp_double_max_exponent __glibcpp_f64_max_exponent
++#define __glibcpp_double_max_exponent10 __glibcpp_f64_max_exponent10
++#elif __glibcpp_double_bits == 80
++#define __glibcpp_double_min __glibcpp_f80_min
++#define __glibcpp_double_max __glibcpp_f80_max
++#define __glibcpp_double_digits __glibcpp_f80_digits
++#define __glibcpp_double_digits10 __glibcpp_f80_digits10
++#define __glibcpp_double_radix __glibcpp_f80_radix
++#define __glibcpp_double_epsilon __glibcpp_f80_epsilon
++#define __glibcpp_double_round_error __glibcpp_f80_round_error
++#define __glibcpp_double_min_exponent __glibcpp_f80_min_exponent
++#define __glibcpp_double_min_exponent10 __glibcpp_f80_min_exponent10
++#define __glibcpp_double_max_exponent __glibcpp_f80_max_exponent
++#define __glibcpp_double_max_exponent10 __glibcpp_f80_max_exponent10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// FIXME: These are just stubs and inkorrect
++
++#ifndef __glibcpp_double_has_infinity
++#define __glibcpp_double_has_infinity false
++#endif
++
++#ifndef __glibcpp_double_has_quiet_NaN
++#define __glibcpp_double_has_quiet_NaN false
++#endif
++
++#ifndef __glibcpp_double_has_signaling_NaN
++#define __glibcpp_double_has_signaling_NaN false
++#endif
++
++#ifndef __glibcpp_double_has_denorm
++#define __glibcpp_double_has_denorm denorm_absent
++#endif
++
++#ifndef __glibcpp_double_has_denorm_loss
++#define __glibcpp_double_has_denorm_loss false
++#endif
++
++#ifndef __glibcpp_double_infinity
++#define __glibcpp_double_infinity 0.0
++#endif
++
++#ifndef __glibcpp_double_quiet_NaN
++#define __glibcpp_double_quiet_NaN 0.0
++#endif
++
++#ifndef __glibcpp_double_signaling_NaN
++#define __glibcpp_double_signaling_NaN 0.0
++#endif
++
++#ifndef __glibcpp_double_denorm_min
++#define __glibcpp_double_denorm_min 0.0
++#endif
++
++#ifndef __glibcpp_double_is_iec559
++#define __glibcpp_double_is_iec559 false
++#endif
++
++#ifndef __glibcpp_double_is_bounded
++#define __glibcpp_double_is_bounded true
++#endif
++
++#ifndef __glibcpp_double_is_modulo
++#define __glibcpp_double_is_modulo false
++#endif
++
++#ifndef __glibcpp_double_traps
++#define __glibcpp_double_traps false
++#endif
++
++#ifndef __glibcpp_double_tinyness_before
++#define __glibcpp_double_tinyness_before false
++#endif
++
++#ifndef __glibcpp_double_round_style
++#define __glibcpp_double_round_style round_toward_zero
++#endif
++
++// long double
++
++#if __glibcpp_long_double_bits == 32
++#define __glibcpp_long_double_min __glibcpp_f32_min
++#define __glibcpp_long_double_max __glibcpp_f32_max
++#define __glibcpp_long_double_digits __glibcpp_f32_digits
++#define __glibcpp_long_double_digits10 __glibcpp_f32_digits10
++#define __glibcpp_long_double_radix __glibcpp_f32_radix
++#define __glibcpp_long_double_epsilon __glibcpp_f32_epsilon
++#define __glibcpp_long_double_round_error __glibcpp_f32_round_error
++#define __glibcpp_long_double_min_exponent __glibcpp_f32_min_exponent
++#define __glibcpp_long_double_min_exponent10 __glibcpp_f32_min_exponent10
++#define __glibcpp_long_double_max_exponent __glibcpp_f32_max_exponent
++#define __glibcpp_long_double_max_exponent10 __glibcpp_f32_max_exponent10
++#elif __glibcpp_long_double_bits == 64
++#define __glibcpp_long_double_min __glibcpp_f64_min
++#define __glibcpp_long_double_max __glibcpp_f64_max
++#define __glibcpp_long_double_digits __glibcpp_f64_digits
++#define __glibcpp_long_double_digits10 __glibcpp_f64_digits10
++#define __glibcpp_long_double_radix __glibcpp_f64_radix
++#define __glibcpp_long_double_epsilon __glibcpp_f64_epsilon
++#define __glibcpp_long_double_round_error __glibcpp_f64_round_error
++#define __glibcpp_long_double_min_exponent __glibcpp_f64_min_exponent
++#define __glibcpp_long_double_min_exponent10 __glibcpp_f64_min_exponent10
++#define __glibcpp_long_double_max_exponent __glibcpp_f64_max_exponent
++#define __glibcpp_long_double_max_exponent10 __glibcpp_f64_max_exponent10
++#elif __glibcpp_long_double_bits == 80
++#define __glibcpp_long_double_min __glibcpp_f80_min
++#define __glibcpp_long_double_max __glibcpp_f80_max
++#define __glibcpp_long_double_digits __glibcpp_f80_digits
++#define __glibcpp_long_double_digits10 __glibcpp_f80_digits10
++#define __glibcpp_long_double_radix __glibcpp_f80_radix
++#define __glibcpp_long_double_epsilon __glibcpp_f80_epsilon
++#define __glibcpp_long_double_round_error __glibcpp_f80_round_error
++#define __glibcpp_long_double_min_exponent __glibcpp_f80_min_exponent
++#define __glibcpp_long_double_min_exponent10 __glibcpp_f80_min_exponent10
++#define __glibcpp_long_double_max_exponent __glibcpp_f80_max_exponent
++#define __glibcpp_long_double_max_exponent10 __glibcpp_f80_max_exponent10
++#elif __glibcpp_long_double_bits == 96
++#define __glibcpp_long_double_min __glibcpp_f96_min
++#define __glibcpp_long_double_max __glibcpp_f96_max
++#define __glibcpp_long_double_digits __glibcpp_f96_digits
++#define __glibcpp_long_double_digits10 __glibcpp_f96_digits10
++#define __glibcpp_long_double_radix __glibcpp_f96_radix
++#define __glibcpp_long_double_epsilon __glibcpp_f96_epsilon
++#define __glibcpp_long_double_round_error __glibcpp_f96_round_error
++#define __glibcpp_long_double_min_exponent __glibcpp_f96_min_exponent
++#define __glibcpp_long_double_min_exponent10 __glibcpp_f96_min_exponent10
++#define __glibcpp_long_double_max_exponent __glibcpp_f96_max_exponent
++#define __glibcpp_long_double_max_exponent10 __glibcpp_f96_max_exponent10
++#elif __glibcpp_long_double_bits == 128
++#define __glibcpp_long_double_min __glibcpp_f128_min
++#define __glibcpp_long_double_max __glibcpp_f128_max
++#define __glibcpp_long_double_digits __glibcpp_f128_digits
++#define __glibcpp_long_double_digits10 __glibcpp_f128_digits10
++#define __glibcpp_long_double_radix __glibcpp_f128_radix
++#define __glibcpp_long_double_epsilon __glibcpp_f128_epsilon
++#define __glibcpp_long_double_round_error __glibcpp_f128_round_error
++#define __glibcpp_long_double_min_exponent __glibcpp_f128_min_exponent
++#define __glibcpp_long_double_min_exponent10 __glibcpp_f128_min_exponent10
++#define __glibcpp_long_double_max_exponent __glibcpp_f128_max_exponent
++#define __glibcpp_long_double_max_exponent10 __glibcpp_f128_max_exponent10
++#else
++// You must define these macros in the configuration file.
++#endif
++
++// FIXME: These are just stubs and inkorrect
++
++#ifndef __glibcpp_long_double_has_infinity
++#define __glibcpp_long_double_has_infinity false
++#endif
++
++#ifndef __glibcpp_long_double_has_quiet_NaN
++#define __glibcpp_long_double_has_quiet_NaN false
++#endif
++
++#ifndef __glibcpp_long_double_has_signaling_NaN
++#define __glibcpp_long_double_has_signaling_NaN false
++#endif
++
++#ifndef __glibcpp_long_double_has_denorm
++#define __glibcpp_long_double_has_denorm denorm_absent
++#endif
++
++#ifndef __glibcpp_long_double_has_denorm_loss
++#define __glibcpp_long_double_has_denorm_loss false
++#endif
++
++#ifndef __glibcpp_long_double_infinity
++#define __glibcpp_long_double_infinity 0.0L
++#endif
++
++#ifndef __glibcpp_long_double_quiet_NaN
++#define __glibcpp_long_double_quiet_NaN 0.0L
++#endif
++
++#ifndef __glibcpp_long_double_signaling_NaN
++#define __glibcpp_long_double_signaling_NaN 0.0L
++#endif
++
++#ifndef __glibcpp_long_double_denorm_min
++#define __glibcpp_long_double_denorm_min 0.0L
++#endif
++
++#ifndef __glibcpp_long_double_is_iec559
++#define __glibcpp_long_double_is_iec559 false
++#endif
++
++#ifndef __glibcpp_long_double_is_bounded
++#define __glibcpp_long_double_is_bounded true
++#endif
++
++#ifndef __glibcpp_long_double_is_modulo
++#define __glibcpp_long_double_is_modulo false
++#endif
++
++#ifndef __glibcpp_long_double_traps
++#define __glibcpp_long_double_traps false
++#endif
++
++#ifndef __glibcpp_long_double_tinyness_before
++#define __glibcpp_long_double_tinyness_before false
++#endif
++
++#ifndef __glibcpp_long_double_round_style
++#define __glibcpp_long_double_round_style round_toward_zero
++#endif
++
++
++namespace std
++{
++  enum float_round_style 
++  {
++    round_indeterminate       = -1,
++    round_toward_zero         = 0,
++    round_to_nearest          = 1,
++    round_toward_infinity     = 2,
++    round_toward_neg_infinity = 3
++  };
++
++  enum float_denorm_style 
++  {
++    denorm_indeterminate = -1,
++    denorm_absent        = 0,
++    denorm_present       = 1
++  };
++
++  //
++  // The primary class traits
++  //
++  struct __numeric_limits_base
++  {
++    static const bool is_specialized = false;
++
++    static const int digits = 0;
++    static const int digits10 = 0;
++    static const bool is_signed = false;
++    static const bool is_integer = false;
++    static const bool is_exact = false;
++    static const int radix = 0;
++
++    static const int min_exponent = 0;
++    static const int min_exponent10 = 0;
++    static const int max_exponent = 0;
++    static const int max_exponent10 = 0;
++    
++    static const bool has_infinity = false;
++    static const bool has_quiet_NaN = false;
++    static const bool has_signaling_NaN = false;
++    static const float_denorm_style has_denorm = denorm_absent;
++    static const bool has_denorm_loss = false;
++
++    static const bool is_iec559 = false;
++    static const bool is_bounded = false;
++    static const bool is_modulo = false;
++
++    static const bool traps = false;
++    static const bool tinyness_before = false;
++    static const float_round_style round_style = round_toward_zero;
++  };
++
++  template<typename _Tp> 
++    struct numeric_limits : public __numeric_limits_base 
++    {
++      static _Tp min() throw() { return static_cast<_Tp>(0); }
++      static _Tp max() throw() { return static_cast<_Tp>(0); }
++      static _Tp epsilon() throw() { return static_cast<_Tp>(0); }
++      static _Tp round_error() throw() { return static_cast<_Tp>(0); }
++      static _Tp infinity() throw()  { return static_cast<_Tp>(0); }
++      static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); }
++      static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); }
++      static _Tp denorm_min() throw() { return static_cast<_Tp>(0); }
++    };
++
++  // Now there follow 15 explicit specializations.  Yes, 15.  Make sure
++  // you get the count right.  
++  template<>
++    struct numeric_limits<bool>
++    {
++      static const bool is_specialized = true;
++
++      static bool min() throw()
++      { return false; }
++
++      static bool max() throw()
++      { return true; }
++
++      static const int digits = __glibcpp_bool_digits;
++      static const int digits10 = 0;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static bool epsilon() throw()
++      { return false; }
++      static bool round_error() throw()
++      { return false; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static bool infinity() throw()
++      { return false; }
++      static bool quiet_NaN() throw()
++      { return false; }
++      static bool signaling_NaN() throw()
++      { return false; }
++      static bool denorm_min() throw()
++      { return false; }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = false;
++
++      // It is not clear what it means for a boolean type to trap.
++      // This is a DR on the LWG issue list.  Here, I use integer
++      // promotion semantics.
++      static const bool traps = __glibcpp_signed_int_traps
++               || __glibcpp_signed_long_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_bool_digits  
++  
++  template<>
++    struct numeric_limits<char>
++    {
++      static const bool is_specialized = true;
++
++      static char min() throw()
++      { return __glibcpp_char_min; }
++      static char max() throw()
++      { return __glibcpp_char_max; }
++
++      static const int digits = __glibcpp_char_digits;
++      static const int digits10 = __glibcpp_char_digits10;
++      static const bool is_signed = __glibcpp_plain_char_is_signed;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static char epsilon() throw()
++      { return char(); }
++      static char round_error() throw()
++      { return char(); }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static char infinity() throw()
++      { return char(); }
++      static char quiet_NaN() throw()
++      { return char(); }
++      static char signaling_NaN() throw()
++      { return char(); }
++      static char denorm_min() throw()
++      { return static_cast<char>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_char_is_modulo;
++
++      static const bool traps = __glibcpp_char_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_char_min
++#undef __glibcpp_char_max  
++#undef __glibcpp_char_digits
++#undef __glibcpp_char_digits10
++#undef __glibcpp_char_is_signed
++#undef __glibcpp_char_is_modulo
++#undef __glibcpp_char_traps
++
++
++
++  template<>
++    struct numeric_limits<signed char>
++    {
++      static const bool is_specialized = true;
++
++      static signed char min() throw()
++      { return __glibcpp_signed_char_min; }
++      static signed char max() throw()
++      { return __glibcpp_signed_char_max; }
++
++      static const int digits = __glibcpp_signed_char_digits;
++      static const int digits10 = __glibcpp_signed_char_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static signed char epsilon() throw()
++      { return 0; }
++      static signed char round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static signed char infinity() throw()
++      { return static_cast<signed char>(0); }
++      static signed char quiet_NaN() throw()
++      { return static_cast<signed char>(0); }
++      static signed char signaling_NaN() throw()
++      { return static_cast<signed char>(0); }
++      static signed char denorm_min() throw()
++      { return static_cast<signed char>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_signed_char_is_modulo;
++
++      static const bool traps = __glibcpp_signed_char_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_signed_char_min
++#undef __glibcpp_signed_char_max
++#undef __glibcpp_signed_char_digits
++#undef __glibcpp_signed_char_digits10
++#undef __glibcpp_signed_char_is_modulo  
++#undef __glibcpp_signed_char_traps  
++
++  template<>
++    struct numeric_limits<unsigned char>
++    {
++      static const bool is_specialized = true;
++
++      static unsigned char min() throw()
++      { return 0; }
++      static unsigned char max() throw()
++      { return __glibcpp_unsigned_char_max; }
++
++      static const int digits = __glibcpp_unsigned_char_digits;
++      static const int digits10 = __glibcpp_unsigned_char_digits10;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static unsigned char epsilon() throw()
++      { return 0; }
++      static unsigned char round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static unsigned char infinity() throw()
++      { return static_cast<unsigned char>(0); }
++      static unsigned char quiet_NaN() throw()
++      { return static_cast<unsigned char>(0); }
++      static unsigned char signaling_NaN() throw()
++      { return static_cast<unsigned char>(0); }
++      static unsigned char denorm_min() throw()
++      { return static_cast<unsigned char>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = true;
++
++      static const bool traps = __glibcpp_unsigned_char_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_unsigned_char_max
++#undef __glibcpp_unsigned_char_digits
++#undef __glibcpp_unsigned_char_digits10
++#undef __glibcpp_unsigned_char_traps  
++
++  template<>
++    struct numeric_limits<wchar_t>
++    {
++      static const bool is_specialized = true;
++
++      static wchar_t min() throw()
++      { return __glibcpp_wchar_t_min; }
++      static wchar_t max() throw()
++      { return __glibcpp_wchar_t_max; }
++
++      static const int digits = __glibcpp_wchar_t_digits;
++      static const int digits10 = __glibcpp_wchar_t_digits10;
++      static const bool is_signed = __glibcpp_wchar_t_is_signed;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static wchar_t epsilon() throw()
++      { return 0; }
++      static wchar_t round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static wchar_t infinity() throw()
++      { return wchar_t(); }
++      static wchar_t quiet_NaN() throw()
++      { return wchar_t(); }
++      static wchar_t signaling_NaN() throw()
++      { return wchar_t(); }
++      static wchar_t denorm_min() throw()
++      { return wchar_t(); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_wchar_t_is_modulo;
++
++      static const bool traps = __glibcpp_wchar_t_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_wchar_t_min
++#undef __glibcpp_wchar_t_max
++#undef __glibcpp_wchar_t_digits
++#undef __glibcpp_wchar_t_digits10  
++#undef __glibcpp_wchar_t_is_signed
++#undef __glibcpp_wchar_t_is_modulo
++#undef __glibcpp_wchar_t_traps  
++  
++  template<>
++    struct numeric_limits<short>
++    {
++      static const bool is_specialized = true;
++
++      static short min() throw()
++      { return __glibcpp_signed_short_min; }
++      static short max() throw()
++      { return __glibcpp_signed_short_max; }
++
++      static const int digits = __glibcpp_signed_short_digits;
++      static const int digits10 = __glibcpp_signed_short_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static short epsilon() throw()
++      { return 0; }
++      static short round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static short infinity() throw()
++      { return short(); }
++      static short quiet_NaN() throw()
++      { return short(); }
++      static short signaling_NaN() throw()
++      { return short(); }
++      static short denorm_min() throw()
++      { return short(); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_signed_short_is_modulo;
++
++      static const bool traps = __glibcpp_signed_short_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_signed_short_min
++#undef __glibcpp_signed_short_max
++#undef __glibcpp_signed_short_digits
++#undef __glibcpp_signed_short_digits10
++#undef __glibcpp_signed_short_is_modulo
++#undef __glibcpp_signed_short_traps  
++  
++  template<>
++    struct numeric_limits<unsigned short>
++    {
++      static const bool is_specialized = true;
++
++      static unsigned short min() throw()
++      { return 0; }
++      static unsigned short max() throw()
++      { return __glibcpp_unsigned_short_max; }
++
++      static const int digits = __glibcpp_unsigned_short_digits;
++      static const int digits10 = __glibcpp_unsigned_short_digits10;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static unsigned short epsilon() throw()
++      { return 0; }
++      static unsigned short round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static unsigned short infinity() throw()
++      { return static_cast<unsigned short>(0); }
++      static unsigned short quiet_NaN() throw()
++      { return static_cast<unsigned short>(0); }
++      static unsigned short signaling_NaN() throw()
++      { return static_cast<unsigned short>(0); }
++      static unsigned short denorm_min() throw()
++      { return static_cast<unsigned short>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = true;
++
++      static const bool traps = __glibcpp_unsigned_short_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_unsigned_short_max
++#undef __glibcpp_unsigned_short_digits
++#undef __glibcpp_unsigned_short_digits10
++#undef __glibcpp_unsigned_short_traps  
++  
++  template<>
++    struct numeric_limits<int>
++    {
++      static const bool is_specialized = true;
++
++      static int min() throw()
++      { return __glibcpp_signed_int_min; }
++      static int max() throw()
++      { return __glibcpp_signed_int_max; }
++
++      static const int digits = __glibcpp_signed_int_digits;
++      static const int digits10 = __glibcpp_signed_int_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static int epsilon() throw()
++      { return 0; }
++      static int round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static int infinity() throw()
++      { return static_cast<int>(0); }
++      static int quiet_NaN() throw()
++      { return static_cast<int>(0); }
++      static int signaling_NaN() throw()
++      { return static_cast<int>(0); }
++      static int denorm_min() throw()
++      { return static_cast<int>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_signed_int_is_modulo;
++
++      static const bool traps = __glibcpp_signed_int_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_signed_int_min
++#undef __glibcpp_signed_int_max
++#undef __glibcpp_signed_int_digits
++#undef __glibcpp_signed_int_digits10
++#undef __glibcpp_signed_int_is_modulo
++#undef __glibcpp_signed_int_traps  
++  
++  template<>
++    struct numeric_limits<unsigned int>
++    {
++      static const bool is_specialized = true;
++
++      static unsigned int min() throw()
++      { return 0; }
++          static unsigned int max() throw()
++      { return __glibcpp_unsigned_int_max; }
++
++      static const int digits = __glibcpp_unsigned_int_digits;
++      static const int digits10 = __glibcpp_unsigned_int_digits10;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static unsigned int epsilon() throw()
++      { return 0; }
++      static unsigned int round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static unsigned int infinity() throw()
++      { return static_cast<unsigned int>(0); }
++      static unsigned int quiet_NaN() throw()
++      { return static_cast<unsigned int>(0); }
++      static unsigned int signaling_NaN() throw()
++      { return static_cast<unsigned int>(0); }
++      static unsigned int denorm_min() throw()
++      { return static_cast<unsigned int>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = true;
++
++      static const bool traps = __glibcpp_unsigned_int_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_unsigned_int_max
++#undef __glibcpp_unsigned_int_digits
++#undef __glibcpp_unsigned_int_digits10
++#undef __glibcpp_unsigned_int_traps  
++
++  template<>
++    struct numeric_limits<long>
++    {
++      static const bool is_specialized = true;
++
++      static long min() throw()
++      { return __glibcpp_signed_long_min; }
++      static long max() throw()
++      { return __glibcpp_signed_long_max; }
++
++      static const int digits = __glibcpp_signed_long_digits;
++      static const int digits10 = __glibcpp_signed_long_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static long epsilon() throw()
++      { return 0; }
++      static long round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static long infinity() throw()
++      { return static_cast<long>(0); }
++      static long quiet_NaN() throw()
++      { return static_cast<long>(0); }
++      static long signaling_NaN() throw()
++      { return static_cast<long>(0); }
++      static long denorm_min() throw()
++      { return static_cast<long>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_signed_long_is_modulo;
++
++      static const bool traps = __glibcpp_signed_long_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_signed_long_min
++#undef __glibcpp_signed_long_max
++#undef __glibcpp_signed_long_digits
++#undef __glibcpp_signed_long_digits10
++#undef __glibcpp_signed_long_is_modulo
++#undef __glibcpp_signed_long_traps  
++  
++  template<>
++    struct numeric_limits<unsigned long>
++    {
++      static const bool is_specialized = true;
++
++      static unsigned long min() throw()
++      { return 0; }
++      static unsigned long max() throw()
++      { return __glibcpp_unsigned_long_max; }
++
++      static const int digits = __glibcpp_unsigned_long_digits;
++      static const int digits10 = __glibcpp_unsigned_long_digits10;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static unsigned long epsilon() throw()
++      { return 0; }
++      static unsigned long round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static unsigned long infinity() throw()
++      { return static_cast<unsigned long>(0); }
++      static unsigned long quiet_NaN() throw()
++      { return static_cast<unsigned long>(0); }
++      static unsigned long signaling_NaN() throw()
++      { return static_cast<unsigned long>(0); }
++      static unsigned long denorm_min() throw()
++      { return static_cast<unsigned long>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = true;
++
++      static const bool traps = __glibcpp_unsigned_long_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_unsigned_long_max
++#undef __glibcpp_unsigned_long_digits
++#undef __glibcpp_unsigned_long_digits10
++#undef __glibcpp_unsigned_long_traps  
++
++  template<>
++    struct numeric_limits<long long>
++    {
++      static const bool is_specialized = true;
++      
++      static long long min() throw()
++      { return __glibcpp_signed_long_long_min; }
++      static long long max() throw()
++      { return __glibcpp_signed_long_long_max; }
++      
++      static const int digits = __glibcpp_signed_long_long_digits;
++      static const int digits10 = __glibcpp_signed_long_long_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static long long epsilon() throw()
++      { return 0; }
++      static long long round_error() throw()
++      { return 0; }
++      
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++      
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++      
++      static long long infinity() throw()
++      { return static_cast<long long>(0); }
++      static long long quiet_NaN() throw()
++      { return static_cast<long long>(0); }
++      static long long signaling_NaN() throw()
++      { return static_cast<long long>(0); }
++      static long long denorm_min() throw()
++      { return static_cast<long long>(0); }
++      
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = __glibcpp_signed_long_long_is_modulo;
++
++      static const bool traps = __glibcpp_signed_long_long_traps;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_signed_long_long_min
++#undef __glibcpp_signed_long_long_max
++#undef __glibcpp_signed_long_long_digits
++#undef __glibcpp_signed_long_long_digits10
++#undef __glibcpp_signed_long_long_is_modulo
++#undef __glibcpp_signed_long_long_traps  
++  
++  template<>
++    struct numeric_limits<unsigned long long>
++    {
++      static const bool is_specialized = true;
++
++      static unsigned long long min() throw()
++      { return 0; }
++      static unsigned long long max() throw()
++      { return __glibcpp_unsigned_long_long_max; }
++
++      static const int digits = __glibcpp_unsigned_long_long_digits;
++      static const int digits10 = __glibcpp_unsigned_long_long_digits10;
++      static const bool is_signed = false;
++      static const bool is_integer = true;
++      static const bool is_exact = true;
++      static const int radix = 2;
++      static unsigned long long epsilon() throw()
++      { return 0; }
++      static unsigned long long round_error() throw()
++      { return 0; }
++
++      static const int min_exponent = 0;
++      static const int min_exponent10 = 0;
++      static const int max_exponent = 0;
++      static const int max_exponent10 = 0;
++
++      static const bool has_infinity = false;
++      static const bool has_quiet_NaN = false;
++      static const bool has_signaling_NaN = false;
++      static const float_denorm_style has_denorm = denorm_absent;
++      static const bool has_denorm_loss = false;
++
++      static unsigned long long infinity() throw()
++      { return static_cast<unsigned long long>(0); }
++      static unsigned long long quiet_NaN() throw()
++      { return static_cast<unsigned long long>(0); }
++      static unsigned long long signaling_NaN() throw()
++      { return static_cast<unsigned long long>(0); }
++      static unsigned long long denorm_min() throw()
++      { return static_cast<unsigned long long>(0); }
++
++      static const bool is_iec559 = false;
++      static const bool is_bounded = true;
++      static const bool is_modulo = true;
++
++      static const bool traps = true;
++      static const bool tinyness_before = false;
++      static const float_round_style round_style = round_toward_zero;
++    };
++
++#undef __glibcpp_unsigned_long_long_max
++#undef __glibcpp_unsigned_long_long_digits
++#undef __glibcpp_unsigned_long_long_digits10
++#undef __glibcpp_unsigned_long_long_traps  
++
++  template<>
++    struct numeric_limits<float>
++    {
++      static const bool is_specialized = true;
++
++      static float min() throw()
++      { return __glibcpp_float_min; }
++      static float max() throw()
++      { return __glibcpp_float_max; }
++
++      static const int digits = __glibcpp_float_digits;
++      static const int digits10 = __glibcpp_float_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = false;
++      static const bool is_exact = false;
++      static const int radix = __glibcpp_float_radix;
++      static float epsilon() throw()
++      { return __glibcpp_float_epsilon; }
++      static float round_error() throw()
++      { return __glibcpp_float_round_error; }
++
++      static const int min_exponent = __glibcpp_float_min_exponent;
++      static const int min_exponent10 = __glibcpp_float_min_exponent10;
++      static const int max_exponent = __glibcpp_float_max_exponent;
++      static const int max_exponent10 = __glibcpp_float_max_exponent10;
++
++      static const bool has_infinity = __glibcpp_float_has_infinity;
++      static const bool has_quiet_NaN = __glibcpp_float_has_quiet_NaN;
++      static const bool has_signaling_NaN = __glibcpp_float_has_signaling_NaN;
++      static const float_denorm_style has_denorm = __glibcpp_float_has_denorm;
++      static const bool has_denorm_loss = __glibcpp_float_has_denorm_loss;
++
++      static float infinity() throw()
++      { return __glibcpp_float_infinity; }
++      static float quiet_NaN() throw()
++      { return __glibcpp_float_quiet_NaN; }
++      static float signaling_NaN() throw()
++      { return __glibcpp_float_signaling_NaN; }
++      static float denorm_min() throw()
++      { return __glibcpp_float_denorm_min; }
++
++      static const bool is_iec559 = __glibcpp_float_is_iec559;
++      static const bool is_bounded = __glibcpp_float_is_bounded;
++      static const bool is_modulo = __glibcpp_float_is_modulo;
++
++      static const bool traps = __glibcpp_float_traps;
++      static const bool tinyness_before = __glibcpp_float_tinyness_before;
++      static const float_round_style round_style = __glibcpp_float_round_style;
++    };
++
++#undef __glibcpp_float_min
++#undef __glibcpp_float_max
++#undef __glibcpp_float_digits
++#undef __glibcpp_float_digits10
++#undef __glibcpp_float_radix
++#undef __glibcpp_float_round_error
++#undef __glibcpp_float_min_exponent
++#undef __glibcpp_float_min_exponent10
++#undef __glibcpp_float_max_exponent
++#undef __glibcpp_float_max_exponent10
++#undef __glibcpp_float_has_infinity
++#undef __glibcpp_float_has_quiet_NaN
++#undef __glibcpp_float_has_signaling_NaN
++#undef __glibcpp_float_has_denorm
++#undef __glibcpp_float_has_denorm_loss
++#undef __glibcpp_float_infinity
++#undef __glibcpp_float_quiet_NaN
++#undef __glibcpp_float_signaling_NaN
++#undef __glibcpp_float_denorm_min
++#undef __glibcpp_float_is_iec559
++#undef __glibcpp_float_is_bounded
++#undef __glibcpp_float_is_modulo
++#undef __glibcpp_float_traps
++#undef __glibcpp_float_tinyness_before
++#undef __glibcpp_float_round_style  
++
++  template<>
++    struct numeric_limits<double>
++    {
++      static const bool is_specialized = true;
++
++      static double min() throw()
++      { return __glibcpp_double_min; }
++      static double max() throw()
++      { return __glibcpp_double_max; }
++
++      static const int digits = __glibcpp_double_digits;
++      static const int digits10 = __glibcpp_double_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = false;
++      static const bool is_exact = false;
++      static const int radix = __glibcpp_double_radix;
++      static double epsilon() throw()
++      { return __glibcpp_double_epsilon; }
++      static double round_error() throw()
++      { return __glibcpp_double_round_error; }
++
++      static const int min_exponent = __glibcpp_double_min_exponent;
++      static const int min_exponent10 = __glibcpp_double_min_exponent10;
++      static const int max_exponent = __glibcpp_double_max_exponent;
++      static const int max_exponent10 = __glibcpp_double_max_exponent10;
++
++      static const bool has_infinity = __glibcpp_double_has_infinity;
++      static const bool has_quiet_NaN = __glibcpp_double_has_quiet_NaN;
++      static const bool has_signaling_NaN = __glibcpp_double_has_signaling_NaN;
++      static const float_denorm_style has_denorm =
++              __glibcpp_double_has_denorm;
++      static const bool has_denorm_loss = __glibcpp_double_has_denorm_loss;
++
++      static double infinity() throw()
++      { return __glibcpp_double_infinity; }
++      static double quiet_NaN() throw()
++      { return __glibcpp_double_quiet_NaN; }
++      static double signaling_NaN() throw()
++      { return __glibcpp_double_signaling_NaN; }
++      static double denorm_min() throw()
++      { return __glibcpp_double_denorm_min; }
++
++      static const bool is_iec559 = __glibcpp_double_is_iec559;
++      static const bool is_bounded = __glibcpp_double_is_bounded;
++      static const bool is_modulo = __glibcpp_double_is_modulo;
++
++      static const bool traps = __glibcpp_double_traps;
++      static const bool tinyness_before = __glibcpp_double_tinyness_before;
++      static const float_round_style round_style =
++              __glibcpp_double_round_style;
++    };
++
++#undef __glibcpp_double_min
++#undef __glibcpp_double_max
++#undef __glibcpp_double_digits
++#undef __glibcpp_double_digits10
++#undef __glibcpp_double_radix
++#undef __glibcpp_double_round_error
++#undef __glibcpp_double_min_exponent
++#undef __glibcpp_double_min_exponent10
++#undef __glibcpp_double_max_exponent
++#undef __glibcpp_double_max_exponent10
++#undef __glibcpp_double_has_infinity
++#undef __glibcpp_double_has_quiet_NaN
++#undef __glibcpp_double_has_signaling_NaN
++#undef __glibcpp_double_has_denorm
++#undef __glibcpp_double_has_denorm_loss
++#undef __glibcpp_double_infinity
++#undef __glibcpp_double_quiet_NaN
++#undef __glibcpp_double_signaling_NaN
++#undef __glibcpp_double_denorm_min
++#undef __glibcpp_double_is_iec559
++#undef __glibcpp_double_is_bounded
++#undef __glibcpp_double_is_modulo
++#undef __glibcpp_double_traps
++#undef __glibcpp_double_tinyness_before
++#undef __glibcpp_double_round_style  
++  
++  
++  template<>
++    struct numeric_limits<long double>
++    {
++      static const bool is_specialized = true;
++
++      static long double min() throw()
++      { return __glibcpp_long_double_min; }
++      static long double max() throw()
++      { return __glibcpp_long_double_max; }
++
++      static const int digits = __glibcpp_long_double_digits;
++      static const int digits10 = __glibcpp_long_double_digits10;
++      static const bool is_signed = true;
++      static const bool is_integer = false;
++      static const bool is_exact = false;
++      static const int radix = __glibcpp_long_double_radix;
++      static long double epsilon() throw()
++      { return __glibcpp_long_double_epsilon; }
++      static long double round_error() throw()
++      { return __glibcpp_long_double_round_error; }
++
++      static const int min_exponent = __glibcpp_long_double_min_exponent;
++      static const int min_exponent10 = __glibcpp_long_double_min_exponent10;
++      static const int max_exponent = __glibcpp_long_double_max_exponent;
++      static const int max_exponent10 = __glibcpp_long_double_max_exponent10;
++
++      static const bool has_infinity = __glibcpp_long_double_has_infinity;
++      static const bool has_quiet_NaN = __glibcpp_long_double_has_quiet_NaN;
++      static const bool has_signaling_NaN =
++                __glibcpp_long_double_has_signaling_NaN;
++      static const float_denorm_style has_denorm =
++                __glibcpp_long_double_has_denorm;
++      static const bool has_denorm_loss =
++                __glibcpp_long_double_has_denorm_loss;
++
++      static long double infinity() throw()
++      { return __glibcpp_long_double_infinity; }
++      static long double quiet_NaN() throw()
++      { return __glibcpp_long_double_quiet_NaN; }
++      static long double signaling_NaN() throw()
++      { return __glibcpp_long_double_signaling_NaN; }
++      static long double denorm_min() throw()
++      { return __glibcpp_long_double_denorm_min; }
++
++      static const bool is_iec559 = __glibcpp_long_double_is_iec559;
++      static const bool is_bounded = __glibcpp_long_double_is_bounded;
++      static const bool is_modulo = __glibcpp_long_double_is_modulo;
++
++      static const bool traps = __glibcpp_long_double_traps; 
++      static const bool tinyness_before = __glibcpp_long_double_tinyness_before;
++      static const float_round_style round_style = 
++        __glibcpp_long_double_round_style;
++    };
++
++#undef __glibcpp_long_double_min
++#undef __glibcpp_long_double_max
++#undef __glibcpp_long_double_digits
++#undef __glibcpp_long_double_digits10
++#undef __glibcpp_long_double_radix
++#undef __glibcpp_long_double_round_error
++#undef __glibcpp_long_double_min_exponent
++#undef __glibcpp_long_double_min_exponent10
++#undef __glibcpp_long_double_max_exponent
++#undef __glibcpp_long_double_max_exponent10
++#undef __glibcpp_long_double_has_infinity
++#undef __glibcpp_long_double_has_quiet_NaN
++#undef __glibcpp_long_double_has_signaling_NaN
++#undef __glibcpp_long_double_has_denorm
++#undef __glibcpp_long_double_has_denorm_loss
++#undef __glibcpp_long_double_infinity
++#undef __glibcpp_long_double_quiet_NaN
++#undef __glibcpp_long_double_signaling_NaN
++#undef __glibcpp_long_double_denorm_min
++#undef __glibcpp_long_double_is_iec559
++#undef __glibcpp_long_double_is_bounded
++#undef __glibcpp_long_double_is_modulo
++#undef __glibcpp_long_double_traps
++#undef __glibcpp_long_double_tinyness_before
++#undef __glibcpp_long_double_round_style  
++  
++} // namespace std
++
++#else
++
+ #include <bits/c++config.h>
+ 
+ //
+@@ -1050,4 +2942,6 @@ namespace std
+ #undef __glibcpp_digits
+ #undef __glibcpp_digits10
+ 
++#endif // GCC 3.3+
++
+ #endif // _CPP_NUMERIC_LIMITS
+--- libstdc++33-v3/include/Makefile.am.jj	2003-08-12 10:15:25.000000000 -0400
++++ libstdc++33-v3/include/Makefile.am	2004-10-14 12:28:42.000000000 -0400
+@@ -316,7 +316,8 @@ target_headers = \
+ 	${target_srcdir}/ctype_inline.h \
+ 	${target_srcdir}/ctype_noninline.h \
+ 	${target_srcdir}/os_defines.h \
+-	${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h 
++	${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h  \
++	${glibcpp_srcdir}/@CPU_LIMITS_INC_SRCDIR@/cpu_limits.h
+ 
+ # Non-installed target_header files.
+ target_headers_noinst = \
+--- libstdc++33-v3/include/Makefile.in.jj	2003-08-12 10:15:25.000000000 -0400
++++ libstdc++33-v3/include/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+@@ -429,7 +430,8 @@ target_headers = \
+ 	${target_srcdir}/ctype_inline.h \
+ 	${target_srcdir}/ctype_noninline.h \
+ 	${target_srcdir}/os_defines.h \
+-	${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h 
++	${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h \
++	${glibcpp_srcdir}/@CPU_LIMITS_INC_SRCDIR@/cpu_limits.h 
+ 
+ 
+ # Non-installed target_header files.
+--- libstdc++33-v3/po/Makefile.in.jj	2003-03-17 14:07:39.000000000 -0500
++++ libstdc++33-v3/po/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/testsuite/Makefile.in.jj	2003-12-19 04:18:29.000000000 -0500
++++ libstdc++33-v3/testsuite/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/Makefile.in.jj	2003-07-09 05:08:57.000000000 -0400
++++ libstdc++33-v3/Makefile.in	2004-10-14 12:28:01.000000000 -0400
+@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@
+ CMONEY_CC = @CMONEY_CC@
+ CNUMERIC_CC = @CNUMERIC_CC@
+ CPP = @CPP@
++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@
+ CSTDIO_H = @CSTDIO_H@
+ CTIME_CC = @CTIME_CC@
+ CTIME_H = @CTIME_H@
+--- libstdc++33-v3/configure.jj	2004-08-18 03:44:22.000000000 -0400
++++ libstdc++33-v3/configure	2004-10-14 12:35:55.000000000 -0400
+@@ -23989,6 +23989,7 @@ fi
+ # uses it, and it only gets used in this file.)
+ OS_INC_SRCDIR=config/${os_include_dir}
+ ATOMICITY_INC_SRCDIR=config/${ATOMICITYH}
++CPU_LIMITS_INC_SRCDIR=config/${CPULIMITSH}
+ 
+ 
+ 
+@@ -24442,6 +24443,7 @@ s%@GLIBCPP_TEST_ABI_TRUE@%$GLIBCPP_TEST_
+ s%@GLIBCPP_TEST_ABI_FALSE@%$GLIBCPP_TEST_ABI_FALSE%g
+ s%@OS_INC_SRCDIR@%$OS_INC_SRCDIR%g
+ s%@ATOMICITY_INC_SRCDIR@%$ATOMICITY_INC_SRCDIR%g
++s%@CPU_LIMITS_INC_SRCDIR@%$CPU_LIMITS_INC_SRCDIR%g
+ s%@GLIBCPP_IS_CROSS_COMPILING@%$GLIBCPP_IS_CROSS_COMPILING%g
+ s%@CANADIAN_TRUE@%$CANADIAN_TRUE%g
+ s%@CANADIAN_FALSE@%$CANADIAN_FALSE%g
+--- libstdc++33-v3/configure.in.jj	2004-08-18 03:44:22.000000000 -0400
++++ libstdc++33-v3/configure.in	2004-10-14 12:35:27.000000000 -0400
+@@ -451,8 +451,10 @@ GLIBCPP_CONFIGURE_TESTSUITE
+ # uses it, and it only gets used in this file.)
+ OS_INC_SRCDIR=config/${os_include_dir}
+ ATOMICITY_INC_SRCDIR=config/${ATOMICITYH}
++CPU_LIMITS_INC_SRCDIR=config/${CPULIMITSH}
+ AC_SUBST(OS_INC_SRCDIR)
+ AC_SUBST(ATOMICITY_INC_SRCDIR)
++AC_SUBST(CPU_LIMITS_INC_SRCDIR)
+ 
+ # Set up cross-compile flags
+ AC_SUBST(GLIBCPP_IS_CROSS_COMPILING)  dnl Unused so far.
+--- libstdc++33-v3/configure.target.jj	2003-10-23 11:45:20.000000000 -0400
++++ libstdc++33-v3/configure.target	2004-10-14 12:34:27.000000000 -0400
+@@ -32,6 +32,8 @@
+ #
+ #   ATOMICITYH             location of atomicity.h,
+ #                          defaults to cpu_include_dir
++#   CPULIMITSH             location of cpu_limits.h,
++#                          defaults to cpu_include_dir
+ #
+ # It possibly modifies the following variables:
+ #
+@@ -198,3 +200,45 @@ case "${target}" in
+     abi_baseline_pair="sparc-freebsd5"
+     ;;
+ esac
++
++# Set CPULIMITSH to the directory where the configuration-dependent
++# cpu_limits.h can be found.
++# THIS TABLE IS SORTED.  KEEP IT THAT WAY.
++case "${target}" in
++   *-*-hpux*)
++     CPULIMITSH=os/hpux
++     ;;
++   alpha*-*-*osf5*)
++     CPULIMITSH=os/osf/osf5.0
++     ;;
++   alpha*-*-*)
++     CPULIMITSH=cpu/alpha
++     ;;
++   cris-*-*)
++     CPULIMITSH=cpu/cris
++     ;;
++   ia64-*-*)
++     CPULIMITSH=cpu/ia64
++     ;;
++   i?86-*-*)
++     CPULIMITSH=cpu/i386
++     ;;
++   m68k-*-* | m680[246]0-*-*)
++     CPULIMITSH=cpu/m68k
++     ;;
++   mmix-*-*)
++     CPULIMITSH=cpu/mmix
++     ;;
++   powerpc*-*-* | rs6000-*-*)
++     CPULIMITSH=cpu/powerpc
++     ;;
++   s390-*-* | s390x-*-*)
++     CPULIMITSH=cpu/s390
++     ;;
++   x86_64-*-*)
++     CPULIMITSH=cpu/x86-64
++     ;;
++   *)
++     CPULIMITSH=cpu/generic
++     ;;
++esac
diff --git a/SOURCES/compat-libstdc++33-symver.patch b/SOURCES/compat-libstdc++33-symver.patch
new file mode 100644
index 0000000..0112c61
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-symver.patch
@@ -0,0 +1,98 @@
+2004-07-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* acinclude.m4 (glibcpp_shared_libgcc): Correct
+	glibcpp_shared_libgcc test for multilibs.
+	* aclocal.m4: Rebuilt.
+	* configure: Rebuilt.
+
+--- libstdc++33-v3/acinclude.m4.jj	2004-06-24 18:06:53.000000000 +0200
++++ libstdc++33-v3/acinclude.m4	2004-08-18 10:28:50.333384148 +0200
+@@ -2294,6 +2294,23 @@ if test $enable_symvers != no; then
+   CFLAGS=' -lgcc_s'
+   AC_TRY_LINK(, [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no)
+   CFLAGS="$ac_save_CFLAGS"
++  if test $glibcpp_shared_libgcc = no; then
++    cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++changequote(,)dnl
++    glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			     -shared -shared-libgcc -o conftest.so \
++			     conftest.c -v 2>&1 >/dev/null \
++			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++changequote([,])dnl
++    rm -f conftest.c conftest.so
++    if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++      CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++      AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes)
++      CFLAGS="$ac_save_CFLAGS"
++    fi
++  fi
+   AC_MSG_RESULT($glibcpp_shared_libgcc)
+ fi
+ 
+--- libstdc++33-v3/aclocal.m4.jj	2004-06-24 18:06:53.000000000 +0200
++++ libstdc++33-v3/aclocal.m4	2004-08-18 10:30:06.361019696 +0200
+@@ -2306,6 +2306,23 @@ if test $enable_symvers != no; then
+   CFLAGS=' -lgcc_s'
+   AC_TRY_LINK(, [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no)
+   CFLAGS="$ac_save_CFLAGS"
++  if test $glibcpp_shared_libgcc = no; then
++    cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++changequote(,)dnl
++    glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			     -shared -shared-libgcc -o conftest.so \
++			     conftest.c -v 2>&1 >/dev/null \
++			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++changequote([,])dnl
++    rm -f conftest.c conftest.so
++    if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++      CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++      AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes)
++      CFLAGS="$ac_save_CFLAGS"
++    fi
++  fi
+   AC_MSG_RESULT($glibcpp_shared_libgcc)
+ fi
+ 
+--- libstdc++33-v3/configure.jj	2004-08-18 09:44:22.000000000 +0200
++++ libstdc++33-v3/configure	2004-08-18 10:31:41.502299528 +0200
+@@ -23563,6 +23563,36 @@ else
+ fi
+ rm -f conftest*
+   CFLAGS="$ac_save_CFLAGS"
++  if test $glibcpp_shared_libgcc = no; then
++    cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++    glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			     -shared -shared-libgcc -o conftest.so \
++			     conftest.c -v 2>&1 >/dev/null \
++			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++    rm -f conftest.c conftest.so
++    if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++      CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++      cat > conftest.$ac_ext <<EOF
++#line 23579 "configure"
++#include "confdefs.h"
++
++int main() {
++return 0;
++; return 0; }
++EOF
++if { (eval echo configure:23586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++  rm -rf conftest*
++  glibcpp_shared_libgcc=yes
++else
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++fi
++rm -f conftest*
++      CFLAGS="$ac_save_CFLAGS"
++    fi
++  fi
+   echo "$ac_t""$glibcpp_shared_libgcc" 1>&6
+ fi
+ 
diff --git a/SOURCES/compat-libstdc++33-v3.patch b/SOURCES/compat-libstdc++33-v3.patch
new file mode 100644
index 0000000..57552ad
--- /dev/null
+++ b/SOURCES/compat-libstdc++33-v3.patch
@@ -0,0 +1,204 @@
+--- Makefile.in	2003-02-03 23:58:12.000000000 +0100
++++ Makefile.in	2004-10-14 17:42:45.175884656 +0200
+@@ -785,6 +785,7 @@ INSTALL_X11_MODULES = \
+ # using $(TARGET_FLAGS_TO_PASS).
+ ALL_TARGET_MODULES = \
+ 	all-target-libstdc++-v3 \
++	all-target-libstdc++33-v3 \
+ 	all-target-librx \
+ 	all-target-newlib \
+ 	all-target-libf2c \
+@@ -808,6 +809,7 @@ ALL_TARGET_MODULES = \
+ # are compiled using the target tools.
+ CONFIGURE_TARGET_MODULES = \
+ 	configure-target-libstdc++-v3 \
++	configure-target-libstdc++33-v3 \
+ 	configure-target-librx \
+ 	configure-target-newlib \
+ 	configure-target-libf2c \
+@@ -831,6 +833,7 @@ CONFIGURE_TARGET_MODULES = \
+ # compiled using $(TARGET_FLAGS_TO_PASS).
+ CHECK_TARGET_MODULES = \
+ 	check-target-libstdc++-v3 \
++	check-target-libstdc++33-v3 \
+ 	check-target-newlib \
+ 	check-target-libf2c \
+ 	check-target-libobjc \
+@@ -847,6 +850,7 @@ CHECK_TARGET_MODULES = \
+ # compiled using $(TARGET_FLAGS_TO_PASS).
+ INSTALL_TARGET_MODULES = \
+ 	install-target-libstdc++-v3 \
++	install-target-libstdc++33-v3 \
+ 	install-target-newlib \
+ 	install-target-libf2c \
+ 	install-target-libobjc \
+@@ -934,6 +938,7 @@ CLEAN_MODULES = \
+ # All of the target modules that can be cleaned
+ CLEAN_TARGET_MODULES = \
+ 	clean-target-libstdc++-v3 \
++	clean-target-libstdc++33-v3 \
+ 	clean-target-librx \
+ 	clean-target-newlib \
+ 	clean-target-libf2c \
+@@ -1659,6 +1664,7 @@ check-c++:
+ 	  $(SET_LIB_PATH) \
+ 	  (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) check-c++); \
+ 	  $(MAKE) check-target-libstdc++-v3; \
++	  $(MAKE) check-target-libstdc++33-v3; \
+ 	else \
+ 	  true; \
+ 	fi 
+@@ -1703,7 +1709,7 @@ install-dosrel-fake:
+ 
+ ALL_GCC = all-gcc
+ ALL_GCC_C = $(ALL_GCC) all-target-newlib all-target-libgloss
+-ALL_GCC_CXX = $(ALL_GCC_C) all-target-libstdc++-v3
++ALL_GCC_CXX = $(ALL_GCC_C) all-target-libstdc++-v3 all-target-libstdc++33-v3
+ 
+ # This is a list of inter-dependencies among modules.
+ all-apache:
+@@ -1747,7 +1753,7 @@ all-gdb: all-libiberty all-opcodes all-b
+ all-gettext:
+ all-gnuserv:
+ configure-target-gperf: $(ALL_GCC_CXX)
+-all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++-v3
++all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++-v3 all-target-libstdc++33-v3
+ all-gprof: all-libiberty all-bfd all-opcodes all-intl
+ all-grep: all-libiberty
+ all-grez: all-libiberty all-bfd all-opcodes
+@@ -1776,6 +1782,8 @@ configure-target-librx: $(ALL_GCC_C)
+ all-target-librx: configure-target-librx
+ configure-target-libstdc++-v3: $(ALL_GCC_C)
+ all-target-libstdc++-v3: configure-target-libstdc++-v3 all-target-libiberty
++configure-target-libstdc++33-v3: $(ALL_GCC_C)
++all-target-libstdc++33-v3: configure-target-libstdc++33-v3 all-target-libiberty
+ configure-target-libstub: $(ALL_GCC_C)
+ all-target-libstub: configure-target-libstub
+ all-libtool:
+--- configure.in.jj	2002-09-24 09:06:53.000000000 -0400
++++ configure.in	2004-10-14 17:53:05.746097559 -0400
+@@ -50,7 +50,7 @@ fi
+ 
+ libstdcxx_version="target-libstdc++-v3"
+ # Don't use libstdc++-v3's flags to configure/build itself.
+-libstdcxx_flags='`case $$dir in libstdc++-v3 | libjava) ;; *) test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags --build-includes;; esac` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
++libstdcxx_flags='`case $$dir in libstdc++-v3 | libstdc++33-v3 | libjava) ;; *) test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags --build-includes;; esac` `test x"$$dir" = xlibstdc++33-v3 && echo "-L$$r/$(TARGET_SUBDIR)/libstdc++33-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++33-v3/src/.libs" || echo "-L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs"`'
+ 
+ # these tools are built for the host environment
+ # Note, the powerpc-eabi build depends on sim occurring before gdb in order to
+@@ -72,6 +72,7 @@ target_libs="target-libiberty \
+ 		target-newlib \
+ 		target-librx \
+ 		${libstdcxx_version} \
++		target-libstdc++33-v3 \
+ 		target-libf2c \
+ 		${libgcj}
+ 		target-libobjc"
+@@ -884,7 +885,7 @@ case "${target}" in
+   mcore-*-pe*)
+   # The EPOC C++ environment does not support exceptions or rtti,
+   # and so building libstdc++-v3 tends not to always work.
+-    noconfigdirs="$noconfigdirs target-libstdc++-v3"
++    noconfigdirs="$noconfigdirs target-libstdc++-v3 target-libstdc++33-v3"
+     ;;
+   mmix-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+@@ -1557,7 +1558,7 @@ elif test -d ${topsrcdir}/gcc; then
+   # We add -shared-libgcc to CXX_FOR_TARGET whenever we use xgcc instead
+   # of g++ for linking C++ or Java, because g++ has -shared-libgcc by
+   # default whereas gcc does not.
+-  CXX_FOR_TARGET='$$r/gcc/`case $$dir in libstdc++-v3 | libjava) echo xgcc -shared-libgcc ;; *) echo g++ ;; esac` -B$$r/gcc/ -nostdinc++ '$libstdcxx_flags
++  CXX_FOR_TARGET='$$r/gcc/`case $$dir in libstdc++-v3 | libstdc++33-v3 | libjava) echo xgcc -shared-libgcc ;; *) echo g++ ;; esac` -B$$r/gcc/ -nostdinc++ '$libstdcxx_flags
+ elif test "$host" = "$target"; then
+   CXX_FOR_TARGET='$(CXX)'
+ else
+--- libstdc++33-v3/acinclude.m4.jj	2004-10-14 17:08:50.000000000 -0400
++++ libstdc++33-v3/acinclude.m4	2004-10-14 17:08:50.000000000 -0400
+@@ -72,7 +72,7 @@ AC_DEFUN(GLIBCPP_CONFIGURE, [
+   AC_ARG_WITH(cross-host,
+   [  --with-cross-host=HOST  configuring with a cross compiler])
+ 
+-  glibcpp_basedir=$srcdir/$toprel/$1/libstdc++-v3
++  glibcpp_basedir=$srcdir/$toprel/$1/libstdc++33-v3
+   AC_SUBST(glibcpp_basedir)
+ 
+   # Never versions of autoconf add an underscore to these functions.
+--- libstdc++33-v3/aclocal.m4.jj	2004-10-14 17:09:05.000000000 -0400
++++ libstdc++33-v3/aclocal.m4	2004-10-14 17:09:05.000000000 -0400
+@@ -84,7 +84,7 @@ AC_DEFUN(GLIBCPP_CONFIGURE, [
+   AC_ARG_WITH(cross-host,
+   [  --with-cross-host=HOST  configuring with a cross compiler])
+ 
+-  glibcpp_basedir=$srcdir/$toprel/$1/libstdc++-v3
++  glibcpp_basedir=$srcdir/$toprel/$1/libstdc++33-v3
+   AC_SUBST(glibcpp_basedir)
+ 
+   # Never versions of autoconf add an underscore to these functions.
+--- libstdc++33-v3/configure.jj	2004-10-14 17:09:31.000000000 -0400
++++ libstdc++33-v3/configure	2004-10-14 17:09:31.000000000 -0400
+@@ -922,7 +922,7 @@ if test "${with_cross_host+set}" = set; 
+ fi
+ 
+ 
+-  glibcpp_basedir=$srcdir/$toprel/./libstdc++-v3
++  glibcpp_basedir=$srcdir/$toprel/./libstdc++33-v3
+   
+ 
+   # Never versions of autoconf add an underscore to these functions.
+--- libstdc++33-v3/testsuite/18_support/numeric_limits.cc.jj	2002-12-19 06:44:30.000000000 -0500
++++ libstdc++33-v3/testsuite/18_support/numeric_limits.cc	2004-10-15 05:12:43.000000000 -0400
+@@ -260,6 +260,10 @@ bool test03()
+ {
+   bool test = true;
+ 
++#ifndef __CHAR_BIT__
++ #define __CHAR_BIT__ 8
++#endif
++
+   VERIFY( std::numeric_limits<bool>::digits10 == 0 );
+   if (__CHAR_BIT__ == 8)
+     {
+--- libstdc++33-v3/testsuite/lib/libstdc++-v3-dg.exp.jj	2003-12-19 04:18:43.000000000 -0500
++++ libstdc++33-v3/testsuite/lib/libstdc++-v3-dg.exp	2004-10-15 05:04:58.000000000 -0400
+@@ -49,7 +49,7 @@ proc libstdc++-v3-init { args } {
+     global original_ld_library_path
+     global tool_root_dir
+ 
+-    set blddir [lookfor_file [get_multilibs] libstdc++-v3]
++    set blddir [lookfor_file [get_multilibs] libstdc++33-v3]
+ 
+     # By default, we assume we want to run program images.
+     global dg-do-what-default
+--- libstdc++33-v3/testsuite_flags.in.jj	2003-05-15 18:08:03.000000000 -0400
++++ libstdc++33-v3/testsuite_flags.in	2004-10-15 04:56:36.000000000 -0400
+@@ -43,7 +43,7 @@ case ${query} in
+       echo ${CXX}
+       ;;
+     --build-cxx)
+-      CXX_build="@glibcpp_CXX@ ${PCHFLAGS}"
++      CXX_build=`echo "@glibcpp_CXX@ ${PCHFLAGS}" | sed 's,libstdc++-v3,libstdc++33-v3,g'`
+       CXX=`echo "$CXX_build" | sed 's,gcc/xgcc ,gcc/g++ ,'`
+       echo ${CXX}
+       ;;
+--- libstdc++33-v3/Makefile.am.jj	2003-07-09 05:08:57.000000000 -0400
++++ libstdc++33-v3/Makefile.am	2004-10-15 09:20:31.000000000 -0400
+@@ -136,7 +136,7 @@ AM_MAKEFLAGS = \
+ 	"includedir=$(includedir)" \
+ 	"prefix=$(prefix)" \
+ 	"tooldir=$(tooldir)" \
+-	"gxx_include_dir=$(gxx_include_dir)" \
++	"gxx_include_dir=@gxx_include_dir@" \
+ 	"AR=$(AR)" \
+ 	"AS=$(AS)" \
+ 	"LD=$(LD)" \
+--- libstdc++33-v3/Makefile.in.jj	2004-10-14 12:28:01.000000000 -0400
++++ libstdc++33-v3/Makefile.in	2004-10-15 09:20:55.000000000 -0400
+@@ -195,7 +195,7 @@ AM_MAKEFLAGS = \
+ 	"includedir=$(includedir)" \
+ 	"prefix=$(prefix)" \
+ 	"tooldir=$(tooldir)" \
+-	"gxx_include_dir=$(gxx_include_dir)" \
++	"gxx_include_dir=@gxx_include_dir@" \
+ 	"AR=$(AR)" \
+ 	"AS=$(AS)" \
+ 	"LD=$(LD)" \
diff --git a/SOURCES/dummylib.sh b/SOURCES/dummylib.sh
new file mode 100755
index 0000000..f36c602
--- /dev/null
+++ b/SOURCES/dummylib.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+if [ $# -lt 3 ]; then echo Usage: dummylib.sh orig_lib_path dummy_lib_path mapfile; exit 1; fi
+TMPDIR=`mktemp -d dummylib.sh.XXXXXX` || exit 1
+F=`file -L $1`
+C=
+S=8
+case "$F" in
+  *ELF\ 64-bit*shared\ object*x86-64*) C=-m64;;
+  *ELF\ 32-bit*shared\ object*80?86*) C=-m32; S=4;;
+  *ELF\ 64-bit*shared\ object*PowerPC*) C=-m64;;
+  *ELF\ 32-bit*shared\ object*PowerPC*) C=-m32; S=4;;
+  *ELF\ 64-bit*shared\ object*cisco*) C=-m64;;
+  *ELF\ 32-bit*shared\ object*cisco*) C=-m32; S=4;;
+  *ELF\ 64-bit*shared\ object*IA-64*) C=;;
+  *ELF\ 64-bit*shared\ object*Alpha*) C=;;
+  *ELF\ 64-bit*shared\ object*390*) C=-m64;;
+  *ELF\ 32-bit*shared\ object*390*) C=-m31; S=4;;
+  *ELF\ 64-bit*shared\ object*SPARC*) C=-m64;;
+  *ELF\ 32-bit*shared\ object*SPARC*) C=-m32; S=4;;
+  *ELF\ 64-bit*shared\ object*Alpha*) C=;;
+esac
+readelf -Ws $1 | awk '
+/\.dynsym.* contains/ { start=1 }
+/^$/ { start=0 }
+/  WEAK.*  UND [^@]*$/ { if (start) {
+  print ".data"; print ".weak " $8; print ".balign 8"
+  print ".'$S'byte " $8
+} }
+/  UND / { next }
+/@/ { if (start) {
+  fn=$8
+  intfn="HACK" hack+0
+  hack++
+  if ($4 ~ /FUNC/) { print ".text"; size=16; print ".type " intfn ",@function" }
+  else if ($4 ~ /OBJECT/) { print ".data"; size=$3; print ".type " intfn ",@object" }
+  else if ($4 ~ /NOTYPE/) { print ".data"; size=$3 }
+  else exit(1);
+  print ".globl " intfn
+  if ($5 ~ /WEAK/) { print ".weak " intfn }
+  else if ($5 !~ /GLOBAL/) exit(1);
+  print intfn ": .skip " size
+  print ".size " intfn "," size
+  print ".symver " intfn "," fn
+} }
+' > $TMPDIR/lib.s || exit
+soname=`readelf -Wd $1 | grep SONAME | sed 's/^.*\[//;s/\].*$//'`
+gcc $C -shared -Wl,-soname,$soname,-version-script,$3 \
+    -o $2 $TMPDIR/lib.s -nostdlib
+strip $2
+rm -rf $TMPDIR
diff --git a/SOURCES/gcc32-CVE-2006-3619.patch b/SOURCES/gcc32-CVE-2006-3619.patch
new file mode 100644
index 0000000..87e910e
--- /dev/null
+++ b/SOURCES/gcc32-CVE-2006-3619.patch
@@ -0,0 +1,31 @@
+2006-07-17  Richard Guenther  <rguenther@suse.de>
+
+	* jartool.c (extract_jar): Do not allow directory traversal
+	to parents of the extraction root.
+
+--- fastjar/jartool.c.jj	2006-07-11 10:53:39.000000000 +0200
++++ fastjar/jartool.c	2006-07-18 13:49:39.000000000 +0200
+@@ -1736,6 +1736,7 @@ int extract_jar(int fd, char **files, in
+       const ub1 *start = filename;
+       char *tmp_buff;
+       struct stat sbuf;
++      int depth = 0;
+ 
+       tmp_buff = malloc(sizeof(char) * strlen((const char *)filename));
+ 
+@@ -1756,7 +1757,14 @@ int extract_jar(int fd, char **files, in
+ #ifdef DEBUG    
+         printf("checking the existance of %s\n", tmp_buff);
+ #endif
+-
++	if(strcmp(tmp_buff, "..") == 0){
++	  --depth;
++	  if (depth < 0){
++	    fprintf(stderr, "Traversal to parent directories during unpacking!\n");
++	    exit(1);
++	  }
++	} else if (strcmp(tmp_buff, ".") != 0)
++	  ++depth;
+         if(stat(tmp_buff, &sbuf) < 0){
+           if(errno != ENOENT){
+             perror("stat");
diff --git a/SOURCES/gcc32-Winline-doc.patch b/SOURCES/gcc32-Winline-doc.patch
new file mode 100644
index 0000000..6c31748
--- /dev/null
+++ b/SOURCES/gcc32-Winline-doc.patch
@@ -0,0 +1,35 @@
+2005-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* doc/invoke.texi (-Winline): Document that GCC 3.2.x only
+	uses this warning for frontends using RTL inliner.
+	* doc/extend.texi (Inline): Don't mention -Winline option.
+
+--- gcc/doc/extend.texi.jj	2003-09-16 16:57:45.000000000 +0200
++++ gcc/doc/extend.texi	2005-01-03 12:26:25.917145090 +0100
+@@ -3396,14 +3396,11 @@ inc (int *a)
+ You can also make all ``simple enough'' functions inline with the option
+ @option{-finline-functions}.
+ 
+-@opindex Winline
+ Note that certain usages in a function definition can make it unsuitable
+ for inline substitution.  Among these usages are: use of varargs, use of
+ alloca, use of variable sized data types (@pxref{Variable Length}),
+ use of computed goto (@pxref{Labels as Values}), use of nonlocal goto,
+-and nested functions (@pxref{Nested Functions}).  Using @option{-Winline}
+-will warn when a function marked @code{inline} could not be substituted,
+-and will give the reason for the failure.
++and nested functions (@pxref{Nested Functions}).
+ 
+ Note that in C and Objective-C, unlike C++, the @code{inline} keyword
+ does not affect the linkage of the function.
+--- gcc/doc/invoke.texi.jj	2004-07-01 12:34:04.000000000 +0200
++++ gcc/doc/invoke.texi	2005-01-03 12:28:05.928165120 +0100
+@@ -2732,6 +2732,8 @@ code is to provide behavior which is sel
+ @item -Winline
+ @opindex Winline
+ Warn if a function can not be inlined and it was declared as inline.
++In GCC 3.2.x, this only works for languages using the RTL inliner,
++such as Java, for C, C++ and Objective-C this option has no effect.
+ 
+ @item -Wlong-long
+ @opindex Wlong-long
diff --git a/SOURCES/gcc32-bison-1.875c.patch b/SOURCES/gcc32-bison-1.875c.patch
new file mode 100644
index 0000000..8e94bac
--- /dev/null
+++ b/SOURCES/gcc32-bison-1.875c.patch
@@ -0,0 +1,61 @@
+--- gcc/cp/parse.y.jj	2003-01-17 12:33:10.000000000 -0500
++++ gcc/cp/parse.y	2004-07-01 09:03:23.000000000 -0400
+@@ -44,6 +44,9 @@ Boston, MA 02111-1307, USA.  */
+ #include "except.h"
+ #include "toplev.h"
+ #include "ggc.h"
++#ifdef __GNUC__
++#define YYMALLOC nonexistent
++#endif
+ 
+ extern struct obstack permanent_obstack;
+ 
+--- gcc/java/parse.y.jj	2004-01-27 10:16:49.000000000 -0500
++++ gcc/java/parse.y	2004-07-01 09:03:53.000000000 -0400
+@@ -65,6 +65,9 @@ definitions and other extensions.  */
+ #include "function.h"
+ #include "except.h"
+ #include "ggc.h"
++#ifdef __GNUC__
++#define YYMALLOC nonexistent
++#endif
+ 
+ #ifndef DIR_SEPARATOR
+ #define DIR_SEPARATOR '/'
+--- gcc/java/parse-scan.y.jj	2001-04-04 18:12:39.000000000 -0400
++++ gcc/java/parse-scan.y	2004-07-01 09:07:17.000000000 -0400
+@@ -43,6 +43,10 @@ definitions and other extensions.  */
+ #include "obstack.h"
+ #include "toplev.h"
+ 
++#ifdef __GNUC__
++#define YYMALLOC nonexistent
++#endif
++
+ extern char *input_filename;
+ extern FILE *finput, *out;
+ 
+--- gcc/tradcif.y.jj	2002-02-04 05:41:44.000000000 -0500
++++ gcc/tradcif.y	2004-07-01 08:55:51.000000000 -0400
+@@ -27,6 +27,9 @@ Foundation, 59 Temple Place - Suite 330,
+ #include "intl.h"
+ #include "tradcpp.h"
+ #include <setjmp.h>
++#ifdef __GNUC__
++#define YYMALLOC nonexistent
++#endif
+ 
+   static int yylex PARAMS ((void));
+   static void yyerror PARAMS ((const char *msgid)) ATTRIBUTE_NORETURN;
+--- gcc/c-parse.in.jj	2003-08-01 19:21:40.000000000 -0400
++++ gcc/c-parse.in	2004-07-01 08:56:33.000000000 -0400
+@@ -47,6 +47,9 @@ end ifc
+ #include "output.h"
+ #include "toplev.h"
+ #include "ggc.h"
++#ifdef __GNUC__
++#define YYMALLOC nonexistent
++#endif
+   
+ #ifdef MULTIBYTE_CHARS
+ #include <locale.h>
diff --git a/SOURCES/gcc32-bison.patch b/SOURCES/gcc32-bison.patch
new file mode 100644
index 0000000..aae49f1
--- /dev/null
+++ b/SOURCES/gcc32-bison.patch
@@ -0,0 +1,73 @@
+--- gcc/c-parse.in.jj	2009-03-09 14:27:38.000000000 +0100
++++ gcc/c-parse.in	2009-03-09 14:33:29.000000000 +0100
+@@ -1713,7 +1713,7 @@ enum_head:
+ 
+ structsp_attr:
+ 	  struct_head identifier '{'
+-		{ $$ = start_struct (RECORD_TYPE, $2);
++		{ $<ttype>$ = start_struct (RECORD_TYPE, $2);
+ 		  /* Start scope of tag before parsing components.  */
+ 		}
+ 	  component_decl_list '}' maybe_attribute 
+@@ -1723,7 +1723,7 @@ structsp_attr:
+ 				      $3, chainon ($1, $5));
+ 		}
+ 	| union_head identifier '{'
+-		{ $$ = start_struct (UNION_TYPE, $2); }
++		{ $<ttype>$ = start_struct (UNION_TYPE, $2); }
+ 	  component_decl_list '}' maybe_attribute
+ 		{ $$ = finish_struct ($<ttype>4, $5, chainon ($1, $7)); }
+ 	| union_head '{' component_decl_list '}' maybe_attribute
+@@ -1731,12 +1731,12 @@ structsp_attr:
+ 				      $3, chainon ($1, $5));
+ 		}
+ 	| enum_head identifier '{'
+-		{ $$ = start_enum ($2); }
++		{ $<ttype>$ = start_enum ($2); }
+ 	  enumlist maybecomma_warn '}' maybe_attribute
+ 		{ $$ = finish_enum ($<ttype>4, nreverse ($5),
+ 				    chainon ($1, $8)); }
+ 	| enum_head '{'
+-		{ $$ = start_enum (NULL_TREE); }
++		{ $<ttype>$ = start_enum (NULL_TREE); }
+ 	  enumlist maybecomma_warn '}' maybe_attribute
+ 		{ $$ = finish_enum ($<ttype>3, nreverse ($4),
+ 				    chainon ($1, $7)); }
+--- gcc/cp/parse.y.jj	2009-03-09 14:39:01.000000000 +0100
++++ gcc/cp/parse.y	2009-03-09 14:41:58.000000000 +0100
+@@ -804,7 +804,7 @@ fndef:
+ 
+ constructor_declarator:
+ 	  nested_name_specifier SELFNAME '(' 
+-                { $$ = begin_constructor_declarator ($1, $2); }
++                { $<ttype>$ = begin_constructor_declarator ($1, $2); }
+ 	  parmlist ')' cv_qualifiers exception_specification_opt
+ 		{ $$ = make_call_declarator ($<ttype>4, $5, $7, $8); }
+ 	| nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt
+@@ -812,7 +812,7 @@ constructor_declarator:
+ 		  $$ = make_call_declarator ($$, empty_parms (), $4, $5);
+ 		}
+ 	| global_scope nested_name_specifier SELFNAME '(' 
+-                { $$ = begin_constructor_declarator ($2, $3); }
++                { $<ttype>$ = begin_constructor_declarator ($2, $3); }
+ 	 parmlist ')' cv_qualifiers exception_specification_opt
+ 		{ $$ = make_call_declarator ($<ttype>5, $6, $8, $9); }
+ 	| global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt
+@@ -820,7 +820,7 @@ constructor_declarator:
+ 		  $$ = make_call_declarator ($$, empty_parms (), $5, $6);
+ 		}
+ 	| nested_name_specifier self_template_type '(' 
+-                { $$ = begin_constructor_declarator ($1, $2); }
++                { $<ttype>$ = begin_constructor_declarator ($1, $2); }
+ 	  parmlist ')' cv_qualifiers exception_specification_opt
+ 		{ $$ = make_call_declarator ($<ttype>4, $5, $7, $8); }
+ 	| nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt
+@@ -828,7 +828,7 @@ constructor_declarator:
+ 		  $$ = make_call_declarator ($$, empty_parms (), $4, $5);
+ 		}
+ 	| global_scope nested_name_specifier self_template_type '(' 
+-                { $$ = begin_constructor_declarator ($2, $3); }
++                { $<ttype>$ = begin_constructor_declarator ($2, $3); }
+ 	 parmlist ')' cv_qualifiers exception_specification_opt
+ 		{ $$ = make_call_declarator ($<ttype>5, $6, $8, $9); }
+ 	| global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt
diff --git a/SOURCES/gcc32-c++-friend-templ-member.patch b/SOURCES/gcc32-c++-friend-templ-member.patch
new file mode 100644
index 0000000..46b0f4c
--- /dev/null
+++ b/SOURCES/gcc32-c++-friend-templ-member.patch
@@ -0,0 +1,60 @@
+2004-08-06  Alexandre Oliva  <aoliva@redhat.com>
+
+	* parse.y (structsp): Skip typename_type obtained from a
+	class_head_decl, use the actual type.
+
+2004-08-09  Alexandre Oliva  <aoliva@redhat.com>
+
+	* g++.old-deja/g++.pt/crash43.C: Don't require error for legal
+	construct.
+	* g++.dg/template/friend0.C: New test.
+
+--- gcc/cp/parse.y.jj
++++ gcc/cp/parse.y
+@@ -2371,6 +2374,13 @@ structsp:
+ 	| class_head_decl
+ 		{
+ 		  $$.t = TREE_TYPE ($1.t);
++		  /* class_head_decl always starts with an aggr, so
++		     get rid of any implicit typename warnings we
++		     might get from it.  We can't remove it before
++		     this point because this is where we get from the
++		     decl to the type.  */
++		  if (IMPLICIT_TYPENAME_P ($$.t))
++		    $$.t = TREE_TYPE ($$.t);
+ 		  $$.new_type_flag = $1.new_type_flag;
+ 		  check_class_key (current_aggr, $$.t);
+ 		}
+--- gcc/testsuite/g++.old-deja/g++.pt/crash43.C 27 Nov 2002 01:03:42 -0000 1.1
++++ gcc/testsuite/g++.old-deja/g++.pt/crash43.C 9 Aug 2004 17:20:46 -0000
+@@ -7,7 +7,7 @@ struct S {
+   struct Y {};
+ 
+   template <int U>
+-  friend struct S<U>::X; // ERROR - typename as friend
++  friend struct S<U>::X; // gets bogus error - XFAIL *-*-*
+ 
+   template <int U>
+   friend typename S<U>::Y; // ERROR - typename as friend
+@@ -15,7 +15,7 @@ struct S {
+ 
+ struct T {
+   template <int T>
+-  friend struct S<T>::X; // ERROR - typename as friend
++  friend struct S<T>::X;
+ };
+ 
+ struct U {
+--- gcc/testsuite/g++.dg/template/friend0.C.jj	2004-08-12 14:03:21.001079817 +0200
++++ gcc/testsuite/g++.dg/template/friend0.C	2004-08-12 14:03:15.734996391 +0200
+@@ -0,0 +1,10 @@
++// http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=129350
++// { dg-do compile }
++
++template<class T> struct A {
++        struct B { };
++};
++
++class C {
++        template<class T> friend struct A<T>::B;
++};
diff --git a/SOURCES/gcc32-c++-pass-by-invisible-ref.patch b/SOURCES/gcc32-c++-pass-by-invisible-ref.patch
new file mode 100644
index 0000000..13c5336
--- /dev/null
+++ b/SOURCES/gcc32-c++-pass-by-invisible-ref.patch
@@ -0,0 +1,67 @@
+2004-12-01  Alexandre Oliva  <aoliva@redhat.com>
+
+	* calls.c (initialize_argument_information): Treat NOP_EXPR
+	of TARGET_EXPR the same as TARGET_EXPR itself.
+
+2005-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* g++.dg/other/destruct1.C: New test.
+
+--- gcc/calls.c.jj	2003-09-16 16:57:44.000000000 +0200
++++ gcc/calls.c	2005-01-03 11:00:11.604022891 +0100
+@@ -1239,7 +1239,10 @@ initialize_argument_information (num_act
+ 					   args[i].tree_value);
+ 	      type = build_pointer_type (type);
+ 	    }
+-	  else if (TREE_CODE (args[i].tree_value) == TARGET_EXPR)
++	  else if (TREE_CODE (args[i].tree_value) == TARGET_EXPR
++		   || (TREE_CODE (args[i].tree_value) == NOP_EXPR
++		       && (TREE_CODE (TREE_OPERAND (args[i].tree_value, 0))
++			   == TARGET_EXPR)))
+ 	    {
+ 	      /* In the V3 C++ ABI, parameters are destroyed in the caller.
+ 		 We implement this by passing the address of the temporary
+--- gcc/testsuite/g++.dg/other/destruct1.C.jj	2005-01-03 11:02:26.440730539 +0100
++++ gcc/testsuite/g++.dg/other/destruct1.C	2005-01-03 11:02:44.971392180 +0100
+@@ -0,0 +1,41 @@
++// { dg-do run }
++
++int i, j, k;
++extern "C" void abort ();
++
++struct S
++{
++  S () { ++i; }
++  S (const S &x) { ++k; }
++  S &operator= (const S &x) { abort (); return *this; }
++  ~S () { ++j; }
++};
++
++const S foo ()
++{
++  S s;
++  return s;
++}
++
++S bar (S x)
++{
++  return S ();
++}
++
++S baz (S x)
++{
++  return x;
++}
++
++void test ()
++{
++  S a = bar (foo ());
++  S b = baz (foo ());
++}
++
++int main ()
++{
++  test ();
++  if (i != 3 || j != 4 || k != 1)
++    abort ();
++}
diff --git a/SOURCES/gcc32-c++-pr10558.patch b/SOURCES/gcc32-c++-pr10558.patch
new file mode 100644
index 0000000..b95bd8e
--- /dev/null
+++ b/SOURCES/gcc32-c++-pr10558.patch
@@ -0,0 +1,90 @@
+2003-07-10  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/10558
+	* parse.y (class_template_ok_as_expr): New variable.
+	(template_arg_1): New non-terminal.
+	(primary): Issue errors about uses of class templates as
+	expressions.
+
+	* g++.dg/parse/template8.C: New test.
+
+--- gcc/cp/parse.y	10 Jul 2003 12:43:11 -0000	1.284.2.7
++++ gcc/cp/parse.y	11 Jul 2003 08:39:55 -0000	1.284.2.8
+@@ -53,6 +53,8 @@ extern struct obstack permanent_obstack;
+ /* Like YYERROR but do call yyerror.  */
+ #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
+ 
++static int class_template_ok_as_expr;
++
+ #define OP0(NODE) (TREE_OPERAND (NODE, 0))
+ #define OP1(NODE) (TREE_OPERAND (NODE, 1))
+ 
+@@ -422,7 +424,7 @@ cp_parse_init ()
+ %type <code>  template_close_bracket
+ %type <ttype> apparent_template_type
+ %type <ttype> template_type template_arg_list template_arg_list_opt
+-%type <ttype> template_arg
++%type <ttype> template_arg template_arg_1
+ %type <ttype> condition xcond paren_cond_or_null
+ %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
+ %type <ttype> complete_type_name notype_identifier nonnested_type
+@@ -1108,7 +1110,7 @@ template_close_bracket:
+ template_arg_list_opt:
+          /* empty */
+                  { $$ = NULL_TREE; }
+-       | template_arg_list
++       | template_arg_list 
+        ;
+ 
+ template_arg_list:
+@@ -1119,6 +1121,15 @@ template_arg_list:
+ 	;
+ 
+ template_arg:
++		{ ++class_template_ok_as_expr; }
++	template_arg_1 
++		{ 
++		  --class_template_ok_as_expr; 
++		  $$ = $2; 
++		}
++	;
++
++template_arg_1:
+ 	  type_id
+ 		{ $$ = groktypename ($1.t); }
+ 	| PTYPENAME
+@@ -1695,7 +1706,14 @@ primary:
+ 		    $$ = $2;
+ 		}
+ 	| overqualified_id  %prec HYPERUNARY
+-		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
++		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$));
++		  if (!class_template_ok_as_expr 
++		      && DECL_CLASS_TEMPLATE_P ($$))
++		    {
++		      error ("invalid use of template `%D'", $$); 
++		      $$ = error_mark_node;
++		    }
++		}
+ 	| overqualified_id '(' nonnull_exprlist ')'
+                 { $$ = finish_qualified_call_expr ($1, $3); }
+ 	| overqualified_id LEFT_RIGHT
+--- gcc/testsuite/g++.dg/parse/template8.C	2005-01-27 14:27:08.338732320 +0100
++++ gcc/testsuite/g++.dg/parse/template8.C	2003-07-16 18:05:35.000000000 +0200
+@@ -0,0 +1,16 @@
++namespace N
++{
++
++template <typename> struct A
++{
++  template <typename T> A(A<T>);
++};
++
++}
++
++void foo(N::A<int>);
++
++void bar()
++{
++  foo(N::A); // { dg-error "" }
++}
diff --git a/SOURCES/gcc32-c++-pr7566.patch b/SOURCES/gcc32-c++-pr7566.patch
new file mode 100644
index 0000000..7857776
--- /dev/null
+++ b/SOURCES/gcc32-c++-pr7566.patch
@@ -0,0 +1,44 @@
+2002-08-14  Gabriel Dos Reis  <gdr@nerim.net>
+
+	Fix PR/7566
+	* c-semantics.c (genrtl_case_label): Don't (mis)use
+	warning_with_decl.
+
+2005-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* g++.dg/parse/jumptocaselab1.C: New test.
+
+--- gcc/c-semantics.c.jj	2003-01-17 18:31:04.000000000 +0100
++++ gcc/c-semantics.c	2005-01-03 10:19:51.912155689 +0100
+@@ -673,8 +673,7 @@ genrtl_case_label (case_label)
+   if (cleanup)
+     {
+       static int explained = 0;
+-      warning_with_decl (TREE_PURPOSE (cleanup), 
+-			 "destructor needed for `%#D'");
++      warning ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
+       warning ("where case label appears here");
+       if (!explained)
+ 	{
+--- gcc/testsuite/g++.dg/parse/jumptocaselab1.C.jj	2005-01-03 10:23:45.286072690 +0100
++++ gcc/testsuite/g++.dg/parse/jumptocaselab1.C	2005-01-03 10:26:29.216516818 +0100
+@@ -0,0 +1,19 @@
++// PR c++/7566
++// { dg-do compile }
++
++struct bar { bar (); ~bar ();};
++
++void foo (int c)
++{
++  switch (c)
++    {
++    case 0:
++    case 1:
++      bar x;	// { dg-error "crosses initialization" }
++      break;
++    default:	// { dg-error "jump to case label" }
++      break;
++    }
++}
++
++// { dg-warning "destructor needed|where case label|enclose actions" "" { target *-*-* } 14 }
diff --git a/SOURCES/gcc32-c++-reregister-specialization.patch b/SOURCES/gcc32-c++-reregister-specialization.patch
new file mode 100644
index 0000000..87b6e85
--- /dev/null
+++ b/SOURCES/gcc32-c++-reregister-specialization.patch
@@ -0,0 +1,89 @@
+2003-07-14  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/7053
+	* pt.c (unregister_specialization): Rename to ...
+	(reregister_specialization): ... this.
+	(tsubst_friend_function): Use it.
+	(regenerate_decl_from_template): Likewise.
+
+	* g++.dg/template/friend20.C: New test.
+
+--- gcc/cp/pt.c	14 Jul 2003 10:08:58 -0000	1.635.2.33
++++ gcc/cp/pt.c	14 Jul 2003 20:18:18 -0000	1.635.2.34
+@@ -128,7 +128,7 @@ static tree retrieve_specialization PARA
+ static tree retrieve_local_specialization PARAMS ((tree));
+ static tree register_specialization PARAMS ((tree, tree, tree));
+ static void register_local_specialization PARAMS ((tree, tree));
+-static int unregister_specialization PARAMS ((tree, tree));
++static int reregister_specialization PARAMS ((tree, tree, tree));
+ static tree reduce_template_parm_level PARAMS ((tree, tree, int));
+ static tree build_template_decl PARAMS ((tree, tree));
+ static int mark_template_parm PARAMS ((tree, void *));
+@@ -969,13 +969,11 @@ register_specialization (spec, tmpl, arg
+ }
+ 
+ /* Unregister the specialization SPEC as a specialization of TMPL.
+-   Returns nonzero if the SPEC was listed as a specialization of
+-   TMPL.  */
++   Replace it with NEW_SPEC, if NEW_SPEC is non-NULL.  Returns true
++   if the SPEC was listed as a specialization of TMPL.  */
+ 
+ static int
+-unregister_specialization (spec, tmpl)
+-     tree spec;
+-     tree tmpl;
++reregister_specialization (tree spec, tree tmpl, tree new_spec)
+ {
+   tree* s;
+ 
+@@ -984,7 +982,10 @@ unregister_specialization (spec, tmpl)
+        s = &TREE_CHAIN (*s))
+     if (TREE_VALUE (*s) == spec)
+       {
+-	*s = TREE_CHAIN (*s);
++	if (!new_spec)
++	  *s = TREE_CHAIN (*s);
++	else
++	  TREE_VALUE (*s) = new_spec;
+ 	return 1;
+       }
+ 
+@@ -4807,8 +4808,9 @@ tsubst_friend_function (decl, args)
+ 	      DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
+ 
+ 	      if (TREE_CODE (old_decl) != TEMPLATE_DECL)
+-		/* duplicate_decls will take care of this case.  */
+-		;
++		reregister_specialization (new_friend,
++					   most_general_template (old_decl),
++					   old_decl);
+ 	      else 
+ 		{
+ 		  tree t;
+@@ -9897,7 +9899,7 @@ regenerate_decl_from_template (decl, tmp
+      instantiation of a specialization, which it isn't: it's a full
+      instantiation.  */
+   gen_tmpl = most_general_template (tmpl);
+-  unregistered = unregister_specialization (decl, gen_tmpl);
++  unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE);
+ 
+   /* If the DECL was not unregistered then something peculiar is
+      happening: we created a specialization but did not call
+--- gcc/testsuite/g++.dg/template/friend20.C	2004-12-09 13:34:01.422415552 +0100
++++ gcc/testsuite/g++.dg/template/friend20.C	2003-07-15 02:29:07.000000000 +0200
+@@ -0,0 +1,15 @@
++template <class T>
++struct A
++{
++  friend void bar(A<T> a) {}
++};
++
++void bar(A<int>);
++
++int main()
++{
++  A<int> a;
++
++  bar(a);
++}
++
diff --git a/SOURCES/gcc32-c++-scope-nesting.patch b/SOURCES/gcc32-c++-scope-nesting.patch
new file mode 100644
index 0000000..e898c55
--- /dev/null
+++ b/SOURCES/gcc32-c++-scope-nesting.patch
@@ -0,0 +1,113 @@
+2004-08-13  Alexandre Oliva  <aoliva@redhat.com>
+
+	Revert:
+	2003-03-17  Jason Merrill  <jason@redhat.com>
+	* decl.c (finish_function): Don't skip a block.
+
+2004-08-12  Alexandre Oliva  <aoliva@redhat.com>
+
+	2002-12-16  Jason Merrill  <jason@redhat.com>
+	* c-semantics.c (add_scope_stmt): Abort if the end SCOPE_STMT
+	doesn't match the begin SCOPE_STMT in partialness.
+
+2004-08-12  Alexandre Oliva  <aoliva@redhat.com>
+
+	2002-12-16  Jason Merrill  <jason@redhat.com>
+	* semantics.c (do_pushlevel): Call pushlevel after adding the
+	SCOPE_STMT.
+	(do_poplevel): Call poplevel before adding the SCOPE_STMT.
+	* parse.y (function_body): Go back to using compstmt.
+	* decl.c (pushdecl): Skip another level to get to the parms level.
+
+--- gcc/c-semantics.c 17 Jan 2003 17:49:35 -0000 1.40.2.2.8.2
++++ gcc/c-semantics.c 12 Aug 2004 09:16:00 -0000
+@@ -143,6 +143,8 @@ add_scope_stmt (begin_p, partial_p)
+     }
+   else
+     {
++      if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top)))
++	abort ();
+       TREE_VALUE (top) = ss;
+       *stack_ptr = TREE_CHAIN (top);
+     }
+--- gcc/cp/decl.c 25 Mar 2003 20:01:38 -0000 1.866.2.36.4.15
++++ gcc/cp/decl.c 12 Aug 2004 09:16:20 -0000
+@@ -4218,6 +4218,9 @@ pushdecl (x)
+ 		     them there.  */
+ 		  struct binding_level *b = current_binding_level->level_chain;
+ 
++		  /* Skip the ctor/dtor cleanup level.  */
++		  b = b->level_chain;
++
+ 		  /* ARM $8.3 */
+ 		  if (b->parm_flag == 1)
+ 		    {
+--- gcc/cp/decl.c	2004-08-13 01:32:01.000000000 -0300
++++ gcc/cp/decl.c	2004-08-12 21:55:06.000000000 -0300
+@@ -14375,7 +14375,8 @@
+ 	     the function so we know that their lifetime always ends with a
+ 	     return; see g++.dg/opt/nrv6.C.  We could be more flexible if
+ 	     we were to do this optimization in tree-ssa.  */
+-	  && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)),
++	  /* Skip the artificial function body block.  */
++	  && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
+ 	      chain_member (r, BLOCK_VARS (outer))))
+ 	{
+ 	  
+--- gcc/cp/parse.y 17 Jan 2003 17:49:55 -0000 1.248.2.5.4.1.2.3
++++ gcc/cp/parse.y 12 Aug 2004 09:16:22 -0000
+@@ -775,15 +775,10 @@ eat_saved_input:
+ 	;
+ 
+ /* The outermost block of a function really begins before the
+-   mem-initializer-list, so we open one there and suppress the one that
+-   actually corresponds to the curly braces.  */
++   mem-initializer-list, so we open one there, too.  */
+ function_body:
+-	  .begin_function_body ctor_initializer_opt save_lineno '{'
+-		{ $<ttype>$ = begin_compound_stmt (/*has_no_scope=*/1); }
+-	  compstmtend 
++	  .begin_function_body ctor_initializer_opt compstmt
+                 {
+-		  STMT_LINENO ($<ttype>5) = $3;
+-		  finish_compound_stmt (/*has_no_scope=*/1, $<ttype>5);
+ 		  finish_function_body ($1);
+ 		}
+ 	;
+--- gcc/cp/semantics.c 25 Mar 2003 20:01:39 -0000 1.252.2.6.8.3
++++ gcc/cp/semantics.c 12 Aug 2004 09:16:23 -0000
+@@ -125,14 +125,17 @@ do_poplevel ()
+     {
+       tree scope_stmts = NULL_TREE;
+ 
+-      if (!processing_template_decl)
+-	scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+-
+       block = poplevel (kept_level_p (), 1, 0);
+-      if (block && !processing_template_decl)
++      if (!processing_template_decl)
+ 	{
+-	  SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
+-	  SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
++	  /* This needs to come after the poplevel so that partial scopes
++	     are properly nested.  */
++	  scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
++	  if (block)
++	    {
++	      SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
++	      SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
++	    }
+ 	}
+     }
+ 
+@@ -146,9 +149,9 @@ do_pushlevel ()
+ {
+   if (stmts_are_full_exprs_p ())
+     {
+-      pushlevel (0);
+       if (!processing_template_decl)
+ 	add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
++      pushlevel (0);
+     }
+ }
+ 
diff --git a/SOURCES/gcc32-c++-unitialized-self-ref.patch b/SOURCES/gcc32-c++-unitialized-self-ref.patch
new file mode 100644
index 0000000..733ecb3
--- /dev/null
+++ b/SOURCES/gcc32-c++-unitialized-self-ref.patch
@@ -0,0 +1,109 @@
+2004-12-02  Alexandre Oliva  <aoliva@redhat.com>
+
+	* decl.c (copy_tree_replacing_r, struct replace_node): New.
+	(grok_reference_init): Use them to replace uses of a reference
+	being initialized with a NULL dereference.
+
+2005-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* g++.dg/other/ref1.C: New test.
+
+--- gcc/cp/decl.c.jj	2003-03-28 22:03:02.000000000 +0100
++++ gcc/cp/decl.c	2005-01-03 11:45:24.669972609 +0100
+@@ -1,6 +1,6 @@
+ /* Process declarations and variables for C compiler.
+    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+-   2001, 2002, 2003  Free Software Foundation, Inc.
++   2001, 2002, 2003, 2004  Free Software Foundation, Inc.
+    Contributed by Michael Tiemann (tiemann@cygnus.com)
+ 
+ This file is part of GNU CC.
+@@ -7535,6 +7535,30 @@ start_decl_1 (decl)
+     DECL_INITIAL (decl) = NULL_TREE;
+ }
+ 
++static tree copy_tree_replacing_r PARAMS ((tree *, int *, void *));
++
++struct replace_node
++{
++  tree from, to;
++};
++
++static tree
++copy_tree_replacing_r (tp, walk_subtrees, data)
++     tree *tp;
++     int *walk_subtrees;
++     void *data;
++{
++  struct replace_node *rn = data;
++
++  if (*tp != rn->from)
++    return copy_tree_r (tp, walk_subtrees, NULL);
++
++  *tp = rn->to;
++  *walk_subtrees = 0;
++
++  return NULL;
++}
++
+ /* Handle initialization of references.
+    These three arguments are from `cp_finish_decl', and have the
+    same meaning here that they do there.
+@@ -7565,6 +7589,35 @@ grok_reference_init (decl, type, init)
+       return NULL_TREE;
+     }
+ 
++  /* Replace occurrences of a reference variable in its own
++     initializer with a zero-initialized NULL reference.  If we don't
++     do this and the reference initializer ends up requiring a
++     temporary (as it almost always will in this case), we'll end up
++     with the initializer of the temporary referencing the reference
++     variable before it's in scope, which crashes because we haven't
++     expanded the reference declaration yet, so its DECL_RTL is NULL.
++     This is equivalent to zero-initializing the reference variable,
++     expanding the temporary definition with initializer, then binding
++     the reference to the temporary, without requiring all the revamp
++     in reference handling that mainline undergone for GCC 3.4.  It
++     actually changes behavior a little bit, in that a reference
++     initialized to itself will now be bound to a NULL reference
++     instead of getting an indeterminate value, but since using it
++     before initialization invokes undefined behavior, either way is
++     fine.  */
++  if (find_tree (init, decl))
++    {
++      struct replace_node rn;
++
++      rn.from = decl;
++      rn.to = build1 (NOP_EXPR, type, integer_zero_node);
++      
++      walk_tree (&init, copy_tree_replacing_r, &rn, NULL);
++
++      if (warn_uninitialized)
++	warning ("reference used in its own initializer");
++    }
++
+   if (TREE_CODE (init) == TREE_LIST)
+     init = build_compound_expr (init);
+ 
+--- gcc/testsuite/g++.dg/other/ref1.C.jj	2005-01-03 11:46:43.005868429 +0100
++++ gcc/testsuite/g++.dg/other/ref1.C	2005-01-03 11:47:34.475601869 +0100
+@@ -0,0 +1,19 @@
++// { dg-do compile }
++// { dg-options "-O2" }
++
++struct A
++{
++  A ();
++  ~A ();
++};
++
++extern const A &bar ();
++extern A baz ();
++extern int operator!= (const A &x, const A &y);
++
++void foo (const A &x)
++{
++  /* This has undefined behaviour, as a is used before it is initialized.
++     Still, we shouldn't ICE on it.  */
++  const A &a = a != bar () ? x : baz ();
++}
diff --git a/SOURCES/gcc32-convert-move.patch b/SOURCES/gcc32-convert-move.patch
new file mode 100644
index 0000000..e456b42
--- /dev/null
+++ b/SOURCES/gcc32-convert-move.patch
@@ -0,0 +1,18 @@
+2003-05-22  Jeff Law  <law@redhat.com>
+
+	* expr.c (convert_move): Avoid making silly copies.
+
+--- gcc/expr.c.jj	2004-05-25 17:05:45.000000000 +0200
++++ gcc/expr.c	2004-08-03 17:40:55.114899943 +0200
+@@ -531,6 +531,11 @@ convert_move (to, from, unsignedp)
+   if (to_real != from_real)
+     abort ();
+ 
++  /* If the source and destination are already the same, then there's
++     nothing to do.  */
++  if (to == from)
++    return;
++
+   /* If FROM is a SUBREG that indicates that we have already done at least
+      the required extension, strip it.  We don't handle such SUBREGs as
+      TO here.  */
diff --git a/SOURCES/gcc32-cxa_demangle-ambiguity.patch b/SOURCES/gcc32-cxa_demangle-ambiguity.patch
new file mode 100644
index 0000000..8a6c28b
--- /dev/null
+++ b/SOURCES/gcc32-cxa_demangle-ambiguity.patch
@@ -0,0 +1,78 @@
+2005-02-13  Jason Merrill  <jason@redhat.com>
+
+	* cp-demangle.c (__cxa_demangle): Change resolution of ambiguous
+	arguments.
+
+2005-02-15  Jakub Jelinek  <jakub@redhat.com>
+
+	PR libstdc++/19946
+	* testsuite/demangle/abi_examples/01.cc (main): Adjust for 2005-02-13
+	demangler change.
+	* testsuite/demangle/abi_examples/02.cc (main): Likewise.
+
+--- libiberty/cp-demangle.c	24 Nov 2004 02:19:09 -0000	1.75
++++ libiberty/cp-demangle.c	13 Feb 2005 06:58:20 -0000	1.76
+@@ -4047,21 +4047,6 @@ __cxa_demangle (mangled_name, output_buf
+       return NULL;
+     }
+ 
+-  /* The specification for __cxa_demangle() is that if the mangled
+-     name could be either an extern "C" identifier, or an internal
+-     built-in type name, then we resolve it as the identifier.  All
+-     internal built-in type names are a single lower case character.
+-     Frankly, this simplistic disambiguation doesn't make sense to me,
+-     but it is documented, so we implement it here.  */
+-  if (IS_LOWER (mangled_name[0])
+-      && mangled_name[1] == '\0'
+-      && cplus_demangle_builtin_types[mangled_name[0] - 'a'].name != NULL)
+-    {
+-      if (status != NULL)
+-	*status = -2;
+-      return NULL;
+-    }
+-
+   demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
+ 
+   if (demangled == NULL)
+--- libstdc++-v3/testsuite/demangle/abi_examples/01.cc.jj	2004-03-09 16:09:24.000000000 +0100
++++ libstdc++-v3/testsuite/demangle/abi_examples/01.cc	2005-02-14 09:05:09.383834357 +0100
+@@ -1,6 +1,6 @@
+ // 2003-02-26 Benjamin Kosnik <bkoz@redhat.com>
+ 
+-// Copyright (C) 2003 Free Software Foundation, Inc.
++// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+@@ -31,7 +31,9 @@ int main()
+   // extern "C" function 
+   // extern "C" float f(void) { };
+   // T f
+-  verify_demangle("f", "error code = -2: invalid mangled name");
++  // f is ambiguous between "C" external name and internal built-in type
++  // name.  The ambiguity is resolved to the built-in type name.
++  verify_demangle("f", "float");
+ 
+   return 0;
+ }
+--- libstdc++-v3/testsuite/demangle/abi_examples/02.cc.jj	2004-03-09 16:09:24.000000000 +0100
++++ libstdc++-v3/testsuite/demangle/abi_examples/02.cc	2005-02-14 09:05:59.661857808 +0100
+@@ -1,6 +1,6 @@
+ // 2003-02-26 Benjamin Kosnik <bkoz@redhat.com>
+ 
+-// Copyright (C) 2003 Free Software Foundation, Inc.
++// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+@@ -31,7 +31,9 @@ int main()
+   // or variable "f" 
+   // int f;
+   // B f
+-  verify_demangle("f", "error code = -2: invalid mangled name");
++  // f is ambiguous between variable external name and internal built-in type
++  // name.  The ambiguity is resolved to the built-in type name.
++  verify_demangle("f", "float");
+ 
+   return 0;
+ }
diff --git a/SOURCES/gcc32-debug-cdtor.patch b/SOURCES/gcc32-debug-cdtor.patch
new file mode 100644
index 0000000..033b118
--- /dev/null
+++ b/SOURCES/gcc32-debug-cdtor.patch
@@ -0,0 +1,17 @@
+2003-07-14  Mark Mitchell  <mark@codesourcery.com>
+
+	PR debug/11098
+	* integrate.c (copy_decl_for_inlining): Do not mark copied decls
+	as DECL_ABSTRACT.
+
+--- gcc/integrate.c.jj	2003-02-14 09:26:34.000000000 +0100
++++ gcc/integrate.c	2005-01-28 21:28:44.332792466 +0100
+@@ -368,6 +368,8 @@ copy_decl_for_inlining (decl, from_fn, t
+   else
+     {
+       copy = copy_node (decl);
++      /* The COPY is not abstract; it will be generated in TO_FN.  */
++      DECL_ABSTRACT (copy) = 0;
+       if (DECL_LANG_SPECIFIC (copy))
+ 	copy_lang_decl (copy);
+ 
diff --git a/SOURCES/gcc32-demangle-pr16240.patch b/SOURCES/gcc32-demangle-pr16240.patch
new file mode 100644
index 0000000..1c190f5
--- /dev/null
+++ b/SOURCES/gcc32-demangle-pr16240.patch
@@ -0,0 +1,32 @@
+2004-06-28  Ian Lance Taylor  <ian@wasabisystems.com>
+
+	PR other/16240
+	* cp-demangle.c (d_expr_primary): Check for a failure return from
+	cplus_demangle_type.
+	* testsuite/demangle-expected: Add test case.
+
+--- libiberty/cp-demangle.c	25 Feb 2004 04:51:37 -0000	1.73
++++ libiberty/cp-demangle.c	28 Jun 2004 15:23:33 -0000	1.74
+@@ -2398,6 +2398,8 @@ d_expr_primary (di)
+       const char *s;
+ 
+       type = cplus_demangle_type (di);
++      if (type == NULL)
++	return NULL;
+ 
+       /* If we have a type we know how to print, we aren't going to
+ 	 print the type name itself.  */
+--- libiberty/testsuite/demangle-expected	25 Feb 2004 04:51:39 -0000	1.30
++++ libiberty/testsuite/demangle-expected	28 Jun 2004 17:36:27 -0000	1.31
+@@ -3699,6 +3699,11 @@ _Z3fooIPA3_iEvRKT_
+ void foo<int (*) [3]>(int (* const&) [3])
+ foo<int (*) [3]>
+ #
++# This used to crash the demangler--PR 16240
++--format=gnu-v3 --no-params
++_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
++_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
++PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue
+ # Test GNU V3 constructor and destructor identification.
+ # 0 means it is not a constructor/destructor.
+ # Other integers correspond to enum gnu_v3_{c,d}tor_kinds in demangle.h.
diff --git a/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch b/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch
new file mode 100644
index 0000000..1dc503c
--- /dev/null
+++ b/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch
@@ -0,0 +1,28 @@
+2004-08-13  Alexandre Oliva  <aoliva@redhat.com>
+
+	* dwarf2out.c (prune_unused_types_walk): Mark the specification if
+	the declaration is marked.
+
+--- gcc/dwarf2out.c	2004-08-13 04:46:06.000000000 -0300
++++ gcc/dwarf2out.c	2004-08-13 04:47:21.904025637 -0300
+@@ -12364,6 +12364,12 @@ prune_unused_types_walk (die)
+     return;
+ 
+   switch (die->die_tag) {
++  case DW_TAG_structure_type:
++    /* If the declaration is marked, mark the specification as well.  */
++    if ((c = get_AT_ref (die, DW_AT_specification)) != NULL
++	&& c->die_mark)
++      break;
++
+   case DW_TAG_const_type:
+   case DW_TAG_packed_type:
+   case DW_TAG_pointer_type:
+@@ -12371,7 +12377,6 @@ prune_unused_types_walk (die)
+   case DW_TAG_volatile_type:
+   case DW_TAG_typedef:
+   case DW_TAG_array_type:
+-  case DW_TAG_structure_type:
+   case DW_TAG_union_type:
+   case DW_TAG_class_type:
+   case DW_TAG_friend:
diff --git a/SOURCES/gcc32-fc4-compile.patch b/SOURCES/gcc32-fc4-compile.patch
new file mode 100644
index 0000000..0af6103
--- /dev/null
+++ b/SOURCES/gcc32-fc4-compile.patch
@@ -0,0 +1,30 @@
+--- gcc/tradcif.y.jj	2005-03-08 15:22:54.000000000 -0500
++++ gcc/tradcif.y	2005-03-08 15:30:11.000000000 -0500
+@@ -29,6 +29,7 @@ Foundation, 59 Temple Place - Suite 330,
+ #include <setjmp.h>
+ #ifdef __GNUC__
+ #define YYMALLOC nonexistent
++#define YYSTACK_USE_ALLOCA 1
+ #endif
+ 
+   static int yylex PARAMS ((void));
+--- gcc/cp/parse.y.jj	2005-03-08 15:53:07.821036000 -0500
++++ gcc/cp/parse.y	2005-03-08 15:57:31.895819332 -0500
+@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA.  */
+ #include "ggc.h"
+ #ifdef __GNUC__
+ #define YYMALLOC nonexistent
++#define YYSTACK_USE_ALLOCA 1
+ #endif
+ 
+ extern struct obstack permanent_obstack;
+--- gcc/c-parse.in.jj	2005-03-08 15:53:07.828035000 -0500
++++ gcc/c-parse.in	2005-03-08 15:57:07.787221389 -0500
+@@ -49,6 +49,7 @@ end ifc
+ #include "ggc.h"
+ #ifdef __GNUC__
+ #define YYMALLOC nonexistent
++#define YYSTACK_USE_ALLOCA 1
+ #endif
+   
+ #ifdef MULTIBYTE_CHARS
diff --git a/SOURCES/gcc32-gnuc-rh-release.patch b/SOURCES/gcc32-gnuc-rh-release.patch
new file mode 100644
index 0000000..1f6aa1a
--- /dev/null
+++ b/SOURCES/gcc32-gnuc-rh-release.patch
@@ -0,0 +1,72 @@
+2005-11-10  Alexandre Oliva  <aoliva@redhat.com>
+
+	* gcc.c (cpp_unique_options): Add %vR.
+	(do_spec_1): Use it to define __GNUC_RH_RELEASE__.
+
+--- gcc/gcc.c	2005-11-10 14:59:39.000000000 -0200
++++ gcc/gcc.c	2005-11-10 15:47:01.000000000 -0200
+@@ -696,7 +696,7 @@
+  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
+  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
+  %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
+- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3 -D__GXX_ABI_VERSION=102}\
++ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3 %vR -D__GXX_ABI_VERSION=102}\
+  %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
+  %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
+  %{fno-inline|O0|!O*:-D__NO_INLINE__} %{ffast-math:-D__FAST_MATH__}\
+@@ -5226,7 +5226,7 @@
+ 
+ 	      /* If desired, advance to third version number.
+                  But don't complain if it's not present */
+-	      if (c1 == '3')
++	      if (c1 >= '3')
+ 		{
+ 		  /* Set V after the second period.  */
+ 		  while (ISDIGIT (*v))
+@@ -5237,11 +5237,45 @@
+ 		    v++;
+ 		}
+ 
++	      if (c1 == 'R')
++		{
++		  /* Move q to the end of compiler_version, so that we
++		     can compare the beginning of compiler_version
++		     with the beginning of version_string below.  */
++		  q = v + strlen (v);
++
++		  v = strchr (version_string, '(');
++		  if (v != NULL && strncmp (v + 1, "Red Hat ", 8) == 0)
++		    {
++		      v += 9;
++		      if (strncmp (v, "Linux ", 6) == 0)
++			v += 6;
++
++		      /* If compiler_version changed, don't define
++			 __GNUC_RH_RELEASE__.  */
++		      if (strncmp (v, compiler_version, q - compiler_version)
++			  != 0)
++			break;
++
++		      if (strncmp (v, version_string, q - compiler_version)
++			  != 0 || v[q - compiler_version] != '-')
++			abort ();
++
++		      /* Skip the version and the dash.  */
++		      v += q - compiler_version + 1;
++		      obstack_grow (&obstack, "-D__GNUC_RH_RELEASE__=",
++				    sizeof ("-D__GNUC_RH_RELEASE__=") - 1);
++		    }
++		  else
++		    break;
++		}
++
+ 	      /* Set Q at the next period or at the end.  */
+ 	      q = v;
+ 	      while (ISDIGIT (*q))
+ 		q++;
+-	      if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
++	      if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-'
++		  && *q != ')')
+ 		abort ();
+ 
+ 	      if (q > v)
diff --git a/SOURCES/gcc32-i386-prefetch-sse.patch b/SOURCES/gcc32-i386-prefetch-sse.patch
new file mode 100644
index 0000000..643c7e2
--- /dev/null
+++ b/SOURCES/gcc32-i386-prefetch-sse.patch
@@ -0,0 +1,95 @@
+2004-07-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* Backport from mainline:
+	2004-07-08  Paolo Bonzini  <bonzini@gnu.org>
+		    Jakub Jelinek  <jakub@redhat.com>
+
+	* config/i386/i386.c (override_options): Enable
+	SSE prefetches with -mtune, as long as we are
+	compiling for i686 or higher.  All i686 processors
+	accept SSE prefetches as NOPS, some i586's don't.
+
+	2004-07-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* config/i386/i386.c (override_options): Don't set x86_prefetch_sse
+	from -mtune= option.
+
+2004-07-08  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.mist-tests/i386-prefetch.exp (PREFETCH_SSE): Change all
+	-march=i386 into -march=i686.  Add -march=i686 -mcpu=prescott and
+	-march=prescott.
+
+2003-08-04  Janis Johnson  <janis187@us.ibm.com>
+
+	PR target/11739
+	* gcc.misc-tests/i386-prefetch.exp: Use -march=i386 when specifying
+	a value for -mcpu.
+
+--- gcc/config/i386/i386.c.jj	2004-07-01 12:52:56.000000000 +0200
++++ gcc/config/i386/i386.c	2004-08-12 14:26:55.039997547 +0200
+@@ -1064,11 +1064,17 @@ override_options ()
+ 	ix86_cpu = processor_alias_table[i].processor;
+ 	if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
+ 	  error ("CPU you selected does not support x86-64 instruction set");
++
++	/* Intel CPUs have always interpreted SSE prefetch instructions as
++	   NOPs; so, we can enable SSE prefetch instructions even when
++	   -mtune (rather than -march) points us to a processor that has them.
++	   However, the VIA C3 gives a SIGILL, so we only do that for i686 and
++	   higher processors.  */
++	if (TARGET_CMOVE && (processor_alias_table[i].flags & PTA_PREFETCH_SSE))
++	  x86_prefetch_sse = true;
+ 	break;
+       }
+ 
+-  if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
+-    x86_prefetch_sse = true;
+   if (i == pta_size)
+     error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
+ 
+--- gcc/testsuite/gcc.misc-tests/i386-prefetch.exp.jj	2002-01-18 19:41:41.000000000 +0100
++++ gcc/testsuite/gcc.misc-tests/i386-prefetch.exp	2004-08-12 14:34:28.702060131 +0200
+@@ -24,14 +24,14 @@
+ # Do not generate prefetch instructions for the following options.
+ 
+ set PREFETCH_NONE [list \
+-	{ -mcpu=i386 } \
+-	{ -mcpu=i486 } \
+-	{ -mcpu=i586 } \
+-	{ -mcpu=i686 } \
+-	{ -mcpu=pentium2 } \
+-	{ -mcpu=k6 } \
+-	{ -mcpu=k6-2 } \
+-	{ -mcpu=k6-3 } \
++	{ -march=i386 -mcpu=i386 } \
++	{ -march=i386 -mcpu=i486 } \
++	{ -march=i386 -mcpu=i586 } \
++	{ -march=i386 -mcpu=i686 } \
++	{ -march=i386 -mcpu=pentium2 } \
++	{ -march=i386 -mcpu=k6 } \
++	{ -march=i386 -mcpu=k6-2 } \
++	{ -march=i386 -mcpu=k6-3 } \
+ 	{ -march=i386 } \
+ 	{ -march=i486 } \
+ 	{ -march=i586 } \
+@@ -44,12 +44,14 @@ set PREFETCH_NONE [list \
+ # instructions as nops.
+ 
+ set PREFETCH_SSE [list \
+-	{ -mcpu=pentium3 } \
+-	{ -mcpu=pentium4 } \
+-	{ -mcpu=athlon } \
+-	{ -mcpu=athlon-4 } \
++	{ -march=i686 -mcpu=pentium3 } \
++	{ -march=i686 -mcpu=pentium4 } \
++	{ -march=i686 -mcpu=prescott } \
++	{ -march=i686 -mcpu=athlon } \
++	{ -march=i686 -mcpu=athlon-4 } \
+ 	{ -march=pentium3 } \
+-	{ -march=pentium4 } ]
++	{ -march=pentium4 } \
++	{ -march=prescott } ]
+ 
+ # Generate 3DNow! prefetch instructions for the following.
+ 
diff --git a/SOURCES/gcc32-ia64-expand_load_address.patch b/SOURCES/gcc32-ia64-expand_load_address.patch
new file mode 100644
index 0000000..e835d30
--- /dev/null
+++ b/SOURCES/gcc32-ia64-expand_load_address.patch
@@ -0,0 +1,17 @@
+2004-10-05  Richard Henderson  <rth@redhat.com>
+
+	* config/ia64/ia64.c (ia64_expand_load_address): Recurse for
+	base of addition.
+
+--- gcc/config/ia64/ia64.c	2003/11/21 14:18:53	1.139.2.15.8.11
++++ gcc/config/ia64/ia64.c	2004/10/05 22:24:12	1.139.2.15.8.12
+@@ -1052,8 +1052,7 @@
+       if (! scratch)
+ 	scratch = no_new_pseudos ? subtarget : gen_reg_rtx (DImode);
+ 
+-      emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi),
+-				  scratch));
++      ia64_expand_load_address (subtarget, plus_constant (sym, hi), scratch);
+       emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
+     }
+   else
diff --git a/SOURCES/gcc32-ice-hack.patch b/SOURCES/gcc32-ice-hack.patch
new file mode 100644
index 0000000..5980863
--- /dev/null
+++ b/SOURCES/gcc32-ice-hack.patch
@@ -0,0 +1,355 @@
+--- gcc/system.h.jj	2003-04-08 15:55:41.000000000 +0200
++++ gcc/system.h	2003-10-03 19:01:24.000000000 +0200
+@@ -153,6 +153,10 @@ extern int errno;
+ # endif
+ #endif
+ 
++#ifndef ICE_EXIT_CODE
++# define ICE_EXIT_CODE 27
++#endif
++
+ #ifdef HAVE_UNISTD_H
+ # include <unistd.h>
+ #endif
+--- gcc/gcc.c.jj	2003-06-11 15:08:12.000000000 +0200
++++ gcc/gcc.c	2003-10-06 10:10:42.000000000 +0200
+@@ -112,6 +112,10 @@ extern int getrusage PARAMS ((int, struc
+ #define TARGET_OBJECT_SUFFIX ".o"
+ #endif
+ 
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++static void retry_ice PARAMS ((const char *, const char **));
++#endif
++
+ #ifndef VMS
+ /* FIXME: the location independence code for VMS is hairier than this,
+    and hasn't been written.  */
+@@ -2857,7 +2861,7 @@ execute ()
+       if (commands[i].pid == -1)
+ 	pfatal_pexecute (errmsg_fmt, errmsg_arg);
+ 
+-      if (string != commands[i].prog)
++      if (i && string != commands[i].prog)
+ 	free ((PTR) string);
+     }
+ 
+@@ -2935,6 +2939,17 @@ See %s for instructions.",
+ 	      else if (WIFEXITED (status)
+ 		       && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
+ 		{
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++		  /* For ICEs in cc1, cc1obj, cc1plus see if it is
++		     reproducible or not.  */
++		  char *p;
++		  if (WEXITSTATUS (status) == ICE_EXIT_CODE
++		      && j == 0
++		      && (p = strrchr (commands[j].argv[0], DIR_SEPARATOR))
++		      && ! strncmp (p + 1, "cc1", 3))
++		    retry_ice (commands[j].prog, commands[j].argv);
++#endif
++
+ 		  if (WEXITSTATUS (status) > greatest_status)
+ 		    greatest_status = WEXITSTATUS (status);
+ 		  ret_code = -1;
+@@ -2946,6 +2961,10 @@ See %s for instructions.",
+ 	      break;
+ 	    }
+       }
++
++    if (commands[0].argv[0] != commands[0].prog)
++      free ((PTR) commands[0].argv[0]);
++
+     return ret_code;
+   }
+ }
+@@ -5667,6 +5686,231 @@ give_switch (switchnum, omit_first_word,
+   switches[switchnum].validated = 1;
+ }
+ 
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++#define RETRY_ICE_ATTEMPTS 2
++
++static void
++retry_ice (prog, argv)
++     const char *prog;
++     const char **argv;
++{
++  int nargs, out_arg = -1, quiet = 0, attempt;
++  int pid, retries, sleep_interval;
++  const char **new_argv;
++  char *temp_filenames[RETRY_ICE_ATTEMPTS * 2 + 2];
++
++  if (input_filename == NULL || ! strcmp (input_filename, "-"))
++    return;
++
++  for (nargs = 0; argv[nargs] != NULL; ++nargs)
++    /* Only retry compiler ICEs, not preprocessor ones.  */
++    if (! strcmp (argv[nargs], "-E"))
++      return;
++    else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
++      {
++	if (out_arg == -1)
++	  out_arg = nargs;
++	else
++	  return;
++      }
++    /* If the compiler is going to output any time information,
++       it might varry between invocations.  */
++    else if (! strcmp (argv[nargs], "-quiet"))
++      quiet = 1;
++    else if (! strcmp (argv[nargs], "-ftime-report"))
++      return;
++
++  if (out_arg == -1 || !quiet)
++    return;
++
++  memset (temp_filenames, '\0', sizeof (temp_filenames));
++  new_argv = alloca ((nargs + 2) * sizeof (const char *));
++  memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
++  if (new_argv[out_arg][2] == '\0')
++    new_argv[out_arg + 1] = "-";
++  else
++    new_argv[out_arg] = "-o-";
++
++  for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS + 1; ++attempt)
++    {
++      int fd;
++      int status;
++
++      temp_filenames[attempt * 2] = make_temp_file (".out");
++      temp_filenames[attempt * 2 + 1] = make_temp_file (".err");
++
++      if (attempt == RETRY_ICE_ATTEMPTS)
++        {
++	  int i;
++	  int fd1, fd2;
++	  struct stat st1, st2;
++	  size_t n, len;
++	  char *buf;
++	  char *cpp0;
++
++	  buf = xmalloc (8192);
++
++	  for (i = 0; i < 2; ++i)
++	    {
++	      fd1 = open (temp_filenames[i], O_RDONLY);
++	      fd2 = open (temp_filenames[2 + i], O_RDONLY);
++
++	      if (fd1 < 0 || fd2 < 0)
++		{
++		  i = -1;
++		  close (fd1);
++		  close (fd2);
++		  break;
++		}
++
++	      if (fstat (fd1, &st1) < 0 || fstat (fd2, &st2) < 0)
++		{
++		  i = -1;
++		  close (fd1);
++		  close (fd2);
++		  break;
++		}
++
++	      if (st1.st_size != st2.st_size)
++		{
++		  close (fd1);
++		  close (fd2);
++		  break;
++		}
++
++	      len = 0;
++	      for (n = st1.st_size; n; n -= len)
++		{
++		  len = n;
++		  if (len > 4096)
++		    len = 4096;
++
++		  if (read (fd1, buf, len) != (int) len
++		      || read (fd2, buf + 4096, len) != (int) len)
++		    {
++		      i = -1;
++		      break;
++		    }
++
++		  if (memcmp (buf, buf + 4096, len) != 0)
++		    break;
++		}
++
++	      close (fd1);
++	      close (fd2);
++
++	      if (n)
++		break;
++	    }
++
++	  free (buf);
++	  if (i == -1)
++	    break;
++
++	  if (i != 2)
++	    {
++	      notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n");
++	      break;
++	    }
++
++          fd = open (temp_filenames[attempt * 2], O_RDWR);
++	  if (fd < 0)
++	    break;
++	  write (fd, "//", 2);
++	  for (i = 0; i < nargs; i++)
++	    {
++	      write (fd, " ", 1);
++	      write (fd, new_argv[i], strlen (new_argv[i]));
++	    }
++	  write (fd, "\n", 1);
++	  cpp0 = alloca (strlen (new_argv[0]) + sizeof "cpp0");
++	  strcpy (cpp0, new_argv[0]);
++	  new_argv[0] = cpp0;
++	  cpp0 = strrchr (new_argv[0], DIR_SEPARATOR);
++	  if (cpp0 != NULL)
++	    strcpy (cpp0 + 1, "cpp0");
++	  new_argv[nargs] = "--ice-hack";
++	  new_argv[nargs + 1] = NULL;
++        }
++
++      /* Fork a subprocess; wait and retry if it fails.  */
++      sleep_interval = 1;
++      pid = -1;
++      for (retries = 0; retries < 4; retries++)
++	{
++	  pid = fork ();
++	  if (pid >= 0)
++	    break;
++	  sleep (sleep_interval);
++	  sleep_interval *= 2;
++	}
++
++      if (pid < 0)
++	break;
++      else if (pid == 0)
++	{
++	  if (attempt != RETRY_ICE_ATTEMPTS)
++	    fd = open (temp_filenames[attempt * 2], O_RDWR);
++	  if (fd < 0)
++	    exit (-1);
++	  if (fd != 1)
++	    {
++	      close (1);
++	      dup (fd);
++	      close (fd);
++	    }
++
++	  fd = open (temp_filenames[attempt * 2 + 1], O_RDWR);
++	  if (fd < 0)
++	    exit (-1);
++	  if (fd != 2)
++	    {
++	      close (2);
++	      dup (fd);
++	      close (fd);
++	    }
++
++	  if (prog == new_argv[0])
++	    execvp (prog, (char *const *) new_argv);
++	  else
++	    execv (new_argv[0], (char *const *) new_argv);
++	  exit (-1);
++	}
++
++      if (waitpid (pid, &status, 0) < 0)
++	break;
++
++      if (attempt < RETRY_ICE_ATTEMPTS
++	  && (! WIFEXITED (status) || WEXITSTATUS (status) != ICE_EXIT_CODE))
++	{
++	  notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n");
++	  break;
++	}
++      else if (attempt == RETRY_ICE_ATTEMPTS)
++	{
++	  close (fd);
++	  if (WIFEXITED (status)
++	      && WEXITSTATUS (status) == SUCCESS_EXIT_CODE)
++	    {
++	      notice ("Preprocessed source stored into %s file, please attach this to your bugreport.\n",
++		      temp_filenames[attempt * 2]);
++	      /* Make sure it is not deleted.  */
++	      free (temp_filenames[attempt * 2]);
++	      temp_filenames[attempt * 2] = NULL;
++	      break;
++	    }
++	}
++    }
++
++  for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS * 2 + 2; attempt++)
++    if (temp_filenames[attempt])
++      {
++	unlink (temp_filenames[attempt]);
++	free (temp_filenames[attempt]);
++      }
++}
++#endif
++
+ /* Search for a file named NAME trying various prefixes including the
+    user's -B prefix and some standard ones.
+    Return the absolute file name found.  If nothing is found, return NAME.  */
+--- gcc/diagnostic.c.jj	2002-01-24 23:37:04.000000000 +0100
++++ gcc/diagnostic.c	2003-10-03 19:01:24.000000000 +0200
+@@ -1242,7 +1242,7 @@ internal_error VPARAMS ((const char *msg
+ "Please submit a full bug report,\n\
+ with preprocessed source if appropriate.\n\
+ See %s for instructions.\n", GCCBUGURL);
+-  exit (FATAL_EXIT_CODE);
++  exit (ICE_EXIT_CODE);
+ }
+ 
+ void
+@@ -1392,7 +1392,7 @@ error_recursion ()
+ "Please submit a full bug report,\n\
+ with preprocessed source if appropriate.\n\
+ See %s for instructions.\n", GCCBUGURL);
+-  exit (FATAL_EXIT_CODE);
++  exit (ICE_EXIT_CODE);
+ }
+ 
+ /* Given a partial pathname as input, return another pathname that
+--- gcc/cppmain.c.jj	2002-05-03 20:19:22.000000000 +0200
++++ gcc/cppmain.c	2003-10-06 10:35:15.000000000 +0200
+@@ -111,10 +111,33 @@ do_preprocessing (argc, argv)
+      char **argv;
+ {
+   int argi = 1;  /* Next argument to handle.  */
++  int ice_hack = 0;
+ 
+-  argi += cpp_handle_options (pfile, argc - argi , argv + argi);
+-  if (CPP_FATAL_ERRORS (pfile))
+-    return;
++  if (argc >= 1 && strcmp (argv[argc - 1], "--ice-hack") == 0)
++    {
++      ice_hack = 1;
++      for (argi = 1; argi + 1 < argc; argi++)
++	if (strcmp (argv[argi], "-dumpbase") == 0)
++	  {
++	    argv[argi] = "-quiet";
++	    argv[argi + 1] = "-quiet";
++	    break;
++	  }
++      argi = 1;
++    }
++
++  do
++    {
++      argi += cpp_handle_options (pfile, argc - argi, argv + argi);
++      if (CPP_FATAL_ERRORS (pfile))
++        return;
++
++      if (argi >= argc || !ice_hack)
++	break;
++
++      argi++;
++    }
++  while (argi < argc);
+ 
+   if (argi < argc)
+     {
diff --git a/SOURCES/gcc32-java-bytecode.patch b/SOURCES/gcc32-java-bytecode.patch
new file mode 100644
index 0000000..8b865a9
--- /dev/null
+++ b/SOURCES/gcc32-java-bytecode.patch
@@ -0,0 +1,23 @@
+2004-08-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* fold-const.c (fold): If flag_syntax_only, don't depend on
+	BITS_PER_WORD.
+
+--- gcc/fold-const.c.jj	2004-08-14 12:17:15.000000000 +0200
++++ gcc/fold-const.c	2004-08-14 13:00:37.814514205 +0200
+@@ -5204,10 +5204,11 @@ fold (expr)
+ 	      && TREE_CODE (TREE_OPERAND (t, 2)) == code
+ 	      && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))
+ 		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 2), 0)))
+-	      && ! (INTEGRAL_TYPE_P (TREE_TYPE (t))
+-		    && (INTEGRAL_TYPE_P
+-			(TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))))
+-		    && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD))
++	      && (! (INTEGRAL_TYPE_P (TREE_TYPE (t))
++		     && (INTEGRAL_TYPE_P
++			 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))))
++		     && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD)
++		  || flag_syntax_only))
+ 	    t = build1 (code, type,
+ 			build (COND_EXPR,
+ 			       TREE_TYPE (TREE_OPERAND
diff --git a/SOURCES/gcc32-java-intlex.patch b/SOURCES/gcc32-java-intlex.patch
new file mode 100644
index 0000000..3ac22db
--- /dev/null
+++ b/SOURCES/gcc32-java-intlex.patch
@@ -0,0 +1,175 @@
+2002-11-05  Tom Tromey  <tromey@redhat.com>
+
+	Fix for PR java/6388.
+	* lex.h (JAVA_INTEGRAL_RANGE_ERROR): Wrap in do...while.
+	* java-tree.h (enum java_tree_index): New values
+	JTI_DECIMAL_INT_MAX_NODE, JTI_DECIMAL_LONG_MAX_NODE.
+	(decimal_int_max, decimal_long_max): New defines.
+	* lex.c (yylex): Rewrote range checking.  Sign extend literals.
+	(error_if_numeric_overflow): Rewrote range checking.
+	* decl.c (java_init_decl_processing): Initialize decimal_int_max,
+	decimal_long_max.
+
+--- gcc/java/decl.c	2 Nov 2002 21:29:36 -0000	1.134
++++ gcc/java/decl.c	6 Nov 2002 00:01:00 -0000	1.135
+@@ -454,6 +454,20 @@ java_init_decl_processing ()
+   integer_four_node = build_int_2 (4, 0);
+   integer_minus_one_node = build_int_2 (-1, -1);
+ 
++  /* A few values used for range checking in the lexer.  */
++  decimal_int_max = build_int_2 (0x80000000, 0);
++  TREE_TYPE (decimal_int_max) = unsigned_int_type_node;
++#if HOST_BITS_PER_WIDE_INT == 64
++  decimal_long_max = build_int_2 (0x8000000000000000, 0);
++#else
++#if HOST_BITS_PER_WIDE_INT == 32
++  decimal_long_max = build_int_2 (0, 0x80000000);
++#else
++ #error "unsupported size"
++#endif
++#endif
++  TREE_TYPE (decimal_long_max) = unsigned_long_type_node;
++
+   size_zero_node = size_int (0);
+   size_one_node = size_int (1);
+   bitsize_zero_node = bitsize_int (0);
+--- gcc/java/java-tree.h	2 Nov 2002 23:52:26 -0000	1.161
++++ gcc/java/java-tree.h	6 Nov 2002 00:01:00 -0000	1.162
+@@ -275,6 +275,9 @@ enum java_tree_index
+   JTI_UNSIGNED_INT_TYPE_NODE,
+   JTI_UNSIGNED_LONG_TYPE_NODE,
+   
++  JTI_DECIMAL_INT_MAX_NODE,
++  JTI_DECIMAL_LONG_MAX_NODE,
++
+   JTI_BOOLEAN_TYPE_NODE,
+ 
+   JTI_OBJECT_TYPE_NODE,
+@@ -441,6 +444,11 @@ extern GTY(()) tree java_global_trees[JT
+ #define unsigned_long_type_node \
+   java_global_trees[JTI_UNSIGNED_LONG_TYPE_NODE]
+ 
++#define decimal_int_max \
++  java_global_trees[JTI_DECIMAL_INT_MAX_NODE]
++#define decimal_long_max \
++  java_global_trees[JTI_DECIMAL_LONG_MAX_NODE]
++
+ #define boolean_type_node \
+   java_global_trees[JTI_BOOLEAN_TYPE_NODE]
+ 
+--- gcc/java/lex.c	2 Nov 2002 21:29:36 -0000	1.94
++++ gcc/java/lex.c	6 Nov 2002 00:01:01 -0000	1.95
+@@ -1218,34 +1218,35 @@ java_lex (java_lval)
+ 	}
+       /* End borrowed section.  */
+ 
++#ifndef JC1_LITE
+       /* Range checking.  */
+-      if (long_suffix)
++      value = build_int_2 (low, high);
++      /* Temporarily set type to unsigned.  */
++      SET_LVAL_NODE_TYPE (value, (long_suffix
++				  ? unsigned_long_type_node
++				  : unsigned_int_type_node));
++
++      /* For base 10 numbers, only values up to the highest value
++	 (plus one) can be written.  For instance, only ints up to
++	 2147483648 can be written.  The special case of the largest
++	 negative value is handled elsewhere.  For other bases, any
++	 number can be represented.  */
++      if (overflow || (radix == 10
++		       && tree_int_cst_lt (long_suffix
++					   ? decimal_long_max
++					   : decimal_int_max,
++					   value)))
+ 	{
+-	  /* 9223372036854775808L is valid if operand of a '-'. Otherwise
+-	     9223372036854775807L is the biggest `long' literal that can be
+-	     expressed using a 10 radix. For other radices, everything that
+-	     fits withing 64 bits is OK.  */
+-	  int hb = (high >> 31);
+-	  if (overflow || (hb && low && radix == 10)
+-	      || (hb && high & 0x7fffffff && radix == 10))
++	  if (long_suffix)
+ 	    JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal");
+-	}
+-      else
+-	{
+-	  /* 2147483648 is valid if operand of a '-'. Otherwise,
+-	     2147483647 is the biggest `int' literal that can be
+-	     expressed using a 10 radix. For other radices, everything
+-	     that fits within 32 bits is OK.  As all literals are
+-	     signed, we sign extend here.  */
+-	  int hb = (low >> 31) & 0x1;
+-	  if (overflow || high || (hb && low & 0x7fffffff && radix == 10))
++	  else
+ 	    JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
+-	  high = -hb;
+ 	}
+-#ifndef JC1_LITE
+-      value = build_int_2 (low, high);
++
++      /* Sign extend the value.  */
++      SET_LVAL_NODE_TYPE (value, (long_suffix ? long_type_node : int_type_node));
++      force_fit_type (value, 0);
+       JAVA_RADIX10_FLAG (value) = radix == 10;
+-      SET_LVAL_NODE_TYPE (value, long_suffix ? long_type_node : int_type_node);
+ #else
+       SET_LVAL_NODE_TYPE (build_int_2 (low, high),
+ 			  long_suffix ? long_type_node : int_type_node);
+@@ -1661,24 +1662,14 @@ static void
+ error_if_numeric_overflow (value)
+      tree value;
+ {
+-  if (TREE_CODE (value) == INTEGER_CST && JAVA_RADIX10_FLAG (value))
++  if (TREE_CODE (value) == INTEGER_CST
++      && JAVA_RADIX10_FLAG (value)
++      && tree_int_cst_sgn (value) < 0)
+     {
+-      unsigned HOST_WIDE_INT lo, hi;
+-
+-      lo = TREE_INT_CST_LOW (value);
+-      hi = TREE_INT_CST_HIGH (value);
+       if (TREE_TYPE (value) == long_type_node)
+-	{
+-	  int hb = (hi >> 31);
+-	  if (hb && !(hi & 0x7fffffff))
+-	    java_lex_error ("Numeric overflow for `long' literal", 0);
+-	}
++	java_lex_error ("Numeric overflow for `long' literal", 0);
+       else
+-	{
+-	  int hb = (lo >> 31) & 0x1;
+-	  if (hb && !(lo & 0x7fffffff))
+-	    java_lex_error ("Numeric overflow for `int' literal", 0);
+-	}
++	java_lex_error ("Numeric overflow for `int' literal", 0);
+     }
+ }
+ #endif /* JC1_LITE */
+--- gcc/java/lex.h	2 Nov 2002 21:29:36 -0000	1.28
++++ gcc/java/lex.h	6 Nov 2002 00:01:01 -0000	1.29
+@@ -185,7 +185,7 @@ extern void java_destroy_lexer PARAMS ((
+ #define SET_LVAL_NODE_TYPE(NODE, TYPE)
+ #define BUILD_ID_WFL(EXP) (EXP)
+ #define JAVA_FLOAT_RANGE_ERROR(S) {}
+-#define JAVA_INTEGRAL_RANGE_ERROR(S) {}
++#define JAVA_INTEGRAL_RANGE_ERROR(S) do { } while (0)
+ 
+ #else
+ 
+@@ -237,12 +237,12 @@ extern void java_destroy_lexer PARAMS ((
+     ctxp->c_line->current = i;						  \
+   }
+ #define JAVA_INTEGRAL_RANGE_ERROR(m)		\
+-  {						\
++  do {						\
+     int i = ctxp->c_line->current;		\
+     ctxp->c_line->current = number_beginning;	\
+     java_lex_error (m, 0);			\
+     ctxp->c_line->current = i;			\
+-  }
++  } while (0)
+ 
+ #endif /* Definitions for jc1 compilation only */
+ 
diff --git a/SOURCES/gcc32-java-nan.patch b/SOURCES/gcc32-java-nan.patch
new file mode 100644
index 0000000..b664554
--- /dev/null
+++ b/SOURCES/gcc32-java-nan.patch
@@ -0,0 +1,27 @@
+2004-08-13  Andrew Haley  <aph@redhat.com>
+
+	* jcf-write.c (find_constant_index): Canonicalize NaN.
+
+--- gcc/java/jcf-write.c.jj	2002-10-16 22:36:11.000000000 +0100
++++ gcc/java/jcf-write.c	2004-08-13 17:10:37.000000000 +0100
+@@ -828,12 +828,20 @@
+       long words[2];
+       if (TYPE_PRECISION (TREE_TYPE (value)) == 32)
+ 	{
++	  if (REAL_VALUE_ISNAN (TREE_REAL_CST (value))
++	      && flag_emit_class_files)
++	    return find_constant1 (&state->cpool, CONSTANT_Float,
++				   0x7fc00000);
+ 	  words[0] = etarsingle (TREE_REAL_CST (value)) & 0xFFFFFFFF;
+ 	  return find_constant1 (&state->cpool, CONSTANT_Float, 
+ 				 (jword)words[0]);
+ 	}
+       else
+ 	{
++	  if (REAL_VALUE_ISNAN (TREE_REAL_CST (value))
++	      && flag_emit_class_files)
++	    return find_constant2 (&state->cpool, CONSTANT_Double,
++				   0x7ff80000, 0x00000000);
+ 	  etardouble (TREE_REAL_CST (value), words);
+ 	  return find_constant2 (&state->cpool, CONSTANT_Double,
+ 				 (jword)(words[1-FLOAT_WORDS_BIG_ENDIAN] & 
diff --git a/SOURCES/gcc32-java-zoneinfo.patch b/SOURCES/gcc32-java-zoneinfo.patch
new file mode 100644
index 0000000..6598017
--- /dev/null
+++ b/SOURCES/gcc32-java-zoneinfo.patch
@@ -0,0 +1,4206 @@
+2007-02-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* java/util/TimeZone.java (getDefaultDisplayName): Don't
+	check if TimeZone is instanceof SimpleTimeZone.
+
+2007-02-23  Jakub Jelinek  <jakub@redhat.com>
+
+	PR libgcj/17002
+	PR classpath/28550
+	* java/lang/System.java: Add gnu.java.util.zoneinfo.dir to comments.
+	* posix.cc (_Jv_platform_initProperties): Set
+	gnu.java.util.zoneinfo.dir.
+	* Makefile.am (ordinary_java_source_files): Add
+	gnu/java/util/ZoneInfo.java.
+	* Makefile.in: Regenerated.
+	* java/util/Date.java (parse): Properly parse 09:01:02 as
+	hours/minutes/seconds, not as hours/minutes/year.
+	* java/util/SimpleTimeZone.java (getOffset): Handle properly
+	millis + dstOffset overflowing into the next day.
+	* java/util/TimeZone.java (zoneinfo_dir, availableIDs, aliases0): New
+	static fields.
+	(timezones): Remove synchronized keyword.  Set zoneinfo_dir.
+	If non-null, set up aliases0 and don't put anything into
+	timezones0.
+	(defaultZone): Call getTZEnvVar to try TZ env var.
+	Try to read /etc/localtime using ZoneInfo.readTZFile.
+	Call getDefaultTimeZone instead of getTimeZone.
+	(getDefaultTimeZone, getDateParams, parseTime): New private methods.
+	(getTimeZoneInternal): New private method.
+	(getTimeZone): Do the custom ID checking first, canonicalize
+	ID for custom IDs as required by documentation.  Call
+	getTimeZoneInternal to handle the rest.
+	(getAvailableIDs(int)): Add locking.  Handle zoneinfo_dir != null.
+	(getAvailableIDs(File,String,ArrayList)): New private method.
+	(getAvailableIDs()): Add locking.  Handle zoneinfo_dir != null.
+	(readSysconfigClockFile): New static method.
+	(getTZEnvVar): New native method.
+	* java/util/natSystem.cc: Include java/lang/Character.h and
+	java/lang/Integer.h.
+	(java::lang::System::getSystemTimeZone): Renamed to...
+	(getSystemTimeZone): ... this.  Add static.
+	(java::lang::System::init_properties): Don't set user.timezone
+	property.
+	(java::util::TimeZone::getDefaultTimeZoneId): New.
+	(java::util::TimeZone::getTZEnvVar): New method.
+	* gnu/java/util/ZoneInfo.java: New file.
+	* java/util/GregorianCalendar.java
+	(GregorianCalendar): Call clear before set in the constructors that
+	don't initialize it to current time.
+
+2007-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+	PR 23566
+	* java/util/TimeZone.java (timezones): Regenerate from tzdata2007a.
+
+2005-02-21  Jeroen Frijters  <jeroen@frijters.net>
+
+	* java/util/GregorianCalendar.java
+	(GregorianCalendar): Chained constructors to a (new)
+	common constructor.
+
+2004-01-03  Per Bothner  <per@bothner.com>
+
+	* java/util/Date.java (parse):  Fix a number of problems.
+	(skipParens):  Remove no-longer-needed method.
+
+2003-11-27  Ito Kazumitsu  <kaz@maczuka.gcd.org>
+
+	* java/util/GregorianCalendar.java (getLinearTime): Avoid counting
+	the leap day of the leap year twice.
+
+2003-09-18  Ingo Proetel  <proetel@aicas.com>
+
+	* java/util/TimeZone.java: Initialize lazily.
+
+2002-05-13  Tom Tromey  <tromey@redhat.com>
+
+	* java/util/TimeZone.java (getDefaultTimeZoneId): New method.
+
+--- libjava/Makefile.am.jj	2007-02-23 21:17:39.000000000 +0100
++++ libjava/Makefile.am	2007-02-23 21:28:22.000000000 +0100
+@@ -1431,6 +1431,7 @@ gnu/java/text/LineBreakIterator.java \
+ gnu/java/text/SentenceBreakIterator.java	\
+ gnu/java/text/WordBreakIterator.java \
+ gnu/java/util/DoubleEnumeration.java \
++gnu/java/util/ZoneInfo.java \
+ java/lang/ref/PhantomReference.java \
+ java/lang/ref/Reference.java \
+ java/lang/ref/ReferenceQueue.java \
+--- libjava/Makefile.in.jj	2007-02-23 21:17:39.000000000 +0100
++++ libjava/Makefile.in	2007-02-23 21:28:55.000000000 +0100
+@@ -1183,6 +1183,7 @@ gnu/java/text/LineBreakIterator.java \
+ gnu/java/text/SentenceBreakIterator.java	\
+ gnu/java/text/WordBreakIterator.java \
+ gnu/java/util/DoubleEnumeration.java \
++gnu/java/util/ZoneInfo.java \
+ java/lang/ref/PhantomReference.java \
+ java/lang/ref/Reference.java \
+ java/lang/ref/ReferenceQueue.java \
+@@ -2017,7 +2018,8 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_D
+ .deps/gnu/java/text/LineBreakIterator.P \
+ .deps/gnu/java/text/SentenceBreakIterator.P \
+ .deps/gnu/java/text/WordBreakIterator.P \
+-.deps/gnu/java/util/DoubleEnumeration.P .deps/interpret.P \
++.deps/gnu/java/util/DoubleEnumeration.P \
++.deps/gnu/java/util/ZoneInfo.P .deps/interpret.P \
+ .deps/java/applet/Applet.P .deps/java/applet/AppletContext.P \
+ .deps/java/applet/AppletStub.P .deps/java/applet/AudioClip.P \
+ .deps/java/awt/AWTError.P .deps/java/awt/AWTEvent.P \
+--- libjava/java/util/GregorianCalendar.java.jj	2007-02-23 21:17:36.000000000 +0100
++++ libjava/java/util/GregorianCalendar.java	2007-02-26 09:54:12.000000000 +0100
+@@ -111,6 +111,13 @@ public class GregorianCalendar extends C
+     this(TimeZone.getDefault(), locale);
+   }
+ 
++  private GregorianCalendar(TimeZone zone, Locale locale, boolean unused)
++  {
++    super(zone, locale);
++    ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale);
++    gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime();
++  }
++
+   /**
+    * Constructs a new GregorianCalender representing the current
+    * time with the given time zone and the given locale.
+@@ -119,9 +126,7 @@ public class GregorianCalendar extends C
+    */
+   public GregorianCalendar(TimeZone zone, Locale locale)
+   {
+-    super(zone, locale);
+-    ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale);
+-    gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime();
++    this(zone, locale, false);
+     setTimeInMillis(System.currentTimeMillis());
+   }
+ 
+@@ -134,7 +139,8 @@ public class GregorianCalendar extends C
+    */
+   public GregorianCalendar(int year, int month, int day)
+   {
+-    super();
++    this(TimeZone.getDefault(), Locale.getDefault(), false);
++    clear();
+     set(year, month, day);
+   }
+ 
+@@ -149,7 +155,8 @@ public class GregorianCalendar extends C
+    */
+   public GregorianCalendar(int year, int month, int day, int hour, int minute)
+   {
+-    super();
++    this(TimeZone.getDefault(), Locale.getDefault(), false);
++    clear();
+     set(year, month, day, hour, minute);
+   }
+ 
+@@ -166,7 +173,8 @@ public class GregorianCalendar extends C
+   public GregorianCalendar(int year, int month, int day,
+ 			   int hour, int minute, int second)
+   {
+-    super();
++    this(TimeZone.getDefault(), Locale.getDefault(), false);
++    clear();
+     set(year, month, day, hour, minute, second);
+   }
+ 
+@@ -254,8 +262,10 @@ public class GregorianCalendar extends C
+ 	//
+ 	// The additional leap year factor accounts for the fact that
+ 	// a leap day is not seen on Jan 1 of the leap year.
++	// And on and after the leap day, the leap day has already been
++	// included in dayOfYear.
+ 	int gregOffset = (year / 400) - (year / 100) + 2;
+-	if (isLeapYear (year, true) && dayOfYear < 31 + 29)
++	if (isLeapYear (year, true))
+ 	  --gregOffset;
+ 	time += gregOffset * (24 * 60 * 60 * 1000L);
+       }
+--- libjava/java/util/SimpleTimeZone.java.jj	2007-02-23 21:17:36.000000000 +0100
++++ libjava/java/util/SimpleTimeZone.java	2007-02-23 21:27:21.000000000 +0100
+@@ -458,16 +458,34 @@ public class SimpleTimeZone extends Time
+     int daylightSavings = 0;
+     if (useDaylight && era == GregorianCalendar.AD && year >= startYear)
+       {
++	int orig_year = year;
+ 	// This does only work for Gregorian calendars :-(
+ 	// This is mainly because setStartYear doesn't take an era.
+ 
+ 	boolean afterStart = !isBefore(year, month, day, dayOfWeek, millis,
+ 				       startMode, startMonth,
+ 				       startDay, startDayOfWeek, startTime);
++	millis += dstSavings;
++	if (millis >= 24 * 60 * 60 * 1000)
++	  {
++	    millis -= 24 * 60 * 60 * 1000;
++	    dayOfWeek = (dayOfWeek % 7) + 1;
++	    if (++day > getDaysInMonth(month, year))
++	      {
++		day = 1;
++		if (month++ == Calendar.DECEMBER)
++		  {
++		    month = Calendar.JANUARY;
++		    year++;
++		  }
++	      }
++	  }
+ 	boolean beforeEnd = isBefore(year, month, day, dayOfWeek, millis,
+ 				     endMode, endMonth,
+ 				     endDay, endDayOfWeek, endTime);
+ 
++	if (orig_year != year)
++	  afterStart = false;
+ 	if (startMonth < endMonth)
+ 	  {
+ 	    // use daylight savings, if the date is after the start of
+--- libjava/java/util/Date.java.jj	2007-02-23 21:17:36.000000000 +0100
++++ libjava/java/util/Date.java	2007-02-26 09:43:28.000000000 +0100
+@@ -304,34 +304,6 @@ public class Date implements Cloneable, 
+     return format.format(this);
+   }
+ 
+-  private static int skipParens(String string, int offset)
+-  {
+-    int len = string.length();
+-    int p = 0;
+-    int i;
+-
+-    for (i = offset; i < len; ++i)
+-      {
+-	if (string.charAt(i) == '(')
+-	  ++p;
+-	else if (string.charAt(i) == ')')
+-	  {
+-	    --p;
+-	    if (p == 0)
+-	      return i + 1;
+-	    // If we've encounted unbalanced parens, just return the
+-	    // leftover one as an ordinary character.  It will be
+-	    // caught later in parsing and cause an
+-	    // IllegalArgumentException.
+-      	    if (p < 0)
+-	      return i;
+-	  }
+-      }
+-
+-    // Not sure what to do if `p != 0' here.
+-    return i;
+-  }
+-
+   private static int parseTz(String tok, char sign)
+     throws IllegalArgumentException
+   {
+@@ -408,20 +380,25 @@ public class Date implements Cloneable, 
+ 
+     // Trim out any nested stuff in parentheses now to make parsing easier.
+     StringBuffer buf = new StringBuffer();
+-    int off = 0;
+-    int openParenOffset, tmpMonth;
+-    while ((openParenOffset = string.indexOf('(', off)) >= 0)
++    int parenNesting = 0;
++    int len = string.length();
++    for (int i = 0;  i < len;  i++)
+       {
+-	// Copy part of string leading up to open paren.
+-	buf.append(string.substring(off, openParenOffset));
+-	off = skipParens(string, openParenOffset);
++	char ch = string.charAt(i);
++	if (ch >= 'a' && ch <= 'z')
++	  ch -= 'a' - 'A';
++	if (ch == '(')
++	  parenNesting++;
++	else if (parenNesting == 0)
++	  buf.append(ch);
++	else if (ch == ')')
++	  parenNesting--;
+       }
+-    buf.append(string.substring(off));
++    int tmpMonth;
+ 
+     // Make all chars upper case to simplify comparisons later.
+     // Also ignore commas; treat them as delimiters.
+-    StringTokenizer strtok =
+-      new StringTokenizer(buf.toString().toUpperCase(), " \t\n\r,");
++    StringTokenizer strtok = new StringTokenizer(buf.toString(), " \t\n\r,");
+ 
+     while (strtok.hasMoreTokens())
+       {
+@@ -434,58 +411,69 @@ public class Date implements Cloneable, 
+ 	  }
+ 	else if (firstch >= '0' && firstch <= '9')
+ 	  {
++	    int lastPunct = -1;
+ 	    while (tok != null && tok.length() > 0)
+ 	      {
+-	        // A colon or slash may be valid in the number.
+-	        // Find the first of these before calling parseInt.
+-	        int colon = tok.indexOf(':');
+-	        int slash = tok.indexOf('/');
+-	        int hyphen = tok.indexOf('-');
+-		// We choose tok.length initially because it makes
+-		// processing simpler.
+-	        int punctOffset = tok.length();
+-		if (colon >= 0)
+-		  punctOffset = Math.min(punctOffset, colon);
+-	        if (slash >= 0)
+-	          punctOffset = Math.min(punctOffset, slash);
+-	        if (hyphen >= 0)
+-	          punctOffset = Math.min(punctOffset, hyphen);
+-		// Following code relies on -1 being the exceptional
+-		// case.
+-		if (punctOffset == tok.length())
+-		  punctOffset = -1;
+-
+-	        int num;
+-	        try
+-	          {
+-		    num = Integer.parseInt(punctOffset < 0 ? tok :
+-					   tok.substring(0, punctOffset));
+-	          }
+-	        catch (NumberFormatException ex)
+-	          {
+-		    throw new IllegalArgumentException(tok);
+-	          }
+-
+-		// TBD: Spec says year can be followed by a slash.  That might
+-		// make sense if using YY/MM/DD formats, but it would fail in
+-		// that format for years <= 70.  Also, what about 1900?  That
+-		// is interpreted as the year 3800; seems that the comparison
+-		// should be num >= 1900 rather than just > 1900.
+-		// What about a year of 62 - 70?  (61 or less could be a (leap)
+-		// second).  70/MM/DD cause an exception but 71/MM/DD is ok
+-		// even though there's no ambiguity in either case.
+-		// For the parse method, the spec as written seems too loose.
+-		// Until shown otherwise, we'll follow the spec as written.
+-	        if (num > 70 && (punctOffset < 0 || punctOffset == slash))
+-		  year = num > 1900 ? num - 1900 : num;
+-		else if (punctOffset > 0 && punctOffset == colon)
++		int punctOffset = tok.length();
++		int num = 0;
++		int punct;
++		for (int i = 0;  ;  i++)
++		  {
++		    if (i >= punctOffset)
++		      {
++			punct = -1;
++			break;
++		      }
++		    else
++		      {
++			punct = tok.charAt(i);
++			if (punct >= '0' && punct <= '9')
++			  {
++			    if (num > 999999999) // in case of overflow
++			      throw new IllegalArgumentException(tok);
++			    num = 10 * num + (punct - '0');
++			  }
++			else
++			  {
++			    punctOffset = i;
++			    break;
++			  }
++		      }
++		      
++		  }
++
++		if (punct == ':')
+ 		  {
+ 		    if (hour < 0)
+ 		      hour = num;
+ 		    else
+ 		      minute = num;
+ 		  }
+-		else if (punctOffset > 0 && punctOffset == slash)
++		else if (lastPunct == ':' && hour >= 0 && (minute < 0 || second < 0))
++		  {
++		    if (minute < 0)
++		      minute = num;
++		    else
++		      second = num;
++		  }
++	        else if ((num >= 70
++			  && (punct == ' ' || punct == ','
++			      || punct == '/' || punct < 0))
++			 || (num < 70 && day >= 0 && month >= 0 && year < 0))
++		  {
++		    if (num >= 100)
++		      year = num;
++		    else
++		      {
++			int curYear = 1900 + new Date().getYear();
++			int firstYear = curYear - 80;
++			year = firstYear / 100 * 100 + num;
++			int yx = year;
++			if (year < firstYear)
++			  year += 100;
++		      }
++		  }
++		else if (punct == '/')
+ 		  {
+ 		    if (month < 0)
+ 		      month = num - 1;
+@@ -502,10 +490,11 @@ public class Date implements Cloneable, 
+ 		  throw new IllegalArgumentException(tok);
+ 
+ 		// Advance string if there's more to process in this token.
+-		if (punctOffset < 0 || punctOffset + 1 >= tok.length())
++		if (punct < 0 || punctOffset + 1 >= tok.length())
+ 		  tok = null;
+ 		else
+ 		  tok = tok.substring(punctOffset + 1);
++		lastPunct = punct;
+ 	      }
+ 	  }
+ 	else if (firstch >= 'A' && firstch <= 'Z')
+@@ -573,22 +562,29 @@ public class Date implements Cloneable, 
+ 	  throw new IllegalArgumentException(tok);
+       }
+ 
+-    // Unspecified minutes and seconds should default to 0.
++    // Unspecified hours, minutes, or seconds should default to 0.
++    if (hour < 0)
++      hour = 0;
+     if (minute < 0)
+       minute = 0;
+     if (second < 0)
+       second = 0;
+ 
+     // Throw exception if any other fields have not been recognized and set.
+-    if (year < 0 || month < 0 || day < 0 || hour < 0)
++    if (year < 0 || month < 0 || day < 0)
+       throw new IllegalArgumentException("Missing field");
+ 
+     // Return the time in either local time or relative to GMT as parsed.
+     // If no time-zone was specified, get the local one (in minutes) and
+     // convert to milliseconds before adding to the UTC.
+-    return UTC(year, month, day, hour, minute, second) + (localTimezone ?
+-		new Date(year, month, day).getTimezoneOffset() * 60 * 1000:
+-		-timezone * 60 * 1000);
++    GregorianCalendar cal
++      = new GregorianCalendar(year, month, day, hour, minute, second);
++    if (!localTimezone)
++      {
++	cal.set(Calendar.ZONE_OFFSET, timezone * 60 * 1000);
++	cal.set(Calendar.DST_OFFSET, 0);
++      }
++    return cal.getTimeInMillis();
+   }
+ 
+   /**
+--- libjava/java/lang/natSystem.cc.jj	2007-02-23 21:17:31.000000000 +0100
++++ libjava/java/lang/natSystem.cc	2007-02-24 22:04:41.000000000 +0100
+@@ -51,6 +51,8 @@ details.  */
+ #include <java/lang/Class.h>
+ #include <java/lang/ArrayStoreException.h>
+ #include <java/lang/ArrayIndexOutOfBoundsException.h>
++#include <java/lang/Character.h>
++#include <java/lang/Integer.h>
+ #include <java/lang/NullPointerException.h>
+ #include <java/lang/StringBuffer.h>
+ #include <java/util/Properties.h>
+@@ -229,61 +231,6 @@ getpwuid_adaptor(T_passwd * (*getpwuid_r
+ }
+ #endif
+ 
+-/*
+- * This method returns a time zone string that is used by init_properties
+- * to set the default timezone property 'user.timezone'.  That value is
+- * used by default as a key into the timezone table used by the
+- * java::util::TimeZone class.
+- */
+-jstring
+-java::lang::System::getSystemTimeZone (void)
+-{
+-  struct tm *tim;
+-  time_t current_time;
+-  long tzoffset;
+-  const char *tz1, *tz2;
+-  char *tzid;
+-
+-  current_time = time(0);
+-
+-  mktime(tim = localtime(&current_time));
+-#ifdef STRUCT_TM_HAS_GMTOFF
+-  // tm_gmtoff is secs EAST of UTC.
+-  tzoffset = -(tim->tm_gmtoff) + tim->tm_isdst * 3600L;
+-#elif HAVE_TIMEZONE
+-  // timezone is secs WEST of UTC.
+-  tzoffset = timezone;	
+-#else
+-  // FIXME: there must be another global if neither tm_gmtoff nor timezone
+-  // is available, esp. if tzname is valid.
+-  // Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
+-  // calculate between gmtime and localtime (and accounting for possible
+-  // daylight savings time) as an alternative.
+-  tzoffset = 0L;
+-#endif
+-
+-#ifdef HAVE_TM_ZONE
+-  tz1 = tim->tm_zone;
+-  tz2 = "";
+-#elif defined (HAVE_TZNAME)
+-  tz1 = tzname[0];
+-  tz2 = strcmp (tzname[0], tzname[1]) ? tzname[1] : "";
+-#else
+-  // Some targets have no concept of timezones.
+-  tz1 = "???";
+-  tz2 = tz1;
+-#endif
+-
+-  if ((tzoffset % 3600) == 0)
+-    tzoffset = tzoffset / 3600;
+-
+-  tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
+-  sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
+-  jstring retval = JvNewStringUTF (tzid);
+-  _Jv_Free (tzid);
+-
+-  return retval;
+-}
+ 
+ extern void _Jv_SetDLLSearchPath (const char *);
+ 
+@@ -441,11 +388,6 @@ java::lang::System::init_properties (voi
+       SET ("user.region", "US");
+     }  
+ 
+-  // Set the "user.timezone" property.
+-  jstring timezone = getDefaultTimeZoneId ();
+-  if (timezone != NULL)
+-    newprops->put (JvNewStringLatin1 ("user.timezone"), timezone);
+-
+   // Set some properties according to whatever was compiled in with
+   // `-D'.
+   for (int i = 0; _Jv_Compiler_Properties[i]; ++i)
+@@ -529,3 +471,146 @@ java::lang::System::init_properties (voi
+   // synchronized in the common case.
+   properties = newprops;
+ }
++
++/*
++ * This method returns a time zone string that is used by init_properties
++ * to set the default timezone property 'user.timezone'.  That value is
++ * used by default as a key into the timezone table used by the
++ * java::util::TimeZone class.
++ */
++static jstring
++getSystemTimeZone (void)
++{
++  struct tm *tim;
++  time_t current_time;
++  long tzoffset;
++  const char *tz1, *tz2;
++  char *tzid;
++
++  current_time = time(0);
++
++  mktime(tim = localtime(&current_time));
++#ifdef STRUCT_TM_HAS_GMTOFF
++  // tm_gmtoff is secs EAST of UTC.
++  tzoffset = -(tim->tm_gmtoff) + tim->tm_isdst * 3600L;
++#elif HAVE_TIMEZONE
++  // timezone is secs WEST of UTC.
++  tzoffset = timezone;	
++#else
++  // FIXME: there must be another global if neither tm_gmtoff nor timezone
++  // is available, esp. if tzname is valid.
++  // Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
++  // calculate between gmtime and localtime (and accounting for possible
++  // daylight savings time) as an alternative.
++  tzoffset = 0L;
++#endif
++
++#ifdef HAVE_TM_ZONE
++  tz1 = tim->tm_zone;
++  tz2 = "";
++#elif defined (HAVE_TZNAME)
++  tz1 = tzname[0];
++  tz2 = strcmp (tzname[0], tzname[1]) ? tzname[1] : "";
++#else
++  // Some targets have no concept of timezones.
++  tz1 = "???";
++  tz2 = tz1;
++#endif
++
++  if ((tzoffset % 3600) == 0)
++    tzoffset = tzoffset / 3600;
++
++  tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
++  sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
++  jstring retval = JvNewStringUTF (tzid);
++  _Jv_Free (tzid);
++
++  return retval;
++}
++
++// Get the System Timezone as reported by the OS.  It should be in
++// the form PST8PDT so we'll need to parse it and check that it's valid.
++// FIXME: Using the code from Classpath for generating the System
++// Timezone IMO is suboptimal because it ignores whether the rules for
++// DST match up.
++jstring
++java::util::TimeZone::getDefaultTimeZoneId ()
++{
++  jstring sysTimeZoneId = getSystemTimeZone ();
++
++  using namespace java::lang;
++
++  // Check if this is a valid timezone.  Make sure the IDs match
++  // since getTimeZone returns GMT if no match is found.
++  TimeZone *tz = TimeZone::getTimeZone (sysTimeZoneId);
++  if (tz->getID ()->equals (sysTimeZoneId))
++    return sysTimeZoneId;
++
++  // Check if the base part of sysTimeZoneId is a valid timezone that
++  // matches with daylight usage and rawOffset.  Make sure the IDs match
++  // since getTimeZone returns GMT if no match is found.
++  // First find start of GMT offset info and any Daylight zone name.
++  int startGMToffset = 0;
++  int sysTimeZoneIdLength = sysTimeZoneId->length();
++  for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++)
++    {
++      if (Character::isDigit (sysTimeZoneId->charAt (i)))
++	startGMToffset = i;
++    }
++
++  int startDaylightZoneName = 0;
++  jboolean usesDaylight = false;
++  for (int i = sysTimeZoneIdLength - 1;
++       i >= 0 && !Character::isDigit (sysTimeZoneId->charAt (i)); --i)
++    {
++      startDaylightZoneName = i;
++    }
++  if (startDaylightZoneName > 0)
++    usesDaylight = true;
++
++  int GMToffset
++    = Integer::parseInt (startDaylightZoneName == 0 ?
++			 sysTimeZoneId->substring (startGMToffset) :
++			 sysTimeZoneId->substring (startGMToffset,
++						   startDaylightZoneName));
++
++  // Offset could be in hours or seconds.  Convert to millis.
++  if (GMToffset < 24)
++    GMToffset *= 60 * 60;
++  GMToffset *= -1000;
++
++  jstring tzBasename = sysTimeZoneId->substring (0, startGMToffset);
++  tz = TimeZone::getTimeZone (tzBasename);
++  if (tz->getID ()->equals (tzBasename) && tz->getRawOffset () == GMToffset)
++    {
++      jboolean tzUsesDaylight = tz->useDaylightTime ();
++      if (usesDaylight && tzUsesDaylight || !usesDaylight && !tzUsesDaylight)
++	return tzBasename;
++    }
++
++  // If no match, see if a valid timezone has the same attributes as this
++  // and then use it instead.
++  jstringArray IDs = TimeZone::getAvailableIDs (GMToffset);
++  jstring *elts = elements (IDs);
++  for (int i = 0; i < IDs->length; ++i)
++    {
++      // FIXME: The daylight savings rules may not match the rules
++      // for the desired zone.
++      jboolean IDusesDaylight =
++	TimeZone::getTimeZone (elts[i])->useDaylightTime ();
++      if (usesDaylight && IDusesDaylight || !usesDaylight && !IDusesDaylight)
++	return elts[i];
++    }
++
++  // If all else fails, return null.
++  return NULL;
++}
++
++jstring
++java::util::TimeZone::getTZEnvVar ()
++{
++  const char *tzenv = ::getenv ("TZ");
++  if (tzenv == NULL)
++    return NULL;
++  return JvNewStringUTF (tzenv);
++}
+--- libjava/java/util/TimeZone.java.jj	2007-02-23 21:17:36.000000000 +0100
++++ libjava/java/util/TimeZone.java	2007-02-24 21:54:41.000000000 +0100
+@@ -1,5 +1,6 @@
+ /* java.util.TimeZone
+-   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
++   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
++   Free Software Foundation, Inc.
+ 
+ This file is part of GNU Classpath.
+ 
+@@ -37,6 +38,13 @@ exception statement from your version. *
+ 
+ 
+ package java.util;
++import gnu.java.util.ZoneInfo;
++import java.io.BufferedInputStream;
++import java.io.BufferedReader;
++import java.io.File;
++import java.io.FileInputStream;
++import java.io.InputStreamReader;
++import java.io.IOException;
+ import java.text.DateFormatSymbols;
+ 
+ /**
+@@ -79,690 +87,1215 @@ public abstract class TimeZone implement
+   /**
+    * The default time zone, as returned by getDefault.
+    */
+-  private static TimeZone defaultZone;
++  private static TimeZone defaultZone0;
++  /* initialize this static field lazily to overhead if
++   * it is not needed: 
++   */
++  private static synchronized TimeZone defaultZone() {
++    /* Look up default timezone */
++    if (defaultZone0 == null) 
++      {
++        // System.loadLibrary("javautil");
++	String tzid = System.getProperty("user.timezone");
++
++	if (tzid == null)
++	  {
++	    tzid = getTZEnvVar();
++	    if (tzid != null && tzid.equals(""))
++	      tzid = null;
++	  }
++
++	if (tzid == null)
++	  {
++	    TimeZone zone = ZoneInfo.readTZFile((String) null, "/etc/localtime");
++	    if (zone != null)
++	      {
++		// Try to find a more suitable ID for the /etc/localtime
++		// timezone.
++		// Sometimes /etc/localtime is a symlink to some
++		// /usr/share/zoneinfo/ file.
++		String id = null;
++		try
++		  {
++		    id = new File("/etc/localtime").getCanonicalPath();
++		    if (id != null)
++		      {
++			String zoneinfo_dir
++			  = System.getProperty("gnu.java.util.zoneinfo.dir");
++			if (zoneinfo_dir != null)
++			  zoneinfo_dir
++			    = new File(zoneinfo_dir
++				       + File.separatorChar).getCanonicalPath();
++			if (zoneinfo_dir != null && id.startsWith(zoneinfo_dir))
++			  {
++			    int pos = zoneinfo_dir.length();
++			    while (pos < id.length()
++				   && id.charAt(pos) == File.separatorChar)
++			      pos++;
++			    if (pos < id.length())
++			      id = id.substring(pos);
++			    else
++			      id = null;
++			  }
++			else
++			  id = null;
++		      }
++		  }
++		catch (IOException ioe)
++		  {
++		    id = null;
++		  }
++
++		if (id == null)
++		  id = readSysconfigClockFile("/etc/sysconfig/clock");
++
++		if (id != null)
++		  zone.setID(id);
++		defaultZone0 = zone;
++		return defaultZone0;
++	      }
++	  }
++
++	if (tzid == null)
++	  tzid = getDefaultTimeZoneId();
++
++	if (tzid == null)
++	  tzid = "GMT";
++
++	defaultZone0 = getDefaultTimeZone(tzid);
++      }
++    return defaultZone0; 
++  }
++
+ 
+   private static final long serialVersionUID = 3581463369166924961L;
+ 
+   /**
+-   * Hashtable for timezones by ID.  
++   * Flag whether zoneinfo data should be used,
++   * otherwise builtin timezone data will be provided.
+    */
+-  private static final Hashtable timezones = new Hashtable();
++  private static String zoneinfo_dir;
+ 
+-  static
+-  {
+-    TimeZone tz;
+-    // Automatically generated by scripts/timezones.pl
+-    // XXX - Should we read this data from a file?
+-    tz = new SimpleTimeZone(-11000 * 3600, "MIT");
+-    timezones.put("MIT", tz);
+-    timezones.put("Pacific/Apia", tz);
+-    timezones.put("Pacific/Midway", tz);
+-    timezones.put("Pacific/Niue", tz);
+-    timezones.put("Pacific/Pago_Pago", tz);
+-    tz = new SimpleTimeZone
+-      (-10000 * 3600, "America/Adak",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("America/Adak", tz);
+-    tz = new SimpleTimeZone(-10000 * 3600, "HST");
+-    timezones.put("HST", tz);
+-    timezones.put("Pacific/Fakaofo", tz);
+-    timezones.put("Pacific/Honolulu", tz);
+-    timezones.put("Pacific/Johnston", tz);
+-    timezones.put("Pacific/Rarotonga", tz);
+-    timezones.put("Pacific/Tahiti", tz);
+-    tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas");
+-    timezones.put("Pacific/Marquesas", tz);
+-    tz = new SimpleTimeZone
+-      (-9000 * 3600, "AST",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("AST", tz);
+-    timezones.put("America/Anchorage", tz);
+-    timezones.put("America/Juneau", tz);
+-    timezones.put("America/Nome", tz);
+-    timezones.put("America/Yakutat", tz);
+-    tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier");
+-    timezones.put("Pacific/Gambier", tz);
+-    tz = new SimpleTimeZone
+-      (-8000 * 3600, "PST",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("PST", tz);
+-    timezones.put("PST8PDT", tz);
+-    timezones.put("America/Dawson", tz);
+-    timezones.put("America/Los_Angeles", tz);
+-    timezones.put("America/Tijuana", tz);
+-    timezones.put("America/Vancouver", tz);
+-    timezones.put("America/Whitehorse", tz);
+-    timezones.put("US/Pacific-New", tz);
+-    tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn");
+-    timezones.put("Pacific/Pitcairn", tz);
+-    tz = new SimpleTimeZone
+-      (-7000 * 3600, "MST",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("MST", tz);
+-    timezones.put("MST7MDT", tz);
+-    timezones.put("America/Boise", tz);
+-    timezones.put("America/Chihuahua", tz);
+-    timezones.put("America/Denver", tz);
+-    timezones.put("America/Edmonton", tz);
+-    timezones.put("America/Inuvik", tz);
+-    timezones.put("America/Mazatlan", tz);
+-    timezones.put("America/Shiprock", tz);
+-    timezones.put("America/Yellowknife", tz);
+-    tz = new SimpleTimeZone(-7000 * 3600, "MST7");
+-    timezones.put("MST7", tz);
+-    timezones.put("PNT", tz);
+-    timezones.put("America/Dawson_Creek", tz);
+-    timezones.put("America/Hermosillo", tz);
+-    timezones.put("America/Phoenix", tz);
+-    tz = new SimpleTimeZone
+-      (-6000 * 3600, "CST",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("CST", tz);
+-    timezones.put("CST6CDT", tz);
+-    timezones.put("America/Cambridge_Bay", tz);
+-    timezones.put("America/Cancun", tz);
+-    timezones.put("America/Chicago", tz);
+-    timezones.put("America/Menominee", tz);
+-    timezones.put("America/Merida", tz);
+-    timezones.put("America/Mexico_City", tz);
+-    timezones.put("America/Monterrey", tz);
+-    timezones.put("America/Rainy_River", tz);
+-    timezones.put("America/Winnipeg", tz);
+-    tz = new SimpleTimeZone(-6000 * 3600, "America/Belize");
+-    timezones.put("America/Belize", tz);
+-    timezones.put("America/Costa_Rica", tz);
+-    timezones.put("America/El_Salvador", tz);
+-    timezones.put("America/Guatemala", tz);
+-    timezones.put("America/Managua", tz);
+-    timezones.put("America/Regina", tz);
+-    timezones.put("America/Swift_Current", tz);
+-    timezones.put("America/Tegucigalpa", tz);
+-    timezones.put("Pacific/Galapagos", tz);
+-    tz = new SimpleTimeZone
+-      (-6000 * 3600, "Pacific/Easter",
+-       Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
+-       Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Pacific/Easter", tz);
+-    tz = new SimpleTimeZone
+-      (-5000 * 3600, "America/Grand_Turk",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Grand_Turk", tz);
+-    timezones.put("America/Havana", tz);
+-    tz = new SimpleTimeZone(-5000 * 3600, "EST5");
+-    timezones.put("EST5", tz);
+-    timezones.put("IET", tz);
+-    timezones.put("America/Bogota", tz);
+-    timezones.put("America/Cayman", tz);
+-    timezones.put("America/Eirunepe", tz);
+-    timezones.put("America/Guayaquil", tz);
+-    timezones.put("America/Indiana/Indianapolis", tz);
+-    timezones.put("America/Indiana/Knox", tz);
+-    timezones.put("America/Indiana/Marengo", tz);
+-    timezones.put("America/Indiana/Vevay", tz);
+-    timezones.put("America/Indianapolis", tz);
+-    timezones.put("America/Iqaluit", tz);
+-    timezones.put("America/Jamaica", tz);
+-    timezones.put("America/Lima", tz);
+-    timezones.put("America/Panama", tz);
+-    timezones.put("America/Pangnirtung", tz);
+-    timezones.put("America/Port-au-Prince", tz);
+-    timezones.put("America/Porto_Acre", tz);
+-    timezones.put("America/Rankin_Inlet", tz);
+-    tz = new SimpleTimeZone
+-      (-5000 * 3600, "EST",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("EST", tz);
+-    timezones.put("EST5EDT", tz);
+-    timezones.put("America/Detroit", tz);
+-    timezones.put("America/Kentucky/Louisville", tz);
+-    timezones.put("America/Kentucky/Monticello", tz);
+-    timezones.put("America/Louisville", tz);
+-    timezones.put("America/Montreal", tz);
+-    timezones.put("America/Nassau", tz);
+-    timezones.put("America/New_York", tz);
+-    timezones.put("America/Nipigon", tz);
+-    timezones.put("America/Thunder_Bay", tz);
+-    tz = new SimpleTimeZone(-4000 * 3600, "PRT");
+-    timezones.put("PRT", tz);
+-    timezones.put("America/Anguilla", tz);
+-    timezones.put("America/Antigua", tz);
+-    timezones.put("America/Aruba", tz);
+-    timezones.put("America/Barbados", tz);
+-    timezones.put("America/Boa_Vista", tz);
+-    timezones.put("America/Caracas", tz);
+-    timezones.put("America/Curacao", tz);
+-    timezones.put("America/Dominica", tz);
+-    timezones.put("America/Grenada", tz);
+-    timezones.put("America/Guadeloupe", tz);
+-    timezones.put("America/Guyana", tz);
+-    timezones.put("America/La_Paz", tz);
+-    timezones.put("America/Manaus", tz);
+-    timezones.put("America/Martinique", tz);
+-    timezones.put("America/Montserrat", tz);
+-    timezones.put("America/Port_of_Spain", tz);
+-    timezones.put("America/Porto_Velho", tz);
+-    timezones.put("America/Puerto_Rico", tz);
+-    timezones.put("America/Santo_Domingo", tz);
+-    timezones.put("America/St_Kitts", tz);
+-    timezones.put("America/St_Lucia", tz);
+-    timezones.put("America/St_Thomas", tz);
+-    timezones.put("America/St_Vincent", tz);
+-    timezones.put("America/Tortola", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "America/Asuncion",
+-       Calendar.OCTOBER, 1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Asuncion", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "America/Cuiaba",
+-       Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Cuiaba", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "America/Goose_Bay",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 60000,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000);
+-    timezones.put("America/Goose_Bay", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "America/Glace_Bay",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("America/Glace_Bay", tz);
+-    timezones.put("America/Halifax", tz);
+-    timezones.put("America/Thule", tz);
+-    timezones.put("Atlantic/Bermuda", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "America/Santiago",
+-       Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
+-       Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Santiago", tz);
+-    timezones.put("Antarctica/Palmer", tz);
+-    tz = new SimpleTimeZone
+-      (-4000 * 3600, "Atlantic/Stanley",
+-       Calendar.SEPTEMBER, 2, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.APRIL, 16, -Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Atlantic/Stanley", tz);
+-    tz = new SimpleTimeZone
+-      (-3500 * 3600, "CNT",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 60000,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000);
+-    timezones.put("CNT", tz);
+-    timezones.put("America/St_Johns", tz);
+-    tz = new SimpleTimeZone
+-      (-3000 * 3600, "America/Araguaina",
+-       Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Araguaina", tz);
+-    timezones.put("America/Sao_Paulo", tz);
+-    tz = new SimpleTimeZone(-3000 * 3600, "AGT");
+-    timezones.put("AGT", tz);
+-    timezones.put("America/Belem", tz);
+-    timezones.put("America/Buenos_Aires", tz);
+-    timezones.put("America/Catamarca", tz);
+-    timezones.put("America/Cayenne", tz);
+-    timezones.put("America/Cordoba", tz);
+-    timezones.put("America/Fortaleza", tz);
+-    timezones.put("America/Jujuy", tz);
+-    timezones.put("America/Maceio", tz);
+-    timezones.put("America/Mendoza", tz);
+-    timezones.put("America/Montevideo", tz);
+-    timezones.put("America/Paramaribo", tz);
+-    timezones.put("America/Recife", tz);
+-    timezones.put("America/Rosario", tz);
+-    tz = new SimpleTimeZone
+-      (-3000 * 3600, "America/Godthab",
+-       Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600,
+-       Calendar.OCTOBER, 30, -Calendar.SATURDAY, 22000 * 3600);
+-    timezones.put("America/Godthab", tz);
+-    tz = new SimpleTimeZone
+-      (-3000 * 3600, "America/Miquelon",
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("America/Miquelon", tz);
+-    tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha");
+-    timezones.put("America/Noronha", tz);
+-    timezones.put("Atlantic/South_Georgia", tz);
+-    tz = new SimpleTimeZone
+-      (-1000 * 3600, "America/Scoresbysund",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("America/Scoresbysund", tz);
+-    timezones.put("Atlantic/Azores", tz);
+-    tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde");
+-    timezones.put("Atlantic/Cape_Verde", tz);
+-    timezones.put("Atlantic/Jan_Mayen", tz);
+-    tz = new SimpleTimeZone(0 * 3600, "GMT");
+-    timezones.put("GMT", tz);
+-    timezones.put("UTC", tz);
+-    timezones.put("Africa/Abidjan", tz);
+-    timezones.put("Africa/Accra", tz);
+-    timezones.put("Africa/Bamako", tz);
+-    timezones.put("Africa/Banjul", tz);
+-    timezones.put("Africa/Bissau", tz);
+-    timezones.put("Africa/Casablanca", tz);
+-    timezones.put("Africa/Conakry", tz);
+-    timezones.put("Africa/Dakar", tz);
+-    timezones.put("Africa/El_Aaiun", tz);
+-    timezones.put("Africa/Freetown", tz);
+-    timezones.put("Africa/Lome", tz);
+-    timezones.put("Africa/Monrovia", tz);
+-    timezones.put("Africa/Nouakchott", tz);
+-    timezones.put("Africa/Ouagadougou", tz);
+-    timezones.put("Africa/Sao_Tome", tz);
+-    timezones.put("Africa/Timbuktu", tz);
+-    timezones.put("Atlantic/Reykjavik", tz);
+-    timezones.put("Atlantic/St_Helena", tz);
+-    timezones.put("Europe/Belfast", tz);
+-    timezones.put("Europe/Dublin", tz);
+-    timezones.put("Europe/London", tz);
+-    tz = new SimpleTimeZone
+-      (0 * 3600, "WET",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
+-    timezones.put("WET", tz);
+-    timezones.put("Atlantic/Canary", tz);
+-    timezones.put("Atlantic/Faeroe", tz);
+-    timezones.put("Atlantic/Madeira", tz);
+-    timezones.put("Europe/Lisbon", tz);
+-    tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers");
+-    timezones.put("Africa/Algiers", tz);
+-    timezones.put("Africa/Bangui", tz);
+-    timezones.put("Africa/Brazzaville", tz);
+-    timezones.put("Africa/Douala", tz);
+-    timezones.put("Africa/Kinshasa", tz);
+-    timezones.put("Africa/Lagos", tz);
+-    timezones.put("Africa/Libreville", tz);
+-    timezones.put("Africa/Luanda", tz);
+-    timezones.put("Africa/Malabo", tz);
+-    timezones.put("Africa/Ndjamena", tz);
+-    timezones.put("Africa/Niamey", tz);
+-    timezones.put("Africa/Porto-Novo", tz);
+-    timezones.put("Africa/Tunis", tz);
+-    tz = new SimpleTimeZone
+-      (1000 * 3600, "Africa/Windhoek",
+-       Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Africa/Windhoek", tz);
+-    tz = new SimpleTimeZone
+-      (1000 * 3600, "CET",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("CET", tz);
+-    timezones.put("ECT", tz);
+-    timezones.put("MET", tz);
+-    timezones.put("Africa/Ceuta", tz);
+-    timezones.put("Arctic/Longyearbyen", tz);
+-    timezones.put("Europe/Amsterdam", tz);
+-    timezones.put("Europe/Andorra", tz);
+-    timezones.put("Europe/Belgrade", tz);
+-    timezones.put("Europe/Berlin", tz);
+-    timezones.put("Europe/Bratislava", tz);
+-    timezones.put("Europe/Brussels", tz);
+-    timezones.put("Europe/Budapest", tz);
+-    timezones.put("Europe/Copenhagen", tz);
+-    timezones.put("Europe/Gibraltar", tz);
+-    timezones.put("Europe/Ljubljana", tz);
+-    timezones.put("Europe/Luxembourg", tz);
+-    timezones.put("Europe/Madrid", tz);
+-    timezones.put("Europe/Malta", tz);
+-    timezones.put("Europe/Monaco", tz);
+-    timezones.put("Europe/Oslo", tz);
+-    timezones.put("Europe/Paris", tz);
+-    timezones.put("Europe/Prague", tz);
+-    timezones.put("Europe/Rome", tz);
+-    timezones.put("Europe/San_Marino", tz);
+-    timezones.put("Europe/Sarajevo", tz);
+-    timezones.put("Europe/Skopje", tz);
+-    timezones.put("Europe/Stockholm", tz);
+-    timezones.put("Europe/Tirane", tz);
+-    timezones.put("Europe/Vaduz", tz);
+-    timezones.put("Europe/Vatican", tz);
+-    timezones.put("Europe/Vienna", tz);
+-    timezones.put("Europe/Warsaw", tz);
+-    timezones.put("Europe/Zagreb", tz);
+-    timezones.put("Europe/Zurich", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "ART",
+-       Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600,
+-       Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 23000 * 3600);
+-    timezones.put("ART", tz);
+-    timezones.put("Africa/Cairo", tz);
+-    tz = new SimpleTimeZone(2000 * 3600, "CAT");
+-    timezones.put("CAT", tz);
+-    timezones.put("Africa/Blantyre", tz);
+-    timezones.put("Africa/Bujumbura", tz);
+-    timezones.put("Africa/Gaborone", tz);
+-    timezones.put("Africa/Harare", tz);
+-    timezones.put("Africa/Johannesburg", tz);
+-    timezones.put("Africa/Kigali", tz);
+-    timezones.put("Africa/Lubumbashi", tz);
+-    timezones.put("Africa/Lusaka", tz);
+-    timezones.put("Africa/Maputo", tz);
+-    timezones.put("Africa/Maseru", tz);
+-    timezones.put("Africa/Mbabane", tz);
+-    timezones.put("Africa/Tripoli", tz);
+-    timezones.put("Europe/Riga", tz);
+-    timezones.put("Europe/Tallinn", tz);
+-    timezones.put("Europe/Vilnius", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Asia/Amman",
+-       Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600,
+-       Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 0 * 3600);
+-    timezones.put("Asia/Amman", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Asia/Beirut",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Asia/Beirut", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Asia/Damascus",
+-       Calendar.APRIL, 1, 0, 0 * 3600,
+-       Calendar.OCTOBER, 1, 0, 0 * 3600);
+-    timezones.put("Asia/Damascus", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Asia/Gaza",
+-       Calendar.APRIL, 3, Calendar.FRIDAY, 0 * 3600,
+-       Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600);
+-    timezones.put("Asia/Gaza", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Asia/Jerusalem",
+-       Calendar.APRIL, 1, 0, 1000 * 3600,
+-       Calendar.OCTOBER, 1, 0, 1000 * 3600);
+-    timezones.put("Asia/Jerusalem", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "EET",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
+-    timezones.put("EET", tz);
+-    timezones.put("Asia/Istanbul", tz);
+-    timezones.put("Asia/Nicosia", tz);
+-    timezones.put("Europe/Athens", tz);
+-    timezones.put("Europe/Bucharest", tz);
+-    timezones.put("Europe/Chisinau", tz);
+-    timezones.put("Europe/Helsinki", tz);
+-    timezones.put("Europe/Istanbul", tz);
+-    timezones.put("Europe/Kiev", tz);
+-    timezones.put("Europe/Nicosia", tz);
+-    timezones.put("Europe/Simferopol", tz);
+-    timezones.put("Europe/Sofia", tz);
+-    timezones.put("Europe/Uzhgorod", tz);
+-    timezones.put("Europe/Zaporozhye", tz);
+-    tz = new SimpleTimeZone
+-      (2000 * 3600, "Europe/Kaliningrad",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Europe/Kaliningrad", tz);
+-    timezones.put("Europe/Minsk", tz);
+-    tz = new SimpleTimeZone
+-      (3000 * 3600, "Asia/Baghdad",
+-       Calendar.APRIL, 1, 0, 3000 * 3600,
+-       Calendar.OCTOBER, 1, 0, 3000 * 3600);
+-    timezones.put("Asia/Baghdad", tz);
+-    tz = new SimpleTimeZone
+-      (3000 * 3600, "Europe/Moscow",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Europe/Moscow", tz);
+-    timezones.put("Europe/Tiraspol", tz);
+-    tz = new SimpleTimeZone(3000 * 3600, "EAT");
+-    timezones.put("EAT", tz);
+-    timezones.put("Africa/Addis_Ababa", tz);
+-    timezones.put("Africa/Asmera", tz);
+-    timezones.put("Africa/Dar_es_Salaam", tz);
+-    timezones.put("Africa/Djibouti", tz);
+-    timezones.put("Africa/Kampala", tz);
+-    timezones.put("Africa/Khartoum", tz);
+-    timezones.put("Africa/Mogadishu", tz);
+-    timezones.put("Africa/Nairobi", tz);
+-    timezones.put("Antarctica/Syowa", tz);
+-    timezones.put("Asia/Aden", tz);
+-    timezones.put("Asia/Bahrain", tz);
+-    timezones.put("Asia/Kuwait", tz);
+-    timezones.put("Asia/Qatar", tz);
+-    timezones.put("Asia/Riyadh", tz);
+-    timezones.put("Indian/Antananarivo", tz);
+-    timezones.put("Indian/Comoro", tz);
+-    timezones.put("Indian/Mayotte", tz);
+-    tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran");
+-    timezones.put("Asia/Tehran", tz);
+-    tz = new SimpleTimeZone
+-      (4000 * 3600, "Asia/Baku",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
+-    timezones.put("Asia/Baku", tz);
+-    tz = new SimpleTimeZone
+-      (4000 * 3600, "Asia/Aqtau",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Asia/Aqtau", tz);
+-    timezones.put("Asia/Tbilisi", tz);
+-    tz = new SimpleTimeZone
+-      (4000 * 3600, "Asia/Yerevan",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Yerevan", tz);
+-    timezones.put("Europe/Samara", tz);
+-    tz = new SimpleTimeZone(4000 * 3600, "NET");
+-    timezones.put("NET", tz);
+-    timezones.put("Asia/Dubai", tz);
+-    timezones.put("Asia/Muscat", tz);
+-    timezones.put("Indian/Mahe", tz);
+-    timezones.put("Indian/Mauritius", tz);
+-    timezones.put("Indian/Reunion", tz);
+-    tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul");
+-    timezones.put("Asia/Kabul", tz);
+-    tz = new SimpleTimeZone
+-      (5000 * 3600, "Asia/Aqtobe",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Asia/Aqtobe", tz);
+-    tz = new SimpleTimeZone
+-      (5000 * 3600, "Asia/Bishkek",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2500 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2500 * 3600);
+-    timezones.put("Asia/Bishkek", tz);
+-    tz = new SimpleTimeZone
+-      (5000 * 3600, "Asia/Yekaterinburg",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Yekaterinburg", tz);
+-    tz = new SimpleTimeZone(5000 * 3600, "PLT");
+-    timezones.put("PLT", tz);
+-    timezones.put("Asia/Ashgabat", tz);
+-    timezones.put("Asia/Dushanbe", tz);
+-    timezones.put("Asia/Karachi", tz);
+-    timezones.put("Asia/Samarkand", tz);
+-    timezones.put("Asia/Tashkent", tz);
+-    timezones.put("Indian/Chagos", tz);
+-    timezones.put("Indian/Kerguelen", tz);
+-    timezones.put("Indian/Maldives", tz);
+-    tz = new SimpleTimeZone(5500 * 3600, "IST");
+-    timezones.put("IST", tz);
+-    timezones.put("Asia/Calcutta", tz);
+-    tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu");
+-    timezones.put("Asia/Katmandu", tz);
+-    tz = new SimpleTimeZone(6000 * 3600, "BST");
+-    timezones.put("BST", tz);
+-    timezones.put("Antarctica/Mawson", tz);
+-    timezones.put("Asia/Colombo", tz);
+-    timezones.put("Asia/Dhaka", tz);
+-    timezones.put("Asia/Thimphu", tz);
+-    tz = new SimpleTimeZone
+-      (6000 * 3600, "Asia/Almaty",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
+-    timezones.put("Asia/Almaty", tz);
+-    tz = new SimpleTimeZone
+-      (6000 * 3600, "Asia/Novosibirsk",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Novosibirsk", tz);
+-    timezones.put("Asia/Omsk", tz);
+-    tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon");
+-    timezones.put("Asia/Rangoon", tz);
+-    timezones.put("Indian/Cocos", tz);
+-    tz = new SimpleTimeZone(7000 * 3600, "VST");
+-    timezones.put("VST", tz);
+-    timezones.put("Antarctica/Davis", tz);
+-    timezones.put("Asia/Bangkok", tz);
+-    timezones.put("Asia/Hovd", tz);
+-    timezones.put("Asia/Jakarta", tz);
+-    timezones.put("Asia/Phnom_Penh", tz);
+-    timezones.put("Asia/Saigon", tz);
+-    timezones.put("Asia/Vientiane", tz);
+-    timezones.put("Indian/Christmas", tz);
+-    tz = new SimpleTimeZone
+-      (7000 * 3600, "Asia/Krasnoyarsk",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Krasnoyarsk", tz);
+-    tz = new SimpleTimeZone(8000 * 3600, "CTT");
+-    timezones.put("CTT", tz);
+-    timezones.put("Antarctica/Casey", tz);
+-    timezones.put("Asia/Brunei", tz);
+-    timezones.put("Asia/Chungking", tz);
+-    timezones.put("Asia/Harbin", tz);
+-    timezones.put("Asia/Hong_Kong", tz);
+-    timezones.put("Asia/Kashgar", tz);
+-    timezones.put("Asia/Kuala_Lumpur", tz);
+-    timezones.put("Asia/Kuching", tz);
+-    timezones.put("Asia/Macao", tz);
+-    timezones.put("Asia/Manila", tz);
+-    timezones.put("Asia/Shanghai", tz);
+-    timezones.put("Asia/Singapore", tz);
+-    timezones.put("Asia/Taipei", tz);
+-    timezones.put("Asia/Ujung_Pandang", tz);
+-    timezones.put("Asia/Ulaanbaatar", tz);
+-    timezones.put("Asia/Urumqi", tz);
+-    timezones.put("Australia/Perth", tz);
+-    tz = new SimpleTimeZone
+-      (8000 * 3600, "Asia/Irkutsk",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Irkutsk", tz);
+-    tz = new SimpleTimeZone(9000 * 3600, "JST");
+-    timezones.put("JST", tz);
+-    timezones.put("Asia/Dili", tz);
+-    timezones.put("Asia/Jayapura", tz);
+-    timezones.put("Asia/Pyongyang", tz);
+-    timezones.put("Asia/Seoul", tz);
+-    timezones.put("Asia/Tokyo", tz);
+-    timezones.put("Pacific/Palau", tz);
+-    tz = new SimpleTimeZone
+-      (9000 * 3600, "Asia/Yakutsk",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Yakutsk", tz);
+-    tz = new SimpleTimeZone
+-      (9500 * 3600, "Australia/Adelaide",
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Australia/Adelaide", tz);
+-    timezones.put("Australia/Broken_Hill", tz);
+-    tz = new SimpleTimeZone(9500 * 3600, "ACT");
+-    timezones.put("ACT", tz);
+-    timezones.put("Australia/Darwin", tz);
+-    tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville");
+-    timezones.put("Antarctica/DumontDUrville", tz);
+-    timezones.put("Australia/Brisbane", tz);
+-    timezones.put("Australia/Lindeman", tz);
+-    timezones.put("Pacific/Guam", tz);
+-    timezones.put("Pacific/Port_Moresby", tz);
+-    timezones.put("Pacific/Saipan", tz);
+-    timezones.put("Pacific/Truk", tz);
+-    timezones.put("Pacific/Yap", tz);
+-    tz = new SimpleTimeZone
+-      (10000 * 3600, "Asia/Vladivostok",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Vladivostok", tz);
+-    tz = new SimpleTimeZone
+-      (10000 * 3600, "Australia/Hobart",
+-       Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Australia/Hobart", tz);
+-    tz = new SimpleTimeZone
+-      (10000 * 3600, "AET",
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("AET", tz);
+-    timezones.put("Australia/Melbourne", tz);
+-    timezones.put("Australia/Sydney", tz);
+-    tz = new SimpleTimeZone
+-      (10500 * 3600, "Australia/Lord_Howe",
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600);
+-    timezones.put("Australia/Lord_Howe", tz);
+-    tz = new SimpleTimeZone
+-      (11000 * 3600, "Asia/Magadan",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Magadan", tz);
+-    tz = new SimpleTimeZone(11000 * 3600, "SST");
+-    timezones.put("SST", tz);
+-    timezones.put("Pacific/Efate", tz);
+-    timezones.put("Pacific/Guadalcanal", tz);
+-    timezones.put("Pacific/Kosrae", tz);
+-    timezones.put("Pacific/Noumea", tz);
+-    timezones.put("Pacific/Ponape", tz);
+-    tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk");
+-    timezones.put("Pacific/Norfolk", tz);
+-    tz = new SimpleTimeZone
+-      (12000 * 3600, "NST",
+-       Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.MARCH, 3, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("NST", tz);
+-    timezones.put("Antarctica/McMurdo", tz);
+-    timezones.put("Antarctica/South_Pole", tz);
+-    timezones.put("Pacific/Auckland", tz);
+-    tz = new SimpleTimeZone
+-      (12000 * 3600, "Asia/Anadyr",
+-       Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
+-       Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
+-    timezones.put("Asia/Anadyr", tz);
+-    timezones.put("Asia/Kamchatka", tz);
+-    tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji");
+-    timezones.put("Pacific/Fiji", tz);
+-    timezones.put("Pacific/Funafuti", tz);
+-    timezones.put("Pacific/Kwajalein", tz);
+-    timezones.put("Pacific/Majuro", tz);
+-    timezones.put("Pacific/Nauru", tz);
+-    timezones.put("Pacific/Tarawa", tz);
+-    timezones.put("Pacific/Wake", tz);
+-    timezones.put("Pacific/Wallis", tz);
+-    tz = new SimpleTimeZone
+-      (12750 * 3600, "Pacific/Chatham",
+-       Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600,
+-       Calendar.MARCH, 3, Calendar.SUNDAY, 2750 * 3600);
+-    timezones.put("Pacific/Chatham", tz);
+-    tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury");
+-    timezones.put("Pacific/Enderbury", tz);
+-    timezones.put("Pacific/Tongatapu", tz);
+-    tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati");
+-    timezones.put("Pacific/Kiritimati", tz);
++  /**
++   * Cached copy of getAvailableIDs().
++   */
++  private static String[] availableIDs = null;
++
++  /**
++   * JDK 1.1.x compatibility aliases.
++   */
++  private static Hashtable aliases0;
++
++  /**
++   * Hashtable for timezones by ID.
++   */
++  private static Hashtable timezones0;
++  /* initialize this static field lazily to overhead if
++   * it is not needed: 
++   */
++  private static Hashtable timezones() {
++    if (timezones0==null) 
++      {
++	Hashtable timezones = new Hashtable();
++	timezones0 = timezones;
++
++	zoneinfo_dir = System.getProperty("gnu.java.util.zoneinfo.dir");
++	if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory())
++	  zoneinfo_dir = null;
++
++	if (zoneinfo_dir != null)
++	  {
++	    aliases0 = new Hashtable();
++
++	    // These deprecated aliases for JDK 1.1.x compatibility
++	    // should take precedence over data files read from
++	    // /usr/share/zoneinfo.
++	    aliases0.put("ACT", "Australia/Darwin");
++	    aliases0.put("AET", "Australia/Sydney");
++	    aliases0.put("AGT", "America/Argentina/Buenos_Aires");
++	    aliases0.put("ART", "Africa/Cairo");
++	    aliases0.put("AST", "America/Juneau");
++	    aliases0.put("BST", "Asia/Colombo");
++	    aliases0.put("CAT", "Africa/Gaborone");
++	    aliases0.put("CNT", "America/St_Johns");
++	    aliases0.put("CST", "CST6CDT");
++	    aliases0.put("CTT", "Asia/Brunei");
++	    aliases0.put("EAT", "Indian/Comoro");
++	    aliases0.put("ECT", "CET");
++	    aliases0.put("EST", "EST5EDT");
++	    aliases0.put("EST5", "EST5EDT");
++	    aliases0.put("IET", "EST5EDT");
++	    aliases0.put("IST", "Asia/Calcutta");
++	    aliases0.put("JST", "Asia/Seoul");
++	    aliases0.put("MIT", "Pacific/Niue");
++	    aliases0.put("MST", "MST7MDT");
++	    aliases0.put("MST7", "MST7MDT");
++	    aliases0.put("NET", "Indian/Mauritius");
++	    aliases0.put("NST", "Pacific/Auckland");
++	    aliases0.put("PLT", "Indian/Kerguelen");
++	    aliases0.put("PNT", "MST7MDT");
++	    aliases0.put("PRT", "America/Anguilla");
++	    aliases0.put("PST", "PST8PDT");
++	    aliases0.put("SST", "Pacific/Ponape");
++	    aliases0.put("VST", "Asia/Bangkok");
++	    return timezones;
++	  }
++
++	TimeZone tz;
++	// Automatically generated by scripts/timezones.pl
++	// XXX - Should we read this data from a file?
++	tz = new SimpleTimeZone(-11000 * 3600, "MIT");
++	timezones0.put("MIT", tz);
++	timezones0.put("Pacific/Apia", tz);
++	timezones0.put("Pacific/Midway", tz);
++	timezones0.put("Pacific/Niue", tz);
++	timezones0.put("Pacific/Pago_Pago", tz);
++	tz = new SimpleTimeZone
++	  (-10000 * 3600, "America/Adak",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Adak", tz);
++	tz = new SimpleTimeZone(-10000 * 3600, "HST");
++	timezones0.put("HST", tz);
++	timezones0.put("Pacific/Fakaofo", tz);
++	timezones0.put("Pacific/Honolulu", tz);
++	timezones0.put("Pacific/Johnston", tz);
++	timezones0.put("Pacific/Rarotonga", tz);
++	timezones0.put("Pacific/Tahiti", tz);
++	tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas");
++	timezones0.put("Pacific/Marquesas", tz);
++	tz = new SimpleTimeZone
++	  (-9000 * 3600, "AST",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("AST", tz);
++	timezones0.put("America/Anchorage", tz);
++	timezones0.put("America/Juneau", tz);
++	timezones0.put("America/Nome", tz);
++	timezones0.put("America/Yakutat", tz);
++	tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier");
++	timezones0.put("Pacific/Gambier", tz);
++	tz = new SimpleTimeZone
++	  (-8000 * 3600, "America/Tijuana",
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Tijuana", tz);
++	tz = new SimpleTimeZone
++	  (-8000 * 3600, "PST",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("PST", tz);
++	timezones0.put("PST8PDT", tz);
++	timezones0.put("America/Dawson", tz);
++	timezones0.put("America/Los_Angeles", tz);
++	timezones0.put("America/Vancouver", tz);
++	timezones0.put("America/Whitehorse", tz);
++	timezones0.put("US/Pacific-New", tz);
++	tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn");
++	timezones0.put("Pacific/Pitcairn", tz);
++	tz = new SimpleTimeZone
++	  (-7000 * 3600, "America/Chihuahua",
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Chihuahua", tz);
++	timezones0.put("America/Mazatlan", tz);
++	tz = new SimpleTimeZone(-7000 * 3600, "MST7");
++	timezones0.put("MST7", tz);
++	timezones0.put("PNT", tz);
++	timezones0.put("America/Dawson_Creek", tz);
++	timezones0.put("America/Hermosillo", tz);
++	timezones0.put("America/Phoenix", tz);
++	tz = new SimpleTimeZone
++	  (-7000 * 3600, "MST",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("MST", tz);
++	timezones0.put("MST7MDT", tz);
++	timezones0.put("America/Boise", tz);
++	timezones0.put("America/Cambridge_Bay", tz);
++	timezones0.put("America/Denver", tz);
++	timezones0.put("America/Edmonton", tz);
++	timezones0.put("America/Inuvik", tz);
++	timezones0.put("America/Shiprock", tz);
++	timezones0.put("America/Yellowknife", tz);
++	tz = new SimpleTimeZone
++	  (-6000 * 3600, "America/Cancun",
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Cancun", tz);
++	timezones0.put("America/Merida", tz);
++	timezones0.put("America/Mexico_City", tz);
++	timezones0.put("America/Monterrey", tz);
++	tz = new SimpleTimeZone(-6000 * 3600, "America/Belize");
++	timezones0.put("America/Belize", tz);
++	timezones0.put("America/Costa_Rica", tz);
++	timezones0.put("America/El_Salvador", tz);
++	timezones0.put("America/Guatemala", tz);
++	timezones0.put("America/Managua", tz);
++	timezones0.put("America/Regina", tz);
++	timezones0.put("America/Swift_Current", tz);
++	timezones0.put("America/Tegucigalpa", tz);
++	timezones0.put("Pacific/Galapagos", tz);
++	tz = new SimpleTimeZone
++	  (-6000 * 3600, "CST",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("CST", tz);
++	timezones0.put("CST6CDT", tz);
++	timezones0.put("America/Chicago", tz);
++	timezones0.put("America/Indiana/Knox", tz);
++	timezones0.put("America/Indiana/Petersburg", tz);
++	timezones0.put("America/Indiana/Vincennes", tz);
++	timezones0.put("America/Menominee", tz);
++	timezones0.put("America/North_Dakota/Center", tz);
++	timezones0.put("America/North_Dakota/New_Salem", tz);
++	timezones0.put("America/Rainy_River", tz);
++	timezones0.put("America/Rankin_Inlet", tz);
++	timezones0.put("America/Winnipeg", tz);
++	tz = new SimpleTimeZone
++	  (-6000 * 3600, "Pacific/Easter",
++	   Calendar.OCTOBER, 2, Calendar.SATURDAY, 22000 * 3600,
++	   Calendar.MARCH, 2, Calendar.SATURDAY, 22000 * 3600);
++	timezones0.put("Pacific/Easter", tz);
++	tz = new SimpleTimeZone(-5000 * 3600, "EST5");
++	timezones0.put("EST5", tz);
++	timezones0.put("IET", tz);
++	timezones0.put("America/Atikokan", tz);
++	timezones0.put("America/Bogota", tz);
++	timezones0.put("America/Cayman", tz);
++	timezones0.put("America/Eirunepe", tz);
++	timezones0.put("America/Guayaquil", tz);
++	timezones0.put("America/Jamaica", tz);
++	timezones0.put("America/Lima", tz);
++	timezones0.put("America/Panama", tz);
++	timezones0.put("America/Rio_Branco", tz);
++	tz = new SimpleTimeZone
++	  (-5000 * 3600, "America/Havana",
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
++	timezones0.put("America/Havana", tz);
++	tz = new SimpleTimeZone
++	  (-5000 * 3600, "America/Grand_Turk",
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("America/Grand_Turk", tz);
++	timezones0.put("America/Port-au-Prince", tz);
++	tz = new SimpleTimeZone
++	  (-5000 * 3600, "EST",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("EST", tz);
++	timezones0.put("EST5EDT", tz);
++	timezones0.put("America/Detroit", tz);
++	timezones0.put("America/Indiana/Indianapolis", tz);
++	timezones0.put("America/Indiana/Marengo", tz);
++	timezones0.put("America/Indiana/Vevay", tz);
++	timezones0.put("America/Iqaluit", tz);
++	timezones0.put("America/Kentucky/Louisville", tz);
++	timezones0.put("America/Kentucky/Monticello", tz);
++	timezones0.put("America/Montreal", tz);
++	timezones0.put("America/Nassau", tz);
++	timezones0.put("America/New_York", tz);
++	timezones0.put("America/Nipigon", tz);
++	timezones0.put("America/Pangnirtung", tz);
++	timezones0.put("America/Thunder_Bay", tz);
++	timezones0.put("America/Toronto", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "America/Asuncion",
++	   Calendar.OCTOBER, 3, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("America/Asuncion", tz);
++	tz = new SimpleTimeZone(-4000 * 3600, "PRT");
++	timezones0.put("PRT", tz);
++	timezones0.put("America/Anguilla", tz);
++	timezones0.put("America/Antigua", tz);
++	timezones0.put("America/Aruba", tz);
++	timezones0.put("America/Barbados", tz);
++	timezones0.put("America/Blanc-Sablon", tz);
++	timezones0.put("America/Boa_Vista", tz);
++	timezones0.put("America/Caracas", tz);
++	timezones0.put("America/Curacao", tz);
++	timezones0.put("America/Dominica", tz);
++	timezones0.put("America/Grenada", tz);
++	timezones0.put("America/Guadeloupe", tz);
++	timezones0.put("America/Guyana", tz);
++	timezones0.put("America/La_Paz", tz);
++	timezones0.put("America/Manaus", tz);
++	timezones0.put("America/Martinique", tz);
++	timezones0.put("America/Montserrat", tz);
++	timezones0.put("America/Port_of_Spain", tz);
++	timezones0.put("America/Porto_Velho", tz);
++	timezones0.put("America/Puerto_Rico", tz);
++	timezones0.put("America/Santo_Domingo", tz);
++	timezones0.put("America/St_Kitts", tz);
++	timezones0.put("America/St_Lucia", tz);
++	timezones0.put("America/St_Thomas", tz);
++	timezones0.put("America/St_Vincent", tz);
++	timezones0.put("America/Tortola", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "America/Campo_Grande",
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("America/Campo_Grande", tz);
++	timezones0.put("America/Cuiaba", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "America/Goose_Bay",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 60000,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000);
++	timezones0.put("America/Goose_Bay", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "America/Glace_Bay",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Glace_Bay", tz);
++	timezones0.put("America/Halifax", tz);
++	timezones0.put("America/Moncton", tz);
++	timezones0.put("America/Thule", tz);
++	timezones0.put("Atlantic/Bermuda", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "America/Santiago",
++	   Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
++	   Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("America/Santiago", tz);
++	timezones0.put("Antarctica/Palmer", tz);
++	tz = new SimpleTimeZone
++	  (-4000 * 3600, "Atlantic/Stanley",
++	   Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.APRIL, 3, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("Atlantic/Stanley", tz);
++	tz = new SimpleTimeZone
++	  (-3500 * 3600, "CNT",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 60000,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000);
++	timezones0.put("CNT", tz);
++	timezones0.put("America/St_Johns", tz);
++	tz = new SimpleTimeZone
++	  (-3000 * 3600, "America/Godthab",
++	   Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600,
++	   Calendar.OCTOBER, 30, -Calendar.SATURDAY, 23000 * 3600);
++	timezones0.put("America/Godthab", tz);
++	tz = new SimpleTimeZone
++	  (-3000 * 3600, "America/Miquelon",
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Miquelon", tz);
++	tz = new SimpleTimeZone
++	  (-3000 * 3600, "America/Montevideo",
++	   Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("America/Montevideo", tz);
++	tz = new SimpleTimeZone
++	  (-3000 * 3600, "America/Sao_Paulo",
++	   Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("America/Sao_Paulo", tz);
++	tz = new SimpleTimeZone(-3000 * 3600, "AGT");
++	timezones0.put("AGT", tz);
++	timezones0.put("America/Araguaina", tz);
++	timezones0.put("America/Argentina/Buenos_Aires", tz);
++	timezones0.put("America/Argentina/Catamarca", tz);
++	timezones0.put("America/Argentina/Cordoba", tz);
++	timezones0.put("America/Argentina/Jujuy", tz);
++	timezones0.put("America/Argentina/La_Rioja", tz);
++	timezones0.put("America/Argentina/Mendoza", tz);
++	timezones0.put("America/Argentina/Rio_Gallegos", tz);
++	timezones0.put("America/Argentina/San_Juan", tz);
++	timezones0.put("America/Argentina/Tucuman", tz);
++	timezones0.put("America/Argentina/Ushuaia", tz);
++	timezones0.put("America/Bahia", tz);
++	timezones0.put("America/Belem", tz);
++	timezones0.put("America/Cayenne", tz);
++	timezones0.put("America/Fortaleza", tz);
++	timezones0.put("America/Maceio", tz);
++	timezones0.put("America/Paramaribo", tz);
++	timezones0.put("America/Recife", tz);
++	timezones0.put("Antarctica/Rothera", tz);
++	tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha");
++	timezones0.put("America/Noronha", tz);
++	timezones0.put("Atlantic/South_Georgia", tz);
++	tz = new SimpleTimeZone
++	  (-1000 * 3600, "America/Scoresbysund",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
++	timezones0.put("America/Scoresbysund", tz);
++	timezones0.put("Atlantic/Azores", tz);
++	tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde");
++	timezones0.put("Atlantic/Cape_Verde", tz);
++	tz = new SimpleTimeZone(0 * 3600, "GMT");
++	timezones0.put("GMT", tz);
++	timezones0.put("UTC", tz);
++	timezones0.put("Africa/Abidjan", tz);
++	timezones0.put("Africa/Accra", tz);
++	timezones0.put("Africa/Bamako", tz);
++	timezones0.put("Africa/Banjul", tz);
++	timezones0.put("Africa/Bissau", tz);
++	timezones0.put("Africa/Casablanca", tz);
++	timezones0.put("Africa/Conakry", tz);
++	timezones0.put("Africa/Dakar", tz);
++	timezones0.put("Africa/El_Aaiun", tz);
++	timezones0.put("Africa/Freetown", tz);
++	timezones0.put("Africa/Lome", tz);
++	timezones0.put("Africa/Monrovia", tz);
++	timezones0.put("Africa/Nouakchott", tz);
++	timezones0.put("Africa/Ouagadougou", tz);
++	timezones0.put("Africa/Sao_Tome", tz);
++	timezones0.put("America/Danmarkshavn", tz);
++	timezones0.put("Atlantic/Reykjavik", tz);
++	timezones0.put("Atlantic/St_Helena", tz);
++	tz = new SimpleTimeZone
++	  (0 * 3600, "WET",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("WET", tz);
++	timezones0.put("Atlantic/Canary", tz);
++	timezones0.put("Atlantic/Faroe", tz);
++	timezones0.put("Atlantic/Madeira", tz);
++	timezones0.put("Europe/Dublin", tz);
++	timezones0.put("Europe/Guernsey", tz);
++	timezones0.put("Europe/Isle_of_Man", tz);
++	timezones0.put("Europe/Jersey", tz);
++	timezones0.put("Europe/Lisbon", tz);
++	timezones0.put("Europe/London", tz);
++	tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers");
++	timezones0.put("Africa/Algiers", tz);
++	timezones0.put("Africa/Bangui", tz);
++	timezones0.put("Africa/Brazzaville", tz);
++	timezones0.put("Africa/Douala", tz);
++	timezones0.put("Africa/Kinshasa", tz);
++	timezones0.put("Africa/Lagos", tz);
++	timezones0.put("Africa/Libreville", tz);
++	timezones0.put("Africa/Luanda", tz);
++	timezones0.put("Africa/Malabo", tz);
++	timezones0.put("Africa/Ndjamena", tz);
++	timezones0.put("Africa/Niamey", tz);
++	timezones0.put("Africa/Porto-Novo", tz);
++	tz = new SimpleTimeZone
++	  (1000 * 3600, "Africa/Windhoek",
++	   Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600);
++	timezones0.put("Africa/Windhoek", tz);
++	tz = new SimpleTimeZone
++	  (1000 * 3600, "CET",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("CET", tz);
++	timezones0.put("ECT", tz);
++	timezones0.put("MET", tz);
++	timezones0.put("Africa/Ceuta", tz);
++	timezones0.put("Africa/Tunis", tz);
++	timezones0.put("Arctic/Longyearbyen", tz);
++	timezones0.put("Atlantic/Jan_Mayen", tz);
++	timezones0.put("Europe/Amsterdam", tz);
++	timezones0.put("Europe/Andorra", tz);
++	timezones0.put("Europe/Belgrade", tz);
++	timezones0.put("Europe/Berlin", tz);
++	timezones0.put("Europe/Bratislava", tz);
++	timezones0.put("Europe/Brussels", tz);
++	timezones0.put("Europe/Budapest", tz);
++	timezones0.put("Europe/Copenhagen", tz);
++	timezones0.put("Europe/Gibraltar", tz);
++	timezones0.put("Europe/Ljubljana", tz);
++	timezones0.put("Europe/Luxembourg", tz);
++	timezones0.put("Europe/Madrid", tz);
++	timezones0.put("Europe/Malta", tz);
++	timezones0.put("Europe/Monaco", tz);
++	timezones0.put("Europe/Oslo", tz);
++	timezones0.put("Europe/Paris", tz);
++	timezones0.put("Europe/Podgorica", tz);
++	timezones0.put("Europe/Prague", tz);
++	timezones0.put("Europe/Rome", tz);
++	timezones0.put("Europe/San_Marino", tz);
++	timezones0.put("Europe/Sarajevo", tz);
++	timezones0.put("Europe/Skopje", tz);
++	timezones0.put("Europe/Stockholm", tz);
++	timezones0.put("Europe/Tirane", tz);
++	timezones0.put("Europe/Vaduz", tz);
++	timezones0.put("Europe/Vatican", tz);
++	timezones0.put("Europe/Vienna", tz);
++	timezones0.put("Europe/Warsaw", tz);
++	timezones0.put("Europe/Zagreb", tz);
++	timezones0.put("Europe/Zurich", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "ART",
++	   Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600,
++	   Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 24000 * 3600);
++	timezones0.put("ART", tz);
++	timezones0.put("Africa/Cairo", tz);
++	tz = new SimpleTimeZone(2000 * 3600, "CAT");
++	timezones0.put("CAT", tz);
++	timezones0.put("Africa/Blantyre", tz);
++	timezones0.put("Africa/Bujumbura", tz);
++	timezones0.put("Africa/Gaborone", tz);
++	timezones0.put("Africa/Harare", tz);
++	timezones0.put("Africa/Johannesburg", tz);
++	timezones0.put("Africa/Kigali", tz);
++	timezones0.put("Africa/Lubumbashi", tz);
++	timezones0.put("Africa/Lusaka", tz);
++	timezones0.put("Africa/Maputo", tz);
++	timezones0.put("Africa/Maseru", tz);
++	timezones0.put("Africa/Mbabane", tz);
++	timezones0.put("Africa/Tripoli", tz);
++	timezones0.put("Asia/Jerusalem", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "Asia/Amman",
++	   Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.FRIDAY, 1000 * 3600);
++	timezones0.put("Asia/Amman", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "Asia/Beirut",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
++	timezones0.put("Asia/Beirut", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "Asia/Damascus",
++	   Calendar.APRIL, 1, 0, 0 * 3600,
++	   Calendar.OCTOBER, 1, 0, 0 * 3600);
++	timezones0.put("Asia/Damascus", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "Asia/Gaza",
++	   Calendar.APRIL, 1, 0, 0 * 3600,
++	   Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600);
++	timezones0.put("Asia/Gaza", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "EET",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 4000 * 3600);
++	timezones0.put("EET", tz);
++	timezones0.put("Asia/Istanbul", tz);
++	timezones0.put("Asia/Nicosia", tz);
++	timezones0.put("Europe/Athens", tz);
++	timezones0.put("Europe/Bucharest", tz);
++	timezones0.put("Europe/Chisinau", tz);
++	timezones0.put("Europe/Helsinki", tz);
++	timezones0.put("Europe/Istanbul", tz);
++	timezones0.put("Europe/Kiev", tz);
++	timezones0.put("Europe/Mariehamn", tz);
++	timezones0.put("Europe/Nicosia", tz);
++	timezones0.put("Europe/Riga", tz);
++	timezones0.put("Europe/Simferopol", tz);
++	timezones0.put("Europe/Sofia", tz);
++	timezones0.put("Europe/Tallinn", tz);
++	timezones0.put("Europe/Uzhgorod", tz);
++	timezones0.put("Europe/Vilnius", tz);
++	timezones0.put("Europe/Zaporozhye", tz);
++	tz = new SimpleTimeZone
++	  (2000 * 3600, "Europe/Kaliningrad",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Europe/Kaliningrad", tz);
++	timezones0.put("Europe/Minsk", tz);
++	tz = new SimpleTimeZone
++	  (3000 * 3600, "Asia/Baghdad",
++	   Calendar.APRIL, 1, 0, 3000 * 3600,
++	   Calendar.OCTOBER, 1, 0, 4000 * 3600);
++	timezones0.put("Asia/Baghdad", tz);
++	tz = new SimpleTimeZone
++	  (3000 * 3600, "Europe/Moscow",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Europe/Moscow", tz);
++	timezones0.put("Europe/Volgograd", tz);
++	tz = new SimpleTimeZone(3000 * 3600, "EAT");
++	timezones0.put("EAT", tz);
++	timezones0.put("Africa/Addis_Ababa", tz);
++	timezones0.put("Africa/Asmara", tz);
++	timezones0.put("Africa/Dar_es_Salaam", tz);
++	timezones0.put("Africa/Djibouti", tz);
++	timezones0.put("Africa/Kampala", tz);
++	timezones0.put("Africa/Khartoum", tz);
++	timezones0.put("Africa/Mogadishu", tz);
++	timezones0.put("Africa/Nairobi", tz);
++	timezones0.put("Antarctica/Syowa", tz);
++	timezones0.put("Asia/Aden", tz);
++	timezones0.put("Asia/Bahrain", tz);
++	timezones0.put("Asia/Kuwait", tz);
++	timezones0.put("Asia/Qatar", tz);
++	timezones0.put("Asia/Riyadh", tz);
++	timezones0.put("Indian/Antananarivo", tz);
++	timezones0.put("Indian/Comoro", tz);
++	timezones0.put("Indian/Mayotte", tz);
++	tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran");
++	timezones0.put("Asia/Tehran", tz);
++	tz = new SimpleTimeZone
++	  (4000 * 3600, "Asia/Baku",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 4000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 5000 * 3600);
++	timezones0.put("Asia/Baku", tz);
++	tz = new SimpleTimeZone
++	  (4000 * 3600, "Asia/Yerevan",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Yerevan", tz);
++	timezones0.put("Europe/Samara", tz);
++	tz = new SimpleTimeZone(4000 * 3600, "NET");
++	timezones0.put("NET", tz);
++	timezones0.put("Asia/Dubai", tz);
++	timezones0.put("Asia/Muscat", tz);
++	timezones0.put("Asia/Tbilisi", tz);
++	timezones0.put("Indian/Mahe", tz);
++	timezones0.put("Indian/Mauritius", tz);
++	timezones0.put("Indian/Reunion", tz);
++	tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul");
++	timezones0.put("Asia/Kabul", tz);
++	tz = new SimpleTimeZone
++	  (5000 * 3600, "Asia/Yekaterinburg",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Yekaterinburg", tz);
++	tz = new SimpleTimeZone(5000 * 3600, "PLT");
++	timezones0.put("PLT", tz);
++	timezones0.put("Asia/Aqtau", tz);
++	timezones0.put("Asia/Aqtobe", tz);
++	timezones0.put("Asia/Ashgabat", tz);
++	timezones0.put("Asia/Dushanbe", tz);
++	timezones0.put("Asia/Karachi", tz);
++	timezones0.put("Asia/Oral", tz);
++	timezones0.put("Asia/Samarkand", tz);
++	timezones0.put("Asia/Tashkent", tz);
++	timezones0.put("Indian/Kerguelen", tz);
++	timezones0.put("Indian/Maldives", tz);
++	tz = new SimpleTimeZone(5500 * 3600, "BST");
++	timezones0.put("BST", tz);
++	timezones0.put("IST", tz);
++	timezones0.put("Asia/Calcutta", tz);
++	timezones0.put("Asia/Colombo", tz);
++	tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu");
++	timezones0.put("Asia/Katmandu", tz);
++	tz = new SimpleTimeZone(6000 * 3600, "Antarctica/Mawson");
++	timezones0.put("Antarctica/Mawson", tz);
++	timezones0.put("Antarctica/Vostok", tz);
++	timezones0.put("Asia/Almaty", tz);
++	timezones0.put("Asia/Bishkek", tz);
++	timezones0.put("Asia/Dhaka", tz);
++	timezones0.put("Asia/Qyzylorda", tz);
++	timezones0.put("Asia/Thimphu", tz);
++	timezones0.put("Indian/Chagos", tz);
++	tz = new SimpleTimeZone
++	  (6000 * 3600, "Asia/Novosibirsk",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Novosibirsk", tz);
++	timezones0.put("Asia/Omsk", tz);
++	tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon");
++	timezones0.put("Asia/Rangoon", tz);
++	timezones0.put("Indian/Cocos", tz);
++	tz = new SimpleTimeZone(7000 * 3600, "VST");
++	timezones0.put("VST", tz);
++	timezones0.put("Antarctica/Davis", tz);
++	timezones0.put("Asia/Bangkok", tz);
++	timezones0.put("Asia/Jakarta", tz);
++	timezones0.put("Asia/Phnom_Penh", tz);
++	timezones0.put("Asia/Pontianak", tz);
++	timezones0.put("Asia/Saigon", tz);
++	timezones0.put("Asia/Vientiane", tz);
++	timezones0.put("Indian/Christmas", tz);
++	tz = new SimpleTimeZone
++	  (7000 * 3600, "Asia/Hovd",
++	   Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
++	   Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
++	timezones0.put("Asia/Hovd", tz);
++	tz = new SimpleTimeZone
++	  (7000 * 3600, "Asia/Krasnoyarsk",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Krasnoyarsk", tz);
++	tz = new SimpleTimeZone(8000 * 3600, "CTT");
++	timezones0.put("CTT", tz);
++	timezones0.put("Antarctica/Casey", tz);
++	timezones0.put("Asia/Brunei", tz);
++	timezones0.put("Asia/Chongqing", tz);
++	timezones0.put("Asia/Harbin", tz);
++	timezones0.put("Asia/Hong_Kong", tz);
++	timezones0.put("Asia/Kashgar", tz);
++	timezones0.put("Asia/Kuala_Lumpur", tz);
++	timezones0.put("Asia/Kuching", tz);
++	timezones0.put("Asia/Macau", tz);
++	timezones0.put("Asia/Makassar", tz);
++	timezones0.put("Asia/Manila", tz);
++	timezones0.put("Asia/Shanghai", tz);
++	timezones0.put("Asia/Singapore", tz);
++	timezones0.put("Asia/Taipei", tz);
++	timezones0.put("Asia/Urumqi", tz);
++	timezones0.put("Australia/Perth", tz);
++	tz = new SimpleTimeZone
++	  (8000 * 3600, "Asia/Irkutsk",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Irkutsk", tz);
++	tz = new SimpleTimeZone
++	  (8000 * 3600, "Asia/Ulaanbaatar",
++	   Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
++	   Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
++	timezones0.put("Asia/Ulaanbaatar", tz);
++	tz = new SimpleTimeZone(8750 * 3600, "Australia/Eucla");
++	timezones0.put("Australia/Eucla", tz);
++	tz = new SimpleTimeZone
++	  (9000 * 3600, "Asia/Choibalsan",
++	   Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
++	   Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
++	timezones0.put("Asia/Choibalsan", tz);
++	tz = new SimpleTimeZone(9000 * 3600, "JST");
++	timezones0.put("JST", tz);
++	timezones0.put("Asia/Dili", tz);
++	timezones0.put("Asia/Jayapura", tz);
++	timezones0.put("Asia/Pyongyang", tz);
++	timezones0.put("Asia/Seoul", tz);
++	timezones0.put("Asia/Tokyo", tz);
++	timezones0.put("Pacific/Palau", tz);
++	tz = new SimpleTimeZone
++	  (9000 * 3600, "Asia/Yakutsk",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Yakutsk", tz);
++	tz = new SimpleTimeZone
++	  (9500 * 3600, "Australia/Adelaide",
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Australia/Adelaide", tz);
++	timezones0.put("Australia/Broken_Hill", tz);
++	tz = new SimpleTimeZone(9500 * 3600, "ACT");
++	timezones0.put("ACT", tz);
++	timezones0.put("Australia/Darwin", tz);
++	tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville");
++	timezones0.put("Antarctica/DumontDUrville", tz);
++	timezones0.put("Australia/Brisbane", tz);
++	timezones0.put("Australia/Lindeman", tz);
++	timezones0.put("Pacific/Guam", tz);
++	timezones0.put("Pacific/Port_Moresby", tz);
++	timezones0.put("Pacific/Saipan", tz);
++	timezones0.put("Pacific/Truk", tz);
++	tz = new SimpleTimeZone
++	  (10000 * 3600, "Asia/Sakhalin",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Sakhalin", tz);
++	timezones0.put("Asia/Vladivostok", tz);
++	tz = new SimpleTimeZone
++	  (10000 * 3600, "Australia/Currie",
++	   Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Australia/Currie", tz);
++	timezones0.put("Australia/Hobart", tz);
++	tz = new SimpleTimeZone
++	  (10000 * 3600, "AET",
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("AET", tz);
++	timezones0.put("Australia/Melbourne", tz);
++	timezones0.put("Australia/Sydney", tz);
++	tz = new SimpleTimeZone
++	  (10500 * 3600, "Australia/Lord_Howe",
++	  Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
++	  Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600);
++	timezones0.put("Australia/Lord_Howe", tz);
++	tz = new SimpleTimeZone
++	  (11000 * 3600, "Asia/Magadan",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Magadan", tz);
++	tz = new SimpleTimeZone(11000 * 3600, "SST");
++	timezones0.put("SST", tz);
++	timezones0.put("Pacific/Efate", tz);
++	timezones0.put("Pacific/Guadalcanal", tz);
++	timezones0.put("Pacific/Kosrae", tz);
++	timezones0.put("Pacific/Noumea", tz);
++	timezones0.put("Pacific/Ponape", tz);
++	tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk");
++	timezones0.put("Pacific/Norfolk", tz);
++	tz = new SimpleTimeZone
++	  (12000 * 3600, "NST",
++	   Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.MARCH, 3, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("NST", tz);
++	timezones0.put("Antarctica/McMurdo", tz);
++	timezones0.put("Antarctica/South_Pole", tz);
++	timezones0.put("Pacific/Auckland", tz);
++	tz = new SimpleTimeZone
++	  (12000 * 3600, "Asia/Anadyr",
++	   Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
++	   Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
++	timezones0.put("Asia/Anadyr", tz);
++	timezones0.put("Asia/Kamchatka", tz);
++	tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji");
++	timezones0.put("Pacific/Fiji", tz);
++	timezones0.put("Pacific/Funafuti", tz);
++	timezones0.put("Pacific/Kwajalein", tz);
++	timezones0.put("Pacific/Majuro", tz);
++	timezones0.put("Pacific/Nauru", tz);
++	timezones0.put("Pacific/Tarawa", tz);
++	timezones0.put("Pacific/Wake", tz);
++	timezones0.put("Pacific/Wallis", tz);
++	tz = new SimpleTimeZone
++	  (12750 * 3600, "Pacific/Chatham",
++	   Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600,
++	   Calendar.MARCH, 3, Calendar.SUNDAY, 3750 * 3600);
++	timezones0.put("Pacific/Chatham", tz);
++	tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury");
++	timezones0.put("Pacific/Enderbury", tz);
++	timezones0.put("Pacific/Tongatapu", tz);
++	tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati");
++	timezones0.put("Pacific/Kiritimati", tz);
++      }
++    return timezones0;
+   }
+ 
++  /**
++   * Maps a time zone name (with optional GMT offset and daylight time
++   * zone name) to one of the known time zones.  This method called
++   * with the result of <code>System.getProperty("user.timezone")</code>
++   * or <code>getDefaultTimeZoneId()</code>.  Note that giving one of
++   * the standard tz data names from ftp://elsie.nci.nih.gov/pub/ is
++   * preferred.  
++   * The time zone name can be given as follows:
++   * <code>(standard zone name)[(GMT offset)[(DST zone name)[DST offset]]]
++   * </code>
++   * <p>
++   * If only a (standard zone name) is given (no numbers in the
++   * String) then it gets mapped directly to the TimeZone with that
++   * name, if that fails null is returned.
++   * <p>
++   * Alternately, a POSIX-style TZ string can be given, defining the time zone:
++   * <code>std offset dst offset,date/time,date/time</code>
++   * See the glibc manual, or the man page for <code>tzset</code> for details
++   * of this format.
++   * <p>
++   * A GMT offset is the offset to add to the local time to get GMT.
++   * If a (GMT offset) is included (either in seconds or hours) then
++   * an attempt is made to find a TimeZone name matching both the name
++   * and the offset (that doesn't observe daylight time, if the
++   * timezone observes daylight time then you must include a daylight
++   * time zone name after the offset), if that fails then a TimeZone
++   * with the given GMT offset is returned (whether or not the
++   * TimeZone observes daylight time is ignored), if that also fails
++   * the GMT TimeZone is returned.
++   * <p>
++   * If the String ends with (GMT offset)(daylight time zone name)
++   * then an attempt is made to find a TimeZone with the given name and
++   * GMT offset that also observes (the daylight time zone name is not
++   * currently used in any other way), if that fails a TimeZone with
++   * the given GMT offset that observes daylight time is returned, if
++   * that also fails the GMT TimeZone is returned.
++   * <p>
++   * Examples: In Chicago, the time zone id could be "CST6CDT", but
++   * the preferred name would be "America/Chicago".  In Indianapolis
++   * (which does not have Daylight Savings Time) the string could be
++   * "EST5", but the preferred name would be "America/Indianapolis".
++   * The standard time zone name for The Netherlands is "Europe/Amsterdam",
++   * but can also be given as "CET-1CEST".
++   */
++  private static TimeZone getDefaultTimeZone(String sysTimeZoneId)
++  {
++    String stdName = null;
++    int stdOffs;
++    int dstOffs;
++    try
++      {
++	int idLength = sysTimeZoneId.length();
++
++	int index = 0;
++	int prevIndex;
++	char c;
++
++	// get std
++	do
++	  c = sysTimeZoneId.charAt(index);
++	while (c != '+' && c != '-' && c != ',' && c != ':'
++	       && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
++
++	if (index >= idLength)
++	  return getTimeZoneInternal(sysTimeZoneId);
++
++	stdName = sysTimeZoneId.substring(0, index);
++	prevIndex = index;
++
++	// get the std offset
++	do
++	  c = sysTimeZoneId.charAt(index++);
++	while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
++	       && index < idLength);
++	if (index < idLength)
++	  index--;
++
++	{ // convert the dst string to a millis number
++	    String offset = sysTimeZoneId.substring(prevIndex, index);
++	    prevIndex = index;
++
++	    if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
++	      stdOffs = parseTime(offset.substring(1));
++	    else
++	      stdOffs = parseTime(offset);
++
++	    if (offset.charAt(0) == '-')
++	      stdOffs = -stdOffs;
+ 
+-  /* Look up default timezone */
+-  static
++	    // TZ timezone offsets are positive when WEST of the meridian.
++	    stdOffs = -stdOffs;
++	}
++
++	// Done yet? (Format: std offset)
++	if (index >= idLength)
++	  {
++	    // Do we have an existing timezone with that name and offset?
++	    TimeZone tz = getTimeZoneInternal(stdName);
++	    if (tz != null)
++	      if (tz.getRawOffset() == stdOffs)
++		return tz;
++
++	    // Custom then.
++	    return new SimpleTimeZone(stdOffs, stdName);
++	  }
++
++	// get dst
++	do
++	  c = sysTimeZoneId.charAt(index);
++	while (c != '+' && c != '-' && c != ',' && c != ':'
++	       && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
++
++	// Done yet? (Format: std offset dst)
++	if (index >= idLength)
++	  {
++	    // Do we have an existing timezone with that name and offset
++	    // which has DST?
++	    TimeZone tz = getTimeZoneInternal(stdName);
++	    if (tz != null)
++	      if (tz.getRawOffset() == stdOffs && tz.useDaylightTime())
++		return tz;
++
++	    // Custom then.
++	    return new SimpleTimeZone(stdOffs, stdName);
++	  }
++
++	// get the dst offset
++	prevIndex = index;
++	do
++	  c = sysTimeZoneId.charAt(index++);
++	while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
++	       && index < idLength);
++	if (index < idLength)
++	  index--;
++
++	if (index == prevIndex && (c == ',' || c == ';'))
++	  {
++	    // Missing dst offset defaults to one hour ahead of standard
++	    // time.
++	    dstOffs = stdOffs + 60 * 60 * 1000;
++	  }
++	else
++	  { // convert the dst string to a millis number
++	    String offset = sysTimeZoneId.substring(prevIndex, index);
++	    prevIndex = index;
++
++	    if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
++	      dstOffs = parseTime(offset.substring(1));
++	    else
++	      dstOffs = parseTime(offset);
++
++	    if (offset.charAt(0) == '-')
++	      dstOffs = -dstOffs;
++
++	    // TZ timezone offsets are positive when WEST of the meridian.
++	    dstOffs = -dstOffs;
++	  }
++
++	// Done yet? (Format: std offset dst offset)
++	// FIXME: We don't support DST without a rule given. Should we?
++	if (index >= idLength)
++	  {
++	    // Time Zone existing with same name, dst and offsets?
++	    TimeZone tz = getTimeZoneInternal(stdName);
++	    if (tz != null)
++	      if (tz.getRawOffset() == stdOffs && tz.useDaylightTime())
++		{
++		  if ((tz instanceof SimpleTimeZone)
++		      && ((SimpleTimeZone) tz).getDSTSavings()
++			 == (dstOffs - stdOffs))
++		    return tz;
++		  if ((tz instanceof ZoneInfo)
++		      && ((ZoneInfo) tz).getDSTSavings()
++			 == (dstOffs - stdOffs))
++		    return tz;
++		}
++
++	    return new SimpleTimeZone(stdOffs, stdName);
++	  }
++
++	// get the DST rule
++	if (sysTimeZoneId.charAt(index) == ','
++	    || sysTimeZoneId.charAt(index) == ';')
++	  {
++	    index++;
++	    int offs = index;
++	    while (sysTimeZoneId.charAt(index) != ','
++	           && sysTimeZoneId.charAt(index) != ';')
++	      index++;
++	    String startTime = sysTimeZoneId.substring(offs, index);
++	    index++;
++	    String endTime = sysTimeZoneId.substring(index);
++
++	    index = startTime.indexOf('/');
++	    int startMillis;
++	    int endMillis;
++	    String startDate;
++	    String endDate;
++	    if (index != -1)
++	      {
++		startDate = startTime.substring(0, index);
++		startMillis = parseTime(startTime.substring(index + 1));
++	      }
++	    else
++	      {
++		startDate = startTime;
++		// if time isn't given, default to 2:00:00 AM.
++		startMillis = 2 * 60 * 60 * 1000;
++	      }
++	    index = endTime.indexOf('/');
++	    if (index != -1)
++	      {
++		endDate = endTime.substring(0, index);
++		endMillis = parseTime(endTime.substring(index + 1));
++	      }
++	    else
++	      {
++		endDate = endTime;
++		// if time isn't given, default to 2:00:00 AM.
++		endMillis = 2 * 60 * 60 * 1000;
++	      }
++
++	    int[] start = getDateParams(startDate);
++	    int[] end = getDateParams(endDate);
++	    return new SimpleTimeZone(stdOffs, stdName, start[0], start[1],
++	                              start[2], startMillis, end[0], end[1],
++	                              end[2], endMillis, (dstOffs - stdOffs));
++	  }
++      }
++
++    // FIXME: Produce a warning here?
++    catch (IndexOutOfBoundsException _)
++      {
++      }
++    catch (NumberFormatException _)
++      {
++      }
++
++    return null;
++  }
++
++  /**
++   * Parses and returns the params for a POSIX TZ date field,
++   * in the format int[]{ month, day, dayOfWeek }, following the
++   * SimpleTimeZone constructor rules.
++   */
++  private static int[] getDateParams(String date)
+   {
+-    // System.loadLibrary("javautil");
++    int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
++    int month;
+ 
+-    String tzid = System.getProperty("user.timezone");
++    if (date.charAt(0) == 'M' || date.charAt(0) == 'm')
++      {
++	int day;
++
++	// Month, week of month, day of week
++
++	// "Mm.w.d".  d is between 0 (Sunday) and 6.  Week w is
++	// between 1 and 5; Week 1 is the first week in which day d
++	// occurs and Week 5 specifies the last d day in the month.
++	// Month m is between 1 and 12.
++
++	month = Integer.parseInt(date.substring(1, date.indexOf('.')));
++	int week = Integer.parseInt(date.substring(date.indexOf('.') + 1,
++	                                           date.lastIndexOf('.')));
++	int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.')
++	                                                + 1));
++	dayOfWeek++; // Java day of week is one-based, Sunday is first day.
++
++ 	if (week == 5)
++ 	  day = -1; // last day of month is -1 in java, 5 in TZ
++ 	else
++	  {
++	    // First day of week starting on or after.  For example,
++	    // to specify the second Sunday of April, set month to
++	    // APRIL, day-of-month to 8, and day-of-week to -SUNDAY.
++	    day = (week - 1) * 7 + 1;
++	    dayOfWeek = -dayOfWeek;
++	  }
++
++	month--; // Java month is zero-based.
++	return new int[] { month, day, dayOfWeek };
++      }
++
++    // julian day, either zero-based 0<=n<=365 (incl feb 29)
++    // or one-based 1<=n<=365 (no feb 29)
++    int julianDay; // Julian day,
++
++    if (date.charAt(0) != 'J' || date.charAt(0) != 'j')
++      {
++	julianDay = Integer.parseInt(date.substring(1));
++	julianDay++; // make 1-based
++	// Adjust day count to include feb 29.
++	dayCount = new int[]
++	           {
++	             0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
++	           };
++      }
++    else
++      // 1-based julian day
++      julianDay = Integer.parseInt(date);
++
++    int i = 11;
++    while (i > 0)
++      if (dayCount[i] < julianDay)
++	break;
++      else
++	i--;
++    julianDay -= dayCount[i];
++    month = i;
++    return new int[] { month, julianDay, 0 };
++  }
+ 
+-    if (tzid == null)
+-      tzid = "GMT";
++  /**
++   * Parses a time field hh[:mm[:ss]], returning the result
++   * in milliseconds. No leading sign.
++   */
++  private static int parseTime(String time)
++  {
++    int millis = 0;
++    int i = 0;
+ 
+-    defaultZone = getTimeZone(tzid);
++    while (i < time.length())
++      if (time.charAt(i) == ':')
++	break;
++      else
++	i++;
++    millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i));
++    if (i >= time.length())
++      return millis;
++
++    int iprev = ++i;
++    while (i < time.length())
++      if (time.charAt(i) == ':')
++	break;
++      else
++	i++;
++    millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i));
++    if (i >= time.length())
++      return millis;
++
++    millis += 1000 * Integer.parseInt(time.substring(++i));
++    return millis;
+   }
+ 
++  /* This method returns us a time zone id string which is in the
++     form <standard zone name><GMT offset><daylight time zone name>.
++     The GMT offset is in seconds, except where it is evenly divisible
++     by 3600, then it is in hours.  If the zone does not observe
++     daylight time, then the daylight zone name is omitted.  Examples:
++     in Chicago, the timezone would be CST6CDT.  In Indianapolis
++     (which does not have Daylight Savings Time) the string would
++     be EST5
++   */
++  private static native String getDefaultTimeZoneId();
++  private static native String getTZEnvVar();
++
+   /**
+    * Gets the time zone offset, for current date, modified in case of 
+    * daylight savings.  This is the offset to add to UTC to get the local
+@@ -916,6 +1449,8 @@ public abstract class TimeZone implement
+ 	// TimeZone knows nothing about daylight saving offsets.
+ 	offset += ((SimpleTimeZone) this).getDSTSavings();
+       }
++    if (dst && this instanceof ZoneInfo)
++      offset += ((ZoneInfo) this).getDSTSavings();
+ 
+     StringBuffer sb = new StringBuffer(9);
+     sb.append("GMT");
+@@ -949,30 +1484,67 @@ public abstract class TimeZone implement
+    * @return The time zone for the identifier or GMT, if no such time
+    * zone exists.
+    */
+-  // FIXME: XXX: JCL indicates this and other methods are synchronized.
+-  public static TimeZone getTimeZone(String ID)
++  private static TimeZone getTimeZoneInternal(String ID)
+   {
+     // First check timezones hash
+-    TimeZone tz = (TimeZone) timezones.get(ID);
+-    if (tz != null)
++    TimeZone tz = null;
++    TimeZone tznew = null;
++    for (int pass = 0; pass < 2; pass++)
+       {
+-	if (tz.getID().equals(ID))
+-	  return tz;
++	synchronized (TimeZone.class)
++	  {
++	    tz = (TimeZone) timezones().get(ID);
++	    if (tz != null)
++	      {
++		if (!tz.getID().equals(ID))
++		  {
++		    // We always return a timezone with the requested ID.
++		    // This is the same behaviour as with JDK1.2.
++		    tz = (TimeZone) tz.clone();
++		    tz.setID(ID);
++		    // We also save the alias, so that we return the same
++		    // object again if getTimeZone is called with the same
++		    // alias.
++		    timezones().put(ID, tz);
++		  }
++		return tz;
++	      }
++	    else if (tznew != null)
++	      {
++		timezones().put(ID, tznew);
++		return tznew;
++	      }
++	  }
++
++	if (pass == 1 || zoneinfo_dir == null)
++	  return null;
+ 
+-	// We always return a timezone with the requested ID.
+-	// This is the same behaviour as with JDK1.2.
+-	tz = (TimeZone) tz.clone();
+-	tz.setID(ID);
+-	// We also save the alias, so that we return the same
+-	// object again if getTimeZone is called with the same
+-	// alias.
+-	timezones.put(ID, tz);
+-	return tz;
++	// aliases0 is never changing after first timezones(), so should
++	// be safe without synchronization.
++	String zonename = (String) aliases0.get(ID);
++	if (zonename == null)
++	  zonename = ID;
++
++	// Read the file outside of the critical section, it is expensive.
++	tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir
++				     + File.separatorChar + zonename);
++	if (tznew == null)
++	  return null;
+       }
+ 
+-    // See if the ID is really a GMT offset form.
+-    // Note that GMT is in the table so we know it is different.
+-    if (ID.startsWith("GMT"))
++    return null;
++  }
++
++  /**
++   * Gets the TimeZone for the given ID.
++   * @param ID the time zone identifier.
++   * @return The time zone for the identifier or GMT, if no such time
++   * zone exists.
++   */
++  public static TimeZone getTimeZone(String ID)
++  {
++    // Check for custom IDs first
++    if (ID.startsWith("GMT") && ID.length() > 3)
+       {
+ 	int pos = 3;
+ 	int offset_direction = 1;
+@@ -1017,8 +1589,20 @@ public abstract class TimeZone implement
+ 		  }
+ 	      }
+ 
+-	    return new SimpleTimeZone((hour * (60 * 60 * 1000) +
+-				       minute * (60 * 1000))
++	    // Custom IDs have to be normalized
++	    StringBuffer sb = new StringBuffer(9);
++	    sb.append("GMT");
++
++	    sb.append(offset_direction >= 0 ? '+' : '-');
++	    sb.append((char) ('0' + hour / 10));
++	    sb.append((char) ('0' + hour % 10));
++	    sb.append(':');
++	    sb.append((char) ('0' + minute / 10));
++	    sb.append((char) ('0' + minute % 10));
++	    ID = sb.toString();
++
++	    return new SimpleTimeZone((hour * (60 * 60 * 1000)
++				       + minute * (60 * 1000))
+ 				      * offset_direction, ID);
+ 	  }
+ 	catch (NumberFormatException e)
+@@ -1026,8 +1610,11 @@ public abstract class TimeZone implement
+ 	  }
+       }
+ 
+-    // Finally, return GMT per spec
+-    return getTimeZone("GMT");
++    TimeZone tz = getTimeZoneInternal(ID);
++    if (tz != null)
++      return tz;
++
++    return new SimpleTimeZone(0, "GMT");
+   }
+ 
+   /**
+@@ -1040,37 +1627,134 @@ public abstract class TimeZone implement
+    */
+   public static String[] getAvailableIDs(int rawOffset)
+   {
++    synchronized (TimeZone.class)
++      {
++	Hashtable h = timezones();
++	int count = 0;
++	if (zoneinfo_dir == null)
++	  {
++	    Iterator iter = h.entrySet().iterator();
++	    while (iter.hasNext())
++	      {
++		// Don't iterate the values, since we want to count
++		// doubled values (aliases)
++		Map.Entry entry = (Map.Entry) iter.next();
++		if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
++		  count++;
++	      }
++
++	    String[] ids = new String[count];
++	    count = 0;
++	    iter = h.entrySet().iterator();
++	    while (iter.hasNext())
++	      {
++		Map.Entry entry = (Map.Entry) iter.next();
++		if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
++		  ids[count++] = (String) entry.getKey();
++	      }
++	    return ids;
++	  }
++      }
++
++    String[] s = getAvailableIDs();
+     int count = 0;
+-    Iterator iter = timezones.entrySet().iterator();
+-    while (iter.hasNext())
++    for (int i = 0; i < s.length; i++)
+       {
+-	// Don't iterate the values, since we want to count 
+-	// doubled values (aliases)
+-	Map.Entry entry = (Map.Entry) iter.next();
+-	if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
++	TimeZone t = getTimeZoneInternal(s[i]);
++	if (t == null || t.getRawOffset() != rawOffset)
++	  s[i] = null;
++	else
+ 	  count++;
+       }
+-
+     String[] ids = new String[count];
+     count = 0;
+-    iter = timezones.entrySet().iterator();
+-    while (iter.hasNext())
+-      {
+-	Map.Entry entry = (Map.Entry) iter.next();
+-	if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
+-	  ids[count++] = (String) entry.getKey();
+-      }
++    for (int i = 0; i < s.length; i++)
++    if (s[i] != null)
++      ids[count++] = s[i];
++
+     return ids;
+   }
+ 
++  private static int getAvailableIDs(File d, String prefix, ArrayList list)
++    {
++      String[] files = d.list();
++      int count = files.length;
++      boolean top = prefix.length() == 0;
++      list.add (files);
++      for (int i = 0; i < files.length; i++)
++	{
++	  if (top
++	      && (files[i].equals("posix")
++		  || files[i].equals("right")
++		  || files[i].endsWith(".tab")
++		  || aliases0.get(files[i]) != null))
++	    {
++	      files[i] = null;
++	      count--;
++	      continue;
++	    }
++
++	  File f = new File(d, files[i]);
++	  if (f.isDirectory())
++	    {
++	      count += getAvailableIDs(f, prefix + files[i]
++				       + File.separatorChar, list) - 1;
++	      files[i] = null;
++	    }
++	  else
++	    files[i] = prefix + files[i];
++	}
++      return count;
++    }
++
+   /**
+    * Gets all available IDs.
+    * @return An array of all supported IDs.
+    */
+   public static String[] getAvailableIDs()
+   {
+-    return (String[])
+-      timezones.keySet().toArray(new String[timezones.size()]);
++    synchronized (TimeZone.class)
++      {
++	Hashtable h = timezones();
++	if (zoneinfo_dir == null)
++	  return (String[]) h.keySet().toArray(new String[h.size()]);
++
++	if (availableIDs != null)
++	  {
++	    String[] ids = new String[availableIDs.length];
++	    for (int i = 0; i < availableIDs.length; i++)
++	      ids[i] = availableIDs[i];
++	    return ids;
++	  }
++
++	File d = new File(zoneinfo_dir);
++	ArrayList list = new ArrayList(30);
++	int count = getAvailableIDs(d, "", list) + aliases0.size();
++	availableIDs = new String[count];
++	String[] ids = new String[count];
++
++	count = 0;
++	for (int i = 0; i < list.size(); i++)
++	  {
++	    String[] s = (String[]) list.get(i);
++	    for (int j = 0; j < s.length; j++)
++	      if (s[j] != null)
++		{
++		  availableIDs[count] = s[j];
++		  ids[count++] = s[j];
++		}
++	  }
++
++	Iterator iter = aliases0.entrySet().iterator();
++	while (iter.hasNext())
++	  {
++	    Map.Entry entry = (Map.Entry) iter.next();
++	    availableIDs[count] = (String) entry.getKey();
++	    ids[count++] = (String) entry.getKey();
++	  }
++
++	return ids;
++      }
+   }
+ 
+   /**
+@@ -1081,12 +1765,12 @@ public abstract class TimeZone implement
+    */
+   public static TimeZone getDefault()
+   {
+-    return defaultZone;
++    return defaultZone();
+   }
+ 
+   public static void setDefault(TimeZone zone)
+   {
+-    defaultZone = zone;
++    defaultZone0 = zone;
+   }
+ 
+   /**
+@@ -1116,4 +1800,66 @@ public abstract class TimeZone implement
+ 	return null;
+       }
+   }
++
++  /**
++   * Tries to read the time zone name from a file.
++   * If the file cannot be read or an IOException occurs null is returned.
++   * <p>
++   * The /etc/sysconfig/clock file is not standard, but a lot of systems
++   * have it. The file is included by shell scripts and the timezone
++   * name is defined in ZONE variable.
++   * This routine should grok it with or without quotes:
++   * ZONE=America/New_York
++   * or
++   * ZONE="Europe/London"
++   */
++  private static String readSysconfigClockFile(String file)
++  {
++    BufferedReader br = null;
++    try
++      {
++	FileInputStream fis = new FileInputStream(file);
++	BufferedInputStream bis = new BufferedInputStream(fis);
++	br = new BufferedReader(new InputStreamReader(bis));
++
++	for (String line = br.readLine(); line != null; line = br.readLine())
++	  {
++	    line = line.trim();
++	    if (line.length() < 8 || !line.startsWith("ZONE="))
++	      continue;
++	    int posstart = 6;
++	    int posend;
++	    if (line.charAt(5) == '"')
++	      posend = line.indexOf('"', 6);
++	    else if (line.charAt(5) == '\'')
++	      posend = line.indexOf('\'', 6);
++	    else
++	      {
++		posstart = 5;
++		posend = line.length();
++	      }
++	    if (posend < 0)
++	      return null;
++	    return line.substring(posstart, posend);
++	  }
++	return null;
++      }
++    catch (IOException ioe)
++      {
++	// Parse error, not a proper tzfile.
++	return null;
++      }
++    finally
++      {
++	try
++	  {
++	    if (br != null)
++	      br.close();
++	  }
++	catch (IOException ioe)
++	  {
++	    // Error while close, nothing we can do.
++	  }
++      }
++  }
+ }
+--- libjava/java/lang/System.java.jj	2007-02-23 21:27:25.000000000 +0100
++++ libjava/java/lang/System.java	2007-02-24 21:47:38.000000000 +0100
+@@ -42,83 +42,6 @@ public final class System
+ 
+   public static native long currentTimeMillis ();
+ 
+-  // FIXME: When merging with Classpath, remember to remove the call to
+-  // getDefaultTimeZoneId from java.util.Timezone.
+-  private static native String getSystemTimeZone ();
+-
+-  // Get the System Timezone as reported by the OS.  It should be in
+-  // the form PST8PDT so we'll need to parse it and check that it's valid.
+-  // The result is used to set the user.timezone property in init_properties.
+-  // FIXME: Using the code from Classpath for generating the System
+-  // Timezone IMO is suboptimal because it ignores whether the rules for
+-  // DST match up.
+-  private static String getDefaultTimeZoneId ()
+-  {
+-    String sysTimeZoneId = getSystemTimeZone ();
+-
+-    // Check if this is a valid timezone.  Make sure the IDs match
+-    // since getTimeZone returns GMT if no match is found.
+-    TimeZone tz = TimeZone.getTimeZone (sysTimeZoneId);
+-    if (tz.getID ().equals (sysTimeZoneId))
+-      return sysTimeZoneId;
+-
+-    // Check if the base part of sysTimeZoneId is a valid timezone that
+-    // matches with daylight usage and rawOffset.  Make sure the IDs match
+-    // since getTimeZone returns GMT if no match is found.
+-    // First find start of GMT offset info and any Daylight zone name.
+-    int startGMToffset = 0;
+-    int sysTimeZoneIdLength = sysTimeZoneId.length();
+-    for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++)
+-      {
+-        if (Character.isDigit (sysTimeZoneId.charAt (i)))
+-	  startGMToffset = i;
+-      }
+-
+-    int startDaylightZoneName = 0;
+-    boolean usesDaylight = false;
+-    for (int i = sysTimeZoneIdLength - 1;
+-         i >= 0 && !Character.isDigit (sysTimeZoneId.charAt (i)); --i)
+-      {
+-        startDaylightZoneName = i;
+-      }
+-    if (startDaylightZoneName > 0)
+-      usesDaylight = true;
+-
+-    int GMToffset = Integer.parseInt (startDaylightZoneName == 0 ?
+-      sysTimeZoneId.substring (startGMToffset) :
+-      sysTimeZoneId.substring (startGMToffset, startDaylightZoneName));
+-
+-    // Offset could be in hours or seconds.  Convert to millis.
+-    if (GMToffset < 24)
+-      GMToffset *= 60 * 60;
+-    GMToffset *= -1000;
+-
+-    String tzBasename = sysTimeZoneId.substring (0, startGMToffset);
+-    tz = TimeZone.getTimeZone (tzBasename);
+-    if (tz.getID ().equals (tzBasename) && tz.getRawOffset () == GMToffset)
+-      {
+-        boolean tzUsesDaylight = tz.useDaylightTime ();
+-        if (usesDaylight && tzUsesDaylight || !usesDaylight && !tzUsesDaylight)
+-          return tzBasename;
+-      }
+-  
+-    // If no match, see if a valid timezone has the same attributes as this
+-    // and then use it instead.
+-    String[] IDs = TimeZone.getAvailableIDs (GMToffset);
+-    for (int i = 0; i < IDs.length; ++i)
+-      {
+-	// FIXME: The daylight savings rules may not match the rules
+-	// for the desired zone.
+-        boolean IDusesDaylight =
+-	  TimeZone.getTimeZone (IDs[i]).useDaylightTime ();
+-        if (usesDaylight && IDusesDaylight || !usesDaylight && !IDusesDaylight)
+-	  return IDs[i];
+-      }
+-
+-    // If all else fails, return null.
+-    return null;
+-  }
+-
+   public static void exit (int status)
+   {
+     Runtime.getRuntime().exit(status);
+--- libjava/posix.cc.jj	2007-02-23 21:17:39.000000000 +0100
++++ libjava/posix.cc	2007-02-23 21:27:25.000000000 +0100
+@@ -79,6 +79,10 @@ _Jv_platform_initProperties (java::util:
+   if (! tmpdir)
+     tmpdir = "/tmp";
+   SET ("java.io.tmpdir", tmpdir);
++  const char *zoneinfodir = ::getenv("TZDATA");
++  if (! zoneinfodir)
++    zoneinfodir = "/usr/share/zoneinfo";
++  SET ("gnu.java.util.zoneinfo.dir", zoneinfodir);
+ }
+ 
+ static inline void
+--- libjava/gnu/java/util/ZoneInfo.java.jj	2007-02-23 21:27:25.000000000 +0100
++++ libjava/gnu/java/util/ZoneInfo.java	2007-02-24 19:14:27.000000000 +0100
+@@ -0,0 +1,1149 @@
++/* gnu.java.util.ZoneInfo
++   Copyright (C) 2007 Free Software Foundation, Inc.
++
++This file is part of GNU Classpath.
++
++GNU Classpath 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, or (at your option)
++any later version.
++
++GNU Classpath is distributed in the hope that it will be useful, but
++WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GNU Classpath; see the file COPYING.  If not, write to the
++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++02110-1301 USA.
++
++Linking this library statically or dynamically with other modules is
++making a combined work based on this library.  Thus, the terms and
++conditions of the GNU General Public License cover the whole
++combination.
++
++As a special exception, the copyright holders of this library give you
++permission to link this library with independent modules to produce an
++executable, regardless of the license terms of these independent
++modules, and to copy and distribute the resulting executable under
++terms of your choice, provided that you also meet, for each linked
++independent module, the terms and conditions of the license of that
++module.  An independent module is a module which is not derived from
++or based on this library.  If you modify this library, you may extend
++this exception to your version of the library, but you are not
++obligated to do so.  If you do not wish to do so, delete this
++exception statement from your version. */
++
++
++package gnu.java.util;
++
++import java.io.BufferedInputStream;
++import java.io.DataInputStream;
++import java.io.EOFException;
++import java.io.FileInputStream;
++import java.io.InputStream;
++import java.io.IOException;
++import java.util.Calendar;
++import java.util.Date;
++import java.util.GregorianCalendar;
++import java.util.SimpleTimeZone;
++import java.util.TimeZone;
++
++/**
++ * This class represents more advanced variant of java.util.SimpleTimeZone.
++ * It can handle zic(8) compiled transition dates plus uses a SimpleTimeZone
++ * for years beyond last precomputed transition.  Before first precomputed
++ * transition it assumes no daylight saving was in effect.
++ * Timezones that never used daylight saving time should use just
++ * SimpleTimeZone instead of this class.
++ *
++ * This object is tightly bound to the Gregorian calendar.  It assumes
++ * a regular seven days week, and the month lengths are that of the
++ * Gregorian Calendar.
++ *
++ * @see Calendar
++ * @see GregorianCalendar
++ * @see SimpleTimeZone
++ * @author Jakub Jelinek
++ */
++public class ZoneInfo extends TimeZone
++{
++  private static final int SECS_SHIFT = 22;
++  private static final long OFFSET_MASK = (1 << 21) - 1;
++  private static final int OFFSET_SHIFT = 64 - 21;
++  private static final long IS_DST = 1 << 21;
++
++  /**
++   * The raw time zone offset in milliseconds to GMT, ignoring
++   * daylight savings.
++   * @serial
++   */
++  private int rawOffset;
++
++  /**
++   * Cached DST savings for the last transition rule.
++   */
++  private int dstSavings;
++
++  /**
++   * Cached flag whether last transition rule uses DST saving.
++   */
++  private boolean useDaylight;
++
++  /**
++   * Array of encoded transitions.
++   * Transition time in UTC seconds since epoch is in the most
++   * significant 64 - SECS_SHIFT bits, then one bit flag
++   * whether DST is active and the least significant bits
++   * containing offset relative to rawOffset.  Both the DST
++   * flag and relative offset apply to time before the transition
++   * and after or equal to previous transition if any.
++   * The array must be sorted.
++   */
++  private long[] transitions;
++
++  /**
++   * SimpleTimeZone rule which applies on or after the latest
++   * transition.  If the DST changes are not expresible as a
++   * SimpleTimeZone rule, then the rule should just contain
++   * the standard time and no DST time.
++   */
++  private SimpleTimeZone lastRule;
++
++  /**
++   * Cached GMT SimpleTimeZone object for internal use in
++   * getOffset method.
++   */
++  private static SimpleTimeZone gmtZone = null;
++
++  static final long serialVersionUID = -3740626706860383657L;
++
++  /**
++   * Create a <code>ZoneInfo</code> with the given time offset
++   * from GMT and with daylight savings.
++   *
++   * @param rawOffset The time offset from GMT in milliseconds.
++   * @param id  The identifier of this time zone.
++   * @param transitions  Array of transition times in UTC seconds since
++   * Epoch in topmost 42 bits, below that 1 boolean bit whether the time
++   * before that transition used daylight saving and in bottommost 21
++   * bits relative daylight saving offset against rawOffset in seconds
++   * that applies before this transition.
++   * @param endRule SimpleTimeZone class describing the daylight saving
++   * rules after the last transition.
++   */
++  public ZoneInfo(int rawOffset, String id, long[] transitions,
++		  SimpleTimeZone lastRule)
++  {
++    if (transitions == null || transitions.length < 1)
++      throw new IllegalArgumentException("transitions must not be null");
++    if (lastRule == null)
++      throw new IllegalArgumentException("lastRule must not be null");
++    this.rawOffset = rawOffset;
++    this.transitions = transitions;
++    this.lastRule = lastRule;
++    setID(id);
++    computeDSTSavings();
++  }
++
++  /**
++   * Gets the time zone offset, for current date, modified in case of
++   * daylight savings.  This is the offset to add to UTC to get the local
++   * time.
++   *
++   * The day must be a positive number and dayOfWeek must be a positive value
++   * from Calendar.  dayOfWeek is redundant, but must match the other values
++   * or an inaccurate result may be returned.
++   *
++   * @param era the era of the given date
++   * @param year the year of the given date
++   * @param month the month of the given date, 0 for January.
++   * @param day the day of month
++   * @param dayOfWeek the day of week; this must match the other fields.
++   * @param millis the millis in the day (in local standard time)
++   * @return the time zone offset in milliseconds.
++   * @throws IllegalArgumentException if arguments are incorrect.
++   */
++  public int getOffset(int era, int year, int month, int day, int dayOfWeek,
++		       int millis)
++  {
++    if (gmtZone == null)
++      gmtZone = new SimpleTimeZone(0, "GMT");
++
++    if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY)
++      throw new IllegalArgumentException("dayOfWeek out of range");
++    if (month < Calendar.JANUARY || month > Calendar.DECEMBER)
++      throw new IllegalArgumentException("month out of range:" + month);
++
++    if (era != GregorianCalendar.AD)
++      return (int) (((transitions[0] << OFFSET_SHIFT) >> OFFSET_SHIFT) * 1000);
++
++    GregorianCalendar cal = new GregorianCalendar((TimeZone) gmtZone);
++    cal.set(year, month, day, 0, 0, 0);
++    if (cal.get(Calendar.DAY_OF_MONTH) != day)
++      throw new IllegalArgumentException("day out of range");
++
++    long date = cal.getTime().getTime() - rawOffset + millis;
++    long d = (date >= 0 ? date / 1000 : (date + 1) / 1000 - 1);
++    long transition = findTransition(d);
++
++    // For times on or after last transition use lastRule.
++    if (transition == Long.MAX_VALUE)
++      return lastRule.getOffset(era, year, month, day, dayOfWeek, millis);
++
++    return (int) (((transition << OFFSET_SHIFT) >> OFFSET_SHIFT) * 1000);
++  }
++
++  private long findTransition(long secs)
++  {
++    if (secs < (transitions[0] >> SECS_SHIFT))
++      return transitions[0];
++
++    if (secs >= (transitions[transitions.length-1] >> SECS_SHIFT))
++      return Long.MAX_VALUE;
++
++    long val = (secs + 1) << SECS_SHIFT;
++    int lo = 1;
++    int hi = transitions.length;
++    int mid = 1;
++    while (lo < hi)
++      {
++	mid = (lo + hi) / 2;
++	// secs < (transitions[mid-1] >> SECS_SHIFT)
++	if (val <= transitions[mid-1])
++	  hi = mid;
++	// secs >= (transitions[mid] >> SECS_SHIFT)
++	else if (val > transitions[mid])
++	  lo = mid + 1;
++	else
++	  break;
++      }
++    return transitions[mid];
++  }
++
++  /**
++   * Returns the time zone offset to GMT in milliseconds, ignoring
++   * day light savings.
++   * @return the time zone offset.
++   */
++  public int getRawOffset()
++  {
++    return rawOffset;
++  }
++
++  /**
++   * Sets the standard time zone offset to GMT.
++   * @param rawOffset The time offset from GMT in milliseconds.
++   */
++  public void setRawOffset(int rawOffset)
++  {
++    this.rawOffset = rawOffset;
++    lastRule.setRawOffset(rawOffset);
++  }
++
++  private void computeDSTSavings()
++  {
++    if (lastRule.useDaylightTime())
++      {
++	dstSavings = lastRule.getDSTSavings();
++	useDaylight = true;
++      }
++    else
++      {
++	dstSavings = 0;
++	useDaylight = false;
++	// lastRule might say no DST is in effect simply because
++	// the DST rules are too complex for SimpleTimeZone, say
++	// for Asia/Jerusalem.
++	// Look at the last DST offset if it is newer than current time.
++	long currentSecs = System.currentTimeMillis() / 1000;
++	int i;
++	for (i = transitions.length - 1;
++	     i >= 0 && currentSecs < (transitions[i] >> SECS_SHIFT);
++	     i--)
++	  if ((transitions[i] & IS_DST) != 0)
++	    {
++	      dstSavings = (int) (((transitions[i] << OFFSET_SHIFT)
++				   >> OFFSET_SHIFT) * 1000)
++			   - rawOffset;
++	      useDaylight = true;
++	      break;
++	    }
++      }
++  }
++
++  /**
++   * Gets the daylight savings offset.  This is a positive offset in
++   * milliseconds with respect to standard time.  Typically this
++   * is one hour, but for some time zones this may be half an our.
++   * @return the daylight savings offset in milliseconds.
++   */
++  public int getDSTSavings()
++  {
++    return dstSavings;
++  }
++
++  /**
++   * Returns if this time zone uses daylight savings time.
++   * @return true, if we use daylight savings time, false otherwise.
++   */
++  public boolean useDaylightTime()
++  {
++    return useDaylight;
++  }
++
++  /**
++   * Determines if the given date is in daylight savings time.
++   * @return true, if it is in daylight savings time, false otherwise.
++   */
++  public boolean inDaylightTime(Date date)
++  {
++    long d = date.getTime();
++    d = (d >= 0 ? d / 1000 : (d + 1) / 1000 - 1);
++    long transition = findTransition(d);
++
++    // For times on or after last transition use lastRule.
++    if (transition == Long.MAX_VALUE)
++      return lastRule.inDaylightTime(date);
++
++    return (transition & IS_DST) != 0;
++  }
++
++  /**
++   * Generates the hashCode for the SimpleDateFormat object.  It is
++   * the rawOffset, possibly, if useDaylightSavings is true, xored
++   * with startYear, startMonth, startDayOfWeekInMonth, ..., endTime.
++   */
++  public synchronized int hashCode()
++  {
++    int hash = lastRule.hashCode();
++    // FIXME - hash transitions?
++    return hash;
++  }
++
++  public synchronized boolean equals(Object o)
++  {
++    if (! hasSameRules((TimeZone) o))
++      return false;
++
++    ZoneInfo zone = (ZoneInfo) o;
++    return getID().equals(zone.getID());
++  }
++
++  /**
++   * Test if the other time zone uses the same rule and only
++   * possibly differs in ID.  This implementation for this particular
++   * class will return true if the other object is a ZoneInfo,
++   * the raw offsets and useDaylight are identical and if useDaylight
++   * is true, also the start and end datas are identical.
++   * @return true if this zone uses the same rule.
++   */
++  public boolean hasSameRules(TimeZone o)
++  {
++    if (this == o)
++      return true;
++    if (! (o instanceof ZoneInfo))
++      return false;
++    ZoneInfo zone = (ZoneInfo) o;
++    if (zone.hashCode() != hashCode() || rawOffset != zone.rawOffset)
++      return false;
++    if (! lastRule.equals(zone.lastRule))
++      return false;
++    // FIXME - compare transitions?
++    return true;
++  }
++
++  /**
++   * Returns a string representation of this ZoneInfo object.
++   * @return a string representation of this ZoneInfo object.
++   */
++  public String toString()
++  {
++    return getClass().getName() + "[" + "id=" + getID() + ",offset="
++	   + rawOffset + ",transitions=" + transitions.length
++	   + ",useDaylight=" + useDaylight
++	   + (useDaylight ? (",dstSavings=" + dstSavings) : "")
++	   + ",lastRule=" + lastRule.toString() + "]";
++  }
++
++  /**
++   * Reads zic(8) compiled timezone data file from file
++   * and returns a TimeZone class describing it, either
++   * SimpleTimeZone or ZoneInfo depending on whether
++   * it can be described by SimpleTimeZone rule or not.
++   */
++  public static TimeZone readTZFile(String id, String file)
++  {
++    DataInputStream dis = null;
++    try
++      {
++	FileInputStream fis = new FileInputStream(file);
++	BufferedInputStream bis = new BufferedInputStream(fis);
++	dis = new DataInputStream(bis);
++
++	// Make sure we are reading a tzfile.
++	byte[] tzif = new byte[5];
++	dis.readFully(tzif);
++	int tzif2 = 4;
++	if (tzif[0] == 'T' && tzif[1] == 'Z'
++	    && tzif[2] == 'i' && tzif[3] == 'f')
++	  {
++	    if (tzif[4] >= '2')
++	      tzif2 = 8;
++	    // Reserved bytes
++	    skipFully(dis, 16 - 1);
++	  }
++	else
++	  // Darwin has tzdata files that don't start with the TZif marker
++	  skipFully(dis, 16 - 5);
++
++	int ttisgmtcnt = dis.readInt();
++	int ttisstdcnt = dis.readInt();
++	int leapcnt = dis.readInt();
++	int timecnt = dis.readInt();
++	int typecnt = dis.readInt();
++	int charcnt = dis.readInt();
++	if (tzif2 == 8)
++	  {
++	    skipFully(dis, timecnt * (4 + 1) + typecnt * (4 + 1 + 1) + charcnt
++			   + leapcnt * (4 + 4) + ttisgmtcnt + ttisstdcnt);
++
++	    dis.readFully(tzif);
++	    if (tzif[0] != 'T' || tzif[1] != 'Z' || tzif[2] != 'i'
++		|| tzif[3] != 'f' || tzif[4] < '2')
++	      return null;
++
++	    // Reserved bytes
++	    skipFully(dis, 16 - 1);
++	    ttisgmtcnt = dis.readInt();
++	    ttisstdcnt = dis.readInt();
++	    leapcnt = dis.readInt();
++	    timecnt = dis.readInt();
++	    typecnt = dis.readInt();
++	    charcnt = dis.readInt();
++	  }
++
++	// Sanity checks
++	if (typecnt <= 0 || timecnt < 0 || charcnt < 0
++	    || leapcnt < 0 || ttisgmtcnt < 0 || ttisstdcnt < 0
++	    || ttisgmtcnt > typecnt || ttisstdcnt > typecnt)
++	  return null;
++
++	// Transition times
++	long[] times = new long[timecnt];
++	for (int i = 0; i < timecnt; i++)
++	  if (tzif2 == 8)
++	    times[i] = dis.readLong();
++	  else
++	    times[i] = (long) dis.readInt();
++
++	// Transition types
++	int[] types = new int[timecnt];
++	for (int i = 0; i < timecnt; i++)
++	  {
++	    types[i] = dis.readByte();
++	    if (types[i] < 0)
++	      types[i] += 256;
++	    if (types[i] >= typecnt)
++	      return null;
++	  }
++
++	// Types
++	int[] offsets = new int[typecnt];
++	int[] typeflags = new int[typecnt];
++	for (int i = 0; i < typecnt; i++)
++	  {
++	    offsets[i] = dis.readInt();
++	    if (offsets[i] >= IS_DST / 2 || offsets[i] <= -IS_DST / 2)
++	      return null;
++	    int dst = dis.readByte();
++	    int abbrind = dis.readByte();
++	    if (abbrind < 0)
++	      abbrind += 256;
++	    if (abbrind >= charcnt)
++	      return null;
++	    typeflags[i] = (dst != 0 ? (1 << 8) : 0) + abbrind;
++	  }
++
++	// Abbrev names
++	byte[] names = new byte[charcnt];
++	dis.readFully(names);
++
++	// Leap transitions, for now ignore
++	skipFully(dis, leapcnt * (tzif2 + 4) + ttisstdcnt + ttisgmtcnt);
++
++	// tzIf2 format has optional POSIX TZ env string
++	String tzstr = null;
++	if (tzif2 == 8 && dis.readByte() == '\n')
++	  {
++	    tzstr = dis.readLine();
++	    if (tzstr.length() <= 0)
++	      tzstr = null;
++	  }
++
++	// Get std/dst_offset and dst/non-dst time zone names.
++	int std_ind = -1;
++	int dst_ind = -1;
++	if (timecnt == 0)
++	  std_ind = 0;
++	else
++	  for (int i = timecnt - 1; i >= 0; i--)
++	    {
++	      if (std_ind == -1 && (typeflags[types[i]] & (1 << 8)) == 0)
++		std_ind = types[i];
++	      else if (dst_ind == -1 && (typeflags[types[i]] & (1 << 8)) != 0)
++		dst_ind = types[i];
++	      if (dst_ind != -1 && std_ind != -1)
++		break;
++	    }
++
++	if (std_ind == -1)
++	  return null;
++
++	int j = typeflags[std_ind] & 255;
++	while (j < charcnt && names[j] != 0)
++	  j++;
++	String std_zonename = new String(names, typeflags[std_ind] & 255,
++					 j - (typeflags[std_ind] & 255),
++					 "ASCII");
++
++	String dst_zonename = "";
++	if (dst_ind != -1)
++	  {
++	    j = typeflags[dst_ind] & 255;
++	    while (j < charcnt && names[j] != 0)
++	      j++;
++	    dst_zonename = new String(names, typeflags[dst_ind] & 255,
++				      j - (typeflags[dst_ind] & 255), "ASCII");
++	  }
++
++	// Only use gmt offset when necessary.
++	// Also special case GMT+/- timezones.
++	String std_offset_string = "";
++	String dst_offset_string = "";
++	if (tzstr == null
++	    && (dst_ind != -1
++		|| (offsets[std_ind] != 0
++		    && !std_zonename.startsWith("GMT+")
++		    && !std_zonename.startsWith("GMT-"))))
++	  {
++	    std_offset_string = Integer.toString(-offsets[std_ind] / 3600);
++	    int seconds = -offsets[std_ind] % 3600;
++	    if (seconds != 0)
++	      {
++		if (seconds < 0)
++		  seconds *= -1;
++		if (seconds < 600)
++		  std_offset_string += ":0" + Integer.toString(seconds / 60);
++		else
++		  std_offset_string += ":" + Integer.toString(seconds / 60);
++		seconds = seconds % 60;
++		if (seconds >= 10)
++		  std_offset_string += ":" + Integer.toString(seconds);
++		else if (seconds > 0)
++		  std_offset_string += ":0" + Integer.toString(seconds);
++	      }
++
++	    if (dst_ind != -1 && offsets[dst_ind] != offsets[std_ind] + 3600)
++	      {
++		dst_offset_string = Integer.toString(-offsets[dst_ind] / 3600);
++		seconds = -offsets[dst_ind] % 3600;
++		if (seconds != 0)
++		  {
++		    if (seconds < 0)
++		      seconds *= -1;
++		    if (seconds < 600)
++		      dst_offset_string
++			+= ":0" + Integer.toString(seconds / 60);
++		    else
++		      dst_offset_string
++			+= ":" + Integer.toString(seconds / 60);
++		    seconds = seconds % 60;
++		    if (seconds >= 10)
++		      dst_offset_string += ":" + Integer.toString(seconds);
++		    else if (seconds > 0)
++		      dst_offset_string += ":0" + Integer.toString(seconds);
++		  }
++	      }
++	  }
++
++	/*
++	 * If no tzIf2 POSIX TZ string is available and the timezone
++	 * uses DST, try to guess the last rule by trying to make
++	 * sense from transitions at 5 years in the future and onwards.
++	 * tzdata actually uses only 3 forms of rules:
++	 * fixed date within a month, e.g. change on April, 5th
++	 * 1st weekday on or after Nth: change on Sun>=15 in April
++	 * last weekday in a month: change on lastSun in April
++	 */
++	String[] change_spec = { null, null };
++	if (tzstr == null && dst_ind != -1 && timecnt > 10)
++	  {
++	    long nowPlus5y = System.currentTimeMillis() / 1000
++			     + 5 * 365 * 86400;
++	    int first;
++
++	    for (first = timecnt - 1; first >= 0; first--)
++	      if (times[first] < nowPlus5y
++		  || (types[first] != std_ind && types[first] != dst_ind)
++		  || types[first] != types[timecnt - 2 + ((first ^ timecnt) & 1)])
++		break;
++	    first++;
++
++	    if (timecnt - first >= 10 && types[timecnt - 1] != types[timecnt - 2])
++	      {
++		GregorianCalendar cal
++		  = new GregorianCalendar(new SimpleTimeZone(0, "GMT"));
++
++		int[] values = new int[2 * 11];
++		int i;
++		for (i = timecnt - 1; i >= first; i--)
++		  {
++		    int base = (i % 2) * 11;
++		    int offset = offsets[types[i > first ? i - 1 : i + 1]];
++		    cal.setTime(new Date((times[i] + offset) * 1000));
++		    if (i >= timecnt - 2)
++		      {
++			values[base + 0] = cal.get(Calendar.YEAR);
++			values[base + 1] = cal.get(Calendar.MONTH);
++			values[base + 2] = cal.get(Calendar.DAY_OF_MONTH);
++			values[base + 3]
++			  = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
++			values[base + 4] = cal.get(Calendar.DAY_OF_WEEK);
++			values[base + 5] = cal.get(Calendar.HOUR_OF_DAY);
++			values[base + 6] = cal.get(Calendar.MINUTE);
++			values[base + 7] = cal.get(Calendar.SECOND);
++			values[base + 8] = values[base + 2]; // Range start
++			values[base + 9] = values[base + 2]; // Range end
++			values[base + 10] = 0; // Determined type
++		      }
++		    else
++		      {
++			int year = cal.get(Calendar.YEAR);
++			int month = cal.get(Calendar.MONTH);
++			int day_of_month = cal.get(Calendar.DAY_OF_MONTH);
++			int month_days
++			  = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
++			int day_of_week = cal.get(Calendar.DAY_OF_WEEK);
++			int hour = cal.get(Calendar.HOUR_OF_DAY);
++			int minute = cal.get(Calendar.MINUTE);
++			int second = cal.get(Calendar.SECOND);
++			if (year != values[base + 0] - 1
++			    || month != values[base + 1]
++			    || hour != values[base + 5]
++			    || minute != values[base + 6]
++			    || second != values[base + 7])
++			  break;
++			if (day_of_week == values[base + 4])
++			  {
++			    // Either a Sun>=8 or lastSun rule.
++			    if (day_of_month < values[base + 8])
++			      values[base + 8] = day_of_month;
++			    if (day_of_month > values[base + 9])
++			      values[base + 9] = day_of_month;
++			    if (values[base + 10] < 0)
++			      break;
++			    if (values[base + 10] == 0)
++			      {
++				values[base + 10] = 1;
++				// If day of month > 28, this is
++				// certainly lastSun rule.
++				if (values[base + 2] > 28)
++				  values[base + 2] = 3;
++				// If day of month isn't in the last
++				// week, it can't be lastSun rule.
++				else if (values[base + 2]
++					 <= values[base + 3] - 7)
++				  values[base + 3] = 2;
++			      }
++			    if (values[base + 10] == 1)
++			      {
++				// If day of month is > 28, this is
++				// certainly lastSun rule.
++				if (day_of_month > 28)
++				  values[base + 10] = 3;
++				// If day of month isn't in the last
++				// week, it can't be lastSun rule.
++				else if (day_of_month <= month_days - 7)
++				  values[base + 10] = 2;
++			      }
++			    else if ((values[base + 10] == 2
++				      && day_of_month > 28)
++				     || (values[base + 10] == 3
++					 && day_of_month <= month_days - 7))
++			      break;
++			  }
++			else
++			  {
++			    // Must be fixed day in month rule.
++			    if (day_of_month != values[base + 2]
++				|| values[base + 10] > 0)
++			      break;
++			    values[base + 4] = day_of_week;
++			    values[base + 10] = -1;
++			  }
++			values[base + 0] -= 1;
++		      }
++		  }
++
++		if (i < first)
++		  {
++		    for (i = 0; i < 2; i++)
++		      {
++			int base = 11 * i;
++			if (values[base + 10] == 0)
++			  continue;
++			if (values[base + 10] == -1)
++			  {
++			    int[] dayCount
++			      = { 0, 31, 59, 90, 120, 151,
++				  181, 212, 243, 273, 304, 334 };
++			    int d = dayCount[values[base + 1]
++					     - Calendar.JANUARY];
++			    d += values[base + 2];
++			    change_spec[i] = ",J" + Integer.toString(d);
++			  }
++			else if (values[base + 10] == 2)
++			  {
++			    // If we haven't seen all days of the week,
++			    // we can't be sure what the rule really is.
++			    if (values[base + 8] + 6 != values[base + 9])
++			      continue;
++
++			    int d;
++			    d = values[base + 1] - Calendar.JANUARY + 1;
++			    // E.g. Sun >= 5 is not representable in POSIX
++			    // TZ env string, use ",Am.n.d" extension
++			    // where m is month 1 .. 12, n is the date on
++			    // or after which it happens and d is day
++			    // of the week, 0 .. 6.  So Sun >= 5 in April
++			    // is ",A4.5.0".
++			    if ((values[base + 8] % 7) == 1)
++			      {
++				change_spec[i] = ",M" + Integer.toString(d);
++				d = (values[base + 8] + 6) / 7;
++			      }
++			    else
++			      {
++				change_spec[i] = ",A" + Integer.toString(d);
++				d = values[base + 8];
++			      }
++			    change_spec[i] += "." + Integer.toString(d);
++			    d = values[base + 4] - Calendar.SUNDAY;
++			    change_spec[i] += "." + Integer.toString(d);
++			  }
++			else
++			  {
++			    // If we don't know whether this is lastSun or
++			    // Sun >= 22 rule.  That can be either because
++			    // there was insufficient number of
++			    // transitions, or February, where it is quite
++			    // probable we haven't seen any 29th dates.
++			    // For February, assume lastSun rule, otherwise
++			    // punt.
++			    if (values[base + 10] == 1
++				&& values[base + 1] != Calendar.FEBRUARY)
++			      continue;
++
++			    int d;
++			    d = values[base + 1] - Calendar.JANUARY + 1;
++			    change_spec[i] = ",M" + Integer.toString(d);
++			    d = values[base + 4] - Calendar.SUNDAY;
++			    change_spec[i] += ".5." + Integer.toString(d);
++			  }
++
++			// Don't add time specification if time is
++			// 02:00:00.
++			if (values[base + 5] != 2
++			    || values[base + 6] != 0
++			    || values[base + 7] != 0)
++			  {
++			    int d = values[base + 5];
++			    change_spec[i] += "/" + Integer.toString(d);
++			    if (values[base + 6] != 0 || values[base + 7] != 0)
++			      {
++				d = values[base + 6];
++				if (d < 10)
++				  change_spec[i]
++				    += ":0" + Integer.toString(d);
++				else
++				  change_spec[i] += ":" + Integer.toString(d);
++				d = values[base + 7];
++				if (d >= 10)
++				   change_spec[i]
++				     += ":" + Integer.toString(d);
++				else if (d > 0)
++				  change_spec[i]
++				    += ":0" + Integer.toString(d);
++			      }
++			  }
++		      }
++		    if (types[(timecnt - 1) & -2] == std_ind)
++		      {
++			String tmp = change_spec[0];
++			change_spec[0] = change_spec[1];
++			change_spec[1] = tmp;
++		      }
++		  }
++	      }
++	  }
++
++	if (tzstr == null)
++	  {
++	    tzstr = std_zonename + std_offset_string;
++	    if (change_spec[0] != null && change_spec[1] != null)
++	      tzstr += dst_zonename + dst_offset_string
++		       + change_spec[0] + change_spec[1];
++	  }
++
++	if (timecnt == 0)
++	  return new SimpleTimeZone(offsets[std_ind] * 1000,
++				    id != null ? id : tzstr);
++
++	SimpleTimeZone endRule = createLastRule(tzstr);
++	if (endRule == null)
++	  return null;
++
++	/* Finally adjust the times array into the form the constructor
++	 * expects.  times[0] is special, the offset and DST flag there
++	 * are for all times before that transition.  Use the first non-DST
++	 * type.  For all other transitions, the data file has the type
++	 * (<offset, isdst, zonename>) for the time interval starting
++	 */
++	for (int i = 0; i < typecnt; i++)
++	  if ((typeflags[i] & (1 << 8)) == 0)
++	    {
++	      times[0] = (times[0] << SECS_SHIFT) | (offsets[i] & OFFSET_MASK);
++	      break;
++	    }
++
++	for (int i = 1; i < timecnt; i++)
++	  times[i] = (times[i] << SECS_SHIFT)
++		     | (offsets[types[i - 1]] & OFFSET_MASK)
++		     | ((typeflags[types[i - 1]] & (1 << 8)) != 0 ? IS_DST : 0);
++
++	return new ZoneInfo(offsets[std_ind] * 1000, id != null ? id : tzstr,
++			    times, endRule);
++      }
++    catch (IOException ioe)
++      {
++	// Parse error, not a proper tzfile.
++	return null;
++      }
++    finally
++      {
++	try
++	  {
++	    if (dis != null)
++	      dis.close();
++	  }
++	catch(IOException ioe)
++	  {
++	    // Error while close, nothing we can do.
++	  }
++      }
++  }
++
++  /**
++   * Skips the requested number of bytes in the given InputStream.
++   * Throws EOFException if not enough bytes could be skipped.
++   * Negative numbers of bytes to skip are ignored.
++   */
++  private static void skipFully(InputStream is, long l) throws IOException
++  {
++    while (l > 0)
++      {
++	long k = is.skip(l);
++	if (k <= 0)
++	  throw new EOFException();
++	l -= k;
++      }
++  }
++
++  /**
++   * Create a SimpleTimeZone from a POSIX TZ environment string,
++   * see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
++   * for details.
++   * It supports also an extension, where Am.n.d rule (m 1 .. 12, n 1 .. 25, d
++   * 0 .. 6) describes day of week d on or after nth day of month m.
++   * Say A4.5.0 is Sun>=5 in April.
++   */
++  private static SimpleTimeZone createLastRule(String tzstr)
++  {
++    String stdName = null;
++    int stdOffs;
++    int dstOffs;
++    try
++      {
++	int idLength = tzstr.length();
++
++	int index = 0;
++	int prevIndex;
++	char c;
++
++	// get std
++	do
++	  c = tzstr.charAt(index);
++	while (c != '+' && c != '-' && c != ',' && c != ':'
++	       && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
++
++	if (index >= idLength)
++	  return new SimpleTimeZone(0, tzstr);
++
++	stdName = tzstr.substring(0, index);
++	prevIndex = index;
++
++	// get the std offset
++	do
++	  c = tzstr.charAt(index++);
++	while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
++	       && index < idLength);
++	if (index < idLength)
++	  index--;
++
++	{ // convert the dst string to a millis number
++	    String offset = tzstr.substring(prevIndex, index);
++	    prevIndex = index;
++
++	    if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
++	      stdOffs = parseTime(offset.substring(1));
++	    else
++	      stdOffs = parseTime(offset);
++
++	    if (offset.charAt(0) == '-')
++	      stdOffs = -stdOffs;
++
++	    // TZ timezone offsets are positive when WEST of the meridian.
++	    stdOffs = -stdOffs;
++	}
++
++	// Done yet? (Format: std offset)
++	if (index >= idLength)
++	  return new SimpleTimeZone(stdOffs, stdName);
++
++	// get dst
++	do
++	  c = tzstr.charAt(index);
++	while (c != '+' && c != '-' && c != ',' && c != ':'
++	       && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
++
++	// Done yet? (Format: std offset dst)
++	if (index >= idLength)
++	  return new SimpleTimeZone(stdOffs, stdName);
++
++	// get the dst offset
++	prevIndex = index;
++	do
++	  c = tzstr.charAt(index++);
++	while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
++	       && index < idLength);
++	if (index < idLength)
++	  index--;
++
++	if (index == prevIndex && (c == ',' || c == ';'))
++	  {
++	    // Missing dst offset defaults to one hour ahead of standard
++	    // time.
++	    dstOffs = stdOffs + 60 * 60 * 1000;
++	  }
++	else
++	  { // convert the dst string to a millis number
++	    String offset = tzstr.substring(prevIndex, index);
++	    prevIndex = index;
++
++	    if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
++	      dstOffs = parseTime(offset.substring(1));
++	    else
++	      dstOffs = parseTime(offset);
++
++	    if (offset.charAt(0) == '-')
++	      dstOffs = -dstOffs;
++
++	    // TZ timezone offsets are positive when WEST of the meridian.
++	    dstOffs = -dstOffs;
++	  }
++
++	// Done yet? (Format: std offset dst offset)
++	if (index >= idLength)
++	  return new SimpleTimeZone(stdOffs, stdName);
++
++	// get the DST rule
++	if (tzstr.charAt(index) == ','
++	    || tzstr.charAt(index) == ';')
++	  {
++	    index++;
++	    int offs = index;
++	    while (tzstr.charAt(index) != ','
++		   && tzstr.charAt(index) != ';')
++	      index++;
++	    String startTime = tzstr.substring(offs, index);
++	    index++;
++	    String endTime = tzstr.substring(index);
++
++	    index = startTime.indexOf('/');
++	    int startMillis;
++	    int endMillis;
++	    String startDate;
++	    String endDate;
++	    if (index != -1)
++	      {
++		startDate = startTime.substring(0, index);
++		startMillis = parseTime(startTime.substring(index + 1));
++	      }
++	    else
++	      {
++		startDate = startTime;
++		// if time isn't given, default to 2:00:00 AM.
++		startMillis = 2 * 60 * 60 * 1000;
++	      }
++	    index = endTime.indexOf('/');
++	    if (index != -1)
++	      {
++		endDate = endTime.substring(0, index);
++		endMillis = parseTime(endTime.substring(index + 1));
++	      }
++	    else
++	      {
++		endDate = endTime;
++		// if time isn't given, default to 2:00:00 AM.
++		endMillis = 2 * 60 * 60 * 1000;
++	      }
++
++	    int[] start = getDateParams(startDate);
++	    int[] end = getDateParams(endDate);
++	    return new SimpleTimeZone(stdOffs, tzstr, start[0], start[1],
++				      start[2], startMillis, end[0], end[1],
++				      end[2], endMillis, (dstOffs - stdOffs));
++	  }
++      }
++
++    catch (IndexOutOfBoundsException _)
++      {
++      }
++    catch (NumberFormatException _)
++      {
++      }
++
++    return null;
++  }
++
++  /**
++   * Parses and returns the params for a POSIX TZ date field,
++   * in the format int[]{ month, day, dayOfWeek }, following the
++   * SimpleTimeZone constructor rules.
++   */
++  private static int[] getDateParams(String date)
++  {
++    int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
++    int month;
++    int type = 0;
++
++    if (date.charAt(0) == 'M' || date.charAt(0) == 'm')
++      type = 1;
++    else if (date.charAt(0) == 'A' || date.charAt(0) == 'a')
++      type = 2;
++
++    if (type > 0)
++      {
++	int day;
++
++	// Month, week of month, day of week
++	// "Mm.w.d".  d is between 0 (Sunday) and 6.  Week w is
++	// between 1 and 5; Week 1 is the first week in which day d
++	// occurs and Week 5 specifies the last d day in the month.
++	// Month m is between 1 and 12.
++
++	// Month, day of month, day of week
++	// ZoneInfo extension, not in POSIX
++	// "Am.n.d".  d is between 0 (Sunday) and 6.  Day of month n is
++	// between 1 and 25.  Month m is between 1 and 12.
++
++	month = Integer.parseInt(date.substring(1, date.indexOf('.')));
++	int week = Integer.parseInt(date.substring(date.indexOf('.') + 1,
++						   date.lastIndexOf('.')));
++	int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.')
++							+ 1));
++	dayOfWeek++; // Java day of week is one-based, Sunday is first day.
++
++	if (type == 2)
++	  {
++	    day = week;
++	    dayOfWeek = -dayOfWeek;
++	  }
++ 	else if (week == 5)
++ 	  day = -1; // last day of month is -1 in java, 5 in TZ
++ 	else
++	  {
++	    // First day of week starting on or after.  For example,
++	    // to specify the second Sunday of April, set month to
++	    // APRIL, day-of-month to 8, and day-of-week to -SUNDAY.
++	    day = (week - 1) * 7 + 1;
++	    dayOfWeek = -dayOfWeek;
++	  }
++
++	month--; // Java month is zero-based.
++	return new int[] { month, day, dayOfWeek };
++      }
++
++    // julian day, either zero-based 0<=n<=365 (incl feb 29)
++    // or one-based 1<=n<=365 (no feb 29)
++    int julianDay; // Julian day
++
++    if (date.charAt(0) != 'J' || date.charAt(0) != 'j')
++      {
++	julianDay = Integer.parseInt(date.substring(1));
++	julianDay++; // make 1-based
++	// Adjust day count to include feb 29.
++	dayCount = new int[]
++		   {
++		     0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
++		   };
++      }
++    else
++      // 1-based julian day
++      julianDay = Integer.parseInt(date);
++
++    int i = 11;
++    while (i > 0)
++      if (dayCount[i] < julianDay)
++	break;
++      else
++	i--;
++    julianDay -= dayCount[i];
++    month = i;
++    return new int[] { month, julianDay, 0 };
++  }
++
++  /**
++   * Parses a time field hh[:mm[:ss]], returning the result
++   * in milliseconds. No leading sign.
++   */
++  private static int parseTime(String time)
++  {
++    int millis = 0;
++    int i = 0;
++
++    while (i < time.length())
++      if (time.charAt(i) == ':')
++	break;
++      else
++	i++;
++    millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i));
++    if (i >= time.length())
++      return millis;
++
++    int iprev = ++i;
++    while (i < time.length())
++      if (time.charAt(i) == ':')
++	break;
++      else
++	i++;
++    millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i));
++    if (i >= time.length())
++      return millis;
++
++    millis += 1000 * Integer.parseInt(time.substring(++i));
++    return millis;
++  }
++}
diff --git a/SOURCES/gcc32-libgcc_eh-hidden.patch b/SOURCES/gcc32-libgcc_eh-hidden.patch
new file mode 100644
index 0000000..eafd7da
--- /dev/null
+++ b/SOURCES/gcc32-libgcc_eh-hidden.patch
@@ -0,0 +1,29 @@
+--- gcc/mklibgcc.in.jj	2006-05-22 14:03:31.000000000 -0400
++++ gcc/mklibgcc.in	2006-05-22 14:03:31.000000000 -0400
+@@ -310,10 +310,24 @@ for ml in $MULTILIBS; do
+ 
+   if [ "$SHLIB_LINK" ]; then
+ 
++    if [ "@libgcc_visibility@" = yes ]; then
++      libgcc_eh_objS=
++      echo ""
++      for o in $libgcc_eh_objs; do
++	# .oS objects will have all non-local symbol definitions .hidden
++	oS=`echo ${o} | sed s~${objext}'$~.oS~g'`
++	echo "${oS}: stmp-dirs libgcc/${dir}/stacknote.s ${o}"
++	echo '	@( $(NM_FOR_TARGET) '${SHLIB_NM_FLAGS} ${o}' | $(AWK) '\''NF == 3 { print "\t.hidden", $$3 }'\''; cat libgcc/${dir}/stacknote.s ) | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -r -nostdinc -nostdlib -o $@ '${o}' -xassembler -'
++	libgcc_eh_objS="${libgcc_eh_objS} ${oS}"
++      done
++    else
++      libgcc_eh_objS="$libgcc_eh_objs"
++    fi
++
+     echo ""
+-    echo "${dir}/libgcc_eh.a: $libgcc_eh_objs"
++    echo "${dir}/libgcc_eh.a: $libgcc_eh_objS"
+     echo "	-rm -rf ${dir}/libgcc_eh.a"
+-    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objs
++    echo '	$(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objS
+     echo '	if $(RANLIB_TEST_FOR_TARGET) ; then' \\
+     echo '	  $(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a ';' \\
+     echo '	else true; fi;'
diff --git a/SOURCES/gcc32-libjava-jar-timestamps.patch b/SOURCES/gcc32-libjava-jar-timestamps.patch
new file mode 100644
index 0000000..5a00838
--- /dev/null
+++ b/SOURCES/gcc32-libjava-jar-timestamps.patch
@@ -0,0 +1,78 @@
+2004-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+	* Makefile.am (libgcj-@gcc_version@.jar): Set timestamp of all files
+	and directories in the jar file to the youngest of gcc/ChangeLog,
+	gcc/java/ChangeLog and libjava/ChangeLog.  Sort the file/directory
+	list before passing it to fastjar.
+	* Makefile.in: Rebuilt.
+
+--- libjava/Makefile.am	2003-02-03 23:58:32.000000000 +0100
++++ libjava/Makefile.am	2004-08-12 13:21:35.928177346 +0200
+@@ -170,9 +170,29 @@ all_java_class_files = $(all_java_source
+ libgcj-@gcc_version@.jar: $(all_java_class_files)
+ 	-@rm -f libgcj-@gcc_version@.jar
+ ## Note that we explicitly want to include directory information.
+-	find java gnu javax org -type d -o -type f -name '*.class' | \
+-	  sed -e '/\/\./d' -e '/\/xlib/d' | \
+-	  $(ZIP) cfM0E@ $@
++	# The following is an attempt to have libgcj-*.jar files
++	# from the same GCC version identical accross the architectures.
++	JARDIR=`mktemp -d ../$@.XXXXXX` || exit 1; \
++	for d in `find java gnu javax org -type d \
++		  | sed -e '/\/\./d' -e '/\/xlib/d'`; do \
++	  mkdir -p $$JARDIR/$$d; \
++	done; \
++	touch -r $(srcdir)/../gcc/ChangeLog $$JARDIR.stamp; \
++	[ $(srcdir)/../gcc/java/ChangeLog -nt $$JARDIR.stamp ] \
++	  && touch -r $(srcdir)/../gcc/java/ChangeLog $$JARDIR.stamp; \
++	[ $(srcdir)/ChangeLog -nt $$JARDIR.stamp ] \
++	  && touch -r $(srcdir)/ChangeLog $$JARDIR.stamp; \
++	for f in `find java gnu javax org -type f -name '*.class' \
++		  | sed -e '/\/\./d' -e '/\/xlib/d'`; do \
++	  cp $$f $$JARDIR/$$f; \
++	  touch -r $$JARDIR.stamp $$JARDIR/$$f; \
++	done; \
++	touch -r $$JARDIR.stamp `find $$JARDIR -type d`; \
++	cd $$JARDIR; \
++	find java gnu javax org -type d -o -type f | \
++	  LC_ALL=C sort | $(ZIP) cfM0E@ ../libjava/$@ || exit 1; \
++	cd -; \
++	rm -rf $$JARDIR $$JARDIR.stamp
+ 
+ MOSTLYCLEANFILES = $(javao_files) $(nat_files) $(nat_headers) $(c_files) $(x_javao_files) $(x_nat_files) $(x_nat_headers)
+ CLEANFILES = libgcj-@gcc_version@.jar
+--- libjava/Makefile.in	2003-02-03 23:58:32.000000000 +0100
++++ libjava/Makefile.in	2004-08-12 13:21:22.928440630 +0200
+@@ -3280,9 +3280,29 @@ install-exec-hook:
+ 
+ libgcj-@gcc_version@.jar: $(all_java_class_files)
+ 	-@rm -f libgcj-@gcc_version@.jar
+-	find java gnu javax org -type d -o -type f -name '*.class' | \
+-	  sed -e '/\/\./d' -e '/\/xlib/d' | \
+-	  $(ZIP) cfM0E@ $@
++	# The following is an attempt to have libgcj-*.jar files
++	# from the same GCC version identical accross the architectures.
++	JARDIR=`mktemp -d ../$@.XXXXXX` || exit 1; \
++	for d in `find java gnu javax org -type d \
++		  | sed -e '/\/\./d' -e '/\/xlib/d'`; do \
++	  mkdir -p $$JARDIR/$$d; \
++	done; \
++	touch -r $(srcdir)/../gcc/ChangeLog $$JARDIR.stamp; \
++	[ $(srcdir)/../gcc/java/ChangeLog -nt $$JARDIR.stamp ] \
++	  && touch -r $(srcdir)/../gcc/java/ChangeLog $$JARDIR.stamp; \
++	[ $(srcdir)/ChangeLog -nt $$JARDIR.stamp ] \
++	  && touch -r $(srcdir)/ChangeLog $$JARDIR.stamp; \
++	for f in `find java gnu javax org -type f -name '*.class' \
++		  | sed -e '/\/\./d' -e '/\/xlib/d'`; do \
++	  cp $$f $$JARDIR/$$f; \
++	  touch -r $$JARDIR.stamp $$JARDIR/$$f; \
++	done; \
++	touch -r $$JARDIR.stamp `find $$JARDIR -type d`; \
++	cd $$JARDIR; \
++	find java gnu javax org -type d -o -type f | \
++	  LC_ALL=C sort | $(ZIP) cfM0E@ ../libjava/$@ || exit 1; \
++	cd -; \
++	rm -rf $$JARDIR $$JARDIR.stamp
+ 
+ clean-local:
+ 	find . -name '*.class' -print | xargs rm -f
diff --git a/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch b/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch
new file mode 100644
index 0000000..32cd729
--- /dev/null
+++ b/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch
@@ -0,0 +1,60 @@
+2004-10-28  Paolo Carlini  <pcarlini@suse.de>
+
+	PR libstdc++/16612
+	* include/bits/basic_string.h (basic_string()): When
+	_GLIBCXX_FULLY_DYNAMIC_STRING is defined, don't deal with _S_empty_rep.
+	* include/bits/basic_string.tcc (_S_construct): Likewise.
+
+--- libstdc++-v3/include/bits/basic_string.tcc.jj	2002-11-09 18:42:55.000000000 +0100
++++ libstdc++-v3/include/bits/basic_string.tcc	2004-11-12 14:17:19.946131774 +0100
+@@ -77,8 +77,10 @@ namespace std
+       _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
+ 		   input_iterator_tag)
+       {
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refcopy();
++#endif
+ 	// Avoid reallocation for common case.
+ 	_CharT __buf[100];
+ 	size_type __i = 0;
+@@ -139,11 +141,13 @@ namespace std
+       {
+ 	size_type __dnew = static_cast<size_type>(distance(__beg, __end));
+ 
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ 	if (__beg == __end && __a == _Alloc())
+ 	  return _S_empty_rep()._M_refcopy();
++#endif
+ 
+ 	// NB: Not required, but considered best practice.
+-	if (__builtin_expect(__beg == _InIter(), 0))
++	if (__builtin_expect(__beg == _InIter() && __beg != __end, 0))
+ 	  __throw_logic_error("attempt to create string with null pointer");
+ 	
+ 	// Check for out_of_range and length_error exceptions.
+@@ -166,8 +170,10 @@ namespace std
+     basic_string<_CharT, _Traits, _Alloc>::
+     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
+     {
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+       if (__n == 0 && __a == _Alloc())
+ 	return _S_empty_rep()._M_refcopy();
++#endif
+ 
+       // Check for out_of_range and length_error exceptions.
+       _Rep* __r = _Rep::_S_create(__n, __a);
+--- libstdc++-v3/include/bits/basic_string.h.jj	2002-05-22 15:39:29.000000000 +0200
++++ libstdc++-v3/include/bits/basic_string.h	2004-11-12 14:14:42.831975711 +0100
+@@ -923,7 +923,11 @@ namespace std
+   template<typename _CharT, typename _Traits, typename _Alloc>
+     inline basic_string<_CharT, _Traits, _Alloc>::
+     basic_string()
++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+     : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
++#else
++    : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
++#endif
+ 
+   // operator+
+   template<typename _CharT, typename _Traits, typename _Alloc>
diff --git a/SOURCES/gcc32-libstdc++-limits.patch b/SOURCES/gcc32-libstdc++-limits.patch
new file mode 100644
index 0000000..62fc602
--- /dev/null
+++ b/SOURCES/gcc32-libstdc++-limits.patch
@@ -0,0 +1,163 @@
+2004-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+	* config/os/gnu-linux/bits/os_defines.h: Define
+	__glibcpp_{float,double,long_double}* macros.
+	* config/cpu/x86-64/bits/cpu_limits.h (__glibcpp_long_bits): Only
+	define to 64 if __x86_64__.
+	* include/std/std_limits.h (__glibcpp_f*_round_error): Only define
+	if not yet defined.
+
+--- libstdc++-v3/config/os/gnu-linux/bits/os_defines.h.jj	2002-06-03 17:33:17.000000000 +0200
++++ libstdc++-v3/config/os/gnu-linux/bits/os_defines.h	2004-10-06 20:07:16.601101686 +0200
+@@ -73,4 +73,87 @@ typedef __loff_t __off64_t;
+ #define __glibcpp_long_double_bits 64
+ #endif
+ 
++/* RHEL3 hack.  */
++#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__IBMCPP__) \
++    && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__) \
++        || defined(__s390__) || defined(__s390x__) || defined(__powerpc__) \
++        || defined(__powerpc64__))
++#define __glibcpp_float_has_quiet_NaN true
++#define __glibcpp_float_has_signaling_NaN true
++#define __glibcpp_float_has_denorm denorm_present
++#define __glibcpp_float_has_infinity true
++#define __glibcpp_float_round_style round_to_nearest
++#define __glibcpp_float_is_iec559 true
++#define __glibcpp_double_has_quiet_NaN true
++#define __glibcpp_double_has_signaling_NaN true
++#define __glibcpp_double_has_denorm denorm_present
++#define __glibcpp_double_has_infinity true
++#define __glibcpp_double_round_style round_to_nearest
++#define __glibcpp_double_is_iec559 true
++#define __glibcpp_long_double_has_quiet_NaN true
++#define __glibcpp_long_double_has_signaling_NaN true
++#define __glibcpp_long_double_has_denorm denorm_present
++#define __glibcpp_long_double_has_infinity true
++#define __glibcpp_long_double_round_style round_to_nearest
++#define __glibcpp_long_double_is_iec559 true
++
++#define __glibcpp_f32_round_error 0.5F
++#define __glibcpp_f64_round_error 0.5
++#define __glibcpp_f80_round_error 0.5L
++#define __glibcpp_f96_round_error 0.5L
++#define __glibcpp_f128_round_error 0.5L
++
++#define __glibcpp_float_infinity 1.0e+40F
++#define __glibcpp_double_infinity 1.0e+320
++#define __glibcpp_long_double_infinity 1.0e+5000L
++
++#define __glibcpp_float_denorm_min 1.40129846e-45F
++#define __glibcpp_double_denorm_min 4.9406564584124654e-324
++
++#define __glibcpp_float_quiet_NaN \
++  (__extension__ ((union { unsigned int __l; float __d; })		\
++		  { __l: 0x7fc00000 }).__d)
++#define __glibcpp_double_quiet_NaN \
++  (__extension__ ((union { unsigned long long __l; double __d; })	\
++		  { __l: 0x7ff8000000000000ULL }).__d)
++
++#define __glibcpp_float_signaling_NaN \
++  (__extension__ ({ union { unsigned int __l; float __d; } __u;		\
++		    __u.__l = 0x7fa00000;				\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++#define __glibcpp_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l; double __d; } __u;	\
++		    __u.__l = 0x7ff4000000000000ULL;			\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#if __glibcpp_long_double_bits == 80
++
++#define __glibcpp_long_double_denorm_min 3.64519953188247460253e-4951L
++#define __glibcpp_long_double_quiet_NaN \
++  (__extension__ ({ union { unsigned long long __l[2];			\
++			    long double __d; } __u;			\
++		    __u.__l[0] = 0xcULL << 60; __u.__l[1] = 0x7fff;	\
++		    __u.__d; }))
++#define __glibcpp_long_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l[2];			\
++			    long double __d; } __u;			\
++		    __u.__l[0] = 0xaULL << 60; __u.__l[1] = 0x7fff;	\
++		    __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#else
++
++#define __glibcpp_long_double_denorm_min 4.9406564584124654e-324L
++#define __glibcpp_long_double_quiet_NaN \
++  (__extension__ ((union { unsigned long long __l; long double __d; })	\
++		  { __l: 0x7ff8000000000000ULL }).__d)
++#define __glibcpp_long_double_signaling_NaN \
++  (__extension__ ({ union { unsigned long long __l;			\
++			    long double __d; } __u;			\
++		     __u.__l = 0x7ff4000000000000ULL;			\
++		     __asm ("" : : "r" (&__u) : "memory"); __u.__d; }))
++
++#endif
++
++#endif
++
+ #endif
+--- libstdc++-v3/config/cpu/x86-64/bits/cpu_limits.h.jj	2002-01-12 23:14:42.000000000 +0100
++++ libstdc++-v3/config/cpu/x86-64/bits/cpu_limits.h	2004-10-06 17:13:39.369189090 +0200
+@@ -28,7 +28,9 @@
+ #ifndef _GLIBCPP_CPU_LIMITS
+ #define _GLIBCPP_CPU_LIMITS 1
+ 
++#ifdef __x86_64__
+ #define __glibcpp_long_bits 64
++#endif
+ 
+ #define __glibcpp_long_double_bits 80
+ 
+--- libstdc++-v3/include/std/std_limits.h.jj	2002-10-16 16:12:23.000000000 +0200
++++ libstdc++-v3/include/std/std_limits.h	2004-10-06 19:59:26.602318867 +0200
+@@ -180,7 +180,9 @@
+ #define __glibcpp_f32_digits10 6
+ #define __glibcpp_f32_radix 2
+ #define __glibcpp_f32_epsilon 1.19209290e-07F
++#ifndef __glibcpp_f32_round_error
+ #define __glibcpp_f32_round_error 1.0F
++#endif
+ #define __glibcpp_f32_min_exponent -125
+ #define __glibcpp_f32_min_exponent10 -37
+ #define __glibcpp_f32_max_exponent 128
+@@ -191,7 +193,9 @@
+ #define __glibcpp_f64_digits10 15
+ #define __glibcpp_f64_radix 2
+ #define __glibcpp_f64_epsilon 2.2204460492503131e-16
++#ifndef __glibcpp_f64_round_error
+ #define __glibcpp_f64_round_error 1.0
++#endif
+ #define __glibcpp_f64_min_exponent -1021
+ #define __glibcpp_f64_min_exponent10 -307
+ #define __glibcpp_f64_max_exponent 1024
+@@ -202,7 +206,9 @@
+ #define __glibcpp_f80_digits10 18
+ #define __glibcpp_f80_radix 2
+ #define __glibcpp_f80_epsilon 1.08420217248550443401e-19L
++#ifndef __glibcpp_f80_round_error
+ #define __glibcpp_f80_round_error 1.0L
++#endif
+ #define __glibcpp_f80_min_exponent -16381
+ #define __glibcpp_f80_min_exponent10 -4931
+ #define __glibcpp_f80_max_exponent 16384
+@@ -213,7 +219,9 @@
+ #define __glibcpp_f96_digits10 18
+ #define __glibcpp_f96_radix 2
+ #define __glibcpp_f96_epsilon 1.08420217248550443401e-19L
++#ifndef __glibcpp_f96_round_error
+ #define __glibcpp_f96_round_error 1.0L
++#endif
+ #define __glibcpp_f96_min_exponent -16382
+ #define __glibcpp_f96_min_exponent10 -4931
+ #define __glibcpp_f96_max_exponent 16384
+@@ -224,7 +232,9 @@
+ #define __glibcpp_f128_digits10 33
+ #define __glibcpp_f128_radix 2
+ #define __glibcpp_f128_epsilon 1.925929944387235853055977942584927319E-34L
++#ifndef __glibcpp_f128_round_error
+ #define __glibcpp_f128_round_error 1.0L
++#endif
+ #define __glibcpp_f128_min_exponent -16381
+ #define __glibcpp_f128_min_exponent10 -4931
+ #define __glibcpp_f128_max_exponent 16384
diff --git a/SOURCES/gcc32-libstdc++-pr9659.patch b/SOURCES/gcc32-libstdc++-pr9659.patch
new file mode 100644
index 0000000..b8b452f
--- /dev/null
+++ b/SOURCES/gcc32-libstdc++-pr9659.patch
@@ -0,0 +1,24 @@
+2003-02-11  Scott Snyder  <snyder@fnal.gov>
+
+	PR libstdc++/9659
+	* include/bits/fstream.tcc (seekoff): Avoid operator+
+	for pos_type.
+
+--- libstdc++-v3/include/bits/fstream.tcc	4 Feb 2003 22:42:32 -0000	1.47
++++ libstdc++-v3/include/bits/fstream.tcc	13 Feb 2003 21:39:02 -0000	1.48
+@@ -450,9 +450,12 @@ namespace std
+  	      pos_type __tmp =
+  		_M_file.seekoff(__off, ios_base::cur, __mode);
+  	      if (__tmp >= 0)
+- 		// Seek successful.
+- 		__ret = __tmp +
+- 		  std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
++		{
++		  // Seek successful.
++		  __ret = __tmp;
++		  __ret +=
++		    std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
++		}
+ 	    }
+ 	}
+       _M_last_overflowed = false;	
diff --git a/SOURCES/gcc32-libstdc++-symver.patch b/SOURCES/gcc32-libstdc++-symver.patch
new file mode 100644
index 0000000..60ecc32
--- /dev/null
+++ b/SOURCES/gcc32-libstdc++-symver.patch
@@ -0,0 +1,98 @@
+2004-07-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* acinclude.m4 (glibcxx_shared_libgcc): Correct
+	glibcxx_shared_libgcc test for multilibs.
+	* aclocal.m4: Rebuilt.
+	* configure: Rebuilt.
+
+--- libstdc++-v3/acinclude.m4.jj	2003-01-28 10:51:32.000000000 +0100
++++ libstdc++-v3/acinclude.m4	2004-08-12 14:54:01.657789664 +0200
+@@ -2208,6 +2208,23 @@ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=' -lgcc_s'
+ AC_TRY_LINK( , [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no)
+ CFLAGS="$ac_save_CFLAGS"
++if test $glibcpp_shared_libgcc = no; then
++  cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++changequote(,)dnl
++  glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			   -shared -shared-libgcc -o conftest.so \
++			   conftest.c -v 2>&1 >/dev/null \
++			   | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++changequote([,])dnl
++  rm -f conftest.c conftest.so
++  if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++    CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++    AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes)
++    CFLAGS="$ac_save_CFLAGS"
++  fi
++fi
+ AC_MSG_RESULT($glibcpp_shared_libgcc)
+ 
+ # For GNU ld, we need at least this version.  It's 2.12 in the same format
+--- libstdc++-v3/aclocal.m4.jj	2003-02-14 09:30:26.000000000 +0100
++++ libstdc++-v3/aclocal.m4	2004-08-12 14:57:06.460552615 +0200
+@@ -2220,6 +2220,23 @@ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=' -lgcc_s'
+ AC_TRY_LINK( , [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no)
+ CFLAGS="$ac_save_CFLAGS"
++if test $glibcpp_shared_libgcc = no; then
++  cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++changequote(,)dnl
++  glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			   -shared -shared-libgcc -o conftest.so \
++			   conftest.c -v 2>&1 >/dev/null \
++			   | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++changequote([,])dnl
++  rm -f conftest.c conftest.so
++  if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++    CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++    AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes)
++    CFLAGS="$ac_save_CFLAGS"
++  fi
++fi
+ AC_MSG_RESULT($glibcpp_shared_libgcc)
+ 
+ # For GNU ld, we need at least this version.  It's 2.12 in the same format
+--- libstdc++-v3/configure.jj	2003-02-14 09:30:58.000000000 +0100
++++ libstdc++-v3/configure	2004-08-12 14:57:49.978961900 +0200
+@@ -22090,6 +22090,36 @@ else
+ fi
+ rm -f conftest*
+ CFLAGS="$ac_save_CFLAGS"
++if test $glibcpp_shared_libgcc = no; then
++  cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++  glibcpp_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
++			   -shared -shared-libgcc -o conftest.so \
++			   conftest.c -v 2>&1 >/dev/null \
++			   | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
++  rm -f conftest.c conftest.so
++  if test x${glibcpp_libgcc_s_suffix+set} = xset; then
++    CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix"
++    cat > conftest.$ac_ext <<EOF
++#line 22106 "configure"
++#include "confdefs.h"
++
++int main() {
++return 0;
++; return 0; }
++EOF
++if { (eval echo configure:22113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++  rm -rf conftest*
++  glibcpp_shared_libgcc=yes
++else
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++fi
++rm -f conftest*
++    CFLAGS="$ac_save_CFLAGS"
++  fi
++fi
+ echo "$ac_t""$glibcpp_shared_libgcc" 1>&6
+ 
+ # For GNU ld, we need at least this version.  It's 2.12 in the same format
diff --git a/SOURCES/gcc32-libstdc++-symver2.patch b/SOURCES/gcc32-libstdc++-symver2.patch
new file mode 100644
index 0000000..ba0430b
--- /dev/null
+++ b/SOURCES/gcc32-libstdc++-symver2.patch
@@ -0,0 +1,36 @@
+2005-05-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* src/globals.cc (_GLIBCPP_ASM_SYMVER): For non-PIC, redefine to a
+	hidden alias.
+	* src/locale.cc (_GLIBCPP_ASM_SYMVER): Likewise.
+
+--- libstdc++-v3/src/globals.cc.jj	2002-10-23 01:24:11.000000000 +0200
++++ libstdc++-v3/src/globals.cc	2005-05-13 12:30:26.000000000 +0200
+@@ -33,6 +33,12 @@
+ #include <locale>
+ #include <ext/stdio_filebuf.h>
+ 
++#ifndef PIC
++# undef _GLIBCPP_ASM_SYMVER
++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \
++  asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur);
++#endif
++
+ // On AIX, and perhaps other systems, library initialization order is
+ // not guaranteed.  For example, the static initializers for the main
+ // program might run before the static initializers for this library.
+--- libstdc++-v3/src/locale.cc.jj	2003-01-17 18:44:45.000000000 +0100
++++ libstdc++-v3/src/locale.cc	2005-05-13 13:02:36.000000000 +0200
+@@ -34,6 +34,12 @@
+ #include <locale>
+ #include <bits/atomicity.h>
+ 
++#ifndef PIC
++# undef _GLIBCPP_ASM_SYMVER
++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \
++  asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur);
++#endif
++
+ namespace __gnu_cxx
+ {
+   // Defined in globals.cc.
diff --git a/SOURCES/gcc32-multi32-hack.patch b/SOURCES/gcc32-multi32-hack.patch
new file mode 100644
index 0000000..488839c
--- /dev/null
+++ b/SOURCES/gcc32-multi32-hack.patch
@@ -0,0 +1,76 @@
+This is an optimization hack which should only be present
+in a sparc 32bit driver of the compiler compiled with
+host/target/build sparc64-redhat-linux --with-cpu=v7.
+As long long HOST_WIDE_INT slows things down, we can have in
+addition to the sparc64-*/3.2/{cc1,cc1plus}
+sparc-*/3.2/{cc1,cc1plus} binaries which are suitable for compiling
+-m32 code only, but use long HOST_WIDE_INT.
+
+--- gcc/gcc.c.jj	Thu Aug  1 17:41:31 2002
++++ gcc/gcc.c	Fri Sep  6 16:48:10 2002
+@@ -3184,6 +3184,8 @@ process_command (argc, argv)
+   int have_c = 0;
+   int have_o = 0;
+   int lang_n_infiles = 0;
++  int m64 = 0;
++  int used_B = 0;
+ #ifdef MODIFY_TARGET_NAME
+   int is_modify_target_name;
+   int j;
+@@ -3565,6 +3567,7 @@ warranty; not even for MERCHANTABILITY o
+ 		spec_machine = p + 1;
+ 
+ 	      warn_std_ptr = &warn_std;
++	      used_B = 1;
+ 	      break;
+ 
+ 	    case 'B':
+@@ -3627,6 +3630,7 @@ warranty; not even for MERCHANTABILITY o
+ 			    PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
+ 		add_prefix (&include_prefixes, concat (value, "include", NULL),
+ 			    NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
++		used_B = 1;
+ 		n_switches++;
+ 	      }
+ 	      break;
+@@ -3731,6 +3735,13 @@ warranty; not even for MERCHANTABILITY o
+ #endif
+ 	      goto normal_switch;
+ 
++	    /* HACK START */
++	    case 'm':
++	      if (p[1] == '6' && p[2] == '4')
++		m64 = 1;
++	    /* FALLTHROUGH */
++	    /* HACK END */
++
+ 	    default:
+ 	    normal_switch:
+ 
+@@ -3798,6 +3809,26 @@ warranty; not even for MERCHANTABILITY o
+   /* Use 2 as fourth arg meaning try just the machine as a suffix,
+      as well as trying the machine and the version.  */
+ #ifndef OS2
++  /* HACK START */
++  if (!m64 && !used_B && !strncmp (spec_machine, "sparc64-", 8))
++    {
++      const char *sparc32_exec_prefix =
++	concat (standard_exec_prefix, "sparc-", spec_machine + 8,
++		dir_separator_str, spec_version, dir_separator_str, NULL);
++      add_prefix (&exec_prefixes, sparc32_exec_prefix, "GCC",
++		  PREFIX_PRIORITY_LAST, 0, warn_std_ptr, 0);
++    }
++  /* HACK END */
++  /* HACK START */
++  if (!m64 && !used_B && !strncmp (spec_machine, "ppc64-", 6))
++    {
++      const char *ppc32_exec_prefix =
++	concat (standard_exec_prefix, "ppc-", spec_machine + 6,
++		dir_separator_str, spec_version, dir_separator_str, NULL);
++      add_prefix (&exec_prefixes, ppc32_exec_prefix, "GCC",
++		  PREFIX_PRIORITY_LAST, 0, warn_std_ptr, 0);
++    }
++  /* HACK END */
+   add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
+ 	      PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+   add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
diff --git a/SOURCES/gcc32-null-pointer-check-noncc0.patch b/SOURCES/gcc32-null-pointer-check-noncc0.patch
new file mode 100644
index 0000000..bd4bf8d
--- /dev/null
+++ b/SOURCES/gcc32-null-pointer-check-noncc0.patch
@@ -0,0 +1,67 @@
+2004-02-26  Alan Modra  <amodra@bigpond.net.au>
+
+	PR rtl-optimization/14279
+	* gcse.c (delete_null_pointer_checks_1): Do not delete CC setter
+	unless HAVE_cc0.
+
+2004-12-22  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.c-torture/execute/20041222-1.c: New test.
+
+--- gcc/gcse.c.jj	2003-03-10 17:42:09.000000000 +0100
++++ gcc/gcse.c	2004-12-22 12:03:32.272762070 +0100
+@@ -5428,8 +5428,10 @@ delete_null_pointer_checks_1 (block_reg,
+ 	}
+ 
+       delete_insn (last_insn);
++#ifdef HAVE_cc0
+       if (compare_and_branch == 2)
+         delete_insn (earliest);
++#endif
+       purge_dead_edges (BASIC_BLOCK (bb));
+ 
+       /* Don't check this block again.  (Note that BLOCK_END is
+--- gcc/testsuite/gcc.c-torture/execute/20041222-1.c.jj	2004-12-22 12:07:50.446611220 +0100
++++ gcc/testsuite/gcc.c-torture/execute/20041222-1.c	2004-12-22 11:34:45.000000000 +0100
+@@ -0,0 +1,41 @@
++extern void abort (void);
++extern void exit (int);
++
++struct S
++{
++  void *a;
++  unsigned int b;
++};
++
++void
++__attribute__((noinline))
++bar (struct S *x)
++{
++  if (x->b != 2)
++    abort ();
++}
++
++void
++__attribute__((noinline))
++foo (struct S *x)
++{
++  if (! x->a)
++    {
++      struct S *y, *z;
++      y = x;
++      if (y)
++	++y->b;
++      z = x;
++      if (z)
++	++z->b;
++      bar (x);
++    }
++}
++
++int
++main (void)
++{
++  struct S s = { 0, 0 };
++  foo (&s);
++  exit (0);
++}
diff --git a/SOURCES/gcc32-obstack-lvalues.patch b/SOURCES/gcc32-obstack-lvalues.patch
new file mode 100644
index 0000000..0374687
--- /dev/null
+++ b/SOURCES/gcc32-obstack-lvalues.patch
@@ -0,0 +1,114 @@
+2003-10-22  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+	* obstack.h: Merge the following change from gnulib:
+	2003-10-21  Paul Eggert  <eggert@twinsun.com>
+	* obstack.h (obstack_1grow_fast): Properly parenthesize arg.
+	(obstack_ptr_grow_fast, obstack_int_grow_fast):
+	Don't use lvalue casts, as GCC plans to remove support for them
+	in GCC 3.5.  Reported by Joseph S. Myers.  This bug
+	was also present in the non-GCC version, indicating that this
+	code had always been buggy and had never been widely used.
+	(obstack_1grow, obstack_ptr_grow, obstack_int_grow, obstack_blank):
+	Use the fast variant of each macro, rather than copying the
+	definiens of the fast variant; that way, we'll be more likely to
+	catch future bugs in the fast variants.
+
+--- include/obstack.h	14 Mar 2001 19:44:38 -0000	1.5
++++ include/obstack.h	22 Oct 2003 22:28:20 -0000	1.6
+@@ -343,7 +343,7 @@ extern int obstack_exit_failure;
+ 
+ #endif
+ 
+-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
++#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
+ 
+ #define obstack_blank_fast(h,n) ((h)->next_free += (n))
+ 
+@@ -411,7 +411,7 @@ __extension__								\
+ ({ struct obstack *__o = (OBSTACK);					\
+    if (__o->next_free + 1 > __o->chunk_limit)				\
+      _obstack_newchunk (__o, 1);					\
+-   *(__o->next_free)++ = (datum);					\
++   obstack_1grow_fast (__o, datum);					\
+    (void) 0; })
+ 
+ /* These assume that the obstack alignment is good enough for pointers or ints,
+@@ -423,19 +423,28 @@ __extension__								\
+ ({ struct obstack *__o = (OBSTACK);					\
+    if (__o->next_free + sizeof (void *) > __o->chunk_limit)		\
+      _obstack_newchunk (__o, sizeof (void *));				\
+-   *((void **)__o->next_free)++ = ((void *)datum);			\
+-   (void) 0; })
++   obstack_ptr_grow_fast (__o, datum); })
+ 
+ # define obstack_int_grow(OBSTACK,datum)				\
+ __extension__								\
+ ({ struct obstack *__o = (OBSTACK);					\
+    if (__o->next_free + sizeof (int) > __o->chunk_limit)		\
+      _obstack_newchunk (__o, sizeof (int));				\
+-   *((int *)__o->next_free)++ = ((int)datum);				\
++   obstack_int_grow_fast (__o, datum); })
++
++# define obstack_ptr_grow_fast(OBSTACK,aptr)				\
++__extension__								\
++({ struct obstack *__o1 = (OBSTACK);					\
++   *(const void **) __o1->next_free = (aptr);				\
++   __o1->next_free += sizeof (const void *);				\
+    (void) 0; })
+ 
+-# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
+-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
++# define obstack_int_grow_fast(OBSTACK,aint)				\
++__extension__								\
++({ struct obstack *__o1 = (OBSTACK);					\
++   *(int *) __o1->next_free = (aint);					\
++   __o1->next_free += sizeof (int);					\
++   (void) 0; })
+ 
+ # define obstack_blank(OBSTACK,length)					\
+ __extension__								\
+@@ -443,7 +452,7 @@ __extension__								\
+    int __len = (length);						\
+    if (__o->chunk_limit - __o->next_free < __len)			\
+      _obstack_newchunk (__o, __len);					\
+-   __o->next_free += __len;						\
++   obstack_blank_fast (__o, __len);					\
+    (void) 0; })
+ 
+ # define obstack_alloc(OBSTACK,length)					\
+@@ -530,26 +539,29 @@ __extension__								\
+ # define obstack_1grow(h,datum)						\
+ ( (((h)->next_free + 1 > (h)->chunk_limit)				\
+    ? (_obstack_newchunk ((h), 1), 0) : 0),				\
+-  (*((h)->next_free)++ = (datum)))
++  obstack_1grow_fast (h, datum))
+ 
+ # define obstack_ptr_grow(h,datum)					\
+ ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
+    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		\
+-  (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
++  obstack_ptr_grow_fast (h, datum))
+ 
+ # define obstack_int_grow(h,datum)					\
+ ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
+    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			\
+-  (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
++  obstack_int_grow_fast (h, datum))
++
++# define obstack_ptr_grow_fast(h,aptr)					\
++  (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
+ 
+-# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
+-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
++# define obstack_int_grow_fast(h,aint)					\
++  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
+ 
+ # define obstack_blank(h,length)					\
+ ( (h)->temp = (length),							\
+   (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
+    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
+-  ((h)->next_free += (h)->temp))
++  obstack_blank_fast (h, (h)->temp))
+ 
+ # define obstack_alloc(h,length)					\
+  (obstack_blank ((h), (length)), obstack_finish ((h)))
diff --git a/SOURCES/gcc32-ppc-altivec-ap.patch b/SOURCES/gcc32-ppc-altivec-ap.patch
new file mode 100644
index 0000000..fa13148
--- /dev/null
+++ b/SOURCES/gcc32-ppc-altivec-ap.patch
@@ -0,0 +1,37 @@
+2004-03-30  Hartmut Penner  <hpenner@de.ibm.com>
+
+	PR 11591
+	* config/rs6000/rs6000.c (rs6000_legitimate_address):
+	Allow any offset to argument pointer in no-strict case.
+
+2002-04-16  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.dg/altivec-5.c: New test.
+
+--- gcc/config/rs6000/rs6000.c	25 Mar 2004 17:43:19 -0000	1.616
++++ gcc/config/rs6000/rs6000.c	30 Mar 2004 08:25:30 -0000	1.617
+@@ -3267,7 +3267,8 @@ rs6000_legitimate_address (enum machine_
+   if (! reg_ok_strict
+       && GET_CODE (x) == PLUS
+       && GET_CODE (XEXP (x, 0)) == REG
+-      && XEXP (x, 0) == virtual_stack_vars_rtx
++      && (XEXP (x, 0) == virtual_stack_vars_rtx
++         || XEXP (x, 0) == arg_pointer_rtx)
+       && GET_CODE (XEXP (x, 1)) == CONST_INT)
+     return 1;
+   if (legitimate_offset_address_p (mode, x, reg_ok_strict))
+--- gcc/testsuite/gcc.dg/altivec-5.c.jj	2004-10-25 23:16:31.270583520 +0200
++++ gcc/testsuite/gcc.dg/altivec-5.c	2004-10-25 23:16:40.327975169 +0200
+@@ -0,0 +1,12 @@
++/* { dg-do compile { target powerpc*-*-* } } */
++/* { dg-options "-maltivec -O2 -m32" } */
++
++#define vector __attribute__((vector_size(16)))
++
++void foo (const unsigned long x,
++	  vector signed int a, vector signed int b)
++{
++  unsigned char d[64];
++
++  __builtin_altivec_stvewx (b, 0, d);
++}
diff --git a/SOURCES/gcc32-ppc-movdi_internal64.patch b/SOURCES/gcc32-ppc-movdi_internal64.patch
new file mode 100644
index 0000000..573c7ed
--- /dev/null
+++ b/SOURCES/gcc32-ppc-movdi_internal64.patch
@@ -0,0 +1,149 @@
+2004-07-25  David Edelsohn  <edelsohn@gnu.org>
+
+	PR target/16239
+	* config/rs6000/rs6000.md (movdi_internal64): Further disparage
+	f->f.
+
+2002-11-06  David Edelsohn  <edelsohn@gnu.org>
+
+	PR target/8480, optimization/8328
+	* config/rs6000/rs6000.md (movdi_internal64): Discourage
+	FPR to FPR moves.
+
+2004-12-22  Ben Elliston  <bje@au.ibm.com>
+
+	PR optimization/8328
+	* gcc.dg/pr8328.c: New test.
+
+--- gcc/config/rs6000/rs6000.md	16 Jul 2003 11:40:06 -0000
++++ gcc/config/rs6000/rs6000.md	22 Dec 2004 08:31:18 -0000
+@@ -8749,7 +8749,7 @@
+ }")
+ 
+ (define_insn "*movdi_internal64"
+-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h")
++  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,??f,f,m,r,*h,*h")
+ 	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+   "TARGET_POWERPC64
+    && (gpc_reg_operand (operands[0], DImode)
+
+--- gcc/testsuite/gcc.dg/pr8328.c	1 Jan 1970 00:00:00 -0000
++++ gcc/testsuite/gcc.dg/pr8328.c	22 Dec 2004 08:31:18 -0000
+@@ -0,0 +1,117 @@
++/* { dg-do compile { target powerpc64-*-linux* } } */
++/* { dg-options "-O3" } */
++
++/* This test case comes from the original PR.  */
++
++struct list
++{
++  unsigned short type;
++  unsigned int len;
++  void *data;
++  short *ind;
++};
++
++extern int foo (int *);
++extern int bar (void);
++extern int qwe (struct list *);
++extern long check (int *);
++extern void display (int *);
++extern void trace (int *);
++
++int
++myfunc (int *opts, char *str)
++{
++  short num;
++  int loc;
++  int start;
++  int len;
++  int code;
++  int rc = 0;
++
++  if (code && (rc = check (opts)))
++    goto exit;
++
++  foo (&code);
++  {
++    struct list mylist[1];
++    mylist[0].type = 960;
++    mylist[0].len = 4;
++    mylist[0].data = (void *) &loc;
++    mylist[0].ind = 0L;
++    qwe (mylist);
++  }
++  bar ();
++
++  if (code && (rc = check (opts)))
++    goto exit;
++
++  foo (&code);
++  bar ();
++
++  if (code && (rc = check (opts)))
++    goto exit;
++
++  if (opts)
++    trace (opts);
++
++  display (opts);
++
++  while (code >= 0)
++    {
++      foo (&code);
++      {
++        struct list mylist[1];
++        mylist[0].type = 500;
++        mylist[0].len = 2;
++        mylist[0].data = (void *) &num;
++        mylist[0].ind = 0L;
++        qwe (mylist);
++      }
++      bar ();
++      {
++        struct list mylist[3];
++        mylist[0].type = 960;
++        mylist[0].len = 4;
++        mylist[0].data = (void *) &loc;
++        mylist[0].ind = 0L;
++        mylist[1].type = 496;
++        mylist[1].len = 4;
++        mylist[1].data = (void *) &start;
++        mylist[1].ind = 0L;
++        mylist[2].type = 496;
++        mylist[2].len = 4;
++        mylist[2].data = (void *) &len;
++        mylist[2].ind = 0L;
++        qwe (mylist);
++      }
++      {
++        struct list mylist[4];
++        mylist[0].type = 460;
++        mylist[0].len = 129;
++        mylist[0].data = (void *) str;
++        mylist[0].ind = 0L;
++        mylist[1].type = 460;
++        mylist[1].len = 129;
++        mylist[1].data = (void *) str;
++        mylist[1].ind = 0L;
++        mylist[2].type = 460;
++        mylist[2].len = 9;
++        mylist[2].data = (void *) str;
++        mylist[2].ind = 0L;
++        mylist[3].type = 500;
++        mylist[3].len = 2;
++        mylist[3].data = (void *) str;
++        mylist[3].ind = 0L;
++        qwe (mylist);
++      }
++    }
++
++ exit:
++  {
++    struct list mylist[1];
++    mylist[0].data = (void *) &loc;
++    mylist[0].ind = 0L;
++    qwe (mylist);
++  }
++  return (rc);
++}
diff --git a/SOURCES/gcc32-ppc-mpowerpc64.patch b/SOURCES/gcc32-ppc-mpowerpc64.patch
new file mode 100644
index 0000000..5874d6d
--- /dev/null
+++ b/SOURCES/gcc32-ppc-mpowerpc64.patch
@@ -0,0 +1,24 @@
+2004-10-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Disallow
+	-m32 -mpowerpc64 and -m64 -mno-powerpc64.
+
+--- gcc/config/rs6000/linux64.h.jj	2004-02-28 12:27:45.000000000 +0100
++++ gcc/config/rs6000/linux64.h	2004-10-26 12:45:20.399107248 +0200
+@@ -142,6 +142,16 @@ Boston, MA 02111-1307, USA.  */
+ 	  flag_pic = 0;						\
+ 	  error ("-m32 and -maddr32 are incompatible");		\
+ 	}							\
++      if (TARGET_32BIT && TARGET_POWERPC64)			\
++        {							\
++          error ("-mpowerpc64 can't be used for 32-bit compilation"); \
++          target_flags &= ~MASK_POWERPC64;			\
++        }							\
++      else if (TARGET_64BIT && !TARGET_POWERPC64)		\
++        {							\
++          error ("-mno-powerpc64 can't be used for 64-bit compilation"); \
++          target_flags |= MASK_POWERPC64 | MASK_POWERPC;	\
++        }							\
+     }								\
+   while (0)
+ 
diff --git a/SOURCES/gcc32-ppc64-crtsavres.patch b/SOURCES/gcc32-ppc64-crtsavres.patch
new file mode 100644
index 0000000..7c0dd58
--- /dev/null
+++ b/SOURCES/gcc32-ppc64-crtsavres.patch
@@ -0,0 +1,14 @@
+2004-08-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* config/rs6000/crtsavres.asm (.fres): Add .align 2.
+
+--- gcc/config/rs6000/crtsavres.asm.jj	2002-02-19 20:40:41.000000000 +0100
++++ gcc/config/rs6000/crtsavres.asm	2004-08-18 10:58:01.952395671 +0200
+@@ -358,6 +358,7 @@ FUNC_END(_savef14)
+ 
+ /* Routines for restoring floating point registers, called by the compiler.  */
+ 
++	.align 2
+ .fres:
+ FUNC_START(_restf14)	lfd	14,-144(1)	/* restore fp registers */
+ FUNC_START(_restf15)	lfd	15,-136(1)
diff --git a/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch b/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch
new file mode 100644
index 0000000..00dbeac
--- /dev/null
+++ b/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch
@@ -0,0 +1,22 @@
+--- gcc/config/rs6000/t-linux64	2003-06-03 05:11:45.000000000 -0400
++++ gcc/config/rs6000/t-linux64	2003-06-11 17:07:16.000000000 -0400
+@@ -4,13 +4,13 @@ LIB2FUNCS_EXTRA = tramp.S $(srcdir)/conf
+ # Modify the shared lib version file
+ SHLIB_MKMAP_OPTS = -v dotsyms=1
+ 
+-MULTILIB_OPTIONS        = m64/m32 msoft-float
+-MULTILIB_DIRNAMES       = 64 32 nof
++MULTILIB_OPTIONS        = m64/m32
++MULTILIB_DIRNAMES       = 64 32
+ MULTILIB_EXTRA_OPTS     = fPIC mstrict-align
+-MULTILIB_EXCEPTIONS     = m64/msoft-float
+-MULTILIB_EXCLUSIONS     = m64/!m32/msoft-float
+-MULTILIB_OSDIRNAMES	= ../lib64 ../lib nof
+-MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
++MULTILIB_EXCEPTIONS     =
++MULTILIB_EXCLUSIONS     =
++MULTILIB_OSDIRNAMES	= ../lib64 ../lib
++MULTILIB_MATCHES        =
+ 
+ TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC
+ 
diff --git a/SOURCES/gcc32-ppc64-stack-boundary.patch b/SOURCES/gcc32-ppc64-stack-boundary.patch
new file mode 100644
index 0000000..a01a86e
--- /dev/null
+++ b/SOURCES/gcc32-ppc64-stack-boundary.patch
@@ -0,0 +1,30 @@
+2005-09-23  Alexandre Oliva  <aoliva@redhat.com>
+
+	* config/rs6000/sysv4.h (PREFERRED_STACK_BOUNDARY): New,
+	same as STACK_BOUNDARY as in rs6000.h.
+
+--- gcc/config/rs6000/sysv4.h.orig
++++ gcc/config/rs6000/sysv4.h
+@@ -395,6 +395,22 @@ do {									\
+ #undef	STACK_BOUNDARY
+ #define	STACK_BOUNDARY	(TARGET_ALTIVEC_ABI ? 128 : 64)
+ 
++/* The definition above is actually wrong, since it doesn't use
++   128-bit alignment on ppc64 like the ABI mandates.  It was removed
++   in newer versions of GCC.  The correct definition would be the one
++   below, from rs6000.h.  Unfortunately, changing it would increase
++   the stack alignment expectations of newly-compiled functions, that
++   might be called by functions compiled with the old compiler.  If
++   the latter didn't keep the stack sufficiently aligned.  This may
++   happen if the latter uses alloca() or dynamically-sized arrays.  We
++   compensate for the error here, getting the compiler to keep the
++   stack aligned to the correct boundary, but not assuming it is
++   sufficiently aligned.  Code that still assumes proper alignment
++   will fail and require recompilation with this patch or a newer
++   compiler, but most of the code will work without change.  */
++#define PREFERRED_STACK_BOUNDARY \
++  ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
++
+ /* Real stack boundary as mandated by the appropriate ABI.  */
+ #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+ 
diff --git a/SOURCES/gcc32-pr12799.patch b/SOURCES/gcc32-pr12799.patch
new file mode 100644
index 0000000..aee7f8d
--- /dev/null
+++ b/SOURCES/gcc32-pr12799.patch
@@ -0,0 +1,111 @@
+2005-10-02  Jakub Jelinek  <jakub@redhat.com>
+
+	PR optimization/12799
+	* gcc.c-torture/execute/20051002-1.c: New test.
+
+2003-11-02  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	PR optimization/12799
+	* reload1.c (reload_cse_move2add): Generate the add2
+	patterns manually.
+
+	* gcc.dg/20031102-1.c: New test.
+
+--- gcc/reload1.c.jj	2003-10-31 11:42:15.000000000 +0100
++++ gcc/reload1.c	2005-10-02 21:52:08.000000000 +0200
+@@ -9176,8 +9176,13 @@ reload_cse_move2add (first)
+ 		    success = validate_change (insn, &SET_SRC (pat), reg, 0);
+ 		  else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
+ 			   && have_add2_insn (reg, new_src))
+-		    success = validate_change (insn, &PATTERN (insn),
+-					       gen_add2_insn (reg, new_src), 0);
++		    {
++		      rtx newpat = gen_rtx_SET (VOIDmode, reg,
++						gen_rtx_PLUS (GET_MODE (reg),
++							      reg, new_src));
++		      success
++			= validate_change (insn, &PATTERN (insn), newpat, 0);
++		    }
+ 		  reg_set_luid[regno] = move2add_luid;
+ 		  reg_mode[regno] = GET_MODE (reg);
+ 		  reg_offset[regno] = INTVAL (src);
+@@ -9227,9 +9232,15 @@ reload_cse_move2add (first)
+ 		      else if ((rtx_cost (new_src, PLUS)
+ 				< COSTS_N_INSNS (1) + rtx_cost (src3, SET))
+ 			       && have_add2_insn (reg, new_src))
+-			success
+-			  = validate_change (next, &PATTERN (next),
+-					     gen_add2_insn (reg, new_src), 0);
++			{
++			  rtx newpat
++			    = gen_rtx_SET (VOIDmode, reg,
++					   gen_rtx_PLUS (GET_MODE (reg),
++							 reg, new_src));
++			  success
++			    = validate_change (next, &PATTERN (next),
++					       newpat, 0);
++			}
+ 		      if (success)
+ 			delete_insn (insn);
+ 		      insn = next;
+--- gcc/testsuite/gcc.dg/20031102-1.c.jj	1 Jan 1970 00:00:00 -0000
++++ gcc/testsuite/gcc.dg/20031102-1.c	2 Nov 2003 08:32:23 -0000	1.1
+@@ -0,0 +1,37 @@
++/* PR optimization/12799 */
++/* Origin: Pratap Subrahmanyam <pratap@vmware.com> */
++
++/* { dg-do run } */
++/* { dg-options "-O2" } */
++/* { dg-options "-O2 -march=i686" { target i686-*-* } } */
++
++/* Verify that reload_cse_move2add doesn't add unexpected CLOBBERs. */
++
++extern void abort(void);
++
++int loo = 1;
++
++__inline__ char InlineFunc(void)
++{
++  return __builtin_expect(!!(loo == 1), 1);
++}
++
++int FooBar(void)
++{
++  int i;
++  int var1 = InlineFunc() ? 2046 : 1023;
++  int var2 = InlineFunc() ? 512 : 1024;
++
++  for (i = 0; i < var1; i++)
++    ;
++
++  if (InlineFunc() && var2 != 512)
++    abort();
++
++  return 0;
++}
++
++int main(void)
++{
++  return FooBar();
++}
+--- gcc/testsuite/gcc.c-torture/execute/20051002-1.c.jj	2005-09-19 08:33:21.659531528 +0200
++++ gcc/testsuite/gcc.c-torture/execute/20051002-1.c	2005-10-02 20:38:54.000000000 +0200
+@@ -0,0 +1,18 @@
++/* PR optimization/12799 */
++extern void abort (void);
++
++unsigned int
++foo (unsigned long a)
++{
++  if (a >= 0xffffffffUL)
++    return 0xffffffff;
++  return a;
++}
++
++int
++main ()
++{
++  if (foo (0) != 0)
++    abort ();
++  return 0;
++}
diff --git a/SOURCES/gcc32-pr13041.patch b/SOURCES/gcc32-pr13041.patch
new file mode 100644
index 0000000..3ca4854
--- /dev/null
+++ b/SOURCES/gcc32-pr13041.patch
@@ -0,0 +1,37 @@
+2003-11-27  Eric Botcazou  <ebotcazou@libertysurf.fr>
+ 
+	PR optimization/13041
+	* final.c (frame_pointer_needed): Fix comment.
+	* reload1.c (reload): Decrease alignment of the frame
+	pointer if it was used for register allocation.
+
+--- gcc/final.c	1 Nov 2003 00:48:50 -0000	1.294
++++ gcc/final.c	27 Nov 2003 06:45:24 -0000	1.295
+@@ -171,8 +171,8 @@ CC_STATUS cc_prev_status;
+ char regs_ever_live[FIRST_PSEUDO_REGISTER];
+ 
+ /* Nonzero means current function must be given a frame pointer.
+-   Set in stmt.c if anything is allocated on the stack there.
+-   Set in reload1.c if anything is allocated on the stack there.  */
++   Initialized in function.c to 0.  Set only in reload1.c as per
++   the needs of the function.  */
+ 
+ int frame_pointer_needed;
+ 
+--- gcc/reload1.c	21 Nov 2003 05:49:05 -0000	1.413
++++ gcc/reload1.c	27 Nov 2003 06:45:25 -0000	1.414
+@@ -1241,6 +1241,14 @@ reload (rtx first, int global)
+      by this, so unshare everything here.  */
+   unshare_all_rtl_again (first);
+ 
++#ifdef STACK_BOUNDARY
++  /* init_emit has set the alignment of the hard frame pointer
++     to STACK_BOUNDARY.  It is very likely no longer valid if
++     the hard frame pointer was used for register allocation.  */
++  if (!frame_pointer_needed)
++    REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
++#endif
++
+   return failure;
+ }
+ 
diff --git a/SOURCES/gcc32-pr13106.patch b/SOURCES/gcc32-pr13106.patch
new file mode 100644
index 0000000..7b6137a
--- /dev/null
+++ b/SOURCES/gcc32-pr13106.patch
@@ -0,0 +1,37 @@
+2005-09-23  Alexandre Oliva  <aoliva@redhat.com>
+
+	* decl.c (finish_function): Skip no-return-statment warning if
+	the return type uses template parms.
+
+	* g++.dg/warn/return-void-1.C: New test.
+
+--- gcc/cp/decl.c.orig
++++ gcc/cp/decl.c
+@@ -14475,7 +14475,8 @@ finish_function (flags)
+       && !DECL_NAME (DECL_RESULT (fndecl))
+       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
+ 	 inline function, as we might never be compiled separately.  */
+-      && (DECL_INLINE (fndecl) || processing_template_decl))
++      && (DECL_INLINE (fndecl) || processing_template_decl)
++      && !uses_template_parms (TREE_TYPE (fntype)))
+     warning ("no return statement in function returning non-void");
+     
+   /* Clear out memory we no longer need.  */
+--- gcc/testsuite/g++.dg/warn/return-void-1.C
++++ gcc/testsuite/g++.dg/warn/return-void-1.C
+@@ -0,0 +1,15 @@
++// { dg-do compile }
++// { dg-options "-Wall" }
++
++template <typename T> T dummy1() {}
++template <typename T> T dummy2() {} // { dg-warning "end of non-void" }
++template <typename T> inline T dummy3() {}
++template <typename T> inline T dummy4() {} // { dg-warning "end of non-void|no return statement" }
++
++int main()
++{
++  dummy1<void>();
++  dummy2<int>(); // { dg-warning "instantiated from here" }
++  dummy3<void>();
++  dummy4<int>(); // { dg-warning "instantiated from here" }
++}
diff --git a/SOURCES/gcc32-pr18300.patch b/SOURCES/gcc32-pr18300.patch
new file mode 100644
index 0000000..2a5cce6
--- /dev/null
+++ b/SOURCES/gcc32-pr18300.patch
@@ -0,0 +1,166 @@
+2005-09-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/18300
+	* config/i386/i386.c (classify_argument): Only use different
+	iterators for nested loops if nested loops sharing the same
+	iterator would hang.
+
+2004-11-13  Zak Kipling  <zak@transversal.com>
+
+	PR target/18300
+	* config/i386/i386.c (classify_argument): Fix infinite loop when
+	passing object with 3 or more base classes by value.
+
+--- gcc/config/i386/i386.c.jj	2005-07-21 11:01:36.000000000 +0200
++++ gcc/config/i386/i386.c	2005-09-07 14:22:19.000000000 +0200
+@@ -1784,8 +1784,17 @@ classify_argument (mode, type, classes, 
+ 	    {
+ 	      tree bases = TYPE_BINFO_BASETYPES (type);
+ 	      int n_bases = TREE_VEC_LENGTH (bases);
+-	      int i;
+-
++	      int i, basenum;
++	      enum x86_64_reg_class saveclasses[MAX_CLASSES];
++	      bool seen[MAX_CLASSES];
++
++	      /* PR target/18300: The following code mistakenly uses the same
++		 iterator variable in both nested for loops.  But to preserve
++		 binary compatibility, do whatever this code used to do before
++		 unless old GCC would hang in an infinite loop.  In that case
++		 use whatever GCC 4.0+ does.  */
++	      memset (seen, 0, sizeof (seen));
++	      memcpy (saveclasses, classes, sizeof (saveclasses));
+ 	      for (i = 0; i < n_bases; ++i)
+ 		{
+ 		   tree binfo = TREE_VEC_ELT (bases, i);
+@@ -1793,6 +1802,12 @@ classify_argument (mode, type, classes, 
+ 		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
+ 		   tree type = BINFO_TYPE (binfo);
+ 
++		   if (i < MAX_CLASSES)
++		     {
++		       if (seen[i])
++			 break;
++		       seen[i] = true;
++		     }
+ 		   num = classify_argument (TYPE_MODE (type),
+ 					    type, subclasses,
+ 					    (offset + bit_offset) % 256);
+@@ -1805,6 +1820,32 @@ classify_argument (mode, type, classes, 
+ 			 merge_classes (subclasses[i], classes[i + pos]);
+ 		     }
+ 		}
++	      if (i < n_bases)
++		{
++		  /* Older GCC 3.[0-4].x would hang in the above loop, so
++		     don't worry about backwards compatibility and
++		     just DTRT.  */
++		  memcpy (classes, saveclasses, sizeof (saveclasses));
++		  for (basenum = 0; basenum < n_bases; ++basenum)
++		    {
++		      tree binfo = TREE_VEC_ELT (bases, basenum);
++		      int num;
++		      int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
++		      tree type = BINFO_TYPE (binfo);
++
++		      num = classify_argument (TYPE_MODE (type),
++					       type, subclasses,
++					       (offset + bit_offset) % 256);
++		      if (!num)
++			return 0;
++		      for (i = 0; i < num; i++)
++			{
++			  int pos = (offset + (bit_offset % 64)) / 8 / 8;
++			  classes[i + pos] =
++			    merge_classes (subclasses[i], classes[i + pos]);
++			}
++		    }
++		}
+ 	    }
+ 	  /* And now merge the fields of structure.   */
+ 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+@@ -1872,8 +1913,17 @@ classify_argument (mode, type, classes, 
+ 	    {
+ 	      tree bases = TYPE_BINFO_BASETYPES (type);
+ 	      int n_bases = TREE_VEC_LENGTH (bases);
+-	      int i;
+-
++	      int i, basenum;
++	      enum x86_64_reg_class saveclasses[MAX_CLASSES];
++	      bool seen[MAX_CLASSES];
++
++	      /* PR target/18300: The following code mistakenly uses the same
++		 iterator variable in both nested for loops.  But to preserve
++		 binary compatibility, do whatever this code used to do before
++		 unless old GCC would hang in an infinite loop.  In that case
++		 use whatever GCC 4.0+ does.  */
++	      memset (seen, 0, sizeof (seen));
++	      memcpy (saveclasses, classes, sizeof (saveclasses));
+ 	      for (i = 0; i < n_bases; ++i)
+ 		{
+ 		   tree binfo = TREE_VEC_ELT (bases, i);
+@@ -1881,6 +1931,12 @@ classify_argument (mode, type, classes, 
+ 		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
+ 		   tree type = BINFO_TYPE (binfo);
+ 
++		   if (i < MAX_CLASSES)
++		     {
++		       if (seen[i])
++			 break;
++		       seen[i] = true;
++		     }
+ 		   num = classify_argument (TYPE_MODE (type),
+ 					    type, subclasses,
+ 					    (offset + (bit_offset % 64)) % 256);
+@@ -1893,6 +1949,32 @@ classify_argument (mode, type, classes, 
+ 			 merge_classes (subclasses[i], classes[i + pos]);
+ 		     }
+ 		}
++	      if (i < n_bases)
++		{
++		  /* Older GCC 3.[0-4].x would hang in the above loop, so
++		     don't worry about backwards compatibility and
++		     just DTRT.  */
++		  memcpy (classes, saveclasses, sizeof (saveclasses));
++		  for (basenum = 0; basenum < n_bases; ++basenum)
++		    {
++		      tree binfo = TREE_VEC_ELT (bases, basenum);
++		      int num;
++		      int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
++		      tree type = BINFO_TYPE (binfo);
++
++		      num = classify_argument (TYPE_MODE (type),
++					       type, subclasses,
++					       (offset + (bit_offset % 64)) % 256);
++		      if (!num)
++			return 0;
++		      for (i = 0; i < num; i++)
++			{
++			  int pos = (offset + (bit_offset % 64)) / 8 / 8;
++			  classes[i + pos] =
++			    merge_classes (subclasses[i], classes[i + pos]);
++			}
++		    }
++		}
+ 	    }
+ 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ 	    {
+--- gcc/testsuite/g++.dg/other/infloop-1.C 1 Jan 1970 00:00:00 -0000
++++ gcc/testsuite/g++.dg/other/infloop-1.C	13 Nov 2004 23:09:08 -0000	1.1
+@@ -0,0 +1,16 @@
++// PR 18300: This sends old compilers into an infinite loop on x86_64
++// Testcase and patch contributed by Zak Kipling <zak@transversal.com>
++
++struct base1 { };
++struct base2 { };
++struct base3 { };
++
++struct derived : base1, base2, base3 { };
++
++void foo(derived);
++
++int main()
++{
++  foo(derived());
++}
++
diff --git a/SOURCES/gcc32-pr19005.patch b/SOURCES/gcc32-pr19005.patch
new file mode 100644
index 0000000..a4f2442
--- /dev/null
+++ b/SOURCES/gcc32-pr19005.patch
@@ -0,0 +1,61 @@
+2005-05-13  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/19005
+	* config/i386/i386.md (swapqi): Use +q instead of +r constraints.
+
+	* gcc.c-torture/execute/pr19005.c: New test.
+
+--- gcc/config/i386/i386.md.jj	2004-07-01 12:40:54.000000000 +0200
++++ gcc/config/i386/i386.md	2005-05-13 13:56:14.000000000 +0200
+@@ -2107,8 +2107,8 @@
+ })
+ 
+ (define_insn "*swapqi"
+-  [(set (match_operand:QI 0 "register_operand" "+r")
+-	(match_operand:QI 1 "register_operand" "+r"))
++  [(set (match_operand:QI 0 "register_operand" "+q")
++	(match_operand:QI 1 "register_operand" "+q"))
+    (set (match_dup 1)
+ 	(match_dup 0))]
+   ""
+--- gcc/testsuite/gcc.c-torture/execute/pr19005.c.jj	2005-04-07 15:51:53.775361896 +0200
++++ gcc/testsuite/gcc.c-torture/execute/pr19005.c	2005-05-13 13:33:21.000000000 +0200
+@@ -0,0 +1,38 @@
++/* PR target/19005 */
++extern void abort (void);
++
++int v, s;
++
++void
++bar (int a, int b)
++{
++  unsigned char x = v;
++
++  if (!s)
++    {
++      if (a != x || b != (unsigned char) (x + 1))
++        abort ();
++    }
++  else if (a != (unsigned char) (x + 1) || b != x)
++    abort ();
++  s ^= 1;
++}
++
++int
++foo (int x)
++{
++  unsigned char a = x, b = x + 1;
++
++  bar (a, b);
++  a ^= b; b ^= a; a ^= b;
++  bar (a, b);
++  return 0;
++}
++
++int
++main (void)
++{
++  for (v = -10; v < 266; v++)
++    foo (v);
++  return 0;
++}
diff --git a/SOURCES/gcc32-pr26208-workaround.patch b/SOURCES/gcc32-pr26208-workaround.patch
new file mode 100644
index 0000000..ed54694
--- /dev/null
+++ b/SOURCES/gcc32-pr26208-workaround.patch
@@ -0,0 +1,249 @@
+--- gcc/unwind-dw2.c.jj	2006-05-22 13:39:48.000000000 -0400
++++ gcc/unwind-dw2.c	2006-05-22 13:48:20.000000000 -0400
+@@ -61,8 +61,8 @@ struct _Unwind_Context
+   void *ra;
+   void *lsda;
+   struct dwarf_eh_bases bases;
++#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
+   _Unwind_Word args_size;
+-  char signal_frame;
+ };
+ 
+ /* Byte size of every register managed by these routines.  */
+@@ -201,7 +201,7 @@ _Unwind_GetIP (struct _Unwind_Context *c
+ inline _Unwind_Ptr
+ _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
+ {
+-  *ip_before_insn = context->signal_frame != 0;
++  *ip_before_insn = (context->args_size & SIGNAL_FRAME_BIT) != 0;
+   return (_Unwind_Ptr) context->ra;
+ }
+ 
+@@ -758,7 +758,8 @@ execute_cfa_program (const unsigned char
+      reflected at the point immediately before the call insn.
+      In signal frames, return address is after last completed instruction,
+      so we add 1 to return address to make the comparison <=.  */
+-  while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
++  while (insn_ptr < insn_end
++	 && fs->pc < context->ra + ((context->args_size & SIGNAL_FRAME_BIT) != 0))
+     {
+       unsigned char insn = *insn_ptr++;
+       _Unwind_Word reg, utmp;
+@@ -918,7 +919,14 @@ execute_cfa_program (const unsigned char
+ 	  break;
+ 
+ 	case DW_CFA_GNU_args_size:
+-	  insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
++	  {
++	    _Unwind_Word args_size;
++	    insn_ptr = read_uleb128 (insn_ptr, &args_size);
++	    if (args_size & SIGNAL_FRAME_BIT)
++	      abort ();
++	    context->args_size
++	      = (context->args_size & SIGNAL_FRAME_BIT) | args_size;
++	  }
+ 	  break;
+ 
+ 	case DW_CFA_GNU_negative_offset_extended:
+@@ -945,10 +953,10 @@ uw_frame_state_for (struct _Unwind_Conte
+   const unsigned char *aug, *insn, *end;
+ 
+   memset (fs, 0, sizeof (*fs));
+-  context->args_size = 0;
++  context->args_size &= SIGNAL_FRAME_BIT;
+   context->lsda = 0;
+ 
+-  fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
++  fde = _Unwind_Find_FDE (context->ra + ((context->args_size & SIGNAL_FRAME_BIT) != 0) - 1,
+ 			  &context->bases);
+   if (fde == NULL)
+     {
+@@ -1092,7 +1100,7 @@ __frame_state_for (void *pc_target, stru
+   state_in->cfa_offset = fs.cfa_offset;
+   state_in->cfa_reg = fs.cfa_reg;
+   state_in->retaddr_column = fs.retaddr_column;
+-  state_in->args_size = context.args_size;
++  state_in->args_size = context.args_size & ~SIGNAL_FRAME_BIT;
+   state_in->eh_ptr = fs.eh_ptr;
+ 
+ #ifdef __linux__
+@@ -1287,7 +1295,10 @@ uw_update_context_1 (struct _Unwind_Cont
+ 	break;
+       }
+ 
+-  context->signal_frame = fs->signal_frame;
++  if (fs->signal_frame)
++    context->args_size |= SIGNAL_FRAME_BIT;
++  else
++    context->args_size &= ~SIGNAL_FRAME_BIT;
+ 
+   MD_FROB_UPDATE_CONTEXT (context, fs);
+ }
+@@ -1403,9 +1414,9 @@ uw_install_context_1 (struct _Unwind_Con
+ 
+     /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
+     if (STACK_GROWS_DOWNWARD)
+-      return target_cfa - current->cfa + target->args_size;
++      return target_cfa - current->cfa + (target->args_size & ~SIGNAL_FRAME_BIT);
+     else
+-      return current->cfa - target_cfa - target->args_size;
++      return current->cfa - target_cfa - (target->args_size & ~SIGNAL_FRAME_BIT);
+   }
+ #else
+   return 0;
+--- libjava/exception.cc.jj	2006-05-22 13:39:48.000000000 -0400
++++ libjava/exception.cc	2006-05-22 14:48:30.000000000 -0400
+@@ -31,6 +31,153 @@ namespace std
+ }
+ #include "unwind.h"
+ 
++#if defined PIC && !defined __ia64__
++
++#include <dlfcn.h>
++
++extern "C" {
++
++static void *libgcc_s_handle;
++
++_Unwind_Reason_Code __attribute__((visibility ("hidden")))
++_Unwind_RaiseException (struct _Unwind_Exception *exc)
++{
++  static _Unwind_Reason_Code (*RaiseException) (struct _Unwind_Exception *);
++
++  if (RaiseException == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      RaiseException = (__typeof (RaiseException))
++	dlsym (libgcc_s_handle, "_Unwind_RaiseException");
++    }
++  return RaiseException (exc);
++}
++
++void __attribute__((visibility ("hidden")))
++_Unwind_Resume (struct _Unwind_Exception *exc)
++{
++  static void (*Resume) (struct _Unwind_Exception *);
++
++  if (Resume == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      Resume = (__typeof (Resume))
++	dlsym (libgcc_s_handle, "_Unwind_Resume");
++    }
++  Resume (exc);
++}
++
++__attribute__((visibility ("hidden"))) void * 
++_Unwind_GetLanguageSpecificData (struct _Unwind_Context *ctx)
++{
++  static void * (*GetLanguageSpecificData) (struct _Unwind_Context *);
++
++  if (GetLanguageSpecificData == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      GetLanguageSpecificData = (__typeof (GetLanguageSpecificData))
++	dlsym (libgcc_s_handle, "_Unwind_GetLanguageSpecificData");
++    }
++  return GetLanguageSpecificData (ctx);
++}
++
++_Unwind_Ptr __attribute__((visibility ("hidden")))
++_Unwind_GetRegionStart (struct _Unwind_Context *ctx)
++{
++  static _Unwind_Ptr (*GetRegionStart) (struct _Unwind_Context *);
++
++  if (GetRegionStart == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      GetRegionStart = (__typeof (GetRegionStart))
++	dlsym (libgcc_s_handle, "_Unwind_GetRegionStart");
++    }
++  return GetRegionStart (ctx);
++}
++
++_Unwind_Ptr __attribute__((visibility ("hidden")))
++_Unwind_GetDataRelBase (struct _Unwind_Context *ctx)
++{
++  static _Unwind_Ptr (*GetDataRelBase) (struct _Unwind_Context *);
++
++  if (GetDataRelBase == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      GetDataRelBase = (__typeof (GetDataRelBase))
++	dlsym (libgcc_s_handle, "_Unwind_GetDataRelBase");
++    }
++  return GetDataRelBase (ctx);
++}
++
++_Unwind_Ptr __attribute__((visibility ("hidden")))
++_Unwind_GetTextRelBase (struct _Unwind_Context *ctx)
++{
++  static _Unwind_Ptr (*GetTextRelBase) (struct _Unwind_Context *);
++
++  if (GetTextRelBase == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      GetTextRelBase = (__typeof (GetTextRelBase))
++	dlsym (libgcc_s_handle, "_Unwind_GetTextRelBase");
++    }
++  return GetTextRelBase (ctx);
++}
++
++_Unwind_Ptr __attribute__((visibility ("hidden")))
++_Unwind_GetIPInfo (struct _Unwind_Context *ctx, int *ip)
++{
++  static _Unwind_Ptr (*GetIPInfo) (struct _Unwind_Context *, int *ip);
++
++  if (GetIPInfo == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      GetIPInfo = (__typeof (GetIPInfo))
++	dlsym (libgcc_s_handle, "_Unwind_GetIPInfo");
++    }
++  return GetIPInfo (ctx, ip);
++}
++
++void __attribute__((visibility ("hidden")))
++_Unwind_SetIP (struct _Unwind_Context *ctx, _Unwind_Ptr ip)
++{
++  static void (*SetIP) (struct _Unwind_Context *, _Unwind_Ptr ip);
++
++  if (SetIP == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      SetIP = (__typeof (SetIP))
++	dlsym (libgcc_s_handle, "_Unwind_SetIP");
++    }
++  SetIP (ctx, ip);
++}
++
++void __attribute__((visibility ("hidden")))
++_Unwind_SetGR (struct _Unwind_Context *ctx, int num, _Unwind_Ptr gr)
++{
++  static void (*SetGR) (struct _Unwind_Context *, int num, _Unwind_Ptr gr);
++
++  if (SetGR == NULL)
++    {
++      if (libgcc_s_handle == NULL)
++	libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
++      SetGR = (__typeof (SetGR))
++	dlsym (libgcc_s_handle, "_Unwind_SetGR");
++    }
++  SetGR (ctx, num, gr);
++}
++
++}
++
++#endif
++
+ struct alignment_test_struct
+ {
+   char space;
diff --git a/SOURCES/gcc32-pr26208.patch b/SOURCES/gcc32-pr26208.patch
new file mode 100644
index 0000000..bb64f2d
--- /dev/null
+++ b/SOURCES/gcc32-pr26208.patch
@@ -0,0 +1,433 @@
+2006-02-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR other/26208
+	* unwind-dw2.c (struct _Unwind_Context): Add signal_frame field.
+	(_Unwind_FrameState): Add signal_frame field.
+	(extract_cie_info): Handle S flag in augmentation string.
+	(execute_cfa_program): If context->signal_frame, execute also
+	fs->pc == context->ra instructions.
+	(uw_frame_state_for): If context->signal_frame, don't subtract one
+	from context->ra to find FDE.
+	(uw_update_context_1): Set context->signal_frame to
+	fs->signal_frame.
+	(_Unwind_GetIPInfo): New function.
+	* unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
+	of _Unwind_GetIP.
+	* unwind-sjlj.c (_Unwind_GetIPInfo): New function.
+	* unwind.h (_Unwind_GetIPInfo): New prototype.
+	* libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0.
+	* config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function.
+	* config/i386/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Set
+	(FS)->signal_frame.
+	* config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise.
+	* config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise.
+	* config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise.
+	* config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise.
+
+	* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use
+	_Unwind_GetIPInfo instead of _Unwind_GetIP.
+
+	* exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
+	of _Unwind_GetIP.
+	* include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro.
+	(HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through
+	to throw.
+	* include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty
+	macro.
+	* include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty
+	macro.
+
+--- libjava/exception.cc.jj	2002-04-09 16:20:32.000000000 +0200
++++ libjava/exception.cc	2006-04-25 15:33:37.000000000 +0200
+@@ -196,6 +196,7 @@ PERSONALITY_FUNCTION (int version,
+   int handler_switch_value;
+   bool saw_cleanup;
+   bool saw_handler;
++  int ip_before_insn = 0;
+ 
+ 
+   // Interface version check.
+@@ -211,10 +212,10 @@ PERSONALITY_FUNCTION (int version,
+       goto install_context;
+     }
+ 
+-  // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
++  // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
+   // the stack trace for this exception.  This will only collect Java
+   // frames, but perhaps that is acceptable.
+-  // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
++  // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
+   // index instead of a PC value.  We could perhaps arrange for
+   // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
+   // is the address of the handler label for __builtin_longjmp, but
+@@ -229,7 +230,9 @@ PERSONALITY_FUNCTION (int version,
+ 
+   // Parse the LSDA header.
+   p = parse_lsda_header (context, language_specific_data, &info);
+-  ip = _Unwind_GetIP (context) - 1;
++  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
++  if (! ip_before_insn)
++    --ip;
+   landing_pad = 0;
+   action_record = 0;
+   handler_switch_value = 0;
+--- libjava/include/i386-signal.h.jj	2002-03-18 23:27:01.000000000 +0100
++++ libjava/include/i386-signal.h	2006-04-25 15:33:37.000000000 +0200
+@@ -22,19 +22,7 @@ details.  */
+ #define SIGNAL_HANDLER(_name)	\
+ static void _name (int _dummy)
+ 
+-#define MAKE_THROW_FRAME(_exception)					\
+-do									\
+-{									\
+-  void **_p = (void **)&_dummy;						\
+-  struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;	\
+-									\
+-  /* Advance the program counter so that it is after the start of the	\
+-     instruction:  the x86 exception handler expects			\
+-     the PC to point to the instruction after a call. */		\
+-  _regs->eip += 2;							\
+-									\
+-}									\
+-while (0)
++#define MAKE_THROW_FRAME(_exception)
+ 
+ #define HANDLE_DIVIDE_OVERFLOW						\
+ do									\
+@@ -84,14 +72,6 @@ do									\
+ 	  _regs->eip = (unsigned long)_eip;				\
+ 	  return;							\
+ 	}								\
+-      else								\
+-	{								\
+-	  /* Advance the program counter so that it is after the start	\
+-	     of the instruction: this is because the x86 exception	\
+-	     handler expects the PC to point to the instruction after a	\
+-	     call. */							\
+-	  _regs->eip += 2;						\
+-	}								\
+     }									\
+ }									\
+ while (0)
+--- libjava/include/x86_64-signal.h.jj	2003-01-24 23:41:38.000000000 +0100
++++ libjava/include/x86_64-signal.h	2006-04-25 15:34:23.000000000 +0200
+@@ -34,17 +34,7 @@ extern "C" 
+   };
+ }
+ 
+-#define MAKE_THROW_FRAME(_exception)					\
+-do									\
+-{									\
+-  /* Advance the program counter so that it is after the start of the	\
+-     instruction:  the x86_64 exception handler expects			\
+-     the PC to point to the instruction after a call. */		\
+-  struct ucontext *_uc = (struct ucontext *)_p;				\
+-  struct sigcontext *_sc = (struct sigcontext *) &_uc->uc_mcontext;	\
+-  _sc->rip += 2;							\
+-}									\
+-while (0)
++#define MAKE_THROW_FRAME(_exception)
+ 
+ #define RESTORE(name, syscall) RESTORE2 (name, syscall)
+ #define RESTORE2(name, syscall)			\
+--- libjava/include/powerpc-signal.h.jj	2004-02-28 12:27:44.000000000 +0100
++++ libjava/include/powerpc-signal.h	2006-04-25 15:33:37.000000000 +0200
+@@ -22,18 +22,12 @@ details.  */
+ #define SIGNAL_HANDLER(_name)						\
+   static void _name (int /* _signal */, struct sigcontext *_sc)
+ 
+-/* PPC either leaves PC pointing at a faulting instruction or the
+-   following instruction, depending on the signal.  SEGV always does
+-   the former, so we adjust the saved PC to point to the following
+-   instruction. This is what the handler in libgcc expects.  */
++/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC
++   before the faulting instruction, so we don't need to do anything
++   here.  */
++
++#define MAKE_THROW_FRAME(_exception)
+ 
+-#define MAKE_THROW_FRAME(_exception)					\
+-do									\
+-  {									\
+-    _sc->regs->nip += 4;						\
+-  }									\
+-while (0)
+-  
+ /* For an explanation why we cannot simply use sigaction to
+    install the handlers, see i386-signal.h.  */
+ 
+--- libstdc++-v3/libsupc++/eh_personality.cc.jj	2003-06-11 15:08:13.000000000 +0200
++++ libstdc++-v3/libsupc++/eh_personality.cc	2006-04-25 15:33:37.000000000 +0200
+@@ -201,6 +201,7 @@ PERSONALITY_FUNCTION (int version,
+   _Unwind_Ptr landing_pad, ip;
+   int handler_switch_value;
+   void *thrown_ptr = xh + 1;
++  int ip_before_insn = 0;
+ 
+   // Interface version check.
+   if (version != 1)
+@@ -227,7 +228,9 @@ PERSONALITY_FUNCTION (int version,
+   // Parse the LSDA header.
+   p = parse_lsda_header (context, language_specific_data, &info);
+   info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
+-  ip = _Unwind_GetIP (context) - 1;
++  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
++  if (! ip_before_insn)
++    --ip;
+   landing_pad = 0;
+   action_record = 0;
+   handler_switch_value = 0;
+--- gcc/libgcc-std.ver.jj	2004-02-28 12:16:53.000000000 +0100
++++ gcc/libgcc-std.ver	2006-04-25 15:33:37.000000000 +0200
+@@ -210,3 +210,8 @@ GCC_3.4 {
+   __paritydi2
+   __parityti2
+ }
++
++%inherit GCC_4.2.0 GCC_3.4
++GCC_4.2.0 {
++  _Unwind_GetIPInfo
++}
+--- gcc/unwind-c.c.jj	2003-06-11 15:08:12.000000000 +0200
++++ gcc/unwind-c.c	2006-04-25 15:33:37.000000000 +0200
+@@ -93,6 +93,7 @@ PERSONALITY_FUNCTION (int version,
+   lsda_header_info info;
+   const unsigned char *language_specific_data, *p, *action_record;
+   _Unwind_Ptr landing_pad, ip;
++  int ip_before_insn = 0;
+ 
+   if (version != 1)
+     return _URC_FATAL_PHASE1_ERROR;
+@@ -110,7 +111,9 @@ PERSONALITY_FUNCTION (int version,
+ 
+   /* Parse the LSDA header.  */
+   p = parse_lsda_header (context, language_specific_data, &info);
+-  ip = _Unwind_GetIP (context) - 1;
++  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
++  if (! ip_before_insn)
++    --ip;
+   landing_pad = 0;
+ 
+ #ifdef __USING_SJLJ_EXCEPTIONS__
+--- gcc/config/rs6000/linux.h.jj	2004-02-28 12:27:45.000000000 +0100
++++ gcc/config/rs6000/linux.h	2006-04-25 15:36:47.000000000 +0200
+@@ -171,6 +171,7 @@ enum { SIGNAL_FRAMESIZE = 64 };
+     (FS)->regs.reg[CR0_REGNO].loc.offset 				\
+       = (long)&(sc_->regs->nip) - new_cfa_;				\
+     (FS)->retaddr_column = CR0_REGNO;					\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ 
+--- gcc/config/rs6000/linux64.h.jj	2004-10-29 09:35:44.000000000 +0200
++++ gcc/config/rs6000/linux64.h	2006-04-25 15:37:14.000000000 +0200
+@@ -656,6 +656,7 @@ enum { SIGNAL_FRAMESIZE = 64 };
+     (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset 			\
+       = (long)&(sc_->regs->nip) - new_cfa_;				\
+     (FS)->retaddr_column = ARG_POINTER_REGNUM;				\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ 
+@@ -720,6 +721,7 @@ enum { SIGNAL_FRAMESIZE = 64 };
+     (FS)->regs.reg[CR0_REGNO].loc.offset 				\
+       = (long)&(sc_->regs->nip) - new_cfa_;				\
+     (FS)->retaddr_column = CR0_REGNO;					\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ 
+--- gcc/config/s390/linux.h.jj	2003-10-31 11:36:50.000000000 +0100
++++ gcc/config/s390/linux.h	2006-04-25 15:33:41.000000000 +0200
+@@ -339,6 +339,7 @@ do {                                    
+       } __attribute__ ((__aligned__ (8))) sigregs_;			\
+ 									\
+     sigregs_ *regs_;							\
++    int *signo_ = NULL;							\
+ 									\
+     /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */		\
+     if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173))		\
+@@ -359,6 +360,7 @@ do {                                    
+ 	  } *uc_ = (CONTEXT)->cfa + 8 + 128;				\
+ 									\
+ 	regs_ = &uc_->uc_mcontext;					\
++	signo_ = (CONTEXT)->cfa + sizeof(long);				\
+       }									\
+ 									\
+     /* Old-style RT frame and all non-RT frames:			\
+@@ -367,6 +369,11 @@ do {                                    
+     else								\
+       {									\
+ 	regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8);			\
++	/* Recent kernels store the signal number immediately after	\
++	   the sigregs; old kernels have the return trampoline at	\
++	   this location.  */						\
++	if ((void *)(regs_ + 1) != (CONTEXT)->ra)			\
++	  signo_ = (int *)(regs_ + 1);					\
+       }									\
+       									\
+     new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32;			\
+@@ -393,6 +400,12 @@ do {                                    
+     (FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_;	\
+     (FS)->retaddr_column = 32;						\
+ 									\
++    /* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr		\
++       after the faulting instruction rather than before it.		\
++       Don't set FS->signal_frame in that case.  */			\
++    if (!signo_ || (*signo_ != 4 && *signo_ != 5 && *signo_ != 8))	\
++      (FS)->signal_frame = 1;						\
++									\
+     goto SUCCESS;							\
+   } while (0)
+ 
+--- gcc/config/i386/linux.h.jj	2003-06-11 14:56:49.000000000 +0200
++++ gcc/config/i386/linux.h	2006-04-25 15:33:41.000000000 +0200
+@@ -280,6 +280,7 @@ Boston, MA 02111-1307, USA.  */
+     (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
+     (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_;		\
+     (FS)->retaddr_column = 8;						\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ #endif /* ifndef inhibit_libc  */
+--- gcc/config/i386/linux64.h.jj	2003-06-11 14:56:49.000000000 +0200
++++ gcc/config/i386/linux64.h	2006-04-25 15:33:41.000000000 +0200
+@@ -135,6 +135,7 @@ Boston, MA 02111-1307, USA.  */
+     (FS)->regs.reg[16].how = REG_SAVED_OFFSET;				\
+     (FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_;		\
+     (FS)->retaddr_column = 16;						\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ #else /* ifdef __x86_64__  */
+@@ -189,6 +190,7 @@ Boston, MA 02111-1307, USA.  */
+     (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
+     (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_;		\
+     (FS)->retaddr_column = 8;						\
++    (FS)->signal_frame = 1;						\
+     goto SUCCESS;							\
+   } while (0)
+ #endif /* ifdef __x86_64__  */
+--- gcc/config/ia64/unwind-ia64.c.jj	2004-07-01 12:49:33.000000000 +0200
++++ gcc/config/ia64/unwind-ia64.c	2006-04-25 15:33:41.000000000 +0200
+@@ -1700,6 +1700,13 @@ _Unwind_GetIP (struct _Unwind_Context *c
+   return context->rp;
+ }
+ 
++inline _Unwind_Ptr
++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
++{
++  *ip_before_insn = 0;
++  return context->rp;
++}
++
+ /* Overwrite the return address for CONTEXT with VAL.  */
+ 
+ inline void
+--- gcc/unwind-sjlj.c.jj	2003-06-11 15:12:42.000000000 +0200
++++ gcc/unwind-sjlj.c	2006-04-25 15:33:44.000000000 +0200
+@@ -197,6 +197,13 @@ _Unwind_GetIP (struct _Unwind_Context *c
+   return context->fc->call_site + 1;
+ }
+ 
++_Unwind_Ptr
++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
++{
++  *ip_before_insn = 0;
++  return context->fc->call_site + 1;
++}
++
+ /* Set the return landing pad index in CONTEXT.  */
+ 
+ void
+--- gcc/unwind.h.jj	2003-09-04 11:16:10.000000000 +0200
++++ gcc/unwind.h	2006-04-25 15:33:44.000000000 +0200
+@@ -136,6 +136,7 @@ extern _Unwind_Word _Unwind_GetGR (struc
+ extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
+ 
+ extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
++extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
+ extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+ 
+ /* @@@ Retrieve the CFA of the given context.  */
+--- gcc/unwind-dw2.c.jj	2003-07-16 13:38:32.000000000 +0200
++++ gcc/unwind-dw2.c	2006-04-25 15:33:44.000000000 +0200
+@@ -62,6 +62,7 @@ struct _Unwind_Context
+   void *lsda;
+   struct dwarf_eh_bases bases;
+   _Unwind_Word args_size;
++  char signal_frame;
+ };
+ 
+ /* Byte size of every register managed by these routines.  */
+@@ -117,6 +118,7 @@ typedef struct
+   unsigned char fde_encoding;
+   unsigned char lsda_encoding;
+   unsigned char saw_z;
++  unsigned char signal_frame;
+   void *eh_ptr;
+ } _Unwind_FrameState;
+ 
+@@ -193,6 +195,16 @@ _Unwind_GetIP (struct _Unwind_Context *c
+   return (_Unwind_Ptr) context->ra;
+ }
+ 
++/* Retrieve the return address and flag whether that IP is before
++   or after first not yet fully executed instruction.  */
++
++inline _Unwind_Ptr
++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
++{
++  *ip_before_insn = context->signal_frame != 0;
++  return (_Unwind_Ptr) context->ra;
++}
++
+ /* Overwrite the return address for CONTEXT with VAL.  */
+ 
+ inline void
+@@ -304,6 +316,13 @@ extract_cie_info (struct dwarf_cie *cie,
+ 	  aug += 1;
+ 	}
+ 
++      /* "S" indicates a signal frame.  */
++      else if (aug[0] == 'S')
++	{
++	  fs->signal_frame = 1;
++	  aug += 1;
++	}
++
+       /* Otherwise we have an unknown augmentation string.
+ 	 Bail unless we saw a 'z' prefix.  */
+       else
+@@ -736,8 +755,10 @@ execute_cfa_program (const unsigned char
+      a different stack configuration that we are not interested in.  We
+      assume that the call itself is unwind info-neutral; if not, or if
+      there are delay instructions that adjust the stack, these must be
+-     reflected at the point immediately before the call insn.  */
+-  while (insn_ptr < insn_end && fs->pc < context->ra)
++     reflected at the point immediately before the call insn.
++     In signal frames, return address is after last completed instruction,
++     so we add 1 to return address to make the comparison <=.  */
++  while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
+     {
+       unsigned char insn = *insn_ptr++;
+       _Unwind_Word reg, utmp;
+@@ -927,7 +948,8 @@ uw_frame_state_for (struct _Unwind_Conte
+   context->args_size = 0;
+   context->lsda = 0;
+ 
+-  fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
++  fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
++			  &context->bases);
+   if (fde == NULL)
+     {
+       /* Couldn't find frame unwind info for this function.  Try a
+@@ -1265,6 +1287,8 @@ uw_update_context_1 (struct _Unwind_Cont
+ 	break;
+       }
+ 
++  context->signal_frame = fs->signal_frame;
++
+   MD_FROB_UPDATE_CONTEXT (context, fs);
+ }
+ 
diff --git a/SOURCES/gcc32-pr3581.patch b/SOURCES/gcc32-pr3581.patch
new file mode 100644
index 0000000..0f704dd
--- /dev/null
+++ b/SOURCES/gcc32-pr3581.patch
@@ -0,0 +1,755 @@
+2002-04-26  Richard Henderson  <rth@redhat.com>
+
+	PR c/3581
+	* c-common.c (fix_string_type): Split out of ...
+	(combine_strings): ... here.  Take a varray, not a tree list.
+	(c_expand_builtin_printf): Use fix_string_type.
+	* c-common.h: Update decls.
+	* c-parse.in (string): Remove.  Update all uses to use STRING
+	instead, and not call combine_strings.
+	(yylexstring): New.
+	(_yylex): Use it.
+	* c-typeck.c (simple_asm_stmt): Don't call combine_strings.
+	(build_asm_stmt): Likewise.
+	* objc/objc-act.c (my_build_string): Use fix_string_type.
+	(build_objc_string_object): Build varray for combine_strings.
+cp/
+	* parse.y (string): Remove.  Update all uses to use STRING
+	instead, and not call combine_strings.
+	* rtti.c (tinfo_name): Use fix_string_type.
+	* semantics.c (finish_asm_stmt): Don't call combine_strings.
+	* spew.c (yylexstring): New.
+	(read_token): Use it.
+testsuite/
+	* g++.dg/parse/concat1.C: New test.
+	* gcc.dg/concat2.c: New test.
+
+--- gcc/objc/objc-act.c.jj	2002-09-24 15:08:15.000000000 +0200
++++ gcc/objc/objc-act.c	2004-10-05 16:08:18.744519118 +0200
+@@ -1207,21 +1207,7 @@ my_build_string (len, str)
+      int len;
+      const char *str;
+ {
+-  int wide_flag = 0;
+-  tree a_string = build_string (len, str);
+-
+-  /* Some code from combine_strings, which is local to c-parse.y.  */
+-  if (TREE_TYPE (a_string) == int_array_type_node)
+-    wide_flag = 1;
+-
+-  TREE_TYPE (a_string)
+-    = build_array_type (wide_flag ? integer_type_node : char_type_node,
+-			build_index_type (build_int_2 (len - 1, 0)));
+-
+-  TREE_CONSTANT (a_string) = 1;	/* Puts string in the readonly segment */
+-  TREE_STATIC (a_string) = 1;
+-
+-  return a_string;
++  return fix_string_type (build_string (len, str));
+ }
+ 
+ /* Given a chain of STRING_CST's, build a static instance of
+@@ -1247,7 +1233,23 @@ build_objc_string_object (strings)
+ 
+   add_class_reference (constant_string_id);
+ 
+-  string = combine_strings (strings);
++  if (TREE_CHAIN (strings))
++    {
++      varray_type vstrings;
++      VARRAY_TREE_INIT (vstrings, 32, "strings");
++
++      for (; strings ; strings = TREE_CHAIN (strings))
++	VARRAY_PUSH_TREE (vstrings, strings);
++
++      string = combine_strings (vstrings);
++
++      VARRAY_FREE (vstrings);
++    }
++  else
++    string = strings;
++
++  string = fix_string_type (string);
++
+   TREE_SET_CODE (string, STRING_CST);
+   length = TREE_STRING_LENGTH (string) - 1;
+ 
+--- gcc/c-common.h.jj	2003-09-16 16:57:44.000000000 +0200
++++ gcc/c-common.h	2004-10-05 16:08:18.669532451 +0200
+@@ -524,8 +524,9 @@ extern void c_finish_else               
+ extern void c_expand_end_cond			PARAMS ((void));
+ /* Validate the expression after `case' and apply default promotions.  */
+ extern tree check_case_value			PARAMS ((tree));
+-/* Concatenate a list of STRING_CST nodes into one STRING_CST.  */
+-extern tree combine_strings			PARAMS ((tree));
++extern tree fix_string_type			PARAMS ((tree));
++struct varray_head_tag;
++extern tree combine_strings		PARAMS ((struct varray_head_tag *));
+ extern void constant_expression_warning		PARAMS ((tree));
+ extern tree convert_and_check			PARAMS ((tree, tree));
+ extern void overflow_warning			PARAMS ((tree));
+--- gcc/cp/rtti.c.jj	2002-12-08 21:43:27.000000000 +0100
++++ gcc/cp/rtti.c	2004-10-05 16:08:18.721523207 +0200
+@@ -298,7 +298,7 @@ tinfo_name (type)
+   tree name_string;
+ 
+   name = mangle_type_string (type);
+-  name_string = combine_strings (build_string (strlen (name) + 1, name));
++  name_string = fix_string_type (build_string (strlen (name) + 1, name));
+   return name_string;
+ }
+ 
+--- gcc/cp/semantics.c.jj	2003-03-28 22:03:02.000000000 +0100
++++ gcc/cp/semantics.c	2004-10-05 16:08:18.723522851 +0200
+@@ -879,9 +879,6 @@ finish_asm_stmt (cv_qualifier, string, o
+   tree r;
+   tree t;
+ 
+-  if (TREE_CHAIN (string))
+-    string = combine_strings (string);
+-
+   if (cv_qualifier != NULL_TREE
+       && cv_qualifier != ridpointers[(int) RID_VOLATILE])
+     {
+--- gcc/cp/parse.y.jj	2003-01-17 18:33:10.000000000 +0100
++++ gcc/cp/parse.y	2004-10-05 16:08:18.717523918 +0200
+@@ -349,7 +349,7 @@ cp_parse_init ()
+ %type <ttype> PFUNCNAME maybe_identifier
+ %type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME
+ %type <ttype> expr_no_commas expr_no_comma_rangle
+-%type <ttype> cast_expr unary_expr primary string STRING
++%type <ttype> cast_expr unary_expr primary STRING
+ %type <ttype> reserved_declspecs boolean.literal
+ %type <ttype> reserved_typespecquals
+ %type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
+@@ -514,9 +514,8 @@ extdef:
+ 		{ do_pending_inlines (); }
+ 	| template_def
+ 		{ do_pending_inlines (); }
+-	| asm_keyword '(' string ')' ';'
+-		{ if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
+-		  assemble_asm ($3); }
++	| asm_keyword '(' STRING ')' ';'
++		{ assemble_asm ($3); }
+ 	| extern_lang_string '{' extdefs_opt '}'
+ 		{ pop_lang_context (); }
+ 	| extern_lang_string .hush_warning fndef .warning_ok eat_saved_input
+@@ -1587,10 +1586,10 @@ primary:
+ 		}		
+ 	| CONSTANT
+ 	| boolean.literal
+-	| string
++	| STRING
+ 		{
+-		  $$ = combine_strings ($$);
+-		  /* combine_strings doesn't set up TYPE_MAIN_VARIANT of
++		  $$ = fix_string_type ($$);
++		  /* fix_string_type doesn't set up TYPE_MAIN_VARIANT of
+ 		     a const array the way we want, so fix it.  */
+ 		  if (flag_const_strings)
+ 		    TREE_TYPE ($$) = build_cplus_array_type
+@@ -1791,13 +1790,6 @@ boolean.literal:
+ 		{ $$ = boolean_false_node; }
+ 	;
+ 
+-/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
+-string:
+-	  STRING
+-	| string STRING
+-		{ $$ = chainon ($$, $2); }
+-	;
+-
+ nodecls:
+ 	  /* empty */
+ 		{
+@@ -2091,8 +2083,8 @@ nomods_initdecls:
+ maybeasm:
+ 	  /* empty */
+ 		{ $$ = NULL_TREE; }
+-	| asm_keyword '(' string ')'
+-		{ if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; }
++	| asm_keyword '(' STRING ')'
++		{ $$ = $3; }
+ 	;
+ 
+ initdcl:
+@@ -3489,27 +3481,27 @@ simple_stmt:
+                 { $$ = finish_return_stmt (NULL_TREE); }
+ 	| RETURN_KEYWORD expr ';'
+                 { $$ = finish_return_stmt ($2); }
+-	| asm_keyword maybe_cv_qualifier '(' string ')' ';'
++	| asm_keyword maybe_cv_qualifier '(' STRING ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE,
+ 					NULL_TREE);
+ 		  ASM_INPUT_P ($$) = 1; }
+ 	/* This is the case with just output operands.  */
+-	| asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';'
++	| asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
+ 	/* This is the case with input operands as well.  */
+-	| asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
++	| asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
+ 	  asm_operands ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
+-	| asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';'
++	| asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); }
+ 	/* This is the case with clobbered registers as well.  */
+-	| asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
++	| asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
+ 	  asm_operands ':' asm_clobbers ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, $6, $8, $10); }
+-	| asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':'
++	| asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ':'
+ 	  asm_clobbers ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); }
+-	| asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE
++	| asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands SCOPE
+ 	  asm_clobbers ')' ';'
+ 		{ $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); }
+ 	| GOTO '*' expr ';'
+@@ -3670,10 +3662,10 @@ asm_operand:
+ 	;
+ 
+ asm_clobbers:
+-	  string
+-		{ $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE);}
+-	| asm_clobbers ',' string
+-		{ $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
++	  STRING
++		{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE);}
++	| asm_clobbers ',' STRING
++		{ $$ = tree_cons (NULL_TREE, $3, $1); }
+ 	;
+ 
+ /* This is what appears inside the parens in a function declarator.
+--- gcc/cp/spew.c.jj	2002-11-09 18:39:59.000000000 +0100
++++ gcc/cp/spew.c	2004-10-05 16:08:18.725522496 +0200
+@@ -102,6 +102,7 @@ static SPEW_INLINE int identifier_type P
+ static void scan_tokens PARAMS ((int));
+ static void feed_defarg PARAMS ((tree));
+ static void finish_defarg PARAMS ((void));
++static void yylexstring PARAMS ((struct token *));
+ static int read_token PARAMS ((struct token *));
+ 
+ static SPEW_INLINE int num_tokens PARAMS ((void));
+@@ -244,6 +245,43 @@ read_process_identifier (pyylval)
+   return IDENTIFIER;
+ }
+ 
++/* Concatenate strings before returning them to the parser.  This isn't quite
++   as good as having it done in the lexer, but it's better than nothing.  */
++
++static void
++yylexstring (t)
++     struct token *t;
++{
++  enum cpp_ttype next_type;
++  tree next;
++
++  next_type = c_lex (&next);
++  if (next_type == CPP_STRING || next_type == CPP_WSTRING)
++    {
++      varray_type strings;
++
++      VARRAY_TREE_INIT (strings, 32, "strings");
++      VARRAY_PUSH_TREE (strings, t->yylval.ttype);
++
++      do
++	{
++	  VARRAY_PUSH_TREE (strings, next);
++	  next_type = c_lex (&next);
++	}
++      while (next_type == CPP_STRING || next_type == CPP_WSTRING);
++
++      t->yylval.ttype = combine_strings (strings);
++      last_token_id = t->yylval.ttype;
++
++      VARRAY_FREE (strings);
++    }
++
++  /* We will have always read one token too many.  */
++  _cpp_backup_tokens (parse_in, 1);
++
++  t->yychar = STRING;
++}
++
+ /* Read the next token from the input file.  The token is written into
+    T, and its type number is returned.  */
+ static int
+@@ -338,7 +376,7 @@ read_token (t)
+ 
+     case CPP_STRING:
+     case CPP_WSTRING:
+-      t->yychar = STRING;
++      yylexstring (t);
+       break;
+ 
+     default:
+--- gcc/c-common.c.jj	2004-10-05 16:07:28.426465214 +0200
++++ gcc/c-common.c	2004-10-05 16:08:18.646536539 +0200
+@@ -554,106 +554,17 @@ fname_decl (rid, id)
+   return decl;
+ }
+ 
+-/* Given a chain of STRING_CST nodes,
+-   concatenate them into one STRING_CST
+-   and give it a suitable array-of-chars data type.  */
++/* Given a STRING_CST, give it a suitable array-of-chars data type.  */
+ 
+ tree
+-combine_strings (strings)
+-     tree strings;
++fix_string_type (value)
++     tree value;
+ {
+-  tree value, t;
+-  int length = 1;
+-  int wide_length = 0;
+-  int wide_flag = 0;
+-  int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
+-  int nchars;
++  const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
++  const int wide_flag = TREE_TYPE (value) == wchar_array_type_node;
+   const int nchars_max = flag_isoc99 ? 4095 : 509;
+-
+-  if (TREE_CHAIN (strings))
+-    {
+-      /* More than one in the chain, so concatenate.  */
+-      char *p, *q;
+-
+-      /* Don't include the \0 at the end of each substring,
+-	 except for the last one.
+-	 Count wide strings and ordinary strings separately.  */
+-      for (t = strings; t; t = TREE_CHAIN (t))
+-	{
+-	  if (TREE_TYPE (t) == wchar_array_type_node)
+-	    {
+-	      wide_length += (TREE_STRING_LENGTH (t) - wchar_bytes);
+-	      wide_flag = 1;
+-	    }
+-	  else
+-	    {
+-	      length += (TREE_STRING_LENGTH (t) - 1);
+-	      if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
+-		warning ("concatenation of string literals with __FUNCTION__ is deprecated"); 
+-	    }
+-	}
+-
+-      /* If anything is wide, the non-wides will be converted,
+-	 which makes them take more space.  */
+-      if (wide_flag)
+-	length = length * wchar_bytes + wide_length;
+-
+-      p = xmalloc (length);
+-
+-      /* Copy the individual strings into the new combined string.
+-	 If the combined string is wide, convert the chars to ints
+-	 for any individual strings that are not wide.  */
+-
+-      q = p;
+-      for (t = strings; t; t = TREE_CHAIN (t))
+-	{
+-	  int len = (TREE_STRING_LENGTH (t)
+-		     - ((TREE_TYPE (t) == wchar_array_type_node)
+-			? wchar_bytes : 1));
+-	  if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag)
+-	    {
+-	      memcpy (q, TREE_STRING_POINTER (t), len);
+-	      q += len;
+-	    }
+-	  else
+-	    {
+-	      int i, j;
+-	      for (i = 0; i < len; i++)
+-		{
+-		  if (BYTES_BIG_ENDIAN)
+-		    {
+-		      for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++)
+-			*q++ = 0;
+-		      *q++ = TREE_STRING_POINTER (t)[i];
+-		    }
+-		  else
+-		    {
+-		      *q++ = TREE_STRING_POINTER (t)[i];
+-		      for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++)
+-			*q++ = 0;
+-		    }
+-		}
+-	    }
+-	}
+-      if (wide_flag)
+-	{
+-	  int i;
+-	  for (i = 0; i < wchar_bytes; i++)
+-	    *q++ = 0;
+-	}
+-      else
+-	*q = 0;
+-
+-      value = build_string (length, p);
+-      free (p);
+-    }
+-  else
+-    {
+-      value = strings;
+-      length = TREE_STRING_LENGTH (value);
+-      if (TREE_TYPE (value) == wchar_array_type_node)
+-	wide_flag = 1;
+-    }
++  int length = TREE_STRING_LENGTH (value);
++  int nchars;
+ 
+   /* Compute the number of elements, for the array type.  */
+   nchars = wide_flag ? length / wchar_bytes : length;
+@@ -686,6 +597,111 @@ combine_strings (strings)
+   TREE_STATIC (value) = 1;
+   return value;
+ }
++
++/* Given a VARRAY of STRING_CST nodes, concatenate them into one
++   STRING_CST.  */
++
++tree
++combine_strings (strings)
++     varray_type strings;
++{
++  const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
++  const int nstrings = VARRAY_ACTIVE_SIZE (strings);
++  tree value, t;
++  int length = 1;
++  int wide_length = 0;
++  int wide_flag = 0;
++  int i;
++  char *p, *q;
++
++  /* Don't include the \0 at the end of each substring.  Count wide
++     strings and ordinary strings separately.  */
++  for (i = 0; i < nstrings; ++i)
++    {
++      t = VARRAY_TREE (strings, i);
++
++      if (TREE_TYPE (t) == wchar_array_type_node)
++	{
++	  wide_length += TREE_STRING_LENGTH (t) - wchar_bytes;
++	  wide_flag = 1;
++	}
++      else
++	{
++	  length += (TREE_STRING_LENGTH (t) - 1);
++	  if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
++	    warning ("concatenation of string literals with __FUNCTION__ is deprecated"); 
++	}
++    }
++
++  /* If anything is wide, the non-wides will be converted,
++     which makes them take more space.  */
++  if (wide_flag)
++    length = length * wchar_bytes + wide_length;
++
++  p = xmalloc (length);
++
++  /* Copy the individual strings into the new combined string.
++     If the combined string is wide, convert the chars to ints
++     for any individual strings that are not wide.  */
++
++  q = p;
++  for (i = 0; i < nstrings; ++i)
++    {
++      int len, this_wide;
++
++      t = VARRAY_TREE (strings, i);
++      this_wide = TREE_TYPE (t) == wchar_array_type_node;
++      len = TREE_STRING_LENGTH (t) - (this_wide ? wchar_bytes : 1);
++      if (this_wide == wide_flag)
++	{
++	  memcpy (q, TREE_STRING_POINTER (t), len);
++	  q += len;
++	}
++      else
++	{
++	  const int nzeros = (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - 1;
++	  int j, k;
++
++	  if (BYTES_BIG_ENDIAN)
++	    {
++	      for (k = 0; k < len; k++)
++		{
++		  for (j = 0; j < nzeros; j++)
++		    *q++ = 0;
++		  *q++ = TREE_STRING_POINTER (t)[k];
++		}
++	    }
++	  else
++	    {
++	      for (k = 0; k < len; k++)
++		{
++		  *q++ = TREE_STRING_POINTER (t)[k];
++		  for (j = 0; j < nzeros; j++)
++		    *q++ = 0;
++		}
++	    }
++	}
++    }
++
++  /* Nul terminate the string.  */
++  if (wide_flag)
++    {
++      for (i = 0; i < wchar_bytes; i++)
++	*q++ = 0;
++    }
++  else
++    *q = 0;
++
++  value = build_string (length, p);
++  free (p);
++
++  if (wide_flag)
++    TREE_TYPE (value) = wchar_array_type_node;
++  else
++    TREE_TYPE (value) = char_array_type_node;
++
++  return value;
++}
+ 
+ static int is_valid_printf_arglist PARAMS ((tree));
+ static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier));
+@@ -4062,7 +4078,7 @@ c_expand_builtin_printf (arglist, target
+ 	  memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1);
+ 	  newstr[newlen - 1] = 0;
+ 	  
+-	  arglist = combine_strings (build_string (newlen, newstr));
++	  arglist = fix_string_type (build_string (newlen, newstr));
+ 	  arglist = build_tree_list (NULL_TREE, arglist);
+ 	  fn = fn_puts;
+ 	}
+--- gcc/testsuite/gcc.dg/concat2.c.jj	2004-10-05 16:08:18.746518763 +0200
++++ gcc/testsuite/gcc.dg/concat2.c	2004-10-05 16:08:18.746518763 +0200
+@@ -0,0 +1,16 @@
++/* PR c/3581 */
++/* { dg-do compile } */
++/* { dg-options "" } */
++
++/* Intended as a compile-time test for string literal concatenation.
++   The fact that the string isn't actually used in the resulting program
++   should allow this to compile for any target.  */
++
++#define e0	"a"
++#define e1	e0 e0 e0 e0 e0 e0 e0 e0 e0 e0
++#define e2	e1 e1 e1 e1 e1 e1 e1 e1 e1 e1
++#define e3	e2 e2 e2 e2 e2 e2 e2 e2 e2 e2
++#define e4	e3 e3 e3 e3 e3 e3 e3 e3 e3 e3
++#define e5	e4 e4 e4 e4 e4 e4 e4 e4 e4 e4
++
++void foo() { (void)(e5); }
+--- gcc/testsuite/g++.dg/parse/concat1.C.jj	2004-10-05 16:08:18.745518941 +0200
++++ gcc/testsuite/g++.dg/parse/concat1.C	2004-10-05 16:08:18.745518941 +0200
+@@ -0,0 +1,15 @@
++/* PR c/3581 */
++/* { dg-do compile } */
++
++/* Intended as a compile-time test for string literal concatenation.
++   The fact that the string isn't actually used in the resulting program
++   should allow this to compile for any target.  */
++
++#define e0	"a"
++#define e1	e0 e0 e0 e0 e0 e0 e0 e0 e0 e0
++#define e2	e1 e1 e1 e1 e1 e1 e1 e1 e1 e1
++#define e3	e2 e2 e2 e2 e2 e2 e2 e2 e2 e2
++#define e4	e3 e3 e3 e3 e3 e3 e3 e3 e3 e3
++#define e5	e4 e4 e4 e4 e4 e4 e4 e4 e4 e4
++
++void foo() { (void)(e5); }
+--- gcc/c-parse.in.jj	2003-08-02 01:21:40.000000000 +0200
++++ gcc/c-parse.in	2004-10-05 16:08:18.682530140 +0200
+@@ -148,7 +148,7 @@ end ifobjc
+ %type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
+ 
+ %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
+-%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
++%type <ttype> expr_no_commas cast_expr unary_expr primary STRING
+ %type <ttype> declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea
+ %type <ttype> declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea
+ %type <ttype> declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea
+@@ -296,6 +296,7 @@ end ifc
+ static void yyprint	  PARAMS ((FILE *, int, YYSTYPE));
+ static void yyerror	  PARAMS ((const char *));
+ static int yylexname	  PARAMS ((void));
++static int yylexstring	  PARAMS ((void));
+ static inline int _yylex  PARAMS ((void));
+ static int  yylex	  PARAMS ((void));
+ static void init_reswords PARAMS ((void));
+@@ -623,8 +624,8 @@ primary:
+ 		  $$ = build_external_ref ($1, yychar == '(');
+ 		}
+ 	| CONSTANT
+-	| string
+-		{ $$ = combine_strings ($1); }
++	| STRING
++		{ $$ = fix_string_type ($$); }
+ 	| VAR_FUNC_NAME
+ 		{ $$ = fname_decl (C_RID_CODE ($$), $$); }
+ 	| '(' typename ')' '{' 
+@@ -735,29 +736,6 @@ ifobjc
+ end ifobjc
+ 	;
+ 
+-/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
+-string:
+-	  STRING
+-	| string STRING
+-		{
+-ifc
+-                  static int last_lineno = 0;
+-                  static const char *last_input_filename = 0;
+-end ifc
+-                  $$ = chainon ($1, $2);
+-ifc
+-		  if (warn_traditional && !in_system_header
+-		      && (lineno != last_lineno || !last_input_filename ||
+-			  strcmp (last_input_filename, input_filename)))
+-		    {
+-		      warning ("traditional C rejects string concatenation");
+-		      last_lineno = lineno;
+-		      last_input_filename = input_filename;
+-		    }
+-end ifc
+-		}
+-	;
+-
+ ifobjc
+ /* Produces an STRING_CST with perhaps more STRING_CSTs chained
+    onto it, which is to be read as an ObjC string object.  */
+@@ -1398,10 +1376,8 @@ notype_initdecls:
+ maybeasm:
+ 	  /* empty */
+ 		{ $$ = NULL_TREE; }
+-	| ASM_KEYWORD '(' string ')'
+-		{ if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
+-		  $$ = $3;
+-		}
++	| ASM_KEYWORD '(' STRING ')'
++		{ $$ = $3; }
+ 	;
+ 
+ initdcl:
+@@ -2482,10 +2458,10 @@ asm_operand:
+ 	;
+ 
+ asm_clobbers:
+-	  string
+-		{ $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
+-	| asm_clobbers ',' string
+-		{ $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
++	  STRING
++		{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
++	| asm_clobbers ',' STRING
++		{ $$ = tree_cons (NULL_TREE, $3, $1); }
+ 	;
+ 
+ /* This is what appears inside the parens in a function declarator.
+@@ -3683,6 +3659,59 @@ end ifobjc
+   return IDENTIFIER;
+ }
+ 
++/* Concatenate strings before returning them to the parser.  This isn't quite
++   as good as having it done in the lexer, but it's better than nothing.  */
++
++static int
++yylexstring ()
++{
++  enum cpp_ttype next_type;
++  tree orig = yylval.ttype;
++
++  next_type = c_lex (&yylval.ttype);
++  if (next_type == CPP_STRING
++      || next_type == CPP_WSTRING
++      || (next_type == CPP_NAME && yylexname () == STRING))
++    {
++      varray_type strings;
++
++ifc
++      static int last_lineno = 0;
++      static const char *last_input_filename = 0;
++      if (warn_traditional && !in_system_header
++	  && (lineno != last_lineno || !last_input_filename ||
++	      strcmp (last_input_filename, input_filename)))
++	{
++	  warning ("traditional C rejects string concatenation");
++	  last_lineno = lineno;
++	  last_input_filename = input_filename;
++	}
++end ifc
++
++      VARRAY_TREE_INIT (strings, 32, "strings");
++      VARRAY_PUSH_TREE (strings, orig);
++
++      do
++	{
++	  VARRAY_PUSH_TREE (strings, yylval.ttype);
++	  next_type = c_lex (&yylval.ttype);
++	}
++      while (next_type == CPP_STRING
++	     || next_type == CPP_WSTRING
++	     || (next_type == CPP_NAME && yylexname () == STRING));
++
++      yylval.ttype = combine_strings (strings);
++
++      VARRAY_FREE (strings);
++    }
++  else
++    yylval.ttype = orig;
++
++  /* We will have always read one token too many.  */
++  _cpp_backup_tokens (parse_in, 1);
++
++  return STRING;
++}
+ 
+ static inline int
+ _yylex ()
+@@ -3749,7 +3778,13 @@ _yylex ()
+       return 0;
+ 
+     case CPP_NAME:
+-      return yylexname ();
++      {
++	int ret = yylexname ();
++	if (ret == STRING)
++	  return yylexstring ();
++	else
++	  return ret;
++      }
+ 
+     case CPP_NUMBER:
+     case CPP_CHAR:
+@@ -3758,7 +3793,7 @@ _yylex ()
+ 
+     case CPP_STRING:
+     case CPP_WSTRING:
+-      return STRING;
++      return yylexstring ();
+       
+       /* This token is Objective-C specific.  It gives the next token
+ 	 special significance.  */
+--- gcc/c-typeck.c.jj	2003-03-10 17:42:06.000000000 +0100
++++ gcc/c-typeck.c	2004-10-05 16:08:48.926153031 +0200
+@@ -6890,9 +6890,6 @@ simple_asm_stmt (expr)
+     {
+       tree stmt;
+ 
+-      if (TREE_CHAIN (expr))
+-	expr = combine_strings (expr);
+-
+       /* Simple asm statements are treated as volatile.  */
+       stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE],
+       				   expr, NULL_TREE, NULL_TREE, NULL_TREE));
+@@ -6917,8 +6914,6 @@ build_asm_stmt (cv_qualifier, string, ou
+ {
+   tree tail;
+ 
+-  if (TREE_CHAIN (string))
+-    string = combine_strings (string);
+   if (TREE_CODE (string) != STRING_CST)
+     {
+       error ("asm template is not a string constant");
diff --git a/SOURCES/gcc32-rh149250.patch b/SOURCES/gcc32-rh149250.patch
new file mode 100644
index 0000000..4ef4284
--- /dev/null
+++ b/SOURCES/gcc32-rh149250.patch
@@ -0,0 +1,59 @@
+2002-09-08  Jan Hubicka  <jh@suse.cz>
+
+	* loop.c (loop_givs_reduce):  Emit addition after.
+
+2005-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+	* g77.dg/20050719-1.f: New test.
+
+--- gcc/loop.c.jj	2003-10-06 12:15:37.000000000 +0200
++++ gcc/loop.c	2005-07-19 11:49:08.000000000 +0200
+@@ -4684,7 +4684,7 @@ loop_givs_reduce (loop, bl)
+ 	      rtx insert_before;
+ 
+ 	      if (! auto_inc_opt)
+-		insert_before = tv->insn;
++		insert_before = NEXT_INSN (tv->insn);
+ 	      else if (auto_inc_opt == 1)
+ 		insert_before = NEXT_INSN (v->insn);
+ 	      else
+--- gcc/testsuite/g77.dg/20050719-1.f.jj	2005-07-19 12:00:18.000000000 +0200
++++ gcc/testsuite/g77.dg/20050719-1.f	2005-07-19 12:01:31.000000000 +0200
+@@ -0,0 +1,37 @@
++C Test for a strength reduction bug.
++C { dg-do run }
++C { dg-options "-O2 -fno-automatic" }
++	SUBROUTINE FOO(D)
++	INTEGER A,B,C,D,E,I,J,K
++	DIMENSION A(5,5),B(5,5),C(5,5),D(5,5)
++	DO I=1,5
++	  DO J=1,5
++	    A(I,J)=J
++	    B(I,J)=1
++	  ENDDO
++	ENDDO
++	DO I=1,5
++	  DO J=1,5
++	    E=0
++	    DO K=1,5
++	      E=E+B(I,K)*A(K,J)
++	    ENDDO
++	    C(I,J)=E
++	  ENDDO
++	ENDDO
++	DO I=1,5
++	  DO J=1,5
++	    D(I,J)=C(I,J)
++	  ENDDO
++	ENDDO
++	END
++
++	INTEGER D,I,J
++	DIMENSION D(5,5)
++	CALL FOO(D)
++	DO I=1,5
++	  DO J=1,5
++	    IF (D(I,J).NE.5*J) CALL ABORT
++	  ENDDO
++	ENDDO
++	END
diff --git a/SOURCES/gcc32-rh156185.patch b/SOURCES/gcc32-rh156185.patch
new file mode 100644
index 0000000..87001a7
--- /dev/null
+++ b/SOURCES/gcc32-rh156185.patch
@@ -0,0 +1,51 @@
+2005-09-26  Alexandre Oliva  <aoliva@redhat.com>
+
+	2002-08-13  Mark Mitchell  <mark@codesourcery.com>
+	* decl.c (pushdecl_class_level): Honor requests to bind names to
+	OVERLOADs.
+
+2005-09-26  Alexandre Oliva  <aoliva@redhat.com>
+
+	* g++.dg/lookup/overload1.C: New.
+
+--- gcc/cp/decl.c.orig
++++ gcc/cp/decl.c
+@@ -4369,8 +4369,9 @@ pushdecl_class_level (x)
+   register tree name;
+ 
+   if (TREE_CODE (x) == OVERLOAD)
+-    x = OVL_CURRENT (x);
+-  name = DECL_NAME (x);
++    name = DECL_NAME (OVL_CURRENT (x));
++  else
++    name = DECL_NAME (x);
+ 
+   if (name)
+     {
+--- gcc/testsuite/g++.dg/lookup/overload1.C
++++ gcc/testsuite/g++.dg/lookup/overload1.C
+@@ -0,0 +1,24 @@
++// { dg-do compile }
++
++// This used to crash expanding the initializer, because instead of
++// pushing the OVERLOAD containing template and function decls, we'd
++// push only the first member of the overload list.  The code below is
++// from the bug report at
++// https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=156185
++
++struct C {
++  template< class N >
++  static C *newInstance() { return new N; };
++};
++
++typedef C*( *CreateFunc)();
++
++struct B {
++  B( CreateFunc _createf ){}
++};
++
++struct A : C {
++  static B b;
++};
++
++B A::b( newInstance<A> );
diff --git a/SOURCES/gcc32-rh156291.patch b/SOURCES/gcc32-rh156291.patch
new file mode 100644
index 0000000..d11f900
--- /dev/null
+++ b/SOURCES/gcc32-rh156291.patch
@@ -0,0 +1,29 @@
+2005-09-29  Alexandre Oliva  <aoliva@redhat.com>
+
+	* error.c (dump_type) <UNKNOWN_TYPE>: Print reworded message.
+
+	* g++.dg/overload/unknown1.C: New.
+
+--- gcc/cp/error.c.orig	2005-09-29 16:02:59.000000000 -0300
++++ gcc/cp/error.c	2005-09-29 16:03:13.000000000 -0300
+@@ -339,7 +339,7 @@
+   switch (TREE_CODE (t))
+     {
+     case UNKNOWN_TYPE:
+-      print_identifier (scratch_buffer, "<unknown type>");
++      print_identifier (scratch_buffer, "<unresolved overloaded function type>");
+       break;
+ 
+     case TREE_LIST:
+--- gcc/testsuite/g++.dg/overload/unknown1.C	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.dg/overload/unknown1.C	2005-09-29 16:03:13.000000000 -0300
+@@ -0,0 +1,9 @@
++// { dg-do compile }
++
++void foo(void);
++int foo(int);
++template <typename T> void bar(T f);
++
++void baz() {
++  bar(foo); // { dg-error "<unresolved overloaded function type>" }
++}
diff --git a/SOURCES/gcc32-rh173224.patch b/SOURCES/gcc32-rh173224.patch
new file mode 100644
index 0000000..523f1b5
--- /dev/null
+++ b/SOURCES/gcc32-rh173224.patch
@@ -0,0 +1,58 @@
+2005-01-09  Alexandre Oliva  <aoliva@redhat.com>
+
+	* config/i386/i386.md: Adjust sse conditional move patterns to
+	match both nonimm&reg and reg&nonimm in compare operands.
+
+2006-04-25  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.dg/20060425-1.c: New test.
+
+--- gcc/config/i386/i386.md	2005-10-24 18:18:40.000000000 -0200
++++ gcc/config/i386/i386.md	2006-01-09 16:16:06.000000000 -0200
+@@ -16815,25 +16815,30 @@
+ (define_split
+   [(set (match_operand 0 "register_operand" "")
+ 	(if_then_else (match_operator 1 "comparison_operator"
+-			[(match_operand 4 "register_operand" "")
++			[(match_operand 4 "nonimmediate_operand" "")
+ 			 (match_operand 5 "nonimmediate_operand" "")])
+ 		      (match_operand 2 "nonmemory_operand" "")
+ 		      (match_operand 3 "nonmemory_operand" "")))]
+   "SSE_REG_P (operands[0]) && reload_completed
++   && ((REG_P (operands[4]) && REGNO (operands[4]) == REGNO (operands[0]))
++       || (REG_P (operands[5]) && REGNO (operands[5]) == REGNO (operands[0])))
+    && (const0_operand (operands[2], GET_MODE (operands[0]))
+        || const0_operand (operands[3], GET_MODE (operands[0])))"
+-  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
++  [(set (match_dup 0) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
+    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
+ 					    (subreg:TI (match_dup 7) 0)))]
+ {
+   PUT_MODE (operands[1], GET_MODE (operands[0]));
+-  if (!sse_comparison_operator (operands[1], VOIDmode))
++  if (REGNO (operands[4]) != REGNO (operands[0])
++      || !sse_comparison_operator (operands[1], VOIDmode))
+     {
+       rtx tmp = operands[5];
+       operands[5] = operands[4];
+       operands[4] = tmp;
+       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
+     }
++  if (!sse_comparison_operator (operands[1], VOIDmode))
++    abort ();
+   if (const0_operand (operands[2], GET_MODE (operands[0])))
+     {
+       operands[7] = operands[3];
+--- gcc/testsuite/gcc.dg/20060425-1.c	2004-06-24 14:04:38.000000000 -0400
++++ gcc/testsuite/gcc.dg/20060425-1.c	2006-04-25 09:15:04.000000000 -0400
+@@ -0,0 +1,10 @@
++/* { dg-do compile } */
++/* { dg-options "-O2" } */
++
++double
++crashme (double v, double *p)
++{
++  if (v < 0. && *p == 1.)
++    v = 0.;
++  return v;
++}
diff --git a/SOURCES/gcc32-rh180778.patch b/SOURCES/gcc32-rh180778.patch
new file mode 100644
index 0000000..ae9feb6
--- /dev/null
+++ b/SOURCES/gcc32-rh180778.patch
@@ -0,0 +1,116 @@
+2005-08-31  Richard Henderson  <rth@redhat.com>
+
+	* expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Force subregs
+	into a pseudo before applying gen_lowpart.
+
+2005-08-30  Richard Henderson  <rth@redhat.com>
+
+	PR target/23630
+	* expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Use gen_lowpart
+	whenever the mode sizes match.
+
+2002-08-19  Geoffrey Keating  <geoffk@redhat.com>
+	    Steve Ellcey  <sje@cup.hp.com>
+
+	* machmode.h (SCALAR_INT_MODE_P): New macro to test for
+	scaler integer mode (MODE_INT or MODE_PARTIAL_INT).
+
+2006-02-22  Alexandre Oliva  <aoliva@redhat.com>
+
+	* gcc.dg/i386-mmx-3.c: New test.
+
+--- gcc/convert.c.orig	2003-08-01 20:24:42.000000000 -0300
++++ gcc/convert.c	2006-02-24 03:51:35.000000000 -0300
+@@ -398,7 +398,7 @@ convert_to_integer (type, expr)
+ 	  error ("can't convert between vector values of different size");
+ 	  return error_mark_node;
+ 	}
+-      return build1 (NOP_EXPR, type, expr);
++      return build1 (VIEW_CONVERT_EXPR, type, expr);
+ 
+     default:
+       error ("aggregate value used where an integer was expected");
+@@ -478,7 +478,7 @@ convert_to_vector (type, expr)
+ 	  error ("can't convert between vector values of different size");
+ 	  return error_mark_node;
+ 	}
+-      return build1 (NOP_EXPR, type, expr);
++      return build1 (VIEW_CONVERT_EXPR, type, expr);
+ 
+     default:
+       error ("can't convert value to a vector");
+--- gcc/expr.c.orig	2006-02-22 15:50:38.000000000 -0300
++++ gcc/expr.c	2006-02-24 04:49:59.000000000 -0300
+@@ -7641,16 +7641,28 @@ expand_expr (exp, target, tmode, modifie
+     case VIEW_CONVERT_EXPR:
+       op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
+ 
+-      /* If the input and output modes are both the same, we are done.
+-	 Otherwise, if neither mode is BLKmode and both are within a word, we
+-	 can use gen_lowpart.  If neither is true, make sure the operand is
+-	 in memory and convert the MEM to the new mode.  */
++      /* If the input and output modes are both the same, we are done.  */
+       if (TYPE_MODE (type) == GET_MODE (op0))
+ 	;
++      /* If neither mode is BLKmode, and both modes are the same size
++	 then we can use gen_lowpart.  */
+       else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
+-	       && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
+-	       && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
+-	op0 = gen_lowpart (TYPE_MODE (type), op0);
++	       && GET_MODE_SIZE (TYPE_MODE (type))
++	          == GET_MODE_SIZE (GET_MODE (op0)))
++	{
++	  if (GET_CODE (op0) == SUBREG)
++	    op0 = force_reg (GET_MODE (op0), op0);
++	  op0 = gen_lowpart (TYPE_MODE (type), op0);
++	}
++      /* If both modes are integral, then we can convert from one to the
++	 other.  */
++      else if (SCALAR_INT_MODE_P (GET_MODE (op0))
++	       && SCALAR_INT_MODE_P (TYPE_MODE (type)))
++	op0 = convert_modes (TYPE_MODE (type), GET_MODE (op0), op0,
++			     TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp,
++								     0))));
++      /* As a last resort, spill op0 to memory, and reload it in a
++	 different mode.  */
+       else if (GET_CODE (op0) != MEM)
+ 	{
+ 	  /* If the operand is not a MEM, force it into memory.  Since we
+--- gcc/machmode.h.orig	2002-02-19 07:13:31.000000000 -0300
++++ gcc/machmode.h	2006-02-24 04:20:47.000000000 -0300
+@@ -75,6 +75,11 @@ extern const enum mode_class mode_class[
+   (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT	\
+    || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
+ 
++/* Nonzero if MODE is a scalar integral mode.  */
++#define SCALAR_INT_MODE_P(MODE)			\
++  (GET_MODE_CLASS (MODE) == MODE_INT		\
++   || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
++
+ /* Get the size in bytes of an object of mode MODE.  */
+ 
+ extern const unsigned char mode_size[NUM_MACHINE_MODES];
+--- gcc/testsuite/gcc.dg/i386-mmx-3.c	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/gcc.dg/i386-mmx-3.c	2006-02-23 02:06:15.000000000 -0300
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
++/* { dg-options "-O -mmmx" } */
++
++#include <stdint.h>
++#include <mmintrin.h>
++
++void x(uint64_t *p_buffer)
++{
++    __m64 mm0, mm1;
++
++    mm0 = (__m64)(uint64_t)0;
++
++    /* This makes no sense whatsoever, it's just the result of
++       minimization of a large testcase.  */
++    mm1 = _mm_srli_pi16(mm0, 0);
++    mm1 = _mm_slli_pi16(mm1, 1);
++    mm0 = _mm_adds_pi16(mm0, mm1);
++
++    *p_buffer = (uint64_t)mm0;
++}
diff --git a/SOURCES/gcc32-rh181894.patch b/SOURCES/gcc32-rh181894.patch
new file mode 100644
index 0000000..6f1faef
--- /dev/null
+++ b/SOURCES/gcc32-rh181894.patch
@@ -0,0 +1,133 @@
+2006-08-09  Alexandre Oliva  <aoliva@redhat.com>
+
+	* function.c (do_warn_unused_parameter): Do not issue warnings
+	for declarations in system headers.
+
+2006-02-22  Alexandre Oliva  <aoliva@redhat.com>
+
+	Backport and tweak:
+	2004-05-06  Jan Hubicka  <jh@suse.cz>
+	PR c/15004
+	* function.c (do_warn_unused_parameter): Break out form ...
+	(expand_function_end): ... here.
+	* function.h (do_warn_unused_parameter): Declare.
+
+2006-02-22  Alexandre Oliva  <aoliva@redhat.com>
+
+	* decl2.c (finish_file): Issue warnings for unused parameters
+	of functions not expanded.
+
+	* g++.dg/Wunused-parm-1.C: New.
+
+--- gcc/cp/decl2.c.orig	2003-08-12 11:12:25.000000000 -0300
++++ gcc/cp/decl2.c	2006-08-09 16:59:09.000000000 -0300
+@@ -3551,6 +3551,17 @@ finish_file ()
+     } 
+   while (reconsider);
+ 
++  if (warn_unused_parameter)
++    for (i = 0; i < deferred_fns_used; ++i)
++      {
++	tree decl = VARRAY_TREE (deferred_fns, i);
++
++	/* Warn about unused parameters in functions we refrained from
++	   synthesizing.  */
++	if (!TREE_ASM_WRITTEN (decl))
++	  do_warn_unused_parameter (decl);
++      }
++
+   /* We give C linkage to static constructors and destructors.  */
+   push_lang_context (lang_name_c);
+ 
+--- gcc/function.c.orig	2003-10-31 08:42:15.000000000 -0200
++++ gcc/function.c	2006-08-10 00:28:06.000000000 -0300
+@@ -6808,6 +6808,27 @@ use_return_register ()
+   diddle_return_value (do_use_return_reg, NULL);
+ }
+ 
++/* Warn about unused parms if extra warnings were specified.  */
++/* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this
++   warning.  WARN_UNUSED_PARAMETER is negative when set by
++   -Wunused.  */
++void
++do_warn_unused_parameter (tree fn)
++{
++  if (warn_unused_parameter > 0
++      || (warn_unused_parameter < 0 && extra_warnings))
++    {
++      tree decl;
++
++      for (decl = DECL_ARGUMENTS (fn);
++	   decl; decl = TREE_CHAIN (decl))
++	if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
++	    && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)
++	    && ! DECL_IN_SYSTEM_HEADER (decl))
++	  warning_with_decl (decl, "unused parameter `%s'");
++    }
++}
++
+ /* Generate RTL for the end of the current function.
+    FILENAME and LINE are the current position in the source file.
+ 
+@@ -6907,21 +6928,8 @@ expand_function_end (filename, line, end
+ 	  }
+     }
+ 
+-  /* Warn about unused parms if extra warnings were specified.  */
+-  /* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this
+-     warning.  WARN_UNUSED_PARAMETER is negative when set by
+-     -Wunused.  */
+-  if (warn_unused_parameter > 0
+-      || (warn_unused_parameter < 0 && extra_warnings))
+-    {
+-      tree decl;
+-
+-      for (decl = DECL_ARGUMENTS (current_function_decl);
+-	   decl; decl = TREE_CHAIN (decl))
+-	if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
+-	    && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
+-	  warning_with_decl (decl, "unused parameter `%s'");
+-    }
++  if (warn_unused_parameter)
++    do_warn_unused_parameter (current_function_decl);
+ 
+   /* Delete handlers for nonlocal gotos if nothing uses them.  */
+   if (nonlocal_goto_handler_slots != 0
+--- gcc/function.h.orig	2003-06-11 09:56:49.000000000 -0300
++++ gcc/function.h	2006-08-09 16:59:09.000000000 -0300
+@@ -614,3 +614,5 @@ extern void init_virtual_regs		PARAMS ((
+ 
+ /* Called once, at initialization, to initialize function.c.  */
+ extern void init_function_once          PARAMS ((void));
++
++extern void do_warn_unused_parameter    PARAMS ((tree));
+--- gcc/testsuite/g++.dg/warn/Wunused-parm-1.C	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.dg/warn/Wunused-parm-1.C	2006-08-09 16:59:09.000000000 -0300
+@@ -0,0 +1,27 @@
++// Test whether we issue warnings for unused parameters, even for
++// inline functions that are not emitted (without optimization, we
++// always emit them).
++// { dg-do compile }
++// { dg-options "-Wunused-parameter -O" }
++
++static inline int foo(int var) { // { dg-warning "unused parameter" }
++  return 0;
++}
++
++static inline int foo2(int var) { // { dg-warning "unused parameter" }
++  return 0;
++}
++
++static inline int bar(int var) {
++  return var;
++}
++
++static inline int bar2(int var) {
++  return var;
++}
++
++int main() {
++  foo (1);
++  bar (2);
++  return 0;
++}
diff --git a/SOURCES/gcc32-rh186252.patch b/SOURCES/gcc32-rh186252.patch
new file mode 100644
index 0000000..c2e1544
--- /dev/null
+++ b/SOURCES/gcc32-rh186252.patch
@@ -0,0 +1,117 @@
+2004-05-01 Ulrich Weigand <weigand@de.ibm.com>
+
+	PR middle-end/15054
+	* expr.c (expand_expr_real): Do not call preserve_temp_slots 
+	on a TARGET_EXPR temp.
+	* function.c (assign_stack_temp_for_type): Set 'keep' flag for
+	TARGET_EXPR temp slots.
+
+	* g++.dg/opt/pr15054.C: New test.
+
+2006-04-25  Jakub Jelinek  <jakub@redhat.com>
+
+	* g++.dg/opt/pr15054-2.C: New test.
+
+--- gcc/expr.c.orig	2006-02-24 04:51:46.000000000 -0300
++++ gcc/expr.c	2006-04-11 03:53:02.000000000 -0300
+@@ -8676,8 +8676,6 @@ expand_expr (exp, target, tmode, modifie
+ 	    else
+ 	      {
+ 		target = assign_temp (type, 2, 0, 1);
+-		/* All temp slots at this level must not conflict.  */
+-		preserve_temp_slots (target);
+ 		SET_DECL_RTL (slot, target);
+ 		if (TREE_ADDRESSABLE (slot))
+ 		  put_var_into_stack (slot);
+--- gcc/function.c.orig	2006-02-24 04:51:52.000000000 -0300
++++ gcc/function.c	2006-04-11 03:53:02.000000000 -0300
+@@ -803,7 +803,7 @@ assign_stack_temp_for_type (mode, size, 
+   if (keep == 2)
+     {
+       p->level = target_temp_slot_level;
+-      p->keep = 0;
++      p->keep = 1;
+     }
+   else if (keep == 3)
+     {
+--- gcc/testsuite/g++.dg/opt/pr15054.C	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.dg/opt/pr15054.C	2006-04-11 03:54:31.000000000 -0300
+@@ -0,0 +1,36 @@
++// PR middle-end/15054
++// This used to abort due to overlapping stack temporaries.
++
++// { dg-do run }
++// { dg-options "-O" }
++
++extern "C" void abort (void);
++
++struct pointer
++{
++  void* ptr;
++
++  pointer(void* x = 0) : ptr(x) {}
++  pointer(const pointer& x) : ptr(x.ptr) {}
++};
++
++struct element
++{
++  int canary;
++
++  element() : canary(123) { }
++  ~element() { pointer(); if (canary != 123) abort (); }
++};
++
++inline pointer
++insert(const element& x)
++{
++  return pointer(new element(x));
++}
++
++int
++main (void)
++{
++  insert(element());
++  return 0;
++}
+--- gcc/testsuite/g++.dg/opt/pr15054-2.C	2006-04-19 19:21:31.748476000 +0200
++++ gcc/testsuite/g++.dg/opt/pr15054-2.C	2006-04-25 15:55:07.000000000 +0200
+@@ -0,0 +1,39 @@
++// PR middle-end/15054
++
++// { dg-do run }
++// { dg-options "-O2" }
++
++extern "C" void abort (void);
++
++void
++__attribute__((noinline))
++check (long x, long y)
++{
++  if (x != y)
++    abort ();
++}
++
++struct A
++{
++  A() : a(2) { check (a, 2); }
++  ~A() { check (a, 2); }
++private:
++  long a;
++};
++
++class B {
++  long b;
++  B& operator =(const B& );
++public:
++  B (long p) : b(p) { check (b, 6); }
++  B (const B& p) : b(p.b) { check (b, 6); }
++  ~B () { check (b, 6); A obj; check (b, 6); }
++  B foo() { return B(*this); }
++};
++
++int main ()
++{
++  B o(6);
++  o.foo().foo();
++  return 0;
++}
diff --git a/SOURCES/gcc32-rh226706.patch b/SOURCES/gcc32-rh226706.patch
new file mode 100644
index 0000000..2091e8f
--- /dev/null
+++ b/SOURCES/gcc32-rh226706.patch
@@ -0,0 +1,37 @@
+2007-02-13  Alexandre Oliva  <aoliva@redhat.com>
+
+	* reload1.c (fixup_abnormal_edges): Backport relevant portion of
+	fix for PR rtl-optimization/23601.
+
+	* g++.dg/eh/bz226706.C: New
+
+--- gcc/reload1.c	2006-10-13 04:32:14.000000000 -0300
++++ gcc/reload1.c	2007-02-13 03:22:08.000000000 -0200
+@@ -9524,7 +9524,10 @@ fixup_abnormal_edges ()
+ 		 && insn != bb->head)
+ 	    insn = PREV_INSN (insn);
+ 	  if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn))
+-	    abort ();
++	    {
++	      purge_dead_edges (bb);
++	      continue;
++	    }
+ 	  bb->end = insn;
+ 	  inserted = true;
+ 	  insn = NEXT_INSN (insn);
+--- gcc/testsuite/g++.dg/eh/bz226706.C	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.dg/eh/bz226706.C	2007-02-13 03:30:16.000000000 -0200
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-options "-fnon-call-exceptions -fPIC -O2" } */
++
++void foo() {
++     try {
++        float y = 10;
++        while (y > 0) {
++            double z = (y / 10);
++            y = z;
++        }
++     }
++     catch (...) {}
++}
diff --git a/SOURCES/gcc32-s390-reload-dup.patch b/SOURCES/gcc32-s390-reload-dup.patch
new file mode 100644
index 0000000..d751a7c
--- /dev/null
+++ b/SOURCES/gcc32-s390-reload-dup.patch
@@ -0,0 +1,77 @@
+2002-09-26  Ulrich Weigand  <uweigand@de.ibm.com>
+
+	* reload.c (dup_replacements): New function.
+	(find_reloads): Use it to duplicate replacements at the top level
+	of match_dup operands.
+
+2004-10-25  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.c-torture/execute/20041025-1.c: New test.
+
+--- gcc/reload.c.jj	2003-04-08 15:51:07.000000000 +0200	1.190
++++ gcc/reload.c	2004-10-25 13:10:48.056167117 +0200	1.191
+@@ -244,6 +244,7 @@ static enum reg_class find_valid_class P
+ 						unsigned int));
+ static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode, int));
+ static void push_replacement	PARAMS ((rtx *, int, enum machine_mode));
++static void dup_replacements	PARAMS ((rtx *, rtx *));
+ static void combine_reloads	PARAMS ((void));
+ static int find_reusable_reload	PARAMS ((rtx *, rtx, enum reg_class,
+ 				       enum reload_type, int, int));
+@@ -1578,6 +1579,25 @@ push_replacement (loc, reloadnum, mode)
+       r->mode = mode;
+     }
+ }
++
++/* Duplicate any replacement we have recorded to apply at
++   location ORIG_LOC to also be performed at DUP_LOC.
++   This is used in insn patterns that use match_dup.  */
++
++static void
++dup_replacements (dup_loc, orig_loc)
++     rtx *dup_loc;
++     rtx *orig_loc;
++{
++  int i, n = n_replacements;
++
++  for (i = 0; i < n; i++)
++    {
++      struct replacement *r = &replacements[i];
++      if (r->where == orig_loc)
++	push_replacement (dup_loc, r->what, r->mode);
++    }
++}
+ 
+ /* Transfer all replacements that used to be in reload FROM to be in
+    reload TO.  */
+@@ -3969,9 +3989,7 @@ find_reloads (insn, replace, ind_levels,
+       {
+ 	int opno = recog_data.dup_num[i];
+ 	*recog_data.dup_loc[i] = *recog_data.operand_loc[opno];
+-	if (operand_reloadnum[opno] >= 0)
+-	  push_replacement (recog_data.dup_loc[i], operand_reloadnum[opno],
+-			    insn_data[insn_code_number].operand[opno].mode);
++	dup_replacements (recog_data.dup_loc[i], recog_data.operand_loc[opno]);
+       }
+ 
+ #if 0
+--- gcc/testsuite/gcc.c-torture/execute/20041025-1.c.jj	2004-10-25 13:13:28.604657996 +0200
++++ gcc/testsuite/gcc.c-torture/execute/20041025-1.c	2004-10-25 13:11:43.119389360 +0200
+@@ -0,0 +1,17 @@
++extern void abort (void);
++
++void
++foo (int a, int b, int c, int d, int e, void **f)
++{
++  char g[4096];
++  if (f == 0 || *f != 0)
++    abort ();
++}
++
++int
++main (void)
++{
++  void *x = 0;
++  foo (0, 1, 2, 3, 4, &x);
++  return 0;
++}
diff --git a/SOURCES/gcc32-s390x-compile.patch b/SOURCES/gcc32-s390x-compile.patch
new file mode 100644
index 0000000..7f6ad4b
--- /dev/null
+++ b/SOURCES/gcc32-s390x-compile.patch
@@ -0,0 +1,10 @@
+--- gcc/builtins.c.jj	2004-02-28 06:14:54.000000000 -0500
++++ gcc/builtins.c	2006-08-10 06:35:16.000000000 -0400
+@@ -41,6 +41,7 @@ Software Foundation, 59 Temple Place - S
+ #include "predict.h"
+ #include "tm_p.h"
+ #include "target.h"
++#include "integrate.h"
+ 
+ #define CALLED_AS_BUILT_IN(NODE) \
+    (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
diff --git a/SOURCES/gcc32-tablejump-cleanup.patch b/SOURCES/gcc32-tablejump-cleanup.patch
new file mode 100644
index 0000000..f26a2fa
--- /dev/null
+++ b/SOURCES/gcc32-tablejump-cleanup.patch
@@ -0,0 +1,222 @@
+2005-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* cfgrtl.c (try_redirect_by_replacing_jump): Add 2 arguments to
+	tablejump_p.
+
+	* gcc.c-torture/compile/20050103-1.c: New test.
+
+2003-07-20  Josef Zlomek  <zlomekj@suse.cz>
+
+	* cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p.
+	* ifcvt.c (find_if_block): Added 2 arguments to tablejump_p.
+	* jump.c (tablejump_p): Added 2 arguments.
+	* rtl.h (tablejump_p): Likewise.
+
+--- gcc/rtl.h.jj	2003-06-11 14:58:17.000000000 +0200
++++ gcc/rtl.h	2005-01-03 17:32:46.113937897 +0100
+@@ -1793,7 +1793,7 @@ extern rtx pc_set			PARAMS ((rtx));
+ extern rtx condjump_label		PARAMS ((rtx));
+ extern int simplejump_p			PARAMS ((rtx));
+ extern int returnjump_p			PARAMS ((rtx));
+-extern int tablejump_p			PARAMS ((rtx));
++extern int tablejump_p			PARAMS ((rtx, rtx *, rtx *));
+ extern int onlyjump_p			PARAMS ((rtx));
+ extern int only_sets_cc0_p		PARAMS ((rtx));
+ extern int sets_cc0_p			PARAMS ((rtx));
+--- gcc/cfgrtl.c.jj	2003-04-08 15:50:58.000000000 +0200
++++ gcc/cfgrtl.c	2005-01-03 17:37:59.150837447 +0100
+@@ -674,7 +674,7 @@ try_redirect_by_replacing_jump (e, targe
+   if (tmp || !onlyjump_p (insn))
+     return false;
+ 
+-  if ((!optimize || flow2_completed) && tablejump_p (insn))
++  if ((!optimize || flow2_completed) && tablejump_p (insn, NULL, NULL))
+     return false;
+ 
+   /* Avoid removing branch with side effects.  */
+--- gcc/cfgcleanup.c.jj	2003-08-02 01:18:22.000000000 +0200
++++ gcc/cfgcleanup.c	2005-01-03 17:32:10.010407336 +0100
+@@ -691,25 +691,20 @@ merge_blocks_move_successor_nojumps (a, 
+      basic_block a, b;
+ {
+   rtx barrier, real_b_end;
++  rtx label, table;
+ 
+   real_b_end = b->end;
+-  barrier = NEXT_INSN (b->end);
+ 
+-  /* Recognize a jump table following block B.  */
+-  if (barrier
+-      && GET_CODE (barrier) == CODE_LABEL
+-      && NEXT_INSN (barrier)
+-      && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN
+-      && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
+-	  || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
++  /* If there is a jump table following block B temporarily add the jump table
++     to block B so that it will also be moved to the correct location.  */
++  if (tablejump_p (b->end, &label, &table)
++      && prev_active_insn (label) == b->end)
+     {
+-      /* Temporarily add the table jump insn to b, so that it will also
+-	 be moved to the correct location.  */
+-      b->end = NEXT_INSN (barrier);
+-      barrier = NEXT_INSN (b->end);
++      b->end = table;
+     }
+ 
+   /* There had better have been a barrier there.  Delete it.  */
++  barrier = NEXT_INSN (b->end);
+   if (barrier && GET_CODE (barrier) == BARRIER)
+     delete_insn (barrier);
+ 
+--- gcc/jump.c.jj	2003-08-01 22:38:45.000000000 +0200
++++ gcc/jump.c	2005-01-03 17:36:59.744484787 +0100
+@@ -1099,20 +1099,32 @@ simplejump_p (insn)
+ 	  && GET_CODE (SET_DEST (PATTERN (insn))) == PC
+ 	  && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
+ }
+-/* Return 1 if INSN is an tablejump.  */
++
++/* If INSN is a tablejump return 1 and store the label (before jump table) to
++   *LABELP and the jump table to *TABLEP.  LABELP and TABLEP may be NULL.  */
+ 
+ int
+-tablejump_p (insn)
++tablejump_p (insn, labelp, tablep)
+      rtx insn;
++     rtx *labelp;
++     rtx *tablep;
+ {
+-  rtx table;
+-  return (GET_CODE (insn) == JUMP_INSN
+-	  && JUMP_LABEL (insn)
+-	  && NEXT_INSN (JUMP_LABEL (insn))
+-	  && (table = next_active_insn (JUMP_LABEL (insn)))
+-	  && GET_CODE (table) == JUMP_INSN
+-	  && (GET_CODE (PATTERN (table)) == ADDR_VEC
+-	      || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC));
++  rtx label, table;
++  
++  if (GET_CODE (insn) == JUMP_INSN
++      && (label = JUMP_LABEL (insn)) != NULL_RTX
++      && (table = next_active_insn (label)) != NULL_RTX
++      && GET_CODE (table) == JUMP_INSN
++      && (GET_CODE (PATTERN (table)) == ADDR_VEC
++	  || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
++    {
++      if (labelp)
++	*labelp = label;
++      if (tablep)
++	*tablep = table;
++      return 1;
++    }
++  return 0;
+ }
+ 
+ /* Return nonzero if INSN is a (possibly) conditional jump
+--- gcc/ifcvt.c.jj	2003-03-25 17:42:24.000000000 +0100
++++ gcc/ifcvt.c	2005-01-03 17:32:10.012406978 +0100
+@@ -2046,7 +2046,7 @@ find_if_block (test_bb, then_edge, else_
+   if (then_succ != NULL_EDGE
+       && (then_succ->succ_next != NULL_EDGE
+           || (then_succ->flags & EDGE_COMPLEX)
+-	  || (flow2_completed && tablejump_p (then_bb->end))))
++	  || (flow2_completed && tablejump_p (then_bb->end, NULL, NULL))))
+     return FALSE;
+ 
+   /* If the THEN block has no successors, conditional execution can still
+@@ -2094,7 +2094,7 @@ find_if_block (test_bb, then_edge, else_
+ 	   && else_bb->pred->pred_next == NULL_EDGE
+ 	   && else_succ->succ_next == NULL_EDGE
+ 	   && ! (else_succ->flags & EDGE_COMPLEX)
+-	   && ! (flow2_completed && tablejump_p (else_bb->end)))
++	   && ! (flow2_completed && tablejump_p (else_bb->end, NULL, NULL)))
+     join_bb = else_succ->dest;
+ 
+   /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
+--- gcc/testsuite/gcc.c-torture/compile/20050103-1.c.jj	2004-12-09 13:34:01.422415552 +0100
++++ gcc/testsuite/gcc.c-torture/compile/20050103-1.c	2005-01-03 15:21:18.146431991 +0100
+@@ -0,0 +1,83 @@
++extern void abort (void);
++
++struct S
++{
++  char *s1;
++  int s2;
++};
++struct T
++{
++  int t1;
++  struct S *t2;
++} *s1;
++
++extern int bar (const struct T *, unsigned int, unsigned int,
++		const struct T *, unsigned int, unsigned int);
++
++extern inline void *
++baz (void *x, const void *y, unsigned int z)
++{
++  unsigned char *s1 = x;
++  const unsigned char *s2 = y;
++
++  if (z > 4 || __builtin_constant_p (z))
++    __builtin_memcpy (x, y, z);
++  else
++    switch (z)
++      {
++      case 4:
++	s1[3] = s2[3];
++      case 3:
++	s1[2] = s2[2];
++      case 2:
++	s1[1] = s2[1];
++      case 1:
++	s1[0] = s2[0];
++      case 0:
++	break;
++      }
++
++  return x;
++}
++
++extern inline int
++foo (struct T *b, unsigned int x, const void *y, unsigned int z)
++{
++  if (!b || !z)
++    return 0;
++  if (x == b->t1)
++    {
++      struct S *r = b->t2;
++      baz (r->s1 + r->s2, y, z);
++      return 1;
++    }
++
++  return 0;
++}
++
++int
++test (struct T *a, struct T *b, struct T *c, struct T *d)
++{
++  if (!a)
++    abort ();
++  if (!b)
++    abort ();
++
++  if (bar (a, 1, a->t1, b, 1, b->t1) > 0)
++    abort ();
++  if (bar (a, 41, a->t1 - 40, b, 1, b->t1) > 0)
++    abort ();
++
++  if (!c)
++    abort ();
++  if (!d)
++    abort ();
++
++  if (bar (c, 1, c->t1, d, 1, d->t1) < 0)
++    abort ();
++  if (bar (c, 41, c->t1 - 40, d, 1, d->t1) < 0)
++    abort ();
++
++  foo (s1, 0, "abcd", 4);
++  return 0;
++}
diff --git a/SOURCES/gcc32-weakref.patch b/SOURCES/gcc32-weakref.patch
new file mode 100644
index 0000000..49af1e5
--- /dev/null
+++ b/SOURCES/gcc32-weakref.patch
@@ -0,0 +1,859 @@
+2005-11-16  Alexandre Oliva  <aoliva@redhat.com>
+
+	* attribs.c (handle_weakref_attribute): New.
+	(c_common_attribute_table): Add weakref.
+	* defaults.h (ASM_OUTPUT_WEAKREF): Define.
+	* doc/extend.texi: Document weakref attribute.
+	* varasm.c (do_assemble_alias): Handle weakrefs.
+	(finish_aliases_1): Do not reject weakrefs to external symbols.
+	* gthr-posix.h: Define __gthrw.  For all identifiers that
+	might be weak, introduce weakrefs or non-weak aliases with
+	__gthrw, and prefix all uses with __ghtrw.
+	* config/rs6000/rs6000.h (ASM_OUTPUT_WEAKREF): Define.
+
+	* g++.old-deja/g++.ext/weakref1.C: New test.
+	* g++.old-deja/g++.ext/weakref1a.cc: New helper file.
+
+--- gcc/defaults.h.orig	2005-11-15 19:55:42.000000000 -0200
++++ gcc/defaults.h	2005-11-16 13:38:28.000000000 -0200
+@@ -156,6 +156,25 @@
+ #endif
+ #endif
+ 
++/* This is how we tell the assembler that a symbol is a weak alias to
++   another symbol that doesn't require the other symbol to be defined.
++   Uses of the former will turn into weak uses of the latter, i.e.,
++   uses that, in case the latter is undefined, will not cause errors,
++   and will add it to the symbol table as weak undefined.  However, if
++   the latter is referenced directly, a strong reference prevails.  */
++#ifndef ASM_OUTPUT_WEAKREF
++#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE)			\
++  do									\
++    {									\
++      fprintf ((FILE), "\t.weakref\t");					\
++      assemble_name ((FILE), (NAME));					\
++      fprintf ((FILE), ",");						\
++      assemble_name ((FILE), (VALUE));					\
++      fprintf ((FILE), "\n");						\
++    }									\
++  while (0)
++#endif
++
+ /* This determines whether or not we support weak symbols.  */
+ #ifndef SUPPORTS_WEAK
+ #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
+--- gcc/doc/extend.texi.orig	2005-11-15 19:55:42.000000000 -0200
++++ gcc/doc/extend.texi	2005-11-15 19:55:48.000000000 -0200
+@@ -2217,6 +2217,38 @@
+ for ELF targets, and also for a.out targets when using the GNU assembler
+ and linker.
+ 
++@item weakref
++@itemx weakref ("@var{target}")
++@cindex @code{weakref} attribute
++The @code{weakref} attribute marks a declaration as a weak reference.
++Without arguments, it should be accompanied by an @code{alias} attribute
++naming the target symbol.  Optionally, the @var{target} may be given as
++an argument to @code{weakref} itself.  In either case, @code{weakref}
++implicitly marks the declaration as @code{weak}.  Without a
++@var{target}, given as an argument to @code{weakref} or to @code{alias},
++@code{weakref} is equivalent to @code{weak}.
++
++@smallexample
++extern int x() __attribute__ ((weakref ("y")));
++/* is equivalent to... */
++extern int x() __attribute__ ((weak, weakref, alias ("y")));
++/* and to... */
++extern int x() __attribute__ ((weakref));
++extern int x() __attribute__ ((alias ("y")));
++@end smallexample
++
++A weak reference is an alias that does not by itself require a
++definition to be given for the target symbol.  If the target symbol is
++only referenced through weak references, then the becomes a @code{weak}
++undefined symbol.  If it is directly referenced, however, then such
++strong references prevail, and a definition will be required for the
++symbol, not necessarily in the same translation unit.
++
++The effect is equivalent to moving all references to the alias to a
++separate translation unit, renaming the alias to the aliased symbol,
++declaring it as weak, compiling the two separate translation units and
++performing a reloadable link on them.
++
+ @item malloc
+ @cindex @code{malloc} attribute
+ The @code{malloc} attribute is used to tell the compiler that a function
+--- gcc/gthr-posix.h.orig	2005-11-15 19:55:42.000000000 -0200
++++ gcc/gthr-posix.h	2005-11-15 19:55:48.000000000 -0200
+@@ -43,6 +43,42 @@
+ #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+ #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
+ 
++#if SUPPORTS_WEAK && GTHREAD_USE_WEAK && defined __GNUC_RH_RELEASE__ && __GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 3 && __GNUC_RH_RELEASE__ > 53 && !defined __attribute__
++# define __gthrw(name) \
++  extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)))
++
++__gthrw(pthread_once);
++__gthrw(pthread_key_create);
++__gthrw(pthread_key_delete);
++__gthrw(pthread_getspecific);
++__gthrw(pthread_setspecific);
++__gthrw(pthread_create);
++
++__gthrw(pthread_mutex_lock );
++__gthrw(pthread_mutex_trylock );
++__gthrw(pthread_mutex_unlock );
++
++#ifdef _LIBOBJC
++/* Objective C.  */
++__gthrw(pthread_cond_broadcast);
++__gthrw(pthread_cond_destroy);
++__gthrw(pthread_cond_init);
++__gthrw(pthread_cond_signal);
++__gthrw(pthread_cond_wait);
++__gthrw(pthread_exit);
++__gthrw(pthread_mutex_init);
++__gthrw(pthread_mutex_destroy);
++__gthrw(pthread_self);
++__gthrw(sched_get_priority_max);
++__gthrw(sched_get_priority_min);
++__gthrw(sched_yield);
++__gthrw(pthread_attr_destroy);
++__gthrw(pthread_attr_init);
++__gthrw(pthread_attr_setdetachstate);
++__gthrw(pthread_getschedparam);
++__gthrw(pthread_setschedparam);
++#endif
++#else
+ #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
+ 
+ #pragma weak pthread_once
+@@ -76,11 +112,47 @@
+ #pragma weak pthread_getschedparam
+ #pragma weak pthread_setschedparam
+ #endif
++#endif
++
++#define __gthrw_pthread_once pthread_once
++#define __gthrw_pthread_key_create pthread_key_create
++#define __gthrw_pthread_key_delete pthread_key_delete
++#define __gthrw_pthread_getspecific pthread_getspecific
++#define __gthrw_pthread_setspecific pthread_setspecific
++#define __gthrw_pthread_create pthread_create
++
++#define __gthrw_pthread_mutex_lock  pthread_mutex_lock
++#define __gthrw_pthread_mutex_trylock  pthread_mutex_trylock
++#define __gthrw_pthread_mutex_unlock  pthread_mutex_unlock
++
++#ifdef _LIBOBJC
++/* Objective C.  */
++#define __gthrw_pthread_cond_broadcast pthread_cond_broadcast
++#define __gthrw_pthread_cond_destroy pthread_cond_destroy
++#define __gthrw_pthread_cond_init pthread_cond_init
++#define __gthrw_pthread_cond_signal pthread_cond_signal
++#define __gthrw_pthread_cond_wait pthread_cond_wait
++#define __gthrw_pthread_exit pthread_exit
++#define __gthrw_pthread_mutex_init pthread_mutex_init
++#define __gthrw_pthread_mutex_destroy pthread_mutex_destroy
++#define __gthrw_pthread_self pthread_self
++#define __gthrw_sched_get_priority_max sched_get_priority_max
++#define __gthrw_sched_get_priority_min sched_get_priority_min
++#define __gthrw_sched_yield sched_yield
++#define __gthrw_pthread_attr_destroy pthread_attr_destroy
++#define __gthrw_pthread_attr_init pthread_attr_init
++#define __gthrw_pthread_attr_setdetachstate pthread_attr_setdetachstate
++#define __gthrw_pthread_getschedparam pthread_getschedparam
++#define __gthrw_pthread_setschedparam pthread_setschedparam
++#endif
++#endif
++
++#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
+ 
+ static inline int
+ __gthread_active_p (void)
+ {
+-  static void *const __gthread_active_ptr = (void *) &pthread_create;
++  static void *const __gthread_active_ptr = (void *) &__gthrw_pthread_create;
+   return __gthread_active_ptr != 0;
+ }
+ 
+@@ -119,13 +191,13 @@
+   if (__gthread_active_p ())
+     {
+       /* Initialize the thread storage key */
+-      if (pthread_key_create(&_objc_thread_storage, NULL) == 0)
++      if (__gthrw_pthread_key_create(&_objc_thread_storage, NULL) == 0)
+         {
+           /* The normal default detach state for threads is
+            * PTHREAD_CREATE_JOINABLE which causes threads to not die
+            * when you think they should.  */
+-          if (pthread_attr_init(&_objc_thread_attribs) == 0
+-              && pthread_attr_setdetachstate(&_objc_thread_attribs, 
++          if (__gthrw_pthread_attr_init(&_objc_thread_attribs) == 0
++              && __gthrw_pthread_attr_setdetachstate(&_objc_thread_attribs,
+                                              PTHREAD_CREATE_DETACHED) == 0)
+             return 0;
+         }
+@@ -139,8 +211,8 @@
+ __gthread_objc_close_thread_system(void)
+ {
+   if (__gthread_active_p ()
+-      && pthread_key_delete(_objc_thread_storage) == 0
+-      && pthread_attr_destroy(&_objc_thread_attribs) == 0)
++      && __gthrw_pthread_key_delete(_objc_thread_storage) == 0
++      && __gthrw_pthread_attr_destroy(&_objc_thread_attribs) == 0)
+     return 0;
+ 
+   return -1;
+@@ -158,7 +230,7 @@
+   if (!__gthread_active_p ())
+     return NULL;
+  
+-  if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
++  if ( !(__gthrw_pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
+     thread_id = (objc_thread_t) new_thread_handle;
+   else
+     thread_id = NULL;
+@@ -173,17 +245,17 @@
+   if (!__gthread_active_p())
+     return -1;
+   else {
+-    pthread_t thread_id = pthread_self();
++    pthread_t thread_id = __gthrw_pthread_self();
+     int policy;
+     struct sched_param params;
+     int priority_min, priority_max;
+ 
+-    if (pthread_getschedparam(thread_id, &policy, &params) == 0)
++    if (__gthrw_pthread_getschedparam(thread_id, &policy, &params) == 0)
+       {
+-        if ((priority_max = sched_get_priority_max(policy)) != 0)
++        if ((priority_max = __gthrw_sched_get_priority_max(policy)) != 0)
+           return -1;
+ 
+-        if ((priority_min = sched_get_priority_min(policy)) != 0)
++        if ((priority_min = __gthrw_sched_get_priority_min(policy)) != 0)
+           return -1;
+ 
+         if (priority > priority_max)
+@@ -197,7 +269,7 @@
+          * this should be a pointer to policy but pthread.h is universally
+          * at odds with this.
+          */
+-        if (pthread_setschedparam(thread_id, policy, &params) == 0)
++        if (__gthrw_pthread_setschedparam(thread_id, policy, &params) == 0)
+           return 0;
+       }
+     return -1;
+@@ -213,7 +285,7 @@
+       int policy;
+       struct sched_param params;
+ 
+-      if (pthread_getschedparam(pthread_self(), &policy, &params) == 0)
++      if (__gthrw_pthread_getschedparam(__gthrw_pthread_self(), &policy, &params) == 0)
+         return params.sched_priority;
+       else
+         return -1;
+@@ -227,7 +299,7 @@
+ __gthread_objc_thread_yield(void)
+ {
+   if (__gthread_active_p ())
+-    sched_yield();
++    __gthrw_sched_yield();
+ }
+ 
+ /* Terminate the current thread.  */
+@@ -236,7 +308,7 @@
+ {
+   if (__gthread_active_p ())
+     /* exit the thread */
+-    pthread_exit(&__objc_thread_exit_status);
++    __gthrw_pthread_exit(&__objc_thread_exit_status);
+ 
+   /* Failed if we reached here */
+   return -1;
+@@ -247,7 +319,7 @@
+ __gthread_objc_thread_id(void)
+ {
+   if (__gthread_active_p ())
+-    return (objc_thread_t) pthread_self();
++    return (objc_thread_t) __gthrw_pthread_self();
+   else
+     return (objc_thread_t) 1;
+ }
+@@ -257,7 +329,7 @@
+ __gthread_objc_thread_set_data(void *value)
+ {
+   if (__gthread_active_p ())
+-    return pthread_setspecific(_objc_thread_storage, value);
++    return __gthrw_pthread_setspecific(_objc_thread_storage, value);
+   else
+     {
+       thread_local_storage = value;
+@@ -270,7 +342,7 @@
+ __gthread_objc_thread_get_data(void)
+ {
+   if (__gthread_active_p ())
+-    return pthread_getspecific(_objc_thread_storage);
++    return __gthrw_pthread_getspecific(_objc_thread_storage);
+   else
+     return thread_local_storage;
+ }
+@@ -285,7 +357,7 @@
+     {
+       mutex->backend = objc_malloc(sizeof(pthread_mutex_t));
+ 
+-      if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
++      if (__gthrw_pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL))
+ 	{
+ 	  objc_free(mutex->backend);
+ 	  mutex->backend = NULL;
+@@ -306,18 +378,18 @@
+ 
+       /*
+        * Posix Threads specifically require that the thread be unlocked
+-       * for pthread_mutex_destroy to work.
++       * for __gthrw_pthread_mutex_destroy to work.
+        */
+ 
+       do
+ 	{
+-	  count = pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
++	  count = __gthrw_pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
+ 	  if (count < 0)
+ 	    return -1;
+ 	}
+       while (count);
+ 
+-      if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
++      if (__gthrw_pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
+ 	return -1;
+ 
+       objc_free(mutex->backend);
+@@ -331,7 +403,7 @@
+ __gthread_objc_mutex_lock(objc_mutex_t mutex)
+ {
+   if (__gthread_active_p () 
+-      && pthread_mutex_lock((pthread_mutex_t *)mutex->backend) != 0)
++      && __gthrw_pthread_mutex_lock((pthread_mutex_t *)mutex->backend) != 0)
+     {
+       return -1;
+     }
+@@ -344,7 +416,7 @@
+ __gthread_objc_mutex_trylock(objc_mutex_t mutex)
+ {
+   if (__gthread_active_p () 
+-      && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 0)
++      && __gthrw_pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 0)
+     {
+       return -1;
+     }
+@@ -357,7 +429,7 @@
+ __gthread_objc_mutex_unlock(objc_mutex_t mutex)
+ {
+   if (__gthread_active_p () 
+-      && pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) != 0)
++      && __gthrw_pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) != 0)
+     {
+       return -1;
+     }
+@@ -375,7 +447,7 @@
+     {
+       condition->backend = objc_malloc(sizeof(pthread_cond_t));
+ 
+-      if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
++      if (__gthrw_pthread_cond_init((pthread_cond_t *)condition->backend, NULL))
+ 	{
+ 	  objc_free(condition->backend);
+ 	  condition->backend = NULL;
+@@ -392,7 +464,7 @@
+ {
+   if (__gthread_active_p ())
+     {
+-      if (pthread_cond_destroy((pthread_cond_t *)condition->backend))
++      if (__gthrw_pthread_cond_destroy((pthread_cond_t *)condition->backend))
+ 	return -1;
+ 
+       objc_free(condition->backend);
+@@ -406,7 +478,7 @@
+ __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+ {
+   if (__gthread_active_p ())
+-    return pthread_cond_wait((pthread_cond_t *)condition->backend,
++    return __gthrw_pthread_cond_wait((pthread_cond_t *)condition->backend,
+ 			   (pthread_mutex_t *)mutex->backend);
+   else
+     return 0;
+@@ -417,7 +489,7 @@
+ __gthread_objc_condition_broadcast(objc_condition_t condition)
+ {
+   if (__gthread_active_p ())
+-    return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
++    return __gthrw_pthread_cond_broadcast((pthread_cond_t *)condition->backend);
+   else
+     return 0;
+ }
+@@ -427,7 +499,7 @@
+ __gthread_objc_condition_signal(objc_condition_t condition)
+ {
+   if (__gthread_active_p ())
+-    return pthread_cond_signal((pthread_cond_t *)condition->backend);
++    return __gthrw_pthread_cond_signal((pthread_cond_t *)condition->backend);
+   else
+     return 0;
+ }
+@@ -438,7 +510,7 @@
+ __gthread_once (__gthread_once_t *once, void (*func) (void))
+ {
+   if (__gthread_active_p ())
+-    return pthread_once (once, func);
++    return __gthrw_pthread_once (once, func);
+   else
+     return -1;
+ }
+@@ -446,7 +518,7 @@
+ static inline int
+ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
+ {
+-  return pthread_key_create (key, dtor);
++  return __gthrw_pthread_key_create (key, dtor);
+ }
+ 
+ static inline int
+@@ -454,7 +526,7 @@
+ {
+   /* Just reset the key value to zero.  */
+   if (ptr)
+-    return pthread_setspecific (key, 0);
++    return __gthrw_pthread_setspecific (key, 0);
+   else
+     return 0;
+ }
+@@ -462,26 +534,26 @@
+ static inline int
+ __gthread_key_delete (__gthread_key_t key)
+ {
+-  return pthread_key_delete (key);
++  return __gthrw_pthread_key_delete (key);
+ }
+ 
+ static inline void *
+ __gthread_getspecific (__gthread_key_t key)
+ {
+-  return pthread_getspecific (key);
++  return __gthrw_pthread_getspecific (key);
+ }
+ 
+ static inline int
+ __gthread_setspecific (__gthread_key_t key, const void *ptr)
+ {
+-  return pthread_setspecific (key, ptr);
++  return __gthrw_pthread_setspecific (key, ptr);
+ }
+ 
+ static inline int
+ __gthread_mutex_lock (__gthread_mutex_t *mutex)
+ {
+   if (__gthread_active_p ())
+-    return pthread_mutex_lock (mutex);
++    return __gthrw_pthread_mutex_lock (mutex);
+   else
+     return 0;
+ }
+@@ -490,7 +562,7 @@
+ __gthread_mutex_trylock (__gthread_mutex_t *mutex)
+ {
+   if (__gthread_active_p ())
+-    return pthread_mutex_trylock (mutex);
++    return __gthrw_pthread_mutex_trylock (mutex);
+   else
+     return 0;
+ }
+@@ -499,7 +571,7 @@
+ __gthread_mutex_unlock (__gthread_mutex_t *mutex)
+ {
+   if (__gthread_active_p ())
+-    return pthread_mutex_unlock (mutex);
++    return __gthrw_pthread_mutex_unlock (mutex);
+   else
+     return 0;
+ }
+--- gcc/varasm.c.orig	2005-11-15 19:55:42.000000000 -0200
++++ gcc/varasm.c	2005-11-16 13:38:44.000000000 -0200
+@@ -5130,6 +5130,9 @@
+       if (! TREE_USED (decl))
+ 	continue;
+ 
++      if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
++	continue;
++
+ #ifdef ASM_WEAKEN_DECL
+       ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
+ #else
+@@ -5195,6 +5198,18 @@
+ 
+   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ 
++  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
++    {
++#ifdef ASM_OUTPUT_WEAKREF
++      ASM_OUTPUT_WEAKREF (asm_out_file, decl,
++			  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
++			  IDENTIFIER_POINTER (target));
++#else
++      error ("%Jweakref is not supported in this configuration", decl);
++#endif
++      return;
++    }
++
+ #ifdef ASM_OUTPUT_DEF
+   /* Make name accessible from other files, if appropriate.  */
+   if (TREE_PUBLIC (decl))
+--- gcc/attribs.c.orig	2005-11-15 19:55:42.000000000 -0200
++++ gcc/attribs.c	2005-11-15 19:55:48.000000000 -0200
+@@ -75,6 +75,8 @@
+ 						 bool *));
+ static tree handle_alias_attribute	PARAMS ((tree *, tree, tree, int,
+ 						 bool *));
++static tree handle_weakref_attribute	PARAMS ((tree *, tree, tree, int,
++						 bool *));
+ static tree handle_visibility_attribute	PARAMS ((tree *, tree, tree, int,
+ 						 bool *));
+ static tree handle_tls_model_attribute	PARAMS ((tree *, tree, tree, int,
+@@ -140,6 +142,8 @@
+ 			      handle_weak_attribute },
+   { "alias",                  1, 1, true,  false, false,
+ 			      handle_alias_attribute },
++  { "weakref",                0, 1, true,  false, false,
++			      handle_weakref_attribute },
+   { "no_instrument_function", 0, 0, true,  false, false,
+ 			      handle_no_instrument_function_attribute },
+   { "malloc",                 0, 0, true,  false, false,
+@@ -1060,7 +1064,12 @@
+       if (TREE_CODE (decl) == FUNCTION_DECL)
+ 	DECL_INITIAL (decl) = error_mark_node;
+       else
+-	DECL_EXTERNAL (decl) = 0;
++	{
++	  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
++	    DECL_EXTERNAL (decl) = 1;
++	  else
++	    DECL_EXTERNAL (decl) = 0;
++	}
+     }
+   else
+     {
+@@ -1071,6 +1080,44 @@
+   return NULL_TREE;
+ }
+ 
++/* Handle a "weakref" attribute; arguments as in struct
++   attribute_spec.handler.  */
++
++static tree
++handle_weakref_attribute (node, name, args, flags, no_add_attrs)
++     tree *node;
++     tree name ATTRIBUTE_UNUSED;
++     tree args;
++     int flags;
++     bool *no_add_attrs;
++{
++  tree attr = NULL_TREE;
++
++  /* The idea here is that `weakref("name")' mutates into `weakref,
++     alias("name")', and weakref without arguments, in turn,
++     implicitly adds weak. */
++
++  if (args)
++    {
++      attr = tree_cons (get_identifier ("alias"), args, attr);
++      attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
++
++      *no_add_attrs = true;
++    }
++  else
++    {
++      if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
++	error ("%Jweakref attribute must appear before alias attribute",
++	       *node);
++
++      attr = tree_cons (get_identifier ("weak"), NULL_TREE, attr);
++    }
++
++  decl_attributes (node, attr, flags);
++
++  return NULL_TREE;
++}
++
+ /* Handle an "visibility" attribute; arguments as in
+    struct attribute_spec.handler.  */
+ 
+--- gcc/testsuite/g++.old-deja/g++.ext/weakref1.C	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.old-deja/g++.ext/weakref1.C	2005-11-15 19:55:48.000000000 -0200
+@@ -0,0 +1,226 @@
++// execution test
++// Additional sources: weakref1a.cc
++
++// Copyright 2005 Free Software Foundation, Inc.
++// Contributed by Alexandre Oliva <aoliva@redhat.com>
++
++// Torture test for weakrefs.  The first letter of an identifier
++// indicates whether/how it is defined; the second letter indicates
++// whether it is part of a variable or function test; the number that
++// follows is a test counter, and a letter that may follow enables
++// multiple identifiers within the same test (e.g., multiple weakrefs
++// or pointers to the same identifier).
++
++// Identifiers starting with W are weakrefs; those with p are
++// pointers; those with g are global definitions; those with l are
++// local definitions; those with w are expected to be weak undefined
++// in the symbol table; those with u are expected to be marked as
++// non-weak undefined in the symbol table.
++
++#include <stdlib.h>
++
++#define USED __attribute__((used))
++
++extern "C" {
++typedef int vtype;
++
++extern vtype wv1;
++extern vtype Wv1a __attribute__((weakref ("wv1")));
++static vtype *pv1a USED = &Wv1a;
++extern vtype Wv1b __attribute__((weak, weakref, alias ("wv1")));
++static vtype *pv1b USED = &Wv1b;
++extern vtype Wv1c __attribute__((weakref));
++extern vtype Wv1c __attribute__((alias ("wv1")));
++static vtype *pv1c USED = &Wv1c;
++
++vtype gv2;
++extern vtype Wv2a __attribute__((weakref ("gv2")));
++static vtype *pv2a USED = &Wv2a;
++
++static vtype lv3;
++extern vtype Wv3a __attribute__((weakref ("lv3")));
++static vtype *pv3a USED = &Wv3a;
++
++extern vtype uv4;
++extern vtype Wv4a __attribute__((weakref ("uv4")));
++static vtype *pv4a USED = &Wv4a;
++static vtype *pv4 USED = &uv4;
++
++extern vtype Wv5a __attribute__((weakref ("uv5")));
++static vtype *pv5a USED = &Wv5a;
++extern vtype uv5;
++static vtype *pv5 USED = &uv5;
++
++extern vtype Wv6a __attribute__((weakref ("wv6")));
++static vtype *pv6a USED = &Wv6a;
++extern vtype wv6;
++
++extern vtype Wv7a __attribute__((weakref ("uv7")));
++static vtype* USED fv7 (void) {
++  return &Wv7a;
++}
++extern vtype uv7;
++static vtype* USED fv7a (void) {
++  return &uv7;
++}
++
++extern vtype uv8;
++static vtype* USED fv8a (void) {
++  return &uv8;
++}
++extern vtype Wv8a __attribute__((weakref ("uv8")));
++static vtype* USED fv8 (void) {
++  return &Wv8a;
++}
++
++extern vtype wv9 __attribute__((weak));
++extern vtype Wv9a __attribute__((weakref ("wv9")));
++static vtype *pv9a USED = &Wv9a;
++
++extern vtype Wv10a __attribute__((weakref ("Wv10b")));
++extern vtype Wv10b __attribute__((weakref ("Wv10c")));
++extern vtype Wv10c __attribute__((weakref ("Wv10d")));
++extern vtype Wv10d __attribute__((weakref ("wv10")));
++extern vtype wv10;
++
++extern vtype wv11;
++extern vtype Wv11d __attribute__((weakref ("wv11")));
++extern vtype Wv11c __attribute__((weakref ("Wv11d")));
++extern vtype Wv11b __attribute__((weakref ("Wv11c")));
++extern vtype Wv11a __attribute__((weakref ("Wv11b")));
++
++extern vtype Wv12 __attribute__((weakref ("wv12")));
++extern vtype wv12 __attribute__((weak));
++
++extern vtype Wv13 __attribute__((weakref ("wv13")));
++extern vtype wv13 __attribute__((weak));
++
++extern vtype Wv14a __attribute__((weakref ("wv14")));
++extern vtype Wv14b __attribute__((weakref ("wv14")));
++extern vtype wv14 __attribute__((weak));
++
++typedef void ftype(void);
++
++extern ftype wf1;
++extern ftype Wf1a __attribute__((weakref ("wf1")));
++static ftype *pf1a USED = &Wf1a;
++extern ftype Wf1b __attribute__((weak, weakref, alias ("wf1")));
++static ftype *pf1b USED = &Wf1b;
++extern ftype Wf1c __attribute__((weakref));
++extern ftype Wf1c __attribute__((alias ("wf1")));
++static ftype *pf1c USED = &Wf1c;
++
++void gf2(void) {}
++extern ftype Wf2a __attribute__((weakref ("gf2")));
++static ftype *pf2a USED = &Wf2a;
++
++static void lf3(void) {}
++extern ftype Wf3a __attribute__((weakref ("lf3")));
++static ftype *pf3a USED = &Wf3a;
++
++extern ftype uf4;
++extern ftype Wf4a __attribute__((weakref ("uf4")));
++static ftype *pf4a USED = &Wf4a;
++static ftype *pf4 USED = &uf4;
++
++extern ftype Wf5a __attribute__((weakref ("uf5")));
++static ftype *pf5a USED = &Wf5a;
++extern ftype uf5;
++static ftype *pf5 USED = &uf5;
++
++extern ftype Wf6a __attribute__((weakref ("wf6")));
++static ftype *pf6a USED = &Wf6a;
++extern ftype wf6;
++
++extern ftype Wf7a __attribute__((weakref ("uf7")));
++static ftype* USED ff7 (void) {
++  return &Wf7a;
++}
++extern ftype uf7;
++static ftype* USED ff7a (void) {
++  return &uf7;
++}
++
++extern ftype uf8;
++static ftype* USED ff8a (void) {
++  return &uf8;
++}
++extern ftype Wf8a __attribute__((weakref ("uf8")));
++static ftype* USED ff8 (void) {
++  return &Wf8a;
++}
++
++extern ftype wf9 __attribute__((weak));
++extern ftype Wf9a __attribute__((weakref ("wf9")));
++static ftype *pf9a USED = &Wf9a;
++
++extern ftype Wf10a __attribute__((weakref ("Wf10b")));
++extern ftype Wf10b __attribute__((weakref ("Wf10c")));
++extern ftype Wf10c __attribute__((weakref ("Wf10d")));
++extern ftype Wf10d __attribute__((weakref ("wf10")));
++extern ftype wf10;
++
++extern ftype wf11;
++extern ftype Wf11d __attribute__((weakref ("wf11")));
++extern ftype Wf11c __attribute__((weakref ("Wf11d")));
++extern ftype Wf11b __attribute__((weakref ("Wf11c")));
++extern ftype Wf11a __attribute__((weakref ("Wf11b")));
++
++extern ftype Wf12 __attribute__((weakref ("wf12")));
++extern ftype wf12 __attribute__((weak));
++
++extern ftype Wf13 __attribute__((weakref ("wf13")));
++extern ftype wf13 __attribute__((weak));
++
++extern ftype Wf14a __attribute__((weakref ("wf14")));
++extern ftype Wf14b __attribute__((weakref ("wf14")));
++extern ftype wf14 __attribute__((weak));
++}
++
++#define chk(p) do { if (!p) abort (); } while (0)
++
++int main () {
++  chk (!pv1a);
++  chk (!pv1b);
++  chk (!pv1c);
++  chk (pv2a);
++  chk (pv3a);
++  chk (pv4a);
++  chk (pv4);
++  chk (pv5a);
++  chk (pv5);
++  chk (!pv6a);
++  chk (fv7 ());
++  chk (fv7a ());
++  chk (fv8 ());
++  chk (fv8a ());
++  chk (!pv9a);
++  chk (!&Wv10a);
++  chk (!&Wv11a);
++  chk (!&Wv12);
++  chk (!&wv12);
++  chk (!&wv13);
++  chk (!&Wv14a);
++
++  chk (!pf1a);
++  chk (!pf1b);
++  chk (!pf1c);
++  chk (pf2a);
++  chk (pf3a);
++  chk (pf4a);
++  chk (pf4);
++  chk (pf5a);
++  chk (pf5);
++  chk (!pf6a);
++  chk (ff7 ());
++  chk (ff7a ());
++  chk (ff8 ());
++  chk (ff8a ());
++  chk (!pf9a);
++  chk (!&Wf10a);
++  chk (!&Wf11a);
++  chk (!&Wf12);
++  chk (!&wf12);
++  chk (!&wf13);
++  chk (!&Wf14a);
++}
+--- gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc	1970-01-01 00:00:00.000000000 +0000
++++ gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc	2005-11-15 19:55:48.000000000 -0200
+@@ -0,0 +1,10 @@
++extern "C" {
++int uv4;
++int uv5;
++int uv7;
++int uv8;
++void uf4 (void) {}
++void uf5 (void) {}
++void uf7 (void) {}
++void uf8 (void) {}
++}
+--- gcc/config/rs6000/rs6000.h.orig	2005-11-16 13:37:46.000000000 -0200
++++ gcc/config/rs6000/rs6000.h	2005-11-16 14:10:01.000000000 -0200
+@@ -2487,6 +2487,24 @@
+   while (0)
+ #endif
+ 
++#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE)			\
++  do									\
++    {									\
++      fputs ("\t.weakref\t", (FILE));					\
++      RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 				\
++      fputs (", ", (FILE));						\
++      RS6000_OUTPUT_BASENAME ((FILE), (VALUE));				\
++      if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL			\
++	  && DEFAULT_ABI == ABI_AIX)					\
++	{								\
++	  fputs ("\n\t.weakref\t.", (FILE));				\
++	  RS6000_OUTPUT_BASENAME ((FILE), (NAME)); 			\
++	  fputs (", .", (FILE));					\
++	  RS6000_OUTPUT_BASENAME ((FILE), (VALUE));			\
++	}								\
++      fputc ('\n', (FILE));						\
++    } while (0)
++
+ /* This implements the `alias' attribute.  */
+ #undef	ASM_OUTPUT_DEF_FROM_DECLS
+ #define	ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET)			\
diff --git a/SPECS/compat-gcc-32.spec b/SPECS/compat-gcc-32.spec
new file mode 100644
index 0000000..7de6e96
--- /dev/null
+++ b/SPECS/compat-gcc-32.spec
@@ -0,0 +1,612 @@
+%define LIBSTDCXXDATE 20040818
+%define DATE 20040701
+%define gcc_version 3.2.3
+%define gcc_release 72
+%define _unpackaged_files_terminate_build 0
+%define multilib_64_archs sparc64 ppc64 s390x x86_64
+%define build_java 0
+%define _default_patch_fuzz 2
+%ifarch s390x
+%define multilib_32_arch s390
+%endif
+%ifarch sparc64
+%define multilib_32_arch sparc
+%endif
+%ifarch ppc64
+%define multilib_32_arch ppc
+%endif
+%ifarch x86_64
+%define multilib_32_arch i386
+%endif
+Summary: The compatibility GNU Compiler Collection
+Name: compat-gcc-32
+Version: %{gcc_version}
+Release: %{gcc_release}%{?dist}
+License: GPLv2+ with exceptions
+Group: Development/Languages
+Source0: gcc-%{gcc_version}-%{DATE}.tar.bz2
+Source2: libstdc++-3.3.4-%{LIBSTDCXXDATE}.tar.bz2
+Source3: dummylib.sh
+URL: http://gcc.gnu.org
+BuildRoot: /var/tmp/gcc-root
+# Need .eh_frame ld optimizations
+# Need proper visibility support
+# Need -pie support
+# Need --as-needed/--no-as-needed support
+# Need .weakref support
+BuildRequires: binutils >= 2.16.91.0.5-1
+BuildRequires: zlib-devel, gettext, dejagnu, bison, flex, texinfo
+# Make sure pthread.h doesn't contain __thread tokens
+BuildRequires: glibc-devel >= 2.2.90-12, glibc-static
+# Need .eh_frame ld optimizations
+# Need proper visibility support
+# Need -pie support
+# Need .weakref support
+Requires: binutils >= 2.16.91.0.5-1
+# Make sure gdb will understand DW_FORM_strp
+Conflicts: gdb < 5.1-2
+Requires: glibc-devel >= 2.2.90-12
+Requires: libgcc >= 3.4.0
+%ifarch %{multilib_64_archs} sparc sparcv9 ppc
+# Ensure glibc{,-devel} is installed for both multilib arches
+BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so
+%endif
+Provides: bundled(libiberty)
+
+Patch1: gcc32-multi32-hack.patch
+Patch2: gcc32-ice-hack.patch
+Patch3: gcc32-ppc64-m32-m64-multilib-only.patch
+Patch4: gcc32-bison-1.875c.patch
+Patch5: gcc32-i386-prefetch-sse.patch
+Patch6: gcc32-convert-move.patch
+Patch7: gcc32-libjava-jar-timestamps.patch
+Patch8: gcc32-c++-friend-templ-member.patch
+Patch9: gcc32-c++-scope-nesting.patch
+Patch10: gcc32-libstdc++-symver.patch
+Patch11: gcc32-java-intlex.patch
+Patch12: gcc32-java-nan.patch
+Patch13: gcc32-dwarf2-pruning-keep-spec.patch
+Patch14: gcc32-java-bytecode.patch
+Patch15: gcc32-pr3581.patch
+Patch16: gcc32-libstdc++-limits.patch
+Patch17: gcc32-ppc64-crtsavres.patch
+Patch18: gcc32-s390-reload-dup.patch
+Patch19: gcc32-ppc-altivec-ap.patch
+Patch20: gcc32-ppc-mpowerpc64.patch
+Patch21: gcc32-null-pointer-check-noncc0.patch
+Patch22: gcc32-ppc-movdi_internal64.patch
+Patch23: gcc32-c++-reregister-specialization.patch
+Patch24: gcc32-c++-pr7566.patch
+Patch25: gcc32-c++-pass-by-invisible-ref.patch
+Patch26: gcc32-c++-unitialized-self-ref.patch
+Patch27: gcc32-tablejump-cleanup.patch
+Patch28: gcc32-libstdc++-fully-dynamic-strings.patch
+Patch29: gcc32-Winline-doc.patch
+Patch30: gcc32-ia64-expand_load_address.patch
+Patch31: gcc32-demangle-pr16240.patch
+Patch32: gcc32-debug-cdtor.patch
+Patch33: gcc32-cxa_demangle-ambiguity.patch
+Patch34: gcc32-c++-pr10558.patch
+Patch35: gcc32-libstdc++-pr9659.patch
+Patch36: gcc32-libstdc++-symver2.patch
+Patch37: gcc32-pr19005.patch
+Patch38: gcc32-rh149250.patch
+Patch39: gcc32-rh156185.patch
+Patch40: gcc32-rh156291.patch
+Patch41: gcc32-pr18300.patch
+Patch42: gcc32-gnuc-rh-release.patch
+Patch43: gcc32-weakref.patch
+Patch44: gcc32-pr13106.patch
+Patch45: gcc32-ppc64-stack-boundary.patch
+Patch46: gcc32-pr12799.patch
+Patch47: gcc32-pr13041.patch
+Patch48: gcc32-pr26208.patch
+Patch49: gcc32-rh173224.patch
+Patch50: gcc32-rh180778.patch
+Patch51: gcc32-rh181894.patch
+Patch52: gcc32-rh186252.patch
+Patch53: gcc32-pr26208-workaround.patch
+Patch54: gcc32-libgcc_eh-hidden.patch
+Patch55: gcc32-java-zoneinfo.patch
+Patch56: gcc32-CVE-2006-3619.patch
+Patch57: gcc32-rh226706.patch
+
+Patch60: gcc32-obstack-lvalues.patch
+Patch61: gcc32-fc4-compile.patch
+Patch62: gcc32-s390x-compile.patch
+Patch63: gcc32-bison.patch
+
+Patch100: compat-libstdc++33-incdir.patch
+Patch101: compat-libstdc++33-limits.patch
+Patch102: compat-libstdc++33-symver.patch
+Patch103: compat-libstdc++33-v3.patch
+Patch104: compat-libstdc++33++-fully-dynamic-strings.patch
+Patch105: compat-libstdc++33++-symver2.patch
+Patch106: compat-libstdc++33-cxa_demangle-ambiguity.patch
+Patch107: compat-libstdc++33-ldbl.patch
+
+%define _gnu %{nil}
+
+%ifarch sparc sparcv9
+%define gcc_target_platform sparc64-%{_vendor}-linux
+%endif
+%ifarch ppc
+%define gcc_target_platform ppc64-%{_vendor}-linux
+%endif
+%ifnarch sparc sparcv9 ppc
+%define gcc_target_platform %{_target_cpu}-%{_vendor}-linux
+%endif
+
+%description
+This package includes a GCC 3.2.3-RH compatibility compiler.
+
+%package -n compat-libstdc++-33
+Summary: Compatibility standard C++ libraries
+Group: System Environment/Libraries
+Obsoletes: compat-libstdc++
+Obsoletes: compat-gcc-32, compat-gcc-32-c++, compat-gcc-32-g77
+
+%description -n compat-libstdc++-33
+The compat-libstdc++ package contains compatibility standard C++ library
+from GCC 3.3.4.
+
+%prep
+%setup -q -n gcc-%{gcc_version}-%{DATE} -a2
+mv gcc-3.3.4-%{LIBSTDCXXDATE}/libstdc++-v3 libstdc++33-v3
+%ifarch sparc ppc
+#%patch1 -p0 -b .multi32-hack~
+%endif
+%patch2 -p0 -b .ice-hack~
+%patch3 -p0 -b .ppc64-m32-m64-multilib-only~
+%patch4 -p0 -b .bison-1.875c~
+%patch5 -p0 -b .i386-prefetch-sse~
+%patch6 -p0 -b .convert-move~
+%patch7 -p0 -b .libjava-jar-timestamps~
+%patch8 -p0 -b .c++-friend-templ-member~
+#%patch9 -p0 -b .c++-scope-nesting~
+%patch10 -p0 -b .libstdc++-symver~
+%patch11 -p0 -b .java-intlex~
+%patch12 -p0 -b .java-nan~
+%patch13 -p0 -b .dwarf2-pruning-keep-spec~
+%patch14 -p0 -b .java-bytecode~
+%patch15 -p0 -b .pr3581~
+%patch16 -p0 -b .libstdc++-limits~
+%patch17 -p0 -b .ppc64-crtsavres~
+%patch18 -p0 -b .s390-reload-dup~
+%patch19 -p0 -b .ppc-altivec-ap~
+%patch20 -p0 -b .ppc-mpowerpc64~
+%patch21 -p0 -b .null-pointer-check-noncc0~
+%patch22 -p0 -b .ppc-movdi_internal64~
+%patch23 -p0 -b .c++-reregister-specialization~
+%patch24 -p0 -b .c++-pr7566~
+%patch25 -p0 -b .c++-pass-by-invisible-ref~
+%patch26 -p0 -b .c++-unitialized-self-ref~
+%patch27 -p0 -b .tablejump-cleanup~
+%patch28 -p0 -b .libstdc++-fully-dynamic-strings~
+%patch29 -p0 -b .Winline-doc~
+%patch30 -p0 -b .ia64-expand_load_address~
+%patch31 -p0 -b .demangle-pr16240~
+%patch32 -p0 -b .debug-cdtor~
+%patch33 -p0 -b .cxa_demangle-ambiguity~
+%patch34 -p0 -b .c++-pr10558~
+%patch35 -p0 -b .libstdc++-pr9659~
+%patch36 -p0 -b .libstdc++-symver2~
+%patch37 -p0 -b .pr19005~
+%patch38 -p0 -b .rh149250~
+%patch39 -p0 -b .rh156185~
+%patch40 -p0 -b .rh156291~
+%patch41 -p0 -b .pr18300~
+%patch42 -p0 -b .gnuc-rh-release~
+%patch43 -p0 -b .weakref~
+%patch44 -p0 -b .pr13106~
+%patch45 -p0 -b .ppc64-stack-boundary~
+%patch46 -p0 -b .pr12799~
+%patch47 -p0 -b .pr13041~
+%patch48 -p0 -b .pr26208~
+%patch49 -p0 -b .rh173224~
+%patch50 -p0 -b .rh180778~
+%patch51 -p0 -b .rh181894~
+%patch52 -p0 -b .rh186252~
+%patch53 -p0 -b .pr26208-workaround~
+%patch54 -p0 -b .libgcc_eh-hidden~
+%patch55 -p0 -b .java-zoneinfo~
+%patch56 -p0 -b .CVE-2006-3619~
+%patch57 -p0 -b .rh226706~
+
+%patch60 -p0 -b .obstack-lvalues~
+%patch61 -p0 -b .fc4-compile~
+%patch62 -p0 -b .s390x-compile~
+%patch63 -p0 -b .bison~
+
+%patch100 -p0 -b .compat-libstdc++33-incdir~
+%patch101 -p0 -b .compat-libstdc++33-limits~
+%patch102 -p0 -b .compat-libstdc++33-symver~
+%patch103 -p0 -b .compat-libstdc++33-v3~
+%patch104 -p0 -b .compat-libstdc++33++-fully-dynamic-strings~
+%patch105 -p0 -b .compat-libstdc++33++-symver2~
+%patch106 -p0 -b .compat-libstdc++33-cxa_demangle-ambiguity~
+%patch107 -p0 -b .compat-libstdc++33-ldbl.patch~
+
+sed -i -e 's/struct siginfo/siginfo_t/' gcc/config/*/linux*.h
+
+%ifarch ppc ppc64 s390 s390x
+sed -i -e 's/-lm @LIBUNWIND_FLAG@/-lm @LIBUNWIND_FLAG@ -lnldbl_nonshared/' \
+  libstdc++33-v3/src/Makefile.{am,in}
+%endif
+# Don't need to test C, only check-g++ and libstdc++-v33's make check
+sed -i -e 's/\$(RUNTEST) --tool gcc/: $(RUNTEST) --tool gcc/' \
+  gcc/Makefile.in
+sed -i -e 's/\$\$runtest \$(RUNTESTDEFAULTFLAGS)/: $$runtest $(RUNTESTDEFAULTFLAGS)/' \
+  libstdc++-v3/testsuite/Makefile.in
+perl -pi -e 's/3\.2\.4/3.2.3/' gcc/version.c
+perl -pi -e 's/"%{gcc_version}"/"%{gcc_version} \(release\)"/' gcc/version.c
+perl -pi -e 's/\((prerelease|experimental|release|Red Hat[^)]*)\)/\(Red Hat Linux %{gcc_version}-%{gcc_release}\)/' gcc/version.c
+
+cp -a libstdc++33-v3/config/cpu/i{4,3}86/atomicity.h
+
+./contrib/gcc_update --touch
+
+%build
+
+rm -fr obj-%{gcc_target_platform}
+mkdir obj-%{gcc_target_platform}
+cd obj-%{gcc_target_platform}
+
+mkdir -p ld_hack
+cat > ld_hack/ld <<\EOF
+#!/bin/sh
+case " $* " in *\ -r\ *) exec /usr/bin/ld "$@";; esac
+exec /usr/bin/ld --build-id "$@"
+EOF
+chmod 755 ld_hack/ld
+export PATH=`pwd`/ld_hack/${PATH:+:$PATH}
+
+if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then
+  mkdir locale
+  localedef -f ISO-8859-1 -i de_DE locale/de_DE
+  export LOCPATH=`pwd`/locale:/usr/lib/locale
+fi
+
+CC=gcc
+OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-fno-rtti//g' -e 's/-fno-exceptions//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'`
+%ifarch %{ix86}
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=pentium4/-mcpu=i686/g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=generic/-mcpu=i686/g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=atom/-mcpu=i686/g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=atom/-mcpu=i686/g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=x86-64//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse//g'`
+%endif
+%ifarch x86_64
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=nocona//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=generic//g'`
+%endif
+%ifarch sparc sparcv9 sparc64
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mcpu=ultrasparc/-mtune=ultrasparc/g'`
+%endif
+%ifarch s390 s390x
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=z9-109//g;s/-march=z10//g;s/-march=z196//g;s/-mtune=z10//g;s/-mtune=zEC12//g'`
+%endif
+%ifarch ppc ppc64
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=power[678]//g;s/-mcpu=power[678]//g;s/-mtune=power[678]//g'`
+%endif
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Wall//g' -e 's/-Wp,-D_FORTIFY_SOURCE=2//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-fexceptions//g' -e 's/-fasynchronous-unwind-tables//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-grecord-gcc-switches//g' -e 's/-fstack-protector-strong//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-fstack-protector//g' -e 's/--param=ssp-buffer-size=[0-9]*//g'`
+%ifarch sparc64
+cat > gcc64 <<"EOF"
+#!/bin/sh
+exec /usr/bin/gcc -m64 "$@"
+EOF
+chmod +x gcc64
+CC=`pwd`/gcc64
+%endif
+%ifarch ppc64
+if gcc -m64 -xc -S /dev/null -o - > /dev/null 2>&1; then
+  cat > gcc64 <<"EOF"
+#!/bin/sh
+exec /usr/bin/gcc -m64 "$@"
+EOF
+  chmod +x gcc64
+  CC=`pwd`/gcc64
+fi
+%endif
+CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="$OPT_FLAGS" XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \
+	GCJFLAGS="$OPT_FLAGS" \
+	../configure --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \
+	--enable-shared --enable-threads=posix --disable-checking \
+	--with-system-zlib --enable-__cxa_atexit \
+	--enable-languages=c,c++ --disable-libgcj \
+%ifarch sparc sparcv9
+	--host=%{gcc_target_platform} --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=v7
+%endif
+%ifarch ppc
+	--host=%{gcc_target_platform} --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=default32
+%endif
+%ifnarch sparc sparcv9 ppc
+	--host=%{gcc_target_platform}
+%endif
+
+make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap-lean
+#make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap
+
+# Fix up libstdc++.so's
+for d in `pwd`/%{gcc_target_platform}/libstdc++-v3 `pwd`/%{gcc_target_platform}/*/libstdc++-v3; do
+  test -d $d || continue
+  d33=`dirname $d`/libstdc++33-v3
+  pushd $d/src
+    sh %{SOURCE3} .libs/libstdc++.so .libs/ll.so linker.map
+    rm .libs/libstdc++.so; mv .libs/ll.so .libs/libstdc++.so
+    f=`basename .libs/libstdc++.so.5.0.*`
+    f33=`basename $d33/src/.libs/libstdc++.so.5.0.*`
+    cp -a $d33/src/.libs/libstdc++.so.5.0.* .libs/
+    if [ "$f" != "$f33" ]; then
+      ln -sf $f33 .libs/libstdc++.so.5
+      ln -sf $f33 .libs/$f
+    fi
+  popd
+  pushd $d33/src
+    sh %{SOURCE3} .libs/libstdc++.so .libs/ll.so libstdc++*.ver
+    rm .libs/libstdc++.so; mv .libs/ll.so .libs/libstdc++.so
+  popd
+done
+
+# Make sure we are using system libgcc_s, as system libc might
+# use unwinding features that require it.
+mv gcc/libgcc_s.so.1{,.bak}
+ln -sf /%{_lib}/libgcc_s.so.1 gcc/libgcc_s.so.1
+
+# run the tests.
+make %{?_smp_mflags} -k check || :
+sed -ie s/libstdc++-v3/libstdc++33-v3/g `find $(find %{gcc_target_platform} -type d -a -name libstdc++33-v3) -name \*.sum`
+echo ====================TESTING=========================
+( ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}'
+echo ====================TESTING END=====================
+
+%install
+rm -fr $RPM_BUILD_ROOT
+
+export PATH=`pwd`/obj-%{gcc_target_platform}/ld_hack/${PATH:+:$PATH}
+
+perl -pi -e \
+  's~href="l(ibstdc|atest)~href="http://gcc.gnu.org/onlinedocs/libstdc++/l\1~' \
+  libstdc++-v3/docs/html/documentation.html
+ln -sf documentation.html libstdc++-v3/docs/html/index.html
+find libstdc++-v3/docs/html -name CVS | xargs rm -rf
+
+cd obj-%{gcc_target_platform}
+
+if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then
+  export LOCPATH=`pwd`/locale:/usr/lib/locale
+fi
+
+TARGET_PLATFORM=%{gcc_target_platform}
+
+# There are some MP bugs in libstdc++ and libjava Makefiles
+# make -C %{gcc_target_platform}/libstdc++-v3
+
+make prefix=$RPM_BUILD_ROOT%{_prefix} mandir=$RPM_BUILD_ROOT%{_mandir} \
+  infodir=$RPM_BUILD_ROOT%{_infodir} install
+
+FULLPATH=$RPM_BUILD_ROOT%{_prefix}/lib/gcc-lib/%{gcc_target_platform}/%{gcc_version}
+FULLPATH33=$RPM_BUILD_ROOT%{_prefix}/lib/gcc-lib/%{gcc_target_platform}/3.3.4
+
+rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libstdc++.*a
+rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libsupc++.*a
+rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libstdc++.so*
+
+for d in %{gcc_target_platform}/libstdc++-v3 %{gcc_target_platform}/*/libstdc++-v3; do
+  test -d $d || continue
+  d33=`dirname $d`/libstdc++33-v3
+  b=""
+  test x"$d" != x%{gcc_target_platform}/libstdc++-v3 && b=/`basename $(dirname $d)`
+  install -m 644 $d/libsupc++/.libs/libsupc++.a $FULLPATH$b/
+  install -m 644 $d/src/.libs/libstdc++.a $FULLPATH$b/
+  strip -g $FULLPATH$b/*.a
+  install -m 644 $d/src/.libs/libstdc++.so $FULLPATH$b/
+
+  mkdir -p $FULLPATH33$b
+  install -m 644 $d33/libsupc++/.libs/libsupc++.a $FULLPATH33$b/
+  install -m 644 $d33/src/.libs/libstdc++.a $FULLPATH33$b/
+  strip -g $FULLPATH33$b/*.a
+  install -m 644 $d33/src/.libs/libstdc++.so $FULLPATH33$b/
+done
+
+mkdir -p $RPM_BUILD_ROOT/%{_lib}
+install -m755 %{gcc_target_platform}/libstdc++33-v3/src/.libs/libstdc++.so.5.0* \
+  $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
+/sbin/ldconfig -n $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
+
+rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgcc_s*
+
+cd ..
+
+for i in $RPM_BUILD_ROOT%{_prefix}/bin/{*gcc,*++,gcov}; do
+  mv -f $i ${i}32
+done
+
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib*/{libiberty.a,*/libiberty.a}
+rm -f $RPM_BUILD_ROOT/lib*/libgcc_s*
+
+%ifarch %{multilib_64_archs}
+# Remove libraries for the other arch on multilib arches
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.so*
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.a
+%else
+%ifarch sparc sparcv9 ppc
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.so*
+rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.a
+%endif
+%endif
+
+rm -rf $RPM_BUILD_ROOT%{_prefix}/{lib/gcc-lib,bin,include}
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -n compat-libstdc++-33 -p /sbin/ldconfig
+
+%postun -n compat-libstdc++-33 -p /sbin/ldconfig
+
+%files -n compat-libstdc++-33
+%defattr(-,root,root)
+%{_prefix}/%{_lib}/libstdc++.so.5*
+
+%changelog
+* Tue Nov  4 2014 Jakub Jelinek  <jakub@redhat.com> 3.2.3-72
+- rebuilt against fixed glibc to avoid infinite recursion in btowc (#1159772)
+
+* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 3.2.3-71
+- Mass rebuild 2014-01-24
+
+* Tue Jan  7 2014 Jakub Jelinek  <jakub@redhat.com> 3.2.3-70
+- filter out -fstack-protector-strong, -grecord-gcc-switches and new
+  i686, ppc and s390 tunings (#1048850)
+
+* Wed Aug 28 2013 Jakub Jelinek  <jakub@redhat.com> 3.2.3-69
+- add %%{?dist} to release (#874993)
+
+* Wed Feb 20 2013 Jakub Jelinek  <jakub@redhat.com> 3.2.3-68.7
+- use siginfo_t instead of struct siginfo
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.3-68.6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Mon Oct 15 2012 Jon Ciesla <limburgher@gmail.com> - 3.2.3-68.5
+- Provides: bundled(libiberty)
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.3-68.4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Feb 28 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.3-68.3
+- Rebuilt for c++ ABI breakage
+
+* Thu Jan 12 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.3-68.2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.3-68.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Thu Sep 17 2009 Jakub Jelinek  <jakub@redhat.com> 3.2.3-68
+- strip -march=z9-109 and -mtune=z10 from OPT_FLAGS on s390, s390x
+  (#523209)
+- make sure to use system libgcc_s.so.1 instead of gcc32 one during
+  testing
+
+* Tue Jul 28 2009 Jakub Jelinek  <jakub@redhat.com> 3.2.3-67
+- replace -mtune=generic in $RPM_OPT_FLAGS with something that
+  GCC 3.2.3 groks
+
+* Mon Mar  9 2009 Jakub Jelinek  <jakub@redhat.com> 3.2.3-66
+- fix up for latest bison
+
+* Sat Feb 14 2009 Dennis Gilmore <dennis@ausil.us> - 3.2.3-65
+- fix to build 32 bit sparc sparcv9
+
+* Tue Jul 15 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 3.2.3-64
+- fix license tag
+- apply patches with fuzz=2
+
+* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 3.2.3-63
+- Autorebuild for GCC 4.3
+
+* Tue Oct  9 2007 Jakub Jelinek  <jakub@redhat.com> 3.2.3-62
+- rebuilt
+
+* Mon Aug 21 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-61
+- fix the ppc*/s390* math *l stub changes
+
+* Fri Aug 18 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-60
+- on ppc*/s390* make sure all needed math *l stubs are included
+
+* Thu Aug 10 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-59
+- fix cleaning up the buildroot before debuginfo generation
+
+* Thu Aug 10 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-58
+- include only compat-libstdc++-33 subpackage
+
+* Thu Aug  3 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-57
+- in 64-bit builds remove 32-bit /usr/lib/lib* libraries from the
+  buildroots (and similarly on 32-bit builds remove 64-bit /usr/lib64/lib*)
+  before AutoReq generation
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 3.2.3-55.fc5.1
+- rebuild
+
+* Sat Feb 11 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-55.fc5
+- replace -mtune=generic in $RPM_OPT_FLAGS with something that
+  GCC 3.2.3 groks
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 3.2.3-54.fc5.2
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 3.2.3-54.fc5.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Wed Jan  4 2006 Jakub Jelinek  <jakub@redhat.com> 3.2.3-54.fc5
+- rebuilt with new gcc, massage $RPM_OPT_FLAGS, as GCC 3.2.3-RH doesn't
+  grok -fstack-protector etc.
+- make sure glibc and glibc-devel for all multilib arches is installed
+  for building (#170601)
+- fix compat-libstdc++-33 %%description (#171684)
+- disable os_defines.h changes introduced in 3.2.3-45 also for
+  IBM xlC compiler (#146196, IT#75174)
+- fix pushdecl_class_level for OVERLOADs (Mark Mitchell,
+  Alexandre Oliva, #156185)
+- reword diagnostics about unresolved overloaded type
+  (Alexandre Oliva, #156291, IT#70101)
+- fix x86_64 compiler hang when passing object with 3+ base classes by value
+  (Zak Kipling, PR target/18300, #164421, #171940, IT#76454)
+- predefine __GNUC_RH_RELEASE__ macro to rpm's %%{release} (Alexandre Oliva)
+- weakref attribute support, use it in <bits/gthr.h> various C++ headers
+  are using (Alexandre Oliva, #165728, IT#73356)
+- don't warn in templates about missing return if return type is dependent
+  on template parameters (Alexandre Oliva, PR c++/13106, #169044, IT#77857)
+- ensure ppc64 keeps stack 16 byte aligned even with dynamic allocation
+  (alloca, VLAs), but don't rely on it in the generated code
+  (Alexandre Oliva, #169111, IT#76136)
+- fix invalid CC clobberation on i?86/x86_64 (Eric Botcazou,
+  PR optimization/12799, #169654)
+- don't assume hard frame pointer register is STACK_BOUNDARY aligned
+  if frame pointer isn't used and the register has been reused
+  for something else (Eric Botcazou, PR optimization/13041, #169845)
+- fix libstdc++ seekoff bug (Scott Snyder, #151692, IT#66065,
+  PR libstdc++/9659)
+- don't use .symver directives in libstdc++.a, instead
+  provide hidden aliases for the obsolete symbols (#151732, IT#64710)
+- fix a strength reduction bug (Jan Hubicka, #149250, IT#66328)
+- fix xchgb constraints on i386 (#156104, IT#69633, PR target/19005)
+- change __cxa_demangle to match cxx-abi change
+  http://www.codesourcery.com/archives/cxx-abi-dev/msg01877.html
+  (Jason Merrill, #133406)
+- fix ICE on invalid use of template without arguments as primary
+  expression (Mark Mitchell, #149492, PR c++/10558)
+- fix c++filt/__cxa_demangle segfault on invalidly mangled names
+  generated by G++ 3.4 (Ian Lance Taylor, #145781, PR c++/16240)
+- disable os_defines.h changes introduced in 3.2.3-45 for non-GCC
+  compilers (#144725, #146196)
+- fix debugging information in in-charge constructors and
+  destructors (Mark Mitchell, #146416, PR debug/11098)
+- fix delete_null_pointer_checks on non-cc0 targets (Alan Modra, #141694,
+  IT#54408, PR rtl-optimization/14279)
+- fix some reload related issues on ppc64 (David Edelsohn, #139099,
+  IT#45622, PRs target/16239, target/8480, optimization/8328)
+- fix ICE in regenerate_decl_from_template (Mark Mitchell, #142418,
+  PR c++/7053)
+- fix ICE when printing jump to case label... crosses initialization
+  warning (Gabriel Dos Reis, #140830, PR c++/7566)
+- fix corner case in passing by invisible reference (Alexandre Oliva,
+  IT#54891, #141270)
+- fix ICE on code that uses value of reference in reference's initializer
+  (Alexandre Oliva, #141274, IT#36304)
+- avoid moving jumptable away from corresponding jump even if there is an
+  intervening barrier (Josef Zlomek, #131378)
+- with -D_GLIBCXX_FULLY_DYNAMIC_STRING, STL should now avoid
+  _S_empty_rep_storage (Paolo Carlini, #131030, IT#45103, PR libstdc++/16612)
+- document -Winline only works for languages that use RTL inliner (Java,
+  Ada, #141272, IT#28331)
+
+* Tue Mar  8 2005 Jakub Jelinek  <jakub@redhat.com> 3.2.3-47.fc4
+- new compatibility package