diff --git a/core/src/main/java/edu/umd/cs/piccolo/PCamera.java b/core/src/main/java/edu/umd/cs/piccolo/PCamera.java
index 8971f3a..4f8feb9 100644
--- a/core/src/main/java/edu/umd/cs/piccolo/PCamera.java
+++ b/core/src/main/java/edu/umd/cs/piccolo/PCamera.java
@@ -174,7 +174,11 @@
      *             modify the viewBounds parameter.
      */
     public void repaintFromLayer(final PBounds viewBounds, final PNode repaintedLayer) {
-        this.repaintFromLayer(viewBounds, (PLayer) repaintedLayer);
+        if (repaintedLayer instanceof PLayer) {
+            this.repaintFromLayer(viewBounds, (PLayer) repaintedLayer);
+        } else {
+            throw new RuntimeException("Passed non PLayer node to repaintFromLayer");
+        }
     }
 
     // ****************************************************************
diff --git a/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java b/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java
index ce287d4..14cae38 100644
--- a/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java
+++ b/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java
@@ -31,6 +31,7 @@
 import java.awt.geom.AffineTransform;
 
 import edu.umd.cs.piccolo.util.PAffineTransform;
+import edu.umd.cs.piccolo.util.PUtil;
 
 /**
  * PTransformActivity interpolates between two transforms setting its
@@ -111,7 +112,7 @@
      * target when the transform activity stops stepping.
      */
     public double[] getDestinationTransform() {
-        return destination;
+        return (destination == null) ? null : (double[]) destination.clone();
     }
 
     /**
@@ -119,7 +120,7 @@
      * target when the transform activity stops stepping.
      */
     public void setDestinationTransform(final double[] newDestination) {
-        destination = newDestination;
+        destination = (newDestination == null) ? null : (double[]) newDestination.clone();
     }
 
     protected void activityStarted() {
diff --git a/core/src/main/java/edu/umd/cs/piccolo/nodes/PImage.java b/core/src/main/java/edu/umd/cs/piccolo/nodes/PImage.java
index 8b53104..7426f54 100644
--- a/core/src/main/java/edu/umd/cs/piccolo/nodes/PImage.java
+++ b/core/src/main/java/edu/umd/cs/piccolo/nodes/PImage.java
@@ -128,31 +128,13 @@
      * load the image using a MediaTracker before returning.
      */
     public void setImage(final Image newImage) {
-        final Image old = image;
+        final Image oldImage = image;
 
         if (newImage == null || newImage instanceof BufferedImage) {
             image = newImage;
         }
-        else { // else make sure the image is loaded
-            final ImageIcon imageLoader = new ImageIcon(newImage);
-            switch (imageLoader.getImageLoadStatus()) {
-                case MediaTracker.LOADING:
-                    System.err.println("media tracker still loading image after requested to wait until finished");
-
-                case MediaTracker.COMPLETE:
-                    image = imageLoader.getImage();
-                    break;
-
-                case MediaTracker.ABORTED:
-                    System.err.println("media tracker aborted image load");
-                    image = null;
-                    break;
-
-                case MediaTracker.ERRORED:
-                    System.err.println("media tracker errored image load");
-                    image = null;
-                    break;
-            }
+        else {
+            image = getLoadedImage(newImage);
         }
 
         if (image != null) {
@@ -160,7 +142,25 @@
             invalidatePaint();
         }
 
-        firePropertyChange(PROPERTY_CODE_IMAGE, PROPERTY_IMAGE, old, image);
+        firePropertyChange(PROPERTY_CODE_IMAGE, PROPERTY_IMAGE, oldImage, image);
+    }
+
+    /**
+     * Ensures the image is loaded enough (loading is fine)
+     * 
+     * @param newImage to check
+     * @return image or null if not loaded enough.
+     */
+    private Image getLoadedImage(final Image newImage) {
+        final ImageIcon imageLoader = new ImageIcon(newImage);
+        switch (imageLoader.getImageLoadStatus()) {
+            case MediaTracker.LOADING:
+                return imageLoader.getImage();
+            case MediaTracker.COMPLETE:
+                return imageLoader.getImage();
+            default:
+                return null;
+        }
     }
 
     protected void paint(final PPaintContext paintContext) {
diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java b/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java
index 26ca50f..1a22847 100644
--- a/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java
+++ b/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java
@@ -56,7 +56,7 @@
 
     public static long DEFAULT_ACTIVITY_STEP_RATE = 20;
     public static int ACTIVITY_SCHEDULER_FRAME_DELAY = 10;
-    private static final int PATH_IS_DONE = -1;
+    private static final int PATH_TERMINATOR = -1;
 
     public static Iterator NULL_ITERATOR = Collections.EMPTY_LIST.iterator();
     public static Enumeration NULL_ENUMERATION = new Enumeration() {
@@ -197,7 +197,7 @@
                     path.closePath();
                     break;
 
-                case PATH_IS_DONE:
+                case PATH_TERMINATOR:
                     return path;
 
                 default:
@@ -253,6 +253,6 @@
             i.next();
         }
 
-        out.writeInt(PATH_IS_DONE);
-    }
+        out.writeInt(PATH_TERMINATOR);
+    }   
 }
