gt:         final Set<EObject> eObjects = findAllEObjects(resourceSet);
context: /**
   * Copyright (C) 2015 Michael Schnell. All rights reserved. 
   * http://www.fuin.org/
   *
   * This library is free software; you can redistribute it and/or modify it under
   * the terms of the GNU Lesser General Public License as published by the Free
   * Software Foundation; either version 3 of the License, or (at your option) any
   * later version.
   *
   * This library is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
   * details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with this library. If not, see http://www.gnu.org/licenses/.
   */
  package org.fuin.srcgen4j.core.emf;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  
  import org.apache.commons.io.FilenameUtils;
  import org.eclipse.emf.common.notify.Notifier;
  import org.eclipse.emf.common.util.EList;
  import org.eclipse.emf.common.util.URI;
  import org.eclipse.emf.ecore.EObject;
  import org.eclipse.emf.ecore.InternalEObject;
  import org.eclipse.emf.ecore.resource.Resource;
  import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
  import org.eclipse.emf.ecore.resource.ResourceSet;
  import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
  import org.eclipse.emf.ecore.util.EcoreUtil;
  import org.fuin.srcgen4j.core.base.AbstractParser;
  import org.fuin.utils4j.Utils4J;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * Basic functionality for parsing EMF Ecore models.
   * 
   * @param <CONFIG_TYPE>
   *            Type of the concrete configuration.
   */
  public abstract class AbstractEMFParser<CONFIG_TYPE> extends AbstractParser<CONFIG_TYPE> {
  
      private static final Logger LOG = LoggerFactory.getLogger(AbstractEMFParser.class);
  
      private ResourceSet resourceSet = new ResourceSetImpl();
  
      private boolean error = false;
  
      private List<File> modelDirs;
  
      private List<String> fileExtensions;
  
      private List<URI> modelResources;
  
      /**
       * Basic constructor.
       * 
       * @param concreteConfigClass
       *            Type of the configuration.
       */
      protected AbstractEMFParser(final Class<CONFIG_TYPE> concreteConfigClass) {
          super(concreteConfigClass);
      }
  
      /**
       * Constructor with array.
       * 
       * @param concreteConfigClass
       *            Type of the configuration.
       * @param modelDirs
       *            Directory with the Ecore model files.
       * @param fileExtensions
       *            List of extensions for files to find ("mymodel", "java", "class", ...)
       */
      protected AbstractEMFParser(final Class<CONFIG_TYPE> concreteConfigClass, final List<File> modelDirs, final String... fileExtensions) {
          this(concreteConfigClass, modelDirs, Arrays.asList(fileExtensions));
      }
  
      /**
       * Constructor with list.
       * 
       * @param concreteConfigClass
       *            Type of the configuration.
       * @param modelDirs
       *            Directory with the Ecore model files.
       * @param fileExtensions
       *            List of extensions for files to find ("mymodel", "java", "class", ...)
       */
      protected AbstractEMFParser(final Class<CONFIG_TYPE> concreteConfigClass, final List<File> modelDirs, final List<String> fileExtensions) {
          super(concreteConfigClass);
          this.modelDirs = modelDirs;
          this.fileExtensions = fileExtensions;
      }
  
      /**
       * Parses all model files in the directories and all resources. y
       */
      protected final void parseModel() {
  
          if ((fileExtensions == null) || (fileExtensions.isEmpty())) {
              throw new IllegalStateException("No file extensions for EMF model files set!");
          }
  
          // Drop previous resource set
          resourceSet = new ResourceSetImpl();
          error = false;
  
          parseDirs();
          parseResources();
  
      }
  
      private void parseDirs() {
          if ((modelDirs == null) || (modelDirs.isEmpty())) {
              LOG.debug("No model directories to parse");
          } else {
              for (final File modelDir : modelDirs) {
                  parseDir(modelDir);
              }
          }
      }
  
      private void parseResources() {
          if ((modelResources == null) || (modelResources.isEmpty())) {
              LOG.debug("No model resources to parse");
          } else {
              for (final URI modelResource : modelResources) {
                  final Resource resource = resourceSet.getResource(modelResource, true);
                  final EList<Diagnostic> diagnostics = resource.getErrors();
                  if (diagnostics.isEmpty()) {
                      LOG.debug("Parsed {}", modelResource);
                  } else {
                      error = true;
                      LOG.error("Parsed {} with errors: {}", modelResource, diagnostics);
                  }
              }
          }
      }
  
      /**
       * Tries to resolve all proxies.
       */
      protected final void resolveProxies() {
          final List<String> unresolved = new ArrayList<>();
          if (!resolvedAllProxies(unresolved, 0)) {
              LOG.warn("Could not resolve the following proxies ({}):", unresolved.size());
              for (final String ref : unresolved) {
                  LOG.warn("Not found: {}", ref);
              }
              final Iterator<Notifier> it = resourceSet.getAllContents();
              while (it.hasNext()) {
                  final Notifier next = it.next();
                  if (next instanceof EObject) {
                      final EObject obj = (EObject) next;
                      if (obj.eIsProxy()) {
                          try {
                              it.remove();
                          } catch (final UnsupportedOperationException ex) {
                              LOG.error("Could not remove proxy: " + obj, ex);
                          }
                      }
                  }
              }
          }
      }
  
      /**
       * Returns files that end with java and all directories. Files and directories started with a "." are excluded.
       * 
       * @param dir
       *            Directory to scan.
       * 
       * @return List of files in the directory.
       */
      private File[] getFiles(final File dir) {
          return dir.listFiles(file ->  {
                  final boolean pointFile = file.getName().startsWith(".");
                  final String extension = FilenameUtils.getExtension(file.getName());
                  return (!pointFile && fileExtensions.contains(extension)) || file.isDirectory();
          });
      }
  
      /**
       * Parse the directory and it's sub directory.
       * 
       * @param dir
       *            Directory to parse.
       */
      private void parseDir(final File dir) {
          LOG.debug("Parse: {}", dir);
          final File[] files = getFiles(dir);
          if ((files == null) || (files.length == 0)) {
              LOG.debug("No files found in directory: {}", dir);
          } else {
              for (final File file : files) {
                  if (file.isFile()) {
                      final Resource resource = resourceSet.getResource(URI.createFileURI(Utils4J.getCanonicalPath(file)), true);
                      final EList<Diagnostic> diagnostics = resource.getErrors();
                      if (diagnostics.isEmpty()) {
                          LOG.debug("Parsed {}", file);
                      } else {
                          error = true;
                          LOG.error("Parsed {} with errors: {}", file, diagnostics);
                      }
                  } else {
                      parseDir(file);
                  }
              }
          }
      }
  
      /**
       * Determines if all proxies in the model are resolved.
       * 
       * @return {@code true} if there are no more proxies in the model.
       */
      public boolean isModelFullyResolved() {
  
          boolean resolved = true;
  