private Address decode(long value) {
		if (useOldAddrMap) {
			return oldAddrMap.decodeAddress(value);
		}
		int type = (int) ((value >> ADDR_TYPE_SHIFT) & ADDR_TYPE_MASK);
		switch (type) {
			case OLD_ADDRESS_KEY_TYPE:
				return addrFactory.oldGetAddressFromLong(value);
			case ABSOLUTE_ADDR_TYPE:
				int baseIndex = (int) ((value >> ADDR_OFFSET_SIZE) & ID_MASK);
				long offset = value & ADDR_OFFSET_MASK;
				try {
					return baseAddrs[baseIndex].add(offset);
				}
				catch (ArrayIndexOutOfBoundsException e) {
					Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
					throw e;
				}
			case RELOCATABLE_ADDR_TYPE:
				baseIndex = (int) ((value >> ADDR_OFFSET_SIZE) & ID_MASK);
				offset = value & ADDR_OFFSET_MASK;
				if (baseIndex >= baseAddrs.length) {
					return Address.NO_ADDRESS;
				}
				Address base = baseAddrs[baseIndex];
				if (base.getAddressSpace().equals(defaultAddrSpace)) {
					offset += baseImageOffset;
				}
				return baseAddrs[baseIndex].addWrapSpace(offset);

			case VARIABLE_ADDR_TYPE:
				offset = value & ADDR_OFFSET_MASK;
				return AddressSpace.VARIABLE_SPACE.getAddress(offset);

			case REGISTER_ADDR_TYPE:
				int nameSpaceID = (int) ((value >> ADDR_OFFSET_SIZE) & ID_MASK);
				offset = value & ADDR_OFFSET_MASK;
				if (nameSpaceID != Namespace.GLOBAL_NAMESPACE_ID) {
					// needed for upgrade
					return new OldGenericNamespaceAddress(addrFactory.getRegisterSpace(), offset,
						nameSpaceID);
				}
				return addrFactory.getRegisterSpace().getAddress(offset);

			case STACK_ADDR_TYPE:
				nameSpaceID = (int) ((value >> ADDR_OFFSET_SIZE) & ID_MASK);
				// integer cast is required to force sign extension of masked value
				offset = (int) (value & ADDR_OFFSET_MASK);
				AddressSpace stackSpace = addrFactory.getStackSpace();
				if (nameSpaceID != Namespace.GLOBAL_NAMESPACE_ID) {
					// needed for upgrade
					try {
						return new OldGenericNamespaceAddress(stackSpace, offset, nameSpaceID);
					}
					catch (AddressOutOfBoundsException e) {
						// Recover bad stack address as best we can (used to be a common 32-bit stack space)
						return new OldGenericNamespaceAddress(stackSpace,
							truncateStackOffset(offset, stackSpace), nameSpaceID);
					}
				}
				try {
					return stackSpace.getAddress(offset);
				}
				catch (AddressOutOfBoundsException e) {
					// Recover bad stack address as best we can (used to be a common 32-bit stack space)
					return stackSpace.getAddress(truncateStackOffset(offset, stackSpace));
				}
			case EXTERNAL_ADDR_TYPE:
				nameSpaceID = (int) ((value >> ADDR_OFFSET_SIZE) & ID_MASK);
				offset = value & ADDR_OFFSET_MASK;
				if (nameSpaceID != Namespace.GLOBAL_NAMESPACE_ID) {
					// needed for upgrade
					return new OldGenericNamespaceAddress(AddressSpace.EXTERNAL_SPACE, offset,
						nameSpaceID);
				}
				return AddressSpace.EXTERNAL_SPACE.getAddress(offset);

			case HASH_ADDR_TYPE:
				offset = value & HASH_OFFSET_MASK;
				return AddressSpace.HASH_SPACE.getAddress(offset);

			case NO_ADDR_TYPE:
				if (value == EXT_FROM_ADDRESS_LONG) {
					return Address.EXT_FROM_ADDRESS;
				}
				return Address.NO_ADDRESS;
		}
		throw new RuntimeException("Unsupported address type: " + type);
	}
Returns the address that was used to generate the given long key. (If the image base was
moved, then a different address is returned unless the value was encoded using the
"absoluteEncoding" method
@param value the long value to convert to an address.
@param useMemorySegmentation if true and the program's default address space is segmented (i.e., SegmentedAddressSpace).
the address returned will be normalized to defined segmented memory blocks if possible.  This parameter should 
generally always be true except when used by the Memory map objects to avoid recursion problems.
@return decoded address
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/map/AddressMapDB.java