class GnuDemangler implements Demangler {

	@Override
	public DemangledObject demangle(String mangled, boolean demangleOnlyKnownPatterns)
			throws DemangledException {

		if (skip(mangled, demangleOnlyKnownPatterns)) {
			return null;
		}

		String originalMangled = mangled;

		String globalPrefix = null;
		if (mangled.startsWith(GLOBAL_PREFIX)) {
			int index = mangled.indexOf("_Z");
			if (index > 0) {
				globalPrefix = mangled.substring(0, index);
				mangled = mangled.substring(index);
			}
		}
		else if (mangled.startsWith("__Z")) {
			mangled = mangled.substring(1);//removed first underscore....
		}

		boolean isDwarf = false;
		if (mangled.startsWith(DWARF_REF)) {
			int len = DWARF_REF.length();
			mangled = mangled.substring(len);
			isDwarf = true;
		}

		try {
			GnuDemanglerNativeProcess process = GnuDemanglerNativeProcess.getDemanglerNativeProcess();
			String demangled = process.demangle(mangled).trim();

			if (mangled.equals(demangled) || demangled.length() == 0) {
				throw new DemangledException(true);
			}

			DemangledObject demangledObject =
				parse(mangled, process, demangled, demangleOnlyKnownPatterns);
			if (demangledObject == null) {
				return demangledObject;
			}

			if (globalPrefix != null) {
				// TODO: may need better naming convention for demangled function
				DemangledFunction dfunc =
					new DemangledFunction(globalPrefix + demangledObject.getName());
				dfunc.setNamespace(demangledObject.getNamespace());
				demangledObject = dfunc;
			}
			else {
				demangledObject.setSignature(demangled);
			}
			demangledObject.setOriginalMangled(originalMangled);

			if (isDwarf) {
				DemangledAddressTable dat = new DemangledAddressTable((String) null, 1);
				dat.setSpecialPrefix("DWARF Debug ");
				dat.setName(demangledObject.getName());
				dat.setNamespace(demangledObject.getNamespace());
				dat.setOriginalMangled(originalMangled);
				return dat;
			}

			return demangledObject;
		}
		catch (IOException e) {
			if (e.getMessage().endsWith("14001")) {//missing runtime dlls, prolly
				ResourceFile installationDir = Application.getInstallationDirectory();
				throw new DemangledException("Missing runtime libraries. " + "Please install " +
					installationDir + File.separatorChar + "support" + File.separatorChar +
					"install_windows_runtime_libraries.exe.");
			}
			throw new DemangledException(e);
		}
	}

	public  GnuDemangler();

}