diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
index 3af43e6eb840e8a93391eea6411ce02b0fbc2b38..a89fba5baf387523070ba1ba41fa3f70654a2d58 100644
--- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java
+++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
@@ -23,16 +23,16 @@ public class Serialize
 {
   // This is the connection that the instance refers to
   protected org.postgresql.Connection conn;
-  
+
   // This is the table name
   protected String tableName;
-  
+
   // This is the class name
   protected String className;
-  
+
   // This is the Class for this serialzed object
   protected Class ourClass;
-  
+
   /**
    * This creates an instance that can be used to serialize or deserialize
    * a Java object from a PostgreSQL table.
@@ -41,16 +41,16 @@ public class Serialize
   {
     try {
       conn = c;
-      tableName = type.toLowerCase();
-      className = toClassName(type);
+      tableName = toPostgreSQL(type);
+      className = type;
       ourClass = Class.forName(className);
     } catch(ClassNotFoundException cnfe) {
       throw new PSQLException("postgresql.serial.noclass",type);
     }
-    
+
     // Second check, the type must be a table
     boolean status = false;
-    ResultSet rs = conn.ExecSQL("select typname from pg_type,pg_class where typname=relname and typname='"+type+"'");
+    ResultSet rs = conn.ExecSQL("select typname from pg_type,pg_class where typname=relname and typname='" + tableName + "'");
     if(rs!=null) {
       if(rs.next())
 	status=true;
@@ -59,10 +59,26 @@ public class Serialize
     // This should never occur, as org.postgresql has it's own internal checks
     if(!status)
       throw new PSQLException("postgresql.serial.table",type);
-    
+
     // Finally cache the fields within the table
   }
-  
+
+  /**
+   * Constructor when Object is passed in
+   */
+  public Serialize(org.postgresql.Connection c,Object o) throws SQLException
+  {
+    this(c, o.getClass().getName());
+  }
+
+  /**
+   * Constructor when Class is passed in
+   */
+  public Serialize(org.postgresql.Connection c, Class cls) throws SQLException
+  {
+    this(c, cls.getName());
+  }
+
   /**
    * This fetches an object from a table, given it's OID
    * @param oid The oid of the object
@@ -73,14 +89,20 @@ public class Serialize
   {
     try {
       Object obj = ourClass.newInstance();
-      
+
       // NB: we use java.lang.reflect here to prevent confusion with
       // the org.postgresql.Field
-      java.lang.reflect.Field f[] = ourClass.getDeclaredFields();
+
+      // used getFields to get only public fields. We have no way to set values
+      // for other declarations. Maybe look for setFieldName() methods?
+      java.lang.reflect.Field f[] = ourClass.getFields();
+
       boolean hasOID=false;
       int oidFIELD=-1;
       StringBuffer sb = new StringBuffer("select");
       char sep=' ';
+
+      // build a select for the fields. Look for the oid field to use in the where
       for(int i=0;i<f.length;i++) {
 	String n = f[i].getName();
 	if(n.equals("oid")) {
@@ -95,13 +117,37 @@ public class Serialize
       sb.append(tableName);
       sb.append(" where oid=");
       sb.append(oid);
-      
+
       DriverManager.println("store: "+sb.toString());
       ResultSet rs = conn.ExecSQL(sb.toString());
       if(rs!=null) {
 	if(rs.next()) {
 	  for(int i=0;i<f.length;i++) {
-	    f[i].set(obj,rs.getObject(i+1));
+            if ( !Modifier.isFinal(f[i].getModifiers()) ) {
+
+              if (f[i].getType().getName().equals("short")){
+                f[i].setShort(obj, rs.getShort(i+1));
+              }
+              else
+              if (f[i].getType().getName().equals("char")){
+                f[i].setChar(obj, rs.getString(i+1).toCharArray()[0]);
+              }
+              else
+              if (f[i].getType().getName().equals("byte")){
+                f[i].setByte(obj, rs.getByte(i+1));
+              }
+              else
+              // booleans come out of pgsql as a t or an f
+              if (f[i].getType().getName().equals("boolean")){
+                if ( rs.getString(i+1).equals("t"))
+                  f[i].setBoolean(obj, true);
+                else
+                  f[i].setBoolean(obj, false);
+              }
+              else{
+	        f[i].set(obj,rs.getObject(i+1));
+              }
+            }
 	  }
 	}
 	rs.close();
@@ -114,7 +160,7 @@ public class Serialize
       throw new SQLException(ie.toString());
     }
   }
-  
+
   /**
    * This stores an object into a table, returning it's OID.<p>
    *
@@ -138,24 +184,27 @@ public class Serialize
     try {
       // NB: we use java.lang.reflect here to prevent confusion with
       // the org.postgresql.Field
-      java.lang.reflect.Field f[] = ourClass.getDeclaredFields();
+
+      // don't save private fields since we would not be able to fetch them
+      java.lang.reflect.Field f[] = ourClass.getFields();
+
       boolean hasOID=false;
       int oidFIELD=-1;
       boolean update=false;
-      
+
       // Find out if we have an oid value
       for(int i=0;i<f.length;i++) {
 	String n = f[i].getName();
 	if(n.equals("oid")) {
 	  hasOID=true;
 	  oidFIELD=i;
-	  
+
 	  // We are an update if oid != 0
 	  update = f[i].getInt(o)>0;
 	}
       }
-      
-      StringBuffer sb = new StringBuffer(update?"update "+tableName+" set":"insert into "+tableName+" values ");
+
+      StringBuffer sb = new StringBuffer(update?"update "+tableName+" set":"insert into " + tableName);
       char sep=update?' ':'(';
       for(int i=0;i<f.length;i++) {
 	String n = f[i].getName();
@@ -164,49 +213,108 @@ public class Serialize
 	sep=',';
 	if(update) {
 	  sb.append('=');
-	  if(f[i].getType().getName().equals("java.lang.String")) {
+          // handle unset values
+          if (f[i].get(o) == null)
+            sb.append("null");
+          else
+	  if(f[i].getType().getName().equals("java.lang.String") ||
+             f[i].getType().getName().equals("char")) {
 	    sb.append('\'');
-	    sb.append(f[i].get(o).toString());
+            // don't allow single qoutes or newlines in the string
+	    sb.append(fixString(f[i].get(o).toString()));
 	    sb.append('\'');
 	  } else
 	    sb.append(f[i].get(o).toString());
 	}
       }
-      
+
       if(!update) {
 	sb.append(") values ");
 	sep='(';
 	for(int i=0;i<f.length;i++) {
-	  String n = f[i].getName();
-	  if(f[i].getType().getName().equals("java.lang.String")) {
+	  sb.append(sep);
+	  sep=',';
+          // handle unset values
+          if (f[i].get(o) == null)
+            sb.append("null");
+          else
+	  if(f[i].getType().getName().equals("java.lang.String") ||
+             f[i].getType().getName().equals("char")) {
 	    sb.append('\'');
-	    sb.append(f[i].get(o).toString());
+            // don't allow single quotes or newlines in the string
+	    sb.append(fixString(f[i].get(o).toString()));
 	    sb.append('\'');
 	  } else
 	    sb.append(f[i].get(o).toString());
 	}
 	sb.append(')');
       }
-      
+
       DriverManager.println("store: "+sb.toString());
-      ResultSet rs = conn.ExecSQL(sb.toString());
-      if(rs!=null) {
-	rs.close();
-      }
-      
+      org.postgresql.ResultSet rs = (org.postgresql.ResultSet)conn.ExecSQL(sb.toString());
+
       // fetch the OID for returning
       int oid=0;
       if(hasOID) {
-	// set the oid in the object
+	// If an update use the existing oid in the object
 	f[oidFIELD].setInt(o,oid);
       }
+      else {
+        String statStr = rs.getStatusString();
+        oid = Integer.parseInt(statStr.substring(statStr.indexOf(" ") + 1, statStr.lastIndexOf(" ")));
+      }
+
+      if(rs!=null) {
+	rs.close();
+      }
+
       return oid;
-      
+
     } catch(IllegalAccessException iae) {
       throw new SQLException(iae.toString());
     }
   }
-  
+
+  /**
+   *
+   */
+   private String fixString(String s) {
+
+   int idx = -1;
+
+     // handle null
+     if (s == null)
+       return "";
+
+     // if the string has single quotes in it escape them
+     if ((idx = s.indexOf("'")) > -1) {
+       StringBuffer buf = new StringBuffer();
+       StringTokenizer tok = new StringTokenizer(s, "'");
+       // handle quote as 1St charater
+       if (idx > 0) buf.append(tok.nextToken());
+
+       while(tok.hasMoreTokens())
+         buf.append("\\'").append(tok.nextToken());
+
+       s = buf.toString();
+     }
+
+     // if the string has newlines in it convert them to \n
+     if ((idx = s.indexOf("\n")) > -1) {
+       StringBuffer buf = new StringBuffer();
+       StringTokenizer tok = new StringTokenizer(s, "\n");
+       if (idx > 0) buf.append(tok.nextToken());
+
+       while(tok.hasMoreTokens())
+         buf.append("\\n").append(tok.nextToken());
+
+       s = buf.toString();
+     }
+
+     return s;
+
+   }
+
   /**
    * This method is not used by the driver, but it creates a table, given
    * a Serializable Java Object. It should be used before serializing any
@@ -219,7 +327,7 @@ public class Serialize
   {
     create(con,o.getClass());
   }
-  
+
   /**
    * This method is not used by the driver, but it creates a table, given
    * a Serializable Java Object. It should be used before serializing any
@@ -232,49 +340,50 @@ public class Serialize
   {
     if(c.isInterface())
       throw new PSQLException("postgresql.serial.interface");
-    
+
     // See if the table exists
     String tableName = toPostgreSQL(c.getName());
-    
+
     ResultSet rs = con.ExecSQL("select relname from pg_class where relname = '"+tableName+"'");
     if(!rs.next()) {
-      DriverManager.println("found "+rs.getString(1));
+//      DriverManager.println("found "+rs.getString(1));
       // No entries returned, so the table doesn't exist
-      
+
       StringBuffer sb = new StringBuffer("create table ");
       sb.append(tableName);
       char sep='(';
-      
-      java.lang.reflect.Field[] fields = c.getDeclaredFields();
+
+//      java.lang.reflect.Field[] fields = c.getDeclaredFields();
+      java.lang.reflect.Field[] fields = c.getFields();
       for(int i=0;i<fields.length;i++) {
 	Class type = fields[i].getType();
-	
+
 	// oid is a special field
 	if(!fields[i].getName().equals("oid")) {
 	  sb.append(sep);
 	  sb.append(fields[i].getName());
 	  sb.append(' ');
 	  sep=',';
-	  
+
 	  if(type.isArray()) {
 	    // array handling
 	  } else {
 	    // convert the java type to org.postgresql, recursing if a class
 	    // is found
-	    String n = fields[i].getType().getName();
+	    String n = type.getName();
 	    int j=0;
 	    for(;j<tp.length && !tp[j][0].equals(n);j++);
 	    if(j<tp.length)
 	      sb.append(tp[j][1]);
 	    else {
-	      create(con,fields[i].getType());
+	      create(con, type);
 	      sb.append(toPostgreSQL(n));
 	    }
 	  }
 	}
       }
       sb.append(")");
-      
+
       // Now create the table
       DriverManager.println("Serialize.create:"+sb);
       con.ExecSQL(sb.toString());
@@ -283,22 +392,26 @@ public class Serialize
       DriverManager.println("Serialize.create: table "+tableName+" exists, skipping");
     }
   }
-  
+
   // This is used to translate between Java primitives and PostgreSQL types.
   private static final String tp[][] = {
-    {"boolean",			"int1"},
+//    {"boolean",			"int1"},
+    {"boolean",			"bool"},
     {"double",			"float8"},
     {"float",			"float4"},
     {"int",			"int4"},
-    {"long",			"int4"},
+//    {"long",			"int4"},
+    {"long",			"int8"},
     {"short",			"int2"},
     {"java.lang.String",	"text"},
     {"java.lang.Integer",	"int4"},
     {"java.lang.Float",		"float4"},
     {"java.lang.Double",	"float8"},
-    {"java.lang.Short",		"int2"}
+    {"java.lang.Short",		"int2"},
+    {"char",                    "char"},
+    {"byte",                    "int2"}
   };
-  
+
   /**
    * This converts a Java Class name to a org.postgresql table, by replacing . with
    * _<p>
@@ -314,17 +427,25 @@ public class Serialize
   public static String toPostgreSQL(String name) throws SQLException
   {
     name = name.toLowerCase();
-    
+
     if(name.indexOf("_")>-1)
       throw new PSQLException("postgresql.serial.underscore");
-    
-    if(name.length()>32)
-      throw new PSQLException("postgresql.serial.namelength",name,new Integer(name.length()));
-    
+
+    // Postgres table names can only be 32 character long
+    // If the full class name with package is too long
+    // then just use the class name. If the class name is
+    // too long throw an exception.
+    if(name.length() > 32) {
+      name = name.substring(name.lastIndexOf(".") + 1);
+
+      if(name.length()>32)
+        throw new PSQLException("postgresql.serial.namelength",name,new Integer(name.length()));
+    }
+
     return name.replace('.','_');
   }
-  
-  
+
+
   /**
    * This converts a org.postgresql table to a Java Class name, by replacing _ with
    * .<p>
@@ -338,5 +459,5 @@ public class Serialize
     name = name.toLowerCase();
     return name.replace('_','.');
   }
-  
+
 }