class Recognito {

    public List<MatchResult<K>> identify(double[] voiceSample) {
        
        if(store.isEmpty()) {
            throw new IllegalStateException("There is no voice print enrolled in the system yet");
        }

        VoicePrint voicePrint = new VoicePrint(extractFeatures(voiceSample, sampleRate));
        
        DistanceCalculator calculator = new EuclideanDistanceCalculator();
        List<MatchResult<K>> matches = new ArrayList<MatchResult<K>>(store.size());

        double distanceFromUniversalModel = voicePrint.getDistance(calculator, universalModel);
        for (Entry<K, VoicePrint> entry : store.entrySet()) {
            double distance = entry.getValue().getDistance(calculator, voicePrint);
            // likelihood : how close is the given voice sample to the current VoicePrint 
            // compared to the total distance between the current VoicePrint and the universal model 
            int likelihood = 100 - (int) (distance / (distance + distanceFromUniversalModel) * 100);
            matches.add(new MatchResult<K>(entry.getKey(), likelihood, distance));
        }

        Collections.sort(matches, new Comparator<MatchResult<K>>() {
            @Override
            public int compare(MatchResult<K> m1, MatchResult<K> m2) {
                return Double.compare(m1.getDistance(), m2.getDistance());
            }
        });
        
        return matches;
    }

    public  Recognito(float sampleRate);
    public  Recognito(float sampleRate, Map<K, VoicePrint> voicePrintsByUserKey);

}