Changed Safe Delete to epsilon-<B; improved error messages
diff --git a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/AddEmptySubprogramRefactoring.java b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/AddEmptySubprogramRefactoring.java
index 44f114a..b718365 100644
--- a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/AddEmptySubprogramRefactoring.java
+++ b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/AddEmptySubprogramRefactoring.java
@@ -24,6 +24,7 @@
 import org.eclipse.photran.internal.core.refactoring.infrastructure.SingleFileFortranRefactoring;
 import org.eclipse.photran.internal.core.vpg.PhotranVPG;
 import org.eclipse.rephraserengine.core.preservation.PreservationAnalysis;
+import org.eclipse.rephraserengine.core.preservation.Preserve;
 import org.eclipse.rephraserengine.core.refactorings.UserInputString;
 
 /**
@@ -95,7 +96,7 @@
         try
         {
             preservation = new PreservationAnalysis(PhotranVPG.getInstance(), pm,
-                PhotranVPG.BINDING_EDGE_TYPE);
+                Preserve.all(PhotranVPG.BINDING_EDGE_TYPE));
 
             preservation.monitor(fileInEditor);
             createNewSubprogram();
diff --git a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/SafeDeleteRefactoring.java b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/SafeDeleteRefactoring.java
index 1294632..bef32dc 100644
--- a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/SafeDeleteRefactoring.java
+++ b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/refactoring/SafeDeleteRefactoring.java
@@ -22,6 +22,7 @@
 import org.eclipse.photran.internal.core.refactoring.infrastructure.SingleFileFortranRefactoring;
 import org.eclipse.photran.internal.core.vpg.PhotranVPG;
 import org.eclipse.rephraserengine.core.preservation.PreservationAnalysis;
+import org.eclipse.rephraserengine.core.preservation.Preserve;
 
 /**
  * Refactoring to delete an unused declaration from a Fortran program.
@@ -80,7 +81,7 @@
         try
         {
             preservation = new PreservationAnalysis(PhotranVPG.getInstance(), pm,
-                PhotranVPG.BINDING_EDGE_TYPE);
+                Preserve.incoming(PhotranVPG.BINDING_EDGE_TYPE));
 
             preservation.monitor(fileInEditor);
             deleteScope();
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
index bba7b35..a1a4b24 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/PreservationAnalysis.java
@@ -51,16 +51,16 @@
 
     private List<PrimitiveOp> primitiveOps = new LinkedList<PrimitiveOp>();
 
-    private Set<Integer> preserveEdgeTypes = Collections.<Integer>emptySet();
+    private Set<Preserve> preserveEdgeTypes = Collections.<Preserve>emptySet();
 
-    public PreservationAnalysis(EclipseVPG vpg, IProgressMonitor pm, int... edgeTypes)
+    public PreservationAnalysis(EclipseVPG vpg, IProgressMonitor pm, Preserve... edgeTypes)
     {
         this.adapterManager = Platform.getAdapterManager();
         this.vpg = vpg;
         this.progressMonitor = pm;
 
-        preserveEdgeTypes = new HashSet<Integer>(edgeTypes.length);
-        for (int type : edgeTypes)
+        preserveEdgeTypes = new HashSet<Preserve>(edgeTypes.length);
+        for (Preserve type : edgeTypes)
             preserveEdgeTypes.add(type);
     }
 
@@ -209,6 +209,7 @@
     private void checkForPreservation(RefactoringStatus status, String filename)
     {
         printDebug("INITIAL MODEL", initialModels.get(filename));
+        printDebug("NORMALIZING RELATIVE TO", primitiveOps);
 
         progressMonitor.subTask("Normalizing initial model - " + lastSegment(filename));
         initialModels.get(filename).inormalize(primitiveOps, preserveEdgeTypes);
@@ -247,7 +248,8 @@
             {
                 String msg = "Completing this transformation will introduce an unexpected "
                     + vpg.describeEdgeType(addition.edgeType).toLowerCase()
-                    + " (" + addition + ")";
+                    //+ " (" + addition + ")"
+                    ;
 
                 status.addError(msg,
                     new PostTransformationContext(
@@ -262,7 +264,8 @@
                 String msg = "Completing this transformation will cause an existing "
                     + vpg.describeEdgeType(deletion.edgeType).toLowerCase()
                     + " to disappear"
-                    + " (" + deletion + ")";
+                    //+ " (" + deletion + ")"
+                    ;
 
                 status.addError(msg,
                     new FileStatusContext(
@@ -276,7 +279,8 @@
                 String msg = "Completing this transformation will cause an existing "
                     + vpg.describeEdgeType(change.edgeType).toLowerCase()
                     + " to change"
-                    + " (" + change + ")";
+                    //+ " (" + change + ")"
+                    ;
 
                 status.addError(msg,
                     new PostTransformationContext(
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/Preserve.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/Preserve.java
new file mode 100644
index 0000000..9936bb8
--- /dev/null
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/core/preservation/Preserve.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009 University of Illinois at Urbana-Champaign and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    UIUC - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.rephraserengine.core.preservation;
+
+/**
+ *
+ * @author Jeff Overbey
+ */
+public final class Preserve
+{
+    public static final Preserve incoming(int edgeType)
+    {
+        return new Preserve(edgeType, true, false);
+    }
+
+    public static final Preserve outgoing(int edgeType)
+    {
+        return new Preserve(edgeType, false, true);
+    }
+
+    public static final Preserve all(int edgeType)
+    {
+        return new Preserve(edgeType, true, true);
+    }
+
+    private int edgeType;
+    private boolean preserveIncoming, preserveOutgoing;
+
+    private Preserve(int edgeType, boolean preserveIncoming, boolean preserveOutgoing)
+    {
+        this.edgeType = edgeType;
+        this.preserveIncoming = preserveIncoming;
+        this.preserveOutgoing = preserveOutgoing;
+    }
+
+    public boolean shouldPreserve(boolean isIncoming, boolean isOutgoing, int edgeType)
+    {
+        if (this.edgeType != edgeType)
+            return false;
+        else if (isIncoming && isOutgoing) // entirely contained in affected region
+            return false;
+        else if (isIncoming)
+            return preserveIncoming;
+        else if (isOutgoing)
+            return preserveOutgoing;
+        else                               // outside affected region
+            return true;
+    }
+}
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
index ac8e66d..0e0acab 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/Model.java
@@ -15,6 +15,7 @@
 import java.util.Set;
 import java.util.TreeSet;
 
