// Path: src/main/java/org/madlonkay/supertmxmerge/data/DiffAnalysis.java
// public class DiffAnalysis<T> {
//     public final Set<T> deleted;
//     public final Set<T> added;
//     public final Set<T> modified;
//     
//     public DiffAnalysis(Set<T> deleted, Set<T> added, Set<T> modified) {
//         this.deleted = Collections.unmodifiableSet(deleted);
//         this.added = Collections.unmodifiableSet(added);
//         this.modified = Collections.unmodifiableSet(modified);
//     }
// }
// 
// Path: src/main/java/org/madlonkay/supertmxmerge/data/MergeAnalysis.java
// public class MergeAnalysis<K,V> {
//     public final Set<K> deleted;
//     public final Set<K> added;
//     public final Map<K, V> modified;
//     public final Set<K> conflicts;
//     
//     public static MergeAnalysis unmodifiableAnalysis(MergeAnalysis analysis) {
//         return new MergeAnalysis(Collections.unmodifiableSet(analysis.deleted),
//                 Collections.unmodifiableSet(analysis.added),
//                 Collections.unmodifiableMap(analysis.modified),
//                 Collections.unmodifiableSet(analysis.conflicts));
//     }
//     
//     public MergeAnalysis(Set<K> deleted, Set<K> added, Map<K,V> modified, Set<K> conflicts) {
//         this.deleted = deleted;
//         this.added = added;
//         this.modified = modified;
//         this.conflicts = conflicts;
//     }
//     
//     public boolean hasConflicts() {
//         return !conflicts.isEmpty();
//     }
// }


import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.madlonkay.supertmxmerge.data.DiffAnalysis;
import org.madlonkay.supertmxmerge.data.MergeAnalysis;
/*
 * Copyright (C) 2013 Aaron Madlon-Kay <aaron@madlon-kay.com>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package org.madlonkay.supertmxmerge.util;


/**
 *
 * @author Aaron Madlon-Kay <aaron@madlon-kay.com>
 */
public class DiffUtil {
    
    public static <K,V> DiffAnalysis mapDiff(Map<K,V> before, Map<K,V> after) {
        // Deleted items
        Set<K> deleted = new HashSet<K>(before.keySet());
        deleted.removeAll(after.keySet());
        
        // Added items
        Set<K> added = new HashSet<K>(after.keySet());
        added.removeAll(before.keySet());
        
        // Modified items
        Set<K> modified = new HashSet<K>();
        for (Map.Entry<K,V> e : before.entrySet()) {
            V newItem = after.get(e.getKey());
            if (newItem == null) {
                continue;
            }
            if (!e.getValue().equals(newItem)) {
                modified.add(e.getKey());
            }
        }
        return new DiffAnalysis<K>(deleted, added, modified);
    }
    
// Path: src/main/java/org/madlonkay/supertmxmerge/data/DiffAnalysis.java
// public class DiffAnalysis<T> {
//     public final Set<T> deleted;
//     public final Set<T> added;
//     public final Set<T> modified;
//     
//     public DiffAnalysis(Set<T> deleted, Set<T> added, Set<T> modified) {
//         this.deleted = Collections.unmodifiableSet(deleted);
//         this.added = Collections.unmodifiableSet(added);
//         this.modified = Collections.unmodifiableSet(modified);
//     }
// }
// 
// Path: src/main/java/org/madlonkay/supertmxmerge/data/MergeAnalysis.java
// public class MergeAnalysis<K,V> {
//     public final Set<K> deleted;
//     public final Set<K> added;
//     public final Map<K, V> modified;
//     public final Set<K> conflicts;
//     
//     public static MergeAnalysis unmodifiableAnalysis(MergeAnalysis analysis) {
//         return new MergeAnalysis(Collections.unmodifiableSet(analysis.deleted),
//                 Collections.unmodifiableSet(analysis.added),
//                 Collections.unmodifiableMap(analysis.modified),
//                 Collections.unmodifiableSet(analysis.conflicts));
//     }
//     
//     public MergeAnalysis(Set<K> deleted, Set<K> added, Map<K,V> modified, Set<K> conflicts) {
//         this.deleted = deleted;
//         this.added = added;
//         this.modified = modified;
//         this.conflicts = conflicts;
//     }
//     
//     public boolean hasConflicts() {
//         return !conflicts.isEmpty();
//     }
// }


// Path: src/main/java/org/madlonkay/supertmxmerge/util/DiffUtil.java
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.madlonkay.supertmxmerge.data.DiffAnalysis;
import org.madlonkay.supertmxmerge.data.MergeAnalysis;

/*
 * Copyright (C) 2013 Aaron Madlon-Kay <aaron@madlon-kay.com>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package org.madlonkay.supertmxmerge.util;


/**
 *
 * @author Aaron Madlon-Kay <aaron@madlon-kay.com>
 */
public class DiffUtil {
    
    public static <K,V> DiffAnalysis mapDiff(Map<K,V> before, Map<K,V> after) {
        // Deleted items
        Set<K> deleted = new HashSet<K>(before.keySet());
        deleted.removeAll(after.keySet());
        
        // Added items
        Set<K> added = new HashSet<K>(after.keySet());
        added.removeAll(before.keySet());
        
        // Modified items
        Set<K> modified = new HashSet<K>();
        for (Map.Entry<K,V> e : before.entrySet()) {
            V newItem = after.get(e.getKey());
            if (newItem == null) {
                continue;
            }
            if (!e.getValue().equals(newItem)) {
                modified.add(e.getKey());
            }
        }
        return new DiffAnalysis<K>(deleted, added, modified);
    }
    
    public static <K,V> MergeAnalysis<K,V> mapMerge(Map<K,V> base, Map<K,V> left, Map<K,V> right) {