public Map<String, Object> getMetatypeDefaults(String symbolicName, String factoryPid) {
    Map<String, Object> properties = new HashMap<>();
    ObjectClassDefinition bundleMetatype = getObjectClassDefinition(symbolicName, factoryPid);
    if (bundleMetatype != null) {
      for (AttributeDefinition attributeDef :
          bundleMetatype.getAttributeDefinitions(ObjectClassDefinition.ALL)) {
        if (attributeDef.getID() != null) {
          if (attributeDef.getDefaultValue() != null) {
            if (attributeDef.getCardinality() == 0) {
              properties.put(
                  attributeDef.getID(),
                  getAttributeValue(attributeDef.getDefaultValue()[0], attributeDef.getType()));
            } else {
              properties.put(attributeDef.getID(), attributeDef.getDefaultValue());
            }
          } else if (attributeDef.getCardinality() != 0) {
            properties.put(attributeDef.getID(), new String[0]);
          }
        }
      }
    } else {
      LOGGER.debug("Metatype was null, returning an empty properties Map");
    }

    return properties;
  }
  public void designate(
      String factoryPid,
      String pid,
      String ocdref,
      Configuration conf,
      List<AE> currentAttributes) {

    ObjectClassDefinition ocd;
    ocd = OCDs.get(ocdref);

    if (ocd != null) {
      if (conf != null && currentAttributes.size() > 0) {
        final AttributeDefinition[] attrDefs =
            ocd.getAttributeDefinitions(ObjectClassDefinition.ALL);
        final Hashtable<String, AttributeDefinition> ADs =
            new Hashtable<String, AttributeDefinition>(); // id is key
        for (final AttributeDefinition ad : attrDefs) {
          ADs.put(ad.getID(), ad);
        }

        final Dictionary<String, Object> props = conf.getProperties();

        for (final AE ae : currentAttributes) {
          final AttributeDefinition ad = ADs.get(ae.adref);

          if (ad != null) {
            Object value = null;
            final int card = ad.getCardinality();

            switch (ad.getType()) {
              case AttributeDefinition.STRING:
                if (card < 0) {
                  final Vector<String> res = new Vector<String>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add((String) values.nextElement());
                  }
                  value = res;
                } else if (card > 0) {
                  final String[] res = new String[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = (String) values.nextElement();
                  }
                  value = res;
                } else {
                  value = ae.values.elementAt(0);
                }
                break;
              case AttributeDefinition.BOOLEAN:
                if (card < 0) {
                  final Vector<Boolean> res = new Vector<Boolean>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Boolean.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Boolean[] res = new Boolean[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Boolean.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Boolean.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.BYTE:
                if (card < 0) {
                  final Vector<Byte> res = new Vector<Byte>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Byte.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Byte[] res = new Byte[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Byte.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Byte.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.DOUBLE:
                if (card < 0) {
                  final Vector<Double> res = new Vector<Double>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Double.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Double[] res = new Double[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Double.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Double.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.FLOAT:
                if (card < 0) {
                  final Vector<Float> res = new Vector<Float>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Float.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Float[] res = new Float[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Float.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Float.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.INTEGER:
                if (card < 0) {
                  final Vector<Integer> res = new Vector<Integer>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Integer.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Integer[] res = new Integer[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Integer.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Integer.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.LONG:
                if (card < 0) {
                  final Vector<Long> res = new Vector<Long>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Long.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Long[] res = new Long[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Long.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Long.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.SHORT:
                if (card < 0) {
                  final Vector<Short> res = new Vector<Short>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(Short.valueOf((String) values.nextElement()));
                  }
                  value = res;
                } else if (card > 0) {
                  final Short[] res = new Short[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = Short.valueOf((String) values.nextElement());
                  }
                  value = res;
                } else {
                  value = Short.valueOf(ae.values.elementAt(0));
                }
                break;
              case AttributeDefinition.CHARACTER:
                if (card < 0) {
                  final Vector<Character> res = new Vector<Character>(-1 * card);
                  final Enumeration<?> values = ae.values.elements();
                  while (values.hasMoreElements()) {
                    res.add(new Character(((String) values.nextElement()).charAt(0)));
                  }
                  value = res;
                } else if (card > 0) {
                  final Character[] res = new Character[card];
                  final Enumeration<?> values = ae.values.elements();
                  for (int i = 0; values.hasMoreElements(); i++) {
                    res[i] = new Character(((String) values.nextElement()).charAt(0));
                  }
                  value = res;
                } else {
                  value = new Character(ae.values.elementAt(0).charAt(0));
                }
                break;
            }

            /*
             * TODO code along these lines would be less repetitive Class clazz
             * = null;
             *
             * switch(ad.getType()){ case AttributeDefinition.STRING: clazz =
             * null; break; case AttributeDefinition.BOOLEAN: clazz =
             * Boolean.class; break; case AttributeDefinition.BYTE: clazz =
             * Byte.class; break; case AttributeDefinition.DOUBLE: clazz =
             * Double.class; break; case AttributeDefinition.FLOAT: clazz =
             * Float.class; break; case AttributeDefinition.INTEGER: clazz =
             * Integer.class; break; case AttributeDefinition.LONG: clazz =
             * Long.class; break; case AttributeDefinition.SHORT: clazz =
             * Short.class; break; case AttributeDefinition.CHARACTER: clazz =
             * Character.class;
             *
             * break;
             *
             * }
             *
             * Method method = null; try{ method = clazz.getMethod("valueOf",
             * new Class[]{String.class}); } catch(NoSuchMethodException e){
             *
             * }
             *
             *
             *
             *
             * Boolean val = null;
             *
             * try{ val = (Boolean) method.invoke(null, new Object[]{"true"}); }
             * catch(IllegalAccessException e){
             *
             * } catch(InvocationTargetException e){
             *
             * }
             */
            if (value != null) {
              props.put(ad.getName(), value);
            }
          }
        } // while

        try {
          conf.update(props);
        } catch (final IOException ioe) {
        }
      } // if

      if (factoryPid != null) {
        factoryPids.put(factoryPid, ocd);
      } else {
        pids.put(pid, ocd);
      }
    }

    // TODO enforce bundleLocation
  }