diff --git a/Contents.m b/Contents.m
index 58018486940e3ba404754cb9dd23b3ab5de53a33..c9e867b11150213e20192a086d7e167a2bb37622 100644
--- a/Contents.m
+++ b/Contents.m
@@ -45,7 +45,7 @@
 % Serialize a MATLAB struct or cell array into a JData-compliant 
 % structure as defined in the JData spec: http://github.com/fangq/jdata
 %
-% This function implements the JData Specification Draft 2a (Oct. 2019)
+% This function implements the JData Specification Draft 2 (Oct. 2019)
 % see http://github.com/fangq/jdata for details
 %
 %
@@ -58,9 +58,11 @@
 %       	       decoded first. This is needed for JSON but not
 %       	       UBJSON data
 %         Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the
-%       	       default JData keyword prefix is 'x0x5F'(default);
-%       	       if the json file is loaded using matlab2018's
-%       	       jsondecode(), the prefix is 'x'.
+%                      default JData keyword prefix is 'x0x5F'; if the
+%                      json file is loaded using matlab2018's
+%                      jsondecode(), the prefix is 'x'; this function
+%                      attempts to automatically determine the prefix;
+%                      for octave, the default value is an empty string ''.
 %         UseArrayZipSize: [1|0] if set to 1, _ArrayZipSize_ will be added to 
 %       	       store the "pre-processed" data dimensions, i.e.
 %       	       the original data stored in _ArrayData_, and then flaten
@@ -93,7 +95,7 @@
 % (accepts JData objects loaded from either loadjson/loadubjson or 
 % jsondecode for MATLAB R2018a or later)
 %
-% This function implements the JData Specification Draft 2a (Oct. 2019)
+% This function implements the JData Specification Draft 2 (Oct. 2019)
 % see http://github.com/fangq/jdata for details
 %
 %
@@ -117,7 +119,8 @@
 %                         default JData keyword prefix is 'x0x5F'; if the
 %                         json file is loaded using matlab2018's
 %                         jsondecode(), the prefix is 'x'; this function
-%                         attempts to automatically determine the prefix.
+%                         attempts to automatically determine the prefix;
+%                         for octave, the default value is an empty string ''.
 %               FormatVersion: [2|float]: set the JSONLab output version; 
 %                         since v2.0, JSONLab uses JData specification Draft 1
 %                         for output format, it is incompatible with all
@@ -236,6 +239,8 @@
 %           FileName [''|string]: a file name to save the output JSON data
 %           FloatFormat ['%.10g'|string]: format to show each numeric element
 %                         of a 1D/2D array;
+%           IntFormat ['%d'|string]: format to display integer elements
+%                         of a 1D/2D array;
 %           ArrayIndent [1|0]: if 1, output explicit data array with
 %                         precedent indentation; if 0, no indentation
 %           ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
@@ -982,7 +987,7 @@
 %        newname: the restored original string
 %
 %    example:
