%%% This file is part of RefactorErl.
%%%
%%% RefactorErl is free software: you can redistribute it and/or modify
%%% it under the terms of the GNU Lesser General Public License as published
%%% by the Free Software Foundation, either version 3 of the License, or
%%% (at your option) any later version.
%%%
%%% RefactorErl is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%%% GNU Lesser General Public License for more details.
%%%
%%% You should have received a copy of the GNU Lesser General Public License
%%% along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.
%%%
%%% The Original Code is RefactorErl.
%%%
%%% The Initial Developer of the Original Code is Eötvös Loránd University.
%%% Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
%%% are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
%%% and Ericsson Hungary. All Rights Reserved.


%%% @doc Unit test for {@link referl_anal_map}.
%%% @author Sandor Varga <vasa@caesar.elte.hu>

-module(reftest_referl_anal_map).
-vsn("$Rev: $").

-compile([export_all]).

-include("test.hrl").

-define(AnalMap, refanal_map).

%%% To run ------> reftest_lib:run(reftest_referl_anal_map).

%%% ============================================================================
%%% Data soruces

files() ->
    [{module, "m1_orig.erl",
	      "-module(m1_orig).					 \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24, phone=>\"999-9999\"},\n"
	      "Person#{height=>180, weight=>80}.			 \n"
     },
     {module, "m1_work_1.erl",
	      "-module(m1_work_1).		      %% For Update test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24, phone=>\"999-9999\"},\n"
	      "Person#{height=>180, weight=>80}.			 \n"
     },
     {module, "m1_work_2.erl",
	      "-module(m1_work_2).		      %% For Update test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24, phone=>\"999-9999\"},\n"
	      "Person#{height=>180, weight=>80}.			 \n"
     },
     {module, "m1_work_3.erl",
	      "-module(m1_work_3).		      %% For Insert test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24},			 \n"
	      "Person#{height=>180, weight=>80}.			 \n"
     },
     {module, "m1_work_4.erl",
	      "-module(m1_work_4).		      %% For Insert test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24, phone=>\"999-9999\"},\n"
	      "Person#{height=>180}.					 \n"
     },
     {module, "m1_work_5.erl",
	      "-module(m1_work_5).		      %% For Remove test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", 				 \n"
	      "           age=>18, age=>24, phone=>\"999-9999\"},	 \n"
	      "Person#{height=>180, weight=>80}.			 \n"
     },
     {module, "m1_work_6.erl",
	      "-module(m1_work_6).		      %% For Remove test \n"
	      "-export([run/0]).					 \n"
	      "run() ->							 \n"
	      "Person = #{name=>\"Test1\", age=>24, phone=>\"999-9999\"},\n"
	      "Person#{height=>180, weight=>10, weight=>80}.		 \n"
     },
     {module, "m2_orig.erl",
	      "-module(m2_orig).			\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_1.erl",
	      "-module(m2_work_1).   %% For Update test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_2.erl",
	      "-module(m2_work_2).   %% For Update test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_3.erl",
	      "-module(m2_work_3).   %% For Insert test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2		  }=>b, \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_4.erl",
	      "-module(m2_work_4).   %% For Insert test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_5.erl",
	      "-module(m2_work_5).   %% For Insert test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2		  }=>d,	\n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_6.erl",
	      "-module(m2_work_6).   %% For Insert test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d}.	\n"
     },
     {module, "m2_work_7.erl",
	      "-module(m2_work_7).		%% For Remove test \n"
	      "-export([run/0]).				   \n"
	      "run() ->						   \n"
	      "CMap = #{#{one=>1, two=>2, three=>3           }=>a, \n"
	      "         #{one=>1, 2=>2,   three=>11, three=>3}=>b, \n"
	      "	        #{one=>1, 2.0=>2, three=>3           }=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,		   \n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   	   \n"
     },
     {module, "m2_work_8.erl",
	      "-module(m2_work_8).   %% For Remove test	\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>x, \n"
	      "         #{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b, \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,    \n" 
	      "      #{one=>1, y=>2,   three=>3}=>e}.   \n"
     },
     {module, "m2_work_9.erl",
	      "-module(m2_work_9).	   %% For Remove test \n"
	      "-export([run/0]).			      \n"
	      "run() ->					      \n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a,       \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b,       \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},      \n"
	      "CMap#{#{one=>1, x=>2, three=>11, three=>3}=>d, \n" 
	      "      #{one=>1, y=>2, three=>3           }=>e}.\n"
     },
     {module, "m2_work_10.erl",
	      "-module(m2_work_10).	   %% For Remove test \n"
	      "-export([run/0]).			      \n"
	      "run() ->					      \n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a,       \n"
	      "         #{one=>1, 2=>2,   three=>3}=>b,       \n"
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},      \n"
	      "CMap#{#{one=>1, x=>2, three=>3}=>x, 	      \n"
	      "      #{one=>1, x=>2, three=>3}=>d,	      \n"  
	      "      #{one=>1, y=>2, three=>3}=>e}.	      \n"
     },
     {module, "m3_orig.erl",
	      "-module(m3_orig).			\n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, two=>2, three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, x=>2,   three=>3}=>e}.   \n"
     },
     {module, "m3_work_1.erl",
	      "-module(m3_work_1).   %% For Insert test \n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, two=>2          }=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	\n" 
	      "      #{one=>1, x=>2,   three=>3}=>e}.   \n"
     },
     {module, "m3_work_2.erl",
	      "-module(m3_work_2).   %% For Insert test \n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, two=>2, three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2	       }=>d,	\n" 
	      "      #{one=>1, x=>2,   three=>3}=>e}.   \n"
     },
     {module, "m3_work_3.erl",
	      "-module(m3_work_3).	   %% For Remove test \n"
	      "-export([run/0]).			      \n"
	      "run() ->					      \n"
	      "CMap = #{#{one=>1, two=>2, three=>3      }=>a, \n"
	      "         #{one=>1, two=>2, three=>3, x=>x}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3      }=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>3}=>d,	      \n" 
	      "      #{one=>1, x=>2,   three=>3}=>e}.         \n"
     },
     {module, "m3_work_4.erl",
	      "-module(m3_work_4).   %% For Remove test \n"
	      "-export([run/0]).			\n"
	      "run() ->					\n"
	      "CMap = #{#{one=>1, two=>2, three=>3}=>a, \n"
	      "         #{one=>1, two=>2, three=>3}=>b, \n"	      
	      "	        #{one=>1, 2.0=>2, three=>3}=>c},\n"
	      "CMap#{#{one=>1, x=>2,   three=>1, three=>3}=>d,	\n" 
	      "      #{one=>1, x=>2,   three=>3          }=>e}. \n"
     },
     {module, "m4_orig.erl",
	      "-module(m4_orig). %% For Remove test  \n"
	      "-export([run/0]).		     \n"
	      "run() ->				     \n"
	      "CMap = #{[#{b=>2}]=>1, [#{b=>2}]=>2}. \n"
     },
     {module, "m4_work_1.erl",
	      "-module(m4_work_1). %% For Remove test \n"
	      "-export([run/0]).		      \n"
	      "run() ->				      \n"
	      "CMap = #{[#{a=>1}, #{b=>2}]=>1,        \n"
	      "         [#{b=>2}         ]=>2}.       \n"
     },
     {module, "m5_orig.erl",
	      "-module(m5_orig). %% For Remove test  \n"
	      "-export([run/0]).		     \n"
	      "run() ->				     \n"
	      "CMap = #{[a, c]=>1, [a, c]=>2}.       \n"
     },
     {module, "m5_work_1.erl",
	      "-module(m5_work_1). %% For Remove test \n"
	      "-export([run/0]).		      \n"
	      "run() ->				      \n"
	      "CMap = #{[a, b, c]=>1, [a, c]=>2}.     \n"
     }].

