public void startElement(String uri, String localName, String name, Attributes attributes)
        throws SAXException {
      // according to the spec, the elements should have the namespace,
      // except when the root element is the "component" element
      // So we check this for the first element, we receive.
      if (this.firstElement) {
        this.firstElement = false;
        if (localName.equals(COMPONENT) && "".equals(uri)) {
          this.overrideNamespace = NAMESPACE_URI_1_0;
        }
      }

      if (this.overrideNamespace != null && "".equals(uri)) {
        uri = this.overrideNamespace;
      }

      // however the spec also states that the inner elements
      // of a component are unqualified, so they don't have
      // the namespace - we allow both: with or without namespace!
      if (this.isComponent && "".equals(uri)) {
        uri = NAMESPACE_URI_1_0;
      }

      // from here on, uri has the namespace regardless of the used xml format
      if (NAMESPACE_URI_1_0.equals(uri)
          || NAMESPACE_URI_1_1.equals(uri)
          || NAMESPACE_URI_1_1_FELIX.equals(uri)) {

        if (NAMESPACE_URI_1_1.equals(uri)) {
          components.setSpecVersion(Constants.VERSION_1_1);
        } else if (NAMESPACE_URI_1_1_FELIX.equals(uri)) {
          components.setSpecVersion(Constants.VERSION_1_1_FELIX);
        }

        if (localName.equals(COMPONENT)) {
          this.isComponent = true;

          this.currentComponent = new Component();
          this.currentComponent.setName(attributes.getValue(COMPONENT_ATTR_NAME));

          // enabled attribute is optional
          if (attributes.getValue(COMPONENT_ATTR_ENABLED) != null) {
            this.currentComponent.setEnabled(
                Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_ENABLED)));
          }

          // immediate attribute is optional
          if (attributes.getValue(COMPONENT_ATTR_IMMEDIATE) != null) {
            this.currentComponent.setImmediate(
                Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_IMMEDIATE)));
          }

          this.currentComponent.setFactory(attributes.getValue(COMPONENT_ATTR_FACTORY));

          // check for version 1.1 attributes
          if (components.getSpecVersion() == Constants.VERSION_1_1) {
            this.currentComponent.setConfigurationPolicy(
                attributes.getValue(COMPONENT_ATTR_POLICY));
            this.currentComponent.setActivate(attributes.getValue(COMPONENT_ATTR_ACTIVATE));
            this.currentComponent.setDeactivate(attributes.getValue(COMPONENT_ATTR_DEACTIVATE));
            this.currentComponent.setModified(attributes.getValue(COMPONENT_ATTR_MODIFIED));
          }
        } else if (localName.equals(IMPLEMENTATION)) {
          // Set the implementation class name (mandatory)
          final Implementation impl = new Implementation();
          this.currentComponent.setImplementation(impl);
          impl.setClassname(attributes.getValue("class"));

        } else if (localName.equals(PROPERTY)) {

          // read the property, unless it is the service.pid
          // property which must not be inherited
          final String propName = attributes.getValue("name");
          if (!org.osgi.framework.Constants.SERVICE_PID.equals(propName)) {
            final Property prop = new Property();

            prop.setName(propName);
            prop.setType(attributes.getValue("type"));

            if (attributes.getValue("value") != null) {
              prop.setValue(attributes.getValue("value"));
              this.currentComponent.addProperty(prop);
            } else {
              // hold the property pending as we have a multi value
              this.pendingProperty = prop;
            }
            // check for abstract properties
            prop.setLabel(attributes.getValue("label"));
            prop.setDescription(attributes.getValue("description"));
            prop.setCardinality(attributes.getValue("cardinality"));
            final String pValue = attributes.getValue("private");
            if (pValue != null) {
              prop.setPrivate(Boolean.valueOf(pValue).booleanValue());
            }
          }

        } else if (localName.equals("properties")) {

          // TODO: implement the properties tag

        } else if (localName.equals(SERVICE)) {

          this.currentService = new Service();

          this.currentService.setServicefactory(attributes.getValue("servicefactory"));

          this.currentComponent.setService(this.currentService);

        } else if (localName.equals(INTERFACE)) {
          final Interface interf = new Interface();
          this.currentService.addInterface(interf);
          interf.setInterfacename(attributes.getValue("interface"));

        } else if (localName.equals(REFERENCE)) {
          final Reference ref = new Reference();

          ref.setName(attributes.getValue("name"));
          ref.setInterfacename(attributes.getValue("interface"));
          ref.setCardinality(attributes.getValue("cardinality"));
          ref.setPolicy(attributes.getValue("policy"));
          ref.setTarget(attributes.getValue("target"));
          ref.setBind(attributes.getValue("bind"));
          ref.setUnbind(attributes.getValue("unbind"));

          if (attributes.getValue("checked") != null) {
            ref.setChecked(Boolean.valueOf(attributes.getValue("checked")).booleanValue());
          }
          if (attributes.getValue("strategy") != null) {
            ref.setStrategy(attributes.getValue("strategy"));
          }

          this.currentComponent.addReference(ref);
        }
      }
    }
 /**
  * Write the xml for a {@link Property}.
  *
  * @param property
  * @param contentHandler
  * @throws SAXException
  */
 protected static void generateXML(
     Property property, ContentHandler contentHandler, boolean isScrPrivateFile)
     throws SAXException {
   final AttributesImpl ai = new AttributesImpl();
   IOUtils.addAttribute(ai, "name", property.getName());
   IOUtils.addAttribute(ai, "type", property.getType());
   IOUtils.addAttribute(ai, "value", property.getValue());
   // we have to write more information if this is our scr private file
   if (isScrPrivateFile) {
     IOUtils.addAttribute(ai, "private", String.valueOf(property.isPrivate()));
     if (property.getLabel() != null) {
       IOUtils.addAttribute(ai, "label", String.valueOf(property.getLabel()));
     }
     if (property.getDescription() != null) {
       IOUtils.addAttribute(ai, "description", String.valueOf(property.getDescription()));
     }
     if (property.getCardinality() != null) {
       IOUtils.addAttribute(ai, "cardinality", String.valueOf(property.getCardinality()));
     }
   }
   IOUtils.indent(contentHandler, 2);
   contentHandler.startElement(
       INNER_NAMESPACE_URI,
       ComponentDescriptorIO.PROPERTY,
       ComponentDescriptorIO.PROPERTY_QNAME,
       ai);
   if (property.getMultiValue() != null && property.getMultiValue().length > 0) {
     // generate a new line first
     IOUtils.text(contentHandler, "\n");
     for (int i = 0; i < property.getMultiValue().length; i++) {
       IOUtils.indent(contentHandler, 3);
       IOUtils.text(contentHandler, property.getMultiValue()[i]);
       IOUtils.newline(contentHandler);
     }
     IOUtils.indent(contentHandler, 2);
   }
   contentHandler.endElement(
       INNER_NAMESPACE_URI, ComponentDescriptorIO.PROPERTY, ComponentDescriptorIO.PROPERTY_QNAME);
   IOUtils.newline(contentHandler);
 }