diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ed08283e301ffefd30b13fe3308a31f2536a4e9b..a4fb4c8fbad55e80222d8e8297ea673276456fc3 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,21 @@
+2005-06-08  Benjamin Kosnik  <bkoz@redhat.com>
+
+	PR libstdc++/21955
+	* include/std/std_sstream.h (basic_stringbuf::showmanyc): Add.
+	Remove unnecessary this->_M_mode decoration.
+	* include/bits/fstream.tcc: Adjust line spacing.	
+	* testsuite/27_io/basic_streambuf/in_avail/char/1.cc: New, test
+	base class behavior.
+	* testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc: Same.
+	* testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc: New.
+	* testsuite/27_io/basic_stringbuf/in_avail/char/1.cc: Match
+	filebuf behavior.
+	* testsuite/27_io/basic_stringbuf/in_avail/wchar_t/1.cc: Same.
+	* testsuite/27_io/basic_stringbuf/str/wchar_t/1.cc: Same.
+	* testsuite/27_io/basic_stringbuf/str/char/1.cc: Same.
+	* testsuite/27_io/basic_streambuf/in_avail/char/9701-3.cc: Move...
+	* testsuite/27_io/basic_filebuf/in_avail/char/9701-3.cc: ...here.
+	
 2005-06-07  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* acinclude.m4 (GLIBCXX_ENABLE_C99): Use C++ compiler for complex
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 40bf428e2c1f726206fbdb47be9d003f077a0897..0228322f2ea57b5d87d9f63a16b113294b647a70 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -203,8 +203,7 @@ namespace std
 	    return traits_type::to_int_type(*this->gptr());
 
 	  // Get and convert input sequence.
-	  const size_t __buflen = _M_buf_size > 1
-	                          ? _M_buf_size - 1 : 1;
+	  const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
 
 	  // Will be set to true if ::read() returns 0 indicating EOF.
 	  bool __got_eof = false;
