How do we handle cython:
    1. when on git, require cython during setup time (do not distribute
    generated .c files via git)
     a) cython present -> fine
     b) no cython present -> install it on the fly. Extensions have to have .pyx suffix
    This is solved via a lazy evaluation of the extension list. This is needed,
    because build_ext is being called before cython will be available.
    https://bitbucket.org/pypa/setuptools/issue/288/cannot-specify-cython-under-setup_requires

    2. src dist install (have pre-converted c files and pyx files)
     a) cython present -> fine
     b) no cython -> use .c files

def extensions():
    """How do we handle cython:
    1. when on git, require cython during setup time (do not distribute
    generated .c files via git)
     a) cython present -> fine
     b) no cython present -> install it on the fly. Extensions have to have .pyx suffix
    This is solved via a lazy evaluation of the extension list. This is needed,
    because build_ext is being called before cython will be available.
    https://bitbucket.org/pypa/setuptools/issue/288/cannot-specify-cython-under-setup_requires

    2. src dist install (have pre-converted c files and pyx files)
     a) cython present -> fine
     b) no cython -> use .c files
    """
    USE_CYTHON = False
    try:
        from Cython.Build import cythonize
        USE_CYTHON = True
    except ImportError:
        warnings.warn('Cython not found. Using pre cythonized files.')

    from numpy import get_include as _np_inc
    np_inc = _np_inc()

    exts = []

    mle_trev_given_pi_dense_module = \
        Extension('msmtools.estimation.dense.mle_trev_given_pi',
                  sources=['msmtools/estimation/dense/mle_trev_given_pi.pyx',
                           'msmtools/estimation/dense/_mle_trev_given_pi.c'],
                  depends=['msmtools/util/sigint_handler.h'],
                  include_dirs=['msmtools/estimation/dense', np_inc])

    mle_trev_given_pi_sparse_module = \
        Extension('msmtools.estimation.sparse.mle_trev_given_pi',
                  sources=['msmtools/estimation/sparse/mle_trev_given_pi.pyx',
                           'msmtools/estimation/sparse/_mle_trev_given_pi.c'],
                  depends=['msmtools/util/sigint_handler.h'],
                  include_dirs=['msmtools/estimation/dense', np_inc])

    mle_trev_dense_module = \
        Extension('msmtools.estimation.dense.mle_trev',
                  sources=['msmtools/estimation/dense/mle_trev.pyx',
                           'msmtools/estimation/dense/_mle_trev.c'],
                  depends=['msmtools/util/sigint_handler.h'],
                  include_dirs=[np_inc])

    mle_trev_sparse_module = \
        Extension('msmtools.estimation.sparse.mle_trev',
                  sources=['msmtools/estimation/sparse/mle_trev.pyx',
                           'msmtools/estimation/sparse/_mle_trev.c'],
                  depends=['msmtools/util/sigint_handler.h'],
                  include_dirs=[np_inc,
                                ])
    rnglib_src = ['msmtools/estimation/dense/rnglib/rnglib.c',
                  'msmtools/estimation/dense/rnglib/ranlib.c']

    mle_trev_sparse_newton_module = \
        Extension('msmtools.estimation.sparse.newton.objective_sparse',
                  sources=['msmtools/estimation/sparse/newton/objective_sparse.pyx'],
                  libraries=['m'] if sys.platform != 'win32' else [],
                  include_dirs=[np_inc,
                                ]
                  )

    sampler_rev = \
        Extension('msmtools.estimation.dense.sampler_rev',
                  sources=['msmtools/estimation/dense/sampler_rev.pyx',
                           'msmtools/estimation/dense/sample_rev.c',
                           ] + rnglib_src,
                  include_dirs=[np_inc,
                                ])

    sampler_revpi = \
        Extension('msmtools.estimation.dense.sampler_revpi',
                  sources=['msmtools/estimation/dense/sampler_revpi.pyx',
                           'msmtools/estimation/dense/sample_revpi.c',
                          ] + rnglib_src,
                  include_dirs=[np_inc,
                                ])

    kahandot_module = \
        Extension('msmtools.util.kahandot',
                  sources = ['msmtools/util/kahandot_src/kahandot.pyx',
                             'msmtools/util/kahandot_src/_kahandot.c'],
                  depends = ['msmtools/util/kahandot_src/_kahandot.h'],
                  include_dirs=[np_inc,
                                ])

    exts += [mle_trev_given_pi_dense_module,
             mle_trev_given_pi_sparse_module,
             mle_trev_dense_module,
             mle_trev_sparse_module,
             mle_trev_sparse_newton_module,
             sampler_rev,
             sampler_revpi,
             kahandot_module
            ]

    if USE_CYTHON: # if we have cython available now, cythonize module
        exts = cythonize(exts)
    else:
        # replace pyx files by their pre generated c code.
        for e in exts:
            new_src = []
            for s in e.sources:
                new_src.append(s.replace('.pyx', '.c'))
            e.sources = new_src

    return exts