function [this,data] = integrate(this,varargin)
% integrate  Integrate VAR process and data associated with it.
%
% Syntax
% =======
%
%     V = integrate(V,...)
%     [V,D] = integrate(V,D,...)
%
% Input arguments
% ================
%
% * `V` [ VAR ] - VAR object whose variables will be integrated.
%
% * `D` [ tseries ] - Database or tseries associated with the VAR object.
%
% Output arguments
% =================
%
% * `V` [ VAR ] - VAR object with (some of) its variables integrated.
%
% * `D` [ struct | tseries ] - Integrated data associated with the VAR
% object.
%
% Options
% ========
%
% * `'applyTo='` [ logical | numeric | *`Inf`* ] - Index of variables to
% integrate; Inf means all variables will be integrated.
%
% Description
% ============
%
% Example
% ========
%

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

if ~isempty(varargin) && ~ischar(varargin{1})
    data = varargin{1};
    varargin(1) = [];
else
    data = [];
end

[ny,p,nalt] = sizeof(this); %#ok<ASGLU>

options = passvalopt('VAR.integrate',varargin{:});

% Make options.applyto logical index.
if isnumeric(options.applyto)
    if isequal(options.applyto,Inf)
        options.applyto = true([1,ny]);
    else
        aux = options.applyto;
        options.applyto = false([1,ny]);
        options.applyto(aux) = true;
    end
else
    options.applyto = logical(options.applyto(1:ny));
end

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

% Integrate model.
if any(options.applyto)
    D = cat(3,eye(ny),-eye(ny));
    D(~options.applyto,~options.applyto,2) = 0;
    A = this.A;
    this.A(:,end+1:end+ny,:) = NaN;
    for ialt = 1 : nalt
        a = poly.polyprod(timedom.var2poly(A(:,:,ialt)),D);
        this.A(:,:,ialt) = poly.poly2var(a);
    end
    this = myschur(this);
end

% Integrate associated data.
if nargout > 1 && ~isempty(data)
    [outputformat,range,y,e] = VAR.datarequest(this,data,Inf,options);
    y(options.applyto,:,:) = cumsum(y(options.applyto,:,:),2);
    presample = nan(ny,1,size(y,3));
    e = [presample,e];
    presample(options.applyto,:,:) = 0;
    y = [presample,y];
    data = VAR.outputdata(this,outputformat,range,[y;e],[], ...
        [this.ynames,this.enames]);
end

end