diff --git a/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java b/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java
new file mode 100644
index 0000000..3daf135
--- /dev/null
+++ b/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java
@@ -0,0 +1,49 @@
+/**
+ * 
+ */
+package edu.umd.cs.piccolo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.umd.cs.piccolo.util.PBounds;
+
+class MockPCamera extends PCamera {       
+    private static final long serialVersionUID = 1L;
+    private List notifications = new ArrayList();
+
+    public void repaintFromLayer(final PBounds bounds, final PLayer layer) {
+        notifications.add(new Notification("repaintFromLayer", bounds, layer));
+        super.repaintFromLayer(bounds, layer);
+    }
+
+    static class Notification {
+        private final String type;
+        private final PBounds bounds;
+        // this should really be PLayer
+        private final PNode layer;
+
+        private Notification(final String type, final PBounds bounds, final PNode layer) {
+            this.bounds = bounds;
+            this.layer = layer;
+            this.type = type;
+        }
+
+        public PNode getLayer() {
+            return layer;
+        }
+
+        public PBounds getBounds() {
+            return bounds;
+        }
+    }
+
+    public int getNotificationCount() {
+        return notifications.size();
+    }
+
+    public Notification getNotification(int i) {
+       return (Notification)notifications.get(i);
+    }
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java b/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java
index 16776a8..9ce2828 100644
--- a/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java
+++ b/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java
@@ -2,20 +2,16 @@
 
 import java.awt.Cursor;
 
-import javax.swing.JPanel;
-
 import junit.framework.TestCase;
 import edu.umd.cs.piccolo.event.PInputEventListener;
 import edu.umd.cs.piccolo.util.PBounds;
 import edu.umd.cs.piccolo.util.PPaintContext;
 
 public class PCanvasTest extends TestCase {
-    private PCanvas canvas;
-    private int pCanvasFinalizerCount;
+    private PCanvas canvas;    
     private MockPInputEventListener mockListener;
 
-    public void setUp() {
-        pCanvasFinalizerCount = 0;
+    public void setUp() {        
         canvas = new PCanvas();
         mockListener = new MockPInputEventListener();
     }
@@ -105,7 +101,7 @@
         canvas.addInputEventListener(mockListener);
         final PInputEventListener[] listeners = canvas.getInputEventListeners();
         assertNotNull(listeners);
-        assertEquals(3, listeners.length); // 3 since pan and zoom are attached
+        assertEquals(3, listeners.length); // zoom + pan + mockListener
         // by default
     }
 
@@ -114,34 +110,6 @@
         canvas.removeInputEventListener(mockListener);
         final PInputEventListener[] listeners = canvas.getInputEventListeners();
         assertNotNull(listeners);
-        assertEquals(2, listeners.length); // 3 since pan and zoom are attached
-        // by default
+        assertEquals(2, listeners.length); // zoom + pan + mockListener
     }
-
-    public void testMemoryLeak() throws InterruptedException {
-        final JPanel panel = new JPanel();
-        for (int i = 0; i < 10; i++) {
-            PCanvas canvas = new PCanvas() {
-                /**
-                 * 
-                 */
-                private static final long serialVersionUID = 1L;
-
-                public void finalize() {
-                    pCanvasFinalizerCount++;
-                }
-            };
-            panel.add(canvas);
-            panel.remove(canvas);
-            canvas = null;
-        }
-        System.gc();
-        System.runFinalization();
-        PCanvas.CURRENT_ZCANVAS = null;
-
-        // Not sure why I need -1 here, but I do. If I create 10000 it'll always
-        // be 1 less
-        // assertEquals(10-1, pCanvasFinalizerCount);
-    }
-
 }
