public String toJSONString( HashMap<String,String> options )
    {
        boolean set = false;
        StringBuilder sb = new StringBuilder();
        int baseRow = -1;
        sb.append("{");
        // put table contents here
        if ( this.depth > 0 )
        {
            String localId = RandomId.getId( 32 );
            sb.append("\"id\":\"");
            sb.append( localId );
            sb.append( "\"," );
            sb.append("\"class\":\"inline\", ");
        }
        if ( options != null )
        {
            sb.append("\"options\": {");
            Set<String> keys = options.keySet();
            Iterator<String> iter = keys.iterator();
            while ( iter.hasNext() )
            {
                String key = iter.next();
                sb.append("\"");
                sb.append(key);
                sb.append("\": \"");
                sb.append(options.get(key));
                sb.append("\"");
                if ( iter.hasNext() )
                    sb.append(", ");
            }
            sb.append("}, ");
        }
        sb.append( "\"rows\":[" );
        // print out the rows
        // ensure base version is at bottom
        for ( int i=0;i<rows.size();i++ )
        {
            Row r = rows.get(i);
            if ( r.versions.nextSetBit(base)!=base )
            {
                sb.append( r.toJSONString() );
                sb.append(",");
            }
            else if ( !set )
            {
                baseRow = i;
                set = true;
            }
            else
                System.out.println("base already set!");
        }
        if ( baseRow == -1 )
            System.out.println("base row not found!");
        else
        {
            Row br = rows.get(baseRow);
            br.setID( id );
            sb.append( br.toJSONString() );
        }
        sb.append("]}");
        return sb.toString();
    }