Pick up bndlib multimap fix
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1362046 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
index a106aae..99c904e 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/Project.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -1722,7 +1722,12 @@
}
boolean replace(File f, String pattern, String replacement) throws IOException {
- Sed sed = new Sed(getReplacer(), f);
+ final Macro macro = getReplacer();
+ Sed sed = new Sed( new Replacer() {
+ public String process(String line) {
+ return macro.process(line);
+ }
+ }, f);
sed.replace(pattern, replacement);
return sed.doIt() > 0;
}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
index e5f0444..d265703 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
@@ -6,7 +6,7 @@
import aQute.bnd.osgi.*;
import aQute.bnd.service.*;
import aQute.bnd.service.RepositoryPlugin.Strategy;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
public interface ProjectMessages extends Messages {
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java b/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java
new file mode 100644
index 0000000..cdeb93c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java
@@ -0,0 +1,31 @@
+package aQute.bnd.component;
+
+import java.io.*;
+
+import aQute.bnd.osgi.*;
+import aQute.lib.tag.*;
+
+class TagResource extends WriteResource {
+ final Tag tag;
+
+ public TagResource(Tag tag) {
+ this.tag = tag;
+ }
+
+ public void write(OutputStream out) throws UnsupportedEncodingException {
+ OutputStreamWriter ow = new OutputStreamWriter(out, "UTF-8");
+ PrintWriter pw = new PrintWriter(ow);
+ pw.println("<?xml version='1.1'?>");
+ try {
+ tag.print(0, pw);
+ }
+ finally {
+ pw.flush();
+ }
+ }
+
+ public long lastModified() {
+ return 0;
+ }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo b/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
index 1a5c61b..09c494f 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
@@ -58,11 +58,11 @@
// Global parameters
private final MultiMap<PackageRef,PackageRef> uses = new MultiMap<PackageRef,PackageRef>(
- PackageRef.class, PackageRef.class,
- true);
+ PackageRef.class, PackageRef.class,
+ true);
private final MultiMap<PackageRef,PackageRef> apiUses = new MultiMap<PackageRef,PackageRef>(
- PackageRef.class, PackageRef.class,
- true);
+ PackageRef.class, PackageRef.class,
+ true);
private final Packages classpathExports = new Packages();
private final Descriptors descriptors = new Descriptors();
private final List<Jar> classpath = list();
@@ -232,11 +232,12 @@
// USES
//
// Add the uses clause to the exports
-
- boolean api = isTrue(getProperty(EXPERIMENTS)) || true; // brave, lets see
-
+
+ boolean api = isTrue(getProperty(EXPERIMENTS)) || true; // brave,
+ // lets see
+
doUses(exports, api ? apiUses : uses, imports);
-
+
//
// Verify that no exported package has a reference to a private
// package
@@ -245,9 +246,7 @@
// exported packages
// should preferably not refer to private packages.
//
- Set<PackageRef> privatePackages = new HashSet<PackageRef>(contained.keySet());
- privatePackages.removeAll(exports.keySet());
- privatePackages.removeAll(imports.keySet());
+ Set<PackageRef> privatePackages = getPrivates();
// References to java are not imported so they would show up as
// private
@@ -647,6 +646,13 @@
return imports;
}
+ public Set<PackageRef> getPrivates() {
+ HashSet<PackageRef> privates = new HashSet<PackageRef>(contained.keySet());
+ privates.removeAll(exports.keySet());
+ privates.removeAll(imports.keySet());
+ return privates;
+ }
+
public Jar getJar() {
return dot;
}
@@ -673,11 +679,11 @@
return unreachable;
}
- public MultiMap<PackageRef,PackageRef> getUses() {
+ public Map<PackageRef,List<PackageRef>> getUses() {
return uses;
}
- public MultiMap<PackageRef,PackageRef> getAPIUses() {
+ public Map<PackageRef,List<PackageRef>> getAPIUses() {
return apiUses;
}
@@ -1296,7 +1302,7 @@
* @param uses
* @throws MojoExecutionException
*/
- void doUses(Packages exports, MultiMap<PackageRef,PackageRef> uses, Packages imports) {
+ void doUses(Packages exports, Map<PackageRef,List<PackageRef>> uses, Packages imports) {
if ("true".equalsIgnoreCase(getProperty(NOUSES)))
return;
@@ -1320,7 +1326,7 @@
* @param uses
* @param imports
*/
- protected void doUses(PackageRef packageRef, Packages exports, MultiMap<PackageRef,PackageRef> uses,
+ protected void doUses(PackageRef packageRef, Packages exports, Map<PackageRef,List<PackageRef>> uses,
Packages imports) {
Attrs clause = exports.get(packageRef);
@@ -1745,7 +1751,6 @@
if (info != null)
contained.merge(packageRef, false, info);
-
// Look at the referred packages
// and copy them to our baseline
Set<PackageRef> refs = Create.set();
@@ -1755,7 +1760,7 @@
}
refs.remove(packageRef);
uses.addAll(packageRef, refs);
-
+
// Collect the API
apiUses.addAll(packageRef, clazz.getAPIUses());
}
@@ -2462,23 +2467,102 @@
}
/**
- * Remove the own references and optionall java references from the uses lib
+ * Remove the own references and optional java references from the uses lib
+ *
* @param apiUses
* @param removeJava
* @return
*/
- public MultiMap<PackageRef,PackageRef> cleanupUses(MultiMap<PackageRef,PackageRef> apiUses, boolean removeJava) {
+ public Map<PackageRef,List<PackageRef>> cleanupUses(Map<PackageRef,List<PackageRef>> apiUses, boolean removeJava) {
MultiMap<PackageRef,PackageRef> map = new MultiMap<PackageRef,PackageRef>(apiUses);
- for ( Entry<PackageRef,List<PackageRef>> e : map.entrySet()) {
+ for (Entry<PackageRef,List<PackageRef>> e : map.entrySet()) {
e.getValue().remove(e.getKey());
if (!removeJava)
continue;
-
- for (Iterator<PackageRef> i = e.getValue().iterator(); i.hasNext(); ) {
- if ( i.next().isJava())
+
+ for (Iterator<PackageRef> i = e.getValue().iterator(); i.hasNext();) {
+ if (i.next().isJava())
i.remove();
}
- }
+ }
return map;
}
+
+ /**
+ * Return the classes for a given source package.
+ *
+ * @param source
+ * the source package
+ * @return a set of classes for the requested package.
+ */
+ public Set<Clazz> getClassspace(PackageRef source) {
+ Set<Clazz> result = new HashSet<Clazz>();
+ for (Clazz c : getClassspace().values()) {
+ if (c.getClassName().getPackageRef() == source)
+ result.add(c);
+ }
+ return result;
+ }
+
+ /**
+ * Create a cross reference from package source, to packages in dest
+ * @param source
+ * @param dest
+ * @param sourceModifiers
+ * @return
+ * @throws Exception
+ */
+ public Map<Clazz.Def, List<TypeRef>> getXRef(final PackageRef source, final Collection<PackageRef> dest, final int sourceModifiers)
+ throws Exception {
+ final MultiMap<Clazz.Def,TypeRef> xref = new MultiMap<Clazz.Def, TypeRef>(Clazz.Def.class, TypeRef.class, true);
+
+ for (final Clazz clazz : getClassspace().values()) {
+ if ((clazz.accessx & sourceModifiers) == 0)
+ continue;
+
+ if (source!=null && source != clazz.getClassName().getPackageRef())
+ continue;
+
+ clazz.parseClassFileWithCollector(new ClassDataCollector() {
+ Clazz.Def member;
+
+ public void extendsClass(TypeRef zuper) throws Exception {
+ if (dest.contains(zuper.getPackageRef()))
+ xref.add(clazz.getExtends(zuper), zuper);
+ }
+
+ public void implementsInterfaces(TypeRef[] interfaces) throws Exception {
+ for (TypeRef i : interfaces) {
+ if (dest.contains(i.getPackageRef()))
+ xref.add(clazz.getImplements(i), i);
+ }
+ }
+
+ public void referTo(TypeRef to, int modifiers) {
+ if (to.isJava())
+ return;
+
+ if (!dest.contains(to.getPackageRef()))
+ return;
+
+ if (member != null && ((modifiers & sourceModifiers) != 0)) {
+ xref.add(member, to);
+ }
+
+ }
+
+ public void method(Clazz.MethodDef defined) {
+ member = defined;
+ }
+
+ public void field(Clazz.FieldDef defined) {
+ member = defined;
+ }
+
+ });
+
+ }
+ return xref;
+ }
+
}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java b/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java
index aac1a52..95b32df 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java
@@ -3,7 +3,7 @@
import java.util.*;
import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
public interface AnalyzerMessages extends Messages {
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
index c8d79c6..c2daba7 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
@@ -24,9 +24,6 @@
public void field(@SuppressWarnings("unused") Clazz.FieldDef defined) {}
- public void reference(@SuppressWarnings("unused") Clazz.MethodDef referenced) {}
-
- public void reference(@SuppressWarnings("unused") Clazz.FieldDef referenced) {}
public void classEnd() throws Exception {}
@@ -83,4 +80,15 @@
}
+ /**
+ * A reference to a type from method or field. The modifiers indicate the
+ * access level of the parent method/field.
+ *
+ * @param typeRef
+ * @param modifiers
+ */
+ public void referTo(TypeRef typeRef, int modifiers) {
+
+ }
+
}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
index dc8784c..0a72c77 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
@@ -69,7 +69,8 @@
return major >= J2SE5.major;
}
- public static JAVA getJava(int major, @SuppressWarnings("unused") int minor) {
+ public static JAVA getJava(int major, @SuppressWarnings("unused")
+ int minor) {
for (JAVA j : JAVA.values()) {
if (j.major == major)
return j;
@@ -145,7 +146,8 @@
int b;
}
- public class Def {
+ public abstract class Def {
+
final int access;
Set<TypeRef> annotations;
@@ -214,6 +216,18 @@
public Collection<TypeRef> getAnnotations() {
return annotations;
}
+
+ public TypeRef getOwnerType() {
+ return className;
+ }
+
+ public abstract String getName();
+ public abstract TypeRef getType();
+ public abstract TypeRef[] getPrototype();
+
+ public Object getClazz() {
+ return Clazz.this;
+ }
}
public class FieldDef extends Def {
@@ -240,10 +254,7 @@
public String getName() {
return name;
}
-
- public String toString() {
- return getName();
- }
+
public TypeRef getType() {
return descriptor.getType();
@@ -279,10 +290,16 @@
return objectDescriptorToFQN(returnType);
}
+ public TypeRef[] getPrototype() {
+ return null;
+ }
public String getSignature() {
return signature;
}
+ public String toString() {
+ return name;
+ }
}
public class MethodDef extends FieldDef {
@@ -297,7 +314,40 @@
public TypeRef[] getPrototype() {
return descriptor.getPrototype();
}
+ }
+ public class TypeDef extends Def {
+ TypeRef type;
+ boolean interf;
+
+ public TypeDef(TypeRef type, boolean interf) {
+ super(Modifier.PUBLIC);
+ this.type = type;
+ this.interf = interf;
+ }
+
+ public TypeRef getReference() {
+ return type;
+ }
+
+ public boolean getImplements() {
+ return interf;
+ }
+
+
+ public String getName() {
+ if (interf)
+ return "<implements>";
+ else
+ return "<extends>";
+ }
+
+ public TypeRef getType() {
+ return type;
+ }
+ public TypeRef[] getPrototype() {
+ return null;
+ }
}
final static byte SkipTable[] = { //
@@ -349,7 +399,6 @@
Set<PackageRef> api;
final Analyzer analyzer;
-
public Clazz(Analyzer analyzer, String path, Resource resource) {
this.path = path;
this.resource = resource;
@@ -388,7 +437,7 @@
Set<TypeRef> parseClassFile(DataInputStream in) throws Exception {
xref = new HashSet<TypeRef>();
-
+
boolean crawl = cd != null; // Crawl the byte code if we have a
// collector
int magic = in.readInt();
@@ -463,36 +512,37 @@
}
pool(pool, intPool);
-
- // All name& type and class constant records contain descriptors we must treat
+
+ // All name& type and class constant records contain descriptors we must
+ // treat
// as references, though not API
-
- for ( Object o : pool ) {
- if ( o == null)
+
+ for (Object o : pool) {
+ if (o == null)
continue;
-
- if (o instanceof Assoc && ((Assoc)o).tag ==12 ) {
- referTo( ((Assoc)o).b, 0); // Descriptor
- } else if ( o instanceof ClassConstant) {
- String binaryClassName = (String) pool[((ClassConstant)o).cname];
+
+ if (o instanceof Assoc && ((Assoc) o).tag == 12) {
+ referTo(((Assoc) o).b, 0); // Descriptor
+ } else if (o instanceof ClassConstant) {
+ String binaryClassName = (String) pool[((ClassConstant) o).cname];
TypeRef typeRef = analyzer.getTypeRef(binaryClassName);
- referTo( typeRef, 0);
+ referTo(typeRef, 0);
}
}
-
+
/*
* Parse after the constant pool, code thanks to Hans Christian
* Falkenberg
*/
accessx = in.readUnsignedShort(); // access
- if ( Modifier.isPublic(accessx))
+ if (Modifier.isPublic(accessx))
api = new HashSet<PackageRef>();
-
+
int this_class = in.readUnsignedShort();
className = analyzer.getTypeRef((String) pool[intPool[this_class]]);
referTo(className, Modifier.PUBLIC);
-
+
try {
if (cd != null) {
@@ -517,7 +567,7 @@
interfaces = new TypeRef[interfacesCount];
for (int i = 0; i < interfacesCount; i++) {
interfaces[i] = analyzer.getTypeRef((String) pool[intPool[in.readUnsignedShort()]]);
- referTo(interfaces[i],accessx);
+ referTo(interfaces[i], accessx);
}
if (cd != null)
cd.implementsInterfaces(interfaces);
@@ -545,8 +595,8 @@
}
if (cd != null)
cd.field(last = new FieldDef(access_flags, name, pool[descriptor_index].toString()));
-
- referTo( descriptor_index, access_flags);
+
+ referTo(descriptor_index, access_flags);
doAttributes(in, ElementType.FIELD, false, access_flags);
}
@@ -582,7 +632,6 @@
int access_flags = in.readUnsignedShort();
int name_index = in.readUnsignedShort();
int descriptor_index = in.readUnsignedShort();
- referTo(descriptor_index, access_flags);
String name = pool[name_index].toString();
String descriptor = pool[descriptor_index].toString();
if (cd != null) {
@@ -590,6 +639,7 @@
last = mdef;
cd.method(mdef);
}
+ referTo(descriptor_index, access_flags);
if ("<init>".equals(name)) {
doAttributes(in, ElementType.CONSTRUCTOR, crawl, access_flags);
@@ -629,7 +679,9 @@
pool[poolIndex] = intPool[poolIndex];
}
- protected void pool(@SuppressWarnings("unused") Object[] pool, @SuppressWarnings("unused") int[] intPool) {}
+ protected void pool(@SuppressWarnings("unused")
+ Object[] pool, @SuppressWarnings("unused")
+ int[] intPool) {}
/**
* @param in
@@ -753,7 +805,7 @@
*
* @param in
* The stream
- * @param access_flags
+ * @param access_flags
* @throws Exception
*/
private void doAttributes(DataInputStream in, ElementType member, boolean crawl, int access_flags) throws Exception {
@@ -769,7 +821,7 @@
*
* @param in
* the data stream
- * @param access_flags
+ * @param access_flags
* @throws Exception
*/
private void doAttribute(DataInputStream in, ElementType member, boolean crawl, int access_flags) throws Exception {
@@ -901,7 +953,7 @@
* </pre>
*
* @param member
- * @param access_flags
+ * @param access_flags
*/
void doSignature(DataInputStream in, ElementType member, int access_flags) throws IOException {
@@ -1101,7 +1153,7 @@
annotations.add(tr);
if (policy == RetentionPolicy.RUNTIME) {
- referTo(type_index,0);
+ referTo(type_index, 0);
hasRuntimeAnnotations = true;
} else {
hasClassAnnotations = true;
@@ -1149,14 +1201,14 @@
case 'e' : // enum constant
int type_name_index = in.readUnsignedShort();
if (policy == RetentionPolicy.RUNTIME)
- referTo(type_name_index,0);
+ referTo(type_name_index, 0);
int const_name_index = in.readUnsignedShort();
return pool[const_name_index];
case 'c' : // Class
int class_info_index = in.readUnsignedShort();
if (policy == RetentionPolicy.RUNTIME)
- referTo(class_info_index,0);
+ referTo(class_info_index, 0);
return pool[class_info_index];
case '@' : // Annotation type
@@ -1192,12 +1244,16 @@
return;
imports.add(packageRef);
-
- if ( api != null && (Modifier.isPublic(modifiers)||Modifier.isProtected(modifiers)))
+
+ if (api != null && (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)))
api.add(packageRef);
+
+ if (cd != null)
+ cd.referTo(typeRef, modifiers);
+
}
-
- void referTo( int index, int modifiers) {
+
+ void referTo(int index, int modifiers) {
String descriptor = (String) pool[index];
parseDescriptor(descriptor, modifiers);
}
@@ -1219,7 +1275,7 @@
* @param rover
* The pointer to start at
*/
-
+
public void parseDescriptor(String descriptor, int modifiers) {
// Some descriptors are weird, they start with a generic
// declaration that contains ':', not sure what they mean ...
@@ -1325,7 +1381,8 @@
// Class Bound?
if (c == 'L' || c == 'T') {
- index = parseReference(descriptor, index, modifiers); // class reference
+ index = parseReference(descriptor, index, modifiers); // class
+ // reference
c = descriptor.charAt(index);
}
@@ -1624,8 +1681,17 @@
}
public Set<PackageRef> getAPIUses() {
- if ( api == null)
+ if (api == null)
return Collections.emptySet();
- return api;
+ return api;
}
+
+ public Clazz.TypeDef getExtends(TypeRef type) {
+ return new TypeDef(type, false);
+ }
+
+ public Clazz.TypeDef getImplements(TypeRef type) {
+ return new TypeDef(type, true);
+ }
+
}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
index b6a6087..f8474f4 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
@@ -9,7 +9,6 @@
import aQute.lib.collections.*;
import aQute.lib.io.*;
-import aQute.libg.sed.*;
/**
* Provide a macro processor. This processor can replace variables in strings
@@ -21,7 +20,7 @@
* Remove largest suffix pattern. ${parameter#word} Remove smallest prefix
* pattern. ${parameter##word} Remove largest prefix pattern.
*/
-public class Macro implements Replacer {
+public class Macro {
Processor domain;
Object targets[];
boolean flattening;
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
index 322a2e8..9bf8481 100644
--- a/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
+++ b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
@@ -23,6 +23,12 @@
this.valueClass = valueClass;
}
+ public MultiMap(Map<K,List<V>> other) {
+ this();
+ for ( java.util.Map.Entry<K,List<V>> e : other.entrySet()) {
+ addAll(e.getKey(), e.getValue());
+ }
+ }
public MultiMap(MultiMap<K,V> other) {
keyClass = other.keyClass;
valueClass = other.valueClass;
@@ -163,4 +169,5 @@
return inverted;
}
+
}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
index 4f2cce3..8d65141 100644
--- a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
@@ -2,7 +2,7 @@
import java.util.*;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
public interface CommandLineMessages extends Messages {
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java
index d2ca832..17191f8 100644
--- a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java
@@ -3,9 +3,8 @@
import java.lang.reflect.*;
import java.util.*;
-import aQute.libg.reporter.Messages.ERROR;
-import aQute.libg.reporter.Messages.WARNING;
import aQute.service.reporter.*;
+import aQute.service.reporter.Messages.*;
import aQute.service.reporter.Reporter.SetLocation;
public class ReporterMessages {
diff --git a/bundleplugin/src/main/java/aQute/service/reporter/Messages.java b/bundleplugin/src/main/java/aQute/service/reporter/Messages.java
new file mode 100644
index 0000000..e4b589e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/service/reporter/Messages.java
@@ -0,0 +1,14 @@
+package aQute.service.reporter;
+
+
+
+public interface Messages {
+ static public interface ERROR extends Reporter.SetLocation {}
+
+ static public interface WARNING extends Reporter.SetLocation {}
+
+ ERROR NoSuchFile_(Object r);
+
+ ERROR Unexpected_Error_(String context, Exception e);
+
+}