// Path: src/main/java/edu/mit/blocks/workspace/RBParent.java
// public interface RBParent {
// 
//     /**
//      * Add this Component the BlockLayer, which is understood to be above the
//      * HighlightLayer, although no guarantee is made about its order relative
//      * to any other layers this RBParent may have.
//      * @param c the Component to add
//      */
//     public void addToBlockLayer(Component c);
// 
//     /**
//      * Add this Component to the HighlightLayer, which is understood to be
//      * directly and completely beneath the BlockLayer, such that all Components
//      * on the HighlightLayer are rendered behind ALL Components on the BlockLayer.
//      * @param c the Component to add
//      */
//     public void addToHighlightLayer(Component c);
// }
// 
// Path: src/main/java/edu/mit/blocks/codeblockutil/GraphicsManager.java
// public class GraphicsManager {
// 
//     /** get GraphicConfiguration for default screen - this should only be done once at startup **/
//     private static GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//     private static GraphicsDevice gs = ge.getDefaultScreenDevice();
//     public static GraphicsConfiguration gc = gs.getDefaultConfiguration();
//     private static final int MAX_RECYCLED_IMAGES = 50;
//     private static int numRecycledImages = 0;
//     private static HashMap<Dimension, List<BufferedImage>> recycledImages = new HashMap<Dimension, List<BufferedImage>>();
// 
//     /**
//      * Functionally equivalent to
//      *   gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT)
//      * but allows reusing released images.
//      */
//     public static BufferedImage getGCCompatibleImage(int width, int height) {
//         List<BufferedImage> imgList = recycledImages.get(new Dimension(width, height));
//         if (imgList == null || imgList.isEmpty()) {
//             return gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
//         }
//         numRecycledImages--;
//         BufferedImage img = imgList.remove(imgList.size() - 1);
//         // Clear the image
//         Graphics2D g2D = img.createGraphics();
//         g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
//         Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, width, height);
//         g2D.fill(rect);
//         return img;
//     }
// 
//     /** 
//      * Add an image to the recycled images list (or if img = null, does nothing).
//      * Note: the passed variable should be immediately set to null to avoid aliasing bugs.
//      */
//     public static void recycleGCCompatibleImage(BufferedImage img) {
//         if (img == null) {
//             return;
//         }
//         // Make sure we don't waste too much memory
//         if (numRecycledImages >= MAX_RECYCLED_IMAGES) {
//             recycledImages.clear();
//         }
//         Dimension dim = new Dimension(img.getWidth(), img.getHeight());
//         List<BufferedImage> imgList = recycledImages.get(dim);
//         if (imgList == null) {
//             imgList = new ArrayList<BufferedImage>();
//             recycledImages.put(dim, imgList);
//         }
//         imgList.add(img);
//     }
// }