%%% ============================================================================
%%% Test functions for Update

test_simple_const_map_key_update() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_1), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(),
					    ?Form:maps()]), map_not_found),
    Keys = ?Query:exec(Map, ?Map:keys()),
    [_,SndK|_] = Keys,
    NumOfKeys = length(Keys),
    
    SndKE = ?Query:exec1(SndK, ?MapKey:keydef(), key_expr_not_found),
    
    ?ESG:update(SndKE, (?ESG:data(SndKE))#expr{value = name}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndKE, (?ESG:data(SndKE))#expr{value = phone}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndKE, (?ESG:data(SndKE))#expr{value = age}),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod).

test_complex_const_map_key_update() -> 
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_1), mod_not_found),

    Form = ?Query:exec1(WorkMod, ?Query:seq(?Mod:local(run, 0), 
				    	    ?Fun:definition()), form_not_found),
    [Map|_] = ?Query:exec(Form, ?Form:maps()),
    Keys = ?Query:exec(Map, ?Map:keys()),
    [_,SndK|_] = Keys,
    NumOfKeys = length(Keys),
    
    [_,SndSubKE,_] = ?Query:exec(SndK, ?Query:seq([?MapKey:keydef(),
						   ?Expr:mapdef(), 
						   ?Map:keys(),
						   ?MapKey:keydef()])),

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = two}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = 2.0}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = 2}),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod).

