	public ObjectClassDefinition getObjectClassDefinition(String id, String localeStr) {
		final Locale locale = (localeStr==null) ? Locale.ENGLISH : new Locale(localeStr);
		final ResourceBundle rb = ResourceBundle.getBundle("OSGI-INF/l10n/" + RuntimeSettings.class.getSimpleName(), locale);		
		final class OptAD implements AttributeDefinition {
			private final OptEntry entry;
			private final String option;
			public OptAD(final OptEntry entry, final String option) {
				this.entry = entry;
				this.option = option;
			}
			public String getID() {
				return entry.getPid();
			}
			public int getCardinality() {
				return 0;
			}
			public String getDescription() {
				return rb.getString(entry.pid + ".desc");
			}
			public String getName() {
				return rb.getString(entry.pid + ".name");
			}
			public String[] getDefaultValue() {
				return new String[] { entry.getValue(option, false).toString() };
			}
			public String[] getOptionLabels() {
				return null;
			}
			public String[] getOptionValues() {
				return null;
			}
			public int getType() {
				return (entry.split) ? STRING : BOOLEAN;
			}
			public String validate(String value) {
				return entry.matches(value);
			}
		}
		return new ObjectClassDefinition() {
			public AttributeDefinition[] getAttributeDefinitions(int filter) {
				final List<AttributeDefinition> attribs = new ArrayList<AttributeDefinition>();
				final List<String> runtimeSettings = readSettings();
				final HashSet<OptEntry> optEntries = new HashSet<OptEntry>(OPTIONS);
				String otherValues = null;
				if (runtimeSettings != null) {
					final StringBuilder sb = new StringBuilder();
					outer: for (final String opt : runtimeSettings) {
						final Iterator<OptEntry> it = optEntries.iterator();
						while (it.hasNext()) {
							final OptEntry e = it.next();
							if (opt.startsWith(e.fixOpt)) {
								attribs.add(new OptAD(e, opt));
								it.remove();
								continue outer;
							}
						}
						if (sb.length() > 0)
							sb.append(OPT_OTHER_SPLIT);
						sb.append(opt);
					}
					otherValues = sb.toString();
				}
				for (final OptEntry e : optEntries)
					attribs.add(new OptAD(e, null));
				if (otherValues != null)
					attribs.add(new OptAD(CM_OTHER_ENTRY, otherValues));
				return attribs.toArray(new AttributeDefinition[attribs.size()]);
			}
			public String getDescription() {
				try {
					return MessageFormat.format(
							rb.getString("runtimeSettings.desc"),
							iniFile.getCanonicalFile().toString()
					);
				} catch (IOException e) {
					logger.error(e);
					return rb.getString("runtimeSettings.desc");
				}
			}
			public String getID() {
				return PID;
			}
			public InputStream getIcon(int size) throws IOException {
				return null;
			}
			public String getName() {
				return rb.getString("runtimeSettings.name");
			}
		};				
	}

	public ObjectClassDefinition getObjectClassDefinition(String id, String localeStr) {
		final Locale locale = (localeStr==null) ? Locale.ENGLISH : new Locale(localeStr);
		final ResourceBundle rb = ResourceBundle.getBundle("OSGI-INF/l10n/" + RuntimeSettings.class.getSimpleName(), locale);		
		final class OptAD implements AttributeDefinition {
			private final OptEntry entry;
			private final String option;
			public OptAD(final OptEntry entry, final String option) {
				this.entry = entry;
				this.option = option;
			}
			public String getID() {
				return entry.getPid();
			}
			public int getCardinality() {
				return 0;
			}
			public String getDescription() {
				return rb.getString(entry.pid + ".desc");
			}
			public String getName() {
				return rb.getString(entry.pid + ".name");
			}
			public String[] getDefaultValue() {
				return new String[] { entry.getValue(option, false).toString() };
			}
			public String[] getOptionLabels() {
				return null;
			}
			public String[] getOptionValues() {
				return null;
			}
			public int getType() {
				return (entry.split) ? STRING : BOOLEAN;
			}
			public String validate(String value) {
				return entry.matches(value);
			}
		}
		return new ObjectClassDefinition() {
			public AttributeDefinition[] getAttributeDefinitions(int filter) {
				final List<AttributeDefinition> attribs = new ArrayList<AttributeDefinition>();
				final List<String> runtimeSettings = readSettings();
				final HashSet<OptEntry> optEntries = new HashSet<OptEntry>(OPTIONS);
				String otherValues = "";
				if (runtimeSettings != null) {
					final StringBuilder sb = new StringBuilder();
					outer: for (final String opt : runtimeSettings) {
						final Iterator<OptEntry> it = optEntries.iterator();
						while (it.hasNext()) {
							final OptEntry e = it.next();
							if (opt.startsWith(e.fixOpt)) {
								attribs.add(new OptAD(e, opt));
								it.remove();
								continue outer;
							}
						}
						if (sb.length() > 0)
							sb.append(OPT_OTHER_SPLIT);
						sb.append(opt);
					}
					otherValues = sb.toString();
				}
				for (final OptEntry e : optEntries)
					attribs.add(new OptAD(e, null));
				attribs.add(new OptAD(CM_OTHER_ENTRY, otherValues));
				return attribs.toArray(new AttributeDefinition[attribs.size()]);
			}
			public String getDescription() {
				try {
					return MessageFormat.format(
							rb.getString("runtimeSettings.desc"),
							iniFile.getCanonicalFile().toString()
					);
				} catch (IOException e) {
					logger.error(e);
					return rb.getString("runtimeSettings.desc");
				}
			}
			public String getID() {
				return PID;
			}
			public InputStream getIcon(int size) throws IOException {
				return null;
			}
			public String getName() {
				return rb.getString("runtimeSettings.name");
			}
		};				
	}