+import org.eclipse.rephraserengine.core.preservation.Preserve;
 import org.eclipse.rephraserengine.core.vpg.TokenRef;
 import org.eclipse.rephraserengine.core.vpg.VPGEdge;
 import org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG;
@@ -31,7 +32,7 @@
     private static final class Entry implements Comparable<Entry>
     {
         private String sourceFilename;
-        private Interval source;
+        private Interval source, origSource;
         private String sinkFilename;
         private Interval sink;
         private int edgeType;
@@ -41,16 +42,27 @@
             if (source == null || sink == null) throw new IllegalArgumentException();
 
             this.sourceFilename = sourceFilename;
-            this.source = source;
+            this.source = this.origSource = source;
             this.sinkFilename = sinkFilename;
             this.sink = sink;
             this.edgeType = edgeType;
         }
 
-        public boolean isEntirelyContainedIn(Interval interval)
+        public boolean shouldPreserveAccordingTo(Set<Preserve> preserveEdgeTypes, Interval affected)
+        {
+            for (Preserve rule : preserveEdgeTypes)
+                if (shouldPreserveAccordingTo(rule, affected))
+                    return true;
+
+            return false;
+        }
+
+        public boolean shouldPreserveAccordingTo(Preserve rule, Interval affected)
         {
             // FIXME: What about filenames?
-            return source.isSubsetOf(interval) && sink.isSubsetOf(interval);
+            boolean incoming = sink.isSubsetOf(affected);
+            boolean outgoing = source.isSubsetOf(affected);
+            return rule.shouldPreserve(incoming, outgoing, this.edgeType);
         }
 
         @Override public boolean equals(Object o)
@@ -119,16 +131,15 @@
         }
     }
 
-    public void inormalize(PrimitiveOp op, Set<Integer> preserveEdgeTypes)
+    public void inormalize(PrimitiveOp op, Set<Preserve> preserveEdgeTypes)
     {
         TreeSet<Entry> revisedList = new TreeSet<Entry>();
 
         for (Entry entry : edgeList)
         {
-            if (preserveEdgeTypes.contains(entry.edgeType)
-                && !entry.isEntirelyContainedIn(op.iaff()))
+            if (entry.shouldPreserveAccordingTo(preserveEdgeTypes, op.iaff()))
             {
-                entry.source = op.inorm(entry.source);
+                entry.source = op.inorm(entry.source); // leave origSource unchanged
                 entry.sink = op.inorm(entry.sink);
                 revisedList.add(entry);
             }
@@ -137,20 +148,19 @@
         edgeList = revisedList;
     }
 
-    public void inormalize(List<PrimitiveOp> primitiveOps, Set<Integer> preserveEdgeTypes)
+    public void inormalize(List<PrimitiveOp> primitiveOps, Set<Preserve> preserveEdgeTypes)
     {
         for (PrimitiveOp op : primitiveOps)
             inormalize(op, preserveEdgeTypes);
     }
-    
-    public void dnormalize(PrimitiveOp op, Set<Integer> preserveEdgeTypes)
+
+    public void dnormalize(PrimitiveOp op, Set<Preserve> preserveEdgeTypes)
     {
         TreeSet<Entry> revisedList = new TreeSet<Entry>();
 
         for (Entry entry : edgeList)
         {
-            if (preserveEdgeTypes.contains(entry.edgeType)
-                && !entry.isEntirelyContainedIn(op.daff()))
+            if (entry.shouldPreserveAccordingTo(preserveEdgeTypes, op.daff()))
             {
                 entry.source = op.dnorm(entry.source);
                 entry.sink = op.dnorm(entry.sink);
@@ -161,7 +171,7 @@
         edgeList = revisedList;
     }
 
-    public void dnormalize(List<PrimitiveOp> primitiveOps, Set<Integer> preserveEdgeTypes)
+    public void dnormalize(List<PrimitiveOp> primitiveOps, Set<Preserve> preserveEdgeTypes)
     {
         for (PrimitiveOp op : primitiveOps)
             dnormalize(op, preserveEdgeTypes);
@@ -183,7 +193,7 @@
                 }
                 else
                 {
-                    diff.add(new EdgeDeleted(entry.source, entry.sink, entry.edgeType));
+                    diff.add(new EdgeDeleted(entry.origSource, entry.sink, entry.edgeType));
                 }
             }
         }
diff --git a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
index 22e3bb9..cc3f00b 100644
--- a/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
+++ b/org.eclipse.rephraserengine.core.vpg/src/org/eclipse/rephraserengine/internal/core/preservation/PrimitiveOp.java
@@ -122,7 +122,7 @@
         @Override
         public Interval dnorm(Interval i)
         {
-            if (i.isSubsetOf(j))
+            if (i.isSubsetOf(k))
                 return k;
             else
                 return i;
@@ -136,7 +136,7 @@
 
         @Override public String toString()
         {
-            return "rho(" + j + ", " + k + ")";
+            return "rho<" + j + ", " + k + ">";
         }
     }