function setSlice(this,Section,B,GridSize)
%SETSLICE  Modifies multi-dimensional slice of value array.
%
%   SETSLICE(ValueArray,Section,Array,GridSize)

%   Author(s): P. Gahinet
%   Copyright 1986-2003 The MathWorks, Inc.
%   $Revision: 1.1.6.1 $  $Date: 2004/12/26 21:32:21 $

% RE: Assumes that 
%  1) the size of B is compatible with the grid slice specified by SECTION
%  2) this assignment does not grow the grid
%  3) If B is not a cell array of samples, it is treated as a SINGLE sample
%     (B -> {B})
Ns = prod(GridSize);
NsB = prod(cellfun('length',Section));
isCellofSampleB = (isa(B,'cell') && numel(B)==NsB);

% Get current array
A = getArray(this); 
isCellofSampleA = (isa(A,'cell') && isequal(this.SampleSize,[1 1]));

% Special case handling
if isequal(A,[]) && isCellofSampleB && isequal(B{:},[])
   % Empty sample values for uninitialized variable: do nothing 
   % (leave it uninitialized)
   return
   
elseif isequal(B,[])
   % Deleting a slice
   if isscalar(A)
      % Scalar storage: Turn A into full-size array
      A = hdsReplicateArray(A,[GridSize 1]);
   end
   % Update container data
   is(:,1:length(this.SampleSize)) = {':'};
   if this.GridFirst
      A = hdsSetSlice(A,[Section is],B);
   else
      A = hdsSetSlice(A,[is Section],B);
   end
   
else
   % Modifying a slice
   % Initialize or expand A
   if isempty(A)
      % Creating new array
      if isCellofSampleB
         % Try converting data to homogenous array (preferred format)
         try
            [B,this.SampleSize] = utCell2Array(this,B);
            isCellofSampleB = false;
         catch
            this.SampleSize = [1 1];
         end
      end
      % Create new array of size grid size and data type inherited from SLICE
      if this.GridFirst
         A = hdsNewArray(B,[GridSize this.SampleSize]);
      else
         A = hdsNewArray(B,[this.SampleSize GridSize]);
      end
      isCellofSampleA = isCellofSampleB;
   end
   
   % Align the formats of A and B
   if isCellofSampleB && ~isCellofSampleA
      % Try converting B to a numeric array
      if isscalar(B)
         % Optimization
         B_Array = B{1};
         SampleSizeB = size(B_Array);
      else
         try
            [B_Array,SampleSizeB] = utCell2Array(this,B);
         catch
            SampleSizeB = [];
         end
      end
      if isequal(this.SampleSize,SampleSizeB)
         % Conversion successful
         B = B_Array;
         isCellofSampleB = false;
      else
         % Conversion failed: must convert A to cell format
         A = this.utArray2Cell(A);
         isCellofSampleA = true;
         this.SampleSize = [1 1];
      end
   end

   if isCellofSampleA && ~isCellofSampleB
      % Treat B as single sample
      B = {B};
   end
   
   % Scalar expansion of A (scalar storage)
   if isscalar(A)
      if isscalar(B) && isequal(A,B)
         % No change (optimization)
         return
      else
         % Turn A into full-size array
         A = hdsReplicateArray(A,[GridSize 1]);
      end
   end
   
   % Handle absolute indexing
   AbsoluteIndex = (length(Section)<length(GridSize));
   if AbsoluteIndex
      % Absolute indexing
      A = this.utReshape(A,Ns);
      B = this.utReshape(B,NsB);
   end
   
   % Perform assignment   
   is(:,1:length(this.SampleSize)) = {':'};
   try
      if this.GridFirst
         A = hdsSetSlice(A,[Section is],B);
      else
         A = hdsSetSlice(A,[is Section],B);
      end
   catch
      % Assignment may fail due to incompatible array types. In such case,
      % convert both A and B to cell array format and try again
      if ~isCellofSampleA
         A = this.utArray2Cell(A);
         B = this.utArray2Cell(B);
         this.SampleSize = [1 1];
      end
      if this.GridFirst
         A = hdsSetSlice(A,[Section is],B);
      else
         A = hdsSetSlice(A,[is Section],B);
      end
   end      

   if AbsoluteIndex
      % Absolute indexing
      A = this.utReshape(A,GridSize);
   end
end

% Update container data
this.setArray(A)
