diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 773a5fce30ce1f97afbe6f954fc1d49f7446c9d5..e45415e10aa1027916e6ae1160f69528b6d8a4ca 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,11 @@
+2005-04-01  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+	* gcj.texi (Invoking gij): Add descriptions of new -X options.
+	Mention recognized-and-ignored compatibility options.
+	(Memory allocation): Add descriptions of JvMalloc, JvRealloc and
+	JvFree.
+	(About CNI): Add Memory allocation section.
+
 2005-04-01  Tom Tromey  <tromey@redhat.com>
 
 	* decl.c (java_init_decl_processing): Fix types of
diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi
index df693c057a0a594d52b941739fb67ef9fcf2367d..e71511af7708ae637e768057faf3147d2f5d26f7 100644
--- a/gcc/java/gcj.texi
+++ b/gcc/java/gcj.texi
@@ -949,16 +949,26 @@ be retrieved at runtime using the @code{java.lang.System.getProperty}
 method.
 
 @item -ms=@var{number}
-This sets the initial heap size.
+Equivalent to @code{-Xms}.
 
 @item -mx=@var{number}
-This sets the maximum heap size.
+Equivalent to @code{-Xmx}.
 
 @item -X
 @itemx -X@var{argument}
 Supplying @code{-X} by itself will cause @code{gij} to list all the
-supported @code{-X} options.  Currently there are none.  Unrecognized
-@code{-X} options are ignored, for compatibility with other runtimes.
+supported @code{-X} options.  Currently these options are supported:
+
+@table @gcctabopt
+@item -Xms@var{size}
+Set the initial heap size.
+
+@item -Xmx@var{size}
+Set the maximum heap size.
+@end table
+
+Unrecognized @code{-X} options are ignored, for compatibility with
+other runtimes.
 
 @item -jar
 This indicates that the name passed to @code{gij} should be interpreted
@@ -971,6 +981,9 @@ Print help, then exit.
 @item --showversion
 Print version number and continue.
 
+@item --fullversion
+Print detailed version information, then exit.
+
 @item --version
 Print version number, then exit.
 
@@ -979,6 +992,12 @@ Print version number, then exit.
 Each time a class is initialized, print a short message on standard error.
 @end table
 
+@code{gij} also recognizes and ignores the following options, for
+compatibility with existing application launch scripts:
+@code{-client}, @code{-server}, @code{-hotspot}, @code{-jrockit},
+@code{-agentlib}, @code{-agentpath}, @code{-debug}, @code{-d32},
+@code{-d64}, @code{-javaagent} and @code{-noclassgc}.
+
 @c man end
 
 @node Invoking gcj-dbtool
@@ -1250,6 +1269,7 @@ alternative to the standard JNI (Java Native Interface).
 * Objects and Classes::         C++ and Java classes.
 * Class Initialization::        How objects are initialized.
 * Object allocation::           How to create Java objects in C++.
+* Memory allocation::           How to allocate and free memory.
 * Arrays::                      Dealing with Java arrays in C++.
 * Methods::                     Java methods in C++.
 * Strings::                     Information about Java Strings.
@@ -1630,6 +1650,27 @@ java::util::Hashtable *ht = new java::util::Hashtable(120);
 @end example
 
 