test_simple_var_map_key_update() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_2), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(), 
					    ?Form:maps()]), map_not_found),
    Keys = ?Query:exec(Map, ?Map:keys()),
    [_,_,_,FthK,_] = Keys,
    NumOfKeys = length(Keys),
    
    FthKE = ?Query:exec1(FthK, ?MapKey:keydef(), key_expr_not_found),
    
    ?ESG:update(FthKE, (?ESG:data(FthKE))#expr{value = age}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(FthKE, (?ESG:data(FthKE))#expr{value = weight}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(FthKE, (?ESG:data(FthKE))#expr{value = height}),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod).

test_complex_var_map_key_update() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_2), mod_not_found),

    Form = ?Query:exec1(WorkMod, ?Query:seq(?Mod:local(run, 0), 
				    	    ?Fun:definition()), form_not_found),
    [Map|_] = ?Query:exec(Form, ?Form:maps()),
    Keys = ?Query:exec(Map, ?Map:keys()),
    [_,_,_,FthK,_] = Keys,
    NumOfKeys = length(Keys),
    
    [_,SndSubKE,_] = ?Query:exec(FthK, ?Query:seq([?MapKey:keydef(),
						   ?Expr:mapdef(), 
						   ?Map:keys(),
						   ?MapKey:keydef()])),

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = two}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = y}),
    ?ESG:finalize(),
    NumOfKeys = length(?Query:exec(Map, ?Map:keys())) + 1,

    ?ESG:update(SndSubKE, (?ESG:data(SndSubKE))#expr{value = x}),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod).

%%% ============================================================================
%%% Test functions for Insert

test_simple_const_map__infix_expr_insert() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_3), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(),
					    ?Form:maps()]), map_not_found),
    Seq = ?Query:seq(?Map:mapdef(), ?Expr:children()),
    AL = ?Query:exec1(Map, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(AL, ?Expr:children()))+1,

    IE = ?Syn:construct({?Syn:construct({atom, phone}), '=>',
			 ?Syn:construct({string, "999-9999"})}),
    ?Syn:replace(AL, {esub,Nth,0}, [IE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% Without sup map references change.
test_complex_const_map__infix_expr_insert1() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_3), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),    
    [_,SndK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(SndK, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(SubAL, ?Expr:children()))+1,

    SubIE = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			    ?Syn:construct({integer, 3})}),

    ?Syn:replace(SubAL, {esub,Nth,0}, [SubIE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% With sup map references change.
test_complex_const_map__infix_expr_insert2() ->
    OrigMod = ?Query:exec1(?Mod:find(m3_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m3_work_1), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    Keys = ?Query:exec(Map, ?Map:keys()),
    [_,SndK|_] = Keys,
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(SndK, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(SubAL, ?Expr:children()))+1,

    SubIE = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			    ?Syn:construct({integer, 3})}),

    ?Syn:replace(SubAL, {esub,Nth,0}, [SubIE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_complex_const_map__assoc_map_insert() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_4), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    Seq = ?Query:seq(?Map:mapdef(), ?Expr:children()),
    AL = ?Query:exec1(Map, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(AL, ?Expr:children()))+1,

    IE_1 = ?Syn:construct({?Syn:construct({atom, one}), '=>',
			   ?Syn:construct({integer, 1})}),
    IE_2 = ?Syn:construct({?Syn:construct({float, 2.0}), '=>', 
			   ?Syn:construct({integer, 2})}),
    IE_3 = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			   ?Syn:construct({integer, 3})}),
    LOp = ?Syn:construct({{assoc_map_expr}, [IE_1, IE_2, IE_3]}),
    ROp = ?Syn:construct({atom, c}),
    IE = ?Syn:construct({LOp,'=>',ROp}),

    ?Syn:replace(AL, {esub,Nth,0}, [IE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_simple_var_map__infix_expr_insert() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_4), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(),
					    ?Form:maps()]), map_not_found),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), [{esub, back}], [{esub, back}]]),
    AL = ?Query:exec1(FthK, Seq, key_value_list_expr_not_found),
    Nth = length(?Query:exec(AL, ?Expr:children()))+1,

    IE = ?Syn:construct({?Syn:construct({atom, weight}), '=>',
			 ?Syn:construct({integer, 80})}),
    ?Syn:replace(AL, {esub,Nth,0}, [IE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% Without sup map references change.
test_complex_var_map__infix_expr_insert1() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_5), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(FthK, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(SubAL, ?Expr:children()))+1,

    SubIE = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			    ?Syn:construct({integer, 3})}),

    ?Syn:replace(SubAL, {esub,Nth,0}, [SubIE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% With sup map references change.
test_complex_var_map__infix_expr_insert2() ->
    OrigMod = ?Query:exec1(?Mod:find(m3_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m3_work_2), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,TrdK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(TrdK, Seq, assoc_list_expr_not_found),
    Nth = length(?Query:exec(SubAL, ?Expr:children()))+1,

    SubIE = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			    ?Syn:construct({integer, 3})}),

    ?Syn:replace(SubAL, {esub,Nth,0}, [SubIE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_complex_var_map__assoc_map_insert() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_6), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), [{esub, back}], [{esub, back}]]),
    AL = ?Query:exec1(FthK, Seq, key_value_list_expr_not_found),
    Nth = length(?Query:exec(AL, ?Expr:children()))+1,

    IE_1 = ?Syn:construct({?Syn:construct({atom, one}), '=>',
			   ?Syn:construct({integer, 1})}),
    IE_2 = ?Syn:construct({?Syn:construct({atom, y}), '=>', 
			   ?Syn:construct({integer, 2})}),
    IE_3 = ?Syn:construct({?Syn:construct({atom, three}), '=>',
			   ?Syn:construct({integer, 3})}),
    LOp = ?Syn:construct({{assoc_map_expr}, [IE_1, IE_2, IE_3]}),
    ROp = ?Syn:construct({atom, e}),
    IE = ?Syn:construct({LOp,'=>',ROp}),

    ?Syn:replace(AL, {esub,Nth,0}, [IE]),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%%% ============================================================================
