function [alignment, align_length, align_position, n_errors] = align_with_constraints(seq, target, varargin)


    fix_left = false;
    fix_right = false;    
    maximum_errors = 0;
    errors_within_range = [1, length(seq)];
    
    n_varargs = length (varargin);
    expect_arg = false;
    for i = 1:n_varargs
        arg = varargin{i};
        if ~expect_arg && ischar (arg) && arg (1) == '-'
            switch arg
                case '-fix_left_position', 
                    if i + 1 <= n_varargs
                        expect_arg = true;
                        start = varargin{i + 1};
                        fix_left = true;
                        assert(start > 0 && start <= length(seq));
                        
                    else
                        error ('align_with_constraints:noarg', 'Required argument for -fix_left_position missing.');
                    end
                case '-fix_right_position',
                    if i + 1 <= n_varargs
                        expect_arg = true;
                        stop = varargin{i + 1};
                        fix_right = true;
                        assert(stop > 0 && stop <= length(seq));
                    else
                        error ('align_with_constraints:noarg', 'Required argument for -fix_right_position missing.');
                    end
                case '-maximum_errors',
                    if i + 1 <= n_varargs
                        expect_arg = true;
                        maximum_errors = varargin{i + 1};
                    else
                        error ('align_with_constraints:noarg', 'Required argument for -maximum_errors missing.');
                    end
                case '-errors_within_range',
                    if i + 1 <= n_varargs
                        expect_arg = true;
                        errors_within_range = varargin{i + 1};
                    else
                        error ('align_with_constraints:noarg', 'Required argument for -errors_within_range missing.');
                    end
                otherwise, error ('align_with_constraints:unknownarg', 'Unknown argument %q.', arg);
            end
        else
            if ~expect_arg
                error ('align_with_constraints:unexparg', 'Unexpected argument at position %d in varargin.', i);
            end
            expect_arg = false;
        end
    end
    
    
    if fix_left && ~fix_right
        l_seq = length(seq);
        l_target = length(target);
        match_length = zeros(l_target,1);
        n_errors = zeros(l_target,1);
        
        for i=1:l_target
            max_length = min( l_target -i + 1, l_seq - start + 1 );
            c = seq(start: start + max_length -1)==target(i: i + max_length - 1);                        
            error_positions = find(c==0,maximum_errors + 1,'first');
            
            if ~isempty(error_positions)                                
                if length(error_positions)==maximum_errors+1
                    c = c(1:error_positions(end)-1);
                end                
                c = c(1: find(c,1,'last'));
                error_positions = find(c==0);
            end
            
            
            if any(error_positions < errors_within_range(1))
                continue;
            end
            
            x = find(error_positions > errors_within_range(2), 1, 'first');
            if ~isempty(x)                            
                match_length(i) = error_positions(x)-1;
                n_errors(i) = x - 1; % check
            
            else                
                match_length(i) = length(c);
                n_errors(i) = length(error_positions);                
            end
            
        end
        
        [align_length, i] = max(match_length);
        n_errors = n_errors(i);        
        align_position = [start, i];
        align_pipes = repmat('|',1,align_length);
        
        error_positions = seq(start: start + align_length -1)~=target(i: i+ align_length -1);
        align_pipes(error_positions)=' ';
        alignment = [seq(start: start + align_length -1); align_pipes ; target(i: i+ align_length -1)];
        
        
    elseif fix_right && ~fix_left        
        l_target = length(target);
        
        
        match_length = zeros(l_target,1);
        n_errors = zeros(l_target,1);
        
        for i=l_target:-1:1
            max_length = min( i, stop );
            c = seq(stop - max_length + 1 : stop)==target(i - max_length + 1: i);            
            
            error_positions = find(c==0,maximum_errors + 1,'last');                        
            
            if ~isempty(error_positions)                
                
                if length(error_positions)==maximum_errors+1
                    c = c(error_positions(1)+1:end);
                end                
                c = c(find(c,1,'first'):end);
                error_positions = find(c==0);
            end
            
            
            if any(error_positions > errors_within_range(2))
                continue;
            end
            
            x = find(error_positions < errors_within_range(1), 1, 'last');
            if ~isempty(x)                
            
                match_length(i) = stop - error_positions(x);
                n_errors(i) = length(error_positions) - x ; % check
            
            else                
                match_length(i) = length(c);
                n_errors(i) = length(error_positions);                
            end
            
        end
        
        [align_length, i] = max(match_length);
        n_errors = n_errors(i);
        
        align_position = [stop - align_length + 1, i - align_length + 1];
        align_pipes = repmat('|',1,align_length);
        
        error_positions = seq(stop - align_length +1: stop)~=target(i - align_length +1 : i);
        align_pipes(error_positions)=' ';
        alignment = [seq(stop - align_length +1: stop); align_pipes ; target(i - align_length +1: i)];
       
      %  
    end

end