function [D,icmap] = elimDelay(D,id,od,fd,icmap)
% Maps specified portion of the delays to 1/z.
%    elimDelay(D)
%    elimDelay(D,inputdelays,outputdelays,internaldelays)

%	 Author(s): P. Gahinet
%   Copyright 2020 The MathWorks, Inc.
if D.Ts==0
   error(message('Control:transformation:FirstArgDiscreteModel','elimDelay'))
end
ni = nargin;
if ni==1
   id = D.Delay.Input;
   od = D.Delay.Output;
   fd = D.Delay.Internal;
end
if ni<5
   % logical vector locating the continuous-time initial
   %   state x0c among the vector of discrete states.
   icmap = true(size(D.k,1),1);
end
[ny,nu] = iosize(D);

% Internal delays
% RE: Always mapping all or none
if any(fd(:))
   % Build a state-space realization of diag(Z.^(-INNERDELAYS))
   nfd = length(fd);
   Df = delay2z(D,D.Delay.Internal);
   % Absorb delay model
   icmap = [icmap ; false(sum(D.Delay.Internal),1)];
   D.Delay.Internal = zeros(0,1);
   D.Delay.Input(nu+nfd,1) = 0;
   D.Delay.Output(ny+nfd,1) = 0;
   D = lft(D,Df,nu+1:nu+nfd,ny+1:ny+nfd,1:nfd,1:nfd);
end

% Input delays
if any(id(:))
   % Build a state-space realization of diag(Z.^(-INPUTDELAYS))
   Din = delay2z(D,id);
   % Connect in series
   icmap = [icmap ; false(sum(id),1)];
   Din.Delay.Input = D.Delay.Input - id;
   D.Delay.Input = zeros(nu,1);
   D = mtimes(D,Din);
end

% Output delays
if any(od(:))
   % Build a state-space realization of diag(Z.^(-OUTPUTDELAYS))
   Dout = delay2z(D,od);
   % Connect in series
   icmap = [false(sum(od),1) ; icmap];
   Dout.Delay.Output = D.Delay.Output - od;
   D.Delay.Output = zeros(ny,1);
   D = mtimes(Dout,D);
end