diff --git a/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java b/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java
index ea446f7..a3b623f 100644
--- a/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java
+++ b/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java
@@ -1,8 +1,6 @@
 package edu.umd.cs.piccolo;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 
 import junit.framework.TestCase;
 import edu.umd.cs.piccolo.util.PBounds;
@@ -96,37 +94,10 @@
         final PBounds bounds = new PBounds(0, 0, 100, 100);
         layer.repaintFrom(bounds, layer);
 
-        assertEquals(1, camera.notifications.size());
+        assertEquals(1, camera.getNotificationCount());
 
-        final MockPCamera.Notification notification = (MockPCamera.Notification) camera.notifications.get(0);
-        assertEquals(layer, notification.layer);
-        assertEquals(bounds, notification.bounds);
-    }
-
-    static class MockPCamera extends PCamera {
-        /**
-         * 
-         */
-        private static final long serialVersionUID = 1L;
-        List notifications = new ArrayList();
-
-        public void repaintFromLayer(final PBounds bounds, final PLayer layer) {
-            notifications.add(new Notification("repaintFromLayer", bounds, layer));
-            super.repaintFromLayer(bounds, layer);
-        }
-
-        class Notification {
-            String type;
-            PBounds bounds;
-            // this should really be PLayer
-            PNode layer;
-
-            Notification(final String type, final PBounds bounds, final PNode layer) {
-                this.bounds = bounds;
-                this.layer = layer;
-                this.type = type;
-            }
-        }
-
+        final MockPCamera.Notification notification = (MockPCamera.Notification) camera.getNotification(0);
+        assertEquals(layer, notification.getLayer());
+        assertEquals(bounds, notification.getBounds());
     }
 }
diff --git a/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java b/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java
index d598490..fb1811d 100644
--- a/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java
+++ b/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java
@@ -63,11 +63,11 @@
 
     public void testCanBeCreatedFromFile() throws IOException {
         final BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
-        final File imgFile = File.createTempFile("test", ".jpeg");
-        imgFile.deleteOnExit();
+        final File imgFile = File.createTempFile("test", ".jpeg");        
         ImageIO.write(img, "JPEG", imgFile);
-
+        imgFile.deleteOnExit();
         final PImage imageNode = new PImage(imgFile.getAbsolutePath());
+        assertNotNull(imageNode.getImage());
         assertEquals(100, imageNode.getImage().getWidth(null));
         assertEquals(100, imageNode.getImage().getHeight(null));
     }
diff --git a/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java b/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java
index 4baf035..f5cb1b5 100644
--- a/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java
+++ b/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java
@@ -76,9 +76,9 @@
         final File file = File.createTempFile("test", "ser");
 
         serializeToFile(srcPath, file);
-
-        final PPath resultPath = deserializeFromFile(srcBounds, file);
-
+        final PPath resultPath = deserializeFromFile(srcBounds, file);        
+        file.deleteOnExit();
+        
         assertEquals(resultPath.getBounds(), srcBounds);
     }
 
@@ -87,8 +87,7 @@
         PPath path;
         final FileInputStream fin = new FileInputStream(file);
         final ObjectInputStream in = new ObjectInputStream(fin);
-        path = (PPath) in.readObject();
-        file.delete();
+        path = (PPath) in.readObject();        
 
         return path;
     }
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/activities/PPathActivity.java b/extras/src/main/java/edu/umd/cs/piccolox/activities/PPathActivity.java
index c402f33..0dd3cfc 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/activities/PPathActivity.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/activities/PPathActivity.java
@@ -29,6 +29,7 @@
 package edu.umd.cs.piccolox.activities;
 
 import edu.umd.cs.piccolo.activities.PInterpolatingActivity;
