diff --git a/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/processor/EcoreProcessor.java b/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/processor/EcoreProcessor.java
index 05ab531967..b49af582f8 100644
--- a/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/processor/EcoreProcessor.java
+++ b/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/processor/EcoreProcessor.java
@@ -26,7 +26,9 @@
import org.eclipse.emf.ecore.EStructuralFeature;
import java.util.ArrayDeque;
+import java.util.Arrays;
import java.util.Deque;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
@@ -112,15 +114,29 @@ public void onReference(BasicReference reference) {
// Checks that the reference is well a reference
if (EReference.class.isInstance(feature)) {
EReference eReference = EReference.class.cast(feature);
- reference.isContainment(eReference.isContainment());
- reference.isMany(eReference.isMany());
- EClass referenceType = eReference.getEReferenceType();
- reference.metaclassReference(new BasicMetaclass(
- BasicNamespace.Registry.getInstance().getFromUri(referenceType.getEPackage().getNsURI()),
- referenceType.getName()));
+ AtomicInteger index = new AtomicInteger();
- notifyReference(reference);
+ Arrays.stream(reference.idReference().value().split(" "))
+ .map(String::trim)
+ .filter(s -> !s.isEmpty())
+ .map(s -> {
+ BasicReference newReference = new BasicReference(reference.name());
+ newReference.id(reference.id());
+
+ newReference.index(eReference.isMany() && !eReference.isContainment() ? index.getAndIncrement() : -1);
+ newReference.idReference(BasicId.original(s));
+ newReference.isContainment(eReference.isContainment());
+ newReference.isMany(eReference.isMany());
+
+ EClass referenceType = eReference.getEReferenceType();
+ newReference.metaclassReference(new BasicMetaclass(
+ BasicNamespace.Registry.getInstance().getFromUri(referenceType.getEPackage().getNsURI()),
+ referenceType.getName()));
+
+ return newReference;
+ })
+ .forEach(this::notifyReference);
}
// Otherwise redirect to the attribute handler
diff --git a/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/reader/AbstractXmiStreamReader.java b/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/reader/AbstractXmiStreamReader.java
index d5d588cb9a..486727d252 100644
--- a/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/reader/AbstractXmiStreamReader.java
+++ b/neoemf-io/src/main/java/fr/inria/atlanmod/neoemf/io/reader/AbstractXmiStreamReader.java
@@ -24,14 +24,12 @@
import fr.inria.atlanmod.neoemf.util.log.Log;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -46,26 +44,12 @@
@ParametersAreNonnullByDefault
public abstract class AbstractXmiStreamReader extends AbstractStreamReader {
- /**
- * Regular expression of an attribute containing one or several references.
- */
- @RegEx
- private static final String REGEX_REFERENCE = "(/{1,2}@\\w+(\\.\\d+)?[ ]?)+";
-
/**
* Regular expression of a prefixed value.
*/
@RegEx
private static final String REGEX_PREFIXED_VALUE = "(\\w+):(\\w+)";
- /**
- * Pattern of an attribute containing one or several references (XPath reference). Multiple references must be
- * separated by a space.
- *
- * Example of recognized strings : {@code "//@<name1>.<index1>/@<name2>"}
- */
- private static final Pattern PATTERN_REFERENCE = Pattern.compile(REGEX_REFERENCE, Pattern.UNICODE_CASE);
-
/**
* Pattern of a prefixed value.
*
@@ -192,27 +176,12 @@ protected void readEndElement() {
* @return a list of {@link BasicFeature} that can be empty.
*
* @see #processAttributes(String, String)
- * @see #processReferences(String, Iterable)
*/
@Nonnull
private List processFeatures(@Nullable String prefix, String name, String value) {
- List features;
-
- if (!processSpecialFeature(prefix, name, value)) {
- List references = parseReference(value);
-
- if (!references.isEmpty()) {
- features = processReferences(name, references);
- }
- else {
- features = processAttributes(name, value);
- }
- }
- else {
- features = Collections.emptyList();
- }
-
- return features;
+ return !processSpecialFeature(prefix, name, value)
+ ? processAttributes(name, value)
+ : Collections.emptyList();
}
/**
@@ -264,43 +233,6 @@ else if (Objects.equals(XmiConstants.NAME, name)) {
return isSpecialFeature;
}
- /**
- * Returns a list of {@link String} representing XPath references, or {@code null} if the {@code value} does not
- * match with {@link #PATTERN_REFERENCE}.
- *
- * @param value the value to parse
- *
- * @return a list of {@link String} representing XPath references, or {@code null} if the {@code value} does not
- * match with {@link #PATTERN_REFERENCE}
- *
- * @see #PATTERN_REFERENCE
- */
- @Nonnull
- private List parseReference(String value) {
- List references;
-
- if (!value.trim().isEmpty()) {
- references = Arrays.stream(value.split(" "))
- .map(String::trim)
- .filter(s -> !s.isEmpty())
- .collect(Collectors.toList());
-
- boolean isReference = true;
- for (int i = 0; i < references.size() && isReference; i++) {
- isReference = PATTERN_REFERENCE.matcher(references.get(i)).matches();
- }
-
- if (!isReference) {
- references = Collections.emptyList();
- }
- }
- else {
- references = Collections.emptyList();
- }
-
- return references;
- }
-
/**
* Processes an attribute.
*
@@ -322,31 +254,6 @@ private List processAttributes(String name, String value) {
return features;
}
- /**
- * Processes a list of {@code references} and returns a list of {@link BasicReference}.
- *
- * @param name the name of the reference
- * @param references the list that holds the identifier of referenced elements
- *
- * @return a list of {@link BasicReference} from the given {@code references}
- */
- @Nonnull
- private List processReferences(String name, Iterable references) {
- List features = new ArrayList<>();
-
- int index = 0;
- for (String rawReference : references) {
- BasicReference ref = new BasicReference(name);
- ref.index(index);
- ref.idReference(BasicId.generated(rawReference));
-
- features.add(ref);
- index++;
- }
-
- return features;
- }
-
/**
* Processes a metaclass attribute from the {@code prefixedValue}, and defines is as the metaclass of the given
* {@code element}.
diff --git a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/AbstractInputTest.java b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/AbstractInputTest.java
index c962673df7..1748d4b6ec 100644
--- a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/AbstractInputTest.java
+++ b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/AbstractInputTest.java
@@ -12,6 +12,7 @@
package fr.inria.atlanmod.neoemf.io;
import fr.inria.atlanmod.neoemf.AbstractTest;
+import fr.inria.atlanmod.neoemf.Tags;
import fr.inria.atlanmod.neoemf.io.mock.DummyElement;
import fr.inria.atlanmod.neoemf.io.mock.DummyWriter;
import fr.inria.atlanmod.neoemf.io.processor.CounterProcessor;
@@ -30,19 +31,59 @@
import org.eclipse.emf.common.util.URI;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.annotation.Nonnull;
import static fr.inria.atlanmod.neoemf.util.Preconditions.checkArgument;
import static fr.inria.atlanmod.neoemf.util.Preconditions.checkNotNull;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
public abstract class AbstractInputTest extends AbstractTest {
+ /**
+ * A map that holds the mapping between an XPath and its {@code xmi:id} value.
+ */
+ private static final Map MAPPING = new HashMap<>();
+
+ static {
+ MAPPING.put("/@Model.0", "_PYE3oE0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@orphanTypes.5", "_PZgbAk0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@orphanTypes.9", "_PZgbBk0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@ownedElements.0", "_PYNagE0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0", "_PYOooU0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0", "_PYOook0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@modifier.0", "_PYUIME0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@returnType.0", "_PYWkdU0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2", "_PYXLgE0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2/@modifier.0", "_PYXLg00VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.3", "_PYXLh00VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.1/@bodyDeclarations.5/@returnType.0", "_PZAExk0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@ownedElements.1", "_PZKcwE0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@ownedElements.1/@ownedPackages.1", "_PZOuME0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@ownedElements.2/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0", "_PZbijE0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@compilationUnits.0", "_PZhpIE0VEeeM143ZRH6p9g");
+
+ MAPPING.put("/@Model.0/@compilationUnits.1", "_PZhpOE0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@compilationUnits.1/@imports.1", "_PZhpOk0VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@compilationUnits.1/@imports.2", "_PZhpO00VEeeM143ZRH6p9g");
+ MAPPING.put("/@Model.0/@compilationUnits.1/@imports.10", "_PZiQNE0VEeeM143ZRH6p9g");
+ }
+
/**
* The root element of the read file.
*/
@@ -71,8 +112,7 @@ public static DummyElement childFrom(DummyElement root, int... indices) {
@BeforeClass
public static void registerPackages() {
- IOResourceManager.registerPackage("java", "http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
- IOResourceManager.registerPackage("uml", "http://schema.omg.org/spec/UML/2.1");
+ IOResourceManager.registerPackage("java");
}
@Before
@@ -82,8 +122,8 @@ public void readResource() throws IOException {
Processor processor = new DirectWriteProcessor(writer);
processor = new CounterProcessor(processor);
processor = new TimerProcessor(processor);
- processor = new EcoreProcessor(processor);
processor = new XPathProcessor(processor);
+ processor = new EcoreProcessor(processor);
new XmiStreamReader(processor).read(new URL(getSample().toString()).openStream());
@@ -98,6 +138,26 @@ public void readResource() throws IOException {
@Nonnull
protected abstract URI getSample();
+ /**
+ * Checks whether this test-case use {@code xmi:id} instead of XPath as references.
+ *
+ * @return {@code true} if this test-case use {@code xmi:id} instead of XPath as references
+ */
+ protected abstract boolean useId();
+
+ /**
+ * Retrieves the identifier of the given {@code path} if {@link #useId()} is {@code true}.
+ *
+ * @param path the path to retrieve
+ *
+ * @return the identifier
+ *
+ * @see #useId()
+ */
+ protected String getId(String path) {
+ return useId() ? MAPPING.get(path) : path;
+ }
+
/**
* Checks that the {@code element} has the given arguments.
*
@@ -152,9 +212,230 @@ protected void assertValidReference(BasicReference reference, String name, Strin
* @param value the expected value
* @param index the expected index
*/
- protected void assertValidAttribute(BasicAttribute attribute, String name, Object value, int index) {
+ protected void assertValidAttribute(BasicAttribute attribute, String name, String value, int index) {
assertThat(attribute.name()).isEqualTo(name);
assertThat(attribute.value()).isEqualTo(value);
assertThat(attribute.index()).isEqualTo(index);
}
+
+ /**
+ * Check that the elements and their children are properly processed.
+ */
+ @Test
+ @Category(Tags.IOTests.class)
+ public void testElementsAndChildren() {
+ DummyElement o;
+ DummyElement child;
+
+ assertValidElement(root, getId("/@Model.0"), "Model", "fr.inria.atlanmod.kyanos.tests", 19);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
+ o = childFrom(root, 0, 0, 0, 0, 0, 0);
+ assertValidElement(o, getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0"), "ownedElements", "TestCreateResource", 7);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
+ child = childFrom(o, 0);
+ assertValidElement(child, getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@modifier.0"), "modifier", null, 0);
+
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
+ child = childFrom(o, 3);
+ assertValidElement(child, getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2"), "bodyDeclarations", "tearDownAfterClass", 5);
+ }
+
+ //@Model/@ownedElements.1
+ o = childFrom(root, 1);
+ assertValidElement(o, getId("/@Model.0/@ownedElements.1"), "ownedElements", "java", 5);
+
+ //@Model/@orphanTypes.5
+ o = childFrom(root, 8);
+ assertValidElement(o, getId("/@Model.0/@orphanTypes.5"), "orphanTypes", "void", 0);
+
+ //@Model/@compilationUnits.1
+ o = childFrom(root, 17);
+ assertValidElement(o, getId("/@Model.0/@compilationUnits.1"), "compilationUnits", "TestXmi.java", 16);
+ {
+ //@Model/@compilationUnits.1/@imports.2
+ child = childFrom(o, 2);
+ assertValidElement(child, getId("/@Model.0/@compilationUnits.1/@imports.2"), "imports", null, 0);
+ }
+ }
+ }
+
+ /**
+ * Check that the XPath references are properly processed.
+ */
+ @Test
+ @Category(Tags.IOTests.class)
+ public void testReferences() {
+ DummyElement o;
+ DummyElement child;
+
+ List references;
+
+ references = root.references();
+ assertThat(references).hasSize(19);
+ assertValidReference(references.get(0), "ownedElements", getId("/@Model.0/@ownedElements.0"), -1, true, true);
+ assertValidReference(references.get(12), "orphanTypes", getId("/@Model.0/@orphanTypes.9"), -1, true, true);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
+ o = childFrom(root, 0, 0, 0, 0, 0, 0);
+ references = o.references();
+ assertThat(references).hasSize(8);
+ assertValidReference(references.get(0), "originalCompilationUnit", getId("/@Model.0/@compilationUnits.0"), -1, false, false);
+ assertValidReference(references.get(5), "bodyDeclarations", getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.3"), -1, true, true);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
+ child = childFrom(o, 0);
+ assertThat(child.references()).isEmpty();
+
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
+ child = childFrom(o, 3);
+ references = child.references();
+ assertThat(references).hasSize(6);
+ assertValidReference(references.get(0), "originalCompilationUnit", getId("/@Model.0/@compilationUnits.0"), -1, false, false);
+ assertValidReference(references.get(2), "modifier", getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2/@modifier.0"), -1, false, true);
+ }
+
+ //@Model/@ownedElements.1
+ o = childFrom(root, 1);
+ references = o.references();
+ assertThat(references).hasSize(5);
+ assertValidReference(references.get(1), "ownedPackages", getId("/@Model.0/@ownedElements.1/@ownedPackages.1"), -1, true, true);
+
+ //@Model/@orphanTypes.5
+ o = childFrom(root, 8);
+ references = o.references();
+
+ assertThat(references).hasSize(12);
+ assertValidReference(references.get(0), "usagesInTypeAccess", getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@returnType.0"), 0, true, false);
+ assertValidReference(references.get(9), "usagesInTypeAccess", getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.1/@bodyDeclarations.5/@returnType.0"), 9, true, false);
+
+ //@Model/@compilationUnits.1
+ o = childFrom(root, 17);
+ references = o.references();
+ assertThat(references).hasSize(18);
+ assertValidReference(references.get(0), "package", getId("/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0"), -1, false, false);
+ assertValidReference(references.get(3), "imports", getId("/@Model.0/@compilationUnits.1/@imports.1"), -1, true, true);
+ assertValidReference(references.get(12), "imports", getId("/@Model.0/@compilationUnits.1/@imports.10"), -1, true, true);
+ {
+ //@Model/@compilationUnits.1/@imports.2
+ child = childFrom(o, 2);
+ references = child.references();
+ assertThat(references).hasSize(2);
+ assertValidReference(references.get(0), "originalCompilationUnit", getId("/@Model.0/@compilationUnits.1"), -1, false, false);
+ assertValidReference(references.get(1), "importedElement", getId("/@Model.0/@ownedElements.2/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0"), -1, false, false);
+ }
+ }
+ }
+
+ /**
+ * Check that the attributes are properly processed.
+ */
+ @Test
+ @Category(Tags.IOTests.class)
+ public void testAttributes() {
+ DummyElement o;
+ DummyElement child;
+
+ List attributes;
+
+ attributes = root.attributes();
+ assertThat(attributes).isEmpty(); // Assert that 'xmi:version' and 'xmlns' don't exist
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
+ o = childFrom(root, 0, 0, 0, 0, 0, 0);
+ attributes = o.attributes();
+ assertThat(attributes).isEmpty();
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
+ child = childFrom(o, 0);
+ attributes = child.attributes();
+ assertThat(attributes).hasSize(1);
+ assertValidAttribute(attributes.get(0), "visibility", "public", 0);
+
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
+ child = childFrom(o, 3);
+ attributes = child.attributes();
+ assertThat(attributes).isEmpty();
+ }
+
+ //@Model/@ownedElements.1
+ o = childFrom(root, 1);
+ attributes = o.attributes();
+ assertThat(attributes).hasSize(1);
+ assertValidAttribute(attributes.get(0), "proxy", "true", 0);
+
+ //@Model/@orphanTypes.5
+ o = childFrom(root, 8);
+ attributes = o.attributes();
+ assertThat(attributes).isEmpty();
+
+ //@Model/@compilationUnits.1
+ o = childFrom(root, 17);
+ attributes = o.attributes();
+ assertThat(attributes).hasSize(1);
+ assertValidAttribute(attributes.get(0), "originalFilePath", "C:\\Eclipse\\eclipse-SDK-4.3.1-win32-x86_64-Blue\\eclipse\\workspace\\fr.inria.atlanmod.kyanos.tests\\src\\fr\\inria\\atlanmod\\kyanos\\tests\\TestXmi.java", 0);
+ {
+ //@Model/@compilationUnits.1/@imports.2
+ child = childFrom(o, 2);
+ assertThat(child.attributes()).isEmpty();
+ }
+ }
+ }
+
+ /**
+ * Check that the metaclasses ('xsi:type' or 'xmi:type') are properly processed.
+ */
+ @Test
+ @Category(Tags.IOTests.class)
+ public void testMetaClasses() {
+ DummyElement o;
+ DummyElement child;
+
+ BasicNamespace ns = root.ns();
+ assertValidMetaClass(root.metaClass(), "Model", ns);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
+ o = childFrom(root, 0, 0, 0, 0, 0, 0);
+ assertValidMetaClass(o.metaClass(), "ClassDeclaration", ns);
+ {
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
+ child = childFrom(o, 0);
+ assertValidMetaClass(child.metaClass(), "Modifier", ns);
+
+ //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
+ child = childFrom(o, 3);
+ assertValidMetaClass(child.metaClass(), "MethodDeclaration", ns);
+ }
+
+ //@Model/@ownedElements.1
+ o = childFrom(root, 1);
+ assertValidMetaClass(o.metaClass(), "Package", ns);
+
+ //@Model/@orphanTypes.5
+ o = childFrom(root, 8);
+ assertValidMetaClass(o.metaClass(), "PrimitiveTypeVoid", ns);
+
+ //@Model/@compilationUnits.1
+ o = childFrom(root, 17);
+ assertValidMetaClass(o.metaClass(), "CompilationUnit", ns);
+ {
+ //@Model/@compilationUnits.1/@imports.2
+ child = childFrom(o, 2);
+ assertValidMetaClass(child.metaClass(), "ImportDeclaration", ns);
+ }
+ }
+ }
+
+ /**
+ * Check if the reader stop its execution if it hasn't any handler.
+ */
+ @Test
+ @Category(Tags.IOTests.class)
+ public void testReaderWithoutHandler() {
+ //noinspection ConstantConditions
+ assertThat(
+ catchThrowable(() -> new XmiStreamReader(null).read(null))
+ ).isInstanceOf(NullPointerException.class);
+ }
}
diff --git a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderStandardTest.java b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderStandardTest.java
index b60cb987ca..579416e7ff 100644
--- a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderStandardTest.java
+++ b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderStandardTest.java
@@ -11,25 +11,12 @@
package fr.inria.atlanmod.neoemf.io;
-import fr.inria.atlanmod.neoemf.Tags;
-import fr.inria.atlanmod.neoemf.io.mock.DummyElement;
-import fr.inria.atlanmod.neoemf.io.reader.XmiStreamReader;
-import fr.inria.atlanmod.neoemf.io.structure.BasicAttribute;
-import fr.inria.atlanmod.neoemf.io.structure.BasicNamespace;
-import fr.inria.atlanmod.neoemf.io.structure.BasicReference;
import fr.inria.atlanmod.neoemf.io.util.IOResourceManager;
import org.eclipse.emf.common.util.URI;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import java.util.List;
import javax.annotation.Nonnull;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.catchThrowable;
-
public class XmiReaderStandardTest extends AbstractInputTest {
@Nonnull
@@ -38,223 +25,8 @@ protected URI getSample() {
return IOResourceManager.xmiStandard();
}
- /**
- * Check that the elements and their children are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testElementsAndChildren() {
- DummyElement o;
- DummyElement child;
-
- assertValidElement(root, "/@Model.0", "Model", "fr.inria.atlanmod.kyanos.tests", 19);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- assertValidElement(o, "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0", "ownedElements", "TestCreateResource", 7);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- child = childFrom(o, 0);
- assertValidElement(child, "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@modifier.0", "modifier", null, 0);
-
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- assertValidElement(child, "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2", "bodyDeclarations", "tearDownAfterClass", 5);
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- assertValidElement(o, "/@Model.0/@ownedElements.1", "ownedElements", "java", 5);
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- assertValidElement(o, "/@Model.0/@orphanTypes.5", "orphanTypes", "void", 0);
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- assertValidElement(o, "/@Model.0/@compilationUnits.1", "compilationUnits", "TestXmi.java", 16);
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- assertValidElement(child, "/@Model.0/@compilationUnits.1/@imports.2", "imports", null, 0);
- }
- }
- }
-
- /**
- * Check that the attributes are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testAttributes() {
- DummyElement o;
- DummyElement child;
-
- List attributeList;
-
- attributeList = root.attributes();
- assertThat(attributeList).isEmpty(); // Assert that 'xmi:version' and 'xmlns' don't exist
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- attributeList = o.attributes();
- assertThat(attributeList).isEmpty();
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- child = childFrom(o, 0);
- attributeList = child.attributes();
- assertThat(attributeList).hasSize(1);
- assertValidAttribute(attributeList.get(0), "visibility", "public", 0);
-
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- attributeList = child.attributes();
- assertThat(attributeList).isEmpty();
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- attributeList = o.attributes();
- assertThat(attributeList).hasSize(1);
- assertValidAttribute(attributeList.get(0), "proxy", "true", 0);
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- attributeList = o.attributes();
- assertThat(attributeList).isEmpty();
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- attributeList = o.attributes();
- assertThat(attributeList).hasSize(1);
- assertValidAttribute(attributeList.get(0), "originalFilePath", "C:\\Eclipse\\eclipse-SDK-4.3.1-win32-x86_64-Blue\\eclipse\\workspace\\fr.inria.atlanmod.kyanos.tests\\src\\fr\\inria\\atlanmod\\kyanos\\tests\\TestXmi.java", 0);
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- assertThat(child.attributes()).isEmpty();
- }
- }
- }
-
- /**
- * Check that the XPath references are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testReferences() {
- DummyElement o;
- DummyElement child;
-
- List referenceList;
-
- referenceList = root.references();
- assertThat(referenceList).hasSize(19); // Now contains containment
- assertValidReference(referenceList.get(0), "ownedElements", "/@Model.0/@ownedElements.0", -1, true, true);
- assertValidReference(referenceList.get(12), "orphanTypes", "/@Model.0/@orphanTypes.9", -1, true, true);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- referenceList = o.references();
- assertThat(referenceList).hasSize(8); // Now contains containment
- assertValidReference(referenceList.get(0), "originalCompilationUnit", "/@Model.0/@compilationUnits.0", 0, false, false);
- assertValidReference(referenceList.get(5), "bodyDeclarations", "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.3", -1, true, true);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- child = childFrom(o, 0);
- assertThat(child.references()).isEmpty();
-
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- referenceList = child.references();
- assertThat(referenceList).hasSize(6); // Now contains containment
- assertValidReference(referenceList.get(0), "originalCompilationUnit", "/@Model.0/@compilationUnits.0", 0, false, false);
- assertValidReference(referenceList.get(2), "modifier", "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.2/@modifier.0", -1, false, true);
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- referenceList = o.references();
- assertThat(referenceList).hasSize(5); // Now contains containment
- assertValidReference(referenceList.get(1), "ownedPackages", "/@Model.0/@ownedElements.1/@ownedPackages.1", -1, true, true);
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- referenceList = o.references();
- assertThat(referenceList).hasSize(12);
- assertValidReference(referenceList.get(0), "usagesInTypeAccess", "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@returnType.0", 0, true, false);
- assertValidReference(referenceList.get(9), "usagesInTypeAccess", "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.1/@bodyDeclarations.5/@returnType.0", 9, true, false);
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- referenceList = o.references();
- assertThat(referenceList).hasSize(18); // Now contains containment
- assertValidReference(referenceList.get(0), "package", "/@Model.0/@ownedElements.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0", 0, false, false);
- assertValidReference(referenceList.get(3), "imports", "/@Model.0/@compilationUnits.1/@imports.1", -1, true, true);
- assertValidReference(referenceList.get(12), "imports", "/@Model.0/@compilationUnits.1/@imports.10", -1, true, true);
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- referenceList = child.references();
- assertThat(referenceList).hasSize(2);
- assertValidReference(referenceList.get(0), "originalCompilationUnit", "/@Model.0/@compilationUnits.1", 0, false, false);
- assertValidReference(referenceList.get(1), "importedElement", "/@Model.0/@ownedElements.2/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedPackages.0/@ownedElements.0", 0, false, false);
- }
- }
- }
-
- /**
- * Check that the metaclasses ('xsi:type' or 'xmi:type') are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testMetaClasses() {
- DummyElement o;
- DummyElement child;
-
- BasicNamespace ns = root.ns();
- assertValidMetaClass(root.metaClass(), "Model", ns);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- assertValidMetaClass(o.metaClass(), "ClassDeclaration", ns);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- child = childFrom(o, 0);
- assertValidMetaClass(child.metaClass(), "Modifier", ns);
-
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- assertValidMetaClass(child.metaClass(), "MethodDeclaration", ns);
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- assertValidMetaClass(o.metaClass(), "Package", ns);
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- assertValidMetaClass(o.metaClass(), "PrimitiveTypeVoid", ns);
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- assertValidMetaClass(o.metaClass(), "CompilationUnit", ns);
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- assertValidMetaClass(child.metaClass(), "ImportDeclaration", ns);
- }
- }
- }
-
- /**
- * Check if the reader stop its execution if it hasn't any handler.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testReaderWithoutHandler() {
- //noinspection ConstantConditions
- assertThat(
- catchThrowable(() -> new XmiStreamReader(null).read(null))
- ).isInstanceOf(NullPointerException.class);
+ @Override
+ protected boolean useId() {
+ return false;
}
}
diff --git a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderWithIdTest.java b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderWithIdTest.java
index 29dcc3954c..576c4ee087 100644
--- a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderWithIdTest.java
+++ b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/XmiReaderWithIdTest.java
@@ -11,23 +11,12 @@
package fr.inria.atlanmod.neoemf.io;
-import fr.inria.atlanmod.neoemf.Tags;
-import fr.inria.atlanmod.neoemf.io.mock.DummyElement;
-import fr.inria.atlanmod.neoemf.io.structure.BasicAttribute;
-import fr.inria.atlanmod.neoemf.io.structure.BasicNamespace;
-import fr.inria.atlanmod.neoemf.io.structure.BasicReference;
import fr.inria.atlanmod.neoemf.io.util.IOResourceManager;
import org.eclipse.emf.common.util.URI;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import java.util.List;
import javax.annotation.Nonnull;
-import static org.assertj.core.api.Assertions.assertThat;
-
public class XmiReaderWithIdTest extends AbstractInputTest {
@Nonnull
@@ -36,214 +25,8 @@ protected URI getSample() {
return IOResourceManager.xmiWithId();
}
- /**
- * Check that the elements are properly processed.
- *
- * All elements must have an id and a class name.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testElementsAndChildren() {
- DummyElement o;
- DummyElement child;
-
- assertValidElement(root, "themodel", "Model", "jbk", 5); // Assert that 'xmi' elements don't exist
- {
- //@Model/@packagedElement.0
- o = childFrom(root, 0);
- assertValidElement(o, "0x81_22", "packagedElement", "jbk", 4);
- {
- //@Model/@packagedElement.0/@packagedElement.0/@ownedAttribute
- child = childFrom(o, 0, 4);
- assertValidElement(child, "0x1f402_1", "ownedAttribute", "attribute1", 0);
-
- //@Model/@packagedElement.0/@packagedElement.3
- o = childFrom(o, 3);
- assertValidElement(o, "COLLABORATION_0x1f402_12", "packagedElement", "machine", 3);
- {
- //@Model/@packagedElement.0/@packagedElement.3/ownedBehavior.0
- o = childFrom(o, 0);
- assertValidElement(o, "INTERACTION_0x1f402_12", "ownedBehavior", "machine", 6);
- {
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@fragment/@operand
- child = childFrom(o, 3, 0);
- assertValidElement(child, "OPERAND1_0x1f402_12", "operand", null, 5);
-
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@message.0
- child = childFrom(o, 4);
- assertValidElement(child, "MSG2_0x1f402_12", "message", "answer", 0);
- }
- }
- }
- //@Model/@packagedElement.2
- o = childFrom(root, 2);
- assertValidElement(o, "RECOPEREVT1_0x81_22", "packagedElement", "answer", 0);
- }
- }
-
- /**
- * Check that the attributes are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testAttributes() {
- DummyElement o;
- DummyElement child;
-
- List attributes;
-
- attributes = root.attributes();
- assertThat(attributes).isEmpty();
- {
- //@Model/@packagedElement.0
- o = childFrom(root, 0);
- attributes = o.attributes();
- assertThat(attributes).isEmpty();
- {
- //@Model/@packagedElement.0/@packagedElement.0/@ownedAttribute
- child = childFrom(o, 0, 4);
- attributes = child.attributes();
- assertThat(attributes).hasSize(1);
- assertValidAttribute(attributes.get(0), "visibility", "private", 0);
-
- //@Model/@packagedElement.0/@packagedElement.3
- o = childFrom(o, 3);
- attributes = o.attributes();
- assertThat(attributes).isEmpty();
- {
- //@Model/@packagedElement.0/@packagedElement.3/ownedBehavior.0
- o = childFrom(o, 0);
- attributes = o.attributes();
- assertThat(attributes).isEmpty();
- {
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@fragment/@operand
- child = childFrom(o, 3, 0);
- assertThat(child.attributes()).isEmpty();
-
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@message.0
- child = childFrom(o, 4);
- attributes = child.attributes();
- assertThat(attributes).hasSize(1);
- assertValidAttribute(attributes.get(0), "messageSort", "synchCall", 0);
- }
- }
- }
- //@Model/@packagedElement.2
- o = childFrom(root, 2);
- attributes = o.attributes();
- assertThat(attributes).isEmpty();
- }
- }
-
- /**
- * Check that the {@code xmi:idref} references are properly processed.
- *
- * Containments and inverse references must have been created.
- * References previously detected as attributes, are now well placed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testReferences() {
- DummyElement o;
- DummyElement child;
-
- List references;
-
- references = root.references();
- assertThat(references).hasSize(5); // Now contains containment
- assertValidReference(references.get(0), "packagedElement", "0x81_22", -1, true, true);
- assertValidReference(references.get(2), "packagedElement", "RECOPEREVT1_0x81_22", -1, true, true);
- {
- //@Model/@packagedElement.0
- o = childFrom(root, 0);
- references = o.references();
- assertThat(references).hasSize(4); // Now contains containment
- assertValidReference(references.get(1), "packagedElement", "0x1f582_4", -1, true, true);
- {
- //@Model/@packagedElement.0/@packagedElement.0/@ownedAttribute
- child = childFrom(o, 0, 4);
- references = child.references();
- assertThat(references).hasSize(1);
- assertValidReference(references.get(0), "type", "0x1f582_4", -1, false, false);
-
- //@Model/@packagedElement.0/@packagedElement.3
- o = childFrom(o, 3);
- references = o.references();
- assertThat(references).hasSize(3); // Now contains containment
- assertValidReference(references.get(0), "ownedBehavior", "INTERACTION_0x1f402_12", -1, true, true);
- {
- //@Model/@packagedElement.0/@packagedElement.3/ownedBehavior.0
- o = childFrom(o, 0);
- references = o.references();
- assertThat(references).hasSize(6); // Now contains containment
- assertValidReference(references.get(4), "message", "MSG2_0x1f402_12", -1, true, true);
- {
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@fragment/@operand
- child = childFrom(o, 3, 0);
- references = child.references();
- assertThat(references).hasSize(5); // Now contains containment
- assertValidReference(references.get(2), "fragment", "BEHEXECSPEC2_0x1f402_12", -1, true, true);
-
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@message.0
- child = childFrom(o, 4);
- references = child.references();
- assertThat(references).hasSize(3);
- assertValidReference(references.get(0), "sendEvent", "MSGOCCSPECSEND2_0x1f402_12", 0, false, false); // New reference
- assertValidReference(references.get(1), "receiveEvent", "MSGOCCSPECREC2_0x1f402_12", 0, false, false); // New reference
- assertValidReference(references.get(2), "connector", "CONNECTOR1_2_0x1f402_12", 0, false, false); // New reference
- }
- }
- }
-
- //@Model/@packagedElement.2
- o = childFrom(root, 2);
- references = o.references();
- assertThat(references).hasSize(1);
- assertValidReference(references.get(0), "operation", "0x1f582_2", 0, false, false); // New reference
- }
- }
-
- /**
- * Check that the metaclasses ({@code xsi:type} or {@code xmi:type}) are properly processed.
- */
- @Test
- @Category(Tags.IOTests.class)
- public void testMetaClasses() {
- DummyElement o;
- DummyElement child;
-
- BasicNamespace ns = root.ns();
- assertValidMetaClass(root.metaClass(), "Model", ns);
- {
- //@Model/@packagedElement.0
- o = childFrom(root, 0);
- assertValidMetaClass(o.metaClass(), "Package", ns);
- {
- //@Model/@packagedElement.0/@packagedElement.0/@ownedAttribute
- child = childFrom(o, 0, 4);
- assertValidMetaClass(child.metaClass(), "Property", ns);
-
- //@Model/@packagedElement.0/@packagedElement.3
- o = childFrom(o, 3);
- assertValidMetaClass(o.metaClass(), "Collaboration", ns);
- {
- //@Model/@packagedElement.0/@packagedElement.3/ownedBehavior.0
- o = childFrom(o, 0);
- assertValidMetaClass(o.metaClass(), "Interaction", ns);
- {
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@fragment/@operand
- child = childFrom(o, 3, 0);
- assertValidMetaClass(child.metaClass(), "InteractionOperand", ns);
-
- //@Model/@packagedElement.0/@packagedElement.3/@ownedBehavior.0/@message.0
- child = childFrom(o, 4);
- assertValidMetaClass(child.metaClass(), "Message", ns);
- }
- }
- }
- //@Model/@packagedElement.2
- o = childFrom(root, 2);
- assertValidMetaClass(o.metaClass(), "ReceiveOperationEvent", ns);
- }
+ @Override
+ protected boolean useId() {
+ return true;
}
}
diff --git a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/util/IOResourceManager.java b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/util/IOResourceManager.java
index 248fdf0908..fb4527926a 100644
--- a/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/util/IOResourceManager.java
+++ b/neoemf-io/src/test/java/fr/inria/atlanmod/neoemf/io/util/IOResourceManager.java
@@ -55,9 +55,7 @@ public static URI xmiWithId() {
*
* The targeted Ecore file must be present in the {@code /resources/ecore} directory of this modules.
*/
- public static void registerPackage(String prefix, String uri) {
- EPackage pkg = null;
-
+ public static void registerPackage(String prefix) {
Resource.Factory.Registry.INSTANCE
.getExtensionToFactoryMap()
.put("ecore", new EcoreResourceFactoryImpl());
@@ -71,13 +69,9 @@ public static void registerPackage(String prefix, String uri) {
EObject eObject = r.getContents().get(0);
if (EPackage.class.isInstance(eObject)) {
- pkg = EPackage.class.cast(eObject);
- rs.getPackageRegistry().put(pkg.getNsURI(), pkg);
+ EPackage pkg = checkNotNull(EPackage.class.cast(eObject));
+ EPackage.Registry.INSTANCE.put(pkg.getNsURI(), pkg);
}
-
- checkNotNull(pkg);
-
- EPackage.Registry.INSTANCE.put(uri, pkg);
}
/**
diff --git a/neoemf-io/src/test/resources/ecore/uml.ecore b/neoemf-io/src/test/resources/ecore/uml.ecore
deleted file mode 100644
index 60779b355c..0000000000
--- a/neoemf-io/src/test/resources/ecore/uml.ecore
+++ /dev/null
@@ -1,18448 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/neoemf-io/src/test/resources/xmi/sampleStandard.xmi b/neoemf-io/src/test/resources/xmi/sampleStandard.xmi
index 3532eb72c2..e59e02bb66 100644
--- a/neoemf-io/src/test/resources/xmi/sampleStandard.xmi
+++ b/neoemf-io/src/test/resources/xmi/sampleStandard.xmi
@@ -1,1450 +1,945 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/neoemf-io/src/test/resources/xmi/sampleWithId.xmi b/neoemf-io/src/test/resources/xmi/sampleWithId.xmi
index 23b7cab55a..37e0ede1e6 100644
--- a/neoemf-io/src/test/resources/xmi/sampleWithId.xmi
+++ b/neoemf-io/src/test/resources/xmi/sampleWithId.xmi
@@ -1,78 +1,945 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/AbstractIOTest.java b/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/AbstractIOTest.java
index 22425e5349..551a6a8fbd 100644
--- a/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/AbstractIOTest.java
+++ b/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/AbstractIOTest.java
@@ -18,10 +18,10 @@
import fr.inria.atlanmod.neoemf.io.writer.WriterFactory;
import fr.inria.atlanmod.neoemf.tests.AbstractBackendTest;
import fr.inria.atlanmod.neoemf.util.emf.compare.LazyMatchEngineFactory;
+import fr.inria.atlanmod.neoemf.util.log.Log;
import org.assertj.core.api.SoftAssertions;
import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.EMFCompare;
@@ -29,9 +29,7 @@
import org.eclipse.emf.compare.match.impl.MatchEngineFactoryRegistryImpl;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
import org.eclipse.emf.compare.scope.IComparisonScope;
-import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
@@ -40,47 +38,13 @@
import java.io.IOException;
import java.net.URL;
-import javax.annotation.Nonnull;
-
-import static fr.inria.atlanmod.neoemf.util.Preconditions.checkNotNull;
-import static java.util.Objects.isNull;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.catchThrowable;
-
-/**
- *
- */
public abstract class AbstractIOTest extends AbstractBackendTest {
- /**
- * Retrieves a child element from the {@code root} following the given {@code indices}.
- *
- * @param root the element from which to start the search
- * @param indices the indices of contained elements. The first index represents the index of the element from the
- * root element, the second represents the index of the element from the previous,...
- *
- * @return the object
- */
- @Nonnull
- protected static EObject childFrom(EObject root, int... indices) {
- if (indices.length == 0) {
- throw new IllegalArgumentException("You must define at least one index");
- }
-
- EObject element = root;
- for (int index : indices) {
- element = element.eContents().get(index);
- }
-
- return checkNotNull(element);
- }
-
@BeforeClass
public static void registerPackages() {
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
- IOResourceManager.registerPackage("java", "http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");
- IOResourceManager.registerPackage("uml", "http://schema.omg.org/spec/UML/2.1");
+ IOResourceManager.registerPackage("java");
}
/**
@@ -90,6 +54,8 @@ public static void registerPackages() {
* @param expected the source notifier
*/
protected void assertNotifierAreEqual(Notifier actual, Notifier expected) {
+ Log.info("Comparing models...");
+
IMatchEngine.Factory.Registry matchEngineRegistry = new MatchEngineFactoryRegistryImpl();
matchEngineRegistry.add(new LazyMatchEngineFactory());
@@ -108,94 +74,6 @@ protected void assertNotifierAreEqual(Notifier actual, Notifier expected) {
softly.assertAll();
}
- /**
- * Asserts that the given {@code object} the given {@code name}, {@code size}, and inherit from an
- * {@link org.eclipse.emf.ecore.EClass} named as {@code metaclassName}.
- *
- * @param obj the {@link EObject} to tests
- * @param metaclassName the expected name of the metaclass of the {@code obj}
- * @param size the expected size of the {@code obj}
- * @param name the expected name of the {@code obj}
- */
- protected void assertObjectHas(EObject obj, String metaclassName, int size, String name) {
- assertThat(obj.eClass().getName()).isEqualTo(metaclassName);
- assertThat(obj.eContents()).hasSize(size);
-
- if (isNull(name)) {
- assertThat(
- catchThrowable(() -> obj.eGet(obj.eClass().getEStructuralFeature("name")))
- ).isInstanceOf(NullPointerException.class);
- }
- else {
- assertThat(obj.eGet(obj.eClass().getEStructuralFeature("name"))).isEqualTo(name);
- }
- }
-
- /**
- * Asserts that the {@link EReference} of the {@code obj}, identified by its {@code name}, has the given parameters.
- *
- * @param obj the {@link EObject} to retrieve to {@link EReference}
- * @param name the name of the {@link EReference} to retrieve
- * @param index the index concerned by the test (if {@code many == true})
- * @param referenceClassName the expected name of the metaclass of the referenced {@link EObject}
- * @param referenceName the expected name of the referenced {@link EObject}
- * @param many if the reference must be a multi-valued feature
- * @param containment if the reference must be a containment
- */
- @SuppressWarnings("unchecked") // Unchecked cast: 'Object' to 'EList<...>'
- protected void assertReferenceHas(EObject obj, String name, int index, String referenceClassName, String referenceName, boolean many, boolean containment) {
- EReference reference = EReference.class.cast(obj.eClass().getEStructuralFeature(name));
-
- Object objectReference = obj.eGet(reference);
- EObject eObjectReference;
-
- if (many) {
- EList eObjectList = (EList) objectReference;
- eObjectReference = eObjectList.get(index);
- }
- else {
- eObjectReference = EObject.class.cast(objectReference);
- }
-
- assertThat(eObjectReference.eClass().getName()).isEqualTo(referenceClassName);
-
- if (isNull(referenceName)) {
- try {
- EAttribute attribute = checkNotNull(EAttribute.class.cast(eObjectReference.eClass().getEStructuralFeature("name")));
- assertThat(eObjectReference.eGet(attribute)).isEqualTo(attribute.getDefaultValue());
- }
- catch (NullPointerException expected) {
- // It's not a problem if this happens
- }
- }
- else {
- EAttribute attribute = EAttribute.class.cast(eObjectReference.eClass().getEStructuralFeature("name"));
- assertThat(eObjectReference.eGet(attribute).toString()).isEqualTo(referenceName);
- }
-
- assertThat(reference.isContainment()).isEqualTo(containment);
- assertThat(reference.isMany()).isEqualTo(many);
- }
-
- /**
- * Asserts that the {@link EAttribute} of the {@code obj}, identified by its {@code name}, has the given {@code
- * value}.
- *
- * @param obj the {@link EObject} to retrieve to {@link EAttribute}
- * @param name the name of the {@link EAttribute} to retrieve
- * @param value the expected value of the attribute
- */
- protected void assertAttributeHas(EObject obj, String name, Object value) {
- EAttribute attribute = checkNotNull(EAttribute.class.cast(obj.eClass().getEStructuralFeature(name)));
-
- if (isNull(value)) {
- assertThat(obj.eGet(attribute)).isEqualTo(attribute.getDefaultValue());
- }
- else {
- assertThat(obj.eGet(attribute).toString()).isEqualTo(value);
- }
- }
-
/**
* Loads the {@code uri} with standard EMF.
*
diff --git a/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/ImportTest.java b/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/ImportTest.java
index 7fca335909..4df0fc78cc 100644
--- a/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/ImportTest.java
+++ b/neoemf-tests/src/test/java/fr/inria/atlanmod/neoemf/tests/io/ImportTest.java
@@ -14,6 +14,7 @@
import fr.inria.atlanmod.neoemf.Tags;
import fr.inria.atlanmod.neoemf.io.util.IOResourceManager;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.junit.Ignore;
import org.junit.Test;
@@ -26,131 +27,6 @@
*/
public class ImportTest extends AbstractIOTest {
- /**
- * Check that the elements are properly processed.
- *
- * All elements must have an id and a class name.
- *
- * @throws IOException if an I/O error occur during the loading of models
- */
- @Test
- @Category({Tags.PersistentTests.class, Tags.IOTests.class})
- public void testElementsAndChildren() throws IOException {
- EObject o;
- EObject child;
-
- final EObject root = loadWithNeoEMF(IOResourceManager.xmiStandard());
- assertObjectHas(root, "Model", 19, "fr.inria.atlanmod.kyanos.tests");
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- assertObjectHas(o, "ClassDeclaration", 7, "TestCreateResource");
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- child = childFrom(o, 0);
- assertObjectHas(child, "Modifier", 0, null);
-
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- assertObjectHas(child, "MethodDeclaration", 5, "tearDownAfterClass");
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- assertObjectHas(o, "Package", 5, "java");
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- assertObjectHas(o, "PrimitiveTypeVoid", 0, "void");
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- assertObjectHas(o, "CompilationUnit", 16, "TestXmi.java");
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- assertObjectHas(child, "ImportDeclaration", 0, null);
- }
- }
- }
-
- /**
- * Check that the attributes are properly processed.
- *
- * @throws IOException if an I/O error occur during the loading of models
- */
- @Test
- @Category({Tags.PersistentTests.class, Tags.IOTests.class})
- public void testAttributes() throws IOException {
- EObject o;
-
- final EObject root = loadWithNeoEMF(IOResourceManager.xmiStandard());
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@modifier
- o = childFrom(root, 0, 0, 0, 0, 0, 0, 0);
- assertAttributeHas(o, "visibility", "public");
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- assertAttributeHas(o, "proxy", "true");
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- assertAttributeHas(o, "originalFilePath", "C:\\Eclipse\\eclipse-SDK-4.3.1-win32-x86_64-Blue\\eclipse\\workspace\\fr.inria.atlanmod.kyanos.tests\\src\\fr\\inria\\atlanmod\\kyanos\\tests\\TestXmi.java");
- }
- }
-
- /**
- * Check that the XPath references/id are properly processed.
- *
- * Containment and inverse reference must have been created. References previously detected as attributes, are now
- * well placed.
- *
- * @throws IOException if an I/O error occur during the loading of models
- */
- @Test
- @Category({Tags.PersistentTests.class, Tags.IOTests.class})
- public void testReferences() throws IOException {
- EObject o;
- EObject child;
-
- final EObject root = loadWithNeoEMF(IOResourceManager.xmiStandard());
- assertReferenceHas(root, "ownedElements", 0, "Package", "fr", true, true);
- assertReferenceHas(root, "orphanTypes", 5, "PrimitiveTypeVoid", "void", true, true);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0
- o = childFrom(root, 0, 0, 0, 0, 0, 0);
- assertReferenceHas(o, "originalCompilationUnit", 0, "CompilationUnit", "TestCreateResource.java", false, false);
- assertReferenceHas(o, "bodyDeclarations", 0, "FieldDeclaration", null, true, true);
- {
- //@Model/@ownedElements.0/@ownedPackages[4]/@ownedElements.0/@bodyDeclarations.2
- child = childFrom(o, 3);
- assertReferenceHas(child, "originalCompilationUnit", 0, "CompilationUnit", "TestCreateResource.java", false, false);
- assertReferenceHas(child, "modifier", 0, "Modifier", null, false, true);
- }
-
- //@Model/@ownedElements.1
- o = childFrom(root, 1);
- assertReferenceHas(o, "ownedPackages", 0, "Package", "io", true, true);
-
- //@Model/@orphanTypes.5
- o = childFrom(root, 8);
- assertReferenceHas(o, "usagesInTypeAccess", 0, "TypeAccess", null, true, false);
- assertReferenceHas(o, "usagesInTypeAccess", 9, "TypeAccess", null, true, false);
-
- //@Model/@compilationUnits.1
- o = childFrom(root, 17);
- assertReferenceHas(o, "package", 0, "Package", "tests", false, false);
- assertReferenceHas(o, "imports", 0, "ImportDeclaration", null, true, true);
- {
- //@Model/@compilationUnits.1/@imports.2
- child = childFrom(o, 2);
- assertReferenceHas(child, "originalCompilationUnit", 0, "CompilationUnit", "TestXmi.java", false, false);
- assertReferenceHas(child, "importedElement", 2, "ClassDeclaration", "URI", false, false);
- }
- }
- }
-
/**
* Compares a model read with standard EMF and another read with NeoEMF.
*
@@ -160,9 +36,11 @@ public void testReferences() throws IOException {
*/
@Test
@Category({Tags.PersistentTests.class, Tags.IOTests.class})
- public void testCompare() throws IOException {
- EObject actual = loadWithNeoEMF(IOResourceManager.xmiStandard());
- EObject expected = loadWithEMF(IOResourceManager.xmiStandard());
+ public void testCompareStandard() throws IOException {
+ URI uri = IOResourceManager.xmiStandard();
+
+ EObject actual = loadWithNeoEMF(uri);
+ EObject expected = loadWithEMF(uri);
assertNotifierAreEqual(actual, expected);
}
@@ -178,8 +56,10 @@ public void testCompare() throws IOException {
@Ignore("Incomplete implementation") // FIXME Inverse references don't exist in EMF
@Category({Tags.PersistentTests.class, Tags.IOTests.class})
public void testCompareWithId() throws IOException {
- EObject actual = loadWithNeoEMF(IOResourceManager.xmiWithId());
- EObject expected = loadWithEMF(IOResourceManager.xmiWithId());
+ URI uri = IOResourceManager.xmiWithId();
+
+ EObject actual = loadWithNeoEMF(uri);
+ EObject expected = loadWithEMF(uri);
assertNotifierAreEqual(actual, expected);
}