private boolean addActivatorClass(PrintWriter writer, Analyzer analyzer, Manifest manifest,
			Summary summary) throws OSGiException, IOException {

		String activatorClassName = null;
		try {
			for (Clazz clazz : analyzer.getClassspace().values()) {
				if (clazz.is(QUERY.IMPLEMENTS,
					new Instruction(INSTRCTION_ACTIVATOR), analyzer)) {
					Msg.trace(this, "Found BundleActivator class " + clazz);
					activatorClassName = clazz.toString();
				}
			}
		}
		catch (Exception e) {
			summary.print("Failed bnd analysis");
			throw new OSGiException("Failed to query classes while searching for activator", e);
		}

		Attributes manifestAttributes = manifest.getMainAttributes();
		if (activatorClassName != null) {
			manifestAttributes.putValue(Constants.BUNDLE_ACTIVATOR, activatorClassName);
			return true;
		}

		activatorClassName = GENERATED_ACTIVATOR_CLASSNAME;
		if (!buildDefaultActivator(binaryDir, activatorClassName, writer)) {
			summary.print("Failed to build generated activator");
			return false;
		}

		// since we add the activator after bndtools built the imports, add its imports too
		String imports = manifestAttributes.getValue(Constants.IMPORT_PACKAGE);
		String activatorPackageName = GhidraBundleActivator.class.getPackageName();
		if (imports == null) {
			manifestAttributes.putValue(Constants.IMPORT_PACKAGE, activatorPackageName);
		}
		else {
			manifestAttributes.putValue(Constants.IMPORT_PACKAGE, imports + "," +
				activatorPackageName);
		}
		manifestAttributes.putValue(Constants.BUNDLE_ACTIVATOR, activatorClassName);
		return true;
	}
Generate a manifest (and an activator)

<p>Assumes that {@link #updateRequirementsFromMetadata()} has been called recently
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/osgi/GhidraSourceBundle.java