+import edu.umd.cs.piccolo.util.PUtil;
 
 /**
  * PPathActivity is the abstract base class for all path activity
@@ -67,12 +68,12 @@
         return knots.length;
     }
 
-    public void setKnots(final float[] knots) {
-        this.knots = knots;
+    public void setKnots(final float[] newKnots) {
+        this.knots = (newKnots == null) ? newKnots : (float[]) newKnots.clone();
     }
 
     public float[] getKnots() {
-        return knots;
+        return (knots == null) ? knots : (float[]) knots.clone();
     }
 
     public void setKnot(final int index, final float knot) {
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/activities/PPositionPathActivity.java b/extras/src/main/java/edu/umd/cs/piccolox/activities/PPositionPathActivity.java
index 748a0fb..d0b4b64 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/activities/PPositionPathActivity.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/activities/PPositionPathActivity.java
@@ -62,8 +62,8 @@
     public PPositionPathActivity(final long duration, final long stepRate, final int loopCount, final int mode,
             final Target aTarget, final float[] knots, final Point2D[] positions) {
         super(duration, stepRate, loopCount, mode, knots);
-        target = aTarget;
-        this.positions = positions;
+        target = aTarget;        
+        this.positions = (Point2D[])positions.clone();
     }
 
     protected boolean isAnimation() {
@@ -71,7 +71,7 @@
     }
 
     public Point2D[] getPositions() {
-        return positions;
+        return (Point2D[])positions.clone();
     }
 
     public Point2D getPosition(final int index) {
@@ -79,7 +79,7 @@
     }
 
     public void setPositions(final Point2D[] positions) {
-        this.positions = positions;
+        this.positions = (Point2D[])positions.clone();
     }
 
     public void setPosition(final int index, final Point2D position) {
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/event/PNavigationEventHandler.java b/extras/src/main/java/edu/umd/cs/piccolox/event/PNavigationEventHandler.java
index f3d412f..338cdb5 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/event/PNavigationEventHandler.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/event/PNavigationEventHandler.java
@@ -326,7 +326,7 @@
 
         final double scaleFactor = d.getWidth() / aCamera.getViewScale();
         final Point2D scalePoint = focusNode.getGlobalFullBounds().getCenter2D();
-        if (scaleFactor != 1) {
+        if (Math.abs(1f-scaleFactor) < 0.0001) {
             aCamera.scaleViewAboutPoint(scaleFactor, scalePoint.getX(), scalePoint.getY());
         }
 
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/nodes/PStyledText.java b/extras/src/main/java/edu/umd/cs/piccolox/nodes/PStyledText.java
index fc4123c..9152099 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/nodes/PStyledText.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/nodes/PStyledText.java
@@ -297,10 +297,10 @@
                 font = style.getFont(((DefaultStyledDocument) document).getCharacterElement(pos).getAttributes());
                 if (font == null) {
                     font = style.getFont(((DefaultStyledDocument) document).getParagraphElement(pos).getAttributes());
-                }
-                if (font == null) {
-                    font = style.getFont(rootElement.getAttributes());
-                }
+                    if (font == null) {
+                        font = style.getFont(rootElement.getAttributes());
+                    }
+                }                
             }
             else {
                 font = style.getFont(rootElement.getAttributes());
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
index 13c1584..c084fdc 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java
@@ -219,10 +219,10 @@
     /**
      * The cutoff at which the Swing component is rendered greek
      */
-    private final double renderCutoff = 0.3;
+    private static final double GREEK_SCALE_CUT_OFF = 0.3d;
     private JComponent component = null;
     private double minFontSize = Double.MAX_VALUE;
-    private Stroke defaultStroke = new BasicStroke();
+    private transient Stroke defaultStroke = new BasicStroke();
     private Font defaultFont = new Font("Serif", Font.PLAIN, 12);
     private PSwingCanvas canvas;
 
