/*******************************************************************************
* Copyright (c) 2014 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.compare.tests.merge;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.not;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.google.common.collect.Iterators;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceKind;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.merge.data.IndividualDiffInputData;
import org.eclipse.emf.compare.tests.nodes.Node;
import org.eclipse.emf.compare.tests.nodes.NodeSingleValueAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.junit.Test;
@SuppressWarnings("nls")
public class PseudoConflictMergeTest {
private IndividualDiffInputData input = new IndividualDiffInputData();
private final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
@Test
public void testPseudoAdd_LtR_1() throws IOException {
// Pseudo Conflict between Node A[containmentRef1 add] from left side and Node A[containmentRef1 add]
// from right side
final Resource left = input.getLeftPseudoConflictAddScope();
final Resource right = input.getRightPseudoConflictAddScope();
final Resource origin = input.getOriginPseudoConflictAddScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.ADD)));
// Merge -> Node A[containmentRef1 add] from left to right : <- Node A[containmentRef1 add] will be
// merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeA = getNodeNamed(left, "A");
assertNotNull(leftNodeA);
final EObject rightNodeA = getNodeNamed(right, "A");
assertNotNull(rightNodeA);
final EStructuralFeature feature = rightNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)rightNodeRoot).getContainmentRef1();
assertFalse(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoAdd_LtR_2() throws IOException {
// Pseudo Conflict between Node A[containmentRef1 add] from left side and Node A[containmentRef1 add]
// from right side
final Resource left = input.getLeftPseudoConflictAddScope();
final Resource right = input.getRightPseudoConflictAddScope();
final Resource origin = input.getOriginPseudoConflictAddScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.ADD)));
// Merge <- Node A[containmentRef1 add] from left to right : -> Node A[containmentRef1 add] will be
// merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeA = getNodeNamed(left, "A");
assertNotNull(leftNodeA);
final EObject rightNodeA = getNodeNamed(right, "A");
assertNotNull(rightNodeA);
final EStructuralFeature feature = rightNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)rightNodeRoot).getContainmentRef1();
assertFalse(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoAdd_RtL_1() throws IOException {
// Pseudo Conflict between Node A[containmentRef1 add] from left side and Node A[containmentRef1 add]
// from right side
final Resource left = input.getLeftPseudoConflictAddScope();
final Resource right = input.getRightPseudoConflictAddScope();
final Resource origin = input.getOriginPseudoConflictAddScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.ADD)));
// Merge -> Node A[containmentRef1 add] from right to left : <- Node A[containmentRef1 add] will be
// merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeA = getNodeNamed(left, "A");
assertNotNull(leftNodeA);
final EObject rightNodeA = getNodeNamed(right, "A");
assertNotNull(rightNodeA);
final EStructuralFeature feature = leftNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)leftNodeRoot).getContainmentRef1();
assertFalse(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoAdd_RtL_2() throws IOException {
// Pseudo Conflict between Node A[containmentRef1 add] from left side and Node A[containmentRef1 add]
// from right side
final Resource left = input.getLeftPseudoConflictAddScope();
final Resource right = input.getRightPseudoConflictAddScope();
final Resource origin = input.getOriginPseudoConflictAddScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.ADD)));
// Merge <- Node A[containmentRef1 add] from right to left : -> Node A[containmentRef1 add] will be
// merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeA = getNodeNamed(left, "A");
assertNotNull(leftNodeA);
final EObject rightNodeA = getNodeNamed(right, "A");
assertNotNull(rightNodeA);
final EStructuralFeature feature = leftNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)leftNodeRoot).getContainmentRef1();
assertFalse(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoDelete_LtR_1() throws IOException {
// Pseudo Conflict between Node B[containmentRef1 delete] from left side and Node B[containmentRef1
// delete] from right side
final Resource left = input.getLeftPseudoConflictDeleteScope();
final Resource right = input.getRightPseudoConflictDeleteScope();
final Resource origin = input.getOriginPseudoConflictDeleteScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.DELETE)));
// Merge -> Node B[containmentRef1 delete] from left to right : <- Node B[containmentRef1 delete] will
// be merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeB = getNodeNamed(left, "B");
assertNull(leftNodeB);
final EObject rightNodeB = getNodeNamed(right, "B");
assertNull(rightNodeB);
final EStructuralFeature feature = rightNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)rightNodeRoot).getContainmentRef1();
assertTrue(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoDelete_LtR_2() throws IOException {
// Pseudo Conflict between Node B[containmentRef1 delete] from left side and Node B[containmentRef1
// delete] from right side
final Resource left = input.getLeftPseudoConflictDeleteScope();
final Resource right = input.getRightPseudoConflictDeleteScope();
final Resource origin = input.getOriginPseudoConflictDeleteScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.DELETE)));
// Merge <- Node B[containmentRef1 delete] from left to right : -> Node B[containmentRef1 delete] will
// be merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeB = getNodeNamed(left, "B");
assertNull(leftNodeB);
final EObject rightNodeB = getNodeNamed(right, "B");
assertNull(rightNodeB);
final EStructuralFeature feature = rightNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)rightNodeRoot).getContainmentRef1();
assertTrue(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoDelete_RtL_1() throws IOException {
// Pseudo Conflict between Node B[containmentRef1 delete] from left side and Node B[containmentRef1
// delete] from right side
final Resource left = input.getLeftPseudoConflictDeleteScope();
final Resource right = input.getRightPseudoConflictDeleteScope();
final Resource origin = input.getOriginPseudoConflictDeleteScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.DELETE)));
// Merge -> Node B[containmentRef1 delete] from right to left : <- Node B[containmentRef1 delete] will
// be merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeB = getNodeNamed(left, "B");
assertNull(leftNodeB);
final EObject rightNodeB = getNodeNamed(right, "B");
assertNull(rightNodeB);
final EStructuralFeature feature = leftNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)leftNodeRoot).getContainmentRef1();
assertTrue(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoDelete_RtL_2() throws IOException {
// Pseudo Conflict between Node B[containmentRef1 delete] from left side and Node B[containmentRef1
// delete] from right side
final Resource left = input.getLeftPseudoConflictDeleteScope();
final Resource right = input.getRightPseudoConflictDeleteScope();
final Resource origin = input.getOriginPseudoConflictDeleteScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.DELETE)));
// Merge <- Node B[containmentRef1 delete] from right to left : -> Node B[containmentRef1 delete] will
// be merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "containmentRef1";
final EObject leftNodeRoot = getNodeNamed(left, "root");
assertNotNull(leftNodeRoot);
final EObject rightNodeRoot = getNodeNamed(right, "root");
assertNotNull(rightNodeRoot);
final EObject leftNodeB = getNodeNamed(left, "B");
assertNull(leftNodeB);
final EObject rightNodeB = getNodeNamed(right, "B");
assertNull(rightNodeB);
final EStructuralFeature feature = leftNodeRoot.eClass().getEStructuralFeature(featureName);
assertNotNull(feature);
final EList<Node> containmentRef1 = ((Node)leftNodeRoot).getContainmentRef1();
assertTrue(containmentRef1.isEmpty());
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoChange_LtR_1() throws IOException {
// Pseudo Conflict between Hello[singleValuedAttribute changed] from left side and
// Hello[singleValuedAttribute changed] from right side
final Resource left = input.getLeftPseudoConflictChangeScope();
final Resource right = input.getRightPseudoConflictChangeScope();
final Resource origin = input.getOriginPseudoConflictChangeScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.CHANGE)));
// Merge -> Hello[singleValuedAttribute changed] from left to right : <- Hello[singleValuedAttribute
// changed] will be merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "singleValuedAttribute";
final EObject leftNodeD = getNodeNamed(left, "D");
assertNotNull(leftNodeD);
final EObject rightNodeD = getNodeNamed(right, "D");
assertNotNull(rightNodeD);
final EStructuralFeature featureRight = rightNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureRight);
final EStructuralFeature featureLeft = leftNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureLeft);
final String singleValuedAttributeRight = ((NodeSingleValueAttribute)rightNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeRight);
final String singleValuedAttributeLeft = ((NodeSingleValueAttribute)leftNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeLeft);
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoChange_LtR_2() throws IOException {
// Pseudo Conflict between Hello[singleValuedAttribute changed] from left side and
// Hello[singleValuedAttribute changed] from right side
final Resource left = input.getLeftPseudoConflictChangeScope();
final Resource right = input.getRightPseudoConflictChangeScope();
final Resource origin = input.getOriginPseudoConflictChangeScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.CHANGE)));
// Merge <- Hello[singleValuedAttribute changed] from left to right : -> Hello[singleValuedAttribute
// changed] will be merge from left to right too.
mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final String featureName = "singleValuedAttribute";
final EObject leftNodeD = getNodeNamed(left, "D");
assertNotNull(leftNodeD);
final EObject rightNodeD = getNodeNamed(right, "D");
assertNotNull(rightNodeD);
final EStructuralFeature featureRight = rightNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureRight);
final EStructuralFeature featureLeft = leftNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureLeft);
final String singleValuedAttributeRight = ((NodeSingleValueAttribute)rightNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeRight);
final String singleValuedAttributeLeft = ((NodeSingleValueAttribute)leftNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeLeft);
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoChange_RtL_1() throws IOException {
// Pseudo Conflict between Hello[singleValuedAttribute changed] from left side and
// Hello[singleValuedAttribute changed] from right side
final Resource left = input.getLeftPseudoConflictChangeScope();
final Resource right = input.getRightPseudoConflictChangeScope();
final Resource origin = input.getOriginPseudoConflictChangeScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.LEFT), ofKind(DifferenceKind.CHANGE)));
// Merge -> Hello[singleValuedAttribute changed] from right to left : <- Hello[singleValuedAttribute
// changed] will be merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "singleValuedAttribute";
final EObject leftNodeD = getNodeNamed(left, "D");
assertNotNull(leftNodeD);
final EObject rightNodeD = getNodeNamed(right, "D");
assertNotNull(rightNodeD);
final EStructuralFeature featureRight = rightNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureRight);
final EStructuralFeature featureLeft = leftNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureLeft);
final String singleValuedAttributeRight = ((NodeSingleValueAttribute)rightNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeRight);
final String singleValuedAttributeLeft = ((NodeSingleValueAttribute)leftNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeLeft);
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
@Test
public void testPseudoChange_RtL_2() throws IOException {
// Pseudo Conflict between Hello[singleValuedAttribute changed] from left side and
// Hello[singleValuedAttribute changed] from right side
final Resource left = input.getLeftPseudoConflictChangeScope();
final Resource right = input.getRightPseudoConflictChangeScope();
final Resource origin = input.getOriginPseudoConflictChangeScope();
final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
Comparison comparison = EMFCompare.builder().build().compare(scope);
List<Diff> differences = comparison.getDifferences();
assertEquals(2, differences.size());
final Diff diff = Iterators.find(differences.iterator(),
and(fromSide(DifferenceSource.RIGHT), ofKind(DifferenceKind.CHANGE)));
// Merge -> Hello[singleValuedAttribute changed] from right to left : <- Hello[singleValuedAttribute
// changed] will be merge from right to left too.
mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final String featureName = "singleValuedAttribute";
final EObject leftNodeD = getNodeNamed(left, "D");
assertNotNull(leftNodeD);
final EObject rightNodeD = getNodeNamed(right, "D");
assertNotNull(rightNodeD);
final EStructuralFeature featureRight = rightNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureRight);
final EStructuralFeature featureLeft = leftNodeD.eClass().getEStructuralFeature(featureName);
assertNotNull(featureLeft);
final String singleValuedAttributeRight = ((NodeSingleValueAttribute)rightNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeRight);
final String singleValuedAttributeLeft = ((NodeSingleValueAttribute)leftNodeD)
.getSingleValuedAttribute();
assertEquals("GoodBye", singleValuedAttributeLeft);
Iterators.any(differences.iterator(), not(hasConflict(ConflictKind.PSEUDO)));
}
private EObject getNodeNamed(Resource res, String name) {
final Iterator<EObject> iterator = EcoreUtil.getAllProperContents(res, false);
while (iterator.hasNext()) {
final EObject next = iterator.next();
final EStructuralFeature nameFeature = next.eClass().getEStructuralFeature("name");
if (nameFeature != null && name.equals(next.eGet(nameFeature))) {
return next;
}
}
return null;
}
}