class SubstructureFingerprinter extends AbstractFingerprinter implements IFingerprinter {

    @Override
    public ICountFingerprint getCountFingerprint(IAtomContainer atomContainer) throws CDKException {
        if (keys.isEmpty()) {
            throw new CDKException("No substructures were defined");
        }

        // init SMARTS invariants (connectivity, degree, etc)
        SmartsPattern.prepare(atomContainer);

        final Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
        for (int i = 0; i < keys.size(); i++) {
            Pattern ptrn = keys.get(i).pattern;
            map.put(i,
                    ptrn.matchAll(atomContainer)
                        .countUnique());
        }

        final int length = keys.size();
        final int size = map.size();
        final int[] hash = new int[size], count = new int[size];
        int n = 0;
        for (int h : map.keySet()) {
            hash[n] = h;
            count[n++] = map.get(h);
        }

        return new ICountFingerprint() {

            @Override
            public long size() { return length; }

            @Override
            public int numOfPopulatedbins() { return size; }

            @Override
            public int getCount(int index) { return count[index]; }

            @Override
            public int getHash(int index) { return hash[index]; }

            @Override
            public void merge(ICountFingerprint fp) {}

            @Override
            public void setBehaveAsBitFingerprint(boolean behaveAsBitFingerprint) {}

            @Override
            public boolean hasHash(int hash) { return map.containsKey(hash); }

            @Override
            public int getCountForHash(int hash) { return map.get(hash); }
        };
    }

    public  SubstructureFingerprinter(String[] smarts);
    public  SubstructureFingerprinter();

}