function [flag,wo,W,Tr,no,unFeasible] = nlp_nm_internal(NLP,n,m,nh,fig,wo,M,wlb,wub,W,Tr,k,no,epsR,epsI,epsC,epsZ)

%   * * * Solution of the k-th NLP * * *


flag = 0;
unFeasible = 0;

nm = n+m;
zu = wo(nm+2);

if (k>0)
   w = W(k,:);
   nfx = Tr(k,4);
else
   w = wo;
   nfx = 0;
end

op = foptions;
op(1) = 0;     % 1 - display some results for constr; 0 - nothing
op(2) = epsR;
op(3) = epsZ;
op(4) = epsC;
op(13) = nh;
op(14) = n*100;  % max function evaluation

x0 = w(1:n);
y = w(n+1:n+m);

if nfx
   fx = n+Tr(k,5:4+nfx);                     % yj fixed in w
   vr = [1:n,n+Tr(k,5+nfx:4+m),nm+1,nm+2];   % w - yj fixed
   wp = w(vr(1:end-2));
   wlbp = wlb(vr(1:end-2));
   wubp = wub(vr(1:end-2));
   index = n+1:nm;
   index(fx-n) = [];
   nodes = num2str(round(y)');
   nodes(index-n) = '*';
   disp(['MINLPN message: sounding nodes ' nodes' '.']);
   [wp,ot,nS] = complexb('fun_nm',wp,0,wlbp,wubp,-1,op(3),op(14),[],[],NLP,y,n,nh,M,fx);
   op(10)=round(nS/n);
else
   nodes(1:m) = '*'; nodes = nodes';
   disp(['MINLPN message: sounding nodes ' nodes' '.']);
   [wp,ot,nS] = complexb('fun_nm',[x0, y],0,wlb,wub,-1,op(3),op(14),[],[],NLP,y,n,nh,M); 
   op(10)=round(nS/n);
end

x0 = wp(1:n);
if nfx
   w([1:n index]) = wp;
   y = w(n+1:nm);
else
   y = wp(n+1:n+m);
end


% getting the values of f and g
[f,g] = eval([NLP '(x0,y)']);

%adicionando as restrições dos limites das variáveis para o teste de viabilidade:
g = [g wlb-[x0 y] [x0 y]-wub];
% (u > epsC) means constraint violation
% fazendo u = max(u,ue), então u > epsC significa violação de restrição]
u = max([ abs(g(1:nh)) g(nh+1:end) ]);

if(u>epsC) | op(10)>=150 % se é inviável o nó ele e todos seus filhos são deletados
   flag = 1;
   disp(['MINLPN Message: Deleting infeasible nodes ' nodes' '.']);
   if k>0
      W = W([1:k-1, k+1:no],:);
      Tr = Tr([1:k-1, k+1:no],:);  % delete all P(i,k) such that z(i,k) >= zu
      no = no - 1;
   end
   unFeasible = 1;
   return;
end % eliminando se é inviável

if k>0
   w(nm+1:nm+2) = [u, f];
   W(k,:) = w;
else
   wo = [wp, u, f];
end


if f+epsZ > zu           % deleting k-th node of the tree
   %disp(['MINLPN Message: inferior limit (' num2str(znl) ') greater than current superior one (' num2str(zu) '), deleting node ' num2str(y) '.']);
   flag = 1;
   W = W([1:k-1, k+1:no],:);
   Tr = Tr([1:k-1, k+1:no],:);  % delete all P(i,k) such that z(i,k) >= zu
   no = no - 1;
   return;
end

if(~k>0) % se é o problema inicial já pode retornar
   return;
end

[dym,j] = max(abs(y-round(y)));

if dym < epsI % integer solution of last NLP
   
   flag = 0;
   
   % Novo NLP para refinar a solução com y "exatamente" inteiro
   y = round(y);
   x0 = complexb('fun_nm',x0,0,wlb(1:m),wub(1:m),-1,op(3),op(14),[],[],NLP,y,n,nh,M,fx);
   
   f = eval([NLP '(x0,y)']);
   
   Tr(no,3) = 0;
   
   if f < zu
      zu = f;
      wo = [x0,y,u,zu];
   end
     
   if no > 0
      xx = W(no,nm+2);
   else
      xx = -inf;
   end
   while no > 0 & xx >= zu
      no = no - 1;
      W = W(1:no,:);
      Tr = Tr(1:no,:);  % delete all P(i,k) such that z(i,k) >= zu
      if no > 0, xx = W(no,nm+2); end
   end
else % caso de solução não inteira e viável
   flag = 1;       % non-integer solution
   Tr(k,3) = j;    % less integer yj
end