@@ -381,7 +381,7 @@
     }
 
     protected boolean shouldRenderGreek(final PPaintContext renderContext) {
-        return renderContext.getScale() < renderCutoff
+        return renderContext.getScale() < GREEK_SCALE_CUT_OFF
         // && pSwingCanvas.getInteracting()
                 || minFontSize * renderContext.getScale() < 0.5;
     }
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
index 76064f1..ef93621 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
@@ -44,9 +44,6 @@
  * @author Lance E. Good
  */
 public class PSwingCanvas extends PCanvas {
-    /**
-     * 
-     */
     private static final long serialVersionUID = 1L;
     public static final String SWING_WRAPPER_KEY = "Swing Wrapper";
     private final ChildWrapper swingWrapper;
@@ -62,14 +59,9 @@
     }
 
     private void initRepaintManager() {
-        final RepaintManager repaintManager = RepaintManager.currentManager(this);
-        PSwingRepaintManager pSwingRepaintManager;
-        if (repaintManager instanceof PSwingRepaintManager) {
-            pSwingRepaintManager = (PSwingRepaintManager) repaintManager;
-        }
-        else {
-            pSwingRepaintManager = new PSwingRepaintManager();
-            RepaintManager.setCurrentManager(pSwingRepaintManager);
+        final RepaintManager repaintManager = RepaintManager.currentManager(this);        
+        if (!(repaintManager instanceof PSwingRepaintManager)) {            
+            RepaintManager.setCurrentManager(new PSwingRepaintManager());
         }
     }
 
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPaneLayout.java b/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPaneLayout.java
index ee936c8..9766a03 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPaneLayout.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPaneLayout.java
@@ -66,6 +66,9 @@
         /*
          * Sync the (now obsolete) policy fields with the JScrollPane.
          */
+        if (!(parent instanceof JScrollPane)) {
+            throw new IllegalArgumentException("layoutContainer may only be applied to JScrollPanes");
+        }
         final JScrollPane scrollPane = (JScrollPane) parent;
         vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
         hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/swing/PViewport.java b/extras/src/main/java/edu/umd/cs/piccolox/swing/PViewport.java
index f54fff7..f67e7cb 100644
--- a/extras/src/main/java/edu/umd/cs/piccolox/swing/PViewport.java
+++ b/extras/src/main/java/edu/umd/cs/piccolox/swing/PViewport.java
@@ -225,6 +225,9 @@
          * @param parent the container to lay out
          */
         public void layoutContainer(final Container parent) {
+            if (!(parent instanceof JViewport)) {
+                throw new IllegalArgumentException("PViewport.layoutContainer may only be applied to JViewports");
+            }
             final JViewport vp = (JViewport) parent;
             final Component view = vp.getView();
 
diff --git a/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingCanvasTest.java b/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingCanvasTest.java
index 14e7b40..4c6bb01 100644
--- a/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingCanvasTest.java
+++ b/extras/src/test/java/edu/umd/cs/piccolox/pswing/PSwingCanvasTest.java
@@ -28,7 +28,7 @@
  */
 package edu.umd.cs.piccolox.pswing;
 
-import javax.swing.JPanel;
+import javax.swing.JLabel;
 
 import junit.framework.TestCase;
 
@@ -40,33 +40,11 @@
 
     public void setUp() {
         finalizerCallCount = 0;
-    }
-
-    public void testMemoryLeak() throws InterruptedException {
-        JPanel panel = new JPanel();
-        for (int i = 0; i < 10; i++) {
-            PSwingCanvas canvas = new PSwingCanvas() {
-                /**
-                 * 
-                 */
-                private static final long serialVersionUID = 1L;
-
-                public void finalize() {
-                    finalizerCallCount++;
-                }
-            };
-            panel.add(canvas);
-            panel.remove(canvas);
-            canvas = null;
-        }
-        panel = null;
-        System.gc();
-        System.runFinalization();
-
-        // Not sure why I need -1 here, but I do. If I create 10000 it'll always
-        // be 1 less
-        // TODO: make this work in all environments. Will not work at the
-        // command line for some.
-        // assertEquals(10 - 1, finalizerCallCount);
+    }  
+    
+    public void testRemovePSwingDoesNothingWithForeignPSwing() {
+        PSwingCanvas canvas = new PSwingCanvas();
+        PSwing orphanPSwing = new PSwing(new JLabel());
+        canvas.removePSwing(orphanPSwing);
     }
 }