%% Outline:


function [r_obj, z0, lowerZ, zUpperPre] = calcGmm6970(params, data, wMat, opt)
    
    % pull out parameters
    el = params(1);
    phi = params(2);

    % Calculate zLower
    z0 = data.zStar+phi./(data.taxPre.t1-data.taxPre.t0 +0.00001); % initial guess, deal with 0 denominator
    lowerZ =fsolve(@(zOld) uOpt(zOld,el,data.taxPre) ...
        - uFric(zOld,el,data.taxPre) - phi, z0, opt);
    
    % Calculate zUpperPre, zUpperPost
    zUpperPre = data.zStar.*( (1-data.t0) ./ (1-data.t1) ).^el;    
    z0 = zUpperPre(data.pre==1); 
    [zUpperPost,~,flag] = fsolve(@(zOld) uOpt(zOld,el,data.taxPost) ...
        - uAK(zOld, el, data.taxPost) - phi, z0, opt);
    if ~(flag==1)
        z0 = 1/2 * (lowerZ + zUpperPre(data.pre==1) );
        [zUpperPost,~,flag] = fsolve(@(zOld) uOpt(zOld,el,data.taxPost) ...
            - uAK(zOld, el, data.taxPost) - phi, z0, opt);   
    end
    if ~(flag ==1)
        r_obj = 1e8;
        return; 
    end
    
    % Can't have more bunching post than pre
    tt = zUpperPre(data.pre);
    zUpperPost = min(zUpperPost, tt(end));
    
    % Get sizes right for combine pre/psot 
    zUpperPost = [zUpperPost ; repmat(zUpperPost(end),sum(data.pre==0),1)];
    
    % Calculate bunching amount
    zUpper = zUpperPre.*(data.pre) + zUpperPost.*(1-data.pre);
    bSim = calcBFromZ(lowerZ,zUpper, data);
 
    % Return GMM objective function
    r_obj = (bSim - data.bunch)'*wMat*(bSim-data.bunch);
    
end