function x = checkForTrivialSolutions(xTest,intcon,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
% Checks 4 trivial cases that may lead to an integer feasible solution.

%   Copyright 2020 The MathWorks, Inc.
x = [];

%all zero integer solution
xTest(intcon) = 0;
if isFeasible(xTest,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
    x = xTest;
    return
end

%all non-zero upper bound integer solution
if ~any(isinf(ub(intcon))) && ~all(ub(intcon) == 0)
    xTest(intcon) = max(floor(ub(intcon)),ceil(lb(intcon)));
    if isFeasible(xTest,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
        x = xTest;
        return
    end
end

%all non-zero lower bound integer solution
if ~any(isinf(lb(intcon))) && ~all(lb(intcon) == 0)
    xTest(intcon) = min(ceil(lb(intcon)),floor(ub(intcon)));
    if isFeasible(xTest,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
        x = xTest;
        return
    end
end

%lock solution: to the bound with the minimum lock. Note that if only
%equalities, all upper/lower bound solution is equivalent to this one.
if ~isempty(A)
    upLocks = sum(A > 0,1) + sum(abs(Aeq) > 0,1);
    downLocks = sum(A < 0,1) + sum(abs(Aeq) > 0,1);
    LessUpLocks = upLocks <= downLocks;
    xTest(intcon) = min(ceil(lb(intcon)),ub(intcon));
    logicalForIntegers = false(size(LessUpLocks));
    logicalForIntegers(intcon) = true;
    integerAndLessUpLocks = LessUpLocks & logicalForIntegers;
    xTest(integerAndLessUpLocks) = max(floor(ub(integerAndLessUpLocks)),ceil(lb(integerAndLessUpLocks)));
    if ~any(isinf(xTest))
        if isFeasible(xTest,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
            x = xTest;
            return
        end
    end
end

function feasible = isFeasible(xTest,A,b,Aeq,beq,lb,ub,ConstraintTolerance)
   feasible = max([0; norm(Aeq*xTest-beq, inf); (lb-xTest); (xTest-ub); (A*xTest-b)]) <= ConstraintTolerance;