%%% Test functions for Remove

test_simple_const_map__expr_remove() ->
    OrigMod = ?Query:exec1(?Mod:find(m5_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m5_work_1), mod_not_found),

    [Map] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	     ?Fun:definition(),
					     ?Form:maps()])),
    [FstK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), ?Expr:children()]),
    FstList = ?Query:exec1(FstK, Seq, list_expr_not_found),
    SndExp = ?Query:exec1(FstList, ?Expr:child(2), expr_not_found),

    ?ESG:remove(FstList, esub, SndExp),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_simple_const_map__infix_expr_remove() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_5), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(),
					    ?Form:maps()]), map_not_found),
    Seq = ?Query:seq(?Map:mapdef(), ?Expr:children()),
    AL = ?Query:exec1(Map, Seq, assoc_list_not_found),
   
    [IE] = ?Query:exec(AL, ?Expr:child(2)),
    ?ESG:remove(AL, esub, IE),
    ?ESG:finalize(),    
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% Without sup map references change.
test_complex_const_map__infix_expr_remove1() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_7), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),    
    [_,SndK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(SndK, Seq, assoc_list_expr_not_found),

    [SubIE] = ?Query:exec(SubAL, ?Expr:child(3)),
    ?ESG:remove(SubAL, esub, SubIE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% With sup map references change.
test_complex_const_map__infix_expr_remove2() ->
    OrigMod = ?Query:exec1(?Mod:find(m3_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m3_work_3), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,SndK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(SndK, Seq, assoc_list_expr_not_found),

    [SubIE] = ?Query:exec(SubAL, ?Expr:child(4)),
    ?ESG:remove(SubAL, esub, SubIE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_complex_const_map__assoc_map_remove() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_8), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    Seq = ?Query:seq(?Map:mapdef(), ?Expr:children()),
    AL = ?Query:exec1(Map, Seq, assoc_list_expr_not_found),

    [IE] = ?Query:exec(AL, ?Expr:child(1)),
    ?ESG:remove(AL, esub, IE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_complex_const_map__assoc_map_remove_from_list() ->
    OrigMod = ?Query:exec1(?Mod:find(m4_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m4_work_1), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [FstK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), ?Expr:children()]),
    FstList = ?Query:exec1(FstK, Seq, list_expr_not_found),
    FstSubME = ?Query:exec1(FstList, ?Expr:child(1), assoc_map_expr_not_found),

    ?ESG:remove(FstList, esub, FstSubME),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_simple_var_map__infix_expr_remove() ->
    OrigMod = ?Query:exec1(?Mod:find(m1_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m1_work_6), mod_not_found),

    Map = ?Query:exec1(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	    ?Fun:definition(),
					    ?Form:maps()]), map_not_found),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), [{esub, back}], [{esub, back}]]),
    AL = ?Query:exec1(FthK, Seq, key_value_list_expr_not_found),

    [IE] = ?Query:exec(AL, ?Expr:child(2)),
    ?ESG:remove(AL, esub, IE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% Without sup map references change.
test_complex_var_map__infix_expr_remove1() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_9), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(FthK, Seq, assoc_list_expr_not_found),

    [SubIE] = ?Query:exec(SubAL, ?Expr:child(3)),
    ?ESG:remove(SubAL, esub, SubIE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

%% With sup map references change.
test_complex_var_map__infix_expr_remove2() ->
    OrigMod = ?Query:exec1(?Mod:find(m3_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m3_work_4), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,TrdK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq(?MapKey:keydef(), ?Expr:children()),
    SubAL = ?Query:exec1(TrdK, Seq, assoc_list_expr_not_found),

    [SubIE] = ?Query:exec(SubAL, ?Expr:child(3)),
    ?ESG:remove(SubAL, esub, SubIE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

test_complex_var_map__assoc_map_remove() ->
    OrigMod = ?Query:exec1(?Mod:find(m2_orig), mod_not_found),
    WorkMod = ?Query:exec1(?Mod:find(m2_work_10), mod_not_found),

    [Map|_] = ?Query:exec(WorkMod, ?Query:seq([?Mod:local(run, 0), 
				    	        ?Fun:definition(),
					        ?Form:maps()])),
    [_,_,_,FthK|_] = ?Query:exec(Map, ?Map:keys()),
    Seq = ?Query:seq([?MapKey:keydef(), [{esub, back}], [{esub, back}]]),
    AL = ?Query:exec1(FthK, Seq, key_value_list_expr_not_found),

    [IE] = ?Query:exec(AL, ?Expr:child(1)),
    ?ESG:remove(AL, esub, IE),
    ?ESG:finalize(),
    ?AnalMap:is_equal_in_maps(OrigMod, WorkMod),
    ok.

