function Dss = dss(Da,Db,Dc,Dd,De,Ts)
% Build dynamic LFT model for DSS(A,B,C,D,E,Ts) given static models for 
% A,B,C,D,E. The E term may be empty.

%   Author(s): P. Gahinet
%   Copyright 2009-2017 The MathWorks, Inc.
[nx,~] = iosize(Da);
if nx==0
   % Static
   ICS = Dd.IC;
   if allfinite(ICS)
      [rs,cs] = size(ICS);
      IC = ltipack.ssdata([],zeros(0,cs),zeros(rs,0),ICS,[],Ts);
      Blocks = Dd.Blocks;
   else
      [rs,cs] = iosize(Dd);
      IC = ltipack.ssdata([],zeros(0,cs),zeros(rs,0),NaN(rs,cs),[],Ts);
      Blocks = ltipack.LFTBlockWrapper.emptyBlockList();
   end
else
   % Dynamic
   try
      Dabcd = iocat(1,iocat(2,Da,Db),iocat(2,Dc,Dd));
   catch ME
      if strcmp(ME.identifier,'Control:lftmodel:BlockName2')
         % Inconsistent block definitions
         throw(ME)
      else
         % Size mismatch
         error(message('Control:lftmodel:ss2'))
      end
   end
   ICS = Dabcd.IC;
   if allfinite(ICS) && (isempty(De) || isfinite(De))
      Blocks = Dabcd.Blocks;
      [rs,cs] = size(ICS);
      if isempty(De)
         % No E matrix
         IC = ltipack.ssdata(ICS(1:nx,1:nx),ICS(1:nx,nx+1:cs),...
            ICS(nx+1:rs,1:nx),ICS(nx+1:rs,nx+1:cs),[],Ts);
      elseif ~isequal(iosize(De),[nx nx])
         error(message('Control:lftmodel:ss3'))
      elseif isempty(De.Blocks)
         % Constant E matrix
         IC = ltipack.ssdata(ICS(1:nx,1:nx),ICS(1:nx,nx+1:cs),...
            ICS(nx+1:rs,1:nx),ICS(nx+1:rs,nx+1:cs),De.IC,Ts);
      else
         % Block-dependent E matrix
         ICE = De.IC;
         [nwE,nzE] = iosize(De.Blocks);
         aa = blkdiag(ICS(1:nx,1:nx),eye(nwE));
         bb = blkdiag(ICS(1:nx,nx+1:cs),-eye(nwE));
         cc = [[ICS(nx+1:rs,1:nx) ; ICE(nx+1:nx+nzE,1:nx)] , zeros(rs-nx+nzE,nwE)];
         dd = blkdiag(ICS(nx+1:rs,nx+1:cs),ICE(nx+1:nx+nzE,nx+1:nx+nwE));
         ee = [ICE(1:nx,:) ; zeros(nwE,nx+nwE)];
         IC = ltipack.ssdata(aa,bb,cc,dd,ee,Ts);
         Blocks = append(Blocks,De.Blocks);
      end
   else
      % Some NaN model
      [rs,cs] = iosize(Dd);
      IC = ltipack.ssdata([],zeros(0,cs),zeros(rs,0),NaN(rs,cs),[],Ts);
      Blocks = ltipack.LFTBlockWrapper.emptyBlockList();
   end
end
Dss = ltipack.lftdataSS(IC,Blocks);
