protected void generateClassToQnameMapping(Data extData, ServiceInformation info)
      throws CodegenExtensionException {
    try {
      Mappings mappings = new Mappings();
      List<ClassToQname> classMappings = new LinkedList<ClassToQname>();
      // the first place to look for mappings is in the model information, which
      // is derived from the data service Domain Model.  If no domain model is to be used,
      // the mappings are still required to do anything with caCORE SDK beans.
      ModelInformation modelInfo = extData.getModelInformation();
      if (modelInfo != null
          && !ModelSourceType.none.equals(modelInfo.getSource())
          && modelInfo.getModelPackage() != null) {
        logger.debug("Model information / domain model found in service model.");
        logger.debug("Generating class to qname mapping from the information");
        logger.debug("stored in the service model");
        // walk packages in the model
        for (ModelPackage pack : modelInfo.getModelPackage()) {
          // locate a NamsepaceType in the service model mapped to this package
          NamespaceType mappedNamespace = null;
          for (NamespaceType nsType : info.getServiceDescriptor().getNamespaces().getNamespace()) {
            if (pack.getPackageName().equals(nsType.getPackageName())) {
              mappedNamespace = nsType;
              break;
            }
          }
          if (mappedNamespace != null && pack.getModelClass() != null) {
            // walk classes in this package, if any exist
            for (ModelClass clazz : pack.getModelClass()) {
              if (clazz.isTargetable()) {
                // find a schema element type mapped to this class
                for (SchemaElementType element : mappedNamespace.getSchemaElement()) {
                  if (clazz.getShortClassName().equals(element.getClassName())) {
                    // found it!  Create a mapping
                    QName qname = new QName(mappedNamespace.getNamespace(), element.getType());
                    String fullClassname = pack.getPackageName() + "." + clazz.getShortClassName();
                    ClassToQname map = new ClassToQname(fullClassname, qname.toString());
                    classMappings.add(map);
                    break;
                  }
                }
              }
            }
          } else {
            logger.warn(
                "Model package " + pack.getPackageName() + " is not mapped to any namespace!");
          }
        }
        ClassToQname[] mapArray = new ClassToQname[classMappings.size()];
        classMappings.toArray(mapArray);
        mappings.setMapping(mapArray);
      } else {
        logger.warn("No model information / domain model found in service model.");
        logger.warn("Falling back to schema information for class to qname mapping.");
        NamespaceType[] namespaces = info.getNamespaces().getNamespace();
        // a set of namespaces to ignore
        Set<String> nsIgnores = new HashSet<String>();
        nsIgnores.add(IntroduceConstants.W3CNAMESPACE);
        nsIgnores.add(info.getServices().getService(0).getNamespace());
        nsIgnores.add(DataServiceConstants.ENUMERATION_DATA_SERVICE_NAMESPACE);
        nsIgnores.add(DataServiceConstants.DATA_SERVICE_NAMESPACE);
        nsIgnores.add(DataServiceConstants.CQL_QUERY_URI);
        nsIgnores.add(DataServiceConstants.CQL_RESULT_SET_URI);

        for (int nsIndex = 0; nsIndex < namespaces.length; nsIndex++) {
          NamespaceType currentNs = namespaces[nsIndex];
          // ignore any unneeded namespaces
          if (!nsIgnores.contains(currentNs.getNamespace())) {
            SchemaElementType[] schemaElements = currentNs.getSchemaElement();
            for (int elemIndex = 0;
                schemaElements != null && elemIndex < schemaElements.length;
                elemIndex++) {
              SchemaElementType currentElement = schemaElements[elemIndex];
              ClassToQname toQname = new ClassToQname();
              QName qname = new QName(currentNs.getNamespace(), currentElement.getType());
              String shortClassName = currentElement.getClassName();
              if (shortClassName == null) {
                shortClassName = currentElement.getType();
              }
              String fullClassName = currentNs.getPackageName() + "." + shortClassName;
              toQname.setQname(qname.toString());
              toQname.setClassName(fullClassName);
              classMappings.add(toQname);
            }
          }
        }
      }

      ClassToQname[] mapArray = new ClassToQname[classMappings.size()];
      classMappings.toArray(mapArray);
      mappings.setMapping(mapArray);
      // create the filename where the mapping will be stored
      String mappingFilename =
          new File(
                  info.getBaseDirectory(),
                  "etc" + File.separator + DataServiceConstants.CLASS_TO_QNAME_XML)
              .getAbsolutePath();
      // serialize the mapping to that file
      Utils.serializeDocument(mappingFilename, mappings, DataServiceConstants.MAPPING_QNAME);
    } catch (Exception ex) {
      ex.printStackTrace();
      throw new CodegenExtensionException(
          "Error generating class to QName mapping: " + ex.getMessage(), ex);
    }
  }