concept Screenshot { S pngPath; // optional, relative (program ID + "/" + file name) Rect r; // optional, rectangle that was shot *() {} // for persistance *(BufferedImage img) { savePNG(pngFile(), img); } File pngFile() { if (pngPath != null) ret prepareFile(new File(javaxDataDir(), pngPath)); ret prepareProgramFile(_programID(), "screenshot" + id + ".png"); } BufferedImage loadImage() { ret loadImage2(pngFile()); } bool hasImage() { ret pngFile().exists(); } } Screenshot > TransientScreenshot { transient BufferedImage img; *() {} // for persistance *(BufferedImage *img) {} bool hasImage() { ret img != null; } BufferedImage loadImage() { ret img; } void disposeImage() { img = null; } } Clip > MarkedClip { new Ref screenshot; Rect positionInScreenshot; } concept Clip { long originalID; // ID in #1005389 BWImage img; S description; } concept Found { new Ref screenshot; new Ref clip; FoundImg fi; // contains Rect r } concept FullySearched { new Ref screenshot; new Ref clip; }