function Classifier_BdryGrowth( cFcn, cPoints, cTrainlabels, cExtraParam);

%
% function Classifier_BdryGrowth( cFcn, cPoints, cTrainlabels, cExtraParam);
%
% IN:
%   gClassifierObj  : global struct containing the state of the object.
%                     Struct containing at least:
%                     L : current labels for the points
%                     Stop : boolean flag, set to true when the classifier is happy with the classification
%   gDiffuseObj     : see Diffuser_Template. 
%   cFcn : string specifying the action to be taken. Should support at least:
%          'create'     : creates and initializes gClassifierObj
%          'classify'   : classifies the points according to the given parameters
%   cExtraParam     : when cFcn=='create', this structure should contain
%                           GrowthFcn   : pointer to function to compute boundary growth
%                           Delta       : radius of neighbors where to check growth
%                           Epsilon     : threshold for acceptable local growth
%                           Diffuser    : a diffuser according to Diffuser_Template. On top of that Diffuser should be able the following action(s):
%                                         'plug' : accepts a list of indices of heated points from which there should be no diffusion any more
% OUT:
%   gClassifierObj  : updated global struct with the state of classifier. Contains:
%                     BdryIdxs : indices of the boundary points
%                     Growth   : growth at each boundary point
%   gDiffuseObj     : possibly updated gDiffuseObj
%
% USES:
%   nada
%
% SOURCE CONTROL
%   MM, 3/1/04
%

global gClassifierObj;
global gDiffuseObj;

if strcmpi(cFcn,'create')==1
    gClassifierObj = [];
    
    gClassifierObj.BdryIdxs = [];
    gClassifierObj.GrowthRate = 0;
    gClassifierObj.Growth = 0;
    gClassifierObj.GrowthFcn = cExtraParam.GrowthFcn;
    gClassifierObj.Delta = cExtraParam.Delta;
    gClassifierObj.Epsilon = cExtraParam.Epsilon;
    gClassifierObj.pNorm = cExtraParam.pNorm;
    gClassifierObj.Stop = false;
    gClassifierObj.Heat = gDiffuseObj.Heat;
    gClassifierObj.OldHeat = [];    
    
elseif strcmpi(cFcn,'classify')==1
    
    lExtraParam.pNorm = gClassifierObj.pNorm;
    lExtraParam.Delta = gClassifierObj.Delta;
    lExtraParam.Epsilon = gClassifierObj.Epsilon;
    lExtraParam.Atria = gDiffuseObj.Atria;
    lExtraParam.A = gDiffuseObj.A;
    lExtraParam.OldOldP = gClassifierObj.OldHeat;
    % Evaluate growth along the boundary of diffusion
    [gClassifierObj.BdryIdxs lNewGrowth lNextBdry] = feval( gClassifierObj.GrowthFcn, cPoints, gDiffuseObj.Heat, gClassifierObj.Heat, lExtraParam );
    gClassifierObj.OldHeat = gClassifierObj.Heat;
    gClassifierObj.Heat = gDiffuseObj.Heat;
    gClassifierObj.Growth = lNewGrowth;    
    % Find the points with growth below threshold
     if length(diff(sort(gClassifierObj.Growth)))>0,
         figure(5);hold off;plot((sort(gClassifierObj.Growth))); %plot(diff(sort(gClassifierObj.Growth))); 
     end;
     %lPlugIdxs = find( gClassifierObj.Growth < median(gClassifierObj.Growth)/3 );
     lPlugIdxs = find( gClassifierObj.Growth < 0.1 );
%     lPlugIdxs = [];
     %lPlugIdxs = 1:floor(length(gClassifierObj.Growth)/5);
%     lPlugIdxs = find( max(diff(sort(gClassifierObj.Growth)))/mean(diff(sort(gClassifierObj.Growth))) > 2 )+1;     
     length(lPlugIdxs)
     if length(lPlugIdxs)>0
         feval( cExtraParam.Diffuser,'plug',cPoints,gClassifierObj.BdryIdxs(lPlugIdxs) );
     end;
         
end;

return;