     }
 
     private init() {
+        parallelExecution = ParallelExecution()
     }
 
     /// Add a feature vector to the index matrix

            threadCount = osThreadCount > 1 ? osThreadCount : 4

            operationQueue.maxConcurrentOperationCount = threadCount
        }
    }


        var matchesBetterThan: [SearchResult] = Array()
        let queryWordCount = query.features.count

        if arrayRanges == nil {
            arrayRanges = try? ArrayRanges(arrayCount: featureVectors.count, sliceCount: parallelExecution.threadCount)
        }

        for i in 0..<parallelExecution.threadCount {

            let arraySlice = featureVectors[arrayRanges!.ranges[i]] // TODO: Does this copy the array contents?

            let operation = BlockOperation { [weak self] in
                for featureVector in arraySlice {
                    let intersectionCount = query.features.intersection(featureVector.features).count

                    let score: Float32 = Float32(intersectionCount)/Float32(queryWordCount)

                    if score >= betterThan {
                        self?.parallelExecution.resultSynchronizationQueue.sync {
                            matchesBetterThan.append(SearchResult(matchingFeatureVector: featureVector, score: score))
                        }
                    }
                }
            }
