'Evaluates limit'

def doit(self, **hints):

    from sympy.series.limitseq import limit_seq
    from sympy.functions import RisingFactorial
    (e, z, z0, dir) = self.args
    if hints.get('deep', True):
        e = e.doit(**hints)
        z = z.doit(**hints)
        z0 = z0.doit(**hints)
    if (e == z):
        return z0
    if (not e.has(z)):
        return e
    if z0.is_positive:
        e = e.rewrite([factorial, RisingFactorial], gamma)
    if e.is_Mul:
        if (abs(z0) is S.Infinity):
            e = factor_terms(e)
            e = e.rewrite(fibonacci, GoldenRatio)
            ok = (lambda w: ((z in w.free_symbols) and any(((a.is_polynomial(z) or any((((z in m.free_symbols) and m.is_polynomial(z)) for m in Mul.make_args(a)))) for a in Add.make_args(w)))))
            if all((ok(w) for w in e.as_numer_denom())):
                u = Dummy(positive=True)
                if (z0 is S.NegativeInfinity):
                    inve = e.subs(z, ((-1) / u))
                else:
                    inve = e.subs(z, (1 / u))
                r = limit(inve.as_leading_term(u), u, S.Zero, '+')
                if isinstance(r, Limit):
                    return self
                else:
                    return r
    if e.is_Order:
        return Order(limit(e.expr, z, z0), *e.args[1:])
    try:
        r = gruntz(e, z, z0, dir)
        if (r is S.NaN):
            raise PoleError()
    except (PoleError, ValueError):
        r = heuristics(e, z, z0, dir)
        if (r is None):
            return self
    except NotImplementedError:
        if (hints.get('sequence', True) and (z0 is S.Infinity)):
            trials = hints.get('trials', 5)
            r = limit_seq(e, z, trials)
            if (r is None):
                raise NotImplementedError()
        else:
            raise NotImplementedError()
    return r
