function [orig during after] = miroptions(method,orig,specif,varg)

DEFAULTFRAMELENGTH = .05;
DEFAULTFRAMEHOP = .5;

% The options are determined during the bottom-up process design (see below). 

% During the following top-down evaluation initiation, the options being
% therefore already computed have simply been passed as fourth and fifth
% arguments of miroptions.
if not(isempty(varg)) && (isstruct(varg{1}) || isempty(varg{1}))
    during = varg{1};
    if isstruct(varg{1})
        if isfield(during,'struct')
            if isa(orig,'mirdesign') 
                orig = set(orig,'Struct',during.struct);
            elseif iscell(orig)
                for i = 1:length(orig)
                    if isa(orig{i},'mirdesign')
                        orig{i} = set(orig{i},'Struct',during.struct);
                    end
                end
            end
            during = rmfield(during,'struct');
        end
    end
    if length(varg) > 1
        after = varg{2};
    else
        after = [];
    end
    return
%elseif length(varg) > 1 && isstruct(varg{2})
%    during = varg{1};
%    after = varg{2};
%    return
%elseif length(varg) >= 1 && isempty(varg{1})
%    during = [];
%    after = [];
%    return
end


during = struct;
after = struct;
if isfield(specif,'option')
    option = specif.option;
else
    option = struct;
end
frame = [];
after = [];
fields = fieldnames(option);
persoframe = '';
for i = 1:length(fields)
    field = fields{i};
    if isfield(option.(field),'key') && ischar(option.(field).key) ...
            && strcmpi(option.(field).key,'Frame')
        persoframe = field;
        during.(field).auto = 0;
    end
    if isfield(option.(field),'when') && ...
            (strcmpi(option.(field).when,'After') || ...
             strcmpi(option.(field).when,'Both'))
        if isamir(orig,func2str(method)) ...
                && not(strcmp(func2str(method),'miraudio'))
            after.(field) = 0;
        elseif strcmp(field,'detect')
           %if haspeaks(orig)
           %    after.(field) = 0;
           %else
               after.(field) = 'Peaks';
           %end
        elseif isfield(specif,'title')
            if isa(orig,'mirdata')
                title = get(orig,'Title');
                sameclass = (length(title) > length(specif.title) && ...
                    strcmp(title(1:length(specif.title)),specif.title));
            else
                sameclass = strcmp(func2str(get(orig,'Method')),'mironsets');
            end
            if sameclass
                after.(field) = 0;
            else
                after.(field) = option.(field).default;
            end
        elseif isfield(option.(field),'default')
            after.(field) = option.(field).default;
        else
            after.(field) = 0;
        end
    end
    if not(isfield(option.(field),'when')) || strcmpi(option.(field).when,'Both')
        if isfield(option.(field),'default')
            if strcmpi(persoframe,field)
                during.(field).length.val = option.(field).default(1);
                during.(field).length.unit = 's';
                during.(field).hop.val = option.(field).default(2);
                during.(field).hop.unit = '/1';
            else
                during.(field) = option.(field).default;
            end
        end
    end
