Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Borkowski2015-05-20 10:41:25 +0000
committerAxel RICHARD2015-06-09 13:43:24 +0000
commitf6103d279ca71758de5a2861e6dd2bb35a3633da (patch)
treeaf8f71651046afe2ce657f03df819e0f89ea9667 /plugins
parent71c2516023c01c4e37892ae50a77e1db47c883d1 (diff)
downloadorg.eclipse.emf.compare-f6103d279ca71758de5a2861e6dd2bb35a3633da.tar.gz
org.eclipse.emf.compare-f6103d279ca71758de5a2861e6dd2bb35a3633da.tar.xz
org.eclipse.emf.compare-f6103d279ca71758de5a2861e6dd2bb35a3633da.zip
[467677] Detection of binary identical resources
Fixes issues regarding the read buffer size used when comparing InputStreams with the ResourceUtil class. The methods now handle arbitrary read buffer sizes. Bug:467677 Change-Id: Ibc3ce27588088065a9c3da82a79b0ee1c7d356c4 Also-by: Alexandra Buzila <abuzila@eclipsesource.com> Also-by: Laurent Delaigue <laurent.delaigue@obeo.fr> Signed-off-by: Michael Borkowski <mborkowski@eclipsesource.com> Signed-off-by: Laurent Delaigue <laurent.delaigue@obeo.fr>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/META-INF/MANIFEST.MF6
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/tests/suite/AllTests.java7
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/LimitedReadingInputStream.java49
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2Test.java162
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2_ReadLimitTest.java147
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3Test.java175
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3_ReadLimitTest.java258
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1279
-rw-r--r--plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2279
-rw-r--r--plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/utils/ResourceUtil.java223
10 files changed, 1467 insertions, 118 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.ide.tests/META-INF/MANIFEST.MF
index a1e5dfb44..1971cd891 100644
--- a/plugins/org.eclipse.emf.compare.ide.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.ide.tests/META-INF/MANIFEST.MF
@@ -10,8 +10,12 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.compare.ide;bundle-version="2.0.1",
org.eclipse.team.core;bundle-version="3.5.0",
org.eclipse.emf.ecore;bundle-version="2.5.0",
- org.eclipse.emf.ecore.xmi;bundle-version="2.5.0"
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.jgit;bundle-version="4.0.0",
+ org.mockito;bundle-version="1.9.5",
+ org.hamcrest;bundle-version="1.1.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-Vendor: %providerName
Bundle-Localization: plugin
+Import-Package: com.google.common.io;version="[11.0.0,16.0.0)"
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/tests/suite/AllTests.java
index 23e6bc3bc..6885ce3e6 100644
--- a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/tests/suite/AllTests.java
@@ -14,12 +14,17 @@ import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import junit.textui.TestRunner;
+import org.eclipse.emf.compare.ide.utils.tests.ResourceUtil_BinaryIdentical2Test;
+import org.eclipse.emf.compare.ide.utils.tests.ResourceUtil_BinaryIdentical2_ReadLimitTest;
+import org.eclipse.emf.compare.ide.utils.tests.ResourceUtil_BinaryIdentical3Test;
+import org.eclipse.emf.compare.ide.utils.tests.ResourceUtil_BinaryIdentical3_ReadLimitTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses({})
+@SuiteClasses({ResourceUtil_BinaryIdentical2Test.class, ResourceUtil_BinaryIdentical2_ReadLimitTest.class,
+ ResourceUtil_BinaryIdentical3Test.class, ResourceUtil_BinaryIdentical3_ReadLimitTest.class })
public class AllTests {
/**
* Launches the test with the given arguments.
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/LimitedReadingInputStream.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/LimitedReadingInputStream.java
new file mode 100644
index 000000000..87ca21b59
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/LimitedReadingInputStream.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Michael Borkowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.utils.tests;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.emf.compare.ide.utils.ResourceUtil;
+
+/**
+ * This class wraps an {@link InputStream} with the purpose of limiting the maximum size a
+ * {@link #read(byte[])} or {@link #read(byte[], int, int)} call will return. This is used to test
+ * functionality of {@link ResourceUtil} and simulating a stream with a limited read buffer size.
+ *
+ * @author Michael Borkowski <mborkowski@eclipsesource.com>
+ */
+public class LimitedReadingInputStream extends InputStream {
+ private final InputStream base;
+
+ private final int limit;
+
+ public LimitedReadingInputStream(InputStream base, int limit) {
+ this.base = base;
+ this.limit = limit;
+ }
+
+ @Override
+ public int read() throws IOException {
+ return base.read();
+ }
+
+ @Override
+ public int read(byte[] buffer) throws IOException {
+ return read(buffer, 0, buffer.length);
+ }
+
+ @Override
+ public int read(byte[] buffer, int off, int len) throws IOException {
+ return super.read(buffer, off, Math.min(len, limit));
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2Test.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2Test.java
new file mode 100644
index 000000000..a357dbd7e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2Test.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandra Buzila - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.utils.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.io.Files;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.compare.ide.utils.ResourceUtil;
+import org.eclipse.jgit.lib.ObjectStream.SmallStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+@SuppressWarnings({"nls", "resource" })
+public class ResourceUtil_BinaryIdentical2Test {
+ File file1, file2;
+
+ IStorage storage1_stream, storage1_smallStream, storage2_stream, storage2_smallStream;
+
+ @Before
+ public void setUp() throws IOException {
+ Bundle bundle = Platform.getBundle("org.eclipse.emf.compare.ide.tests");
+ URL file1Entry = bundle
+ .getEntry("src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1");
+ URL file1URL = FileLocator.resolve(file1Entry);
+ String file1Path = file1URL.getPath();
+ URL file2Entry = bundle
+ .getEntry("src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2");
+ URL file2URL = FileLocator.resolve(file2Entry);
+ String file2Path = file2URL.getPath();
+
+ file1 = new File(file1Path);
+ file2 = new File(file2Path);
+
+ storage1_stream = mockStorage(new FileInputStream(file1));
+ storage1_smallStream = mockStorage(new SmallStream(0, Files.toByteArray(file1)));
+ storage2_stream = mockStorage(new FileInputStream(file2));
+ storage2_smallStream = mockStorage(new SmallStream(0, Files.toByteArray(file2)));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData() throws IOException {
+ assertTrue(ResourceUtil.binaryIdentical(storage1_stream, storage1_smallStream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_Stream_Stream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_stream, storage2_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_Stream_SmallStream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_stream, storage2_smallStream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_SmallStream_Stream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_SmallStream_SmallStream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2_smallStream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData_differentBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file1, 8192));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1, storage2));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData_sameBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file1, 16384));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1, storage2));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_sameBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file2, 16384));
+
+ assertFalse(ResourceUtil.binaryIdentical(storage1, storage2));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_mixedTypes() throws IOException {
+ IStorage storage1Buffered = mockStorage(buffer(file1, 1024));
+ IStorage storage2Buffered = mockStorage(buffer(file2, 1024));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1_smallStream, storage1Buffered));
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2Buffered));
+ }
+
+ @Test
+ public void testFalseIfCoreException() throws Exception {
+ InputStream input1 = new ByteArrayInputStream(new byte[] {12, 64, });
+ IStorage storage2 = mock(IStorage.class);
+ when(storage2.getContents()).thenThrow(new CoreException(Status.CANCEL_STATUS));
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), storage2));
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testFalseIfIOException() throws IOException {
+ InputStream input1 = new ByteArrayInputStream(new byte[] {12, 64, });
+ InputStream input2 = mock(InputStream.class);
+ when(input2.read(any(byte[].class), anyInt(), anyInt())).thenThrow(new IOException());
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ private InputStream buffer(File file, int bufferSize) throws IOException {
+ return new BufferedInputStream(new ByteArrayInputStream(Files.toByteArray(file)), bufferSize);
+ }
+
+ @SuppressWarnings("boxing")
+ private static IStorage mockStorage(InputStream input) {
+ try {
+ IStorage mockStorage = mock(IStorage.class);
+ when(mockStorage.getContents()).thenReturn(input);
+ when(mockStorage.isReadOnly()).thenReturn(true);
+ return mockStorage;
+ } catch (CoreException cEx) {
+ // this is merely a checked exception of mockStorage.getContents() and will never happen since we
+ // use mockito
+ return null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2_ReadLimitTest.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2_ReadLimitTest.java
new file mode 100644
index 000000000..4c8c0b57b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical2_ReadLimitTest.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandra Buzila - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.utils.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.compare.ide.utils.ResourceUtil;
+import org.junit.Test;
+
+@SuppressWarnings({"resource" })
+public class ResourceUtil_BinaryIdentical2_ReadLimitTest {
+ byte[] data_A = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46, 74 };
+
+ byte[] data_B = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46, 0 };
+
+ byte[] data_C = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46 };
+
+ @Test
+ public void testSameData_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+
+ assertTrue(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testDifferentData_sameLength_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_B);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_C);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_rightSmaller() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+
+ assertTrue(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_leftSmaller() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 7);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+
+ assertTrue(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testDifferentData_sameLength_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_B);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_C);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testZeroData_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput2 = new ByteArrayInputStream(new byte[0]);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+
+ assertTrue(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @Test
+ public void testZeroData_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput2 = new ByteArrayInputStream(new byte[0]);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+
+ assertTrue(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2)));
+ }
+
+ @SuppressWarnings("boxing")
+ private static IStorage mockStorage(InputStream input) {
+ try {
+ IStorage mockStorage = mock(IStorage.class);
+ when(mockStorage.getContents()).thenReturn(input);
+ when(mockStorage.isReadOnly()).thenReturn(true);
+ return mockStorage;
+ } catch (CoreException cEx) {
+ // this is merely a checked exception of mockStorage.getContents() and will never happen since we
+ // use mockito
+ return null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3Test.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3Test.java
new file mode 100644
index 000000000..bdbebc268
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3Test.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandra Buzila - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.utils.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.io.Files;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.compare.ide.utils.ResourceUtil;
+import org.eclipse.jgit.lib.ObjectStream.SmallStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+@SuppressWarnings({"nls", "resource" })
+public class ResourceUtil_BinaryIdentical3Test {
+ File file1, file2;
+
+ IStorage storage1_stream, storage1_stream2, storage1_smallStream, storage2_stream, storage2_smallStream;
+
+ @Before
+ public void setUp() throws IOException {
+ Bundle bundle = Platform.getBundle("org.eclipse.emf.compare.ide.tests");
+ URL file1Entry = bundle
+ .getEntry("src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1");
+ URL file1URL = FileLocator.resolve(file1Entry);
+ String file1Path = file1URL.getPath();
+ URL file2Entry = bundle
+ .getEntry("src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2");
+ URL file2URL = FileLocator.resolve(file2Entry);
+ String file2Path = file2URL.getPath();
+
+ file1 = new File(file1Path);
+ file2 = new File(file2Path);
+
+ storage1_stream = mockStorage(new FileInputStream(file1));
+ storage1_stream2 = mockStorage(new FileInputStream(file1));
+ storage1_smallStream = mockStorage(new SmallStream(0, Files.toByteArray(file1)));
+ storage2_stream = mockStorage(new FileInputStream(file2));
+ storage2_smallStream = mockStorage(new SmallStream(0, Files.toByteArray(file2)));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData() throws IOException {
+ assertTrue(ResourceUtil.binaryIdentical(storage1_stream, storage1_smallStream, storage1_stream2));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_Stream_Stream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_stream, storage2_stream, storage1_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_Stream_SmallStream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_stream, storage2_smallStream, storage1_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_SmallStream_Stream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2_stream, storage1_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_SmallStream_SmallStream() {
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2_smallStream, storage1_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_reordered() {
+ assertFalse(ResourceUtil.binaryIdentical(storage2_stream, storage2_smallStream, storage1_stream));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData_differentBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file1, 8192));
+ IStorage storage3 = mockStorage(buffer(file1, 1021));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1, storage2, storage3));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_sameData_sameBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file1, 16384));
+ IStorage storage3 = mockStorage(buffer(file1, 16384));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1, storage2, storage3));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_differentData_sameBuffers() throws IOException {
+ IStorage storage1 = mockStorage(buffer(file1, 16384));
+ IStorage storage2 = mockStorage(buffer(file2, 16384));
+ IStorage storage3 = mockStorage(buffer(file2, 16384));
+
+ assertFalse(ResourceUtil.binaryIdentical(storage1, storage2, storage3));
+ }
+
+ @Test
+ public void testBinaryIdentical_2_mixedTypes() throws IOException {
+ IStorage storage1Buffered = mockStorage(buffer(file1, 1024));
+ IStorage storage1Buffered2 = mockStorage(buffer(file1, 1024));
+ IStorage storage2Buffered = mockStorage(buffer(file2, 1024));
+
+ assertTrue(ResourceUtil.binaryIdentical(storage1Buffered2, storage1_smallStream, storage1Buffered));
+ assertFalse(ResourceUtil.binaryIdentical(storage1_smallStream, storage2Buffered, storage1Buffered));
+ }
+
+ @Test
+ public void testFalseIfCoreException() throws Exception {
+ InputStream input1 = new ByteArrayInputStream(new byte[] {12, 64, });
+ InputStream input3 = new ByteArrayInputStream(new byte[] {12, 64, });
+ IStorage storage2 = mock(IStorage.class);
+ when(storage2.getContents()).thenThrow(new CoreException(Status.CANCEL_STATUS));
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), storage2, mockStorage(input3)));
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testFalseIfIOException() throws IOException {
+ InputStream input1 = new ByteArrayInputStream(new byte[] {12, 64, });
+ InputStream input3 = new ByteArrayInputStream(new byte[] {12, 64, });
+ InputStream input2 = mock(InputStream.class);
+ when(input2.read(any(byte[].class), anyInt(), anyInt())).thenThrow(new IOException());
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ private InputStream buffer(File file, int bufferSize) throws IOException {
+ return new BufferedInputStream(new ByteArrayInputStream(Files.toByteArray(file)), bufferSize);
+ }
+
+ @SuppressWarnings("boxing")
+ private static IStorage mockStorage(InputStream input) {
+ try {
+ IStorage mockStorage = mock(IStorage.class);
+ when(mockStorage.getContents()).thenReturn(input);
+ when(mockStorage.isReadOnly()).thenReturn(true);
+ return mockStorage;
+ } catch (CoreException cEx) {
+ // this is merely a checked exception of mockStorage.getContents() and will never happen since we
+ // use mockito
+ return null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3_ReadLimitTest.java b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3_ReadLimitTest.java
new file mode 100644
index 000000000..7c71ac483
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/ResourceUtil_BinaryIdentical3_ReadLimitTest.java
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource Muenchen GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandra Buzila - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.utils.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.compare.ide.utils.ResourceUtil;
+import org.junit.Test;
+
+@SuppressWarnings({"resource" })
+public class ResourceUtil_BinaryIdentical3_ReadLimitTest {
+ byte[] data_A = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46, 74 };
+
+ byte[] data_B = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46, 0 };
+
+ byte[] data_C = {36, 24, 91, 13, 85, 58, 10, 69, 97, 94, 63, 99, 82, 37, 46 };
+
+ @Test
+ public void testSameData_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_sameLength_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_B);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_sameLimit_order1() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_C);
+ InputStream rawInput3 = new ByteArrayInputStream(data_B);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_sameLimit_order2() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_B);
+ InputStream rawInput3 = new ByteArrayInputStream(data_C);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_sameLimit_order3() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_C);
+ InputStream rawInput2 = new ByteArrayInputStream(data_C);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order1() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 6);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order2() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 6);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 7);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order3() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 6);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 7);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order4() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 6);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order5() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 7);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 6);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testSameData_differentLimit_order6() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_A);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 7);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 6);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_sameLength_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_B);
+ InputStream rawInput3 = new ByteArrayInputStream(data_A);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 6);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testDifferentData_differentLength_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(data_A);
+ InputStream rawInput2 = new ByteArrayInputStream(data_C);
+ InputStream rawInput3 = new ByteArrayInputStream(data_B);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 6);
+
+ assertFalse(ResourceUtil.binaryIdentical(mockStorage(input1), mockStorage(input2),
+ mockStorage(input3)));
+ }
+
+ @Test
+ public void testZeroData_sameLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput2 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput3 = new ByteArrayInputStream(new byte[0]);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 8);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 8);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @Test
+ public void testZeroData_differentLimit() throws IOException {
+ InputStream rawInput1 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput2 = new ByteArrayInputStream(new byte[0]);
+ InputStream rawInput3 = new ByteArrayInputStream(new byte[0]);
+
+ InputStream input1 = new LimitedReadingInputStream(rawInput1, 8);
+ InputStream input2 = new LimitedReadingInputStream(rawInput2, 7);
+ InputStream input3 = new LimitedReadingInputStream(rawInput3, 6);
+
+ assertTrue(ResourceUtil
+ .binaryIdentical(mockStorage(input1), mockStorage(input2), mockStorage(input3)));
+ }
+
+ @SuppressWarnings("boxing")
+ private static IStorage mockStorage(InputStream input) {
+ try {
+ IStorage mockStorage = mock(IStorage.class);
+ when(mockStorage.getContents()).thenReturn(input);
+ when(mockStorage.isReadOnly()).thenReturn(true);
+ return mockStorage;
+ } catch (CoreException cEx) {
+ // this is merely a checked exception of mockStorage.getContents() and will never happen since we
+ // use mockito
+ return null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1 b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1
new file mode 100644
index 000000000..e985bcc18
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata1
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_m0XvsPlxEeS1vIMVt0hA3w" type="PapyrusUMLActivityDiagram" name="Activity Diagram" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_m0XvsflxEeS1vIMVt0hA3w" type="2001">
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvsvlxEeS1vIMVt0hA3w" type="5001"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvtPlxEeS1vIMVt0hA3w" type="7001">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvtflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvtvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvt_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvuPlxEeS1vIMVt0hA3w" type="7002">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvuflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvuvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvu_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvvPlxEeS1vIMVt0hA3w" type="7003">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvvflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvvvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvv_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvwPlxEeS1vIMVt0hA3w" type="7004">
+ <children xmi:type="notation:Shape" xmi:id="_9g2eoP1WEeS3caWTu98RFw" type="3067">
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3FsP1WEeS3caWTu98RFw" type="5118"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3Fsf1WEeS3caWTu98RFw" type="6016">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9g3Fsv1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3Fs_1WEeS3caWTu98RFw" type="7006">
+ <children xmi:type="notation:Shape" xmi:id="__T7l0P1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__T7l0_1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__T7l1P1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__T7l1f1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__T-CEP1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__T-CEf1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__T-CEv1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_A1vW0P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_A1vW0_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_A1vW1P1XEeS3caWTu98RFw" x="17" y="-2"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_A1vW1f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_A1vW1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_A1vW0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_A1rscP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_A1vW0v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_CJ0N0P1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_CJ0N0_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CJ0N1P1XEeS3caWTu98RFw" x="-4" y="-31"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_CJ0N1f1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CJ0N1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_CJ0N0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_CJxKgP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_CJ0N0v1XEeS3caWTu98RFw"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__T7l0f1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__T4igP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__T7l0v1WEeS3caWTu98RFw" x="30" y="30"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="__mYnwP1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__mYnw_1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__mYnxP1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__mYnxf1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__mac8P1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__mac8f1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__mac8v1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_BKVt0P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_BKVt0_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BKVt1P1XEeS3caWTu98RFw" x="16" y="3"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_BKVt1f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BKVt1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_BKVt0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_BKSqgP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_BKVt0v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_CgzKcP1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_CgzKc_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CgzKdP1XEeS3caWTu98RFw" x="20" y="-1"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_CgzKdf1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CgzKdv1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_CgzKcf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_Cgu5AP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_CgzKcv1XEeS3caWTu98RFw" x="69" y="-15"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__mYnwf1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__mWLgP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__mYnwv1WEeS3caWTu98RFw" x="30" y="130"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="__1BgsP1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__1CHwv1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__1CHw_1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__1CHxP1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__1D88P1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__1D88f1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__1D88v1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_BfF10P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_BfF10_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BfF11P1XEeS3caWTu98RFw" x="24" y="11"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_BfF11f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BfF11v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_BfF10f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_BfCLcP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_BfF10v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_C46IcP1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_C46Ic_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_C46IdP1XEeS3caWTu98RFw" x="24" y="-2"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_C46Idf1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_C46Idv1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_C46Icf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_C413AP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_C46Icv1XEeS3caWTu98RFw" x="69" y="-15"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__1CHwP1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__0_rgP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__1CHwf1WEeS3caWTu98RFw" x="30" y="230"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9g3FtP1WEeS3caWTu98RFw"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_9g2eof1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityPartition" href="model1.uml#_9g13kP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9g2eov1WEeS3caWTu98RFw" x="30" y="30" width="254" height="364"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0XvwflxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_zMvfoP1YEeS3caWTu98RFw" type="3059">
+ <children xmi:type="notation:DecorationNode" xmi:id="_zMvfo_1YEeS3caWTu98RFw" type="5071"/>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_zMvfof1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityParameterNode" href="model1.uml#_zMpZAP1YEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_zMvfov1YEeS3caWTu98RFw" y="117"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_3AQNgP1YEeS3caWTu98RFw" type="3059">
+ <children xmi:type="notation:DecorationNode" xmi:id="_3AQNg_1YEeS3caWTu98RFw" type="5071"/>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_3AQNgf1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityParameterNode" href="model1.uml#_3AKG4P1YEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3AQNgv1YEeS3caWTu98RFw" x="345" y="314"/>
+ </children>
+ <element xmi:type="uml:Activity" href="model1.uml#_m0IfIPlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0XvwvlxEeS1vIMVt0hA3w" width="310" height="497"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_m0Xvw_lxEeS1vIMVt0hA3w" name="diagram_compatibility_version" stringValue="1.1.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_m0XvxPlxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_m0XvxflxEeS1vIMVt0hA3w">
+ <owner xmi:type="uml:Model" href="model1.uml#_mzXDEPlxEeS1vIMVt0hA3w"/>
+ </styles>
+ <element xmi:type="uml:Activity" href="model1.uml#_m0IfIPlxEeS1vIMVt0hA3w"/>
+ <edges xmi:type="notation:Connector" xmi:id="_EZz6gP1XEeS3caWTu98RFw" type="4003" source="_A1vW0P1XEeS3caWTu98RFw" target="_CgzKcP1XEeS3caWTu98RFw" routing="Rectilinear">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_KM0a8P1XEeS3caWTu98RFw" source="PapyrusCSSForceValue">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_KM0a8f1XEeS3caWTu98RFw" key="routing" value="true"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hkP1XEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hkf1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hkv1XEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hk_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hlP1XEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hlf1XEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hlv1XEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hl_1XEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hmP1XEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hmf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hmv1XEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hm_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hnP1XEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hnf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_EZz6gf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_EZvCAP1XEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_EZz6gv1XEeS3caWTu98RFw" points="[-42, 9, -42, -45]$[-42, 69, -42, 15]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_EaIqoP1XEeS3caWTu98RFw" id="(0.0,1.0)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_EaIqof1XEeS3caWTu98RFw" id="(1.0,0.0)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_FWV0MP1XEeS3caWTu98RFw" type="4003" source="_BKVt0P1XEeS3caWTu98RFw" target="_C46IcP1XEeS3caWTu98RFw" routing="Rectilinear">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_KM4FUP1XEeS3caWTu98RFw" source="PapyrusCSSForceValue">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_KM4FUf1XEeS3caWTu98RFw" key="routing" value="true"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0M_1XEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0NP1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0Nf1XEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0Nv1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0N_1XEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0OP1XEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0Of1XEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0Ov1XEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbQP1XEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbQf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbQv1XEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbQ_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbRP1XEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbRf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_FWV0Mf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_FWPtkP1XEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_FWV0Mv1XEeS3caWTu98RFw" points="[-42, 9, -42, -45]$[-42, 69, -42, 15]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FWqkUP1XEeS3caWTu98RFw" id="(0.0,1.0)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FWqkUf1XEeS3caWTu98RFw" id="(1.0,0.0)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_5QsmIP1YEeS3caWTu98RFw" type="4003" source="_zMvfoP1YEeS3caWTu98RFw" target="_CJ0N0P1XEeS3caWTu98RFw">
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QsmI_1YEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QsmJP1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QsmJf1YEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QsmJv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNMP1YEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNMf1YEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNMv1YEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNM_1YEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNNP1YEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNNf1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNNv1YEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNN_1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNOP1YEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNOf1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_5QsmIf1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_5QnGkP1YEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_5QsmIv1YEeS3caWTu98RFw" points="[20, 2, -167, -24]$[183, 18, -4, -8]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5Q8dwP1YEeS3caWTu98RFw" id="(1.0,0.5)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5Q8dwf1YEeS3caWTu98RFw" id="(0.0,0.1875)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_6cwwoP1YEeS3caWTu98RFw" type="4003" source="_BfF10P1XEeS3caWTu98RFw" target="_3AQNgP1YEeS3caWTu98RFw">
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwo_1YEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwpP1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwpf1YEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwpv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwp_1YEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwqP1YEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwqf1YEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwqv1YEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwq_1YEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwrP1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwrf1YEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwrv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwr_1YEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwsP1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_6cwwof1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_6cqC8P1YEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6cwwov1YEeS3caWTu98RFw" points="[8, -5, -379, 214]$[407, -219, 20, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6dESoP1YEeS3caWTu98RFw" id="(1.0,0.125)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6dESof1YEeS3caWTu98RFw" id="(0.0,0.8)"/>
+ </edges>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2 b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2
new file mode 100644
index 000000000..7b5b4ffff
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.tests/src/org/eclipse/emf/compare/ide/utils/tests/data/binaryequalitytestinputdata2
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_m0XvsPlxEeS1vIMVt0hA3w" type="PapyrusUMLActivityDiagram" name="Activity Diagram" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_m0XvsflxEeS1vIMVt0hA3w" type="2001">
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvsvlxEeS1vIMVt0hA3w" type="5001"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvtPlxEeS1vIMVt0hA3w" type="7001">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvtflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvtvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvt_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvuPlxEeS1vIMVt0hA3w" type="7002">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvuflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvuvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvu_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvvPlxEeS1vIMVt0hA3w" type="7003">
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m0XvvflxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m0XvvvlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0Xvv_lxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m0XvwPlxEeS1vIMVt0hA3w" type="7004">
+ <children xmi:type="notation:Shape" xmi:id="_9g2eoP1WEeS3caWTu98RFw" type="3067">
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3FsP1WEeS3caWTu98RFw" type="5118"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3Fsf1WEeS3caWTu98RFw" type="6016">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_9g3Fsv1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_9g3Fs_1WEeS3caWTu98RFw" type="7006">
+ <children xmi:type="notation:Shape" xmi:id="__T7l0P1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__T7l0_1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__T7l1P1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__T7l1f1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__T-CEP1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__T-CEf1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__T-CEv1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_A1vW0P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_A1vW0_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_A1vW1P1XEeS3caWTu98RFw" x="17" y="-2"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_A1vW1f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_A1vW1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_A1vW0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_A1rscP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_A1vW0v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_CJ0N0P1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_CJ0N0_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CJ0N1P1XEeS3caWTu98RFw" x="-4" y="-31"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_CJ0N1f1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CJ0N1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_CJ0N0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_CJxKgP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_CJ0N0v1XEeS3caWTu98RFw"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__T7l0f1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__T4igP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__T7l0v1WEeS3caWTu98RFw" x="30" y="30"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="__mYnwP1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__mYnw_1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__mYnxP1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__mYnxf1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__mac8P1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__mac8f1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__mac8v1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_BKVt0P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_BKVt0_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BKVt1P1XEeS3caWTu98RFw" x="16" y="3"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_BKVt1f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BKVt1v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_BKVt0f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_BKSqgP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_BKVt0v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_CgzKcP1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_CgzKc_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CgzKdP1XEeS3caWTu98RFw" x="20" y="-1"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_CgzKdf1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_CgzKdv1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_CgzKcf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_Cgu5AP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_CgzKcv1XEeS3caWTu98RFw" x="69" y="-15"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__mYnwf1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__mWLgP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__mYnwv1WEeS3caWTu98RFw" x="30" y="130"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="__1BgsP1WEeS3caWTu98RFw" type="3007">
+ <children xmi:type="notation:DecorationNode" xmi:id="__1CHwv1WEeS3caWTu98RFw" type="5003"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="__1CHw_1WEeS3caWTu98RFw" type="6028">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="__1CHxP1WEeS3caWTu98RFw" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="__1D88P1WEeS3caWTu98RFw" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="__1D88f1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__1D88v1WEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_BfF10P1XEeS3caWTu98RFw" type="3014">
+ <children xmi:type="notation:DecorationNode" xmi:id="_BfF10_1XEeS3caWTu98RFw" type="5010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BfF11P1XEeS3caWTu98RFw" x="24" y="11"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_BfF11f1XEeS3caWTu98RFw" type="5086">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_BfF11v1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_BfF10f1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OutputPin" href="model1.uml#_BfCLcP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_BfF10v1XEeS3caWTu98RFw"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_C46IcP1XEeS3caWTu98RFw" type="3013">
+ <children xmi:type="notation:DecorationNode" xmi:id="_C46Ic_1XEeS3caWTu98RFw" type="5009">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_C46IdP1XEeS3caWTu98RFw" x="24" y="-2"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_C46Idf1XEeS3caWTu98RFw" type="5085">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_C46Idv1XEeS3caWTu98RFw" y="5"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_C46Icf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:InputPin" href="model1.uml#_C413AP1XEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_C46Icv1XEeS3caWTu98RFw" x="69" y="-15"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="__1CHwP1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:OpaqueAction" href="model1.uml#__0_rgP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="__1CHwf1WEeS3caWTu98RFw" x="30" y="230"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9g3FtP1WEeS3caWTu98RFw"/>
+ </children>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_9g2eof1WEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityPartition" href="model1.uml#_9g13kP1WEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9g2eov1WEeS3caWTu98RFw" x="30" y="30" width="254" height="364"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0XvwflxEeS1vIMVt0hA3w"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_zMvfoP1YEeS3caWTu98RFw" type="3059">
+ <children xmi:type="notation:DecorationNode" xmi:id="_zMvfo_1YEeS3caWTu98RFw" type="5071"/>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_zMvfof1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityParameterNode" href="model1.uml#_zMpZAP1YEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_zMvfov1YEeS3caWTu98RFw" y="117"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_3AQNgP1YEeS3caWTu98RFw" type="3059">
+ <children xmi:type="notation:DecorationNode" xmi:id="_3AQNg_1YEeS3caWTu98RFw" type="5071"/>
+ <styles xmi:type="notation:HintedDiagramLinkStyle" xmi:id="_3AQNgf1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ActivityParameterNode" href="model1.uml#_3AKG4P1YEeS3caWTu98RFw"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3AQNgv1YEeS3caWTu98RFw" x="345" y="314"/>
+ </children>
+ <element xmi:type="uml:Activity" href="model1.uml#_m0IfIPlxEeS1vIMVt0hA3w"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m0XvwvlxEeS1vIMVt0hA3w" width="310" height="497"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_m0Xvw_lxEeS1vIMVt0hA3w" name="diagram_compatibility_version" stringValue="1.1.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_m0XvxPlxEeS1vIMVt0hA3w"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_m0XvxflxEeS1vIMVt0hA3w">
+ <owner xmi:type="uml:Model" href="model1.uml#_mzXDEPlxEeS1vIMVt0hA3w"/>
+ </styles>
+ <element xmi:type="uml:Activity" href="model1.uml#_m0IfIPlxEeS1vIMVt0hA3w"/>
+ <edges xmi:type="notation:Connector" xmi:id="_EZz6gP1XEeS3caWTu98RFw" type="4003" source="_A1vW0P1XEeS3caWTu98RFw" target="_CgzKcP1XEeS3caWTu98RFw" routing="Rectilinear">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_KM0a8P1XEeS3caWTu98RFw" source="PapyrusCSSForceValue">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_KM0a8f1XEeS3caWTu98RFw" key="routing" value="true"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hkP1XEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hkf1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hkv1XEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hk_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hlP1XEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hlf1XEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hlv1XEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hl_1XEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hmP1XEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hmf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hmv1XEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hm_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_EZ0hnP1XEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_EZ0hnf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_EZz6gf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_EZvCAP1XEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_EZz6gv1XEeS3caWTu98RFw" points="[-42, 9, -42, -45]$[-42, 69, -42, 15]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_EaIqoP1XEeS3caWTu98RFw" id="(0.0,1.0)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_EaIqof1XEeS3caWTu98RFw" id="(1.0,0.0)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_FWV0MP1XEeS3caWTu98RFw" type="4003" source="_BKVt0P1XEeS3caWTu98RFw" target="_C46IcP1XEeS3caWTu98RFw" routing="Rectilinear">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_KM4FUP1XEeS3caWTu98RFw" source="PapyrusCSSForceValue">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_KM4FUf1XEeS3caWTu98RFw" key="routing" value="true"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0M_1XEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0NP1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0Nf1XEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0Nv1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0N_1XEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0OP1XEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWV0Of1XEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWV0Ov1XEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbQP1XEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbQf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbQv1XEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbQ_1XEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_FWWbRP1XEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_FWWbRf1XEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_FWV0Mf1XEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_FWPtkP1XEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_FWV0Mv1XEeS3caWTu98RFw" points="[-42, 9, -42, -45]$[-42, 69, -42, 15]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FWqkUP1XEeS3caWTu98RFw" id="(0.0,1.0)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FWqkUf1XEeS3caWTu98RFw" id="(1.0,0.0)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_5QsmIP1YEeS3caWTu98RFw" type="4003" source="_zMvfoP1YEeS3caWTu98RFw" target="_CJ0N0P1XEeS3caWTu98RFw">
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QsmI_1YEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QsmJP1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QsmJf1YEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QsmJv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNMP1YEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNMf1YEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNMv1YEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNM_1YEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNNP1YEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNNf1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNNv1YEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNN_1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_5QtNOP1YEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_5QtNOf1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_5QsmIf1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_5QnGkP1YEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_5QsmIv1YEeS3caWTu98RFw" points="[20, 2, -167, -24]$[183, 18, -4, -8]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5Q8dwP1YEeS3caWTu98RFw" id="(1.0,0.5)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5Q8dwf1YEeS3caWTu98RFw" id="(0.0,0.1875)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_6cwwoP1YEeS3caWTu98RFw" type="4003" source="_BfF10P1XEeS3caWTu98RFw" target="_3AQNgP1YEeS3caWTu98RFw">
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwo_1YEeS3caWTu98RFw" visible="false" type="6001">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwpP1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwpf1YEeS3caWTu98RFw" visible="false" type="6002">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwpv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwp_1YEeS3caWTu98RFw" visible="false" type="6005">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwqP1YEeS3caWTu98RFw" x="20" y="40"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwqf1YEeS3caWTu98RFw" visible="false" type="6006">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwqv1YEeS3caWTu98RFw" x="-20" y="-60"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwq_1YEeS3caWTu98RFw" visible="false" type="6007">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwrP1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwrf1YEeS3caWTu98RFw" visible="false" type="6008">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwrv1YEeS3caWTu98RFw" y="20"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6cwwr_1YEeS3caWTu98RFw" visible="false" type="6010">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_6cwwsP1YEeS3caWTu98RFw" y="-20"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_6cwwof1YEeS3caWTu98RFw"/>
+ <element xmi:type="uml:ObjectFlow" href="model1.uml#_6cqC8P1YEeS3caWTu98RFw"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6cwwov1YEeS3caWTu98RFw" points="[8, -5, -379, 214]$[407, -219, 20, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6dESoP1YEeS3caWTu98RFw" id="(1.0,0.125)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_6dESof1YEeS3caWTu98RFw" id="(0.0,0.8)"/>
+ </edges>
+</notation:Diagrax>
diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/utils/ResourceUtil.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/utils/ResourceUtil.java
index 9d03794f8..18e20ba29 100644
--- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/utils/ResourceUtil.java
+++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/utils/ResourceUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 Obeo.
+ * Copyright (c) 2012, 2015 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Michael Borkowski - bug 467677
*******************************************************************************/
package org.eclipse.emf.compare.ide.utils;
@@ -14,11 +15,9 @@ import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.io.Closeables;
-import java.io.BufferedReader;
+import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
import java.util.List;
import java.util.Map;
@@ -131,34 +130,38 @@ public final class ResourceUtil {
* @return <code>true</code> if {@code left} and {@code right} are binary identical.
*/
public static boolean binaryIdentical(IStorage left, IStorage right) {
- Reader leftReader = null;
- Reader rightReader = null;
+ BufferedInputStream leftStream = null;
+ BufferedInputStream rightStream = null;
try {
- leftReader = new BufferedReader(new InputStreamReader(left.getContents()));
- rightReader = new BufferedReader(new InputStreamReader(right.getContents()));
-
- final int bufferSize = 16384;
- final char[] leftBuff = new char[bufferSize];
- final char[] rightBuff = new char[bufferSize];
- int readLeft = leftReader.read(leftBuff);
- int readRight = rightReader.read(rightBuff);
- while (readLeft > 0 && readRight > 0 && equalArrays(readLeft, readRight, leftBuff, rightBuff)) {
- readLeft = leftReader.read(leftBuff);
- readRight = rightReader.read(rightBuff);
- }
- // One last check in case we've reached the end of one side but not of the other
- return equalArrays(readLeft, readRight, leftBuff, rightBuff);
+ final int maxBufferSize = 8192;
+ final byte[] buffer = new byte[maxBufferSize];
+
+ leftStream = new BufferedInputStream(left.getContents(), maxBufferSize);
+ rightStream = new BufferedInputStream(right.getContents(), maxBufferSize);
+
+ int readLeft;
+ boolean identical = true;
+ do {
+ readLeft = leftStream.read(buffer, 0, buffer.length);
+ if (readLeft == -1) {
+ // check if there is anything left to read on right
+ identical = rightStream.read() == -1;
+ break;
+ }
+ if (!verifyNextBytes(rightStream, buffer, 0, readLeft)) {
+ identical = false;
+ break;
+ }
+ } while (readLeft > 0);
+
+ return identical;
} catch (CoreException e) {
logError(e);
} catch (IOException e) {
logError(e);
} finally {
- if (leftReader != null) {
- Closeables.closeQuietly(leftReader);
- }
- if (rightReader != null) {
- Closeables.closeQuietly(rightReader);
- }
+ Closeables.closeQuietly(leftStream);
+ Closeables.closeQuietly(rightStream);
}
return false;
}
@@ -177,48 +180,78 @@ public final class ResourceUtil {
* @return <code>true</code> if {@code left}, {@code right} and {@code origin} are binary identical.
*/
public static boolean binaryIdentical(IStorage left, IStorage right, IStorage origin) {
- Reader leftReader = null;
- Reader rightReader = null;
- Reader originReader = null;
+ BufferedInputStream leftStream = null;
+ BufferedInputStream rightStream = null;
+ BufferedInputStream originStream = null;
try {
- leftReader = new BufferedReader(new InputStreamReader(left.getContents()));
- rightReader = new BufferedReader(new InputStreamReader(right.getContents()));
- originReader = new BufferedReader(new InputStreamReader(origin.getContents()));
-
- final int bufferSize = 16384;
- final char[] leftBuff = new char[bufferSize];
- final char[] rightBuff = new char[bufferSize];
- final char[] originBuff = new char[bufferSize];
- int readLeft = leftReader.read(leftBuff);
- int readRight = rightReader.read(rightBuff);
- int readOrigin = originReader.read(originBuff);
- while (readLeft > 0 && readRight > 0 && readOrigin > 0
- && equalArrays(readLeft, readRight, readOrigin, leftBuff, rightBuff, originBuff)) {
- readLeft = leftReader.read(leftBuff);
- readRight = rightReader.read(rightBuff);
- readOrigin = originReader.read(originBuff);
- }
- // One last check in case we've reached the end of one side but not of the other
- return equalArrays(readLeft, readRight, readOrigin, leftBuff, rightBuff, originBuff);
+ final int maxBufferSize = 8192;
+ final byte[] buffer = new byte[maxBufferSize];
+
+ leftStream = new BufferedInputStream(left.getContents(), maxBufferSize);
+ rightStream = new BufferedInputStream(right.getContents(), maxBufferSize);
+ originStream = new BufferedInputStream(origin.getContents(), maxBufferSize);
+
+ int readLeft;
+ boolean identical = true;
+ do {
+ readLeft = leftStream.read(buffer, 0, buffer.length);
+ if (readLeft == -1) {
+ // check if there is anything left to read on right or origin
+ identical = rightStream.read() == -1 && originStream.read() == -1;
+ break;
+ }
+ if (!verifyNextBytes(rightStream, buffer, 0, readLeft)
+ || !verifyNextBytes(originStream, buffer, 0, readLeft)) {
+ identical = false;
+ break;
+ }
+ } while (readLeft > 0);
+
+ return identical;
} catch (CoreException e) {
logError(e);
} catch (IOException e) {
logError(e);
} finally {
- if (leftReader != null) {
- Closeables.closeQuietly(leftReader);
- }
- if (rightReader != null) {
- Closeables.closeQuietly(rightReader);
- }
- if (originReader != null) {
- Closeables.closeQuietly(originReader);
- }
+ Closeables.closeQuietly(leftStream);
+ Closeables.closeQuietly(rightStream);
+ Closeables.closeQuietly(originStream);
}
return false;
}
/**
+ * Verifies whether the next <code>length</code> bytes coming from <code>stream</code> equal
+ * <code>bytes</code> at offset <code>offset</code>.
+ *
+ * @param stream
+ * The stream to read bytes from
+ * @param bytes
+ * The array of bytes to compare to (from offset of <code>offset</code> bytes)
+ * @param offset
+ * The offset in the byte array to use
+ * @param length
+ * The amount of bytes to verify
+ * @return <code>true</code> if there are at least <code>length</code> bytes in the stream and they equal
+ * the provided bytes
+ * @throws IOException
+ * If an I/O problem occurs
+ */
+ private static boolean verifyNextBytes(InputStream stream, byte[] bytes, int offset, int length)
+ throws IOException {
+ int done = 0;
+ byte[] buffer = new byte[offset + length];
+ while (done < length) {
+ int read = stream.read(buffer, offset + done, length - done);
+ if (read == -1 || !equalArrays(offset + done, read, bytes, buffer)) {
+ return false;
+ }
+ done += read;
+ }
+ return true;
+ }
+
+ /**
* Create the URI with which we'll load the given IFile as an EMF resource.
*
* @param file
@@ -447,73 +480,31 @@ public final class ResourceUtil {
}
/**
- * Checks whether the two arrays contain identical data in the {@code [0:length]} range. Note that we
- * won't even check the arrays' contents if {@code length1} is not equal to {@code length2}.
+ * Checks whether the two arrays contain identical data in the {@code [0:length]} range.
*
- * @param length1
- * Length of the data range to check within {@code array1}.
- * @param length2
- * Length of the data range to check within {@code array2}.
+ * @param offset
+ * The offset at which to start comparing
+ * @param length
+ * Length of the data range to check within the arrays.
* @param array1
* First of the two arrays which content we need to check.
* @param array2
* Second of the two arrays which content we need to check.
- * @return <code>true</code> if the two given arrays contain identical data in the {@code [0:length]}
- * range.
+ * @return <code>true</code> if the two given arrays contain identical data in the
+ * {@code [offset..offset+length]} range.
*/
- private static boolean equalArrays(int length1, int length2, char[] array1, char[] array2) {
- if (length1 == length2) {
- boolean result = true;
- if (array1 == array2) {
- result = true;
- } else if (array1 == null || array2 == null) {
- result = false;
- } else {
- for (int i = 0; i < length1 && result; i++) {
- result = array1[i] == array2[i];
- }
- }
- return result;
- }
- return false;
- }
-
- /**
- * Checks whether the three arrays contain identical data in the {@code [0:length]} range. Note that we
- * will only check the arrays' contents if {@code length1} is equal to {@code length2} and {@code length3}
- * .
- *
- * @param length1
- * Length of the data range to check within {@code array1}.
- * @param length2
- * Length of the data range to check within {@code array2}.
- * @param length3
- * Length of the data range to check within {@code array3}.
- * @param array1
- * First of the three arrays which content we need to check.
- * @param array2
- * Second of the three arrays which content we need to check.
- * @param array3
- * Third of the three arrays which content we need to check.
- * @return <code>true</code> if the three given arrays contain identical data in the {@code [0:length]}
- * range.
- */
- private static boolean equalArrays(int length1, int length2, int length3, char[] array1, char[] array2,
- char[] array3) {
- if (length1 == length2 && length1 == length3) {
- boolean result = true;
- if (array1 == array2 && array1 == array3) {
- result = true;
- } else if (array1 == null || array2 == null || array3 == null) {
- result = false;
- } else {
- for (int i = 0; i < length1 && result; i++) {
- result = array1[i] == array2[i] && array1[i] == array3[i];
- }
+ private static boolean equalArrays(int offset, int length, byte[] array1, byte[] array2) {
+ boolean result = true;
+ if (array1 == array2) {
+ result = true;
+ } else if (array1 == null || array2 == null) {
+ result = false;
+ } else {
+ for (int i = offset; result && i < offset + length; i++) {
+ result = array1[i] == array2[i];
}
- return result;
}
- return false;
+ return result;
}
/**

Back to the top