public Release calculateDelta(File aTopTempDir, File aTempXmlDir,
            File aTempMD5Dir) throws Exception
    {
        int nbDeleted = 0;
        int nbCreated = 0;
        int nbModified = 0;
        
        // create a temp release
        File releaseTempDir = FileSystem.createTempDirectory("release-",
                aTopTempDir);

        Release tempRelease = Release.createRelease(releaseTempDir);

        Release latestRelease = m_ReleaseDB.getLatestRelease();

        // copy the SOURCE Part of Release
        tempRelease.addInSrcMD5s(aTempMD5Dir);
        tempRelease.addInSrcXmls(aTempXmlDir);

        // No previous Release so all origin XML files go into Delta Result and
        // there are no deleted files
        if (latestRelease == null)
        {
            // Copy XML into Delta/Result
            tempRelease.addInDeltaResult(aTempXmlDir);

            for (String filename : tempRelease.getDeltaXmlFilenames())
            {
                this.cleverPrinting(Release.getIDFromReleaseFile(filename)
                        + " metadata is new.", nbCreated);

                nbCreated++;
            }
        }
        else
        {
            // get list of previous MD5s and the list of current MD5s
            HashMap<String, Pair<String, String>> prev = latestRelease
                    .getSrcMD5s();
            HashMap<String, Pair<String, String>> curr = tempRelease
                    .getSrcMD5s();

            Set<String> currSet = new HashSet<String>();
            Set<String> deletedSet = new HashSet<String>();
            Set<String> newSet = new HashSet<String>();
            

            /*
             * calculate the delta It is important to understand that the UID is
             * the MD_Metadata.fileidentifier and not the filename. Several
             * modifications of the same metadata in the Release are not handled
             * properly here (this should not happen but). algorithm: for
             * elemOld in old: if elemOld not in new: add in deletedSet if
             * elemOld in new and elemOld.md5 != elemNew.md5: add in newSet
             * 
             * remove elemOld from currSet
             * 
             * All elem left in currSet are the new ones and must be added in
             * newSet newSet.add(currSet);
             */

            // copy curr keys in currSet
            currSet.addAll(curr.keySet());

            for (String key : prev.keySet())
            {
                if (!curr.containsKey(key))
                {
                    deletedSet.add(key);
                }
                else
                {
                    if (!prev.get(key).equals(curr.get(key)))
                    {
                        // md5 different so the file has been updated
                        logger.debug(
                                "MD5 Differents for {}. old:[{}], new:[{}]",
                                new String[] { key, prev.get(key).getKey(),
                                        curr.get(key).getKey() });

                        this.cleverPrinting(key
                                + " metadata has been modified.", nbModified);

                        nbModified++;

                        // add in newSet because it has been modified
                        newSet.add(key);

                    }

                    // remove from currSet in any case
                    currSet.remove(key);
                }
            }

            // elems left in currSet are new and need to be added to newSet
            newSet.addAll(currSet);

            // print elems left in currSet which are the new ones
            for (String name : currSet)
            {
                this.cleverPrinting(name + " metadata is new.", nbCreated);

                nbCreated++;
            }

            String basename;
            // copy newSet in Delta/Files
            for (String name : newSet)
            {
                // add files in Results and their MD5s in MD5

                // get the basename from curr HashMap
                basename = curr.get(name).getValue();

                tempRelease.addFileInDeltaResult(new File(aTempXmlDir
                        + File.separator + basename + ".xml"));
            }

            // add files in deleted
            for (String name : deletedSet)
            {
                this.cleverPrinting(name + " metadata has been deleted.",
                        nbDeleted);
                nbDeleted++;
                tempRelease.flagAsDeleted(name);
            }
        }
        
        if (nbCreated + nbModified + nbDeleted != 0)
        {
            logger
                    .info("Delta Summary: " + nbCreated + " new - "
                            + nbModified + " modified - " + nbDeleted
                            + " deleted.");
        }

        return tempRelease;
    }