diff --git a/libstdc++-v3/include/std/std_sstream.h b/libstdc++-v3/include/std/std_sstream.h
index 66215b2f730de5556f8f2c9e9d9331d8bf6ceaae..52c416f85b922c5cda10cb4571cedf577cea46f6 100644
--- a/libstdc++-v3/include/std/std_sstream.h
+++ b/libstdc++-v3/include/std/std_sstream.h
@@ -1,6 +1,6 @@
 // String based streams -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004, 2005
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -127,16 +127,18 @@ namespace std
       __string_type
       str() const
       {
+	__string_type __ret;
 	if (this->pptr())
 	  {
 	    // The current egptr() may not be the actual string end.
 	    if (this->pptr() > this->egptr())
-	      return __string_type(this->pbase(), this->pptr());
+	      __ret = __string_type(this->pbase(), this->pptr());
 	    else
- 	      return __string_type(this->pbase(), this->egptr());
+ 	      __ret = __string_type(this->pbase(), this->egptr());
 	  }
 	else
-	  return _M_string;
+	  __ret = _M_string;
+	return __ret;
       }
 
       /**
@@ -151,7 +153,7 @@ namespace std
       {
 	// Cannot use _M_string = __s, since v3 strings are COW.
 	_M_string.assign(__s.data(), __s.size());
-	_M_stringbuf_init(this->_M_mode);
+	_M_stringbuf_init(_M_mode);
       }
 
     protected:
@@ -159,14 +161,25 @@ namespace std
       void
       _M_stringbuf_init(ios_base::openmode __mode)
       {
-	this->_M_mode = __mode;
-
+	_M_mode = __mode;
 	__size_type __len = 0;
-	if (this->_M_mode & (ios_base::ate | ios_base::app))
+	if (_M_mode & (ios_base::ate | ios_base::app))
 	  __len = _M_string.size();
 	_M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
       }
 
+      virtual streamsize
+      showmanyc()
+      { 
+	streamsize __ret = -1;
+	if (_M_mode & ios_base::in)
+	  {
+	    _M_update_egptr();
+	    __ret = this->egptr() - this->gptr();
+	  }
+	return __ret;
+      }
+
       virtual int_type
       underflow();
 
@@ -223,8 +236,8 @@ namespace std
       void
       _M_sync(char_type* __base, __size_type __i, __size_type __o)
       {
-	const bool __testin = this->_M_mode & ios_base::in;
-	const bool __testout = this->_M_mode & ios_base::out;
+	const bool __testin = _M_mode & ios_base::in;
+	const bool __testout = _M_mode & ios_base::out;
 	char_type* __end = __base + _M_string.size();
 
 	if (__testin)
@@ -252,8 +265,7 @@ namespace std
       void
       _M_update_egptr()
       {
-	const bool __testin = this->_M_mode & ios_base::in;
-
+	const bool __testin = _M_mode & ios_base::in;
 	if (this->pptr() && this->pptr() > this->egptr())
 	  if (__testin)
 	    this->setg(this->eback(), this->gptr(), this->pptr());
diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/9701-3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/in_avail/char/9701-3.cc
similarity index 100%
rename from libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/9701-3.cc
rename to libstdc++-v3/testsuite/27_io/basic_filebuf/in_avail/char/9701-3.cc
diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/9701-3.cc b/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/1.cc
similarity index 57%
rename from libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/9701-3.cc
rename to libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/1.cc
index 239f790fe473a124a2cfebef5ed8146e47b265c3..ee9a81c816d586a2f36fc6299968f91e202f589a 100644
--- a/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/9701-3.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/1.cc
@@ -1,4 +1,6 @@
-// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+// 2005-06-07 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 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
@@ -16,44 +18,37 @@
 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 // USA.
 
-// 27.5.2.2.3 Get area
+// 27.8.1.4 Overridden virtual functions
 
 #include <fstream>
 #include <testsuite_hooks.h>
 
-class Derived_fbuf : public std::wfilebuf
-{
-public:
-  const char_type* pub_egptr() const
-  { return egptr(); }
+typedef std::basic_streambuf<char> 	streambuf_type;
 
-  const char_type* pub_gptr() const
-  { return gptr(); }
+struct testbuf : streambuf_type
+{
+  testbuf() { }
 };
 
-// libstdc++/9701 (in_avail)
-void test01()
+void test05() 
 {
-  using namespace std;
-  bool test __attribute__((unused)) = true;
-  const char* name = "tmp_file1_w";
+  typedef streambuf_type::int_type 	int_type;
+  typedef streambuf_type::traits_type 	traits_type;
+  typedef streambuf_type::pos_type 	pos_type;
+  typedef streambuf_type::off_type 	off_type;
+  typedef size_t 			size_type;
 
-  Derived_fbuf df2;
-  df2.open(name, ios_base::in | ios_base::out | ios_base::trunc);
-
-  df2.sputn(L"Comomoc", 7);
-
-  df2.pubseekoff(0, ios_base::beg);
-  df2.sbumpc();
-  df2.sputbackc(L't');
+  bool test __attribute__((unused)) = true;
+  std::streamoff  			strmof_1, strmof_2;
+  testbuf	sb01;
 
-  VERIFY( df2.pub_gptr() < df2.pub_egptr() );
-  VERIFY( df2.in_avail() == df2.pub_egptr() - df2.pub_gptr() );
+  // int in_avail()
+  strmof_1 = sb01.in_avail();
+  VERIFY( strmof_1  == 0 ); 
 }
 
-int
-main()
+int main() 
 {
-  test01();
+  test05();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fd10c0b0d9d584586a9f6a9b221329bd8056ca95
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc
@@ -0,0 +1,54 @@
+// 2005-06-07 Benjamin Kosnik  <bkoz@redhat.com>
+
+// Copyright (C) 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
+// 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.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+typedef std::basic_streambuf<wchar_t> 	streambuf_type;
+
+struct testbuf : streambuf_type
+{
+  testbuf() { }
+};
+
+void test05() 
+{
+  typedef streambuf_type::int_type 	int_type;
+  typedef streambuf_type::traits_type 	traits_type;
+  typedef streambuf_type::pos_type 	pos_type;
+  typedef streambuf_type::off_type 	off_type;
+  typedef size_t 			size_type;
+
+  bool test __attribute__((unused)) = true;
+  std::streamoff  			strmof_1, strmof_2;
+  testbuf	sb01;
+
+  // int in_avail()
+  strmof_1 = sb01.in_avail();
+  VERIFY( strmof_1  == 0 ); 
+}
+
+int main() 
+{
+  test05();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc
index 99942f766101603691ddc7445755b3ad755a2398..5833c9652c933f5c7da7302e003c0469b6a9eada 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc
@@ -1,6 +1,6 @@
 // 981208 bkoz test functionality of basic_stringbuf for char_type == char
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -43,8 +43,8 @@ void test04()
   VERIFY( strmof_1 == static_cast<std::streamoff>(str_01.length()) );
   VERIFY( strmof_2 == static_cast<std::streamoff>(str_02.length()) );
   strmof_1 = strb_03.in_avail(); 
-  // zero cuz write-only, or eof()? zero, from showmany
-  VERIFY( strmof_1 == 0 ); 
+  // zero cuz write-only, or eof() to match basic_filebuf
+  VERIFY( strmof_1 == -1 ); 
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc
new file mode 100644
index 0000000000000000000000000000000000000000..023418cfd64988a405bb4c48981ef9db856b1670
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc
@@ -0,0 +1,54 @@
+// 2005-06-07 Benjamin Kosnik
+
+// Copyright (C) 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
+// 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.
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <stdexcept>
+
+double  
+test_stringstream()
+{
+  double result;
+  char* source = "1918"; 
+  std::stringstream s;
+  s << source;
+
+  std::string tmp = s.str();
+  std::streambuf* sb = s.rdbuf();
+  int i = sb->in_avail();
+
+  if (i)
+    {
+      s >> result;
+    }
+  else
+    {
+      throw std::runtime_error("conversion failed");
+    }
+  return result;
+}
+
+
+int main ()
+{
+  test_stringstream();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/wchar_t/1.cc
index ed6f2484dbc3a6071b93d856a698bfccd04cbfef..346a4db1baf658269ee8c0643204055418581381 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/wchar_t/1.cc
@@ -1,6 +1,6 @@
 // 981208 bkoz test functionality of basic_stringbuf for char_type == wchar_t
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -43,8 +43,8 @@ void test04()
   VERIFY( strmof_1 == static_cast<std::streamoff>(str_01.length()) );
   VERIFY( strmof_2 == static_cast<std::streamoff>(str_02.length()) );
   strmof_1 = strb_03.in_avail(); 
-  // zero cuz write-only, or eof()? zero, from showmany
-  VERIFY( strmof_1 == 0 ); 
+  // zero cuz write-only, or eof() to match basic_filebuf
+  VERIFY( strmof_1 == -1 ); 
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc
index 2f9a5cf176f1c6459642ebbca776d375f5e8ef07..d788f1274c2bd2a1891098e643692d03cc7c600b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc
@@ -1,6 +1,6 @@
 // 981208 bkoz test functionality of basic_stringbuf for char_type == char
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -45,7 +45,7 @@ void test03()
   std::streamsize d1 = strb_01.in_avail();
   std::streamsize d2 = strb_03.in_avail();
   VERIFY( d1 ); // non-zero
-  VERIFY( !d2 ); // zero, cuz ios_base::out
+  VERIFY( d2 == -1 ); // -1, cuz ios_base::out
   VERIFY( d1 != d2 ); //these should be the same
   VERIFY( static_cast<std::streamsize>(str_01.length()) == d1 );  
   VERIFY( strb_01.str() == strb_03.str() ); //ditto
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/1.cc
index 4c89bc932c7d94c5b439fbc50ee9ec955f705d3d..cc0e0ab2dcddb2967479dc3dd118f56af7dca04b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/1.cc
@@ -1,6 +1,6 @@
 // 981208 bkoz test functionality of basic_stringbuf for char_type == wchar_t
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -45,7 +45,7 @@ void test03()
   std::streamsize d1 = strb_01.in_avail();
   std::streamsize d2 = strb_03.in_avail();
   VERIFY( d1 ); // non-zero
-  VERIFY( !d2 ); // zero, cuz ios_base::out
+  VERIFY( d2 == -1 ); // -1, cuz ios_base::out
   VERIFY( d1 != d2 ); //these should be the same
   VERIFY( static_cast<std::streamsize>(str_01.length()) == d1 );  
   VERIFY( strb_01.str() == strb_03.str() ); //ditto