function comp=encapNew(comp,encap,chd,idx)
% Get indexes
cmnames=string(extractfield(comp,'name'));%unique
if length(cmnames)>length(unique(cmnames))
    disp('There are duplicate component names')
    return
end
chdnames=string(extractfield(chd,'name'));%unique
if length(chdnames)>length(unique(chdnames))
    disp('There are duplicate children components')
    return
end
[~,idxEncap,~]=intersect(cmnames,encap,'stable');
nChd=length(chdnames);
comp(idxEncap).children=chdnames';
for i=1:nChd
    [~,idxChd,~]=intersect(cmnames,chd(i).def,'stable');
    icomp=comp(idxChd);
    % Label alias for some vars
    if ~isempty(chd(i).label)
    [~,idxVar,idxLabel]=intersect(icomp.vars(:,idx.var),chd(i).label(:,1),'stable');
    icomp.vars(idxVar,idx.var)=chd(i).label(idxLabel,2);
    end
    %% Copy the non-overlapped parameters of the child to the parent
    idxes_encap=find(comp(idxEncap).vars(:,idx.vctg)=='para');
    idxes_chd=icomp.vars(:,idx.vctg)=='para';
    vars_Encap=comp(idxEncap).vars(idxes_encap,:);
    vars_chd=icomp.vars(idxes_chd,:);
    if ~(isempty(vars_Encap) && isempty(vars_chd)) % at least one has para
        if isempty(vars_Encap) || isempty(vars_chd)
            varsMatch=[];
            vars_nomatch_chd=vars_chd;
        else %both have para
            [varsMatch,idxMatch_encap,idxMatch_ichd]=intersect(vars_Encap(:,idx.var),vars_chd(:,idx.var),'stable');
            nomatch_chd=setdiff((1:size(vars_chd,1)),idxMatch_ichd);
            vars_nomatch_chd=vars_chd(nomatch_chd,:);
        end
        if (~isempty(varsMatch))
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.priv)='out';
        end
        if ~isempty(vars_nomatch_chd)
            vars_nomatch_chd(:,idx.pub)='in';
            vars_nomatch_chd(:,idx.priv)='out';            
            comp(idxEncap).vars=[vars_nomatch_chd;comp(idxEncap).vars;];%creat
        end
    end
    %% Find the matched outputs of the parent for the inputs of the child
    idxes_encap=find(comp(idxEncap).vars(:,idx.vctg)=='out');
    idxes_chd=icomp.vars(:,idx.vctg)=='in';
    vars_Encap=comp(idxEncap).vars(idxes_encap,:);
    vars_chd=icomp.vars(idxes_chd,:);
    if ~(isempty(vars_Encap) && isempty(vars_chd)) % at least one is not empty
        if isempty(vars_Encap) || isempty(vars_chd)
            varsMatch=[];
        else %neither is empty
            [varsMatch,idxMatch_encap,~]=intersect(vars_Encap(:,idx.var),vars_chd(:,idx.var),'stable');
        end
        % connect the outputs of the parent to the inputs of the child
        if (~isempty(varsMatch))
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.priv)='out';
        end
    end
    %% Find the matched inputs of the parent for the outputs of the child
    idxes_encap=find(comp(idxEncap).vars(:,idx.vctg)=='in');
    idxes_chd=icomp.vars(:,idx.vctg)=='out';
    vars_Encap=comp(idxEncap).vars(idxes_encap',:);
    vars_chd=icomp.vars(idxes_chd',:);
    if ~(isempty(vars_Encap) && isempty(vars_chd)) % at least one is not empty
        if isempty(vars_Encap) || isempty(vars_chd)
            varsMatch=[];
        else %neither is empty
            [varsMatch,idxMatch_encap,~]=intersect(vars_Encap(:,idx.var),vars_chd(:,idx.var),'stable');
        end
        % connect the inputs of the parent to the outputs of the child
        if (~isempty(varsMatch))
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.priv)='in';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.pub)='out';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.vctg)='out';
        end
    end
    %% Pass the matched inputs of the parent to the inputs of the child
    idxes_encap=find(comp(idxEncap).vars(:,idx.vctg)=='in');
    idxes_chd=icomp.vars(:,idx.vctg)=='in';
    vars_Encap=comp(idxEncap).vars(idxes_encap',:);
    vars_chd=icomp.vars(idxes_chd',:);
    if ~(isempty(vars_Encap) && isempty(vars_chd)) % at least one is not empty
        if isempty(vars_Encap) || isempty(vars_chd)
            varsMatch=[];
        else %neither is empty
            [varsMatch,idxMatch_encap,~]=intersect(vars_Encap(:,idx.var),vars_chd(:,idx.var),'stable');
        end
        % connect the inputs of the parent to the inputs of the child
        if (~isempty(varsMatch))
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.priv)='out';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.pub)='in';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.vctg)='in';
        end
    end
    %% Pass the matched outputs of the child to the outputs of the parent
    idxes_encap=find(comp(idxEncap).vars(:,idx.vctg)=='out');
    idxes_chd=icomp.vars(:,idx.vctg)=='out';
    vars_Encap=comp(idxEncap).vars(idxes_encap',:);
    vars_chd=icomp.vars(idxes_chd',:);
    if ~(isempty(vars_Encap) && isempty(vars_chd)) % at least one is not empty
        if isempty(vars_Encap) || isempty(vars_chd)
            varsMatch=[];
        else %neither is empty
            [varsMatch,idxMatch_encap,~]=intersect(vars_Encap(:,idx.var),vars_chd(:,idx.var),'stable');
        end
        % connect the inputs of the parent to the inputs of the child
        if (~isempty(varsMatch))
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.priv)='in';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.pub)='out';
            comp(idxEncap).vars(idxes_encap(idxMatch_encap),idx.vctg)='out';
        end
    end
end
end
