static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<FunctionDeclDefLink> link, CppTools::CppRefactoringChanges changes)
{
    QSharedPointer<FunctionDeclDefLink> noResult;
    const Snapshot &snapshot = changes.snapshot();

    // find the matching decl/def symbol
    Symbol *target = 0;
    CppTools::SymbolFinder finder;
    if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) {
        QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
        finder.findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot),
                                       funcDef->symbol,
                                       &typeMatch, &argumentCountMatch, &nameMatch);
        if (!typeMatch.isEmpty())
            target = typeMatch.first();
    } else if (link->sourceDeclaration->asSimpleDeclaration()) {
        target = finder.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, snapshot, true);
    }
    if (!target) {
        return noResult;
    }

    // parse the target file to get the linked decl/def
    const QString targetFileName = QString::fromUtf8(
                target->fileName(), target->fileNameLength());
    CppTools::CppRefactoringFileConstPtr targetFile = changes.fileNoEditor(targetFileName);
    if (!targetFile->isValid())
        return noResult;

    DeclarationAST *targetParent = 0;
    FunctionDeclaratorAST *targetFuncDecl = 0;
    DeclaratorAST *targetDeclarator = 0;
    if (!findDeclOrDef(targetFile->cppDocument(), target->line(), target->column(),
                       &targetParent, &targetDeclarator, &targetFuncDecl))
        return noResult;

    // the parens are necessary for finding good places for changes
    if (!targetFuncDecl->lparen_token || !targetFuncDecl->rparen_token)
        return noResult;
    QTC_ASSERT(targetFuncDecl->symbol, return noResult);
    // if the source and target argument counts differ, something is wrong
    QTC_ASSERT(targetFuncDecl->symbol->argumentCount() == link->sourceFunction->argumentCount(), return noResult);

    int targetStart, targetEnd;
    declDefLinkStartEnd(targetFile, targetParent, targetFuncDecl, &targetStart, &targetEnd);
    QString targetInitial = targetFile->textOf(
                targetFile->startOf(targetParent),
                targetEnd);

    targetFile->lineAndColumn(targetStart, &link->targetLine, &link->targetColumn);
    link->targetInitial = targetInitial;

    link->targetFile = targetFile;
    link->targetFunction = targetFuncDecl->symbol;
    link->targetFunctionDeclarator = targetFuncDecl;
    link->targetDeclaration = targetParent;

    return link;
}
// TODO: remove me, this is taken from cppeditor.cpp. Find some common place for this function
static Document::Ptr findDefinition(Function *functionDeclaration, int *line)
{
    CppTools::CppModelManager *cppModelManager = CppTools::CppModelManager::instance();
    const Snapshot snapshot = cppModelManager->snapshot();
    CppTools::SymbolFinder symbolFinder;
    if (Function *fun = symbolFinder.findMatchingDefinition(functionDeclaration, snapshot)) {
        if (line)
            *line = fun->line();

        return snapshot.document(QString::fromUtf8(fun->fileName(), fun->fileNameLength()));
    }

    return Document::Ptr();
}