function setSpecialDirs(h,buildInfo)

%   Copyright 2014-2017 The MathWorks, Inc.
    
%% Determine the inputs needed from the Builder object and from buildInfo
% Data required from buildInfo
specialDirsFromBuildInfo = buildInfo.Settings.getSpecialDirsAndTokens...
    ('includeAltNames', true, 'includeEmptyNames', true, 'includeRegexpPats', true);
lFileSep = buildInfo.Settings.FileSep;
platform = buildInfo.getBuildToolInfo( 'Platform' );

% Toolchain-specific implementation of fullfile
lToolchainInfo = h.ToolchainInfo;
fcnToolchainInfoFullfile = @lToolchainInfo.fullfile;

% MakefileWriter-specific path transformation e.g. for nmake escape $ by
% replacing it with $$
fcnTransformPathBasedOnWriter = @h.transformPathBasedOnWriter;

%% Return transformed "special dirs" as field on Builder object
h.SpecialDirs = i_getSpecialDirs ...
    (specialDirsFromBuildInfo, lFileSep, platform, fcnToolchainInfoFullfile, ...
     fcnTransformPathBasedOnWriter);



%% Function to do the "special dirs" transformation
function specialDirs = i_getSpecialDirs ...
        (specialDirs, lFileSep, platform, fcnToolchainInfoFullfile, ...
         fcnTransformPathBasedOnWriter)

% Special dir: MATLAB ROOT ------------
mlRootIdx = 1;  % MATLAB root is always the first element
matlabRoot = specialDirs.dirs{ mlRootIdx };
altMatlabRoot = specialDirs.altNames{ mlRootIdx };
% Special dir: MATLAB BIN ------------
matlabBin = [ specialDirs.dirs{ mlRootIdx }, lFileSep, 'bin' ];
altMatlabBin = [ specialDirs.altNames{ mlRootIdx }, lFileSep, 'bin' ];
if ~strcmp( matlabRoot, altMatlabRoot )
    matlabRoot = altMatlabRoot;
    matlabBin = altMatlabBin;
end
% Special dir: MATLAB ARCH BIN ------------
if isempty( platform )
    platform = computer( 'arch' );
end
matlabArchBin = fcnToolchainInfoFullfile('$(MATLAB_BIN)', platform);
% Macros
macros = { 'MATLAB_ROOT'; 'MATLAB_BIN'; 'MATLAB_ARCH_BIN' };
% Their values
macroValues = { matlabRoot; matlabBin; matlabArchBin };
% Other special dirs ------------
% Get the regular replacements
specDirs = specialDirs.dirs( 2:end );
specDirsAlt = specialDirs.altNames( 2:end );
specDirToks = specialDirs.tmfToks( 2:end );
% For dirs that do not have replacements, use the alternate replacements
spaceIdx = contains( specDirs, ' ' );  % folders with spaces
specDirs( spaceIdx ) = specDirsAlt( spaceIdx );
% Use the macro-based value for MASTER_ANCHOR_DIR, e.g. $(START_DIR)
% masterIdx = find(strcmp(specDirToks, '|>MASTER_ANCHOR_DIR<|'));
% specDirs(masterIdx) = specialDirs.toks(masterIdx+1);
% ------------------------------------------------------
% Remove |>MASTER_ANCHOR_DIR<| from list of special dirs
% ------------------------------------------------------
% Because the master anchor dir and start dir map to the same makefile
% macro $(START_DIR), we only need one of them from here on out.  Remove
% the index for the token matching '|>MASTER_ANCHOR_DIR<|'
idx = ~strcmp( specialDirs.tmfToks, '|>MASTER_ANCHOR_DIR<|' );
specialDirs.dirs = specialDirs.dirs( idx );
specialDirs.toks = specialDirs.toks( idx );
specialDirs.tmfToks = specialDirs.tmfToks( idx );
specialDirs.altNames = specialDirs.altNames( idx );
specialDirs.regexpPats = specialDirs.regexpPats( idx );
specialDirs.regexpAltNamePats = specialDirs.regexpAltNamePats( idx );
% ---------------------------------------------------------------------
% Add the special dirs to list of tokens that need to be replaced early
% ---------------------------------------------------------------------
macros = [ macros; specDirToks' ];
macroValues = [ macroValues; specDirs' ];
macros = coder.make.internal.unrefMacro( macros, '\|>(\w*)<\|' );
macroValues = fcnTransformPathBasedOnWriter( macroValues );
numMacros = numel( macros );
finalMacros( numMacros ) = struct( 'Name', [  ], 'Value', [  ] );
for i = 1:numMacros
    finalMacros( i ).Name = macros{ i };
    finalMacros( i ).Value = macroValues{ i };
end
specialDirs.Macros = finalMacros;