import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import edu.mit.blocks.workspace.RBParent;
import edu.mit.blocks.codeblockutil.GraphicsManager;

    public void removeFromParent() {
        if (this.getParent() != null) {
            this.getParent().remove(this);
        }
    }

    public void updateImage() {
        if (GraphicsEnvironment.isHeadless()) {
            return;
        }

        // cache the focus so it'll know when it needs to redraw later.
        hasFocus = rb.getBlock().hasFocus();

        Color color = null;
        if (hColor != null) {
            color = hColor;
        } else if (rb.getBlock().hasFocus()) {
            color = new Color(200, 200, 255); //Color.BLUE);
        } else if (isSearchResult) {
            color = new Color(255, 255, 120); //Color.YELLOW);
        } else if (rb.getBlock().isBad()) {
            color = new Color(255, 100, 100); //Color.RED);
        } else {
            GraphicsManager.recycleGCCompatibleImage(hImage);
            hImage = null;
            return; // if we're not highlighting, destroy the image and just return
        }

        if (!rb.isVisible()) {

// Path: src/main/java/edu/mit/blocks/workspace/RBParent.java
// public interface RBParent {
// 
//     /**
//      * Add this Component the BlockLayer, which is understood to be above the
//      * HighlightLayer, although no guarantee is made about its order relative
//      * to any other layers this RBParent may have.
//      * @param c the Component to add
//      */
//     public void addToBlockLayer(Component c);
// 
//     /**
//      * Add this Component to the HighlightLayer, which is understood to be
//      * directly and completely beneath the BlockLayer, such that all Components
//      * on the HighlightLayer are rendered behind ALL Components on the BlockLayer.
//      * @param c the Component to add
//      */
//     public void addToHighlightLayer(Component c);
// }
// 
// Path: src/main/java/edu/mit/blocks/codeblockutil/GraphicsManager.java
// public class GraphicsManager {
// 
//     /** get GraphicConfiguration for default screen - this should only be done once at startup **/
//     private static GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//     private static GraphicsDevice gs = ge.getDefaultScreenDevice();
//     public static GraphicsConfiguration gc = gs.getDefaultConfiguration();
//     private static final int MAX_RECYCLED_IMAGES = 50;
//     private static int numRecycledImages = 0;
//     private static HashMap<Dimension, List<BufferedImage>> recycledImages = new HashMap<Dimension, List<BufferedImage>>();
// 
//     /**
//      * Functionally equivalent to
//      *   gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT)
//      * but allows reusing released images.
//      */
//     public static BufferedImage getGCCompatibleImage(int width, int height) {
//         List<BufferedImage> imgList = recycledImages.get(new Dimension(width, height));
//         if (imgList == null || imgList.isEmpty()) {
//             return gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
//         }
//         numRecycledImages--;
//         BufferedImage img = imgList.remove(imgList.size() - 1);
//         // Clear the image
//         Graphics2D g2D = img.createGraphics();
//         g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
//         Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, width, height);
//         g2D.fill(rect);
//         return img;
//     }
// 
//     /** 
//      * Add an image to the recycled images list (or if img = null, does nothing).
//      * Note: the passed variable should be immediately set to null to avoid aliasing bugs.
//      */
//     public static void recycleGCCompatibleImage(BufferedImage img) {
//         if (img == null) {
//             return;
//         }
//         // Make sure we don't waste too much memory
//         if (numRecycledImages >= MAX_RECYCLED_IMAGES) {
//             recycledImages.clear();
//         }
//         Dimension dim = new Dimension(img.getWidth(), img.getHeight());
//         List<BufferedImage> imgList = recycledImages.get(dim);
//         if (imgList == null) {
//             imgList = new ArrayList<BufferedImage>();
//             recycledImages.put(dim, imgList);
//         }
//         imgList.add(img);
//     }
// }


// Path: src/main/java/edu/mit/blocks/renderable/RBHighlightHandler.java
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import edu.mit.blocks.workspace.RBParent;
import edu.mit.blocks.codeblockutil.GraphicsManager;

    public void removeFromParent() {
        if (this.getParent() != null) {
            this.getParent().remove(this);
        }
    }

    public void updateImage() {
        if (GraphicsEnvironment.isHeadless()) {
            return;
        }

        // cache the focus so it'll know when it needs to redraw later.
        hasFocus = rb.getBlock().hasFocus();

        Color color = null;
        if (hColor != null) {
            color = hColor;
        } else if (rb.getBlock().hasFocus()) {
            color = new Color(200, 200, 255); //Color.BLUE);
        } else if (isSearchResult) {
            color = new Color(255, 255, 120); //Color.YELLOW);
        } else if (rb.getBlock().isBad()) {
            color = new Color(255, 100, 100); //Color.RED);
        } else {
            GraphicsManager.recycleGCCompatibleImage(hImage);
            hImage = null;
            return; // if we're not highlighting, destroy the image and just return
        }

        if (!rb.isVisible()) {

            GraphicsManager.recycleGCCompatibleImage(hImage);