end
i = 1;
while i <= length(varg)
    arg = varg{i};
    if strcmpi(arg,'Frame')
        frame.auto = isempty(persoframe);
        frame.length.unit = 's';
        frame.hop.unit = '/1';
        if length(varg) > i && isnumeric(varg{i+1})
            i = i+1;
            frame.length.val = varg{i};
            if length(varg) > i && ischar(varg{i+1}) && ...
                    (strcmpi(varg{i+1},'s') || strcmpi(varg{i+1},'sp'))
                i = i+1;
                frame.length.unit = varg{i};
            end
            if length(varg) > i && isnumeric(varg{i+1})
                i = i+1;
                frame.hop.val = varg{i};
                if length(varg) > i && ischar(varg{i+1}) && ...
                        (strcmpi(varg{i+1},'%') || strcmpi(varg{i+1},'/1') || ...
                         strcmpi(varg{i+1},'s') || strcmpi(varg{i+1},'sp')|| ...
                         strcmpi(varg{i+1},'Hz'))
                    i = i+1;
                    frame.hop.unit = varg{i};
                end
                if not(frame.hop.val || strcmpi(frame.hop.unit,'Hz'))
                    mirerror(func2str(method),'The hop factor should be strictly positive.')
                end
            else
                if not(isempty(persoframe))
                    if isfield(option.(persoframe),'keydefault')
                        frame.hop.val = option.(persoframe).keydefault(2);
                    else
                        frame.hop.val = option.(persoframe).default(2);
                    end
                elseif isfield(specif,'defaultframehop')
                    frame.hop.val = specif.defaultframehop;
                else
                    frame.hop.val = DEFAULTFRAMEHOP;
                end
            end
        else
            if not(isempty(persoframe))
                if isfield(option.(persoframe),'keydefault')
                    frame.length.val = option.(persoframe).keydefault(1);
                else
                    frame.length.val = option.(persoframe).default(1);
                end
            elseif isfield(specif,'defaultframelength')
                frame.length.val = specif.defaultframelength;
            else
                frame.length.val = DEFAULTFRAMELENGTH;
            end
            if not(isempty(persoframe))
                if isfield(option.(persoframe),'keydefault')
                    frame.hop.val = option.(persoframe).keydefault(2);
                else
                    frame.hop.val = option.(persoframe).default(2);
                end
            elseif isfield(specif,'defaultframehop')
                frame.hop.val = specif.defaultframehop;
            else
                frame.hop.val = DEFAULTFRAMEHOP;
            end
        end
        frame.eval = 0;
        if not(isfield(option,'frame')) || ...
                not(isfield(option.frame,'when')) || ...
                strcmpi(option.frame.when,'Before') || ...
                strcmpi(option.frame.when,'Both')
            during.frame = frame;
        end
        if isfield(option,'frame') && ...
               isfield(option.frame,'when') && ...
               (strcmpi(option.frame.when,'After') || ...
               strcmpi(option.frame.when,'Both'))
            after.frame = frame;
        end
    else
        match = 0;
        k = 0;
        while not(match) && k<length(fields)
            k = k+1;
            field = fields{k};
            if isfield(option.(field),'key')
                key = option.(field).key;
                if not(iscell(key))
                    key = {key};
                end
                for j = 1:length(key)
                    if strcmpi(arg,key{j})
                        match = 1;
                    end
                end
                if match
                    if isfield(option.(field),'type')
                        type = option.(field).type;
                    else
                        type = [];
                    end
                    if isfield(option.(field),'unit')
                        unit = option.(field).unit;
                        defaultunit = option.(field).defaultunit;
                    else
                        unit = {};
                    end
                    if isfield(option.(field),'from')
                        from = option.(field).from;
                        defaultfrom = option.(field).defaultfrom;
                    else
                        from = {};
                    end
                    if strcmpi(type,'String')
                        if length(varg) > i && ...
                                (ischar(varg{i+1}) || varg{i+1} == 0)
                            if isfield(option.(field),'choice')
                                match2 = 0;
                                arg2 = varg{i+1};
                                for j = option.(field).choice
                                    if (ischar(j{1}) && strcmpi(arg2,j)) || ...
                                       (not(ischar(j{1})) && isequal(arg2,j{1}))
                                            match2 = 1;
                                            i = i+1;
                                            optionvalue = arg2;
                                    end
                                end
                                if not(match2)
                                    if isfield(option.(field),'keydefault')
                                        optionvalue = option.(field).keydefault;
                                    else
                                        error(['SYNTAX ERROR IN ',func2str(method),...
                                            ': Unexpected keyword after key ',arg'.']);
                                    end
                                end
                            else
                                i = i+1;
                                optionvalue = varg{i};
                            end
                        elseif isfield(option.(field),'keydefault')
                            optionvalue = option.(field).keydefault;
                        elseif isfield(option.(field),'default')
                            optionvalue = option.(field).default;
                        else
                            error(['SYNTAX ERROR IN ',func2str(method),...
                                ': A string should follow the key ',arg'.']);
                        end
                    elseif strcmpi(type,'Boolean')
                        if length(varg) > i && (isnumeric(varg{i+1}) || islogical(varg{i+1}))
                            i = i+1;
                            optionvalue = varg{i};
                        elseif length(varg) > i && ischar(varg{i+1}) ...
                                && (strcmpi(varg{i+1},'on') || ...
                                    strcmpi(varg{i+1},'yes'))
                            i = i+1;
                            optionvalue = 1;
                        elseif length(varg) > i && ischar(varg{i+1}) ...
                                && (strcmpi(varg{i+1},'off') || ...
                                    strcmpi(varg{i+1},'no'))
                            i = i+1;
                            optionvalue = 0;
                        else
                            optionvalue = 1;
                        end
                    elseif strcmpi(type,'Integer') || strcmpi(type,'Integers')
                        if length(varg) > i && isnumeric(varg{i+1})
                            i = i+1;
                            optionvalue = varg{i};
                        elseif isfield(option.(field),'keydefault')
                            if strcmpi(type,'Integers')
                                optionvalue = option.(field).keydefault;
                            else
                                optionvalue = option.(field).keydefault(1);
                            end
                        elseif isfield(option.(field),'default')
                            if strcmpi(type,'Integers')
                                optionvalue = option.(field).default;
                            else
                                optionvalue = option.(field).default(1);
                            end
                        else
                            error(['SYNTAX ERROR IN ',func2str(method),...
                                ': An integer should follow the key ',arg'.']);
                        end
                        if isfield(option.(field),'number')...
                                && option.(field).number == 2
                            if length(varg) > i && isnumeric(varg{i+1})
                                i = i+1;
                                optionvalue = [optionvalue varg{i}];
                            elseif isfield(option.(field),'keydefault')
                                optionvalue = [optionvalue option.(field).keydefault(2)];
                            elseif isfield(option.(field),'default')
                                optionvalue = [optionvalue option.(field).default(2)];
                            else
                                error(['SYNTAX ERROR IN ',func2str(method),...
                                ': Two integers should follow the key ',arg'.']);
                            end
                        end
                        if not(isempty(unit))
                            if (strcmpi(unit{1},'s') || ...
                                strcmpi(unit{2},'s')) && ...
                               (strcmpi(unit{1},'Hz') || ...
                                strcmpi(unit{2},'Hz'))
                                if length(varg) > i && ...
                                   ischar(varg{i+1}) && ...
                                   (strcmpi(varg{i+1},'s') || ...
                                    strcmpi(varg{i+1},'Hz'))
                                    i = i+1;
                                    if not(strcmpi(varg{i},defaultunit))
                                        if isfield(option.(field),'opposite')
                                            field = option.(field).opposite;
                                        end
                                        optionvalue = 1/optionvalue;
                                    end
                                end
                            end
                            if (strcmpi(unit{1},'s') || ...
                                strcmpi(unit{2},'s')) && ...
                               (strcmpi(unit{1},'sp') || ...
                                strcmpi(unit{2},'sp'))
                                if length(varg) > i && ...
                                   ischar(varg{i+1}) && ...
                                   (strcmpi(varg{i+1},'sp') || ...
                                    strcmpi(varg{i+1},'s'))
                                    i = i+1;
                                    if strcmpi(varg{i},'sp')
                                        optionvalue = [optionvalue 0];
                                    else
                                        optionvalue = [optionvalue 1];
                                    end
                                else
                                    optionvalue = [optionvalue 1];
                                end
                            end
                        end
                        if not(isempty(from))
                            if length(varg) > i && ...
                               ischar(varg{i+1}) && ...
                               (strcmpi(varg{i+1},'Start') || ...
                                strcmpi(varg{i+1},'Middle') || ...
                                strcmpi(varg{i+1},'End'))
                                i = i+1;
                                if strcmpi(varg{i},'Start')
                                    optionvalue = [optionvalue 0];
                                elseif strcmpi(varg{i},'Middle')
                                    optionvalue = [optionvalue 1];
                                elseif strcmpi(varg{i},'End')
                                    optionvalue = [optionvalue 2];           
                                end
                            else
                                optionvalue = [optionvalue 0];
                            end
                            if isa(orig,'mirdesign')
                                orig = set(orig,'Size',optionvalue);
                            end
                        end
                    else
                        if length(varg) > i
                            i = i+1;
                            optionvalue = varg{i};
                        elseif isfield(option.(field),'keydefault')
                            optionvalue = option.(field).keydefault(1);
                        else
                            error(['SYNTAX ERROR IN ',func2str(method),...
                                ': Data should follow the key ',arg'.']);
                        end
                    end
                end
            else
                if isfield(option.(field),'choice')
                    for j = option.(field).choice
                        if strcmpi(arg,j)
                            match = 1;
                            optionvalue = arg;
                        end
                    end
                end
            end
            if not(match)
                if isfield(option.(field),'position')
                    if i+1 == option.(field).position
                        match = 1;
                        optionvalue = arg;
                    end
                %else
                %    error(['SYNTAX ERROR IN ',func2str(method),...
                %            ': Badly specified key ',arg'.']);
                end
            end
            if match == 1
                match = 2;
                if isfield(option.(field),'when') ...
                        && (strcmpi(option.(field).when,'After') || ...
                            strcmpi(option.(field).when,'Both'))
                    after.(field) = optionvalue;
                end
                if not(isfield(option.(field),'when')) ...
                        || strcmpi(option.(field).when,'Both')
                    during.(field) = optionvalue;
                end
            end
        end
        if not(match)
            if isnumeric(arg) || islogical(arg)
                arg = num2str(arg);
            end
            error(['SYNTAX ERROR IN ',func2str(method),...
                ': Unknown parameter ',arg'.']);
        end
    end    
    i = i+1;
end