View Javadoc
1   package org.andromda.metafacades.uml14;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Iterator;
6   import java.util.LinkedHashMap;
7   import java.util.List;
8   import java.util.Map;
9   import org.andromda.core.common.ExceptionUtils;
10  import org.andromda.core.metafacade.MetafacadeConstants;
11  import org.andromda.core.metafacade.MetafacadeFactory;
12  import org.andromda.metafacades.uml.ActivityGraphFacade;
13  import org.andromda.metafacades.uml.ClassifierFacade;
14  import org.andromda.metafacades.uml.EventFacade;
15  import org.andromda.metafacades.uml.MetafacadeUtils;
16  import org.andromda.metafacades.uml.ModelElementFacade;
17  import org.andromda.metafacades.uml.ParameterFacade;
18  import org.andromda.metafacades.uml.UMLProfile;
19  import org.andromda.metafacades.uml.UseCaseFacade;
20  import org.apache.commons.collections.CollectionUtils;
21  import org.apache.commons.collections.Predicate;
22  import org.apache.commons.lang.StringUtils;
23  import org.omg.uml.behavioralelements.activitygraphs.ActivityGraph;
24  import org.omg.uml.behavioralelements.statemachines.Event;
25  import org.omg.uml.behavioralelements.statemachines.FinalState;
26  import org.omg.uml.behavioralelements.usecases.UseCase;
27  import org.omg.uml.foundation.core.Attribute;
28  import org.omg.uml.foundation.core.Classifier;
29  import org.omg.uml.foundation.core.CorePackage;
30  import org.omg.uml.foundation.core.ModelElement;
31  import org.omg.uml.foundation.core.Parameter;
32  import org.omg.uml.foundation.core.Stereotype;
33  import org.omg.uml.foundation.core.TaggedValue;
34  import org.omg.uml.foundation.core.UmlClass;
35  import org.omg.uml.foundation.datatypes.VisibilityKind;
36  import org.omg.uml.foundation.datatypes.VisibilityKindEnum;
37  import org.omg.uml.modelmanagement.Model;
38  import org.omg.uml.modelmanagement.UmlPackage;
39  
40  /**
41   * Utilities for dealing with UML 1.4 metafacades
42   *
43   * @author Chad Brandon
44   * @author Bob Fields
45   */
46  public class UML14MetafacadeUtils
47  {
48      /**
49       * Finds a given model element in the model having the specified
50       * <code>fullyQualifiedName</code>. If the model element can <strong>NOT
51       * </strong> be found, <code>null</code> will be returned instead.
52       *
53       * @param fullyQualifiedName the fully qualified name of the element to
54       *        search for.
55       * @param separator the PSM separator used for qualifying the name (example
56       *        ".").
57       * @param modelName a flag indicating whether or not a search shall be performed using
58       *        the fully qualified model name or fully qualified PSM name.
59       * @return the found model element
60       */
61      static Object findByFullyQualifiedName(final String fullyQualifiedName, final String separator, final boolean modelName)
62      {
63          Object modelElement;
64          Collection elements = ((org.omg.uml.UmlPackage)MetafacadeFactory.getInstance().getModel().getModel()).getCore()
65                  .getModelElement()
66                  .refAllOfType();
67          modelElement = CollectionUtils.find(elements, new Predicate()
68          {
69              public boolean evaluate(Object object)
70              {
71                  ModelElement element = (ModelElement)object;
72                  StringBuilder fullName = new StringBuilder(getPackageName(element, separator, modelName));
73                  String name = element.getName();
74                  if (StringUtils.isNotBlank(name))
75                  {
76                      String namespaceSeparator = MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR;
77                      if (!modelName)
78                      {
79                          namespaceSeparator = separator;
80                      }
81                      fullName.append(namespaceSeparator);
82                      fullName.append(name);
83                  }
84                  return fullName.toString().equals(fullyQualifiedName);
85              }
86          });
87          return modelElement;
88      }
89  
90      private static String empty = "";
91      /**
92       * Constructs the package name for the given <code>metaObject</code>, separating the package name by the given
93       * <code>separator</code>.
94       *
95       * @param metaObject the Model Element
96       * @param separator the PSM namespace separator
97       * @param modelName true/false on whether or not to get the model package name instead
98       *        of the PSM package name.
99       * @return the package name.
100      */
101     static String getPackageName(ModelElement metaObject, String separator, boolean modelName)
102     {
103         String packageName = empty;
104         for (ModelElement namespace = metaObject.getNamespace(); (namespace instanceof UmlPackage) &&
105                 !(namespace instanceof Model); namespace = namespace.getNamespace())
106         {
107             packageName = packageName.equals(empty) ? namespace.getName() : namespace.getName() + separator + packageName;
108         }
109         if (modelName && StringUtils.isNotBlank(packageName))
110         {
111             packageName = StringUtils.replace(packageName, separator, MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR);
112         }
113         return packageName;
114     }
115 
116     /**
117      * Basically just checks to make sure the <code>model</code> is of type <code>org.omg.uml.UmlPackage</code> and
118      * retrieves the <code>CorePackage</code> from it.
119      *
120      * @return the <code>model</code> as a <code>org.omg.uml.UmlPackage</code>
121      */
122     static CorePackage getCorePackage()
123     {
124         return ((org.omg.uml.UmlPackage)MetafacadeFactory.getInstance().getModel().getModel()).getCore();
125     }
126 
127     /**
128      * Finds and returns the first model element having the given <code>name</code> in the <code>modelPackage</code>,
129      * returns <code>null</code> if not found.
130      *
131      * @param name the name to find.
132      * @return the found model element.
133      */
134     static Object findByName(final String name)
135     {
136         Object modelElement = null;
137         if (StringUtils.isNotBlank(name))
138         {
139             modelElement = CollectionUtils.find(getModel().getCore().getModelElement().refAllOfType(), new Predicate()
140             {
141                 public boolean evaluate(Object object)
142                 {
143                     return StringUtils.trimToEmpty(((ModelElement)object).getName()).equals(name);
144                 }
145             });
146         }
147         return modelElement;
148     }
149 
150     /**
151      * Gets the root package in the model.
152      *
153      * @return the root package as a UmlPackage.
154      */
155     static UmlPackage getRootPackage()
156     {
157         Object result = null;
158         Collection rootPackages = UML14MetafacadeUtils.getModel().getModelManagement().getModel().refAllOfType();
159         for (Object rootPackage : rootPackages)
160         {
161             // get the first package that's a ModelElement instance
162             // Note: UML2 allows top level ModelElement to be a Package.
163             if (rootPackage instanceof ModelElement)
164             {
165                 result = rootPackage;
166                 break;
167             }
168         }
169         return (UmlPackage)result;
170     }
171 
172     /**
173      * Returns the entire model.
174      *
175      * @return org.omg.uml.UmlPackage model instance.
176      */
177     static org.omg.uml.UmlPackage getModel()
178     {
179         return (org.omg.uml.UmlPackage)MetafacadeFactory.getInstance().getModel().getModel();
180     }
181 
182     /**
183      * Gets the correct meta model visibility kind for the given <code>visibility</code> string.
184      *
185      * @param visibility the visibility to retrieve.
186      * @return the VisibilityKind
187      */
188     static VisibilityKind getVisibilityKind(String visibility)
189     {
190         VisibilityKind visibilityKind = null;
191         visibility = StringUtils.trimToEmpty(visibility);
192         if ("public".equals(visibility))
193         {
194             visibilityKind = VisibilityKindEnum.VK_PUBLIC;
195         }
196         else if ("private".equals(visibility))
197         {
198             visibilityKind = VisibilityKindEnum.VK_PRIVATE;
199         }
200         else if (StringUtils.isEmpty(visibility))
201         {
202             visibilityKind = VisibilityKindEnum.VK_PACKAGE;
203         }
204         else if ("protected".equals(visibility))
205         {
206             visibilityKind = VisibilityKindEnum.VK_PROTECTED;
207         }
208         return visibilityKind;
209     }
210 
211     /**
212      * Creates an attribute having the give <code>name</code> and the type
213      * having the given <code>fullyQualifiedTypeName</code>, with the
214      * specified visibility, if no type can be found with the given name, no
215      * type is set.
216      *
217      * @param name the new name
218      * @param fullyQualifiedTypeName the name of the fully qualified type
219      * @param visibility the visibility name
220      * @param separator the separator used for qualifying the name.
221      * @return the new Attribute.
222      */
223     static Attribute createAttribute(String name, String fullyQualifiedTypeName, String visibility, String separator)
224     {
225         Attribute attribute = UML14MetafacadeUtils.getCorePackage().getAttribute().createAttribute();
226         attribute.setName(name);
227         attribute.setVisibility(UML14MetafacadeUtils.getVisibilityKind(visibility));
228         Object type = UML14MetafacadeUtils.findByFullyQualifiedName(fullyQualifiedTypeName, separator, false);
229         if (type != null && Classifier.class.isAssignableFrom(type.getClass()))
230         {
231             attribute.setType((Classifier)type);
232         }
233         return attribute;
234     }
235 
236     /**
237      * Indicates whether or not the attribute exists on the given </code>classifier</code>.
238      *
239      * @param classifier the classifier to check
240      * @param name the name of the attribute
241      * @return true/false
242      */
243     static boolean attributeExists(Object classifier, String name)
244     {
245         boolean exists = false;
246         if (Classifier.class.isAssignableFrom(classifier.getClass()))
247         {
248             List features = ((Classifier)classifier).getFeature();
249             if (features != null && !features.isEmpty())
250             {
251                 for (final Iterator featureIterator = features.iterator(); featureIterator.hasNext();)
252                 {
253                     Object feature = featureIterator.next();
254                     if (feature != null && Attribute.class.isAssignableFrom(feature.getClass()))
255                     {
256                         exists = StringUtils.trimToEmpty(((Attribute)feature).getName()).equals(name);
257                         if(exists)
258                         {
259                             break;
260                         }
261                     }
262                 }
263             }
264         }
265         return exists;
266     }
267 
268     /**
269      * Finds or creates a stereotype with the given name. If the stereotype isn't found, it will be created.
270      *
271      * @param name the name of the stereotype.
272      * @return the new Stereotype.
273      */
274     static Stereotype findOrCreateStereotype(String name)
275     {
276         Object stereotype = UML14MetafacadeUtils.findByName(name);
277         if (stereotype == null || !Stereotype.class.isAssignableFrom(stereotype.getClass()))
278         {
279             stereotype = UML14MetafacadeUtils.getCorePackage().getStereotype().createStereotype();
280             ((Stereotype)stereotype).setName(name);
281         }
282         return (Stereotype)stereotype;
283     }
284 
285     /**
286      * Returns the first use-case it can find with the given name.
287      * @param name
288      * @return findFirstUseCaseWithNameAndStereotype(name, null)
289      */
290     static UseCase findFirstUseCaseWithName(String name)
291     {
292         return findFirstUseCaseWithNameAndStereotype(name, null);
293     }
294 
295     /**
296      * Returns the first use-case it can find with the given name and stereotype, if the stereotype is not specified (it
297      * is null) it will be ignored and the returned use-case may have any arbitrary stereotype.
298      * @param name
299      * @param stereotypeName
300      * @return useCaseWithNameAndStereotype
301      */
302     static UseCase findFirstUseCaseWithNameAndStereotype(String name, String stereotypeName)
303     {
304         UseCase useCaseWithNameAndStereotype = null;
305 
306         Collection<UseCase> useCases = getModel().getUseCases().getUseCase().refAllOfType();
307         for (final Iterator<UseCase> useCaseIterator = useCases.iterator(); useCaseIterator.hasNext() && useCaseWithNameAndStereotype ==
308                 null;)
309         {
310             UseCase useCase = useCaseIterator.next();
311             if (name.equals(useCase.getName()))
312             {
313                 if (stereotypeName == null || isStereotypePresent(useCase, stereotypeName))
314                 {
315                     useCaseWithNameAndStereotype = useCase;
316                 }
317             }
318         }
319 
320         return useCaseWithNameAndStereotype;
321     }
322 
323     /**
324      * Returns the first activity graph it can find with the given name.
325      * @param name
326      * @return findFirstActivityGraphWithNameAndStereotype(name, null)
327      */
328     static ActivityGraph findFirstActivityGraphWithName(String name)
329     {
330         return findFirstActivityGraphWithNameAndStereotype(name, null);
331     }
332 
333     /**
334      * Returns the first activity graph it can find with the given name and stereotype, if the stereotype is not
335      * specified (it is null) it will be ignored and the returned activity graph may have any arbitrary stereotype.
336      * @param name
337      * @param stereotypeName
338      * @return graphWithNameAndStereotype
339      */
340     static ActivityGraph findFirstActivityGraphWithNameAndStereotype(String name, String stereotypeName)
341     {
342         ActivityGraph graphWithNameAndStereotype = null;
343 
344         Collection<ActivityGraph> graphs = getModel().getActivityGraphs().getActivityGraph().refAllOfType();
345         for (final Iterator<ActivityGraph> graphIterator = graphs.iterator();
346              graphIterator.hasNext() && graphWithNameAndStereotype == null;)
347         {
348             ActivityGraph graph = graphIterator.next();
349             if (name.equals(graph.getName()))
350             {
351                 if (stereotypeName == null || isStereotypePresent(graph, stereotypeName))
352                 {
353                     graphWithNameAndStereotype = graph;
354                 }
355             }
356         }
357 
358         return graphWithNameAndStereotype;
359     }
360 
361     /**
362      * Returns true if the given model element has a tag with the given name and value, returns false otherwise.
363      * @param element
364      * @param tag
365      * @param value
366      * @return tagPresent
367      */
368     static boolean isTagPresent(ModelElement element, String tag, Object value)
369     {
370         boolean tagPresent = false;
371 
372         Collection<TaggedValue> taggedValues = element.getTaggedValue();
373         for (final Iterator<TaggedValue> taggedValueIterator = taggedValues.iterator(); taggedValueIterator.hasNext() && !tagPresent;)
374         {
375             TaggedValue taggedValue = taggedValueIterator.next();
376             // does this name match the argument tagged value name ?
377             // Check both the UML14 format name @andromda.value and EMF Format andromda_whatever
378             String tagName = taggedValue.getName();
379             if (tag.equals(tagName) || MetafacadeUtils.getEmfTaggedValue(tag).equals(tagName)
380                 || MetafacadeUtils.getUml14TaggedValue(tag).equals(tagName))
381             {
382                 for (final Iterator valueIterator = taggedValue.getDataValue().iterator(); valueIterator.hasNext() &&
383                         !tagPresent;)
384                 {
385                     Object dataValue = valueIterator.next();
386                     if (value.equals(dataValue))
387                     {
388                         tagPresent = true;
389                     }
390                 }
391                 for (final Iterator valueIterator = taggedValue.getReferenceValue().iterator(); valueIterator.hasNext() &&
392                         !tagPresent;)
393                 {
394                     Object referenceValue = valueIterator.next();
395                     if (value.equals(referenceValue))
396                     {
397                         tagPresent = true;
398                     }
399                 }
400             }
401         }
402         return tagPresent;
403     }
404 
405     /**
406      * Returns true if the given model element has a hyperlink with the given value, returns false otherwise.
407      * @param element
408      * @param value
409      * @return isTagPresent(element, "hyperlinkModel", value)
410      */
411     static boolean isHyperlinkPresent(ModelElement element, Object value)
412     {
413         return isTagPresent(element, "hyperlinkModel", value);
414     }
415 
416     /**
417      * @param element
418      * @param stereotypeName
419      * @return stereotypePresent
420      */
421     static boolean isStereotypePresent(ModelElement element, String stereotypeName)
422     {
423         boolean stereotypePresent = false;
424 
425         Collection<Stereotype> stereotypes = element.getStereotype();
426         for (final Iterator<Stereotype> stereotypeIterator = stereotypes.iterator();
427              stereotypeIterator.hasNext() && !stereotypePresent;)
428         {
429             Stereotype stereotype = stereotypeIterator.next();
430             if (stereotypeName.equals(stereotype.getName()))
431             {
432                 stereotypePresent = true;
433             }
434         }
435         return stereotypePresent;
436     }
437 
438     /**
439      * Returns the first use-case this method can find with the given tagged value or hyperlink. Both arguments are used
440      * to look for the tagged value but only <code>value</code> is used to search for the hyperlink.
441      * @param tag
442      * @param value
443      * @return useCaseWithTaggedValue
444      */
445     static UseCase findUseCaseWithTaggedValueOrHyperlink(String tag, String value)
446     {
447         UseCase useCaseWithTaggedValue = null;
448 
449         Collection<UseCase> useCases = getModel().getUseCases().getUseCase().refAllOfType();
450         for (final Iterator<UseCase> useCaseIterator = useCases.iterator(); useCaseIterator.hasNext() && useCaseWithTaggedValue ==
451                 null;)
452         {
453             // loop over all use-cases
454             UseCase useCase = useCaseIterator.next();
455             if (isTagPresent(useCase, tag, value) || isHyperlinkPresent(useCase, value))
456             {
457                 useCaseWithTaggedValue = useCase;
458             }
459         }
460 
461         return useCaseWithTaggedValue;
462     }
463 
464     /**
465      * Returns the first class this method can find with the given tagged value or hyperlink. Both arguments are used to
466      * look for the tagged value but only <code>value</code> is used to search for the hyperlink.
467      * @param tag
468      * @param value
469      * @return classWithTaggedValue
470      */
471     static UmlClass findClassWithTaggedValueOrHyperlink(String tag, String value)
472     {
473         UmlClass classWithTaggedValue = null;
474 
475         Collection<UmlClass> classes = getModel().getCore().getUmlClass().refAllOfType();
476         for (final Iterator<UmlClass> classIterator = classes.iterator(); classIterator.hasNext() && classWithTaggedValue == null;)
477         {
478             // loop over all classes
479             UmlClass clazz = classIterator.next();
480             if (isTagPresent(clazz, tag, value) || isHyperlinkPresent(clazz, value))
481             {
482                 classWithTaggedValue = clazz;
483             }
484         }
485 
486         return classWithTaggedValue;
487     }
488 
489     /**
490      * @param useCase
491      * @return finalStates
492      */
493     static Collection<FinalState> findFinalStatesWithNameOrHyperlink(UseCase useCase)
494     {
495         List finalStates = new ArrayList();
496 
497         if (useCase != null && useCase.getName() != null)
498         {
499             String useCaseName = useCase.getName();
500             Collection<FinalState> allFinalStates = getModel().getStateMachines().getFinalState().refAllOfType();
501             for (final Iterator<FinalState> iterator = allFinalStates.iterator(); iterator.hasNext();)
502             {
503                 FinalState finalState = iterator.next();
504                 if (useCaseName != null)
505                 {
506                     if (useCaseName.equals(finalState.getName()))
507                     {
508                         finalStates.add(finalState);
509                     }
510                     else
511                     {
512                         if (isHyperlinkPresent(finalState, useCase))
513                         {
514                             finalStates.add(finalState);
515                         }
516                     }
517                 }
518                 else
519                 {
520                     if (isHyperlinkPresent(finalState, useCase))
521                     {
522                         finalStates.add(finalState);
523                     }
524                 }
525             }
526         }
527 
528         return finalStates;
529     }
530 
531     /**
532      * Finds the given metafacade class for the passed in <code>facade</code>.
533      *
534      * @param facade the model element facade for which to find the meta class.
535      * @return the meta model element
536      */
537     static ActivityGraph getMetaClass(ActivityGraphFacade facade)
538     {
539         ActivityGraph activityGraph = null;
540 
541         if (facade != null)
542         {
543             String id = facade.getId();
544             Collection<ModelElement> graphs = getModel().getActivityGraphs().getActivityGraph().refAllOfType();
545             for (final Iterator<ModelElement> iterator = graphs.iterator(); iterator.hasNext() && activityGraph == null;)
546             {
547                 ModelElement element = iterator.next();
548                 if (id.equals(element.refMofId()))
549                 {
550                     activityGraph = (ActivityGraph)element;
551                 }
552             }
553         }
554         return activityGraph;
555     }
556 
557     /**
558      * Finds the given metafacade class for the passed in <code>facade</code>.
559      *
560      * @param facade the model element facade for which to find the meta class.
561      * @return the meta model element
562      */
563     static UseCase getMetaClass(UseCaseFacade facade)
564     {
565         UseCase useCase = null;
566 
567         if (facade != null)
568         {
569             String id = facade.getId();
570             Collection<ModelElement> useCases = getModel().getUseCases().getUseCase().refAllOfType();
571             for (final Iterator<ModelElement> iterator = useCases.iterator(); iterator.hasNext() && useCase == null;)
572             {
573                 ModelElement element = iterator.next();
574                 if (id.equals(element.refMofId()))
575                 {
576                     useCase = (UseCase)element;
577                 }
578             }
579         }
580         return useCase;
581     }
582 
583     /**
584      * Finds the given metafacade class for the passed in <code>facade</code>.
585      *
586      * @param facade the model element facade for which to find the meta class.
587      * @return the meta model element
588      */
589     static Parameter getMetaClass(ParameterFacade facade)
590     {
591         Parameter parameter = null;
592 
593         if (facade != null)
594         {
595             String id = facade.getId();
596             Collection<ModelElement> parameters = getModel().getCore().getParameter().refAllOfType();
597             for (final Iterator<ModelElement> iterator = parameters.iterator(); iterator.hasNext() && parameter == null;)
598             {
599                 ModelElement element = iterator.next();
600                 if (id.equals(element.refMofId()))
601                 {
602                     parameter = (Parameter)element;
603                 }
604             }
605         }
606         return parameter;
607     }
608 
609     /**
610      * Finds the given metafacade class for the passed in <code>facade</code>.
611      *
612      * @param facade the model element facade for which to find the meta class.
613      * @return the meta model element
614      */
615     static Event getMetaClass(EventFacade facade)
616     {
617         Event event = null;
618 
619         if (facade != null)
620         {
621             String id = facade.getId();
622             Collection<ModelElement> events = getModel().getStateMachines().getEvent().refAllOfType();
623             for (final Iterator<ModelElement> iterator = events.iterator(); iterator.hasNext() && event == null;)
624             {
625                 ModelElement element = iterator.next();
626                 if (id.equals(element.refMofId()))
627                 {
628                     event = (Event)element;
629                 }
630             }
631         }
632         return event;
633     }
634 
635     /**
636      * Finds the given metafacade class for the passed in <code>facade</code>.
637      *
638      * @param facade the model element facade for which to find the meta class.
639      * @return the meta model element
640      */
641     static ModelElement getMetaClass(ModelElementFacade facade)
642     {
643         ModelElement modelElement = null;
644 
645         if (facade != null)
646         {
647             String id = facade.getId();
648             Collection<ModelElement> modelElements = getModel().getCore().getModelElement().refAllOfType();
649             for (final Iterator<ModelElement> iterator = modelElements.iterator(); iterator.hasNext() && modelElement == null;)
650             {
651                 ModelElement element = iterator.next();
652                 if (id.equals(element.refMofId()))
653                 {
654                     modelElement = element;
655                 }
656             }
657         }
658         return modelElement;
659     }
660 
661     /**
662      * Retrieves the serial version UID by reading the tagged value
663      * {@link UMLProfile#TAGGEDVALUE_SERIALVERSION_UID} of the
664      * <code>classifier</code>.
665      *
666      * @param classifier the classifier to be inspected.
667      * @return the serial version UID of the classifier. Returns
668      *         <code>null</code> if the tagged value cannot be found.
669      */
670     public static String getSerialVersionUID(ClassifierFacade classifier)
671     {
672         ExceptionUtils.checkNull("classifer", classifier);
673         String serialVersionString = (String)classifier
674                 .findTaggedValue(UMLProfile.TAGGEDVALUE_SERIALVERSION_UID);
675         return StringUtils.trimToNull(serialVersionString);
676     }
677 
678     /**
679      * This method removes all duplicates within the <code>elements</code> collection while at the same
680      * time copying tagged values from duplicates to the one remaining element with the given name.
681      *
682      * @param elements the elements to remove duplicates and copy tagged values to.
683      * @return the elements with duplicates removed.
684      */
685     public static List<ModelElementFacade> removeDuplicatesAndCopyTaggedValues(final Collection<ModelElementFacade> elements)
686     {
687         final Map<String, ModelElementFacade> map = new LinkedHashMap<String, ModelElementFacade>();
688         if (elements != null)
689         {
690             for (final Iterator<ModelElementFacade> iterator = elements.iterator(); iterator.hasNext();)
691             {
692                 ModelElementFacade element = iterator.next();
693                 final String name = element.getName();
694                 final ModelElementFacade existingVariable = map.get(name);
695                 // - copy over any tagged values from the existing variable to the new one.
696                 if (existingVariable != null)
697                 {
698                     element.copyTaggedValues(existingVariable);
699                 }
700                 map.put(
701                     name,
702                     element);
703             }
704         }
705         return new ArrayList<ModelElementFacade>(map.values());
706     }
707 }