diff --git a/examples/demo_jsonlab_basic.m b/examples/demo_jsonlab_basic.m
new file mode 100644
index 0000000000000000000000000000000000000000..7d955c7c1e2352648f9bfb22ea7482edc367fa3b
--- /dev/null
+++ b/examples/demo_jsonlab_basic.m
@@ -0,0 +1,96 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%         Demonstration of Basic Utilities of JSONlab
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+rngstate = rand ('state');
+randseed=hex2dec('623F9A9E');
+clear data2json json2data
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a simple scalar value \n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=pi
+savejson('',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a complex number\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=1+2*i
+savejson('',data2json)
+json2data=loadjson(ans) 
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a complex matrix\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=magic(6);
+data2json=data2json(:,1:3)+data2json(:,4:6)*i
+savejson('',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  MATLAB special constants\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=[NaN Inf -Inf]
+savejson('specials',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a real sparse matrix\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=sprand(10,10,0.1)
+savejson('sparse',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a complex sparse matrix\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=data2json-data2json*i
+savejson('complex_sparse',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a structure\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=struct('name','Think Different','year',1997,'magic',magic(3),...
+                 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false))
+savejson('astruct',data2json,struct('ParseLogical',1))
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a structure array\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=struct('name','Nexus Prime','rank',9);
+data2json(2)=struct('name','Sentinel Prime','rank',9);
+data2json(3)=struct('name','Optimus Prime','rank',9);
+savejson('Supreme Commander',data2json)
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  a cell array\n')
+fprintf(1,'%%=================================================\n\n')
+
+data2json=cell(3,1);
+data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,...
+              'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0);
+data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']);
+data2json{3}=[10.04,10.10,11.04,11.10]
+savejson('debian',data2json,struct('FloatFormat','%.2f'))
+json2data=loadjson(ans)
+
+fprintf(1,'\n%%=================================================\n')
+fprintf(1,'%%  invalid field-name handling\n')
+fprintf(1,'%%=================================================\n\n')
+
+json2data=loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}')
+
+rand ('state',rngstate);
+
diff --git a/examples/jsonlab_selftest.m b/examples/jsonlab_selftest.m
new file mode 100644
index 0000000000000000000000000000000000000000..37d104be63ecdb6bdf00ac00b24ab088ec08e88d
--- /dev/null
+++ b/examples/jsonlab_selftest.m
@@ -0,0 +1,12 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%         Regression Test Unit of loadjson and savejson
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+for i=1:3
+    fname=sprintf('example%d.json',i);
+    if(exist(fname,'file')==0) break; end
+    fprintf(1,'===============================================\n>> %s\n',fname);
+    json=savejson('data',loadjson(fname));
+    fprintf(1,'%s\n',json);
+    data=loadjson(json);
+end
diff --git a/examples/jsonlab_selftest.matlab b/examples/jsonlab_selftest.matlab
new file mode 100644
index 0000000000000000000000000000000000000000..7911d883adf2f187d2f5adb85c79cf159e2eb8df
--- /dev/null
+++ b/examples/jsonlab_selftest.matlab
@@ -0,0 +1,87 @@
+ 
+  To get started, type one of these: helpwin, helpdesk, or demo.
+  For product information, visit www.mathworks.com.
+ 
+===============================================
+>> example1.json
+{
+	"data": {
+		"firstName": "John",
+		"lastName": "Smith",
+		"age": [25],
+		"address": {
+			"streetAddress": "21 2nd Street",
+			"city": "New York",
+			"state": "NY",
+			"postalCode": "10021"
+		},
+		"phoneNumber": [
+			{
+				"type": "home",
+				"number": "212 555-1234"
+			},
+			{
+				"type": "fax",
+				"number": "646 555-4567"
+			}
+		]
+	}
+}
+
+===============================================
+>> example2.json
+{
+	"data": {
+		"glossary": {
+			"title": "example glossary",
+			"GlossDiv": {
+				"title": "S",
+				"GlossList": {
+					"GlossEntry": {
+						"ID": "SGML",
+						"SortAs": "SGML",
+						"GlossTerm": "Standard Generalized Markup Language",
+						"Acronym": "SGML",
+						"Abbrev": "ISO 8879:1986",
+						"GlossDef": {
+							"para": "A meta-markup language, used to create markup languages such as DocBook.",
+							"GlossSeeAlso": [
+								"GML",
+								"XML"
+							]
+						},
+						"GlossSee": "markup"
+					}
+				}
+			}
+		}
+	}
+}
+
+===============================================
+>> example3.json
+{
+	"data": {
+		"menu": {
+			"id": "file",
+			"value": "_&File",
+			"popup": {
+				"menuitem": [
+					{
+						"value": "_&New",
+						"onclick": "CreateNewDoc(\"\")"
+					},
+					{
+						"value": "_&Open",
+						"onclick": "OpenDoc()"
+					},
+					{
+						"value": "_&Close",
+						"onclick": "CloseDoc()"
+					}
+				]
+			}
+		}
+	}
+}
+
diff --git a/loadjson.m b/loadjson.m
deleted file mode 100644
index 74ffa967b65532e2c4db0d9427c6be4a65f99470..0000000000000000000000000000000000000000
--- a/loadjson.m
+++ /dev/null
@@ -1,391 +0,0 @@
-function data = loadjson(fname)
-%
-% data=loadjson(fname)
-%
-% parse a JSON (JavaScript Object Notation) file or string
-%
-% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
-%            date: 2011/09/09
-%         Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713
-%            date: 2009/11/02
-%         François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393
-%            date: 2009/03/22
-%         Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565
-%            date: 2008/07/03
-%
-% input:
-%      fname: input file name, if fname contains "{}" or "[]", fname
-%      will be interpreted as a JSON string
-%
-% output:
-%      dat: a cell array, where {...} blocks are converted into cell arrays,
-%           and [...] are converted to arrays
-%
-% license:
-%     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details 
-%
-% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
-%
-
-global pos inStr len  esc index_esc len_esc isoct arraytoken
-
-if(regexp(fname,'[\{\}\]\[]','once'))
-   string=fname;
-elseif(exist(fname,'file'))
-   fid = fopen(fname,'rt');
-   string = fscanf(fid,'%c');
-   fclose(fid);
-else
-   error('input file does not exist');
-end
-
-pos = 1; len = length(string); inStr = string;
-isoct=exist('OCTAVE_VERSION');
-arraytoken=find(inStr=='[' | inStr==']' | inStr=='"');
-
-% String delimiters and escape chars identified to improve speed:
-esc = find(inStr=='"' | inStr=='\' ); % comparable to: regexp(inStr, '["\\]');
-index_esc = 1; len_esc = length(esc);
-
-if pos <= len
-    switch(next_char)
-        case '{'
-            data = parse_object;
-        case '['
-            data = parse_array;
-        otherwise
-            error_pos('Outer level structure must be an object or an array');
-    end
-end % if
-
-len=length(data);
-if(len==1)
-    data=jstruct2array(data);
-else
-    for i=1:len
-        if(isstruct(data(i)))
-            data(i)=jstruct2array(data(i));
-        end
-    end
-end
-
-%%-------------------------------------------------------------------------
-function newdata=jstruct2array(data)
-
-fn=fieldnames(data);
-newdata=data;
-for i=1:length(fn) % depth-first
-    if(isstruct(getfield(data,fn{i})))
-        newdata=setfield(newdata,fn{i},jstruct2array(getfield(data,fn{i})));
-    end
-end
-if(~isempty(strmatch('x_ArrayType_',fn)) && ~isempty(strmatch('x_ArrayData_',fn)))
-    newdata=cast(data.x_ArrayData_,data.x_ArrayType_);
-    if(~isempty(strmatch('x_ArrayIsSparse_',fn)))
-        if(data.x_ArrayIsSparse_)
-            if(~isempty(strmatch('x_ArraySize_',fn)))
-                dim=data.x_ArraySize_;
-                newdata=sparse(newdata(:,1),newdata(:,2),newdata(:,3),dim(1),prod(dim(2:end)));
-            else
-                newdata=sparse(newdata(:,1),newdata(:,2),newdata(:,3));
-            end
-        end
-    elseif(~isempty(strmatch('x_ArraySize_',fn)))
-        newdata=reshape(newdata(:),data.x_ArraySize_);
-    end
-end
-
-%%-------------------------------------------------------------------------
-function object = parse_object
-    parse_char('{');
-    object = [];
-    if next_char ~= '}'
-        while 1
-            str = parseStr;
-            if isempty(str)
-                error_pos('Name of value at position %d cannot be empty');
-            end
-            parse_char(':');
-            val = parse_value;
-            eval( sprintf( 'object.%s  = val;', valid_field(str) ) );
-            if next_char == '}'
-                break;
-            end
-            parse_char(',');
-        end
-    end
-    parse_char('}');
-
-%%-------------------------------------------------------------------------
-
-function object = parse_array % JSON array is written in row-major order
-global pos inStr 
-    parse_char('[');
-    object = cell(0, 1);
-    if next_char ~= ']'
-        endpos=matching_bracket(inStr,pos);
-        arraystr=['[' inStr(pos:endpos)];
-        arraystr(find(arraystr==sprintf('\n')))=[];
-        arraystr(find(arraystr==sprintf('\r')))=[];
-        arraystr=regexprep(arraystr,'\]\s*,','];');
-        arraystr=regexprep(arraystr,'"_NaN_"','NaN');
-        arraystr=regexprep(arraystr,'"([-+]*)_Inf_"','$1Inf');
-        try
-           if(isoct && regexp(arraystr,'"','once'))
-                error('Octave eval can produce empty cells for JSON-like input');
-           end
-           object=eval(arraystr);
-           pos=endpos;
-        catch
-         while 1
-            val = parse_value;
-            object{end+1} = val;
-            if next_char == ']'
-                break;
-            end
-            parse_char(',');
-         end
-        end
-    end
-    try
-        object=cell2mat(object')';
-        if(size(object,1)>1 && ndims(object)==2)
-            object=object';
-        end
-    catch
-    end
-    parse_char(']');
-
-%%-------------------------------------------------------------------------
-
-function parse_char(c)
-    global pos inStr len
-    skip_whitespace;
-    if pos > len || inStr(pos) ~= c
-        error_pos(sprintf('Expected %c at position %%d', c));
-    else
-        pos = pos + 1;
-        skip_whitespace;
-    end
-
-%%-------------------------------------------------------------------------
-
-function c = next_char
-    global pos inStr len
-    skip_whitespace;
-    if pos > len
-        c = [];
-    else
-        c = inStr(pos);
-    end
-
-%%-------------------------------------------------------------------------
-
-function skip_whitespace
-    global pos inStr len
-    while pos <= len && isspace(inStr(pos))
-        pos = pos + 1;
-    end
-
-%%-------------------------------------------------------------------------
-function str = parseStr
-    global pos inStr len  esc index_esc len_esc
- % len, ns = length(inStr), keyboard
-    if inStr(pos) ~= '"'
-        error_pos('String starting with " expected at position %d');
-    else
-        pos = pos + 1;
-    end
-    str = '';
-    while pos <= len
-        while index_esc <= len_esc && esc(index_esc) < pos
-            index_esc = index_esc + 1;
-        end
-        if index_esc > len_esc
-            str = [str inStr(pos:len)];
-            pos = len + 1;
-            break;
-        else
-            str = [str inStr(pos:esc(index_esc)-1)];
-            pos = esc(index_esc);
-        end
-        nstr = length(str); switch inStr(pos)
-            case '"'
-                pos = pos + 1;
-                if(~isempty(str))
-                    if(strcmp(str,'_Inf_'))
-                        str=Inf;
-                    elseif(strcmp(str,'-_Inf_'))
-                        str=-Inf;
-                    elseif(strcmp(str,'_NaN_'))
-                        str=NaN;
-                    end
-                end
-                return;
-            case '\'
-                if pos+1 > len
-                    error_pos('End of file reached right after escape character');
-                end
-                pos = pos + 1;
-                switch inStr(pos)
-                    case {'"' '\' '/'}
-                        str(nstr+1) = inStr(pos);
-                        pos = pos + 1;
-                    case {'b' 'f' 'n' 'r' 't'}
-                        str(nstr+1) = sprintf(['\' inStr(pos)]);
-                        pos = pos + 1;
-                    case 'u'
-                        if pos+4 > len
-                            error_pos('End of file reached in escaped unicode character');
-                        end
-                        str(nstr+(1:6)) = inStr(pos-1:pos+4);
-                        pos = pos + 5;
-                end
-            otherwise % should never happen
-                str(nstr+1) = inStr(pos), keyboard
-                pos = pos + 1;
-        end
-    end
-    error_pos('End of file while expecting end of inStr');
-
-%%-------------------------------------------------------------------------
-
-function num = parse_number
-    global pos inStr len isoct
-    currstr=inStr(pos:end);
-    numstr=0;
-    if(isoct~=0)
-        numstr=regexp(currstr,'^\s*-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+\-]?\d+)?','end');
-        [num, one] = sscanf(currstr, '%f', 1);
-        delta=numstr+1;
-    else
-        [num, one, err, delta] = sscanf(currstr, '%f', 1);
-        if ~isempty(err)
-            error_pos('Error reading number at position %d');
-        end
-    end
-    pos = pos + delta-1;
-
-%%-------------------------------------------------------------------------
-
-function val = parse_value
-    global pos inStr len
-    true = 1; false = 0;
-
-    switch(inStr(pos))
-        case '"'
-            val = parseStr;
-            return;
-        case '['
-            val = parse_array;
-            return;
-        case '{'
-            val = parse_object;
-            return;
-        case {'-','0','1','2','3','4','5','6','7','8','9'}
-            val = parse_number;
-            return;
-        case 't'
-            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'true')
-                val = true;
-                pos = pos + 4;
-                return;
-            end
-        case 'f'
-            if pos+4 <= len && strcmpi(inStr(pos:pos+4), 'false')
-                val = false;
-                pos = pos + 5;
-                return;
-            end
-        case 'n'
-            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'null')
-                val = [];
-                pos = pos + 4;
-                return;
-            end
-    end
-    error_pos('Value expected at position %d');
-%%-------------------------------------------------------------------------
-
-function error_pos(msg)
-    global pos inStr len
-    poShow = max(min([pos-15 pos-1 pos pos+20],len),1);
-    if poShow(3) == poShow(2)
-        poShow(3:4) = poShow(2)+[0 -1];  % display nothing after
-    end
-    msg = [sprintf(msg, pos) ': ' ...
-    inStr(poShow(1):poShow(2)) '<error>' inStr(poShow(3):poShow(4)) ];
-    error( ['JSONparser:invalidFormat: ' msg] );
-
-%%-------------------------------------------------------------------------
-
-function str = valid_field(str)
-global isoct
-% From MATLAB doc: field names must begin with a letter, which may be
-% followed by any combination of letters, digits, and underscores.
-% Invalid characters will be converted to underscores, and the prefix
-% "x_" will be added if first character is not a letter.
-    if ~isletter(str(1)) || str(1)>'z'
-        str = ['x' str];
-    end
-    if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' ))) return;  end
-    if(~isoct)
-        str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_');
-    else
-        pos=regexp(str,'[^0-9A-Za-z_]');
-        if(isempty(pos)) return; end
-        str0=str;
-        pos0=[0 pos(:)' length(str)];
-        str='';
-        for i=1:length(pos)
-            str=[str str0(pos0(i)+1:pos(i)-1) sprintf('_0x%X_',str0(pos(i)))];
-        end
-        if(pos(end)~=length(str))
-            str=[str str0(pos0(end-1)+1:pos0(end))];
-        end
-    end
-    %str(~isletter(str) & ~('0' <= str & str <= '9')) = '_';
-
-%%-------------------------------------------------------------------------
-function endpos = matching_quote(str,pos)
-len=length(str);
-while(pos<len)
-    if(str(pos)=='"')
-        if(~(pos>1 && str(pos-1)=='\'))
-            endpos=pos;
-            return;
-        end        
-    end
-    pos=pos+1;
-end
-
-%%-------------------------------------------------------------------------
-function endpos = matching_bracket(str,pos)
-global arraytoken
-level=1;
-endpos=0;
-bpos=arraytoken(arraytoken>=pos);
-tokens=str(bpos);
-len=length(tokens);
-pos=1;
-while(pos<=len)
-    c=tokens(pos);
-    if(c==']')
-        level=level-1;
-        if(level==0)
-            endpos=bpos(pos);
-            return
-        end
-    end
-    if(c=='[')
-        level=level+1;
-    end
-    if(c=='"')
-        pos=matching_quote(tokens,pos+1);
-    end
-    pos=pos+1;
-end
-if(endpos==0) 
-    error('unmatched "]"');
-end
-
diff --git a/loadjson.m b/loadjson.m
new file mode 120000
index 0000000000000000000000000000000000000000..af0075af5ace00b0646e3d47aba1a43acc9f2361
--- /dev/null
+++ b/loadjson.m
@@ -0,0 +1 @@
+../iso2mesh/loadjson.m
\ No newline at end of file
diff --git a/savejson.m b/savejson.m
deleted file mode 100644
index 3179c20a45cf791466ebd39251ebad38b378bf0a..0000000000000000000000000000000000000000
--- a/savejson.m
+++ /dev/null
@@ -1,250 +0,0 @@
-function json=savejson(rootname,obj,varargin)
-%
-% json=savejson(rootname,obj,opt)
-%
-% convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
-% Object Notation) string
-%
-% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
-%            date: 2011/09/09
-%
-% input:
-%      rootname: name of the root-object, if set to '', will use variable name
-%      obj: a MATLAB object (array, cell, cell array, struct, struct array)
-%      opt: a struct for additional options, use [] if all use default
-%        opt can have the following fields (first in [.|.] is the default)
-%        opt.FloatFormat ['%.10g'|string]: format to show each numeric element
-%                         of a 1D/2D array;
-%        opt.ArrayIndent [1|0]: if 1, output explicit data array with
-%                         precedent indentation; if 0, no indentation
-%        opt.ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
-%                         array in JSON array format; if sets to 1, an
-%                         array will be shown as a struct with fields
-%                         "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
-%                         sparse arrays, the non-zero elements will be
-%                         saved to _ArrayData_ field in triplet-format i.e.
-%                         (ix,iy,val) and "_ArrayIsSparse_" will be added
-%                         with a value of 1.
-%
-% output:
-%      json: a string in the JSON format (see http://json.org)
-%
-% examples:
-%      a=struct('node',[1  9  10; 2 1 1.2], 'elem',[9 1;1 2;2 3],...
-%           'face',[9 01 2; 1 2 3; NaN,Inf,-Inf], 'author','FangQ');
-%      savejson('mesh',a)
-%      savejson('',a,struct('ArrayIndent',0,'FloatFormat','\t%.5g'))
-%
-% license:
-%     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
-%
-% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
-%
-
-varname=inputname(2);
-if(~isempty(rootname))
-   varname=rootname;
-end
-rootisarray=0;
-rootlevel=1;
-if((isnumeric(obj) || islogical(obj) || ischar(obj)) && isempty(rootname))
-    rootisarray=1;
-    rootlevel=0;
-    varname='';
-end
-json=obj2json(varname,obj,rootlevel,varargin{:});
-if(rootisarray)
-    json=sprintf('%s\n',json);
-else
-    json=sprintf('{\n%s\n}\n',json);
-end
-
-%%-------------------------------------------------------------------------
-function txt=obj2json(name,item,level,varargin)
-
-cname=class(item);
-
-if(iscell(item))
-    txt=cell2json(name,item,level,varargin{:});
-elseif(isstruct(item))
-    txt=struct2json(name,item,level,varargin{:});
-elseif(ischar(item))
-    txt=str2json(name,item,level,varargin{:});
-else
-    txt=mat2json(name,item,level,varargin{:});
-end
-
-%%-------------------------------------------------------------------------
-function txt=cell2json(name,item,level,varargin)
-txt='';
-if(~iscell(item))
-        error('input is not a cell');
-end
-
-dim=size(item);
-len=numel(item); % let's handle 1D cell first
-padding1=repmat(sprintf('\t'),1,level-1);
-padding0=repmat(sprintf('\t'),1,level);
-if(len>1) txt=sprintf('%s"%s": [\n',padding0, name); name=''; end
-for i=1:len
-    txt=sprintf('%s%s%s',txt,padding1,obj2json(name,item{i},level+(len>1),varargin{:}));
-    if(i<len) txt=sprintf('%s%s',txt,sprintf(',\n')); end
-end
-if(len>1) txt=sprintf('%s\n%s]',txt,padding0); end
-
-%%-------------------------------------------------------------------------
-function txt=struct2json(name,item,level,varargin)
-txt='';
-if(~isstruct(item))
-	error('input is not a struct');
-end
-len=numel(item);
-padding1=repmat(sprintf('\t'),1,level);
-padding0=repmat(sprintf('\t'),1,level+1);
-sep=',';
-
-if(~isempty(name)) 
-    if(len>1) txt=sprintf('%s"%s": [\n',padding1,name); end
-else
-    if(len>1) txt=sprintf('%s[\n',padding1); end
-end
-for e=1:len
-  names = fieldnames(item(e));
-  if(~isempty(name) && len==1)
-        txt=sprintf('%s%s"%s": {\n',txt,padding1, name); 
-  else
-        txt=sprintf('%s%s{\n',txt,repmat(sprintf('\t'),1,level+(len>1))); 
-  end
-  if(~isempty(names))
-    for i=1:length(names)
-	    txt=sprintf('%s%s',txt,obj2json(names{i},getfield(item(e),...
-             names{i}),level+1+(len>1),varargin{:}));
-        if(i<length(names)) txt=sprintf('%s%s',txt,','); end
-        txt=sprintf('%s%s',txt,sprintf('\n'));
-    end
-  end
-  txt=sprintf('%s%s}',txt,repmat(sprintf('\t'),1,level+(len>1)));
-  if(e==len) sep=''; end
-  if(e<len) txt=sprintf('%s%s',txt,sprintf(',\n')); end
-end
-if(len>1) txt=sprintf('%s\n%s]',txt,padding1); end
-
-%%-------------------------------------------------------------------------
-function txt=str2json(name,item,level,varargin)
-txt='';
-if(~ischar(item))
-        error('input is not a string');
-end
-len=size(item,1);
-sep=sprintf(',\n');
-
-padding1=repmat(sprintf('\t'),1,level);
-padding0=repmat(sprintf('\t'),1,level+1);
-
-if(~isempty(name)) 
-    if(len>1) txt=sprintf('%s"%s": [\n',padding1,name); end
-else
-    if(len>1) txt=sprintf('%s[\n',padding1); end
-end
-for e=1:len
-    val=regexprep(item(e,:),'\\','\\\\');
-    val=regexprep(val,'"','\\"');
-    val=regexprep(val,'^"','\\"');
-    if(len==1)
-        obj=['"' name '": ' '"',val,'"'];
-	if(isempty(name)) obj=['"',val,'"']; end
-        txt=sprintf('%s%s%s%s',txt,repmat(sprintf('\t'),1,level),obj);
-    else
-        txt=sprintf('%s%s%s%s',txt,repmat(sprintf('\t'),1,level+1),['"',val,'"']);
-    end
-    if(e==len) sep=''; end
-    txt=sprintf('%s%s',txt,sep);
-end
-if(len>1) txt=sprintf('%s\n%s%s',txt,padding1,']'); end
-
-%%-------------------------------------------------------------------------
-function txt=mat2json(name,item,level,varargin)
-if(~isnumeric(item) && ~islogical(item))
-        error('input is not an array');
-end
-
-padding1=repmat(sprintf('\t'),1,level);
-padding0=repmat(sprintf('\t'),1,level+1);
-
-if(length(size(item))>2 || issparse(item) || jsonopt('ArrayToStruct',0,varargin{:}))
-    if(isempty(name))
-    	txt=sprintf('%s{\n%s"_ArrayType_": "%s",\n%s"_ArraySize_": %s,\n',...
-              padding1,padding0,class(item),padding0,regexprep(mat2str(size(item)),'\s+',',') );
-    else
-    	txt=sprintf('%s"%s": {\n%s"_ArrayType_": "%s",\n%s"_ArraySize_": %s,\n',...
-              padding1,name,padding0,class(item),padding0,regexprep(mat2str(size(item)),'\s+',',') );
-    end
-else
-    if(isempty(name))
-    	txt=sprintf('%s%s',padding1,matdata2json(item,level+1,varargin{:}));
-    else
-    	txt=sprintf('%s"%s": %s',padding1,name,matdata2json(item,level+1,varargin{:}));
-    end
-    return;
-end
-dataformat='%s%s%s%s%s';
-
-if(issparse(item))
-    [ix,iy]=find(item);
-    txt=sprintf(dataformat,txt,padding0,'"_ArrayIsSparse_": ','1', sprintf(',\n'));
-    if(find(size(item)==1))
-        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
-           matdata2json([ix,full(item(find(item)))],level+2,varargin{:}), sprintf('\n'));
-    else
-        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
-           matdata2json([ix,iy,full(item(find(item)))],level+2,varargin{:}), sprintf('\n'));
-    end
-else
-    txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
-        matdata2json(item(:)',level+2,varargin{:}), sprintf('\n'));
-end
-txt=sprintf('%s%s%s',txt,padding1,'}');
-
-%%-------------------------------------------------------------------------
-function txt=matdata2json(mat,level,varargin)
-if(size(mat,1)==1)
-    pre='';
-    post='';
-    level=level-1;
-else
-    pre=sprintf('[\n');
-    post=sprintf('\n%s]',repmat(sprintf('\t'),1,level-1));
-end
-if(isempty(mat))
-    txt='null';
-    return;
-end
-floatformat=jsonopt('FloatFormat','%.10g',varargin{:});
-formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],\n')]];
-
-if(nargin>=2 && size(mat,1)>1 && jsonopt('ArrayIndent',1,varargin{:}))
-    formatstr=[repmat(sprintf('\t'),1,level) formatstr];
-end
-txt=sprintf(formatstr,mat');
-txt(end-1:end)=[];
-%txt=regexprep(mat2str(mat),'\s+',',');
-%txt=regexprep(txt,';',sprintf('],\n['));
-% if(nargin>=2 && size(mat,1)>1)
-%     txt=regexprep(txt,'\[',[repmat(sprintf('\t'),1,level) '[']);
-% end
-txt=[pre txt post];
-if(any(isinf(mat(:))))
-    txt=regexprep(txt,'([-+]*)Inf','"$1_Inf_"');
-end
-if(any(isnan(mat(:))))
-    txt=regexprep(txt,'NaN','"_NaN_"');
-end
-
-%%-------------------------------------------------------------------------
-function val=jsonopt(key,default,varargin)
-val=default;
-if(nargin<=2) return; end
-opt=varargin{1};
-if(isstruct(opt) && isfield(opt,key))
-    val=getfield(opt,key);
-end
diff --git a/savejson.m b/savejson.m
new file mode 120000
index 0000000000000000000000000000000000000000..c6a5ba0852a005d015e972374014bdbaa9fb603d
--- /dev/null
+++ b/savejson.m
@@ -0,0 +1 @@
+../iso2mesh/savejson.m
\ No newline at end of file