private void create_device_project(
      final IPath projectPath,
      final String deviceType,
      final String lang,
      final String codegenId,
      final String templateId,
      final IProgressMonitor progressMonitor)
      throws CoreException {
    final SubMonitor monitor = SubMonitor.convert(progressMonitor, 1);

    final String projectName = projectPath.lastSegment();
    final java.net.URI locationURI = projectPath.toFile().toURI();

    final ICodeGeneratorDescriptor code_gen = findCodeGen(lang, codegenId);

    final ITemplateDesc template = findCodeGenTemplate(templateId, code_gen);

    // Create the implementation
    final SoftPkg spd = SpdFactory.eINSTANCE.createSoftPkg();
    final Implementation impl = SpdFactory.eINSTANCE.createImplementation();
    spd.getImplementation().add(impl);
    final ImplementationSettings settings = CodegenFactory.eINSTANCE.createImplementationSettings();

    initializeSoftPkg(lang, projectName, code_gen, template, spd, impl, settings);

    final WorkspaceModifyOperation operation =
        new WorkspaceModifyOperation() {

          @Override
          protected void execute(final IProgressMonitor progress_monitor)
              throws CoreException, InvocationTargetException, InterruptedException {
            final SubMonitor monitor = SubMonitor.convert(progress_monitor, 2);

            final IProject project =
                DeviceProjectCreator.createEmptyProject(
                    projectName, locationURI, monitor.newChild(1));

            DeviceProjectCreator.createDeviceFiles(
                project, spd.getName(), spd.getId(), "", deviceType, false, monitor.newChild(1));

            ProjectCreator.addImplementation(
                project, spd.getName(), impl, settings, monitor.newChild(1));

            // Setup the IDL Path
            ResourceUtils.createIdlLibraryResource(project, monitor.newChild(1));
          }
        };
    try {
      operation.run(monitor.newChild(1));
    } catch (final InvocationTargetException e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR, CodegeneratorApplication.PLUGIN_ID, "Failure creating project", e));
    } catch (final InterruptedException e) {
      // pass
    }
  }
  private List<Resource> addEventPort(final SoftPkg spd) throws CoreException {
    final Descriptor desc = spd.getDescriptor();
    if (desc != null) {
      final SoftwareComponent scd = desc.getComponent();
      ComponentFeatures features = scd.getComponentFeatures();
      if (features == null) {
        features = ScdFactory.eINSTANCE.createComponentFeatures();
        scd.setComponentFeatures(features);
      }
      Ports ports = features.getPorts();
      if (ports == null) {
        ports = ScdFactory.eINSTANCE.createPorts();
        features.setPorts(ports);
      }

      Interfaces interfaces = scd.getInterfaces();
      boolean found = false;
      if (interfaces != null) {
        for (final Interface i : interfaces.getInterface()) {
          if (EventChannelHelper.id().equals(i.getRepid())) {
            found = true;
            break;
          }
        }
      } else {
        interfaces = ScdFactory.eINSTANCE.createInterfaces();
        scd.setInterfaces(interfaces);
      }

      if (!found) {
        final Interface i = ScdFactory.eINSTANCE.createInterface();
        i.setName("EventChannel");
        i.setRepid(EventChannelHelper.id());
        interfaces.getInterface().add(i);
      }

      final Uses uses = ScdFactory.eINSTANCE.createUses();
      ports.getUses().add(uses);
      uses.setName(Uses.PORT_NAME_PROP_EVENTS);
      uses.setRepID(EventChannelHelper.id());
      final PortTypeContainer ptc = ScdFactory.eINSTANCE.createPortTypeContainer();
      ptc.setType(PortType.RESPONSES);
      uses.getPortType().add(ptc);

      return Collections.singletonList(scd.eResource());
    } else {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              ComponentUiPlugin.PLUGIN_ID,
              "No descriptor, quick fix failed for " + spd.eResource().getURI().path(),
              null));
    }
  }
  @Test
  public void initEnv_component() throws CoreException, URISyntaxException, IOException {
    SdrRoot sdr = SdrPluginLoader.getSdrRoot(PLUGIN_ID, DEFAULT_SDR_PATH);
    SoftPkg spd =
        sdr.getComponentsContainer().getSoftPkg("DCE:4f46ef40-8c58-47e3-904b-e725b366808b");
    Assert.assertEquals("CppComponent", spd.getName());

    Map<String, String> map = new HashMap<String, String>();
    mapper.initEnv(spd.getImplementation("cpp"), map);
    Assert.assertEquals(1, map.size());
    checkOctavePath(map, new String[0]);
  }
  @Test
  public void initEnv_componentWithDeps() throws CoreException, URISyntaxException, IOException {
    SdrRoot sdr = SdrPluginLoader.getSdrRoot(PLUGIN_ID, DEFAULT_SDR_PATH);
    SoftPkg spd =
        sdr.getComponentsContainer().getSoftPkg("DCE:2fc3c8c5-a984-4be7-87c5-16ff9f0d0c8f");
    Assert.assertEquals("CppComponentWithDeps", spd.getName());

    Map<String, String> map = new HashMap<String, String>();
    mapper.initEnv(spd.getImplementation("cpp"), map);
    Assert.assertEquals(1, map.size());
    String sdrDom = getSdrDomLocation();
    String[] paths = {
      sdrDom + "/deps/CppDepD/cpp/lib",
      sdrDom + "/deps/CppDepDE/cpp/lib",
      sdrDom + "/deps/CppDepA/cpp/lib",
      sdrDom + "/deps/CppDepAC/cpp/lib",
      sdrDom + "/deps/CppDepAB/cpp/lib"
    };
    checkOctavePath(map, paths);
  }
  private void initializeSoftPkg(
      final String lang,
      final String projectName,
      final ICodeGeneratorDescriptor code_gen,
      final ITemplateDesc template,
      final SoftPkg spd,
      final Implementation impl,
      final ImplementationSettings settings) {
    spd.setId(DceUuidUtil.createDceUUID());
    spd.setName(projectName);

    final ProgrammingLanguage pl = SpdFactory.eINSTANCE.createProgrammingLanguage();
    final HumanLanguage hl = SpdFactory.eINSTANCE.createHumanLanguage();
    pl.setName(lang);
    impl.setProgrammingLanguage(pl);
    hl.setName(RedhawkCodegenActivator.ENGLISH);
    impl.setHumanLanguage(hl);
    if (code_gen.getCompiler() != null) {
      final Compiler c = SpdFactory.eINSTANCE.createCompiler();
      c.setName(code_gen.getCompiler());
      c.setVersion(code_gen.getCompilerVersion());
      impl.setCompiler(c);
    } else {
      impl.setCompiler(null);
    }
    if (code_gen.getRuntime() != null) {
      final mil.jpeojtrs.sca.spd.Runtime r = SpdFactory.eINSTANCE.createRuntime();
      r.setName(code_gen.getRuntime());
      r.setVersion(code_gen.getRuntimeVersion());
      impl.setRuntime(r);
    } else {
      impl.setRuntime(null);
    }

    settings.setGeneratorId(code_gen.getId());
    settings.setOutputDir(CodegenFileHelper.createDefaultOutputDir(spd, code_gen));
    settings.setTemplate(template.getId());
    impl.setId(settings.getOutputDir());
  }
  /**
   * Recursive method to dive down into a softpackage, find any shared library dependencies for it
   * and any children
   *
   * @param spd The Soft Package to begin the recurive dive
   * @param incPaths The Set to store the include paths.
   */
  private void populateIncludePaths(SoftPkg spd, Set<IPath> incPaths) {
    if (spd == null) {
      return;
    }

    // We need to check if the project contains any shared library dependencies for all the
    // implementations
    for (Implementation impl : spd.getImplementation()) {
      EList<Dependency> deps = impl.getDependency();
      for (Dependency dep : deps) {
        // Construct the include path based on the dependency local file name
        String sharedLibraryPath =
            ScaEcoreUtils.getFeature(
                dep,
                SpdPackage.Literals.DEPENDENCY__SOFT_PKG_REF,
                SpdPackage.Literals.SOFT_PKG_REF__LOCAL_FILE,
                SpdPackage.Literals.LOCAL_FILE__NAME);
        if (sharedLibraryPath == null) {
          continue;
        }
        IPath includeDirPath =
            new Path("${SdrRoot}")
                .append("dom")
                .append(sharedLibraryPath)
                .removeLastSegments(1)
                .append("include");

        // This check prevents us from getting into a circular loop in the case where there
        // is a circular dependency within the shared library list.
        if (incPaths.contains(includeDirPath)) {
          continue;
        }

        incPaths.add(includeDirPath);

        // Retrieve the SoftPkg object for the shared library and recurse. May return null if the
        // SPD file
        // isn't present in the SDRROOT.
        SoftPkg sharedLibrary =
            ScaEcoreUtils.getFeature(
                dep,
                SpdPackage.Literals.DEPENDENCY__SOFT_PKG_REF,
                SpdPackage.Literals.SOFT_PKG_REF__SOFT_PKG);
        populateIncludePaths(sharedLibrary, incPaths);
      }
    }
  }
  /** {@inheritDoc} */
  public String generate(Object argument) {
    final StringBuffer stringBuffer = new StringBuffer();

    TemplateParameter templ = (TemplateParameter) argument;
    ImplementationSettings implSettings = templ.getImplSettings();
    Implementation impl = templ.getImpl();
    SoftPkg softPkg = (SoftPkg) impl.eContainer();
    String PREFIX =
        gov.redhawk.ide.codegen.util.CodegenFileHelper.getPreferredFilePrefix(
            softPkg, implSettings);
    boolean hasSddsPort = false;
    Date date = new Date(System.currentTimeMillis());
    EList<Provides> provides =
        softPkg.getDescriptor().getComponent().getComponentFeatures().getPorts().getProvides();

    for (Provides entry : provides) {
      if (entry.getRepID().contains("BULKIO/dataSDDS")) {
        hasSddsPort = true;
      }
    }

    stringBuffer.append(TEXT_1);
    stringBuffer.append(ModelUtil.getSpdFileName(softPkg));
    stringBuffer.append(TEXT_2);
    stringBuffer.append(date.toString());

    String[] output;
    IProduct product = Platform.getProduct();
    if (product != null) {
      output = product.getProperty("aboutText").split("\n");

      stringBuffer.append(TEXT_3);
      stringBuffer.append(output[0]);
      stringBuffer.append(TEXT_4);
      stringBuffer.append(output[1]);
      stringBuffer.append(TEXT_5);
      stringBuffer.append(output[2]);
    }

    stringBuffer.append(TEXT_6);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_7);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_8);
    if (!templ.isDevice()) {
      stringBuffer.append(TEXT_9);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_10);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_11);
      stringBuffer.append(TEXT_12);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_13);
    } else {
      stringBuffer.append(TEXT_14);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_15);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_16);
      stringBuffer.append(TEXT_17);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_18);
      stringBuffer.append(TEXT_19);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_20);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_21);
      stringBuffer.append(TEXT_22);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_23);
      stringBuffer.append(TEXT_24);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_25);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_26);
      stringBuffer.append(TEXT_27);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_28);
      stringBuffer.append(TEXT_29);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_30);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_31);
      stringBuffer.append(TEXT_32);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_33);
    }
    stringBuffer.append(TEXT_34);
    stringBuffer.append(TEXT_35);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_36);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_37);
    if (hasSddsPort) {
      stringBuffer.append(TEXT_38);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_39);
      stringBuffer.append(PREFIX);
      stringBuffer.append(TEXT_40);
    }
    stringBuffer.append(TEXT_41);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_42);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_43);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_44);
    stringBuffer.append(TEXT_45);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_46);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_47);
    stringBuffer.append(TEXT_48);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_49);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_50);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_51);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_52);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_53);
    stringBuffer.append(PREFIX);
    stringBuffer.append(TEXT_54);
    stringBuffer.append(TEXT_55);
    return stringBuffer.toString();
  }
  @SuppressWarnings("deprecation")
  private WaveDevSettings getWaveDevSettings(
      final ResourceSet set, final SoftPkg softPkg, final String codegenId, final String templateId)
      throws CoreException {
    WaveDevSettings retVal = null;
    // First, try to get the .wavedev from disk. This will throw an exception if it fails.
    try {
      retVal =
          CodegenUtil.getWaveDevSettings(
              set.getResource(CodegenUtil.getSettingsURI(softPkg), true));
    } catch (final Exception e) {
      System.out.println("Unable to find the settings file, inferring defaults");
    }

    // if we weren't able to find the wavedev, create it
    if (retVal == null) {
      retVal = CodegenFactory.eINSTANCE.createWaveDevSettings();
      // Recreate the basic settings for each implementation
      // This makes assumptions that the defaults are selected for everything
      for (final Implementation impl : softPkg.getImplementation()) {
        final ImplementationSettings settings =
            CodegenFactory.eINSTANCE.createImplementationSettings();
        final String lang = impl.getProgrammingLanguage().getName();

        // Find the code generator if specified, otherwise pick the first one returned by the
        // registry
        ICodeGeneratorDescriptor codeGenDesc = null;
        if (codegenId != null) {
          codeGenDesc = RedhawkCodegenActivator.getCodeGeneratorsRegistry().findCodegen(codegenId);
        } else {
          final ICodeGeneratorDescriptor[] codeGens =
              RedhawkCodegenActivator.getCodeGeneratorsRegistry().findCodegenByLanguage(lang);
          if (codeGens.length > 0) {
            codeGenDesc = codeGens[0];
          }
        }

        // Proceed if we found one
        if (codeGenDesc != null) {
          final IScaComponentCodegen generator = codeGenDesc.getGenerator();

          // Assume that there is <name>[/].+<other> format for the entrypoint
          // Pick out <name> for both the output dir and settings name
          final String lf = impl.getCode().getEntryPoint();
          final String name = lf.substring(0, lf.indexOf('/'));

          // Set the generator, settings name and output directory
          settings.setGeneratorId(generator.getClass().getCanonicalName());
          settings.setName(name);
          settings.setOutputDir(lf.substring(0, lf.lastIndexOf('/')));

          // Find the template if specified, otherwise pick the first selectable and defaultable one
          // returned by the registry
          ITemplateDesc templateDesc = null;
          if (templateId != null) {
            templateDesc =
                RedhawkCodegenActivator.getCodeGeneratorTemplatesRegistry()
                    .findTemplate(templateId);
          } else {
            final ITemplateDesc[] templates =
                RedhawkCodegenActivator.getCodeGeneratorTemplatesRegistry()
                    .findTemplatesByCodegen(settings.getGeneratorId());
            for (final ITemplateDesc itd : templates) {
              if (itd.isSelectable() && !itd.notDefaultableGenerator()) {
                templateDesc = itd;
                break;
              }
            }
          }

          // If we found the template, use it
          if (templateDesc != null) {
            // Set the properties to their default values
            for (final IPropertyDescriptor prop : templateDesc.getPropertyDescriptors()) {
              final Property p = CodegenFactory.eINSTANCE.createProperty();
              p.setId(prop.getKey());
              p.setValue(prop.getDefaultValue());
              settings.getProperties().add(p);
            }
            // Set the template
            settings.setTemplate(templateDesc.getId());
          } else {
            System.err.println("Unable to find a valid template! Desired: " + templateId);
          }
        } else {
          System.err.println("Unable to find a valid Code Generator! Desired: " + codegenId);
        }
        // Save the created settings
        retVal.getImplSettings().put(impl.getId(), settings);
      }
      // Create the URI to the .wavedev file
      final URI uri =
          URI.createPlatformResourceURI(
              softPkg.getName() + "/." + softPkg.getName() + ".wavedev", false);
      final Resource res = set.createResource(uri);

      // Add the WaveDevSettings to the resource and save to disk to persist the newly created
      // WaveDevSettings
      res.getContents().add(retVal);
      try {
        res.save(null);
      } catch (final IOException e) {

      }
    }
    return retVal;
  }
  // TODO - turn this into an OSGi command
  private void generate_code(
      final String project_path,
      final String lang,
      String codegenId,
      final String templateId,
      final String[] preserveFiles,
      final NullProgressMonitor progressMonitor)
      throws CoreException {
    final SubMonitor monitor = SubMonitor.convert(progressMonitor, 2);

    final ResourceSet set = ScaResourceFactoryUtil.createResourceSet();

    final IPath projectPath = new Path(project_path);
    final IProject project = openProject(projectPath);
    final SoftPkg softPkg = getSoftPkg(project);

    if (softPkg == null) {
      throw new IllegalStateException("Could not load spd.xml for project");
    }

    // Create or open the existing settings
    final WaveDevSettings waveDev = getWaveDevSettings(set, softPkg, codegenId, templateId);
    if (waveDev == null) {
      throw new IllegalStateException("Could not load wavedev settings for project");
    }

    final EMap<String, ImplementationSettings> implSet = waveDev.getImplSettings();

    // Try generate each implementation, or just the specified language
    for (final Implementation impl : softPkg.getImplementation()) {
      final String currLang = impl.getProgrammingLanguage().getName();
      if ((lang != null) && !lang.equals(currLang.toLowerCase())) {
        continue;
      }

      // Prepare for generation
      final ImplementationSettings settings = implSet.get(impl.getId());
      final ArrayList<FileToCRCMap> crcMap = new ArrayList<FileToCRCMap>();

      System.out.println("\n\nGenerating " + currLang + " code for " + softPkg.getName());

      // Validate the settings name
      final String implName = CodegenFileHelper.safeGetImplementationName(impl, settings);
      if (!implName.equals(CodegenUtil.getValidName(implName))) {
        System.err.println("Invalid characters in implementation name for " + implName);
        continue;
      } else if (settings.getGeneratorId() != null) {
        // Find the desired code generator
        codegenId = settings.getGeneratorId();
        final ICodeGeneratorDescriptor codeGenDesc =
            RedhawkCodegenActivator.getCodeGeneratorsRegistry().findCodegen(codegenId);
        if (codeGenDesc == null) {
          System.err.println(
              "The code generator(" + codegenId + ") for this implementation could not be found.");
          continue;
        }
        // Get the actual code generator
        final IScaComponentCodegen generator = codeGenDesc.getGenerator();
        // Get files to generate
        final Set<FileStatus> fileStatusSet = generator.getGeneratedFilesStatus(settings, softPkg);
        final Set<String> fileList = new HashSet<String>();
        for (FileStatus s : fileStatusSet) {
          fileList.add(s.getFilename());
        }
        // Remove files we don't want to delete
        if (preserveFiles.length != 0) {
          if ("*".equals(preserveFiles[0])) {
            fileList.clear();
          } else {
            for (final String f : preserveFiles) {
              if (fileList.contains(f)) {
                fileList.remove(f);
              }
            }
          }
        }
        // Generate the files
        final IStatus status =
            generator.generate(
                settings,
                impl,
                System.out,
                System.err,
                monitor.newChild(1),
                fileList.toArray(new String[0]),
                generator.shouldGenerate(),
                crcMap);
        // Save the workspace
        final WorkspaceModifyOperation operation =
            new WorkspaceModifyOperation() {

              @Override
              protected void execute(final IProgressMonitor monitor)
                  throws CoreException, InvocationTargetException, InterruptedException {
                final IStatus saveStatus = ResourcesPlugin.getWorkspace().save(true, monitor);
                // Check the save results, hopefully this worked
                if (!saveStatus.isOK()) {
                  System.err.println(
                      "Generated files, but there was a problem saving the workspace: "
                          + saveStatus.getMessage());
                }
              }
            };
        try {
          operation.run(monitor.newChild(1));
        } catch (final InvocationTargetException e) {
          throw new CoreException(
              new Status(
                  IStatus.ERROR, CodegeneratorApplication.PLUGIN_ID, "Error saving resources", e));
        } catch (final InterruptedException e) {
          throw new CoreException(
              new Status(
                  IStatus.ERROR, CodegeneratorApplication.PLUGIN_ID, "Error saving resources", e));
        }

        // Check the results
        if (!status.isOK()) {
          System.err.println(
              "\nErrors occurred generating " + currLang + " code: " + status.getMessage());
          continue;
        } else {
          System.out.println("\nDone generating " + currLang + " code!");
        }
      } else {
        System.err.println(
            "No generator specified for implementation: " + implName + ". No code generated.");
      }
    }

    project.build(IncrementalProjectBuilder.FULL_BUILD, monitor.newChild(1));
  }