+@node Memory allocation
+@section Memory allocation
+
+When allocting memory in @acronym{CNI} methods it is best to handle
+out-of-memory conditions by throwing a Java exception.  These
+functions are provided for that purpose:
+
+@deftypefun void* JvMalloc (jsize @var{size})
+Calls malloc.  Throws @code{java.lang.OutOfMemoryError} if allocation
+fails.
+@end deftypefun
+
+@deftypefun void* JvRealloc (void* @var{ptr}, jsize @var{size})
+Calls realloc.  Throws @code{java.lang.OutOfMemoryError} if
+reallocation fails.
+@end deftypefun
+
+@deftypefun void JvFree (void* @var{ptr})
+Calls free.
+@end deftypefun
+
 @node Arrays
 @section Arrays
 
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 50b0f95b6a54a5d6e68609338c4ce23907f1b118..3492f48e1875998ec44f8b0e46acf77ab87da34b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,27 @@
+2005-04-01  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+	PR libgcj/20090, PR libgcj/20526
+	* gij.cc (nonstandard_opts_help): New function.
+	(add_option): New function.
+	(main): Support java options.  Set java.class.path.  Don't set
+	_Jv_Jar_Class_Path.
+	* prims.cc (parse_x_arg): New function.
+	(parse_init_args): Call parse_x_arg for -X and _ options, when
+	ignoreUnrecognized is true.
+	(new _Jv_RunMain): New vm_args variant.
+	(old _Jv_RunMain): Call new vm_args _Jv_RunMain.
+	(_Jv_Jar_Class_Path): Remove variable.
+	* include/java-props.h: Likewise.
+	* include/cni.h (JvRealloc): New function.
+	* include/jvm.h (_Jv_RunMain): Declare vm_args variant.
+	* java/lang/natRuntime.cc (insertSystemProperties): Remove
+	_Jv_Jar_Class_Path logic.  Use JV_VERSION and JV_API_VERSION
+	macros.
+	* configure.ac (JV_VERSION): Define.
+	(JV_API_VERSION): Likewise.
+	* configure: Regenerate.
+	* include/config.h.in: Regenerate.
+
 2005-04-01 Mark Anderson <mark@panonet.net>
 
 	* java/lang/natDouble.cc (parseDouble): Handle NaN, Infinity and
diff --git a/libjava/configure b/libjava/configure
index 1373373f0bfbe9ebaecb6bdc7eb6de041c8da8bc..20b22660b7aee3e5c66a54788e660eec13076287 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -13829,6 +13829,17 @@ _ACEOF
 
 
 
