function [d,C,range,res] = residuals(this,d,range)
% residuals  Evaluate bkwmodel residuals and calculate covariance matrix.
%
% Syntax
% =======
%
%     [d,C,range] = residuals(b,d,range)
%
% Input arguments
% ================
%
% * `b` [ bkwmodel ] - Bkwmodel object.
%
% * `D` [ struct ] - Input database with all endogenous and exogenous
% variables.
%
% * `range` [ numeric ] - Date range including the necessary pre-sample
% observations; if Inf is entered, the longest available range will be
% used.
%
% Output arguments
% =================
%
% * `d` [ struct ] - Output database including the residuals.
%
% * `C` [ numeric ] - Covariance matrix of the residuals.
%
% * `range` [ numeric ] - Date range.
%
% Description
% ============
%
% Example
% ========
% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

%**************************************************************************

maxlag = size(this.occur,3) - 1;
ne = sum(this.nametype == 3);

% Get input data.
if ~isinf(range(1))
   xrange = [range(1)-maxlag,range(end)];
else
   xrange = range;
end
[x,xrange] = db2dp(this,d,xrange);

% Number of data sets.
nloop = size(x,3);

nper = length(xrange);
first = maxlag + 1;
t = first : nper;
T = nper - maxlag;

% Evaluate residuals from all equations and compute the cov matrix.
res = nan([ne,nper,nloop]);
C = nan([ne,ne,nloop]);
for iloop = 1 : nloop
   res(:,first:nper,iloop) = this.eqtnEvalAllRes(x(:,:,iloop),t);
   C(:,:,iloop) = res(:,first:nper,iloop)*res(:,first:nper,iloop).' / T;
end

% Convert residuals to a database.
template = tseries();
template.start = xrange(first);
template.data = zeros([nper-maxlag,nloop]);
template.Comment = cell([1,nloop]);
elist = this.name(this.nametype == 3);
elabel = this.namelabel(this.nametype == 3);
for i = 1 : length(elist)
   d.(elist{i}) = template;
   d.(elist{i}).data = permute(res(i,:,:),[2,3,1]);
   d.(elist{i}).Comment(:) = elabel(i);
end

res = res(:,first:nper,:);

end
