def _fit_newton(self, fitcache=None, ebin=None, **kwargs):
        """Fast fitting method using newton fitter."""

        tol = kwargs.get('tol', self.config['optimizer']['tol'])
        max_iter = kwargs.get('max_iter',
                              self.config['optimizer']['max_iter'])
        init_lambda = kwargs.get('init_lambda',
                                 self.config['optimizer']['init_lambda'])
        use_reduced = kwargs.get('use_reduced', True)

        free_params = self.get_params(True)
        free_norm_params = [p for p in free_params if p['is_norm'] is True]

        if len(free_params) != len(free_norm_params):
            msg = 'Executing Newton fitter with one ' + \
                'or more free shape parameters.'
            self.logger.error(msg)
            raise Exception(msg)

        verbosity = kwargs.get('verbosity', 0)
        if fitcache is None:
            fitcache = self._create_fitcache(**kwargs)

        fitcache.update(self.get_params(),
                        tol, max_iter, init_lambda, use_reduced)

        logemin = self.loge_bounds[0]
        logemax = self.loge_bounds[1]
        imin = int(utils.val_to_edge(self.log_energies, logemin)[0])
        imax = int(utils.val_to_edge(self.log_energies, logemax)[0])

        if ebin is not None:
            fitcache.fitcache.setEnergyBin(ebin)
        elif imin == 0 and imax == self.enumbins:
            fitcache.fitcache.setEnergyBin(-1)
        else:
            fitcache.fitcache.setEnergyBins(imin, imax)

        num_free = len(free_norm_params)

        o = {'fit_status': 0,
             'fit_quality': 3,
             'fit_success': True,
             'edm': 0,
             'loglike': None,
             'values': np.ones(num_free) * np.nan,
             'errors': np.ones(num_free) * np.nan,
             'indices': np.zeros(num_free, dtype=int),
             'is_norm': np.empty(num_free, dtype=bool),
             'src_names': num_free * [None],
             'par_names': num_free * [None],
             }

        if num_free == 0:
            return o

        ref_vals = np.array(fitcache.fitcache.refValues())
        free = np.array(fitcache.fitcache.currentFree())
        norm_vals = ref_vals[free]

        norm_idxs = []
        for i, p in enumerate(free_norm_params):

            norm_idxs += [p['idx']]
            o['indices'][i] = p['idx']
            o['src_names'][i] = p['src_name']
            o['par_names'][i] = p['par_name']
            o['is_norm'][i] = p['is_norm']

        o['fit_status'] = fitcache.fit(verbose=verbosity)
        o['edm'] = fitcache.fitcache.currentEDM()

        pars, errs, cov = fitcache.get_pars()
        pars *= norm_vals
        errs *= norm_vals
        cov = cov * np.outer(norm_vals, norm_vals)

        o['values'] = pars
        o['errors'] = errs
        o['covariance'] = cov
        errinv = np.zeros_like(o['errors'])
        m = o['errors'] > 0
        errinv[m] = 1. / o['errors'][m]
        o['correlation'] = o['covariance'] * np.outer(errinv, errinv)

        if o['fit_status'] in [-2, 0]:
            for idx, val, err in zip(norm_idxs, pars, errs):
                self._set_value_bounded(idx, val)
                self.like[idx].setError(err)
            self.like.syncSrcParams()
            o['fit_success'] = True
        else:
            o['fit_success'] = False

        if o['fit_status']:
            self.logger.error('Error in NEWTON fit. Fit Status: %i',
                              o['fit_status'])

        # FIXME: Figure out why currentLogLike gets out of sync
        #loglike = fitcache.fitcache.currentLogLike()
        #prior_vals, prior_errs, has_prior = gtutils.get_priors(self.like)
        #loglike -= np.sum(has_prior) * np.log(np.sqrt(2 * np.pi))
        loglike = -self.like()
        o['loglike'] = loglike

        return o