+cat >>confdefs.h <<\_ACEOF
+#define JV_VERSION "1.4.2"
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define JV_API_VERSION "1.4"
+_ACEOF
+
+
+
 case "${with_gxx_include_dir}" in
   yes)
     { { echo "$as_me:$LINENO: error: --with-gxx-include-dir=[dir] requires a directory" >&5
diff --git a/libjava/configure.ac b/libjava/configure.ac
index 2df1385c099ec0c3caa73ef11c86f3202fd04b52..2c958a9f3c98b78c6fdc7809cd7059f55d6de1dc 100644
--- a/libjava/configure.ac
+++ b/libjava/configure.ac
@@ -1196,6 +1196,9 @@ GCJVERSION=$gcjversion
 AC_SUBST(GCJVERSION)
 AC_DEFINE_UNQUOTED(GCJVERSION, "$GCJVERSION", [Short GCJ version ID])
 
+AC_DEFINE(JV_VERSION, "1.4.2", [Compatibility version string])
+AC_DEFINE(JV_API_VERSION, "1.4", [API compatibility version string])
+
 TL_AC_GXX_INCLUDE_DIR
 
 # We check for sys/filio.h because Solaris 2.5 defines FIONREAD there.
diff --git a/libjava/gcj/cni.h b/libjava/gcj/cni.h
index 4aea4b6e4a7b6490859b112e91ba23de01a097fd..b94260b8465bd53ccaec7680f823dc7a6ec2daad 100644
--- a/libjava/gcj/cni.h
+++ b/libjava/gcj/cni.h
@@ -108,6 +108,12 @@ JvMalloc (jsize size)
   return _Jv_Malloc (size);
 }
 
+extern inline void *
+JvRealloc (void *ptr, jsize size)
+{
+  return _Jv_Realloc (ptr, size);
+}
+
 extern inline void
 JvFree (void *ptr)
 {
diff --git a/libjava/gij.cc b/libjava/gij.cc
index 1894d9b9c968c4ecc0b771ec5d1d72d53197e17d..6eee6b5a40adee7d521afedde30704f67b16da1e 100644
--- a/libjava/gij.cc
+++ b/libjava/gij.cc
@@ -1,26 +1,20 @@
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004  Free Software Foundation
+/* Copyright (C) 1999-2005  Free Software Foundation
 
    This file is part of libgcj.
 
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-/* Author: Kresten Krab Thorup <krab@gnu.org>  */
+   This software is copyrighted work licensed under the terms of the
+   Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+   details. */
 
 #include <config.h>
 
 #include <jvm.h>
 #include <gcj/cni.h>
-#include <java-props.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#include <java/lang/System.h>
-#include <java/util/Properties.h>
-
 static void
 help ()
 {
@@ -46,105 +40,262 @@ help ()
 static void
 version ()
 {
+  printf ("java version " JV_VERSION "\n");
   printf ("gij (GNU libgcj) version %s\n\n", __VERSION__);
   printf ("Copyright (C) 2005 Free Software Foundation, Inc.\n");
   printf ("This is free software; see the source for copying conditions.  There is NO\n");
   printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
 }
 
+static void
+nonstandard_opts_help ()
+{
+  printf ("  -Xms<size>         set initial heap size\n");
+  printf ("  -Xmx<size>         set maximum heap size\n");
+  exit (0);
+}
+
+static void
+add_option (JvVMInitArgs& vm_args, char const* option, void const* extra)
+{
+  vm_args.options =
+    (JvVMOption*) JvRealloc (vm_args.options,
+                             (vm_args.nOptions + 1) * sizeof (JvVMOption));
+
+  vm_args.options[vm_args.nOptions].optionString = const_cast<char*> (option);
+  vm_args.options[vm_args.nOptions].extraInfo = const_cast<void*> (extra);
+  ++vm_args.nOptions;
+}
+
 int
-main (int argc, const char **argv)
+main (int argc, char const** argv)
 {
-  /* We rearrange ARGV so that all the -D options appear near the
-     beginning.  */
-  int last_D_option = 0;
+  JvVMInitArgs vm_args;
   bool jar_mode = false;
 
+  vm_args.options = NULL;
+  vm_args.nOptions = 0;
+  vm_args.ignoreUnrecognized = true;
+
+  // Command-line options always override the CLASSPATH environment
+  // variable.
+  char *classpath = getenv("CLASSPATH");
+
+  if (classpath)
+    {
+      char* darg = (char*) JvMalloc (strlen (classpath)
+                                     + sizeof ("-Djava.class.path="));
+      sprintf (darg, "-Djava.class.path=%s", classpath);
+      add_option (vm_args, darg, NULL);
+    }
+
+  // Handle arguments to the java command.  Store in vm_args arguments
+  // handled by the invocation API.
   int i;
   for (i = 1; i < argc; ++i)
     {
-      const char *arg = argv[i];
+      char* arg = const_cast<char*> (argv[i]);
 
-      /* A non-option stops processing.  */
+      // A non-option stops processing.
       if (arg[0] != '-')
 	break;
-      /* A "--" stops processing.  */
+
+      // A "--" stops processing.
       if (! strcmp (arg, "--"))
 	{
 	  ++i;
 	  break;
 	}
 
-      if (! strncmp (arg, "-D", 2))
-	{
-	  argv[last_D_option++] = arg + 2;
-	  continue;
-	}
-
-      if (! strcmp (arg, "-jar"))
-	{
-	  jar_mode = true;
-	  continue;
-	}
-
-      /* Allow both single or double hyphen for all remaining
-	 options.  */
+      // Allow both single or double hyphen for all options.
       if (arg[1] == '-')
 	++arg;
 
-      if (! strcmp (arg, "-help") || ! strcmp (arg, "-?"))
-	help ();
-      else if (! strcmp (arg, "-version"))
-	{
-	  version ();
-	  exit (0);
-	}
-      else if (! strcmp (arg, "-showversion"))
-	version ();
-      /* FIXME: use getopt and avoid the ugliness here.
-	 We at least need to handle the argument in a better way.  */
-      else if (! strncmp (arg, "-ms=", 4))
-	_Jv_SetInitialHeapSize (arg + 4);
-      else if (! strcmp (arg, "-ms"))
-	{
-	  if (i >= argc - 1)
-	    {
+      // Ignore JIT options
+      if (! strcmp (arg, "-client"))
+        continue;
+      else if (! strcmp (arg, "-server"))
+        continue;
+      else if (! strcmp (arg, "-hotspot"))
+        continue;
+      else if (! strcmp (arg, "-jrockit"))
+        continue;
+      // Ignore JVM Tool Interface options
+      else if (! strncmp (arg, "-agentlib:", sizeof ("-agentlib:") - 1))
+        continue;
+      else if (! strncmp (arg, "-agentpath:", sizeof ("-agentpath:") - 1))
+        continue;
+      else if (! strcmp (arg, "-classpath") || ! strcmp (arg, "-cp"))
+        {
+          if (i >= argc - 1)
+            {
 	    no_arg:
 	      fprintf (stderr, "gij: option requires an argument -- `%s'\n",
 		       argv[i]);
 	      fprintf (stderr, "Try `gij --help' for more information.\n");
 	      exit (1);
-	    }
-	  _Jv_SetInitialHeapSize (argv[++i]);
+            }
+
+          // Sun seems to translate the -classpath option into
+          // -Djava.class.path because if both -classpath and
+          // -Djava.class.path are specified on the java command line,
+          // the last one always wins.
+          char* darg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Djava.class.path="));
+          sprintf (darg, "-Djava.class.path=%s", argv[i]);
+          add_option (vm_args, darg, NULL);
+        }
+      else if (! strcmp (arg, "-debug"))
+        {
+          char* xarg = strdup ("-Xdebug");
+          add_option (vm_args, xarg, NULL);
+        }
+      else if (! strncmp (arg, "-D", sizeof ("-D") - 1))
+        add_option (vm_args, arg, NULL);
+      // Ignore 32/64-bit JIT options
+      else if (! strcmp (arg, "-d32") || ! strcmp (arg, "-d64"))
+        continue;
+      else if (! strcmp (arg, "-enableassertions") || ! strcmp (arg, "-ea"))
+        {
+          if (i >= argc - 1)
+            goto no_arg;
+          // FIXME: hook up assertion support
+          ++i;
+          continue;
+        }
+      else if (! strcmp (arg, "-disableassertions") || ! strcmp (arg, "-da"))
+        {
+          if (i >= argc - 1)
+            goto no_arg;
+          // FIXME
+          ++i;
+          continue;
+        }
+      else if (! strcmp (arg, "-enablesystemassertions")
+               || ! strcmp (arg, "-esa"))
+        {
+          // FIXME: hook up system assertion support
+          continue;
+        }
+      else if (! strcmp (arg, "-disablesystemassertions")
+               || ! strcmp (arg, "-dsa"))
+        {
+          // FIXME
+          continue;
+        }
+      else if (! strcmp (arg, "-jar"))
+	{
+	  jar_mode = true;
+	  continue;
+	}
+      // Ignore java.lang.instrument option
+      else if (! strncmp (arg, "-javaagent:", sizeof ("-javaagent:") - 1))
+        continue;
+      else if (! strcmp (arg, "-noclassgc"))
+        {
+          char* xarg = strdup ("-Xnoclassgc");
+          add_option (vm_args, xarg, NULL);
+        }
+      // -ms=n
+      else if (! strncmp (arg, "-ms=", sizeof ("-ms=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 'm';
+          arg[3] = 's';
+          add_option (vm_args, arg, NULL);
+        }
+      // -ms n
+      else if (! strcmp (arg, "-ms"))
+	{
+	  if (i >= argc - 1)
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xms"));
+          sprintf (xarg, "-Xms%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
+	}
+      // -msn
+      else if (! strncmp (arg, "-ms", sizeof ("-ms") - 1))
+	{
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xms%s", arg + sizeof ("-Xms") - 1);
+          add_option (vm_args, xarg, NULL);
 	}
-      else if (! strncmp (arg, "-mx=", 4))
-	_Jv_SetMaximumHeapSize (arg + 4);
+      // -mx=n
+      else if (! strncmp (arg, "-mx=", sizeof ("-mx=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 'm';
+          arg[3] = 'x';
+          add_option (vm_args, arg, NULL);
+        }
+      // -mx n
       else if (! strcmp (arg, "-mx"))
 	{
 	  if (i >= argc - 1)
-	    goto no_arg;
-	  _Jv_SetMaximumHeapSize (argv[++i]);
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xmx"));
+          sprintf (xarg, "-Xmx%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
+	}
+      // -mxn
+      else if (! strncmp (arg, "-mx", sizeof ("-mx") - 1))
+	{
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xmx%s", arg + sizeof ("-Xmx") - 1);
+          add_option (vm_args, xarg, NULL);
 	}
-      else if (! strcmp (arg, "-cp") || ! strcmp (arg, "-classpath"))
+      // -ss=n
+      else if (! strncmp (arg, "-ss=", sizeof ("-ss=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 's';
+          arg[3] = 's';
+          add_option (vm_args, arg, NULL);
+        }
+      // -ss n
+      else if (! strcmp (arg, "-ss"))
 	{
 	  if (i >= argc - 1)
-	    goto no_arg;
-	  // We set _Jv_Jar_Class_Path.  If the user specified `-jar'
-	  // then the jar code will override this.  This is the
-	  // correct behavior.
-	  _Jv_Jar_Class_Path = argv[++i];
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xss"));
+          sprintf (xarg, "-Xss%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
 	}
-      else if (! strcmp (arg, "-verbose") || ! strcmp (arg, "-verbose:class"))
-	gcj::verbose_class_flag = true;
-      else if (arg[1] == 'X')
+      // -ssn
+      else if (! strncmp (arg, "-ss", sizeof ("-ss") - 1))
 	{
-	  if (arg[2] == '\0')
-	    {
-	      printf ("gij: currently no -X options are recognized\n");
-	      exit (0);
-	    }
-	  /* Ignore other -X options.  */
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xss%s", arg + sizeof ("-Xss") - 1);
+          add_option (vm_args, xarg, NULL);
 	}
+      // This handles all the option variants that begin with
+      // -verbose.
+      else if (! strncmp (arg, "-verbose", 8))
+        add_option (vm_args, arg, NULL);
+      else if (! strcmp (arg, "-version"))
+	{
+	  version ();
+	  exit (0);
+	}
+      else if (! strcmp (arg, "-fullversion"))
+        {
+          printf ("java full version \"gcj-" JV_VERSION "\"\n");
+          exit (0);
+        }
+      else if (! strcmp (arg, "-showversion"))
+        version ();
+      else if (! strcmp (arg, "-help") || ! strcmp (arg, "-?"))
+	help ();
+      else if (! strcmp (arg, "-X"))
+        nonstandard_opts_help ();
+      else if (! strncmp (arg, "-X", 2))
+        add_option (vm_args, arg, NULL);
       else
 	{
 	  fprintf (stderr, "gij: unrecognized option -- `%s'\n", argv[i]);
@@ -153,9 +304,6 @@ main (int argc, const char **argv)
 	}
     }
 
-  argv[last_D_option] = NULL;
-  _Jv_Compiler_Properties = argv;
-
   if (argc - i < 1)
     {
       fprintf (stderr, "Usage: gij [OPTION] ... CLASS [ARGS] ...\n");
@@ -166,5 +314,16 @@ main (int argc, const char **argv)
       exit (1);
     }
 
-  _Jv_RunMain (NULL, argv[i], argc - i, argv + i, jar_mode);
+  // -jar mode overrides all other modes of specifying class path:
+  // -CLASSPATH, -Djava.class.path, -classpath and -cp.
+  if (jar_mode)
+    {
+      char* darg = (char*) JvMalloc (strlen (argv[i])
+                                      + sizeof ("-Djava.class.path="));
+      sprintf (darg, "-Djava.class.path=%s", argv[i]);
+      add_option (vm_args, darg, NULL);
+    }
+
+  _Jv_RunMain (&vm_args, NULL, argv[i], argc - i,
+               (char const**) (argv + i), jar_mode);
 }
diff --git a/libjava/include/config.h.in b/libjava/include/config.h.in
index 8722869e280a3660c8ad898991c2640f596bd61f..04f8be0b7ff9ab7d56b5a652a63beab5d02e30dd 100644
--- a/libjava/include/config.h.in
+++ b/libjava/include/config.h.in
@@ -364,6 +364,9 @@
 /* Define if you want a bytecode interpreter. */
 #undef INTERPRETER
 
+/* API compatibility version string */
+#undef JV_API_VERSION
+
 /* Define if hash synchronization is in use */
 #undef JV_HASH_SYNCHRONIZATION
 
@@ -373,6 +376,9 @@
 /* Indicate that linker is not able to 8-byte align static data */
 #undef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
 
+/* Compatibility version string */
+#undef JV_VERSION
+
 /* Define if we want to use debug calls into the garbage collector. */
 #undef LIBGCJ_GC_DEBUG
 
diff --git a/libjava/include/java-props.h b/libjava/include/java-props.h
index 19d7106f8f22b897c0f59207ef21eebcd0159234..43020006e2a811e3f07bc01599e3dc5992eda7c2 100644
--- a/libjava/include/java-props.h
+++ b/libjava/include/java-props.h
@@ -23,9 +23,6 @@ typedef struct
 extern const char **_Jv_Compiler_Properties;
 extern int _Jv_Properties_Count;
 
-// The JAR file to add to the beginning of java.class.path.
-extern const char *_Jv_Jar_Class_Path;
-
 // Properties taken from the user's environment.
 extern property_pair *_Jv_Environment_Properties;
 
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index 7a5a4eaa28e0fb5027b34f377eb3d142d4996ffa..a95b7124aa853423bd25db6f6d6f03925fac52bf 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -360,6 +360,9 @@ extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
 void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
 		  bool is_jar);
 
+void _Jv_RunMain (struct _Jv_VMInitArgs *vm_args, jclass klass,
+                  const char *name, int argc, const char **argv, bool is_jar);
+
 // Delayed until after _Jv_AllocBytes is declared.
 //
 // Note that we allocate this as unscanned memory -- the vtables
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
index 248bf44b89c65ef20b9e58337d6a368727b2dcc5..d9529e8bb317ec9f03515da9f712d548b428269b 100644
--- a/libjava/java/lang/natRuntime.cc
+++ b/libjava/java/lang/natRuntime.cc
@@ -369,8 +369,8 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops)
   // (introduced in 1.2), and earlier versioning properties.  Some
   // programs rely on seeing values that they expect, so we claim to
   // be a 1.4-ish VM for their sake.
-  SET ("java.version", "1.4.2");
-  SET ("java.runtime.version", "1.4.2");
+  SET ("java.version", JV_VERSION);
+  SET ("java.runtime.version", JV_VERSION);
   SET ("java.vendor", "Free Software Foundation, Inc.");
   SET ("java.vendor.url", "http://gcc.gnu.org/java/");
   SET ("java.class.version", "46.0");
@@ -380,7 +380,7 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops)
   SET ("java.vm.version", __VERSION__);
   SET ("java.vm.vendor", "Free Software Foundation, Inc.");
   SET ("java.vm.name", "GNU libgcj");
-  SET ("java.specification.version", "1.4");
+  SET ("java.specification.version", JV_API_VERSION);
   SET ("java.specification.name", "Java(tm) Platform API Specification");
   SET ("java.specification.vendor", "Sun Microsystems Inc.");
 
@@ -569,30 +569,6 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops)
     }
 #endif
 
-  if (_Jv_Jar_Class_Path)
-    newprops->put(JvNewStringLatin1 ("java.class.path"),
- 		  JvNewStringLatin1 (_Jv_Jar_Class_Path));
-  else
-    {
-      // FIXME: find libgcj.zip and append its path?
-      char *classpath = ::getenv("CLASSPATH");
-      jstring cp = newprops->getProperty (JvNewStringLatin1("java.class.path"));
-      java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
-      
-      if (classpath)
-	{
-	  sb->append (JvNewStringLatin1 (classpath));
-	  sb->append (_Jv_platform_path_separator);
-	}
-      if (cp != NULL)
-	sb->append (cp);
-      else
-	sb->append ((jchar) '.');
-      
-      newprops->put(JvNewStringLatin1 ("java.class.path"),
-		      sb->toString ());
-    }
-
   // The name used to invoke this process (argv[0] in C).
   SET ("gnu.gcj.progname", _Jv_GetSafeArg (0));
 
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 5643902f27f59b53f793d7f89ce4907704de086a..7060171223819cdfdf14d1e62e595681d77996ab 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -85,9 +85,6 @@ static java::lang::OutOfMemoryError *no_memory;
 const char **_Jv_Compiler_Properties = NULL;
 int _Jv_Properties_Count = 0;
 
-// The JAR file to add to the beginning of java.class.path.
-const char *_Jv_Jar_Class_Path;
-
 #ifndef DISABLE_GETENV_PROPERTIES
 // Property key/value pairs.
 property_pair *_Jv_Environment_Properties;
@@ -909,9 +906,115 @@ namespace gcj
   bool runtimeInitialized = false;
 }
 
+// We accept all non-standard options accepted by Sun's java command,
+// for compatibility with existing application launch scripts.
+static jint
+parse_x_arg (char* option_string)
+{
+  if (strlen (option_string) <= 0)
+    return -1;
+
+  if (! strcmp (option_string, "int"))
+    {
+      // FIXME: this should cause the vm to never load shared objects
+    }
+  else if (! strcmp (option_string, "mixed"))
+    {
+      // FIXME: allow interpreted and native code
+    }
+  else if (! strcmp (option_string, "batch"))
+    {
+      // FIXME: disable background JIT'ing
+    }
+  else if (! strcmp (option_string, "debug"))
+    {
+      // FIXME: add JDWP/JVMDI support
+    }
+  else if (! strncmp (option_string, "bootclasspath:", 14))
+    {
+      // FIXME: add a parse_bootclasspath_arg function
+    }
+  else if (! strncmp (option_string, "bootclasspath/a:", 16))
+    {
+    }
+  else if (! strncmp (option_string, "bootclasspath/p:", 16))
+    {
+    }
+  else if (! strcmp (option_string, "check:jni"))
+    {
+      // FIXME: enable strict JNI checking
+    }
+  else if (! strcmp (option_string, "future"))
+    {
+      // FIXME: enable strict class file format checks
+    }
+  else if (! strcmp (option_string, "noclassgc"))
+    {
+      // FIXME: disable garbage collection for classes
+    }
+  else if (! strcmp (option_string, "incgc"))
+    {
+      // FIXME: incremental garbage collection
+    }
+  else if (! strncmp (option_string, "loggc:", 6))
+    {
+      if (option_string[6] == '\0')
+        {
+          fprintf (stderr,
+                   "libgcj: filename argument expected for loggc option\n");
+          return -1;
+        }
+      // FIXME: set gc logging filename
+    }
+  else if (! strncmp (option_string, "ms", 2))
+    {
+      // FIXME: ignore this option until PR 20699 is fixed.
+      // _Jv_SetInitialHeapSize (option_string + 2);
+    }
+  else if (! strncmp (option_string, "mx", 2))
+    _Jv_SetMaximumHeapSize (option_string + 2);
+  else if (! strcmp (option_string, "prof"))
+    {
+      // FIXME: enable profiling of program running in vm
+    }
+  else if (! strncmp (option_string, "runhprof:", 9))
+    {
+      // FIXME: enable specific type of vm profiling.  add a
+      // parse_runhprof_arg function
+    }
+  else if (! strcmp (option_string, "rs"))
+    {
+      // FIXME: reduced system signal usage.  disable thread dumps,
+      // only terminate in response to user-initiated calls,
+      // e.g. System.exit()
+    }
+  else if (! strncmp (option_string, "ss", 2))
+    {
+      // FIXME: set thread stack size
+    }
+  else if (! strcmp (option_string, "X:+UseAltSigs"))
+    {
+      // FIXME: use signals other than SIGUSR1 and SIGUSR2
+    }
+  else if (! strcmp (option_string, "share:off"))
+    {
+      // FIXME: don't share class data
+    }
+  else if (! strcmp (option_string, "share:auto"))
+    {
+      // FIXME: share class data where possible
+    }
+  else if (! strcmp (option_string, "share:on"))
+    {
+      // FIXME: fail if impossible to share class data
+    }
+
+  return 0;
+}
+
 static jint
 parse_verbose_args (char* option_string,
-		    bool ignore_unrecognized)
+                    bool ignore_unrecognized)
 {
   size_t len = sizeof ("-verbose");
 
@@ -1045,7 +1148,7 @@ parse_init_args (JvVMInitArgs* vm_args)
 			  "-verbose", sizeof ("-verbose") - 1))
 	{
 	  jint result = parse_verbose_args (option_string,
-					    vm_args->ignoreUnrecognized);
+                                            vm_args->ignoreUnrecognized);
 	  if (result < 0)
 	    return result;
 	}
@@ -1061,11 +1164,20 @@ parse_init_args (JvVMInitArgs* vm_args)
 	  continue;
 	}
       else if (vm_args->ignoreUnrecognized)
-	{
-	  if (option_string[0] == '_'
-	      || ! strncmp (option_string, "-X", 2))
-	    continue;
+        {
+          if (option_string[0] == '_')
+            parse_x_arg (option_string + 1);
+          else if (! strncmp (option_string, "-X", 2))
+            parse_x_arg (option_string + 2);
+          else
+            {
+            unknown_option:
+              fprintf (stderr, "libgcj: unknown option: %s\n", option_string);
+              return -1;
+            }
 	}
+      else
+        goto unknown_option;
     }
   return 0;
 }
@@ -1167,8 +1279,8 @@ _Jv_CreateJavaVM (JvVMInitArgs* vm_args)
 }
 
 void
-_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
-	     bool is_jar)
+_Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc,
+             const char **argv, bool is_jar)
 {
 #ifndef DISABLE_MAIN_ARGS
   _Jv_SetArgs (argc, argv);
@@ -1178,12 +1290,7 @@ _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
 
   try
     {
-      // Set this very early so that it is seen when java.lang.System
-      // is initialized.
-      if (is_jar)
-	_Jv_Jar_Class_Path = strdup (name);
-
-      if (_Jv_CreateJavaVM (NULL) < 0)
+      if (_Jv_CreateJavaVM (vm_args) < 0)
 	{
 	  fprintf (stderr, "libgcj: couldn't create virtual machine\n");
 	  exit (1);
@@ -1225,6 +1332,13 @@ _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
   runtime->exit (status);
 }
 
+void
+_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
+	     bool is_jar)
+{
+  _Jv_RunMain (NULL, klass, name, argc, argv, is_jar);
+}
+
 void
 JvRunMain (jclass klass, int argc, const char **argv)
 {