function D = replaceBlocks(D,BlockNames,BlockValues)
% Replaces blocks in D with names BLOCKNAMES by the values specified in 
% BLOCKVALUES. All values are single ltipack.lftdata* objects of the 
% same type as D.

%   Copyright 1986-2011 The MathWorks, Inc.
[ny,nu] = iosize(D);
NumFlag = isnumeric(D.IC);

% Locate blocks to replace
Blocks = D.Blocks;
iLoc = ltipack.findNamesInList(getBlockName(Blocks),BlockNames);
isubs = find(iLoc>0);
if isempty(isubs)
   return
end
ikeep = find(iLoc==0); 
D.Blocks = Blocks(ikeep,:);

% Permute blocks to put replaced blocks first
if ~isempty(ikeep)
   bperm = [isubs ; ikeep];
   [cperm,rperm] = getRowColPerm(Blocks,bperm); % before permuting Blocks!
   Blocks = Blocks(bperm);
   iLoc = iLoc(bperm);
   if NumFlag
      D.IC = D.IC([1:ny,ny+rperm],[1:nu,nu+cperm]);
   else
      D.IC = ioperm(D.IC,[1:ny,ny+rperm],[1:nu,nu+cperm]);
   end
end

% Perform block replacement
for ct=1:length(isubs)
   Value = BlockValues{iLoc(ct)};
   if isempty(Value)
      % Replace by current block wrapper value
      if NumFlag
         Value = D.createGain(double_(Blocks(ct)));
      else
         Value = D.lti2lft(D.blk2lti(Blocks(ct)));
      end
   else
      % Get block wrapper value, taking R,S transformation into account
      Value = evalBlockTransform(Blocks(ct),Value);
   end
   if ct==1
      BV = Value;
   else
      BV = append(BV,Value);
   end
end
[ny1,nu1] = iosize(D);
[ny2,nu2] = iosize(BV);
D = lft(D,BV,nu1-ny2+1:nu1,ny1-nu2+1:ny1,1:nu2,1:ny2);
