':param project:         the project
:param addr:            the address to start calling at
:param args:            a tuple of arguments. Any members that are None will be replaced with symbolic expressions with a
length of the architecture\'s bitwidth.
:param start:           a path (or set of paths) to start from
:param num_find:        find at least this many returns from the function
:param concrete_only:   Throw an exception if the execution splits into multiple paths'

def __init__(self, project, addr, args=(), start=None, num_find=None, concrete_only=False, **kwargs):

    self._fake_return_addr = project.entry
    self._cc = DEFAULT_CC[project.arch.name](project.arch)
    self._concrete_only = concrete_only
    start_paths = []
    if (start is None):
        start_paths.append(project.factory.path(project.factory.blank_state(addr=addr)))
    elif isinstance(start, (tuple, list, set)):
        start_paths.extend(start)
    else:
        start_paths.append(start)
    self.symbolic_args = [(start_paths[0].state.se.Unconstrained(('arg%d' % i), project.arch.bits) if (arg is None) else arg) for (i, arg) in enumerate(args)]
    self._ret_addr = start_paths[0].state.se.BVV(self._fake_return_addr, project.arch.bits)
    for p in start_paths:
        p.state.ip = addr
        self._cc.setup_callsite(p.state, self._ret_addr, self.symbolic_args)
    super(Caller, self).__init__(project, find=self._fake_return_addr, start=start_paths, num_find=num_find, **kwargs)
