function M = append(varargin)
%APPEND  Appends model inputs and outputs. 
%
%   M = APPEND(M1,M2, ...) constructs the aggregate model
% 
%                 [ M1  0  .. 0 ]
%             M = [  0  M2      ]
%                 [  :      .   ]
%                 [  0        . ]
%
%   by concatenating the input and output vectors of the models M1, M2,... 
%   APPEND takes any combination of input/output model types (see
%   INPUTOUTPUTMODEL for an overview of available types). 
%
%   If M1,M2,... are arrays of models, APPEND returns a model array M of 
%   the same size where 
%      M(:,:,k) = APPEND(M1(:,:,k),M2(:,:,k),...) .
%
%   See also INPUTOUTPUTMODEL/BLKDIAG, SERIES, PARALLEL, FEEDBACK, INPUTOUTPUTMODEL.

%   Copyright 1986-2022 The MathWorks, Inc.
ni = nargin;
if ni<2
   M = varargin{1};  return
end

try
   % Harmonize types
   if ~ltipack.hasMatchingType('cat',varargin{:})
      [varargin{1:ni}] = ltipack.matchType('cat',varargin{:});
   end
   
   % All operands are now of the same type
   M = varargin{1};
   for j=2:ni
      Mj = varargin{j};
      % Combine data and metadata
      MMj = append_(M,Mj); % overloadable since M and Mj are of the same class
      M = iocatMetaData([1 2],MMj,M,Mj);
   end
   
   % Consistency checks (e.g., consistent block definition in LFT arrays)
   checkModelArray_(M)
catch E
   throw(E)
end