-%        decodevarname('x0x5F_a)   % returns _a
+%        decodevarname('x0x5F_a')   % returns _a
 %        decodevarname('a_')   % returns a_ as it is a valid variable name
 %        decodevarname('x0xE58F98__0xE9878F_')  % returns '变量' 
 %
diff --git a/README.rst b/README.rst
index 527b24b057d46290cebe05b16dc49b054ad7f9a8..1c7f0d5973b8fac204b5549c184e91251e360cf4 100644
--- a/README.rst
+++ b/README.rst
@@ -5,7 +5,7 @@
 * Copyright (C) 2011-2019  Qianqian Fang <q.fang at neu.edu>
 * License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt
 * Version: 1.9.8 (Magnus - beta)
-* JData Specification Version: Draft 2a (http://github.com/fangq/jdata)
+* JData Specification Version: Draft 2 (http://github.com/fangq/jdata)
 * URL: http://openjdata.org/jsonlab
 
 
@@ -25,7 +25,7 @@ JSONLab v1.9.8 is the beta release of the next milestone - code named "Magnus".
 Starting from this release, JSONLab supports encoding/decoding MessagePack,
 a widely-used binary JSON-like data format. Via ZMat v0.9, JSONLab v1.9.8
 also supports LZMA/LZ4/LZ4HC data compression/decompression. More importantly,
-JSONLab is now the official reference implementation for JData Specification (Draft 2a)
+JSONLab is now the official reference implementation for JData Specification (Draft 2)
 as defined in http://github.com/fangq/jdata, the foundation for the OpenJData
 Project (http://openjdata.org).
 
@@ -55,7 +55,7 @@ with key features marked by *:
 - 2019-05-19*[c87e7d2] support containers.Map
 
 
-Please note that JSONLab v1.9.8 is compliant with JData Spec Draft 2a, while
+Please note that JSONLab v1.9.8 is compliant with JData Spec Draft 2, while
 v1.9 and previous releases are compatible with Draft 1. The main differences are
 
 * ``_ArrayCompressionMethod_, _ArrayCompressionSize_`` and ``_ArrayCompressedData_`` 
diff --git a/README.txt b/README.txt
index 8a65b14cb67e76d6dbb2800c2967132ab3b6c22c..a149aaa25db65a3052a4448dadbc5504b7ef66e1 100644
--- a/README.txt
+++ b/README.txt
@@ -6,7 +6,7 @@
 * Copyright (C) 2011-2019  Qianqian Fang <q.fang at neu.edu>
 * License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt
 * Version: 1.9.8 (Magnus - beta)
-* JData Specification Version: Draft 2a (http://github.com/fangq/jdata)
+* JData Specification Version: Draft 2 (http://github.com/fangq/jdata)
 * URL: http://openjdata.org/jsonlab
 
 -------------------------------------------------------------------------------
@@ -30,7 +30,7 @@ JSONLab v1.9.8 is the beta release of the next milestone - code named "Magnus".
 Starting from this release, JSONLab supports encoding/decoding MessagePack,
 a widely-used binary JSON-like data format. Via ZMat v0.9, JSONLab v1.9.8
 also supports LZMA/LZ4/LZ4HC data compression/decompression. More importantly,
-JSONLab is now the official reference implementation for JData Specification (Draft 2a)
+JSONLab is now the official reference implementation for JData Specification (Draft 2)
 as defined in http://github.com/fangq/jdata, the foundation for the OpenJData
 Project (http://openjdata.org).
 
@@ -60,7 +60,7 @@ with key features marked by *:
 * 2019-05-19*[c87e7d2] support containers.Map
 
 
-Please note that JSONLab v1.9.8 is compliant with JData Spec Draft 2a, while
+Please note that JSONLab v1.9.8 is compliant with JData Spec Draft 2, while
 v1.9 and previous releases are compatible with Draft 1. The main differences are
 
 * _ArrayCompressionMethod_, _ArrayCompressionSize_</tt> and <tt>_ArrayCompressedData_</tt> \
diff --git a/decodevarname.m b/decodevarname.m
index 20c87536146ec5ffce7293ed83a87c982046024c..66298d2b593b2634148a8e3d0b66237fdc06787b 100644
--- a/decodevarname.m
+++ b/decodevarname.m
@@ -21,7 +21,7 @@ function newname = decodevarname(name,varargin)
 %        newname: the restored original string
 %
 %    example:
-%        decodevarname('x0x5F_a)   % returns _a
+%        decodevarname('x0x5F_a')   % returns _a
 %        decodevarname('a_')   % returns a_ as it is a valid variable name
 %        decodevarname('x0xE58F98__0xE9878F_')  % returns '变量' 
 %
diff --git a/examples/demo_jsonlab_basic.m b/examples/demo_jsonlab_basic.m
index 25e69df56e36fc7e3aa883f67d7930cfbae2365b..233e53292a702ba2b183e002877bbfa13cf786c5 100644
--- a/examples/demo_jsonlab_basic.m
+++ b/examples/demo_jsonlab_basic.m
@@ -37,6 +37,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=1:3
 savejson('',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a simple column vector \n')
@@ -45,6 +48,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=(1:3)'
 savejson('',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a string array \n')
@@ -69,6 +75,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json={'a',true,[2;3]}
 savejson('',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a 3-D array in nested array form\n')
@@ -77,7 +86,7 @@ fprintf(1,'%%=================================================\n\n')
 data2json=reshape(1:(2*4*6),[2,4,6]);
 savejson('',data2json,'NestArray',1)
 json2data=loadjson(ans)
-if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+if(~isequaln(json2data,data2json))
     warning('conversion does not preserve original data');
 end
 
@@ -88,7 +97,7 @@ fprintf(1,'%%=================================================\n\n')
 data2json=reshape(1:(2*4*6),[2,4,6]);
 savejson('',data2json,'NestArray',0)
 json2data=loadjson(ans)
-if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+if(~isequaln(json2data,data2json))
     warning('conversion does not preserve original data');
 end
 
@@ -99,7 +108,7 @@ fprintf(1,'%%=================================================\n\n')
 data2json=reshape(1:(2*4*3*2),[2,4,3,2]);
 savejson('',data2json,'NestArray',0)  % nestarray for 4-D or above is not working
 json2data=loadjson(ans)
-if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+if(~isequaln(json2data,data2json))
     warning('conversion does not preserve original data');
 end
 
@@ -110,7 +119,7 @@ fprintf(1,'%%=================================================\n\n')
 data2json=reshape(1:(2*4*6),[2,4,6]);
 savejson('',data2json,'NestArray',1,'FormatVersion',1.8)
 json2data=loadjson(ans,'FormatVersion',1.8)
-if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+if(~isequaln(json2data,data2json))
     warning('conversion does not preserve original data');
 end
 
@@ -121,7 +130,7 @@ fprintf(1,'%%=================================================\n\n')
 data2json=reshape(1:(2*4*6),[2,4,6]);
 savejson('',data2json,'NestArray',0,'FormatVersion',1.8)
 json2data=loadjson(ans,'FormatVersion',1.8)
-if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+if(~isequaln(json2data,data2json))
     warning('conversion does not preserve original data');
 end
 
@@ -132,6 +141,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=1+2i
 savejson('',data2json)
 json2data=loadjson(ans) 
+if(~isequaln(json2data,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a complex matrix\n')
@@ -141,6 +153,9 @@ data2json=magic(6);
 data2json=data2json(:,1:3)+data2json(:,4:6)*1i
 savejson('',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  MATLAB special constants\n')
@@ -149,22 +164,32 @@ fprintf(1,'%%=================================================\n\n')
 data2json=[NaN Inf -Inf]
 savejson('specials',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data.specials,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a real sparse matrix\n')
 fprintf(1,'%%=================================================\n\n')
 
 data2json=sprand(10,10,0.1)
-savejson('sparse',data2json)
+savejson('sparse',data2json,'FloatFormat','%.18g')
 json2data=loadjson(ans)
+if(~isequaln(json2data.sparse,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a complex sparse matrix\n')
 fprintf(1,'%%=================================================\n\n')
 
+data2json=sprand(10,10,0.1);
 data2json=data2json-data2json*1i
-savejson('complex_sparse',data2json)
+savejson('complex_sparse',data2json,'FloatFormat','%.18g')
 json2data=loadjson(ans)
+if(~isequaln(json2data.complex_sparse,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  an all-zero sparse matrix\n')
@@ -173,6 +198,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=sparse(2,3);
 savejson('all_zero_sparse',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data.all_zero_sparse,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  an empty sparse matrix\n')
@@ -181,6 +209,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=sparse([]);
 savejson('empty_sparse',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data.empty_sparse,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  an empty 0-by-0 real matrix\n')
@@ -197,6 +228,9 @@ fprintf(1,'%%=================================================\n\n')
 data2json=zeros(0,3);
 savejson('empty_0by3_real',data2json)
 json2data=loadjson(ans)
+if(~isequaln(json2data.empty_0by3_real,data2json))
+    warning('conversion does not preserve original data');
+end
 
 fprintf(1,'\n%%=================================================\n')
 fprintf(1,'%%  a sparse real column vector\n')
@@ -338,7 +372,7 @@ try
     data2json(20,1)=1;
     savejson('',data2json,'Compression','zlib','CompressionSize',0)  % nestarray for 4-D or above is not working
     json2data=loadjson(ans)
-    if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json)))
+    if(~isequaln(json2data,data2json))
         warning('conversion does not preserve original data');
     end
 catch
diff --git a/examples/jsonlab_basictest.matlab b/examples/jsonlab_basictest.matlab
index 050b82f76055389cbc84e7efc01c49a31ec857ab..f4a92dd5b5ba4337f425e9784a7ca83670b94dc0 100644
--- a/examples/jsonlab_basictest.matlab
+++ b/examples/jsonlab_basictest.matlab
@@ -98,7 +98,7 @@ json2data =
 
      1     2     3
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a simple column vector 
 >> %=================================================
@@ -127,7 +127,7 @@ json2data =
      2
      3
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a string array 
 >> %=================================================
@@ -202,9 +202,9 @@ ans =
 >> 
 json2data = 
 
-    'a'    [1]    {1x2 cell}
+    'a'    [1]    [2x1 double]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a 3-D array in nested array form
 >> %=================================================
@@ -530,7 +530,7 @@ json2data =
 
    1.0000 + 2.0000i
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a complex matrix
 >> %=================================================
@@ -569,7 +569,7 @@ json2data =
   30.0000 +12.0000i   5.0000 +14.0000i  34.0000 +16.0000i
    4.0000 +13.0000i  36.0000 +18.0000i  29.0000 +11.0000i
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  MATLAB special constants
 >> %=================================================
@@ -592,7 +592,7 @@ json2data =
 
     specials: [NaN Inf -Inf]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a real sparse matrix
 >> %=================================================
@@ -621,7 +621,7 @@ ans =
 		"_ArrayData_": [
 			[1,9,3,10,10,7,2,6,10],
 			[2,2,5,5,8,9,10,10,10],
-			[0.6557406992,0.7577401306,0.8491293059,0.7431324681,0.3922270195,0.6787351549,0.03571167857,0.9339932478,0.6554778902]
+			[0.655740699156586837,0.757740130578333448,0.849129305868777107,0.743132468124916179,0.392227019534168164,0.678735154857773471,0.0357116785741895537,0.933993247757550549,0.655477890177556644]
 		]
 	}
 }
@@ -632,23 +632,24 @@ json2data =
 
     sparse: [10x10 double]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a complex sparse matrix
 >> %=================================================
 
->> >> 
+>> >> >> 
 data2json =
 
-   (1,2)      0.6557 - 0.6557i
-   (9,2)      0.7577 - 0.7577i
-   (3,5)      0.8491 - 0.8491i
-  (10,5)      0.7431 - 0.7431i
-  (10,8)      0.3922 - 0.3922i
-   (7,9)      0.6787 - 0.6787i
-   (2,10)     0.0357 - 0.0357i
-   (6,10)     0.9340 - 0.9340i
-  (10,10)     0.6555 - 0.6555i
+   (2,1)      0.6551 - 0.6551i
+   (1,2)      0.7547 - 0.7547i
+   (1,4)      0.2760 - 0.2760i
+   (7,5)      0.4984 - 0.4984i
+   (8,5)      0.9597 - 0.9597i
+   (9,5)      0.3404 - 0.3404i
+   (4,7)      0.1190 - 0.1190i
+   (1,8)      0.6797 - 0.6797i
+   (3,8)      0.1626 - 0.1626i
+  (10,8)      0.5853 - 0.5853i
 
 >> 
 ans =
@@ -660,10 +661,10 @@ ans =
 		"_ArrayIsComplex_": true,
 		"_ArrayIsSparse_": true,
 		"_ArrayData_": [
-			[1,9,3,10,10,7,2,6,10],
-			[2,2,5,5,8,9,10,10,10],
-			[0.6557406992,0.7577401306,0.8491293059,0.7431324681,0.3922270195,0.6787351549,0.03571167857,0.9339932478,0.6554778902],
-			[-0.6557406992,-0.7577401306,-0.8491293059,-0.7431324681,-0.3922270195,-0.6787351549,-0.03571167857,-0.9339932478,-0.6554778902]
+			[2,1,1,7,8,9,4,1,3,10],
+			[1,2,4,5,5,5,7,8,8,8],
+			[0.655098003973840659,0.754686681982360885,0.276025076998578367,0.498364051982142953,0.959743958516081075,0.340385726666133204,0.118997681558376645,0.679702676853674803,0.162611735194630569,0.585267750979777346],
+			[-0.655098003973840659,-0.754686681982360885,-0.276025076998578367,-0.498364051982142953,-0.959743958516081075,-0.340385726666133204,-0.118997681558376645,-0.679702676853674803,-0.162611735194630569,-0.585267750979777346]
 		]
 	}
 }
@@ -674,7 +675,7 @@ json2data =
 
     complex_sparse: [10x10 double]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  an all-zero sparse matrix
 >> %=================================================
@@ -697,7 +698,7 @@ json2data =
 
     all_zero_sparse: [2x3 double]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  an empty sparse matrix
 >> %=================================================
@@ -720,7 +721,7 @@ json2data =
 
     empty_sparse: []
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  an empty 0-by-0 real matrix
 >> %=================================================
@@ -760,7 +761,7 @@ json2data =
 
     empty_0by3_real: [0x3 double]
 
->> >> 
+>> >> >> 
 %=================================================
 >> %  a sparse real column vector
 >> %=================================================
diff --git a/examples/jsonlab_selftest.matlab b/examples/jsonlab_selftest.matlab
index f2b215e5444ef99725c43b6f57c219e2a088bad8..ba84d9da537964e57d3fa485213e8e91b7f0c616 100644
--- a/examples/jsonlab_selftest.matlab
+++ b/examples/jsonlab_selftest.matlab
@@ -1,13 +1,16 @@
 
                             < M A T L A B (R) >
-                  Copyright 1984-2010 The MathWorks, Inc.
-                Version 7.11.0.584 (R2010b) 64-bit (glnxa64)
-                              August 16, 2010
+                  Copyright 1984-2016 The MathWorks, Inc.
+                   R2016a (9.0.0.341360) 64-bit (glnxa64)
+                             February 11, 2016
 
  
-  To get started, type one of these: helpwin, helpdesk, or demo.
-  For product information, visit www.mathworks.com.
+For online documentation, see http://www.mathworks.com/support
+For product information, visit www.mathworks.com.
  
+
+	Academic License
+
 >> >> >> >> >> ===============================================
 >> example1.json
 {
@@ -150,5 +153,5 @@ GlossEntry{UIDSUSGMLUSortAsSUSGMLU	GlossTermSU$Standard Generalized Markup L
 CloseDoc()}]}}}}
 ===============================================
 >> example4.json
-{Udata[{Usample{UrhoU}}{Usample{UrhoU}}[[$U#U[$U#U[$U#U][SUPaperSUScissorsSUStone][CaSUb\SUc"SUd\"SUe"[SUf\"[SUg[\SUh[\"]]}
+{Udata[{Usample{UrhoU}}{Usample{UrhoU}}[[$U#U [$U#U[$U#U][SUPaperSUScissorsSUStone][CaSUb\SUc"SUd\"SUe"[SUf\"[SUg[\SUh[\"]]}
 >> 
\ No newline at end of file
diff --git a/isoctavemesh.m b/isoctavemesh.m
index 28066772cbed47033d40d168ed4113c067a34f53..a305a97a826e73e2ba4faec77dd53102ad57f4d3 100644
--- a/isoctavemesh.m
+++ b/isoctavemesh.m
@@ -1,4 +1,4 @@
-function [isoctave verinfo]=isoctavemesh
+function [isoctave, verinfo]=isoctavemesh
 %
 % [isoctave verinfo]=isoctavemesh
 %
diff --git a/jdatadecode.m b/jdatadecode.m
index f0b502ae201825b6f96d163b12052645389fe45b..ade9ff9a668aada871d28f225b72e978e5dcc374 100644
--- a/jdatadecode.m
+++ b/jdatadecode.m
@@ -6,7 +6,7 @@ function newdata=jdatadecode(data,varargin)
 % (accepts JData objects loaded from either loadjson/loadubjson or 
 % jsondecode for MATLAB R2018a or later)
 %
-% This function implements the JData Specification Draft 2a (Oct. 2019)
+% This function implements the JData Specification Draft 2 (Oct. 2019)
 % see http://github.com/fangq/jdata for details
 %
 % authors:Qianqian Fang (q.fang <at> neu.edu)
@@ -31,7 +31,8 @@ function newdata=jdatadecode(data,varargin)
 %                         default JData keyword prefix is 'x0x5F'; if the
 %                         json file is loaded using matlab2018's
 %                         jsondecode(), the prefix is 'x'; this function
-%                         attempts to automatically determine the prefix.
+%                         attempts to automatically determine the prefix;
+%                         for octave, the default value is an empty string ''.
 %               FormatVersion: [2|float]: set the JSONLab output version; 
 %                         since v2.0, JSONLab uses JData specification Draft 1
 %                         for output format, it is incompatible with all
@@ -80,7 +81,11 @@ function newdata=jdatadecode(data,varargin)
     len=length(data);
     needbase64=jsonopt('Base64',0,opt);
     format=jsonopt('FormatVersion',2,opt);
-    prefix=jsonopt('Prefix','x0x5F',opt);
+    if(isoctavemesh)
+        prefix=jsonopt('Prefix','',opt);
+    else
+        prefix=jsonopt('Prefix','x0x5F',opt);
+    end
     if(~isfield(data,N_('_ArrayType_')) && isfield(data,'x_ArrayType_'))
         prefix='x';
         opt.prefix='x';
diff --git a/jdataencode.m b/jdataencode.m
index 6bdbe8ce4309e0cdd323cdc3bdb0ba8f805e6e34..348664f61dbef3e3c8a48c276a7c15bbb432148d 100644
--- a/jdataencode.m
+++ b/jdataencode.m
@@ -8,7 +8,7 @@ function jdata=jdataencode(data, varargin)
 % Serialize a MATLAB struct or cell array into a JData-compliant 
 % structure as defined in the JData spec: http://github.com/fangq/jdata
 %
-% This function implements the JData Specification Draft 2a (Oct. 2019)
+% This function implements the JData Specification Draft 2 (Oct. 2019)
 % see http://github.com/fangq/jdata for details
 %
 % author: Qianqian Fang (q.fang <at> neu.edu)
@@ -22,9 +22,11 @@ function jdata=jdataencode(data, varargin)
 %       	       decoded first. This is needed for JSON but not
 %       	       UBJSON data
 %         Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the
-%       	       default JData keyword prefix is 'x0x5F'(default);
-%       	       if the json file is loaded using matlab2018's
-%       	       jsondecode(), the prefix is 'x'.
+%                      default JData keyword prefix is 'x0x5F'; if the
+%                      json file is loaded using matlab2018's
+%                      jsondecode(), the prefix is 'x'; this function
+%                      attempts to automatically determine the prefix;
+%                      for octave, the default value is an empty string ''.
 %         UseArrayZipSize: [1|0] if set to 1, _ArrayZipSize_ will be added to 
 %       	       store the "pre-processed" data dimensions, i.e.
 %       	       the original data stored in _ArrayData_, and then flaten
@@ -58,6 +60,20 @@ if(nargin==0)
 end
 
 opt=varargin2struct(varargin{:});
+if(isoctavemesh)
+    opt.prefix=jsonopt('Prefix','',opt);
+else
+    opt.prefix=jsonopt('Prefix',sprintf('x0x%X','_'+0),opt);
+end
+opt.compression=jsonopt('Compression','',opt);
+opt.nestarray=jsonopt('NestArray',0,opt);
+opt.formatversion=jsonopt('FormatVersion',2,opt);
+opt.compressarraysize=jsonopt('CompressArraySize',100,opt);
+opt.base64=jsonopt('Base64',0,opt);
+opt.mapasstruct=jsonopt('MapAsStruct',0,opt);
+opt.usearrayzipsize=jsonopt('UseArrayZipSize',1,opt);
+opt.messagepack=jsonopt('MessagePack',0,opt);
+
 jdata=obj2jd(data,opt);
 
 %%-------------------------------------------------------------------------
@@ -114,7 +130,7 @@ end
 function newitem=map2jd(item,varargin)
 
 names=item.keys;
-if(jsonopt('MapAsStruct',0,varargin{:}))  % convert a map to struct
+if(varargin{1}.mapasstruct)  % convert a map to struct
     newitem=struct;
     if(~strcmp(item.KeyType,'char'))
         data=num2cell(reshape([names, item.values],length(names),2),2);
@@ -136,15 +152,16 @@ end
 %%-------------------------------------------------------------------------
 function newitem=mat2jd(item,varargin)
 
-if(isempty(item) || isa(item,'string') || ischar(item) || ...
-        ((isvector(item) || ismatrix(item)) && isreal(item) && ~issparse(item)) || ...
-        jsonopt('NestArray',0,varargin{:}))
+if(isempty(item) || isa(item,'string') || ischar(item) || varargin{1}.nestarray || ...
+        ((isvector(item) || ismatrix(item)) && isreal(item) && ~issparse(item)))
     newitem=item;
-    return;
+    if(~(varargin{1}.messagepack && size(item,1)>1))
+        return;
+    end
 end
 
-zipmethod=jsonopt('Compression','',varargin{:});
-minsize=jsonopt('CompressArraySize',100,varargin{:});
+zipmethod=varargin{1}.compression;
+minsize=varargin{1}.compressarraysize;
 
 if(isa(item,'logical'))
     item=uint8(item);
@@ -166,7 +183,7 @@ if(isreal(item))
 	        newitem.(N('_ArrayData_'))=[ix(:)' , iy(:)', fulldata(:)'];
 	end
     else
-        if(jsonopt('FormatVersion',2,varargin{:})>1.9)
+        if(varargin{1}.formatversion>1.9)
                 item=permute(item,ndims(item):-1:1);
         end
 	newitem.(N('_ArrayData_'))=item(:)';
@@ -184,7 +201,7 @@ else
             newitem.(N('_ArrayData_'))=[ix(:)' , iy(:)' , real(fulldata(:))', imag(fulldata(:))'];
 	end
     else
-        if(jsonopt('FormatVersion',2,varargin{:})>1.9)
+        if(varargin{1}.formatversion>1.9)
                 item=permute(item,ndims(item):-1:1);
         end
         newitem.(N('_ArrayZipSize_'))=[2,numel(item)];
@@ -192,11 +209,11 @@ else
     end
 end
 
-if(jsonopt('UseArrayZipSize',1,varargin{:})==0 && isfield(newitem,N('_ArrayZipSize_')))
+if(varargin{1}.usearrayzipsize==0 && isfield(newitem,N('_ArrayZipSize_')))
     data=newitem.(N('_ArrayData_'));
     data=reshape(data,fliplr(newitem.(N('_ArrayZipSize_'))));
     newitem.(N('_ArrayData_'))=permute(data,ndims(data):-1:1);
-    newitem=rmfield(newitem,N_('_ArrayZipSize_'));
+    newitem=rmfield(newitem,N('_ArrayZipSize_'));
 end
 
 if(~isempty(zipmethod) && numel(item)>minsize)
@@ -204,14 +221,14 @@ if(~isempty(zipmethod) && numel(item)>minsize)
     newitem.(N('_ArrayZipType_'))=lower(zipmethod);
     newitem.(N('_ArrayZipSize_'))=size(newitem.(N('_ArrayData_')));
     newitem.(N('_ArrayZipData_'))=compfun(typecast(newitem.(N('_ArrayData_')),'uint8'));
-    newitem=rmfield(newitem,N_('_ArrayData_'));
-    if(jsonopt('Base64',0,varargin{:}))
+    newitem=rmfield(newitem,N('_ArrayData_'));
+    if(varargin{1}.base64)
         newitem.(N('_ArrayZipData_'))=char(base64encode(newitem.(N('_ArrayZipData_'))));
     end
 end
 
-if(isfield(newitem,N('_ArrayData_')) && isempty(newitem.(N_('_ArrayData_'))))
-    newitem.(N_('_ArrayData_'))=[];
+if(isfield(newitem,N('_ArrayData_')) && isempty(newitem.(N('_ArrayData_'))))
+    newitem.(N('_ArrayData_'))=[];
 end
 
 %%-------------------------------------------------------------------------
@@ -240,7 +257,7 @@ if(isfield(edgedata,'EndNodes'))
 end
 edgenodes(:,3)=num2cell(edgedata);
 if(isa(item,'graph'))
-    if(strcmp(jsonopt('Prefix',sprintf('x0x%X','_'+0),varargin{:}),'x'))
+    if(strcmp(varargin{1}.prefix,'x'))
         newitem.(genvarname('_GraphEdges0_'))=edgenodes;
     else
         newitem.(encodevarname('_GraphEdges0_'))=edgenodes;
@@ -274,12 +291,11 @@ function newitem=any2jd(item,varargin)
 N=@(x) N_(x,varargin{:});
 newitem.(N('_DataInfo_'))=struct('MATLABObjectClass',class(item),'MATLABObjectSize',size(item));
 newitem.(N('_ByteStream_'))=getByteStreamFromArray(item);  % use undocumented matlab function
-if(jsonopt('Base64',0,varargin{:}))
+if(varargin{1}.base64)
     newitem.(N('_ByteStream_'))=char(base64encode(newitem.(N('_ByteStream_'))));
 end
 
 %%-------------------------------------------------------------------------
 function newname=N_(name,varargin)
 
-prefix=jsonopt('Prefix',sprintf('x0x%X','_'+0),varargin{:});
-newname=[prefix name];
+newname=[varargin{1}.prefix name];
diff --git a/loadjson.m b/loadjson.m
index ae74e932c2ceb0ce8120cd1962908159229fa18d..ea9c7a0e336e7194bda67bfdb17fe59078cd83b3 100644
--- a/loadjson.m
+++ b/loadjson.m
@@ -455,6 +455,12 @@ end
 %%-------------------------------------------------------------------------
 function newstr=unescapejsonstring(str)
     newstr=str;
+    if(iscell(str))
+        try
+            newstr=cell2mat(cellfun(@(x) cell2mat(x),str(:),'un',0));
+        catch
+        end
+    end
     if(~ischar(str))
         return;
     end
diff --git a/loadmsgpack.m b/loadmsgpack.m
index 06fc5d7d967d0dfe797752ff1e029f902a20841e..82a4aaf9f0f2a8264aa6c7fd119dcdda839e8fca 100644
--- a/loadmsgpack.m
+++ b/loadmsgpack.m
@@ -201,7 +201,7 @@ function [str, idx] = parsestring(len, bytes, idx)
     if(~isoctavemesh)
          str = native2unicode(bytes(idx:idx+len-1)', 'utf-8');
     else
-         str = bytes(idx:idx+len-1)';
+         str = char(bytes(idx:idx+len-1)');
     end
     idx = idx + len;
 end
diff --git a/savejson.m b/savejson.m
index f53a146fd0780f83959b4653521abf1ff7b53c26..de6ae0cf62535d3ab322c97ec07a20de1a5cf493 100644
--- a/savejson.m
+++ b/savejson.m
@@ -135,7 +135,7 @@ else
    opt=varargin2struct(varargin{:});
 end
 
-opt.IsOctave=isoctavemesh;
+opt.isoctave=isoctavemesh;
 
 opt.compression=jsonopt('Compression','',opt);
 opt.nestarray=jsonopt('NestArray',0,opt);
@@ -148,6 +148,8 @@ opt.intformat=jsonopt('IntFormat','%d',opt);
 opt.floatformat=jsonopt('FloatFormat','%.10g',opt);
 opt.unpackhex=jsonopt('UnpackHex',1,opt);
 opt.arraytostruct=jsonopt('ArrayToStruct',0,opt);
+opt.parselogical=jsonopt('ParseLogical',0,opt);
+opt.arrayindent=jsonopt('ArrayIndent',1,opt);
 opt.num2cell_=0;
 
 if(jsonopt('PreEncode',1,opt))
@@ -418,7 +420,11 @@ if(~strcmp(item.KeyType,'char'))
         txt=obj2json('_MapData_',mm,level+1,varargin{:});
     else
         temp=struct(name,struct());
-        temp.(name).('x0x5F_MapData_')=mm;
+	if(varargin{1}.isoctave)
+            temp.(name).('_MapData_')=mm;
+	else
+	    temp.(name).('x0x5F_MapData_')=mm;
+	end
         txt=obj2json(name,temp.(name),level,varargin{:});
     end
     return;
@@ -490,7 +496,7 @@ else
     end
 end
 for e=1:len
-    val=escapejsonstring(item(e,:));
+    val=escapejsonstring(item(e,:),varargin{:});
     if(len==1)
         obj=['"' decodevarname(name,varargin{1}.unpackhex) '": ' '"',val,'"'];
         if(isempty(name))
@@ -548,6 +554,7 @@ else
     end
     return;
 end
+
 dataformat='%s%s%s%s%s';
 
 if(issparse(item))
@@ -621,6 +628,7 @@ else
         end
     end
 end
+
 txt=sprintf('%s%s%s',txt,padding1,'}');
 
 %%-------------------------------------------------------------------------
@@ -706,13 +714,13 @@ if(numel(mat)==1 && varargin{1}.singletarray==0 && level>0)
 else
     formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],%s',nl)]];
 end
-if(nargin>=2 && size(mat,1)>1 && jsonopt('ArrayIndent',1,varargin{:})==1)
+if(nargin>=2 && size(mat,1)>1 && varargin{1}.arrayindent==1)
     formatstr=[repmat(tab,1,level) formatstr];
 end
 
 txt=sprintf(formatstr,mat');
 txt(end-length(nl):end)=[];
-if(islogical(mat) && (numel(mat)==1 || jsonopt('ParseLogical',0,varargin{:})==1))
+if(islogical(mat) && (numel(mat)==1 || varargin{1}.parselogical==1))
    txt=regexprep(txt,'1','true');
    txt=regexprep(txt,'0','false');
 end
@@ -728,7 +736,7 @@ end
 %%-------------------------------------------------------------------------
 function txt=any2json(name,item,level,varargin)
 st=containers.Map();
-st('_DataInfo_')=struct('MATLABObjectClass',class(item),'MATLABObjectSize',size(item));
+st('_DataInfo_')=struct('MATLABObjectName',name, 'MATLABObjectClass',class(item),'MATLABObjectSize',size(item));
 st('_ByteStream_')=char(base64encode(getByteStreamFromArray(item)));
 
 if(isempty(name))
@@ -740,9 +748,9 @@ else
 end
 
 %%-------------------------------------------------------------------------
-function newstr=escapejsonstring(str)
+function newstr=escapejsonstring(str,varargin)
 newstr=str;
-isoct=isoctavemesh;
+isoct=varargin{1}.isoctave;
 if(isoct)
    vv=sscanf(OCTAVE_VERSION,'%f');
    if(vv(1)>=3.8)
diff --git a/saveubjson.m b/saveubjson.m
index 630d1ff5530a74cd433cf13b6031923464cef3e6..530e789a305dbe6a13307d9ae5f68ca7654af26f 100644
--- a/saveubjson.m
+++ b/saveubjson.m
@@ -140,7 +140,7 @@ opt.messagepack=jsonopt('MessagePack',0,opt);
 opt.num2cell_=0;
 
 if(jsonopt('PreEncode',1,opt))
-    obj=jdataencode(obj,'Base64',0,'UseArrayZipSize',jsonopt('MessagePack',0,opt),opt);
+    obj=jdataencode(obj,'Base64',0,'UseArrayZipSize',opt.messagepack,opt);
 end
 
 dozip=opt.compression;