function [busObj, busName] = getBusObjectFromName(busName, okToError, dataAccessor)
%

%   Copyright 2011-2020 The MathWorks, Inc.

    persistent DataAcc BusMap;

    % As this function is called excessively when preparing data
    % for simulation, often with the same strings, use memoization 
    % to improve performance WJA - 5-26-2021
    if nargin==1 && busName==-1
        % Clear the memoization
        DataAcc = [];
        BusMap = [];
        return;
    end
    
    if isempty(dataAccessor)
        % Clear the memoization
        DataAcc = [];
        BusMap = [];
        error(message('Sldv:shared:utils:MissingDataAccessor'));
    end

    if isempty(DataAcc) || ~isequal(dataAccessor, DataAcc)
        DataAcc = dataAccessor;
        BusMap = containers.Map('KeyType','char','ValueType','any');
    end
    

    busName = strtrim(strrep(busName,'Bus:',''));

    % Use try-catch instead of gaurding with map.isKey() to handle when 
    % we do not have cached results because the vast majority of cases 
    % the cache will exist
    try
        % Retrieve stored value from previous call
        busObj = BusMap(busName);
        if (isnumeric(busObj) && busObj==-1)
            busObj = [];
        end
    catch Mx %#ok<NASGU>
        try
            busObj = sl('slbus_get_object_from_name_withDataAccessor', busName, okToError, dataAccessor);
        catch Mex %#ok<NASGU>
            % Dont expect an error but it could happen
            busObj = [];
        end

        % Cache the value for future calls
        if isempty(busObj)
            BusMap(busName) = -1;
        else
            BusMap(busName) = busObj;
        end
    end
end
