private void loadProfile(String n, Map<String, ProfileDefn> profiles) throws Exception {
   File spreadsheet = new CSFile(rootDir + ini.getStringProperty("profiles", n));
   if (TextFile.fileToString(spreadsheet.getAbsolutePath())
       .contains("urn:schemas-microsoft-com:office:spreadsheet")) {
     SpreadsheetParser sparser =
         new SpreadsheetParser(
             new CSFileInputStream(spreadsheet),
             spreadsheet.getName(),
             definitions,
             srcDir,
             logger,
             registry);
     try {
       ProfileDefn profile = sparser.parseProfile(definitions);
       definitions.getProfiles().put(n, profile);
     } catch (Exception e) {
       throw new Exception("Error Parsing Profile: '" + n + "': " + e.getMessage(), e);
     }
   } else {
     ProfileDefn profile = new ProfileDefn();
     try {
       profile.setSource((Profile) new XmlParser().parse(new FileInputStream(spreadsheet)));
       definitions.getProfiles().put(n, profile);
     } catch (Exception e) {
       throw new Exception("Error Parsing Profile: '" + n + "': " + e.getMessage(), e);
     }
   }
 }
  private String loadCompositeType(String n, Map<String, ElementDefn> map) throws Exception {
    TypeParser tp = new TypeParser();
    List<TypeRef> ts = tp.parse(n);
    definitions.getKnownTypes().addAll(ts);

    try {
      TypeRef t = ts.get(0);
      File csv = new CSFile(dtDir + t.getName().toLowerCase() + ".xml");
      if (csv.exists()) {
        SpreadsheetParser p =
            new SpreadsheetParser(
                new CSFileInputStream(csv), csv.getName(), definitions, srcDir, logger, registry);
        ElementDefn el = p.parseCompositeType();
        map.put(t.getName(), el);
        el.getAcceptableGenericTypes().addAll(ts.get(0).getParams());
        return el.getName();
      } else {
        String p = ini.getStringProperty("types", n);
        csv = new CSFile(dtDir + p.toLowerCase() + ".xml");
        if (!csv.exists()) throw new Exception("unable to find a definition for " + n + " in " + p);
        XLSXmlParser xls = new XLSXmlParser(new CSFileInputStream(csv), csv.getAbsolutePath());
        Sheet sheet = xls.getSheets().get("Restrictions");
        boolean found = false;
        for (int i = 0; i < sheet.rows.size(); i++) {
          if (sheet.getColumn(i, "Name").equals(n)) {
            found = true;
            Invariant inv = new Invariant();
            inv.setId(n);
            inv.setEnglish(sheet.getColumn(i, "Rules"));
            inv.setOcl(sheet.getColumn(i, "OCL"));
            inv.setXpath(sheet.getColumn(i, "XPath"));
            definitions.getConstraints().put(n, new DefinedCode(n, sheet.getColumn(i, "Rules"), p));
            definitions.getConstraintInvariants().put(n, inv);
          }
        }
        if (!found) throw new Exception("Unable to find definition for " + n);
        return n;
      }
    } catch (Exception e) {
      throw new Exception("Unable to load " + n + ": " + e.getMessage(), e);
    }
  }
  private ResourceDefn loadResource(String n, Map<String, ResourceDefn> map, boolean sandbox)
      throws Exception {
    String src = sandbox ? sndBoxDir : srcDir;
    File spreadsheet =
        new CSFile(
            (sandbox ? sndBoxDir : srcDir) + n + File.separatorChar + n + "-spreadsheet.xml");
    if (!spreadsheet.exists())
      spreadsheet =
          new CSFile((sandbox ? sndBoxDir : srcDir) + n + File.separatorChar + n + "-def.xml");

    SpreadsheetParser sparser =
        new SpreadsheetParser(
            new CSFileInputStream(spreadsheet),
            spreadsheet.getName(),
            definitions,
            src,
            logger,
            registry);
    ResourceDefn root;
    try {
      root = sparser.parseResource();
    } catch (Exception e) {
      throw new Exception("Error Parsing Resource " + n + ": " + e.getMessage(), e);
    }

    root.setSandbox(sandbox);
    for (EventDefn e : sparser.getEvents()) processEvent(e, root.getRoot());

    // EK: Commented this out, seems double with next statement, since
    // loadResource()
    // is always called with definitions.getResources in its map argument.
    // definitions.getResources().put(root.getName(), root);
    if (map != null) {
      map.put(root.getName(), root);
      definitions
          .getKnownResources()
          .put(root.getName(), new DefinedCode(root.getName(), root.getRoot().getDefinition(), n));
    }
    root.setStatus(ini.getStringProperty("status", n));
    return root;
  }
  public void parse(Calendar genDate, String version) throws Exception {
    logger.log("Loading", LogMessageType.Process);

    eCoreParseResults = DefinitionsImpl.build(genDate.getTime(), version);

    loadGlobalConceptDomains();
    eCoreParseResults
        .getBinding()
        .addAll(
            sortBindings(
                BindingConverter.buildBindingsFromFhirModel(
                    definitions.getBindings().values(), null)));

    loadPrimitives();

    eCoreParseResults
        .getPrimitive()
        .addAll(
            PrimitiveConverter.buildPrimitiveTypesFromFhirModel(
                definitions.getPrimitives().values()));

    for (String n : ini.getPropertyNames("removed-resources"))
      definitions.getDeletedResources().add(n);

    for (String n : ini.getPropertyNames("types")) loadCompositeType(n, definitions.getTypes());
    for (String n : ini.getPropertyNames("structures"))
      loadCompositeType(n, definitions.getStructures());

    String[] shared = ini.getPropertyNames("shared");
    if (shared != null)
      for (String n : shared)
        definitions.getShared().add(loadCompositeType(n, definitions.getStructures()));

    for (String n : ini.getPropertyNames("infrastructure"))
      loadCompositeType(n, definitions.getInfrastructure());

    List<TypeDefn> allFhirComposites = new ArrayList<TypeDefn>();

    allFhirComposites.add(CompositeTypeConverter.buildElementBaseType());

    allFhirComposites.addAll(
        PrimitiveConverter.buildCompositeTypesForPrimitives(eCoreParseResults.getPrimitive()));

    allFhirComposites.addAll(
        CompositeTypeConverter.buildCompositeTypesFromFhirModel(
            definitions.getTypes().values(), null));

    allFhirComposites.addAll(
        CompositeTypeConverter.buildCompositeTypesFromFhirModel(
            definitions.getStructures().values(), null));

    List<CompositeTypeDefn> infra =
        CompositeTypeConverter.buildCompositeTypesFromFhirModel(
            definitions.getInfrastructure().values(), null);
    for (CompositeTypeDefn composite : infra) composite.setInfrastructure(true);
    allFhirComposites.addAll(infra);

    allFhirComposites.addAll(
        ConstrainedTypeConverter.buildConstrainedTypesFromFhirModel(
            definitions.getConstraints().values(), definitions.getConstraintInvariants()));

    eCoreParseResults.getType().addAll(sortTypes(allFhirComposites));

    for (String n : ini.getPropertyNames("resources"))
      loadResource(n, definitions.getResources(), false);

    ResourceDefn baseResource = loadResource("resource", null, false);
    baseResource.setAbstract(true);
    definitions.setBaseResource(baseResource);

    loadCompartments();
    loadStatusCodes();

    org.hl7.fhir.definitions.ecore.fhir.ResourceDefn eCoreBaseResource =
        CompositeTypeConverter.buildResourceFromFhirModel(baseResource, null);
    eCoreBaseResource.getElement().add(CompositeTypeConverter.buildInternalIdElement());
    eCoreParseResults.getType().add(eCoreBaseResource);

    eCoreParseResults
        .getType()
        .addAll(
            sortTypes(
                CompositeTypeConverter.buildResourcesFromFhirModel(
                    definitions.getResources().values())));

    eCoreParseResults.getType().add(CompositeTypeConverter.buildBinaryResourceDefn());

    for (String n : ini.getPropertyNames("svg"))
      definitions.getDiagrams().put(n, ini.getStringProperty("svg", n));

    if (ini.getPropertyNames("future-resources") != null)
      for (String n : ini.getPropertyNames("future-resources")) {
        DefinedCode cd =
            new DefinedCode(ini.getStringProperty("future-resources", n), "Yet to be defined", n);
        definitions.getKnownResources().put(n, cd);

        ResourceDefn futureResource = new ResourceDefn();
        futureResource.setName(cd.getCode());
        futureResource.setDefinition("Future resource " + cd.getCode() + ". As yet undefined.");
        futureResource.setForFutureUse(true);
        definitions.getFutureResources().put(cd.getCode(), futureResource);
      }

    eCoreParseResults
        .getType()
        .addAll(
            CompositeTypeConverter.buildResourcesFromFhirModel(
                definitions.getFutureResources().values()));

    eCoreParseResults
        .getEvent()
        .addAll(EventConverter.buildEventsFromFhirModel(definitions.getEvents().values()));

    // As a second pass, resolve typerefs to the types
    fixTypeRefs(eCoreParseResults);

    eCoreParseResults
        .getBinding()
        .add(BindingConverter.buildResourceTypeBinding(eCoreParseResults));

    for (String n : ini.getPropertyNames("special-resources"))
      definitions.getAggregationEndpoints().add(n);

    String[] pn = ini.getPropertyNames("valuesets");
    if (pn != null)
      for (String n : pn) {
        loadValueSet(n);
      }
    for (String n : ini.getPropertyNames("profiles")) {
      loadProfile(n, definitions.getProfiles());
    }

    for (ResourceDefn r : definitions.getResources().values()) {
      for (RegisteredProfile p : r.getProfiles()) {
        SpreadsheetParser sparser =
            new SpreadsheetParser(
                new CSFileInputStream(p.getFilepath()),
                p.getName(),
                definitions,
                srcDir,
                logger,
                registry);
        sparser.setFolder(Utilities.getDirectoryForFile(p.getFilepath()));
        p.setProfile(sparser.parseProfile(definitions));
      }
    }
  }